Removed redundant functions from Invoice, optimised Invoice tables
This commit is contained in:
parent
a16277d9bb
commit
e1a4db700f
@ -97,7 +97,7 @@ class AdminController extends Controller
|
|||||||
if (collect($value)->sum() > $request->post('total_amt'))
|
if (collect($value)->sum() > $request->post('total_amt'))
|
||||||
$fail('Allocation is greater than payment total.');
|
$fail('Allocation is greater than payment total.');
|
||||||
}],
|
}],
|
||||||
'invoices.*.id' => 'nullable|exists:ab_invoice,id',
|
'invoices.*.id' => 'nullable|exists:invoices,id',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (! $o->exists) {
|
if (! $o->exists) {
|
||||||
|
@ -54,7 +54,7 @@ class HomeController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function invoice_pdf(Invoice $o)
|
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));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,13 +24,13 @@ class AccountController extends Controller
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get our invoice due date for this invoice
|
// 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
|
// @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
|
// 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)
|
foreach ($s as $so)
|
||||||
{
|
{
|
||||||
if ($so->isInvoiceDueSoon($days))
|
if ($so->isInvoiceDueSoon($days))
|
||||||
|
@ -38,7 +38,7 @@ class InvoiceEmail extends Mailable
|
|||||||
->subject(sprintf( 'Invoice: %s - Total: $%s - Due: %s',
|
->subject(sprintf( 'Invoice: %s - Total: $%s - Due: %s',
|
||||||
$this->invoice->id,
|
$this->invoice->id,
|
||||||
number_format($this->invoice->total,2),
|
number_format($this->invoice->total,2),
|
||||||
$this->invoice->date_due))
|
$this->invoice->due_at->format('Y-m-d')))
|
||||||
->with([
|
->with([
|
||||||
'user'=>$this->invoice->account->user,
|
'user'=>$this->invoice->account->user,
|
||||||
'site'=>$this->invoice->account->user->site,
|
'site'=>$this->invoice->account->user->site,
|
||||||
|
@ -25,7 +25,7 @@ use App\Traits\{NextKey,PushNew};
|
|||||||
* + paid_date : Date the invoice was paid in full
|
* + paid_date : Date the invoice was paid in full
|
||||||
* + paid_pending : Total of pending payments received
|
* + paid_pending : Total of pending payments received
|
||||||
* + sid : System ID for invoice
|
* + 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_tax : Invoices total of taxes
|
||||||
* + total : Invoice total
|
* + total : Invoice total
|
||||||
*
|
*
|
||||||
@ -33,17 +33,11 @@ use App\Traits\{NextKey,PushNew};
|
|||||||
*/
|
*/
|
||||||
class Invoice extends Model implements IDs
|
class Invoice extends Model implements IDs
|
||||||
{
|
{
|
||||||
use NextKey,PushNew,ScopeActive;
|
use PushNew,ScopeActive;
|
||||||
|
|
||||||
const RECORD_ID = 'invoice';
|
protected $dates = [
|
||||||
public $incrementing = FALSE;
|
'due_at',
|
||||||
|
];
|
||||||
protected $table = 'ab_invoice';
|
|
||||||
const CREATED_AT = 'date_orig';
|
|
||||||
const UPDATED_AT = 'date_last';
|
|
||||||
|
|
||||||
protected $dates = ['date_orig','due_date'];
|
|
||||||
public $dateFormat = 'U';
|
|
||||||
|
|
||||||
public const BILL_WEEKLY = 0;
|
public const BILL_WEEKLY = 0;
|
||||||
public const BILL_MONTHLY = 1;
|
public const BILL_MONTHLY = 1;
|
||||||
@ -56,45 +50,44 @@ class Invoice extends Model implements IDs
|
|||||||
public const BILL_FIVEYEARS = 8;
|
public const BILL_FIVEYEARS = 8;
|
||||||
|
|
||||||
/* Our available billing periods */
|
/* Our available billing periods */
|
||||||
// @todo change this to a function - with billing_name()?
|
|
||||||
public const billing_periods = [
|
public const billing_periods = [
|
||||||
0 => [
|
self::BILL_WEEKLY => [
|
||||||
'name' => 'Weekly',
|
'name' => 'Weekly',
|
||||||
'interval' => 0.25,
|
'interval' => 0.25,
|
||||||
],
|
],
|
||||||
1 => [
|
self::BILL_MONTHLY => [
|
||||||
'name' => 'Monthly',
|
'name' => 'Monthly',
|
||||||
'interval' => 1,
|
'interval' => 1,
|
||||||
],
|
],
|
||||||
2 => [
|
self::BILL_QUARTERLY => [
|
||||||
'name' => 'Quarterly',
|
'name' => 'Quarterly',
|
||||||
'interval' => 3,
|
'interval' => 3,
|
||||||
],
|
],
|
||||||
3 => [
|
self::BILL_SEMI_YEARLY => [
|
||||||
'name' => 'Semi-Annually',
|
'name' => 'Semi-Annually',
|
||||||
'interval' => 6,
|
'interval' => 6,
|
||||||
],
|
],
|
||||||
4 => [
|
self::BILL_YEARLY => [
|
||||||
'name' => 'Annually',
|
'name' => 'Annually',
|
||||||
'interval' => 12,
|
'interval' => 12,
|
||||||
],
|
],
|
||||||
5 => [
|
self::BILL_TWOYEARS => [
|
||||||
'name' => 'Two years',
|
'name' => 'Two years',
|
||||||
'interval' => 24,
|
'interval' => 24,
|
||||||
],
|
],
|
||||||
6 => [
|
self::BILL_THREEYEARS => [
|
||||||
'name' => 'Three Years',
|
'name' => 'Three Years',
|
||||||
'interval' => 36,
|
'interval' => 36,
|
||||||
],
|
],
|
||||||
7 => [
|
self::BILL_FOURYEARS => [
|
||||||
'name' => 'Four Years',
|
'name' => 'Four Years',
|
||||||
'interval' => 48,
|
'interval' => 48,
|
||||||
],
|
],
|
||||||
8 => [
|
SELF::BILL_FIVEYEARS => [
|
||||||
'name' => 'Five Years',
|
'name' => 'Five Years',
|
||||||
'interval' => 60,
|
'interval' => 60,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Array of items that can be updated with PushNew
|
// Array of items that can be updated with PushNew
|
||||||
protected $pushable = ['items'];
|
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));
|
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 */
|
/* RELATIONS */
|
||||||
|
|
||||||
public function account()
|
public function account()
|
||||||
@ -206,7 +221,7 @@ class Invoice extends Model implements IDs
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Balance due on an invoice
|
* Balance due on an invoice
|
||||||
* @return string
|
* @return float
|
||||||
*/
|
*/
|
||||||
public function getDueAttribute(): float
|
public function getDueAttribute(): float
|
||||||
{
|
{
|
||||||
@ -215,11 +230,11 @@ class Invoice extends Model implements IDs
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @return mixed
|
* @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
|
public function getInvoiceDateAttribute(): Carbon
|
||||||
{
|
{
|
||||||
return $this->date_orig;
|
return $this->created_at;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get account System ID
|
|
||||||
* @return string
|
|
||||||
* @deprecated use getSIDAttribute()
|
|
||||||
*/
|
|
||||||
public function getInvoiceAccountIdAttribute()
|
|
||||||
{
|
|
||||||
return $this->getSIDAttribute();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo Move this to a site configuration
|
// @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);
|
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
|
* Total of payments received for this invoice
|
||||||
* excluding pending payments
|
* excluding pending payments
|
||||||
@ -286,7 +281,7 @@ class Invoice extends Model implements IDs
|
|||||||
->filter(function($item) { return ! $item->pending_status; })
|
->filter(function($item) { return ! $item->pending_status; })
|
||||||
->last();
|
->last();
|
||||||
|
|
||||||
return $o ? $o->payment_date : NULL;
|
return $o?->payment_date;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -301,44 +296,12 @@ class Invoice extends Model implements IDs
|
|||||||
->sum('alloc_amt');
|
->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
|
* Get invoice subtotal before taxes
|
||||||
*
|
*
|
||||||
* @return float
|
* @return float
|
||||||
* @deprecated use getTotalSubAttribute()
|
|
||||||
*/
|
*/
|
||||||
public function getSubTotalAttribute(): float
|
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');
|
return $this->items->where('active',TRUE)->sum('sub_total');
|
||||||
}
|
}
|
||||||
@ -371,9 +334,12 @@ class Invoice extends Model implements IDs
|
|||||||
*/
|
*/
|
||||||
public function getTotalAttribute(): float
|
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()
|
public function currency()
|
||||||
{
|
{
|
||||||
return $this->account->country->currency;
|
return $this->account->country->currency;
|
||||||
@ -389,7 +355,7 @@ class Invoice extends Model implements IDs
|
|||||||
// Re-use an existing code
|
// Re-use an existing code
|
||||||
$io = Invite::where('for',$this->account->user->email)->first();
|
$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
|
// Extend the expire date
|
||||||
if ($io AND ($tokendate > $io->valid_until)) {
|
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]);
|
return url('u/invoice',[$this->id,'email',$code]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo document
|
||||||
public function products()
|
public function products()
|
||||||
{
|
{
|
||||||
$return = collect();
|
$return = collect();
|
||||||
|
|
||||||
foreach ($this->items->groupBy('product_id') as $o)
|
foreach ($this->items->groupBy('product_id') as $o) {
|
||||||
{
|
|
||||||
$po = $o->first()->product;
|
$po = $o->first()->product;
|
||||||
$po->count = count($o->pluck('service_id')->unique());
|
$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)
|
public function product_services(Product $po)
|
||||||
{
|
{
|
||||||
$return = collect();
|
$return = collect();
|
||||||
@ -436,6 +403,7 @@ class Invoice extends Model implements IDs
|
|||||||
return $return->unique()->sortBy('name');
|
return $return->unique()->sortBy('name');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo document
|
||||||
public function product_service_items(Product $po,Service $so)
|
public function product_service_items(Product $po,Service $so)
|
||||||
{
|
{
|
||||||
return $this->items->filter(function ($item) use ($po,$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
|
* @todo Ugly hack to update reminders
|
||||||
*/
|
*/
|
||||||
public function reminders(string $key) {
|
public function reminders(string $key) {
|
||||||
$r = unserialize($this->reminders);
|
$r = json_decode($this->reminders);
|
||||||
|
|
||||||
if (! Arr::get($r,$key)) {
|
if (! Arr::get($r,$key)) {
|
||||||
$r[$key] = time();
|
$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
|
* @param array $options
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function save(array $options = []) {
|
public function save(array $options = []) {
|
||||||
// Automatically set the date_due attribute for new records.
|
// Automatically set the date_due attribute for new records.
|
||||||
if (! $this->exists AND ! $this->due_date) {
|
if (! $this->exists AND ! $this->due_at) {
|
||||||
$this->due_date = $this->items->min('date_start');
|
$this->due_at = $this->items->min('start_at');
|
||||||
|
|
||||||
// @todo This 7 days should be sysetm configurable
|
// @todo This 7 days should be sysetm configurable
|
||||||
if (($x=Carbon::now()->addDay(7)) > $this->due_date)
|
if (($x=Carbon::now()->addDay(7)) > $this->due_at)
|
||||||
$this->due_date = $x;
|
$this->due_at = $x;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent::save($options);
|
return parent::save($options);
|
||||||
|
@ -5,9 +5,8 @@ namespace App\Models;
|
|||||||
use Illuminate\Database\Eloquent\Collection;
|
use Illuminate\Database\Eloquent\Collection;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Leenooks\Carbon;
|
use Leenooks\Carbon as LeenooksCarbon;
|
||||||
|
|
||||||
use App\Traits\NextKey;
|
|
||||||
use App\Traits\PushNew;
|
use App\Traits\PushNew;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,24 +14,18 @@ use App\Traits\PushNew;
|
|||||||
* Items that belong on an invoice
|
* Items that belong on an invoice
|
||||||
*
|
*
|
||||||
* Attributes for services:
|
* Attributes for services:
|
||||||
* + date_start : Start date
|
|
||||||
* + date_stop : End date
|
|
||||||
* + sub_total : Value of item
|
* + sub_total : Value of item
|
||||||
* + tax : Total of all taxes
|
* + tax : Total of all taxes
|
||||||
* + total : Total including taxes
|
* + total : Total including taxes
|
||||||
*/
|
*/
|
||||||
class InvoiceItem extends Model
|
class InvoiceItem extends Model
|
||||||
{
|
{
|
||||||
use NextKey,PushNew;
|
use PushNew;
|
||||||
const RECORD_ID = 'invoice_item';
|
|
||||||
public $incrementing = FALSE;
|
|
||||||
|
|
||||||
protected $table = 'ab_invoice_item';
|
protected $dates = [
|
||||||
const CREATED_AT = 'date_orig';
|
'start_at',
|
||||||
const UPDATED_AT = 'date_last';
|
'stop_at',
|
||||||
|
];
|
||||||
protected $dates = ['date_start','date_stop'];
|
|
||||||
public $dateFormat = 'U';
|
|
||||||
|
|
||||||
// Array of items that can be updated with PushNew
|
// Array of items that can be updated with PushNew
|
||||||
protected $pushable = ['taxes'];
|
protected $pushable = ['taxes'];
|
||||||
@ -60,11 +53,6 @@ class InvoiceItem extends Model
|
|||||||
return $this->belongsTo(Invoice::class);
|
return $this->belongsTo(Invoice::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Product for this item
|
|
||||||
*
|
|
||||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
|
||||||
*/
|
|
||||||
public function product()
|
public function product()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Product::class);
|
return $this->belongsTo(Product::class);
|
||||||
@ -82,73 +70,51 @@ class InvoiceItem extends Model
|
|||||||
|
|
||||||
/* ATTRIBUTES */
|
/* 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()
|
public function getItemTypeNameAttribute()
|
||||||
{
|
{
|
||||||
// @todo use self::type
|
switch ($this->item_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)
|
|
||||||
{
|
|
||||||
// * Line Charge Topic on Invoice.
|
// * Line Charge Topic on Invoice.
|
||||||
case 0:
|
case 0:
|
||||||
if ($this->date_start)
|
if ($this->start_at)
|
||||||
return sprintf('%s [%s]','Product/Service',
|
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
|
else
|
||||||
return 'Product/Service';
|
return 'Product/Service';
|
||||||
|
|
||||||
// * Excess Service Item, of item 0, must have corresponding SERVICE_ID
|
// * Excess Service Item, of item 0, must have corresponding SERVICE_ID
|
||||||
case 5:
|
case 5:
|
||||||
return sprintf('%s [%s] (%s)','Excess Usage',
|
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()
|
$this->module_text()
|
||||||
);
|
);
|
||||||
|
|
||||||
default:
|
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
|
* Sub total of item
|
||||||
*
|
*
|
||||||
@ -190,8 +156,7 @@ class InvoiceItem extends Model
|
|||||||
if ($this->exists)
|
if ($this->exists)
|
||||||
throw new \Exception('Refusing to add Taxes to existing record');
|
throw new \Exception('Refusing to add Taxes to existing record');
|
||||||
|
|
||||||
foreach($taxes as $to)
|
foreach($taxes as $to) {
|
||||||
{
|
|
||||||
$iit = new InvoiceItemTax;
|
$iit = new InvoiceItemTax;
|
||||||
$iit->tax_id = $to->id;
|
$iit->tax_id = $to->id;
|
||||||
$iit->amount = round($this->quantity*$this->price_base*$to->rate,3);
|
$iit->amount = round($this->quantity*$this->price_base*$to->rate,3);
|
||||||
@ -200,15 +165,12 @@ class InvoiceItem extends Model
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function module_text()
|
public function module_text(){
|
||||||
{
|
switch ($this->module_id) {
|
||||||
switch ($this->module_id)
|
|
||||||
{
|
|
||||||
// Charges Module
|
// Charges Module
|
||||||
case 30: return Charge::findOrFail($this->module_ref)->name;
|
case 30: return Charge::findOrFail($this->module_ref)->name;
|
||||||
|
|
||||||
default: abort(500,'Unable to handle '.$this->module_id);
|
default: abort(500,'Unable to handle '.$this->module_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,23 +4,12 @@ namespace App\Models;
|
|||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
use App\Traits\NextKey;
|
|
||||||
use App\Traits\PushNew;
|
use App\Traits\PushNew;
|
||||||
|
|
||||||
class InvoiceItemTax extends Model
|
class InvoiceItemTax extends Model
|
||||||
{
|
{
|
||||||
use NextKey,PushNew;
|
use PushNew;
|
||||||
const RECORD_ID = 'invoice_item_tax';
|
|
||||||
public $incrementing = FALSE;
|
|
||||||
|
|
||||||
protected $table = 'ab_invoice_item_tax';
|
protected $table = 'invoice_item_taxes';
|
||||||
const CREATED_AT = 'date_orig';
|
public $timestamps = FALSE;
|
||||||
const UPDATED_AT = NULL;
|
|
||||||
|
|
||||||
public $dateFormat = 'U';
|
|
||||||
|
|
||||||
public function invoice_item()
|
|
||||||
{
|
|
||||||
return $this->belongsTo(InvoiceItem::class);
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -318,7 +318,7 @@ class Service extends Model implements IDs
|
|||||||
{
|
{
|
||||||
$query = $this->hasMany(InvoiceItem::class)
|
$query = $this->hasMany(InvoiceItem::class)
|
||||||
->where('item_type','=',0)
|
->where('item_type','=',0)
|
||||||
->orderBy('date_start');
|
->orderBy('start_at');
|
||||||
|
|
||||||
// @todo Change to $query->active();
|
// @todo Change to $query->active();
|
||||||
if ($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')
|
$query = $this->hasManyThrough(Invoice::class,InvoiceItem::class,NULL,'id',NULL,'invoice_id')
|
||||||
->distinct('id')
|
->distinct('id')
|
||||||
->where('ab_invoice.site_id','=',$this->site_id)
|
->where('invoices.site_id','=',$this->site_id)
|
||||||
->where('ab_invoice_item.site_id','=',$this->site_id)
|
->where('invoice_items.site_id','=',$this->site_id)
|
||||||
->orderBy('date_orig')
|
->orderBy('created_at')
|
||||||
->orderBy('due_date');
|
->orderBy('due_at');
|
||||||
|
|
||||||
if ($active)
|
if ($active)
|
||||||
$query->where('ab_invoice_item.active','=',TRUE)
|
$query->where('invoice_items.active','=',TRUE)
|
||||||
->where('ab_invoice.active','=',TRUE);
|
->where('invoices.active','=',TRUE);
|
||||||
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
@ -469,49 +469,7 @@ class Service extends Model implements IDs
|
|||||||
*/
|
*/
|
||||||
public function getBillingMonthlyPriceAttribute(): float
|
public function getBillingMonthlyPriceAttribute(): float
|
||||||
{
|
{
|
||||||
$d = 1;
|
return number_format($this->getBillingChargeAttribute()/Arr::get(Invoice::billing_periods,$this->recur_schedule.'.interval',1),2);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -593,7 +551,18 @@ class Service extends Model implements IDs
|
|||||||
$last = $this->getInvoiceToAttribute();
|
$last = $this->getInvoiceToAttribute();
|
||||||
return $last
|
return $last
|
||||||
? $last->addDay()
|
? $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
|
* @return float
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
@ -734,12 +703,12 @@ class Service extends Model implements IDs
|
|||||||
/**
|
/**
|
||||||
* Get the date that the service has been invoiced to
|
* 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()
|
$result = ($x=$this->invoice_items->filter(function($item) { return $item->item_type === 0;}))->count()
|
||||||
? $x->last()->date_stop
|
? $x->last()->stop_at
|
||||||
: NULL;
|
: NULL;
|
||||||
|
|
||||||
// For SSL Certificates, the invoice_to date is the expiry date of the Cert
|
// 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;
|
return $item->item_type === 0;
|
||||||
})
|
})
|
||||||
->last()
|
->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->item_type = 4; // @todo change to const or something
|
||||||
$o->price_base = $this->product->getSetupChargeAttribute($this->recur_schedule,$this->account->group);
|
$o->price_base = $this->product->getSetupChargeAttribute($this->recur_schedule,$this->account->group);
|
||||||
//$o->recurring_schedule = $this->recur_schedule;
|
//$o->recurring_schedule = $this->recur_schedule;
|
||||||
$o->date_start = $this->invoice_next;
|
$o->start_at = $this->invoice_next;
|
||||||
$o->date_stop = $this->invoice_next;
|
$o->stop_at = $this->invoice_next;
|
||||||
$o->quantity = 1;
|
$o->quantity = 1;
|
||||||
$o->site_id = 1; // @todo
|
$o->site_id = 1; // @todo
|
||||||
|
|
||||||
@ -1254,9 +1223,9 @@ class Service extends Model implements IDs
|
|||||||
$o->price_base = is_null($this->price)
|
$o->price_base = is_null($this->price)
|
||||||
? (is_null($this->price_override) ? $this->product->getBaseChargeAttribute($this->recur_schedule,$this->account->group) : $this->price_override)
|
? (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
|
: $this->price; // @todo change to a method in this class
|
||||||
$o->recurring_schedule = $this->recur_schedule;
|
$o->recur_schedule = $this->recur_schedule;
|
||||||
$o->date_start = $this->invoice_next;
|
$o->start_at = $this->invoice_next;
|
||||||
$o->date_stop = $this->invoice_next_end;
|
$o->stop_at = $this->invoice_next_end;
|
||||||
$o->quantity = $this->invoice_next_quantity;
|
$o->quantity = $this->invoice_next_quantity;
|
||||||
$o->site_id = 1; // @todo
|
$o->site_id = 1; // @todo
|
||||||
|
|
||||||
@ -1277,8 +1246,8 @@ class Service extends Model implements IDs
|
|||||||
$o->quantity = $oo->quantity;
|
$o->quantity = $oo->quantity;
|
||||||
$o->item_type = $oo->type;
|
$o->item_type = $oo->type;
|
||||||
$o->price_base = $oo->amount;
|
$o->price_base = $oo->amount;
|
||||||
$o->date_start = $oo->date_charge;
|
$o->start_at = $oo->date_charge;
|
||||||
$o->date_stop = $oo->date_charge;
|
$o->stop_at = $oo->date_charge;
|
||||||
$o->module_id = 30; // @todo This shouldnt be hard coded
|
$o->module_id = 30; // @todo This shouldnt be hard coded
|
||||||
$o->module_ref = $oo->id;
|
$o->module_ref = $oo->id;
|
||||||
$o->site_id = 1; // @todo
|
$o->site_id = 1; // @todo
|
||||||
|
@ -4,6 +4,7 @@ namespace App\Models\Service;
|
|||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
|
use Leenooks\Carbon as LeenooksCarbon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class SSL (Service)
|
* Class SSL (Service)
|
||||||
@ -76,9 +77,9 @@ class SSL extends Type
|
|||||||
/**
|
/**
|
||||||
* Return the Certificate Expiry Date
|
* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace App\Models\Service;
|
namespace App\Models\Service;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Leenooks\Carbon as LeenooksCarbon;
|
||||||
|
|
||||||
use App\Interfaces\ServiceItem;
|
use App\Interfaces\ServiceItem;
|
||||||
use App\Models\{Account,Service};
|
use App\Models\{Account,Service};
|
||||||
@ -63,7 +63,7 @@ abstract class Type extends Model implements ServiceItem
|
|||||||
return $this->service->offering->contract_term;
|
return $this->service->offering->contract_term;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getServiceExpireAttribute(): ?Carbon
|
public function getServiceExpireAttribute(): ?LeenooksCarbon
|
||||||
{
|
{
|
||||||
return $this->expire_at ?: $this->service->invoice_next_at;
|
return $this->expire_at ?: $this->service->invoice_next_at;
|
||||||
}
|
}
|
||||||
@ -80,6 +80,17 @@ abstract class Type extends Model implements ServiceItem
|
|||||||
|
|
||||||
/* ATTRIBUTES */
|
/* 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()
|
public function getTypeAttribute()
|
||||||
{
|
{
|
||||||
return strtolower((new \ReflectionClass($this))->getShortName());
|
return strtolower((new \ReflectionClass($this))->getShortName());
|
||||||
|
@ -333,16 +333,16 @@ class User extends Authenticatable implements IDs
|
|||||||
*/
|
*/
|
||||||
private function query_invoice_items()
|
private function query_invoice_items()
|
||||||
{
|
{
|
||||||
return DB::table('ab_invoice_item')
|
return DB::table('invoice_items')
|
||||||
->select([
|
->select([
|
||||||
'invoice_id',
|
'invoice_id',
|
||||||
DB::raw('ab_invoice_item.id AS invoice_item_id'),
|
DB::raw('invoice_items.id AS invoice_item_id'),
|
||||||
DB::raw('IFNULL(ab_invoice_item.discount_amt,0) AS discount'),
|
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(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);
|
->where('active',TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -382,9 +382,9 @@ class User extends Authenticatable implements IDs
|
|||||||
DB::raw('false AS payment_fees'),
|
DB::raw('false AS payment_fees'),
|
||||||
])
|
])
|
||||||
->from($this->query_invoice_items(),'II')
|
->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'))
|
->whereIN('account_id',$this->accounts->pluck('id'))
|
||||||
->where('ab_invoice.active',TRUE)
|
->where('invoices.active',TRUE)
|
||||||
->groupBy(['invoice_id']);
|
->groupBy(['invoice_id']);
|
||||||
|
|
||||||
$payments = (new Payment)
|
$payments = (new Payment)
|
||||||
@ -420,8 +420,8 @@ class User extends Authenticatable implements IDs
|
|||||||
->select([
|
->select([
|
||||||
'account_id',
|
'account_id',
|
||||||
'id',
|
'id',
|
||||||
'due_date',
|
'due_at',
|
||||||
'date_orig',
|
'created_at',
|
||||||
'discount',
|
'discount',
|
||||||
'invoice_base',
|
'invoice_base',
|
||||||
'invoice_tax',
|
'invoice_tax',
|
||||||
@ -430,7 +430,7 @@ class User extends Authenticatable implements IDs
|
|||||||
'payment_fees',
|
'payment_fees',
|
||||||
DB::raw('ROUND(invoice_total-payments,2) AS balance'),
|
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'])
|
->with(['items.taxes'])
|
||||||
->from($summary,'summary');
|
->from($summary,'summary');
|
||||||
}
|
}
|
||||||
|
124
database/migrations/2022_04_22_122640_rename_invoice_tables.php
Normal file
124
database/migrations/2022_04_22_122640_rename_invoice_tables.php
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
DB::statement('ALTER TABLE ab_invoice RENAME TO invoices');
|
||||||
|
DB::statement('ALTER TABLE invoices MODIFY account_id int unsigned NOT NULL');
|
||||||
|
DB::statement('ALTER TABLE invoices MODIFY account_billing_id int unsigned DEFAULT NULL');
|
||||||
|
DB::statement('ALTER TABLE invoices MODIFY active tinyint(1) NOT NULL,MODIFY process_status tinyint(1) DEFAULT NULL,MODIFY billing_status tinyint(1) DEFAULT NULL,MODIFY print_status tinyint(1) DEFAULT NULL');
|
||||||
|
|
||||||
|
Schema::table('invoices', function (Blueprint $table) {
|
||||||
|
$table->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');
|
||||||
|
}
|
||||||
|
};
|
@ -65,7 +65,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="date" class="form-control" name="date_start" value="{{ $o->service->date_start ? $o->service->date_start->format('Y-m-d') : '' }}">
|
<input type="date" class="form-control" name="start_at" value="{{ $o->service->start_at ? $o->service->start_at->format('Y-m-d') : '' }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -3,7 +3,7 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
<th>{{ $o->product->type->supplied->supplier_detail->supplier->name }}</th>
|
<th>{{ ($s=$o->supplied)->supplier_detail->supplier->name }}</th>
|
||||||
<th>Us</th>
|
<th>Us</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Product</th>
|
<th>Product</th>
|
||||||
<td>#{{ ($s=$o->product->type->supplied)->id }}: {{ $s->name }}</td>
|
<td>#{{ $s->id }}: {{ $s->name }}</td>
|
||||||
<td>#{{ $o->product->id }}: {{ $o->product->name }}</td>
|
<td>#{{ $o->product->id }}: {{ $o->product->name }}</td>
|
||||||
<td>{{ $s->type }}</td>
|
<td>{{ $s->type }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -20,61 +20,45 @@
|
|||||||
<th>Setup</th>
|
<th>Setup</th>
|
||||||
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->setup_cost,$o->account->taxes),2) }}</td>
|
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->setup_cost,$o->account->taxes),2) }}</td>
|
||||||
<td>${{ number_format($b=\App\Models\Tax::tax_calc($o->product->setup_charge,$o->account->taxes),2) }}</td>
|
<td>${{ number_format($b=\App\Models\Tax::tax_calc($o->product->setup_charge,$o->account->taxes),2) }}</td>
|
||||||
<td>
|
<td>{!! markup($a,$b) !!}</td>
|
||||||
@if ($a > $b)
|
|
||||||
<span class="badge bg-danger>">({{ number_format($a ? ($b-$a)/($b ?: 1)*100 : 100,1) }})%</span>
|
|
||||||
@else
|
|
||||||
<span class="badge">{{ number_format($a ? ($b-$a)/($b ?: 1)*100 : ($b ? 100: 0),1) }}%</span>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Billed</th>
|
<th>Billed</th>
|
||||||
<td>{{ $s->billing_interval_string }}</td>
|
<td>{{ $s->billing_interval_string }}</td>
|
||||||
<td>{{ $o->product->billing_interval_string }}</td>
|
<td>{{ $o->billing_interval_string }}</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Billing Charge</th>
|
<th>Billing Price</th>
|
||||||
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->base_cost*\App\Models\Invoice::billing_change($s->billing_interval,$o->product->billing_interval),$o->account->taxes),2) }}</td>
|
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->base_cost*\App\Models\Invoice::billing_change($s->billing_interval,$o->product->billing_interval),$o->account->taxes),2) }}</td>
|
||||||
<td>${{ number_format($b=\App\Models\Tax::tax_calc($o->product->getBaseChargeAttribute($o->billing_interval),$o->account->taxes),2) }}</td>
|
<td>${{ number_format($b=$o->billing_charge,2) }}</td>
|
||||||
<td>
|
<td>{!! markup($a,$b) !!}</td>
|
||||||
@if ($a > $b)
|
|
||||||
<span class="badge bg-danger>">({{ number_format($a ? ($b-$a)/($b ?: 1)*100 : 100,1) }})%</span>
|
|
||||||
@else
|
|
||||||
<span class="badge">{{ number_format($a ? ($b-$a)/($b ?: 1)*100 : ($b ? 100: 0),1) }}%</span>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Monthly Cost</th>
|
<th>Monthly Price</th>
|
||||||
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->base_cost*\App\Models\Invoice::billing_change($s->billing_interval,1),$o->account->taxes),2) }}</td>
|
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->base_cost*\App\Models\Invoice::billing_change($s->billing_interval,1),$o->account->taxes),2) }}</td>
|
||||||
<td>${{ number_format($b=\App\Models\Tax::tax_calc($o->product->getBaseChargeAttribute($o->billing_interval)*\App\Models\Invoice::billing_change($o->billing_interval,1),$o->account->taxes),2) }}</td>
|
<td>${{ number_format($b=$o->billing_monthly_price,2) }}</td>
|
||||||
<td>
|
<td>{!! markup($a,$b) !!}</td>
|
||||||
@if ($a > $b)
|
|
||||||
<span class="badge bg-danger>">({{ number_format($a ? ($b-$a)/($b ?: 1)*100 : 100,1) }})%</span>
|
|
||||||
@else
|
|
||||||
<span class="badge">{{ number_format($a ? ($b-$a)/($b ?: 1)*100 : ($b ? 100: 0),1) }}%</span>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Contract</th>
|
<th>Contract</th>
|
||||||
<td>{{ $s->contract_term }} months</td>
|
<td>{{ $s->contract_term }} months</td>
|
||||||
<td>{{ $o->product->contract_term }} months</td>
|
<td>{{ $o->contract_term }} months</td>
|
||||||
<td> </td>
|
<td> </td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Min Cost</th>
|
<th>Min Price</th>
|
||||||
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->min_cost,$o->account->taxes),2) }}</td>
|
<td>${{ number_format($a=\App\Models\Tax::tax_calc($s->min_cost,$o->account->taxes),2) }}</td>
|
||||||
<td>${{ number_format($b=\App\Models\Tax::tax_calc($o->product->getMinChargeAttribute($o->billing_interval),$o->account->taxes),2) }}</td>
|
<td>${{ number_format($b=\App\Models\Tax::tax_calc($o->product->getMinChargeAttribute($o->billing_interval),$o->account->taxes),2) }}</td>
|
||||||
<td>
|
<td>{!! markup($a,$b) !!}</td>
|
||||||
@if ($a > $b)
|
|
||||||
<span class="badge bg-danger>">({{ number_format($a ? ($b-$a)/($b ?: 1)*100 : 100,1) }})%</span>
|
|
||||||
@else
|
|
||||||
<span class="badge">{{ number_format($a ? ($b-$a)/($b ?: 1)*100 : ($b ? 100: 0),1) }}%</span>
|
|
||||||
@endif
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@php
|
||||||
|
function markup($a,$b) {
|
||||||
|
return ($a > $b)
|
||||||
|
? sprintf('<span class="badge bg-danger>">(%3.1f%%)</span>',$a ? ($b-$a)/($b ?: 1)*100 : 100)
|
||||||
|
: sprintf('<span class="badge">%3.1f%%</span>',$a ? ($b-$a)/($b ?: 1)*100 : ($b ? 100: 0));
|
||||||
|
}
|
||||||
|
@endphp
|
@ -14,8 +14,8 @@
|
|||||||
@foreach ($o->invoices as $io)
|
@foreach ($o->invoices as $io)
|
||||||
<tr>
|
<tr>
|
||||||
<td class="text-right"><a href="{{ url('u/invoice',$io->id) }}">{{ $io->id }}</a></td>
|
<td class="text-right"><a href="{{ url('u/invoice',$io->id) }}">{{ $io->id }}</a></td>
|
||||||
<td class="text-right">{{ $io->date_orig->format('Y-m-d') }}</td>
|
<td class="text-right">{{ $io->created_at->format('Y-m-d') }}</td>
|
||||||
<td class="text-right">{{ $io->due_date->format('Y-m-d') }}</td>
|
<td class="text-right">{{ $io->due_at->format('Y-m-d') }}</td>
|
||||||
<td class="text-right">${{ number_format($io->total,2) }}</td>
|
<td class="text-right">${{ number_format($io->total,2) }}</td>
|
||||||
<td class="text-right">${{ number_format($io->paid,2) }}</td>
|
<td class="text-right">${{ number_format($io->paid,2) }}</td>
|
||||||
<td class="text-right">${{ number_format($io->due,2) }}</td>
|
<td class="text-right">${{ number_format($io->due,2) }}</td>
|
||||||
|
@ -22,11 +22,11 @@
|
|||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($o->query_invoice_summary()->having('balance','>',0)->get() as $oo)
|
@foreach ($o->query_invoice_summary()->having('balance','>',0)->get() as $oo)
|
||||||
<tr @if ($oo->due_date->isPast()) class="table-danger" @endif>
|
<tr @if ($oo->due_at->isPast()) class="table-danger" @endif>
|
||||||
<td>{{ $oo->account->name }}</td>
|
<td>{{ $oo->account->name }}</td>
|
||||||
<td><a href="{{ url('u/invoice',$oo->id) }}">{{ $oo->sid }}</a></td>
|
<td><a href="{{ url('u/invoice',$oo->id) }}">{{ $oo->sid }}</a></td>
|
||||||
<td>{{ $oo->date_orig->format('Y-m-d') }}</td>
|
<td>{{ $oo->created_at->format('Y-m-d') }}</td>
|
||||||
<td>{{ $oo->due_date->format('Y-m-d') }}</td>
|
<td>{{ $oo->due_at->format('Y-m-d') }}</td>
|
||||||
<td class="text-right">${{ number_format($oo->total,2) }}</td>
|
<td class="text-right">${{ number_format($oo->total,2) }}</td>
|
||||||
<td class="text-right">${{ number_format($oo->paid,2) }}</td>
|
<td class="text-right">${{ number_format($oo->paid,2) }}</td>
|
||||||
<td class="text-right">${{ number_format($oo->due,2) }}</td>
|
<td class="text-right">${{ number_format($oo->due,2) }}</td>
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
<div class="input-group-prepend">
|
<div class="input-group-prepend">
|
||||||
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
<span class="input-group-text"><i class="fa fa-fw fa-calendar"></i></span>
|
||||||
</div>
|
</div>
|
||||||
<input type="text" class="form-control" id="datestart" name="date_start" value="{{ ($x=$o->date_start) ? $x->format('Y-m-d') : '' }}">
|
<input type="text" class="form-control" id="datestart" name="start_at" value="{{ ($x=$o->start_at) ? $x->format('Y-m-d') : '' }}">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -68,7 +68,7 @@
|
|||||||
<td class="p-0">Invoice:</td><td class="p-0"><strong>{{ $o->lid }}</strong></td>
|
<td class="p-0">Invoice:</td><td class="p-0"><strong>{{ $o->lid }}</strong></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="p-0">Payment Due:</td><td class="p-0"><strong>{{ $o->due_date->format('Y-m-d') }}</strong></td>
|
<td class="p-0">Payment Due:</td><td class="p-0"><strong>{{ $o->due_at->format('Y-m-d') }}</strong></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="p-0">This Invoice Due:</td><td class="p-0"><strong>${{ number_format($o->total,$o->currency()->rounding) }}</strong></td>
|
<td class="p-0">This Invoice Due:</td><td class="p-0"><strong>${{ number_format($o->total,$o->currency()->rounding) }}</strong></td>
|
||||||
@ -157,7 +157,7 @@
|
|||||||
<table class="table">
|
<table class="table">
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="3" style="width:50%">Subtotal:</th>
|
<th colspan="3" style="width:50%">Subtotal:</th>
|
||||||
<td colspan="2" class="text-right">${{ number_format($o->total_sub,$o->currency()->rounding) }}</td>
|
<td colspan="2" class="text-right">${{ number_format($o->sub_total,$o->currency()->rounding) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
|
@ -21,11 +21,11 @@
|
|||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach ($x as $oo)
|
@foreach ($x as $oo)
|
||||||
<tr @if ($oo->due_date->isPast()) class="table-danger" @endif>
|
<tr @if ($oo->due_at->isPast()) class="table-danger" @endif>
|
||||||
<td>{{ $oo->account->name }}</td>
|
<td>{{ $oo->account->name }}</td>
|
||||||
<td><a href="{{ url('u/invoice',$oo->id) }}">{{ $oo->sid }}</a></td>
|
<td><a href="{{ url('u/invoice',$oo->id) }}">{{ $oo->sid }}</a></td>
|
||||||
<td>{{ $oo->date_orig->format('Y-m-d') }}</td>
|
<td>{{ $oo->created_at->format('Y-m-d') }}</td>
|
||||||
<td>{{ $oo->due_date->format('Y-m-d') }}</td>
|
<td>{{ $oo->due_at->format('Y-m-d') }}</td>
|
||||||
<td class="text-right">${{ number_format($oo->total,2) }}</td>
|
<td class="text-right">${{ number_format($oo->total,2) }}</td>
|
||||||
<td class="text-right">${{ number_format($oo->paid,2) }}</td>
|
<td class="text-right">${{ number_format($oo->paid,2) }}</td>
|
||||||
<td class="text-right">${{ number_format($oo->due,2) }}</td>
|
<td class="text-right">${{ number_format($oo->due,2) }}</td>
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@if(($x=$o->invoices()->where('ab_invoice.date_orig','>',\Carbon\Carbon::now()->subMonths(12)->unix())->with(['items.taxes','paymentitems.payment','account.country.currency'])->get()->where('due','<=',0))->count())
|
@if(($x=$o->invoices()->where('invoices.created_at','>',\Carbon\Carbon::now()->subMonths(12))->with(['items.taxes','paymentitems.payment','account.country.currency'])->get()->where('due','<=',0))->count())
|
||||||
<table class="table table-bordered w-100" id="invoices_past">
|
<table class="table table-bordered w-100" id="invoices_past">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -23,8 +23,8 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ $oo->account->name }}</td>
|
<td>{{ $oo->account->name }}</td>
|
||||||
<td><a href="{{ url('u/invoice',$oo->id) }}">{{ $oo->sid }}</a></td>
|
<td><a href="{{ url('u/invoice',$oo->id) }}">{{ $oo->sid }}</a></td>
|
||||||
<td>{{ $oo->date_orig->format('Y-m-d') }}</td>
|
<td>{{ $oo->created_at->format('Y-m-d') }}</td>
|
||||||
<td>{{ $oo->due_date->format('Y-m-d') }}</td>
|
<td>{{ $oo->due_at->format('Y-m-d') }}</td>
|
||||||
<td>{{ $oo->paid_date ? $oo->paid_date->format('Y-m-d') : '' }}</td>
|
<td>{{ $oo->paid_date ? $oo->paid_date->format('Y-m-d') : '' }}</td>
|
||||||
<td class="text-right">${{ number_format($oo->total,2) }}</td>
|
<td class="text-right">${{ number_format($oo->total,2) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -45,7 +45,7 @@
|
|||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#invoices_past').DataTable({
|
$('#invoices_past').DataTable({
|
||||||
order: [[0,'asc'],[3,'desc']],
|
order: [[3,'desc'],[0,'asc']],
|
||||||
rowGroup: {
|
rowGroup: {
|
||||||
dataSrc: 0,
|
dataSrc: 0,
|
||||||
},
|
},
|
||||||
|
@ -28,16 +28,16 @@
|
|||||||
<td>{{ $o->order_info_reference ?? '' }}</td>
|
<td>{{ $o->order_info_reference ?? '' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endif
|
@endif
|
||||||
@if ($o->date_start AND $o->isPending())
|
@if ($o->start_at AND $o->isPending())
|
||||||
<tr>
|
<tr>
|
||||||
<th>Pending Connection</th>
|
<th>Pending Connection</th>
|
||||||
<td>{{ $o->date_start->format('Y-m-d') }}</td>
|
<td>{{ $o->start_at->format('Y-m-d') }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endif
|
@endif
|
||||||
@if ($o->date_end)
|
@if ($o->stop_at)
|
||||||
<tr>
|
<tr>
|
||||||
<th>Cancellation Date</th>
|
<th>Cancellation Date</th>
|
||||||
<td>{{ $o->date_end->format('Y-m-d') }}</td>
|
<td>{{ $o->stop_at->format('Y-m-d') }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endif
|
@endif
|
||||||
@if (($o->active OR $o->isPending()) AND ! $o->external_billing)
|
@if (($o->active OR $o->isPending()) AND ! $o->external_billing)
|
||||||
@ -74,7 +74,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Cancelled</th>
|
<th>Cancelled</th>
|
||||||
<!-- @todo This should show the cancelled date -->
|
<!-- @todo This should show the cancelled date -->
|
||||||
<td>{!! $o->date_end ? $o->date_end->format('Y-m-d') : ($o->paid_to ? $o->paid_to->format('Y-m-d') : '').'<sup>*</sup>' !!}</td>
|
<td>{!! $o->stop_at ? $o->stop_at->format('Y-m-d') : ($o->paid_to ? $o->paid_to->format('Y-m-d') : '').'<sup>*</sup>' !!}</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endif
|
@endif
|
||||||
</table>
|
</table>
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
namespace Tests\Feature;
|
namespace Tests\Feature;
|
||||||
|
|
||||||
|
use Carbon\Carbon;
|
||||||
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
use App\Models\{Account,Group,Product,Service,Site};
|
use App\Models\{Account,Group,Invoice,Product,Service,Site};
|
||||||
|
|
||||||
class InvoiceTest extends TestCase
|
class InvoiceTest extends TestCase
|
||||||
{
|
{
|
||||||
@ -42,6 +43,7 @@ class InvoiceTest extends TestCase
|
|||||||
$this->site_setup();
|
$this->site_setup();
|
||||||
$this->account_setup();
|
$this->account_setup();
|
||||||
|
|
||||||
|
// @todo This test description doesnt reflect what is tested - this needs to be reworked.
|
||||||
// Create two services for the same account
|
// Create two services for the same account
|
||||||
// First service was billed a month ago, so this invoice will have 1 service charge
|
// First service was billed a month ago, so this invoice will have 1 service charge
|
||||||
$po = Product::factory()->notStrict()->create([
|
$po = Product::factory()->notStrict()->create([
|
||||||
@ -51,6 +53,8 @@ class InvoiceTest extends TestCase
|
|||||||
'site_id'=>Arr::get($this->setup,'site.a')->site_id,
|
'site_id'=>Arr::get($this->setup,'site.a')->site_id,
|
||||||
'account_id'=>Arr::get($this->setup,'account.a')->id,
|
'account_id'=>Arr::get($this->setup,'account.a')->id,
|
||||||
'product_id'=>$po->id,
|
'product_id'=>$po->id,
|
||||||
|
'recur_schedule'=>Invoice::BILL_MONTHLY,
|
||||||
|
'start_at'=>Carbon::now()->addMonth()->startofMonth(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$o->setRelation('product',$po);
|
$o->setRelation('product',$po);
|
||||||
|
Loading…
Reference in New Issue
Block a user