'Service Charge', 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 9 => 'Usage Charge', 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 ]; /* RELATIONS */ public function invoice() { return $this->belongsTo(Invoice::class); } 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 */ public function getItemTypeNameAttribute() { switch ($this->item_type) { // * Line Charge Topic on Invoice. case 0: if ($this->start_at) return sprintf('%s [%s]','Product/Service', (($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->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(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 * * @return float */ public function getSubTotalAttribute(): float { return sprintf('%3.2f',$this->quantity * $this->price_base - $this->discount_amt); } /** * Total of all taxes * * @return mixed */ public function getTaxAttribute(): float { return sprintf('%3.2f',$this->taxes->sum('amount')); } /** * Total including taxes * * @return float */ public function getTotalAttribute(): float { return sprintf('%3.2f',$this->getSubTotalAttribute()+$this->getTaxAttribute()); } /* METHODS */ /** * 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); } } }