Working on Generates Number

This commit is contained in:
David Bomba 2019-04-30 16:02:39 +10:00
parent 19a5c7119b
commit defbae832b
6 changed files with 118 additions and 19 deletions

View File

@ -68,6 +68,8 @@ class ClientSettings extends BaseSettings
public $credit_number_counter; public $credit_number_counter;
public $shared_invoice_quote_counter; public $shared_invoice_quote_counter;
public $recurring_invoice_number_prefix;
public $counter_padding; public $counter_padding;
/** /**

View File

@ -96,7 +96,7 @@ class CompanySettings extends BaseSettings
public $shared_invoice_quote_counter; public $shared_invoice_quote_counter;
public $entity_number_padding; public $entity_number_padding;
public $recurring_number_prefix; public $recurring_invoice_number_prefix;
public $reset_counter_frequency_id; public $reset_counter_frequency_id;
public $reset_counter_date; public $reset_counter_date;
public $counter_padding; public $counter_padding;

View File

@ -10,6 +10,7 @@ use App\Models\Country;
use App\Models\Filterable; use App\Models\Filterable;
use App\Models\Timezone; use App\Models\Timezone;
use App\Utils\Traits\GeneratesNumberCounter; use App\Utils\Traits\GeneratesNumberCounter;
use App\Utils\Traits\MakesDates;
use App\Utils\Traits\MakesHash; use App\Utils\Traits\MakesHash;
use Hashids\Hashids; use Hashids\Hashids;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
@ -19,6 +20,7 @@ class Client extends BaseModel
{ {
use PresentableTrait; use PresentableTrait;
use MakesHash; use MakesHash;
use MakesDates;
use SoftDeletes; use SoftDeletes;
use Filterable; use Filterable;
use GeneratesNumberCounter; use GeneratesNumberCounter;

View File

@ -37,7 +37,6 @@ class Company extends BaseModel
]; ];
protected $appends = [ protected $appends = [
'settings_object'
]; ];
protected $casts = [ protected $casts = [
@ -48,16 +47,6 @@ class Company extends BaseModel
// 'tokens' // 'tokens'
]; ];
public function getSettingsObjectAttribute()
{
return new CompanySettings($this->settings);
}
public function getRouteKeyName()
{
return 'company_id';
}
public function getCompanyIdAttribute() public function getCompanyIdAttribute()
{ {
return $this->encodePrimaryKey($this->id); return $this->encodePrimaryKey($this->id);
@ -130,11 +119,11 @@ class Company extends BaseModel
} }
/** /**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo *
*/ */
public function timezone() public function timezone()
{ {
return $this->belongsTo(Timezone::class); return Timezone::find($this->settings->timezone_id);
} }
/** /**
@ -142,7 +131,7 @@ class Company extends BaseModel
*/ */
public function language() public function language()
{ {
return $this->belongsTo(Language::class); return Language::find($this->settings->language_id);
} }
/** /**

View File

@ -6,6 +6,8 @@ use App\Models\Client;
use App\Models\Credit; use App\Models\Credit;
use App\Models\Invoice; use App\Models\Invoice;
use App\Models\Quote; use App\Models\Quote;
use App\Models\RecurringInvoice;
use Illuminate\Support\Carbon;
/** /**
* Class GeneratesNumberCounter * Class GeneratesNumberCounter
@ -18,22 +20,79 @@ trait GeneratesNumberCounter
{ {
$counter = $this->getCounter($entity); $counter = $this->getCounter($entity);
$check = false;
do {
if ($this->hasNumberPattern($entity)) {
$number = $this->applyNumberPattern($entity, $counter);
} else {
$number = $prefix . str_pad($counter, $this->invoice_number_padding, '0', STR_PAD_LEFT);
}
if ($entity->recurring_invoice_id) {
$number = $this->recurring_invoice_number_prefix . $number;
}
if ($entity->isentity(ENTITY_CLIENT)) {
$check = Client::scope(false, $this->id)->whereIdNumber($number)->withTrashed()->first();
} else {
$check = Invoice::scope(false, $this->id)->whereInvoiceNumber($number)->withTrashed()->first();
}
$counter++;
$counterOffset++;
// prevent getting stuck in a loop
if ($number == $lastNumber) {
return '';
}
$lastNumber = $number;
} while ($check);
} }
public function hasSharedCounter() : bool public function hasSharedCounter() : bool
{ {
return $this->getSettingsByKey($shared_invoice_quote_counter)->shared_invoice_quote_counter; return $this->getSettingsByKey('shared_invoice_quote_counter')->shared_invoice_quote_counter;
} }
/**
* @param $entity
*
* @return bool
*/
public function hasNumberPattern($entity) : bool
{
return $this->getNumberPattern($entity) ? true : false;
}
/**
* @param $entity
*
* @return NULL|string
*/
public function getNumberPattern($entity)
{
/** Recurring invoice share the same number pattern as invoices */
if($entity == RecurringInvoice::class )
$entity = Invoice::class;
$field = $this->entityName($entity) . "_number_pattern";
return $this->getSettingsByKey( $field )->{$field};
}
private function incrementCounter($entity) private function incrementCounter($entity)
{ {
} }
private function entity_name($entity) private function entityName($entity)
{ {
return strtolower(class_basename($entity)); return strtolower(class_basename($entity));
@ -42,10 +101,57 @@ trait GeneratesNumberCounter
public function getCounter($entity) : int public function getCounter($entity) : int
{ {
$counter = $this->entity_name($entity) . '_number_counter'; /** Recurring invoice share the same counter as invoices also harvest the invoice_counter if quote and invoices are sharing a counter */
if($entity == RecurringInvoice::class || $this->hasSharedCounter())
$entity = Invoice::class;
$counter = $this->entityName($entity) . '_number_counter';
return $this->getSettingsByKey( $counter )->{$counter}; return $this->getSettingsByKey( $counter )->{$counter};
} }
/**
* @param $entity
* @param mixed $counter
* todo localize PHP date
* @return bool|mixed
*/
public function applyNumberPattern($entity, $counter = 1)
{
$counter = $counter ?: $this->getCounter($entity);
$pattern = $this->getNumberPattern($entity);
if (! $pattern) {
return false;
}
$search = ['{$year}'];
$replace = [date('Y')];
$search[] = '{$counter}';
$replace[] = str_pad($counter, $this->getSettingsByKey( 'counter_padding' )->counter_padding, '0', STR_PAD_LEFT);
if (strstr($pattern, '{$user_id}')) {
$user_id = $entity->user ? $entity->user->id : (auth()->check() ? auth()->user()->id : 0);
$search[] = '{$user_id}';
$replace[] = str_pad(($user_id + 1), 2, '0', STR_PAD_LEFT);
}
$matches = false;
preg_match('/{\$date:(.*?)}/', $pattern, $matches);
if (count($matches) > 1) {
$format = $matches[1];
$search[] = $matches[0];
$date = Carbon::now($this->company->timezone()->name)->format($format);
$replace[] = str_replace($format, $date, $matches[1]);
}
$pattern = str_replace($search, $replace, $pattern);
$pattern = $this->getClientInvoiceNumber($pattern, $entity);
return $pattern;
}
} }

View File

@ -37,7 +37,7 @@ class GenerateNumberTest extends TestCase
public function testEntityName() public function testEntityName()
{ {
$this->assertEquals($this->entity_name(Client::class), 'client'); $this->assertEquals($this->entityName(Client::class), 'client');
} }