diff --git a/app/Http/Controllers/AdminController.php b/app/Http/Controllers/AdminController.php
index ea34afa..fa2a1d0 100644
--- a/app/Http/Controllers/AdminController.php
+++ b/app/Http/Controllers/AdminController.php
@@ -97,7 +97,7 @@ class AdminController extends Controller
if (collect($value)->sum() > $request->post('total_amt'))
$fail('Allocation is greater than payment total.');
}],
- 'invoices.*.id' => 'nullable|exists:ab_invoice,id',
+ 'invoices.*.id' => 'nullable|exists:invoices,id',
]);
if (! $o->exists) {
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 0984756..28f0fef 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -54,7 +54,7 @@ class HomeController extends Controller
*/
public function invoice_pdf(Invoice $o)
{
- return PDF::loadView('u.invoice.home',['o'=>$o])->stream(sprintf('%s.pdf',$o->invoice_account_id));
+ return PDF::loadView('u.invoice.home',['o'=>$o])->stream(sprintf('%s.pdf',$o->sid));
}
/**
diff --git a/app/Http/Controllers/User/AccountController.php b/app/Http/Controllers/User/AccountController.php
index add8640..7655282 100644
--- a/app/Http/Controllers/User/AccountController.php
+++ b/app/Http/Controllers/User/AccountController.php
@@ -24,13 +24,13 @@ class AccountController extends Controller
});
// Get our invoice due date for this invoice
- $io->due_date = $s->min(function($item) { return $item->invoice_next; });
+ $io->due_at = $s->min(function($item) { return $item->invoice_next; });
// @todo The days in advance is an application parameter
- $io->date_orig = $io->due_date->subDays(30);
+ $io->created_at = $io->due_at->subDays(30);
// Work out items to add to this invoice, plus any in the next additional days
- $days = now()->diffInDays($io->due_date)+1+7;
+ $days = now()->diffInDays($io->due_at)+1+7;
foreach ($s as $so)
{
if ($so->isInvoiceDueSoon($days))
diff --git a/app/Mail/InvoiceEmail.php b/app/Mail/InvoiceEmail.php
index cc3bba8..1dfdbb6 100644
--- a/app/Mail/InvoiceEmail.php
+++ b/app/Mail/InvoiceEmail.php
@@ -38,7 +38,7 @@ class InvoiceEmail extends Mailable
->subject(sprintf( 'Invoice: %s - Total: $%s - Due: %s',
$this->invoice->id,
number_format($this->invoice->total,2),
- $this->invoice->date_due))
+ $this->invoice->due_at->format('Y-m-d')))
->with([
'user'=>$this->invoice->account->user,
'site'=>$this->invoice->account->user->site,
diff --git a/app/Models/Invoice.php b/app/Models/Invoice.php
index e67934b..3ff2033 100644
--- a/app/Models/Invoice.php
+++ b/app/Models/Invoice.php
@@ -25,7 +25,7 @@ use App\Traits\{NextKey,PushNew};
* + paid_date : Date the invoice was paid in full
* + paid_pending : Total of pending payments received
* + sid : System ID for invoice
- * + total_sub : Invoice sub-total before taxes
+ * + sub_total : Invoice sub-total before taxes
* + total_tax : Invoices total of taxes
* + total : Invoice total
*
@@ -33,17 +33,11 @@ use App\Traits\{NextKey,PushNew};
*/
class Invoice extends Model implements IDs
{
- use NextKey,PushNew,ScopeActive;
+ use PushNew,ScopeActive;
- const RECORD_ID = 'invoice';
- public $incrementing = FALSE;
-
- protected $table = 'ab_invoice';
- const CREATED_AT = 'date_orig';
- const UPDATED_AT = 'date_last';
-
- protected $dates = ['date_orig','due_date'];
- public $dateFormat = 'U';
+ protected $dates = [
+ 'due_at',
+ ];
public const BILL_WEEKLY = 0;
public const BILL_MONTHLY = 1;
@@ -56,45 +50,44 @@ class Invoice extends Model implements IDs
public const BILL_FIVEYEARS = 8;
/* Our available billing periods */
- // @todo change this to a function - with billing_name()?
public const billing_periods = [
- 0 => [
- 'name' => 'Weekly',
- 'interval' => 0.25,
- ],
- 1 => [
- 'name' => 'Monthly',
- 'interval' => 1,
- ],
- 2 => [
- 'name' => 'Quarterly',
- 'interval' => 3,
- ],
- 3 => [
- 'name' => 'Semi-Annually',
- 'interval' => 6,
- ],
- 4 => [
- 'name' => 'Annually',
- 'interval' => 12,
- ],
- 5 => [
- 'name' => 'Two years',
- 'interval' => 24,
- ],
- 6 => [
- 'name' => 'Three Years',
- 'interval' => 36,
- ],
- 7 => [
- 'name' => 'Four Years',
- 'interval' => 48,
- ],
- 8 => [
- 'name' => 'Five Years',
- 'interval' => 60,
- ],
- ];
+ self::BILL_WEEKLY => [
+ 'name' => 'Weekly',
+ 'interval' => 0.25,
+ ],
+ self::BILL_MONTHLY => [
+ 'name' => 'Monthly',
+ 'interval' => 1,
+ ],
+ self::BILL_QUARTERLY => [
+ 'name' => 'Quarterly',
+ 'interval' => 3,
+ ],
+ self::BILL_SEMI_YEARLY => [
+ 'name' => 'Semi-Annually',
+ 'interval' => 6,
+ ],
+ self::BILL_YEARLY => [
+ 'name' => 'Annually',
+ 'interval' => 12,
+ ],
+ self::BILL_TWOYEARS => [
+ 'name' => 'Two years',
+ 'interval' => 24,
+ ],
+ self::BILL_THREEYEARS => [
+ 'name' => 'Three Years',
+ 'interval' => 36,
+ ],
+ self::BILL_FOURYEARS => [
+ 'name' => 'Four Years',
+ 'interval' => 48,
+ ],
+ SELF::BILL_FIVEYEARS => [
+ 'name' => 'Five Years',
+ 'interval' => 60,
+ ],
+ ];
// Array of items that can be updated with PushNew
protected $pushable = ['items'];
@@ -164,6 +157,28 @@ class Invoice extends Model implements IDs
return ceil(($contract_term ?: 1)/(Arr::get(self::billing_periods,$source.'.interval') ?: 1));
}
+ /* INTERFACES */
+
+ /**
+ * Invoice Local ID
+ *
+ * @return string
+ */
+ public function getLIDAttribute(): string
+ {
+ return sprintf('%06s',$this->id);
+ }
+
+ /**
+ * Invoice System ID
+ *
+ * @return string
+ */
+ public function getSIDAttribute(): string
+ {
+ return sprintf('%02s-%04s-%s',$this->site_id,$this->account_id,$this->getLIDAttribute());
+ }
+
/* RELATIONS */
public function account()
@@ -206,7 +221,7 @@ class Invoice extends Model implements IDs
/**
* Balance due on an invoice
- * @return string
+ * @return float
*/
public function getDueAttribute(): float
{
@@ -215,11 +230,11 @@ class Invoice extends Model implements IDs
/**
* @return mixed
- * @deprecated use self::due_date;
+ * @todo Change references to due_at to use due_date
*/
- public function getDateDueAttribute()
+ public function getDueDateAttribute(): Carbon
{
- return $this->due_date->format('Y-m-d');
+ return $this->due_at;
}
/**
@@ -229,17 +244,7 @@ class Invoice extends Model implements IDs
*/
public function getInvoiceDateAttribute(): Carbon
{
- return $this->date_orig;
- }
-
- /**
- * Get account System ID
- * @return string
- * @deprecated use getSIDAttribute()
- */
- public function getInvoiceAccountIdAttribute()
- {
- return $this->getSIDAttribute();
+ return $this->created_at;
}
// @todo Move this to a site configuration
@@ -248,16 +253,6 @@ class Invoice extends Model implements IDs
return sprintf('Thank you for using %s for your Internet Services.',config('site')->site_name);
}
- /**
- * Invoice Local ID
- *
- * @return string
- */
- public function getLIDAttribute(): string
- {
- return sprintf('%06s',$this->id);
- }
-
/**
* Total of payments received for this invoice
* excluding pending payments
@@ -286,7 +281,7 @@ class Invoice extends Model implements IDs
->filter(function($item) { return ! $item->pending_status; })
->last();
- return $o ? $o->payment_date : NULL;
+ return $o?->payment_date;
}
/**
@@ -301,44 +296,12 @@ class Invoice extends Model implements IDs
->sum('alloc_amt');
}
- /**
- * Total of pending payments received for this invoice
- *
- * @return mixed
- * @deprecated use getPaidPendingAttribute()
- */
- public function getPendingPaidAttribute(): float
- {
- return $this->getPaidPendingAttribute();
- }
-
- /**
- * Invoice System ID
- *
- * @return string
- */
- public function getSIDAttribute(): string
- {
- return sprintf('%02s-%04s-%s',$this->site_id,$this->account_id,$this->getLIDAttribute());
- }
-
/**
* Get invoice subtotal before taxes
*
* @return float
- * @deprecated use getTotalSubAttribute()
*/
public function getSubTotalAttribute(): float
- {
- return $this->getTotalSubAttribute();
- }
-
- /**
- * Get invoice subtotal before taxes
- *
- * @return float
- */
- public function getTotalSubAttribute(): float
{
return $this->items->where('active',TRUE)->sum('sub_total');
}
@@ -371,9 +334,12 @@ class Invoice extends Model implements IDs
*/
public function getTotalAttribute(): float
{
- return $this->getTotalSubAttribute()+$this->getTotalTaxAttribute();
+ return $this->getSubTotalAttribute()+$this->getTotalTaxAttribute();
}
+ /* METHODS */
+
+ // @todo This shouldnt be here - current should be handled at an account level.
public function currency()
{
return $this->account->country->currency;
@@ -389,7 +355,7 @@ class Invoice extends Model implements IDs
// Re-use an existing code
$io = Invite::where('for',$this->account->user->email)->first();
- $tokendate = ($x=Carbon::now()->addDays(21)) > ($y=$this->due_date->addDays(21)) ? $x : $y;
+ $tokendate = ($x=Carbon::now()->addDays(21)) > ($y=$this->due_at->addDays(21)) ? $x : $y;
// Extend the expire date
if ($io AND ($tokendate > $io->valid_until)) {
@@ -402,12 +368,12 @@ class Invoice extends Model implements IDs
return url('u/invoice',[$this->id,'email',$code]);
}
+ // @todo document
public function products()
{
$return = collect();
- foreach ($this->items->groupBy('product_id') as $o)
- {
+ foreach ($this->items->groupBy('product_id') as $o) {
$po = $o->first()->product;
$po->count = count($o->pluck('service_id')->unique());
@@ -419,6 +385,7 @@ class Invoice extends Model implements IDs
});
}
+ // @todo document
public function product_services(Product $po)
{
$return = collect();
@@ -436,6 +403,7 @@ class Invoice extends Model implements IDs
return $return->unique()->sortBy('name');
}
+ // @todo document
public function product_service_items(Product $po,Service $so)
{
return $this->items->filter(function ($item) use ($po,$so) {
@@ -449,28 +417,28 @@ class Invoice extends Model implements IDs
* @todo Ugly hack to update reminders
*/
public function reminders(string $key) {
- $r = unserialize($this->reminders);
+ $r = json_decode($this->reminders);
if (! Arr::get($r,$key)) {
$r[$key] = time();
- return serialize($r);
+ return json_encode($r);
}
}
/**
- * Automatically set our due_date at save time.
+ * Automatically set our due_at at save time.
*
* @param array $options
* @return bool
*/
public function save(array $options = []) {
// Automatically set the date_due attribute for new records.
- if (! $this->exists AND ! $this->due_date) {
- $this->due_date = $this->items->min('date_start');
+ if (! $this->exists AND ! $this->due_at) {
+ $this->due_at = $this->items->min('start_at');
// @todo This 7 days should be sysetm configurable
- if (($x=Carbon::now()->addDay(7)) > $this->due_date)
- $this->due_date = $x;
+ if (($x=Carbon::now()->addDay(7)) > $this->due_at)
+ $this->due_at = $x;
}
return parent::save($options);
diff --git a/app/Models/InvoiceItem.php b/app/Models/InvoiceItem.php
index 0425c0c..becc6d7 100644
--- a/app/Models/InvoiceItem.php
+++ b/app/Models/InvoiceItem.php
@@ -5,9 +5,8 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
-use Leenooks\Carbon;
+use Leenooks\Carbon as LeenooksCarbon;
-use App\Traits\NextKey;
use App\Traits\PushNew;
/**
@@ -15,24 +14,18 @@ use App\Traits\PushNew;
* Items that belong on an invoice
*
* Attributes for services:
- * + date_start : Start date
- * + date_stop : End date
* + sub_total : Value of item
* + tax : Total of all taxes
* + total : Total including taxes
*/
class InvoiceItem extends Model
{
- use NextKey,PushNew;
- const RECORD_ID = 'invoice_item';
- public $incrementing = FALSE;
+ use PushNew;
- protected $table = 'ab_invoice_item';
- const CREATED_AT = 'date_orig';
- const UPDATED_AT = 'date_last';
-
- protected $dates = ['date_start','date_stop'];
- public $dateFormat = 'U';
+ protected $dates = [
+ 'start_at',
+ 'stop_at',
+ ];
// Array of items that can be updated with PushNew
protected $pushable = ['taxes'];
@@ -60,11 +53,6 @@ class InvoiceItem extends Model
return $this->belongsTo(Invoice::class);
}
- /**
- * Product for this item
- *
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
- */
public function product()
{
return $this->belongsTo(Product::class);
@@ -82,73 +70,51 @@ class InvoiceItem extends Model
/* ATTRIBUTES */
- /**
- * Start date for the invoice item line
- *
- * @param $value
- * @return Carbon
- * @throws \Exception
- */
- public function getDateStartAttribute($value)
- {
- if (! is_null($value))
- return Carbon::createFromTimestamp($value);
- }
-
- /**
- * End date for the invoice item line
- *
- * @param $value
- * @return Carbon
- * @throws \Exception
- */
- public function getDateStopAttribute($value)
- {
- if (! is_null($value))
- return Carbon::createFromTimestamp($value);
- }
-
public function getItemTypeNameAttribute()
{
- // @todo use self::type
- $types = [
- 1=>'Hardware', // *
- 2=>'Service Relocation Fee', // * Must have corresponding SERVICE_ID
- 3=>'Service Change', // * Must have corresponding SERVICE_ID
- 4=>'Service Connection', // * Must have corresponding SERVICE_ID
- 6=>'Service Cancellation', // * Must have corresponding SERVICE_ID
- 7=>'Extra Product/Service Charge', // * Service Billing in advance, Must have corresponding SERVICE_ID
- 8=>'Product Addition', // * Additional Product Customisation, Must have corresponding SERVICE_ID
- 120=>'Credit/Debit Transfer', // * SERVICE_ID is NULL, MODULE_ID is NULL, MODULE_REF is NULL : INVOICE_ID is NOT NULL
- 123=>'Shipping',
- 124=>'Late Payment Fee', // * SERVICE_ID is NULL, MODULE_ID = CHECKOUT MODULE,
- 125=>'Payment Fee', // * SERVICE_ID is NULL, MODULE_ID = CHECKOUT MODULE, MODULE_REF = CHECKOUT NAME
- 126=>'Other', // * MODEL_ID should be a module
- 127=>'Rounding', // * SERVICE_ID is NULL, MODULE_ID is NULL, MODULE_REF is NULL
- ];
-
- switch ($this->item_type)
- {
+ switch ($this->item_type) {
// * Line Charge Topic on Invoice.
case 0:
- if ($this->date_start)
+ if ($this->start_at)
return sprintf('%s [%s]','Product/Service',
- (($this->date_start == $this->date_stop) || (! $this->date_stop)) ? $this->date_start->format('Y-m-d') : sprintf('%s -> %s',$this->date_start->format('Y-m-d'),$this->date_stop->format('Y-m-d')));
+ (($this->start_at == $this->stop_at) || (! $this->stop_at)) ? $this->start_at->format('Y-m-d') : sprintf('%s -> %s',$this->start_at->format('Y-m-d'),$this->stop_at->format('Y-m-d')));
else
return 'Product/Service';
// * Excess Service Item, of item 0, must have corresponding SERVICE_ID
case 5:
return sprintf('%s [%s] (%s)','Excess Usage',
- $this->date_start == $this->date_stop ? $this->date_start->format('Y-m-d') : sprintf('%s -> %s',$this->date_start->format('Y-m-d'),$this->date_stop->format('Y-m-d')),
+ $this->start_at == $this->stop_at ? $this->start_at->format('Y-m-d') : sprintf('%s -> %s',$this->start_at->format('Y-m-d'),$this->stop_at->format('Y-m-d')),
$this->module_text()
);
default:
- return ($this->module_id == 30 ? 'Additional Charge: ' : '').Arr::get($types,$this->item_type,'Unknown');
+ return ($this->module_id == 30 ? 'Additional Charge: ' : '').Arr::get(self::type,$this->item_type,'Unknown');
}
}
+ /**
+ * We need to cast some dates to LeenooksCarbon to get access to startOfHalf()/endOfHalf() methods
+ *
+ * @param $value
+ * @return LeenooksCarbon
+ */
+ public function getStartAtAttribute($value): LeenooksCarbon
+ {
+ return LeenooksCarbon::create($value);
+ }
+
+ /**
+ * We need to cast some dates to LeenooksCarbon to get access to startOfHalf()/endOfHalf() methods
+ *
+ * @param $value
+ * @return LeenooksCarbon
+ */
+ public function getStopAtAttribute($value): LeenooksCarbon
+ {
+ return LeenooksCarbon::create($value);
+ }
+
/**
* Sub total of item
*
@@ -190,8 +156,7 @@ class InvoiceItem extends Model
if ($this->exists)
throw new \Exception('Refusing to add Taxes to existing record');
- foreach($taxes as $to)
- {
+ foreach($taxes as $to) {
$iit = new InvoiceItemTax;
$iit->tax_id = $to->id;
$iit->amount = round($this->quantity*$this->price_base*$to->rate,3);
@@ -200,15 +165,12 @@ class InvoiceItem extends Model
}
}
- public function module_text()
- {
- switch ($this->module_id)
- {
+ public function module_text(){
+ switch ($this->module_id) {
// Charges Module
case 30: return Charge::findOrFail($this->module_ref)->name;
default: abort(500,'Unable to handle '.$this->module_id);
}
-
}
}
\ No newline at end of file
diff --git a/app/Models/InvoiceItemTax.php b/app/Models/InvoiceItemTax.php
index eb01ca7..2030070 100644
--- a/app/Models/InvoiceItemTax.php
+++ b/app/Models/InvoiceItemTax.php
@@ -4,23 +4,12 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
-use App\Traits\NextKey;
use App\Traits\PushNew;
class InvoiceItemTax extends Model
{
- use NextKey,PushNew;
- const RECORD_ID = 'invoice_item_tax';
- public $incrementing = FALSE;
+ use PushNew;
- protected $table = 'ab_invoice_item_tax';
- const CREATED_AT = 'date_orig';
- const UPDATED_AT = NULL;
-
- public $dateFormat = 'U';
-
- public function invoice_item()
- {
- return $this->belongsTo(InvoiceItem::class);
- }
+ protected $table = 'invoice_item_taxes';
+ public $timestamps = FALSE;
}
\ No newline at end of file
diff --git a/app/Models/Service.php b/app/Models/Service.php
index c175b6e..083ce95 100644
--- a/app/Models/Service.php
+++ b/app/Models/Service.php
@@ -318,7 +318,7 @@ class Service extends Model implements IDs
{
$query = $this->hasMany(InvoiceItem::class)
->where('item_type','=',0)
- ->orderBy('date_start');
+ ->orderBy('start_at');
// @todo Change to $query->active();
if ($active)
@@ -334,14 +334,14 @@ class Service extends Model implements IDs
{
$query = $this->hasManyThrough(Invoice::class,InvoiceItem::class,NULL,'id',NULL,'invoice_id')
->distinct('id')
- ->where('ab_invoice.site_id','=',$this->site_id)
- ->where('ab_invoice_item.site_id','=',$this->site_id)
- ->orderBy('date_orig')
- ->orderBy('due_date');
+ ->where('invoices.site_id','=',$this->site_id)
+ ->where('invoice_items.site_id','=',$this->site_id)
+ ->orderBy('created_at')
+ ->orderBy('due_at');
if ($active)
- $query->where('ab_invoice_item.active','=',TRUE)
- ->where('ab_invoice.active','=',TRUE);
+ $query->where('invoice_items.active','=',TRUE)
+ ->where('invoices.active','=',TRUE);
return $query;
}
@@ -469,49 +469,7 @@ class Service extends Model implements IDs
*/
public function getBillingMonthlyPriceAttribute(): float
{
- $d = 1;
- switch ($this->recur_schedule) {
- case Invoice::BILL_WEEKLY:
- $d = 12/52;
- break;
-
- case Invoice::BILL_MONTHLY:
- $d = 1;
- break;
-
- case Invoice::BILL_QUARTERLY:
- $d = 3;
- break;
-
- case Invoice::BILL_SEMI_YEARLY:
- $d = 6;
- break;
-
- case Invoice::BILL_YEARLY:
- $d = 12;
- break;
-
- case Invoice::BILL_TWOYEARS:
- $d = 24;
- break;
-
- case Invoice::BILL_THREEYEARS:
- $d = 36;
- break;
-
- case Invoice::BILL_FOURYEARS:
- $d = 48;
- break;
-
- case Invoice::BILL_FIVEYEARS:
- $d = 60;
- break;
-
- default:
- throw new Exception('Unknown recur_schedule');
- }
-
- return number_format($this->getBillingChargeAttribute()/$d,2);
+ return number_format($this->getBillingChargeAttribute()/Arr::get(Invoice::billing_periods,$this->recur_schedule.'.interval',1),2);
}
/**
@@ -593,7 +551,18 @@ class Service extends Model implements IDs
$last = $this->getInvoiceToAttribute();
return $last
? $last->addDay()
- : ($this->date_next_invoice ? $this->date_next_invoice->clone() : ($this->start_at ?: LeenooksCarbon::now()));
+ : ($this->invoice_next_at ? $this->invoice_next_at->clone() : ($this->start_at ?: LeenooksCarbon::now()));
+ }
+
+ /**
+ * We need to cast some dates to LeenooksCarbon to get access to startOfHalf()/endOfHalf() methods
+ *
+ * @param $value
+ * @return LeenooksCarbon|null
+ */
+ public function getInvoiceNextAtAttribute($value): ?LeenooksCarbon
+ {
+ return $value ? LeenooksCarbon::create($value) : NULL;
}
/**
@@ -674,7 +643,7 @@ class Service extends Model implements IDs
}
/**
- * Determine how much quantity (at the charge rate) is requite for the next invoice
+ * Determine how much quantity (at the charge rate) is required for the next invoice
*
* @return float
* @throws Exception
@@ -734,12 +703,12 @@ class Service extends Model implements IDs
/**
* Get the date that the service has been invoiced to
*
- * @return Carbon|null
+ * @return LeenooksCarbon|null
*/
- public function getInvoiceToAttribute(): ?Carbon
+ public function getInvoiceToAttribute(): ?LeenooksCarbon
{
$result = ($x=$this->invoice_items->filter(function($item) { return $item->item_type === 0;}))->count()
- ? $x->last()->date_stop
+ ? $x->last()->stop_at
: NULL;
// For SSL Certificates, the invoice_to date is the expiry date of the Cert
@@ -823,7 +792,7 @@ class Service extends Model implements IDs
return $item->item_type === 0;
})
->last()
- ->date_stop;
+ ->stop_at;
}
/**
@@ -1228,8 +1197,8 @@ class Service extends Model implements IDs
$o->item_type = 4; // @todo change to const or something
$o->price_base = $this->product->getSetupChargeAttribute($this->recur_schedule,$this->account->group);
//$o->recurring_schedule = $this->recur_schedule;
- $o->date_start = $this->invoice_next;
- $o->date_stop = $this->invoice_next;
+ $o->start_at = $this->invoice_next;
+ $o->stop_at = $this->invoice_next;
$o->quantity = 1;
$o->site_id = 1; // @todo
@@ -1254,9 +1223,9 @@ class Service extends Model implements IDs
$o->price_base = is_null($this->price)
? (is_null($this->price_override) ? $this->product->getBaseChargeAttribute($this->recur_schedule,$this->account->group) : $this->price_override)
: $this->price; // @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->recur_schedule = $this->recur_schedule;
+ $o->start_at = $this->invoice_next;
+ $o->stop_at = $this->invoice_next_end;
$o->quantity = $this->invoice_next_quantity;
$o->site_id = 1; // @todo
@@ -1277,8 +1246,8 @@ class Service extends Model implements IDs
$o->quantity = $oo->quantity;
$o->item_type = $oo->type;
$o->price_base = $oo->amount;
- $o->date_start = $oo->date_charge;
- $o->date_stop = $oo->date_charge;
+ $o->start_at = $oo->date_charge;
+ $o->stop_at = $oo->date_charge;
$o->module_id = 30; // @todo This shouldnt be hard coded
$o->module_ref = $oo->id;
$o->site_id = 1; // @todo
diff --git a/app/Models/Service/SSL.php b/app/Models/Service/SSL.php
index bd1e622..91ed9d6 100644
--- a/app/Models/Service/SSL.php
+++ b/app/Models/Service/SSL.php
@@ -4,6 +4,7 @@ namespace App\Models\Service;
use Carbon\Carbon;
use Illuminate\Support\Arr;
+use Leenooks\Carbon as LeenooksCarbon;
/**
* Class SSL (Service)
@@ -76,9 +77,9 @@ class SSL extends Type
/**
* Return the Certificate Expiry Date
*/
- public function getServiceExpireAttribute(): ?Carbon
+ public function getServiceExpireAttribute(): ?LeenooksCarbon
{
- return $this->cert ? Carbon::createFromTimestamp($this->crt_parse->get('validTo_time_t')) : NULL;
+ return $this->cert ? LeenooksCarbon::createFromTimestamp($this->crt_parse->get('validTo_time_t')) : NULL;
}
/**
diff --git a/app/Models/Service/Type.php b/app/Models/Service/Type.php
index 070e1d6..c953a2e 100644
--- a/app/Models/Service/Type.php
+++ b/app/Models/Service/Type.php
@@ -2,8 +2,8 @@
namespace App\Models\Service;
-use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
+use Leenooks\Carbon as LeenooksCarbon;
use App\Interfaces\ServiceItem;
use App\Models\{Account,Service};
@@ -63,7 +63,7 @@ abstract class Type extends Model implements ServiceItem
return $this->service->offering->contract_term;
}
- public function getServiceExpireAttribute(): ?Carbon
+ public function getServiceExpireAttribute(): ?LeenooksCarbon
{
return $this->expire_at ?: $this->service->invoice_next_at;
}
@@ -80,6 +80,17 @@ abstract class Type extends Model implements ServiceItem
/* ATTRIBUTES */
+ /**
+ * We need to cast some dates to LeenooksCarbon to get access to startOfHalf()/endOfHalf() methods
+ *
+ * @param $value
+ * @return LeenooksCarbon
+ */
+ public function getExpireAtAttribute($value): LeenooksCarbon
+ {
+ return LeenooksCarbon::create($value);
+ }
+
public function getTypeAttribute()
{
return strtolower((new \ReflectionClass($this))->getShortName());
diff --git a/app/Models/User.php b/app/Models/User.php
index b2e54f8..accb285 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -333,16 +333,16 @@ class User extends Authenticatable implements IDs
*/
private function query_invoice_items()
{
- return DB::table('ab_invoice_item')
+ return DB::table('invoice_items')
->select([
'invoice_id',
- DB::raw('ab_invoice_item.id AS invoice_item_id'),
- DB::raw('IFNULL(ab_invoice_item.discount_amt,0) AS discount'),
+ DB::raw('invoice_items.id AS invoice_item_id'),
+ DB::raw('IFNULL(invoice_items.discount_amt,0) AS discount'),
DB::raw('ROUND(CAST(quantity*price_base AS decimal(8,2)),2) AS base'),
- DB::raw('ROUND(ab_invoice_item_tax.amount,2) AS tax'),
+ DB::raw('ROUND(invoice_item_taxes.amount,2) AS tax'),
])
- ->leftjoin('ab_invoice_item_tax',['ab_invoice_item_tax.invoice_item_id'=>'ab_invoice_item.id'])
+ ->leftjoin('invoice_item_taxes',['invoice_item_taxes.invoice_item_id'=>'invoice_items.id'])
->where('active',TRUE);
}
@@ -382,9 +382,9 @@ class User extends Authenticatable implements IDs
DB::raw('false AS payment_fees'),
])
->from($this->query_invoice_items(),'II')
- ->join('ab_invoice',['ab_invoice.id'=>'II.invoice_id'])
+ ->join('invoices',['invoices.id'=>'II.invoice_id'])
->whereIN('account_id',$this->accounts->pluck('id'))
- ->where('ab_invoice.active',TRUE)
+ ->where('invoices.active',TRUE)
->groupBy(['invoice_id']);
$payments = (new Payment)
@@ -420,8 +420,8 @@ class User extends Authenticatable implements IDs
->select([
'account_id',
'id',
- 'due_date',
- 'date_orig',
+ 'due_at',
+ 'created_at',
'discount',
'invoice_base',
'invoice_tax',
@@ -430,7 +430,7 @@ class User extends Authenticatable implements IDs
'payment_fees',
DB::raw('ROUND(invoice_total-payments,2) AS balance'),
])
- ->join('ab_invoice',['ab_invoice.id'=>'invoice_id'])
+ ->join('invoices',['invoices.id'=>'invoice_id'])
->with(['items.taxes'])
->from($summary,'summary');
}
diff --git a/database/migrations/2022_04_22_122640_rename_invoice_tables.php b/database/migrations/2022_04_22_122640_rename_invoice_tables.php
new file mode 100644
index 0000000..1ef1eaa
--- /dev/null
+++ b/database/migrations/2022_04_22_122640_rename_invoice_tables.php
@@ -0,0 +1,124 @@
+dropPrimary();
+ $table->dropForeign('ab_invoice_site_id_foreign');
+ $table->dropIndex('ab_invoice_site_id_foreign');
+ $table->primary(['id','site_id']);
+ $table->dropIndex('ab_invoice_id_site_id_index');
+ $table->datetime('created_at')->nullable()->after('id');
+ $table->datetime('updated_at')->nullable()->after('created_at');
+ $table->date('due_at')->nullable()->after('discount_amt');
+ });
+
+ // Convert out dates
+ foreach (\App\Models\Invoice::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->cursor() as $o) {
+ if ($o->date_orig)
+ $o->created_at = \Carbon\Carbon::createFromTimestamp($o->date_orig);
+ if ($o->date_last)
+ $o->updated_at = \Carbon\Carbon::createFromTimestamp($o->date_last);
+ if ($o->due_date)
+ $o->due_at = \Carbon\Carbon::createFromTimestamp($o->due_date);
+ if ($o->reminders) {
+ try {
+ $reminders = unserialize($o->reminders);
+ } catch (Exception $e) {
+ $reminders = unserialize(gzuncompress($o->reminders));
+ }
+
+ $o->reminders = $reminders;
+ }
+ $o->save();
+ }
+
+ Schema::table('invoices', function (Blueprint $table) {
+ $table->dropColumn(['date_orig','date_last','due_date']);
+
+ $table->foreign(['account_id','site_id'])->references(['id','site_id'])->on('accounts');
+ });
+
+ DB::statement('ALTER TABLE ab_invoice_item RENAME TO invoice_items');
+ DB::statement('ALTER TABLE invoice_items MODIFY invoice_id int unsigned NOT NULL');
+ DB::statement('ALTER TABLE invoice_items MODIFY service_id int unsigned DEFAULT NULL');
+ DB::statement('ALTER TABLE invoice_items MODIFY product_id int unsigned DEFAULT NULL');
+ DB::statement('ALTER TABLE invoice_items MODIFY module_id int unsigned DEFAULT NULL');
+ DB::statement('ALTER TABLE invoice_items MODIFY module_ref int unsigned DEFAULT NULL');
+ DB::statement('ALTER TABLE invoice_items RENAME COLUMN recurring_schedule TO recur_schedule');
+
+ Schema::table('invoice_items', function (Blueprint $table) {
+ $table->dropPrimary();
+ $table->dropForeign('ab_invoice_item_site_id_foreign');
+ $table->dropIndex('ab_invoice_item_site_id_foreign');
+ $table->primary(['id','site_id']);
+ $table->dropIndex('ab_invoice_item_id_site_id_index');
+ $table->datetime('created_at')->nullable()->after('id');
+ $table->datetime('updated_at')->nullable()->after('created_at');
+ $table->date('start_at')->nullable()->after('recur_schedule');
+ $table->date('stop_at')->nullable()->after('start_at');
+ });
+
+ // Convert out dates
+ foreach (\App\Models\InvoiceItem::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->cursor() as $o) {
+ if ($o->date_orig)
+ $o->created_at = \Carbon\Carbon::createFromTimestamp($o->date_orig);
+ if ($o->date_last)
+ $o->updated_at = \Carbon\Carbon::createFromTimestamp($o->date_last);
+ if ($o->date_start)
+ $o->start_at = \Carbon\Carbon::createFromTimestamp($o->date_start);
+ if ($o->date_stop)
+ $o->stop_at = \Carbon\Carbon::createFromTimestamp($o->date_stop);
+ $o->save();
+ }
+
+ Schema::table('invoice_items', function (Blueprint $table) {
+ $table->dropColumn(['date_orig','date_last','date_start','date_stop']);
+
+ $table->foreign(['service_id','site_id'])->references(['id','site_id'])->on('services');
+ $table->foreign(['invoice_id','site_id'])->references(['id','site_id'])->on('invoices');
+ $table->foreign(['product_id','site_id'])->references(['id','site_id'])->on('products');
+ });
+
+ DB::statement('ALTER TABLE ab_invoice_item_tax RENAME TO invoice_item_taxes');
+ DB::statement('ALTER TABLE invoice_item_taxes MODIFY invoice_item_id int unsigned NOT NULL');
+ DB::statement('ALTER TABLE invoice_item_taxes MODIFY tax_id int unsigned NOT NULL');
+ DB::statement('ALTER TABLE invoice_item_taxes DROP PRIMARY KEY,ADD PRIMARY KEY (id,site_id)');
+
+ Schema::table('invoice_item_taxes', function (Blueprint $table) {
+ $table->dropForeign('ab_invoice_item_tax_site_id_foreign');
+ $table->dropIndex('ab_invoice_item_tax_site_id_foreign');
+ $table->dropIndex('ab_invoice_item_tax_id_site_id_index');
+ $table->dropColumn(['date_orig']);
+
+ $table->foreign(['invoice_item_id','site_id'])->references(['id','site_id'])->on('invoice_items');
+ $table->foreign(['tax_id'])->references(['id'])->on('taxes');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ abort(500,'Cant go back');
+ }
+};
diff --git a/resources/views/theme/backend/adminlte/a/service/widgets/broadband/update.blade.php b/resources/views/theme/backend/adminlte/a/service/widgets/broadband/update.blade.php
index 6bef20d..e1e7022 100644
--- a/resources/views/theme/backend/adminlte/a/service/widgets/broadband/update.blade.php
+++ b/resources/views/theme/backend/adminlte/a/service/widgets/broadband/update.blade.php
@@ -65,7 +65,7 @@
-
+
\ No newline at end of file
diff --git a/resources/views/theme/backend/adminlte/a/service/widgets/internal.blade.php b/resources/views/theme/backend/adminlte/a/service/widgets/internal.blade.php
index 66df046..b99438e 100644
--- a/resources/views/theme/backend/adminlte/a/service/widgets/internal.blade.php
+++ b/resources/views/theme/backend/adminlte/a/service/widgets/internal.blade.php
@@ -3,7 +3,7 @@