osb/app/Models/InvoiceItem.php

180 lines
4.7 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Arr;
use App\Traits\NextKey;
use App\Traits\PushNew;
use Leenooks\Carbon;
class InvoiceItem extends Model
{
use NextKey,PushNew;
const RECORD_ID = 'invoice_item';
public $incrementing = FALSE;
protected $table = 'ab_invoice_item';
const CREATED_AT = 'date_orig';
const UPDATED_AT = 'date_last';
protected $dates = ['date_start','date_stop'];
public $dateFormat = 'U';
// Array of items that can be updated with PushNew
protected $pushable = ['taxes'];
private $_tax = 0;
public function invoice()
{
return $this->belongsTo(Invoice::class);
}
/**
* Product for this item
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function product()
{
return $this->belongsTo(Product::class);
}
public function service()
{
return $this->belongsTo(Service::class);
}
public function taxes()
{
return $this->hasMany(InvoiceItemTax::class);
}
/** ATTRIBUTES **/
/**
* Start date for the invoice item line
*
* We need cast this value to a Leenooks\Carbon for access to startOfHalf() endOfHalf() methods
*
* @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
*
* We need cast this value to a Leenooks\Carbon for access to startOfHalf() endOfHalf() methods
*
* @param $value
* @return Carbon
* @throws \Exception
*/
public function getDateStopAttribute($value)
{
if (! is_null($value))
return Carbon::createFromTimestamp($value);
}
public function getItemTypeNameAttribute()
{
$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.
case 0:
return sprintf('%s [%s]','Product/Service',
$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')));
// * 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->module_text()
);
default:
return ($this->module_id == 30 ? 'Additional Charge: ' : '').Arr::get($types,$this->item_type,'Unknown');
}
}
public function getSubTotalAttribute()
{
return $this->quantity * $this->price_base;
}
public function getTaxAttribute()
{
if (! $this->_tax)
{
foreach ($this->taxes as $o)
{
$this->_tax += $o->amount;
}
}
return $this->_tax;
}
public function getTotalAttribute()
{
return $this->tax + $this->sub_total;
}
/** FUNCTIONS **/
/**
* Add taxes to this record
*/
public function addTaxes(Collection $taxes)
{
// Refuse to change an existing record
if ($this->exists)
throw new \Exception('Refusing to add Taxes to existing record');
foreach($taxes as $to)
{
$iit = new InvoiceItemTax;
$iit->tax_id = $to->id;
$iit->amount = round($this->quantity*$this->price_base*$to->rate,3);
$iit->site_id = 1;
$this->taxes->push($iit);
}
}
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);
}
}
}