Invoice testing and line item catchup

This commit is contained in:
Deon George
2020-02-12 21:32:57 +11:00
parent f41fc3eb9c
commit 5cc0dcd8e1
9 changed files with 146 additions and 42 deletions

View File

@@ -14,12 +14,18 @@ class Product extends Model
const RECORD_ID = 'product';
public $incrementing = FALSE;
protected $table = 'ab_product';
protected $with = ['descriptions'];
const CREATED_AT = 'date_orig';
const UPDATED_AT = 'date_last';
public $dateFormat = 'U';
protected $table = 'ab_product';
protected $casts = [
// @todo convert existing data to a json array
// 'price_group'=>'array',
];
protected $with = ['descriptions'];
public function descriptions()
{
@@ -126,7 +132,7 @@ class Product extends Model
public function getPriceArrayAttribute()
{
return unserialize($this->price_group);
return unserialize($this->attributes['price_group']);
}
public function getPriceTypeAttribute()

View File

@@ -43,7 +43,7 @@ class Service extends Model
protected $dates = [
'date_last_invoice',
'date_next_invoice'.
'date_next_invoice',
'date_start',
'date_end',
];
@@ -324,15 +324,17 @@ class Service extends Model
/**
* Return the date for the next invoice
*
* @todo This function negates the need for date_next_invoice
* @todo Change date_next_invoice to connect_date/invoice_start_date
* @return Carbon|string
*/
public function getInvoiceNextAttribute()
{
$last = $this->getInvoiceToAttribute();
$date = $last ? $last->addDay() : Carbon::now();
$date = $last
? $last->addDay()
: ($this->date_next_invoice ? $this->date_next_invoice->clone() : Carbon::now());
return request()->wantsJson() ? $date->format('Y-m-d') : $date;
return $date;
}
/**
@@ -450,7 +452,7 @@ class Service extends Model
*/
public function getInvoiceToAttribute()
{
return $this->invoice_items->count() ? $this->invoice_items->last()->date_stop : NULL;
return ($x=$this->invoice_items->filter(function($item) { return $item->item_type === 0;}))->count() ? $x->last()->date_stop : NULL;
}
public function getNameAttribute(): string
@@ -590,7 +592,9 @@ class Service extends Model
*/
public function getSDescAttribute(): string
{
return $this->type->service_description ?: 'Service Description NOT Defined for :'.$this->type->type;
return ($this->type AND $this->type->service_description)
? $this->type->service_description
: 'Service Description NOT Defined for :'.($this->type ? $this->type->type : $this->id);
}
/**
@@ -605,7 +609,9 @@ class Service extends Model
*/
public function getSNameAttribute(): string
{
return $this->type->service_name ?: 'Service Name NOT Defined for :'.$this->type->type;
return ($this->type AND $this->type->service_name)
? $this->type->service_name
: 'Service Name NOT Defined for :'.($this->type ? $this->type->type : $this->id);
}
/**
@@ -770,35 +776,22 @@ class Service extends Model
* @return Collection
* @throws Exception
*/
public function next_invoice_items(): Collection
public function next_invoice_items(bool $future): Collection
{
$result = collect();
$o = new InvoiceItem;
// If the service is active, there will be service charges
if ($this->active or $this->isPending()) {
$o->active = TRUE;
$o->service_id = $this->id;
$o->product_id = $this->product_id;
$o->item_type = 0;
$o->price_base = $this->price ?: $this->product->price($this->recur_schedule); // @todo change to a method in this class
$o->recurring_schedule = $this->recur_schedule;
$o->date_start = $this->invoice_next;
$o->date_stop = $this->invoice_next_end;
$o->quantity = $this->invoice_next_quantity;
$o->addTaxes($this->account->country->taxes);
$result->push($o);
}
if ($this->wasCancelled())
return collect();
// If pending, add any connection charges
if ($this->isPending()) {
// Connection charges are only charged once
if ((! $this->invoice_items->filter(function($item) { return $item->item_type==4; })->sum('total'))
AND ($this->isPending() OR is_null($this->invoice_to)))
{
$o = new InvoiceItem;
$o->active = TRUE;
$o->service_id = $this->id;
$o->product_id = $this->product_id;
$o->item_type = 4;
$o->item_type = 4; // @todo change to const or something
$o->price_base = $this->price ?: $this->product->price($this->recur_schedule,'price_setup'); // @todo change to a method in this class
//$o->recurring_schedule = $this->recur_schedule;
$o->date_start = $this->invoice_next;
@@ -806,7 +799,26 @@ class Service extends Model
$o->quantity = 1;
$o->addTaxes($this->account->country->taxes);
$result->push($o);
$this->invoice_items->push($o);
}
// If the service is active, there will be service charges
if ($this->active OR $this->isPending()) {
do {
$o = new InvoiceItem;
$o->active = TRUE;
$o->service_id = $this->id;
$o->product_id = $this->product_id;
$o->item_type = 0;
$o->price_base = $this->price ?: $this->product->price($this->recur_schedule); // @todo change to a method in this class
$o->recurring_schedule = $this->recur_schedule;
$o->date_start = $this->invoice_next;
$o->date_stop = $this->invoice_next_end;
$o->quantity = $this->invoice_next_quantity;
$o->addTaxes($this->account->country->taxes);
$this->invoice_items->push($o);
} while ($future == FALSE AND ($this->invoice_to < Carbon::now()->addDays(30)));
}
// Add additional charges
@@ -824,10 +836,10 @@ class Service extends Model
$o->module_ref = $oo->id;
$o->addTaxes($this->account->country->taxes);
$result->push($o);
$this->invoice_items->push($o);
}
return $result;
return $this->invoice_items->filter(function($item) { return ! $item->exists; });
}
/**
@@ -887,4 +899,14 @@ class Service extends Model
{
return $this->testNextStatusValid($status);
}
/**
* Service that was cancelled or never provisioned
*
* @return bool
*/
public function wasCancelled(): bool
{
return in_array($this->order_status,$this->inactive_status);
}
}