1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 13:12:50 +01:00
invoiceninja/app/Utils/Traits/GeneratesCounter.php

818 lines
27 KiB
PHP
Raw Normal View History

2019-05-27 07:26:34 +02:00
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
2019-05-27 07:26:34 +02:00
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
2024-04-12 06:15:41 +02:00
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
2019-05-27 07:26:34 +02:00
*
2021-06-16 08:58:16 +02:00
* @license https://www.elastic.co/licensing/elastic-license
2019-05-27 07:26:34 +02:00
*/
namespace App\Utils\Traits;
2020-10-28 11:10:49 +01:00
use App\Models\BaseModel;
2019-05-27 07:26:34 +02:00
use App\Models\Client;
use App\Models\Credit;
2020-09-23 02:16:19 +02:00
use App\Models\Expense;
2019-05-27 07:26:34 +02:00
use App\Models\Invoice;
use App\Models\Payment;
2020-10-20 01:55:14 +02:00
use App\Models\Project;
2022-05-31 00:28:32 +02:00
use App\Models\PurchaseOrder;
2019-05-27 07:26:34 +02:00
use App\Models\Quote;
2021-08-23 01:38:55 +02:00
use App\Models\RecurringExpense;
2019-05-27 07:26:34 +02:00
use App\Models\RecurringInvoice;
2021-08-24 07:32:22 +02:00
use App\Models\RecurringQuote;
2020-10-29 10:40:13 +01:00
use App\Models\Task;
2019-09-19 07:50:05 +02:00
use App\Models\Timezone;
2020-09-23 02:16:19 +02:00
use App\Models\Vendor;
2019-05-27 07:26:34 +02:00
use Illuminate\Support\Carbon;
2021-07-22 00:44:03 +02:00
use Illuminate\Support\Str;
2019-05-27 07:26:34 +02:00
/**
* Class GeneratesCounter.
2019-05-27 07:26:34 +02:00
*/
trait GeneratesCounter
2019-05-27 07:26:34 +02:00
{
2022-10-02 03:24:49 +02:00
private int $update_counter;
//todo in the form validation, we need to ensure that if a prefix and pattern is set we throw a validation error,
//only one type is allow else this will cause confusion to the end user
private function getNextEntityNumber($entity, Client $client, $is_recurring = false)
{
$prefix = '';
$this->resetCounters($client);
2021-01-29 06:41:19 +01:00
$is_client_counter = false;
$counter_string = $this->getEntityCounter($entity, $client);
$pattern = $this->getNumberPattern($entity, $client);
2021-01-29 06:41:19 +01:00
if ((strpos($pattern, 'clientCounter') !== false) || (strpos($pattern, 'client_counter') !== false)) {
2021-01-29 06:41:19 +01:00
if (property_exists($client->settings, $counter_string)) {
$counter = $client->settings->{$counter_string};
} else {
$counter = 1;
}
$counter_entity = $client;
2021-04-10 04:01:36 +02:00
} elseif ((strpos($pattern, 'groupCounter') !== false) || (strpos($pattern, 'group_counter') !== false)) {
2023-01-16 21:44:25 +01:00
if ($client->group_settings()->exists() && property_exists($client->group_settings?->settings, $counter_string)) {
$counter = $client->group_settings?->settings?->{$counter_string};
} else {
$counter = 1;
}
$counter_entity = $client->group_settings ?: $client->company;
} else {
2021-01-29 06:41:19 +01:00
$counter = $client->company->settings->{$counter_string};
$counter_entity = $client->company;
}
//If it is a quote - we need to
2021-01-29 06:41:19 +01:00
$pattern = $this->getNumberPattern($entity, $client);
if (strlen($pattern) > 1 && (stripos($pattern, 'counter') === false)) {
2021-04-10 04:01:36 +02:00
$pattern = $pattern.'{$counter}';
}
$padding = $client->getSetting('counter_padding');
if ($is_recurring) {
$prefix = $client->getSetting('recurring_number_prefix');
}
$entity_number = $this->checkEntityNumber($entity, $client, $counter, $padding, $pattern, $prefix);
2021-01-29 06:41:19 +01:00
$this->incrementCounter($counter_entity, $counter_string);
return $entity_number;
}
2021-01-29 06:41:19 +01:00
private function getNumberPattern($entity, Client $client)
{
$pattern_string = '';
switch ($entity) {
case Invoice::class:
$pattern_string = 'invoice_number_pattern';
break;
case Quote::class:
$pattern_string = 'quote_number_pattern';
break;
case RecurringInvoice::class:
$pattern_string = 'recurring_invoice_number_pattern';
break;
case Payment::class:
$pattern_string = 'payment_number_pattern';
break;
case Credit::class:
$pattern_string = 'credit_number_pattern';
break;
case Project::class:
$pattern_string = 'project_number_pattern';
break;
}
2020-10-07 01:16:57 +02:00
2021-01-29 06:41:19 +01:00
return $client->getSetting($pattern_string);
}
2021-01-29 06:41:19 +01:00
private function getEntityCounter($entity, $client)
{
switch ($entity) {
case Invoice::class:
return 'invoice_number_counter';
2024-01-14 05:05:00 +01:00
2021-01-29 06:41:19 +01:00
case Quote::class:
if ($this->hasSharedCounter($client, 'quote')) {
2021-01-29 06:41:19 +01:00
return 'invoice_number_counter';
}
2021-01-29 06:41:19 +01:00
return 'quote_number_counter';
2024-01-14 05:05:00 +01:00
2021-01-29 06:41:19 +01:00
case RecurringInvoice::class:
return 'recurring_invoice_number_counter';
2024-01-14 05:05:00 +01:00
2021-08-24 07:32:22 +02:00
case RecurringQuote::class:
return 'recurring_quote_number_counter';
2024-01-14 05:05:00 +01:00
2021-08-24 07:32:22 +02:00
case RecurringExpense::class:
return 'recurring_expense_number_counter';
2024-01-14 05:05:00 +01:00
2021-01-29 06:41:19 +01:00
case Payment::class:
return 'payment_number_counter';
2024-01-14 05:05:00 +01:00
2021-01-29 06:41:19 +01:00
case Credit::class:
if ($this->hasSharedCounter($client, 'credit')) {
2021-03-17 11:06:08 +01:00
return 'invoice_number_counter';
}
2021-01-29 06:41:19 +01:00
return 'credit_number_counter';
2024-01-14 05:05:00 +01:00
2021-01-29 06:41:19 +01:00
case Project::class:
return 'project_number_counter';
2024-01-14 05:05:00 +01:00
case PurchaseOrder::class:
return 'purchase_order_number_counter';
2022-05-31 00:28:32 +02:00
2021-01-29 06:41:19 +01:00
default:
return 'default_number_counter';
}
}
/**
* Gets the next invoice number.
*
* @param Client $client The client
*
* @param Invoice|null $invoice
* @return string The next invoice number.
*/
2024-01-14 05:05:00 +01:00
public function getNextInvoiceNumber(Client $client, ?Invoice $invoice, $is_recurring = false): string
{
$entity_number = $this->getNextEntityNumber(Invoice::class, $client, $is_recurring);
return $this->replaceUserVars($invoice, $entity_number);
}
2019-05-27 07:26:34 +02:00
/**
* Gets the next credit number.
*
* @param Client $client The client
*
* @return string The next credit number.
*/
2024-01-14 05:05:00 +01:00
public function getNextCreditNumber(Client $client, ?Credit $credit): string
{
$entity_number = $this->getNextEntityNumber(Credit::class, $client);
return $this->replaceUserVars($credit, $entity_number);
}
/**
* Gets the next quote number.
*
* @param Client $client The client
*
* @return string The next credit number.
*/
public function getNextQuoteNumber(Client $client, ?Quote $quote)
{
$entity_number = $this->getNextEntityNumber(Quote::class, $client);
return $this->replaceUserVars($quote, $entity_number);
}
public function getNextRecurringInvoiceNumber(Client $client, $recurring_invoice)
{
$entity_number = $this->getNextEntityNumber(RecurringInvoice::class, $client);
return $this->replaceUserVars($recurring_invoice, $entity_number);
}
2021-10-17 05:21:13 +02:00
public function getNextRecurringQuoteNumber(Client $client, $recurring_quote)
2021-08-24 07:32:22 +02:00
{
$entity_number = $this->getNextEntityNumber(RecurringQuote::class, $client);
return $this->replaceUserVars($recurring_quote, $entity_number);
2021-08-24 07:32:22 +02:00
}
/**
* Gets the next Payment number.
*
* @param Client $client The client
*
* @return string The next payment number.
*/
2024-01-14 05:05:00 +01:00
public function getNextPaymentNumber(Client $client, ?Payment $payment): string
{
$entity_number = $this->getNextEntityNumber(Payment::class, $client);
return $this->replaceUserVars($payment, $entity_number);
}
/**
* Gets the next client number.
*
2020-10-28 11:10:49 +01:00
* @param Client $client The client
*
* @return string The next client number.
2020-10-28 11:10:49 +01:00
* @throws \Exception
*/
2024-01-14 05:05:00 +01:00
public function getNextClientNumber(Client $client): string
{
//Reset counters if enabled
$this->resetCounters($client);
$counter = $client->getSetting('client_number_counter');
2019-10-08 13:14:23 +02:00
$setting_entity = $client->getSettingEntity('client_number_counter');
$client_number = $this->checkEntityNumber(Client::class, $client, $counter, $client->getSetting('counter_padding'), $client->getSetting('client_number_pattern'));
$this->incrementCounter($setting_entity, 'client_number_counter');
2019-05-27 07:26:34 +02:00
$entity_number = $client_number;
return $this->replaceUserVars($client, $entity_number);
}
2019-05-27 07:26:34 +02:00
2020-09-23 02:16:19 +02:00
/**
* Gets the next client number.
*
2020-10-28 11:10:49 +01:00
* @param Vendor $vendor The vendor
2020-09-23 02:16:19 +02:00
* @return string The next vendor number.
*/
2024-01-14 05:05:00 +01:00
public function getNextVendorNumber(Vendor $vendor): string
2020-09-23 02:16:19 +02:00
{
$this->resetCompanyCounters($vendor->company);
$counter = $vendor->company->settings->vendor_number_counter;
$setting_entity = $vendor->company->settings->vendor_number_counter;
$vendor_number = $this->checkEntityNumber(Vendor::class, $vendor, $counter, $vendor->company->settings->counter_padding, $vendor->company->settings->vendor_number_pattern);
$this->incrementCounter($vendor->company, 'vendor_number_counter');
$entity_number = $vendor_number;
return $this->replaceUserVars($vendor, $entity_number);
2020-09-23 02:16:19 +02:00
}
2020-10-29 12:01:37 +01:00
/**
* Project Number Generator.
* @param Project $project
* @return string The project number
*/
2024-01-14 05:05:00 +01:00
public function getNextProjectNumber(Project $project): string
2020-10-29 12:01:37 +01:00
{
2024-04-29 08:50:04 +02:00
$entity_number = $this->getNextEntityNumber(Project::class, $project->client, false);
return $this->replaceUserVars($project, $entity_number);
2020-10-29 12:01:37 +01:00
}
2020-10-29 10:40:13 +01:00
/**
* Gets the next task number.
*
* @param Task $task The task
* @return string The next task number.
*/
2024-01-14 05:05:00 +01:00
public function getNextTaskNumber(Task $task): string
2020-10-29 10:40:13 +01:00
{
$this->resetCompanyCounters($task->company);
$counter = $task->company->settings->task_number_counter;
$setting_entity = $task->company->settings->task_number_counter;
$task_number = $this->checkEntityNumber(Task::class, $task, $counter, $task->company->settings->counter_padding, $task->company->settings->task_number_pattern);
$this->incrementCounter($task->company, 'task_number_counter');
$entity_number = $task_number;
return $this->replaceUserVars($task, $entity_number);
2020-10-29 10:40:13 +01:00
}
/**
* Gets the next expense number.
*
* @param Expense $expense The expense
* @return string The next expense number.
*/
2024-01-14 05:05:00 +01:00
public function getNextExpenseNumber(Expense $expense): string
2020-10-29 10:40:13 +01:00
{
$this->resetCompanyCounters($expense->company);
$counter = $expense->company->settings->expense_number_counter;
$setting_entity = $expense->company->settings->expense_number_counter;
$expense_number = $this->checkEntityNumber(Expense::class, $expense, $counter, $expense->company->settings->counter_padding, $expense->company->settings->expense_number_pattern);
$this->incrementCounter($expense->company, 'expense_number_counter');
$entity_number = $expense_number;
return $this->replaceUserVars($expense, $entity_number);
2020-10-29 10:40:13 +01:00
}
2020-09-23 02:16:19 +02:00
2024-01-14 05:05:00 +01:00
public function getNextPurchaseOrderNumber(PurchaseOrder $purchase_order): string
2022-05-31 00:28:32 +02:00
{
$this->resetCompanyCounters($purchase_order->company);
$counter = $purchase_order->company->settings->purchase_order_number_counter;
$setting_entity = $purchase_order->company->settings->purchase_order_number_counter;
$purchase_order_number = $this->checkEntityNumber(PurchaseOrder::class, $purchase_order, $counter, $purchase_order->company->settings->counter_padding, $purchase_order->company->settings->purchase_order_number_pattern);
2022-06-05 11:41:19 +02:00
$this->incrementCounter($purchase_order->company, 'purchase_order_number_counter');
2022-05-31 00:28:32 +02:00
$entity_number = $purchase_order_number;
return $this->replaceUserVars($purchase_order, $entity_number);
}
2022-05-31 00:28:32 +02:00
2021-08-23 01:38:55 +02:00
/**
* Gets the next expense number.
*
* @param RecurringExpense $expense The expense
* @return string The next expense number.
*/
2024-01-14 05:05:00 +01:00
public function getNextRecurringExpenseNumber(RecurringExpense $expense): string
2021-08-23 01:38:55 +02:00
{
$this->resetCompanyCounters($expense->company);
// - 18/09/21 need to set this property if it doesn't exist. //todo refactor this for other properties
if (! property_exists($expense->company->settings, 'recurring_expense_number_counter')) {
$settings = $expense->company->settings;
$settings->recurring_expense_number_counter = 1;
$settings->recurring_expense_number_pattern = '';
$expense->company->settings = $settings;
$expense->company->save();
}
2021-08-23 01:38:55 +02:00
$counter = $expense->company->settings->recurring_expense_number_counter;
$setting_entity = $expense->company->settings->recurring_expense_number_counter;
$expense_number = $this->checkEntityNumber(RecurringExpense::class, $expense, $counter, $expense->company->settings->counter_padding, $expense->company->settings->recurring_expense_number_pattern);
$this->incrementCounter($expense->company, 'recurring_expense_number_counter');
$entity_number = $expense_number;
return $this->replaceUserVars($expense, $entity_number);
2021-08-23 01:38:55 +02:00
}
/**
* Determines if it has shared counter.
*
2020-10-28 11:10:49 +01:00
* @param Client $client The client
*
* @return bool True if has shared counter, False otherwise.
*/
2024-01-14 05:05:00 +01:00
public function hasSharedCounter(Client $client, string $type = 'quote'): bool
{
if ($type == 'quote') {
2021-07-16 15:10:27 +02:00
return (bool) $client->getSetting('shared_invoice_quote_counter');
}
2021-07-16 15:10:27 +02:00
2022-07-18 02:04:17 +02:00
//credit
2023-02-16 02:36:09 +01:00
return (bool) $client->getSetting('shared_invoice_credit_counter');
}
2019-05-27 13:54:27 +02:00
/**
* Checks that the number has not already been used.
*
2020-10-28 11:10:49 +01:00
* @param $class
* @param Collection $entity The entity ie App\Models\Client, Invoice, Quote etc
* @param int $counter The counter
* @param int $padding The padding
*
2021-01-25 11:34:12 +01:00
* @param string $pattern
* @param string $prefix
* @return string The padded and prefixed entity number
*/
2024-01-14 05:05:00 +01:00
private function checkEntityNumber($class, $entity, $counter, $padding, $pattern, $prefix = ''): string
{
$check = false;
2021-07-22 00:44:03 +02:00
$check_counter = 1;
2019-05-27 13:54:27 +02:00
do {
$number = $this->padCounter($counter, $padding);
2019-05-27 07:26:34 +02:00
2020-09-23 02:16:19 +02:00
$number = $this->applyNumberPattern($entity, $number, $pattern);
2020-10-07 05:00:32 +02:00
$number = $this->prefixCounter($number, $prefix);
$check = $class::where('company_id', $entity->company_id)->where('number', $number)->withTrashed()->exists();
2020-10-28 11:10:49 +01:00
$counter++;
2021-07-22 00:44:03 +02:00
$check_counter++;
if ($check_counter > 100) {
2022-10-02 03:24:49 +02:00
$this->update_counter = $counter--;
return $number.'_'.Str::random(5);
}
} while ($check);
2019-05-27 07:26:34 +02:00
2022-10-02 03:24:49 +02:00
$this->update_counter = $counter--;
return $number;
}
2019-05-27 07:26:34 +02:00
/*Check if a number is available for use. */
2024-01-14 05:05:00 +01:00
public function checkNumberAvailable($class, $entity, $number): bool
{
if ($entity = $class::whereCompanyId($entity->company_id)->whereNumber($number)->withTrashed()->exists()) {
2021-01-25 11:34:12 +01:00
return false;
}
return true;
}
/**
* Saves counters at both the company and client level.
*
2020-10-28 11:10:49 +01:00
* @param $entity
* @param string $counter_name The counter name
*/
2024-01-14 05:05:00 +01:00
private function incrementCounter($entity, string $counter_name): void
{
$settings = $entity->settings;
if ($counter_name == 'invoice_number_counter' && ! property_exists($entity->settings, 'invoice_number_counter')) {
$settings->invoice_number_counter = 0;
}
if (! property_exists($settings, $counter_name)) {
2021-01-29 06:41:19 +01:00
$settings->{$counter_name} = 1;
}
2021-01-29 06:41:19 +01:00
2022-10-02 03:24:49 +02:00
// $settings->{$counter_name} = $settings->{$counter_name} + 1;
$settings->{$counter_name} = $this->update_counter;
$entity->settings = $settings;
$entity->save();
}
2019-05-27 07:26:34 +02:00
2024-01-14 05:05:00 +01:00
private function prefixCounter($counter, $prefix): string
{
if (strlen($prefix) == 0) {
return $counter;
}
2019-05-27 07:26:34 +02:00
return $prefix.$counter;
}
2019-05-27 07:26:34 +02:00
/**
* Pads a number with leading 000000's.
*
* @param int $counter The counter
* @param int $padding The padding
*
2020-10-28 11:10:49 +01:00
* @return string the padded counter
*/
2024-01-14 05:05:00 +01:00
private function padCounter($counter, $padding): string
2019-05-27 07:26:34 +02:00
{
return str_pad($counter, $padding, '0', STR_PAD_LEFT);
}
/**
* If we are using counter reset,
* check if we need to reset here.
*
2020-10-28 11:10:49 +01:00
* @param Client $client client entity
* @return void
*/
private function resetCounters(Client $client)
{
$reset_counter_frequency = (int) $client->getSetting('reset_counter_frequency_id');
$settings_entity = $client->getSettingEntity('reset_counter_frequency_id');
$settings = $settings_entity->settings;
2021-04-21 11:57:59 +02:00
if ($reset_counter_frequency == 0) {
2023-02-16 02:36:09 +01:00
if ($client->getSetting('reset_counter_date')) {
// $settings = $client->company->settings;
2023-02-16 02:36:09 +01:00
$settings->reset_counter_date = "";
$settings_entity->settings = $settings;
$settings_entity->saveQuietly();
// $client->company->settings = $settings;
// $client->company->save();
2023-02-16 02:36:09 +01:00
}
2021-04-21 11:57:59 +02:00
return;
}
2019-09-19 07:50:05 +02:00
$timezone = Timezone::find($client->getSetting('timezone_id'));
2019-05-27 07:26:34 +02:00
2019-09-19 07:50:05 +02:00
$reset_date = Carbon::parse($client->getSetting('reset_counter_date'), $timezone->name);
2019-05-27 07:26:34 +02:00
2021-05-05 02:58:18 +02:00
if (! $reset_date->lte(now()) || ! $client->getSetting('reset_counter_date')) {
2019-05-27 07:26:34 +02:00
return false;
}
2019-05-27 07:26:34 +02:00
2021-04-21 11:57:59 +02:00
switch ($reset_counter_frequency) {
2021-04-08 12:38:31 +02:00
case RecurringInvoice::FREQUENCY_DAILY:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addDay();
2021-04-08 12:38:31 +02:00
break;
2019-05-27 07:26:34 +02:00
case RecurringInvoice::FREQUENCY_WEEKLY:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addWeek();
2019-05-27 07:26:34 +02:00
break;
case RecurringInvoice::FREQUENCY_TWO_WEEKS:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addWeeks(2);
2019-05-27 07:26:34 +02:00
break;
case RecurringInvoice::FREQUENCY_FOUR_WEEKS:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addWeeks(4);
2019-05-27 07:26:34 +02:00
break;
case RecurringInvoice::FREQUENCY_MONTHLY:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addMonth();
2019-05-27 07:26:34 +02:00
break;
case RecurringInvoice::FREQUENCY_TWO_MONTHS:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addMonths(2);
2019-05-27 07:26:34 +02:00
break;
case RecurringInvoice::FREQUENCY_THREE_MONTHS:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addMonths(3);
2019-05-27 07:26:34 +02:00
break;
case RecurringInvoice::FREQUENCY_FOUR_MONTHS:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addMonths(4);
2019-05-27 07:26:34 +02:00
break;
case RecurringInvoice::FREQUENCY_SIX_MONTHS:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addMonths(6);
2019-05-27 07:26:34 +02:00
break;
case RecurringInvoice::FREQUENCY_ANNUALLY:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addYear();
2019-05-27 07:26:34 +02:00
break;
case RecurringInvoice::FREQUENCY_TWO_YEARS:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addYears(2);
2022-01-19 00:03:41 +01:00
break;
2023-02-16 02:36:09 +01:00
default:
2022-01-19 04:11:08 +01:00
$new_reset_date = $reset_date->addYear();
2019-05-27 07:26:34 +02:00
break;
}
// $settings = $client->company->settings;
2022-01-19 00:03:41 +01:00
$settings->reset_counter_date = $new_reset_date->format('Y-m-d');
2019-05-27 07:26:34 +02:00
$settings->invoice_number_counter = 1;
$settings->quote_number_counter = 1;
$settings->credit_number_counter = 1;
2023-01-28 04:59:35 +01:00
$settings->ticket_number_counter = 1;
$settings->payment_number_counter = 1;
$settings->project_number_counter = 1;
$settings->task_number_counter = 1;
$settings->expense_number_counter = 1;
$settings->recurring_expense_number_counter = 1;
$settings->purchase_order_number_counter = 1;
2019-05-27 07:26:34 +02:00
// $client->company->settings = $settings;
// $client->company->save();
$settings_entity->settings = $settings;
$settings_entity->saveQuietly();
2019-05-27 07:26:34 +02:00
}
2020-09-23 02:16:19 +02:00
private function resetCompanyCounters($company)
{
$timezone = Timezone::find($company->settings->timezone_id);
$reset_date = Carbon::parse($company->settings->reset_counter_date, $timezone->name);
2021-05-05 02:58:18 +02:00
if (! $reset_date->lte(now()) || ! $company->settings->reset_counter_date) {
2020-09-23 02:16:19 +02:00
return false;
}
2023-01-28 04:59:35 +01:00
$settings = $company->settings;
$reset_counter_frequency = (int) $settings->reset_counter_frequency_id;
if ($reset_counter_frequency == 0) {
2023-02-16 02:36:09 +01:00
if ($settings->reset_counter_date) {
$settings->reset_counter_date = "";
$company->settings = $settings;
$company->save();
}
2023-01-28 04:59:35 +01:00
return;
}
switch ($reset_counter_frequency) {
2021-04-10 04:01:36 +02:00
case RecurringInvoice::FREQUENCY_DAILY:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addDay();
2021-04-10 04:01:36 +02:00
break;
2020-09-23 02:16:19 +02:00
case RecurringInvoice::FREQUENCY_WEEKLY:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addWeek();
2020-09-23 02:16:19 +02:00
break;
case RecurringInvoice::FREQUENCY_TWO_WEEKS:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addWeeks(2);
2020-09-23 02:16:19 +02:00
break;
case RecurringInvoice::FREQUENCY_FOUR_WEEKS:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addWeeks(4);
2020-09-23 02:16:19 +02:00
break;
case RecurringInvoice::FREQUENCY_MONTHLY:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addMonth();
2020-09-23 02:16:19 +02:00
break;
case RecurringInvoice::FREQUENCY_TWO_MONTHS:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addMonths(2);
2020-09-23 02:16:19 +02:00
break;
case RecurringInvoice::FREQUENCY_THREE_MONTHS:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addMonths(3);
2020-09-23 02:16:19 +02:00
break;
case RecurringInvoice::FREQUENCY_FOUR_MONTHS:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addMonths(4);
2020-09-23 02:16:19 +02:00
break;
case RecurringInvoice::FREQUENCY_SIX_MONTHS:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addMonths(6);
2020-09-23 02:16:19 +02:00
break;
case RecurringInvoice::FREQUENCY_ANNUALLY:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addYear();
2020-09-23 02:16:19 +02:00
break;
case RecurringInvoice::FREQUENCY_TWO_YEARS:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addYears(2);
break;
2023-02-16 02:36:09 +01:00
default:
2023-01-28 04:59:35 +01:00
$new_reset_date = $reset_date->addYear();
2020-09-23 02:16:19 +02:00
break;
}
2023-01-28 04:59:35 +01:00
$settings->reset_counter_date = $new_reset_date->format('Y-m-d');
2020-09-23 02:16:19 +02:00
$settings->invoice_number_counter = 1;
$settings->quote_number_counter = 1;
$settings->credit_number_counter = 1;
$settings->ticket_number_counter = 1;
$settings->payment_number_counter = 1;
$settings->project_number_counter = 1;
2020-09-23 02:16:19 +02:00
$settings->task_number_counter = 1;
$settings->expense_number_counter = 1;
$settings->recurring_expense_number_counter = 1;
$settings->purchase_order_number_counter = 1;
2020-09-23 02:16:19 +02:00
$company->settings = $settings;
2020-10-28 11:10:49 +01:00
$company->save();
2020-09-23 02:16:19 +02:00
}
/**
2020-09-23 02:16:19 +02:00
* Formats a entity number by pattern
*
2020-10-28 11:10:49 +01:00
* @param BaseModel $entity The entity object
2020-09-23 02:16:19 +02:00
* @param string $counter The counter
* @param null|string $pattern The pattern
*
2020-09-23 02:16:19 +02:00
* @return string The formatted number pattern
*/
2024-01-14 05:05:00 +01:00
private function applyNumberPattern($entity, string $counter, $pattern): string
2019-05-27 07:26:34 +02:00
{
if (! $pattern) {
return $counter;
}
2019-05-27 07:26:34 +02:00
2022-05-02 04:50:55 +02:00
$search = [];
$replace = [];
2019-05-27 07:26:34 +02:00
$search[] = '{$counter}';
2019-05-27 13:54:27 +02:00
$replace[] = $counter;
2019-05-27 07:26:34 +02:00
2020-11-23 13:55:04 +01:00
$search[] = '{$client_counter}';
$replace[] = $counter;
$search[] = '{$clientCounter}';
$replace[] = $counter;
2020-11-23 13:55:04 +01:00
$search[] = '{$group_counter}';
2019-05-27 13:54:27 +02:00
$replace[] = $counter;
2019-05-27 07:26:34 +02:00
$search[] = '{$year}';
2022-05-03 01:33:18 +02:00
$replace[] = Carbon::now($entity->company->timezone()->name)->format('Y');
if (strstr($pattern, '{$user_id}') || strstr($pattern, '{$userId}')) {
2020-09-23 02:16:19 +02:00
$user_id = $entity->user_id ? $entity->user_id : 0;
2019-05-27 07:26:34 +02:00
$search[] = '{$user_id}';
$replace[] = str_pad(($user_id), 2, '0', STR_PAD_LEFT);
$search[] = '{$userId}';
$replace[] = str_pad(($user_id), 2, '0', STR_PAD_LEFT);
2019-05-27 07:26:34 +02:00
}
2023-06-08 09:16:24 +02:00
$matches = [];
2019-05-27 07:26:34 +02:00
preg_match('/{\$date:(.*?)}/', $pattern, $matches);
if (count($matches) > 1) {
$format = $matches[1];
$search[] = $matches[0];
/* The following adjusts for the company timezone - may bork tests depending on the time of day the tests are run!!!!!!*/
2020-09-23 02:16:19 +02:00
$date = Carbon::now($entity->company->timezone()->name)->format($format);
2019-05-27 07:26:34 +02:00
$replace[] = str_replace($format, $date, $matches[1]);
}
2020-12-07 11:43:21 +01:00
if ($entity instanceof Vendor) {
$search[] = '{$vendor_id_number}';
$replace[] = $entity->id_number;
}
2020-12-07 11:43:21 +01:00
if ($entity instanceof Expense) {
if ($entity->vendor) {
2020-12-07 11:43:21 +01:00
$search[] = '{$vendor_id_number}';
$replace[] = $entity->vendor->id_number;
2021-01-25 11:34:12 +01:00
$search[] = '{$vendor_number}';
$replace[] = $entity->vendor->number;
2020-12-07 11:43:21 +01:00
$search[] = '{$vendor_custom1}';
$replace[] = $entity->vendor->custom_value1;
2019-05-27 07:26:34 +02:00
2020-12-07 11:43:21 +01:00
$search[] = '{$vendor_custom2}';
$replace[] = $entity->vendor->custom_value2;
$search[] = '{$vendor_custom3}';
$replace[] = $entity->vendor->custom_value3;
$search[] = '{$vendor_custom4}';
$replace[] = $entity->vendor->custom_value4;
}
$search[] = '{$expense_id_number}';
2020-11-23 13:55:04 +01:00
$replace[] = $entity->id_number;
}
if ($entity->client || ($entity instanceof Client)) {
$client = $entity->client ?: $entity;
2020-11-23 13:55:04 +01:00
$search[] = '{$client_custom1}';
$replace[] = $client->custom_value1;
2020-11-23 13:55:04 +01:00
$search[] = '{$clientCustom1}';
$replace[] = $client->custom_value1;
2020-11-23 13:55:04 +01:00
$search[] = '{$client_custom2}';
$replace[] = $client->custom_value2;
2020-11-23 13:55:04 +01:00
$search[] = '{$clientCustom2}';
$replace[] = $client->custom_value2;
2020-11-23 13:55:04 +01:00
$search[] = '{$client_custom3}';
$replace[] = $client->custom_value3;
2020-11-23 13:55:04 +01:00
$search[] = '{$client_custom4}';
$replace[] = $client->custom_value4;
2020-11-23 13:55:04 +01:00
2021-01-25 11:34:12 +01:00
$search[] = '{$client_number}';
$replace[] = $client->number;
2020-12-07 11:43:21 +01:00
$search[] = '{$client_id_number}';
$replace[] = $client->id_number ?: $client->number;
$search[] = '{$clientIdNumber}';
2022-11-30 22:49:59 +01:00
$replace[] = $client->id_number ?: $client->number;
2020-11-23 13:55:04 +01:00
}
return str_replace($search, $replace, $pattern);
}
private function replaceUserVars($entity, $pattern)
{
if (! $entity) {
return $pattern;
}
$search = [];
$replace = [];
$search[] = '{$user_custom1}';
2023-10-25 10:04:27 +02:00
$replace[] = $entity->user->custom_value1 ?? '';
$search[] = '{$user_custom2}';
2023-10-25 10:04:27 +02:00
$replace[] = $entity->user->custom_value2 ?? '';
$search[] = '{$user_custom3}';
2023-10-25 10:04:27 +02:00
$replace[] = $entity->user->custom_value3 ?? '';
$search[] = '{$user_custom4}';
2023-10-25 10:04:27 +02:00
$replace[] = $entity->user->custom_value4 ?? '';
2019-05-27 07:26:34 +02:00
return str_replace($search, $replace, $pattern);
}
}