diff --git a/app/Models/Service.php b/app/Models/Service.php index d8854b4..30a0f5d 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -23,21 +23,26 @@ use App\Traits\{ScopeAccountUserAuthorised,ScopeServiceActive,SiteID}; * Class Service * Services that belong to an account * - * So each service attribute has: - * - Offering, what product we supply (we make offerings from supplier's supplied products) - in the DB these are products/* - * - Supplied, our supplier's product that is providing the service - in the DB these are supplier/* - * - Type, what service we are providing, made up of a product we supply - in the DB these are service/* + * So each service attribute has: + * - Offering, what product we supply (we make offerings from supplier's supplied products) - in the DB these are products/* + * - Supplied, our supplier's product that is providing the service - in the DB these are supplier/* + * - Type, what service we are providing, made up of a product we supply - in the DB these are service/* * * Attributes for services: + * + billing_orig : Charge for this service before being overridden by $this->price (ex TAX) + * + billing_orig_normalised_taxed: Charge for this service before being overridden by $this->price, normalised to MONTHLY (with Account TAX) + * + billing_orig_taxed : Charge for this service before being overridden by $this->price (with Account TAX) + * + billing_charge : Charge for this service each invoice period (ex TAX) + * + billing_charge_normalised_taxed: Charge for this service each invoice period, normalised to MONTHLY (with Account TAX) + * + billing_charge_taxed : Charge for this service each invoice period (with Account TAX) + * + billing_interval : The period that this service is billed + * + billing_interval_name : The period that this service is billed as a name * + is_billed : Does this service generate an invoice * + is_charge_overridden : Has the price been overridden * + is_cost_overridden : Has the cost been overridden * * Attributes for services (OLD): * + additional_cost : Pending additional charges for this service (excluding setup) //@todo check all these are still valid - * + billing_charge : Charge for this service each invoice period - * + billing_interval : The period that this service is billed for by default - * + billing_interval_string : The period that this service is billed for by default as a name * + invoiced_to : When this service has been billed to * + contract_term : The term that this service must be active * + contract_end : The date that the contract ends for this service @@ -53,7 +58,6 @@ use App\Traits\{ScopeAccountUserAuthorised,ScopeServiceActive,SiteID}; * * @package App\Models * @todo Add min_charge - * @todo Add charge_orig : The original chargeable price */ class Service extends Model implements IDs { @@ -274,6 +278,14 @@ class Service extends Model implements IDs public function __get($key): mixed { return match ($key) { + 'billing_orig' => $this->product->getBaseChargeAttribute($this->billing_interval,$this->account->group), + 'billing_orig_normalised_taxed' => $this->billing_orig_taxed*Invoice::billing_change($this->billing_interval,Invoice::BILL_MONTHLY), + 'billing_orig_taxed' => $this->account->taxed($this->billing_orig), + 'billing_charge' => $this->billing_charge(), + 'billing_charge_normalised_taxed' => $this->billing_charge_taxed*Invoice::billing_change($this->billing_interval,Invoice::BILL_MONTHLY), + 'billing_charge_taxed' => $this->account->taxed($this->billing_charge), + 'billing_interval' => $this->recur_schedule ?: $this->product->billing_interval, + 'billing_interval_name' => Invoice::billing_name($this->billing_interval), 'is_billed' => (! ($this->external_billing || $this->suspend_billing || ($this->price === 0))), 'is_charge_overridden' => (! is_null($this->price)), 'is_cost_overridden' => (! is_null($this->cost)), @@ -507,62 +519,18 @@ class Service extends Model implements IDs /* ATTRIBUTES */ - /** - * How much do we charge for this service, base on the current recur schedule - * price in the DB overrides the base price used - * - * @return float - */ - public function getBillingChargeAttribute(): float - { - return $this->account->taxed($this->billing_charge()); - } - public function getBillingCostAttribute(): float { return $this->account->taxed($this->billing_cost()); } - /** - * Determine a monthly price for a service, even if it is billed at a different frequency - * - * @return float - * @throws Exception - */ - public function getBillingChargeNormalisedAttribute(): float - { - return number_format( - $this->getBillingChargeAttribute()*Invoice::billing_change($this->getBillingIntervalAttribute(),$this->offering->billing_interval), - 2); - } - public function getBillingCostNormalisedAttribute(): float { return number_format( - $this->getBillingCostAttribute()*Invoice::billing_change($this->getBillingIntervalAttribute(),$this->offering->billing_interval), + $this->getBillingCostAttribute()*Invoice::billing_change($this->billing_interval,$this->offering->billing_interval), 2); } - /** - * Return the service billing period - * - * @return int - */ - public function getBillingIntervalAttribute(): int - { - return $this->recur_schedule ?: $this->product->getBillingIntervalAttribute(); - } - - /** - * Return a human friendly name for the billing interval - * - * @return string - */ - public function getBillingIntervalStringAttribute(): string - { - return Invoice::billing_name($this->getBillingIntervalAttribute()); - } - /** * Return the earliest date that the service can be canceled as per contract/billing intervals * @@ -899,14 +867,14 @@ class Service extends Model implements IDs * * @return float */ - public function billing_charge(): float + private function billing_charge(): float { - // If recur_schedule is null, then we only bill this item once - if (is_null($this->getBillingIntervalAttribute()) && $this->getInvoicedToAttribute()) + // If recur_schedule is null, and we have already invoiced, then nothing further required + if (is_null($this->billing_interval) && $this->getInvoicedToAttribute()) $this->price = 0; return is_null($this->price) - ? $this->product->getBaseChargeAttribute($this->getBillingIntervalAttribute(),$this->account->group) + ? $this->billing_orig : $this->price; } @@ -927,12 +895,12 @@ class Service extends Model implements IDs $max = max($date,$this->getCancelDateAttribute())->clone(); if (! $this->getPaidToAttribute()) - return $this->account->taxed($this->getContractTermAttribute()*$this->getBillingChargeNormalisedAttribute()); + return $this->getContractTermAttribute()*$this->billing_charge_normalised_taxed; if ($this->getPaidToAttribute()->lessThan($max)) { $d = $this->getPaidToAttribute()->diffInDays($max); - return $this->account->taxed($d/30*$this->getBillingChargeNormalisedAttribute()); + return $d/30*$this->billing_charge_normalised_taxed; } return 0; @@ -967,7 +935,7 @@ class Service extends Model implements IDs $max = max($date,$this->getCancelDateAttribute())->clone(); if (! $this->getInvoicedToAttribute()) - return $this->account->taxed($this->getContractTermAttribute()*$this->getBillingChargeNormalisedAttribute()); + return $this->account->taxed($this->getContractTermAttribute()*$this->getBillingCostNormalisedAttribute()); if ($this->getInvoicedToAttribute()->lessThan($max)) { $d = $this->getInvoicedToAttribute()->diffInDays($max); @@ -1129,7 +1097,7 @@ class Service extends Model implements IDs // Connection charges are only charged once, so ignore if if we have already billed them if ((! $this->invoiced_items()->where('item_type',InvoiceItem::INVOICEITEM_SETUP)->count()) && (InvoiceItem::distinct('invoice_id')->where('service_id',$this->id)->count() < 2) - && $this->product->getSetupChargeAttribute($this->getBillingIntervalAttribute(),$this->account->group)) + && $this->product->getSetupChargeAttribute($this->billing_interval,$this->account->group)) { $ii = new InvoiceItem; @@ -1137,7 +1105,7 @@ class Service extends Model implements IDs $ii->service_id = $this->id; $ii->product_id = $this->product_id; $ii->item_type = InvoiceItem::INVOICEITEM_SETUP; - $ii->price_base = $this->product->getSetupChargeAttribute($this->getBillingIntervalAttribute(),$this->account->group); + $ii->price_base = $this->product->getSetupChargeAttribute($this->billing_interval,$this->account->group); $ii->start_at = $this->invoice_next; $ii->stop_at = $this->invoice_next; $ii->quantity = 1; @@ -1153,14 +1121,14 @@ class Service extends Model implements IDs while ($invoiced_to <= ($this->stop_at ?: $billdate)) { $ii = new InvoiceItem; - $period = Invoice::invoice_period($invoiced_to,$this->getBillingIntervalAttribute(),(bool)$this->product->price_recur_strict); + $period = Invoice::invoice_period($invoiced_to,$this->billing_interval,(bool)$this->product->price_recur_strict); $ii->active = TRUE; $ii->service_id = $this->id; $ii->product_id = $this->product_id; $ii->item_type = InvoiceItem::INVOICEITEM_SERVICE; - $ii->price_base = $this->billing_charge(); - $ii->recur_schedule = $this->getBillingIntervalAttribute(); + $ii->price_base = $this->billing_charge; + $ii->recur_schedule = $this->billing_interval; $ii->start_at = $invoiced_to; $ii->stop_at = ($this->stop_at && ($this->stop_at < Arr::get($period,'end'))) ? $this->stop_at : Arr::get($period,'end'); $ii->quantity = Invoice::invoice_quantity($ii->start_at,$ii->stop_at,$period); diff --git a/resources/views/theme/backend/adminlte/product/widget/services.blade.php b/resources/views/theme/backend/adminlte/product/widget/services.blade.php index 968631c..978fea9 100644 --- a/resources/views/theme/backend/adminlte/product/widget/services.blade.php +++ b/resources/views/theme/backend/adminlte/product/widget/services.blade.php @@ -24,7 +24,7 @@ {{ $so->stop_at ? $so->stop_at->format('Y-m-d') : '-' }} {{ $so->invoice_to ? $so->invoice_to->format('Y-m-d') : '-' }} {{ $so->active ? 'YES' : 'NO' }} - {{ $a=number_format($so->billing_charge_normalised,2) }} + {{ $a=number_format($so->billing_charge_normalised_taxed,2) }} {{ $b=number_format($so->product->cost_normalized(),2) }} diff --git a/resources/views/theme/backend/adminlte/service/domain/list.blade.php b/resources/views/theme/backend/adminlte/service/domain/list.blade.php index 7f22b3b..16c6bee 100644 --- a/resources/views/theme/backend/adminlte/service/domain/list.blade.php +++ b/resources/views/theme/backend/adminlte/service/domain/list.blade.php @@ -47,7 +47,7 @@ {{ $oo->registrar_ns }} @if ($oo->service->is_billed) {{ $oo->service->invoice_next->format('Y-m-d') }}@else - @endif @if (! $oo->service->external_billing)${{ number_format($oo->service->next_invoice_items()->sum('total'),2) }}@else - @endif - {{ $oo->service->billing_interval_string }} + {{ $oo->service->billing_interval_name }} @endforeach diff --git a/resources/views/theme/backend/adminlte/service/email/list.blade.php b/resources/views/theme/backend/adminlte/service/email/list.blade.php index a83db6a..103782f 100644 --- a/resources/views/theme/backend/adminlte/service/email/list.blade.php +++ b/resources/views/theme/backend/adminlte/service/email/list.blade.php @@ -51,7 +51,7 @@ {{ number_format($oo->accounts ?: 0) }} @if ($oo->service->is_billed) {{ $oo->service->invoice_next->format('Y-m-d') }} @else - @endif @if (! $oo->service->external_billing)${{ number_format($oo->service->next_invoice_items()->sum('total'),2) }}@else - @endif - {{ $oo->service->billing_interval_string }} + {{ $oo->service->billing_interval_name }} @endforeach diff --git a/resources/views/theme/backend/adminlte/service/hosting/list.blade.php b/resources/views/theme/backend/adminlte/service/hosting/list.blade.php index 79fd84c..1426f1a 100644 --- a/resources/views/theme/backend/adminlte/service/hosting/list.blade.php +++ b/resources/views/theme/backend/adminlte/service/hosting/list.blade.php @@ -45,7 +45,7 @@ {{ $oo->service->product->supplier->name }} @if ($oo->service->is_billed) {{ $oo->service->invoice_next->format('Y-m-d') }}@else - @endif @if (! $oo->service->external_billing)${{ number_format($oo->service->next_invoice_items()->sum('total'),2) }}@else - @endif - {{ $oo->service->billing_interval_string }} + {{ $oo->service->billing_interval_name }} @endforeach diff --git a/resources/views/theme/backend/adminlte/service/report.blade.php b/resources/views/theme/backend/adminlte/service/report.blade.php index 886b1f5..b141836 100644 --- a/resources/views/theme/backend/adminlte/service/report.blade.php +++ b/resources/views/theme/backend/adminlte/service/report.blade.php @@ -40,7 +40,7 @@ {{ $o->name }} {{ $o->product->name }} {{ $o->supplierid }} - {{ number_format($o->billing_charge_normalised,2) }} + {{ number_format($o->billing_charge_normalised_taxed,2) }} {{ number_format($o->billing_cost_normalised,2) }} {{ $o->product->hasUsage() ? number_format($o->type->usage_summary(0)->sum()/1000,1) : '-' }} {{ $o->product->supplier->name }} diff --git a/resources/views/theme/backend/adminlte/service/widget/information.blade.php b/resources/views/theme/backend/adminlte/service/widget/information.blade.php index 033ad4f..0ee3a3e 100644 --- a/resources/views/theme/backend/adminlte/service/widget/information.blade.php +++ b/resources/views/theme/backend/adminlte/service/widget/information.blade.php @@ -43,14 +43,14 @@ @if(($o->active || $o->isPending()) && (! $o->external_billing)) Billed - {{ $o->billing_interval_string }} + {{ $o->billing_interval_name }} Amount @if($o->is_charge_overridden) - @if($o->billing_charge < $o->charge_orig)${{ number_format($o->charge_orig,2) }} @endif${{ number_format($o->billing_charge,2) }} + @if($o->billing_charge < $o->billing_orig)${{ number_format($o->billing_orig_taxed,2) }} @endif${{ number_format($o->billing_charge_taxed,2) }} @else - ${{ number_format($o->billing_charge,2) }} + ${{ number_format($o->billing_charge_taxed,2) }} @endif @if($o->isActive() && $o->invoiced_to) diff --git a/resources/views/theme/backend/adminlte/service/widget/internal.blade.php b/resources/views/theme/backend/adminlte/service/widget/internal.blade.php index db69007..4101f96 100644 --- a/resources/views/theme/backend/adminlte/service/widget/internal.blade.php +++ b/resources/views/theme/backend/adminlte/service/widget/internal.blade.php @@ -55,11 +55,11 @@ Billed - {{ $o->billing_interval_string }} + {{ $o->billing_interval_name }} {{ $c->type->billing_interval_string }}   @if($p->exists) - {{ $o->billing_interval_string }} + {{ $o->billing_interval_name }} {{ $p->type->billing_interval_string }}   @endif @@ -67,7 +67,7 @@ Billing Price - $o->is_charge_overridden])>${{ number_format($b=$o->billing_charge,2) }} + $o->is_charge_overridden])>${{ number_format($b=$o->billing_charge_taxed,2) }} $o->is_cost_overridden])>${{ number_format($a=$o->billing_cost,2) }} {!! markup($a,$b) !!} @if($p->exists) @@ -81,14 +81,14 @@ Monthly Price $o->is_charge_overridden])> @if($o->is_charge_overridden) - ${{ number_format($b=$o->billing_charge_normalised,2) }} + ${{ number_format($b=$o->billing_charge_normalised_taxed,2) }} @else - ${{ number_format($b=$o->billing_charge_normalised,2) }} + ${{ number_format($b=$o->billing_charge_normalised_taxed,2) }} @endif $o->is_cost_overridden])> @if($o->is_cost_overridden) - ${{ number_format($b=$o->billing_cost_normalised,2) }} + ${{ number_format($b=$o->billing_cost_normalised,2) }} @else ${{ number_format($a=$o->billing_cost_normalised,2) }} @endif diff --git a/resources/views/theme/backend/adminlte/supplier/cost/view.blade.php b/resources/views/theme/backend/adminlte/supplier/cost/view.blade.php index 96e4c1f..3414da9 100644 --- a/resources/views/theme/backend/adminlte/supplier/cost/view.blade.php +++ b/resources/views/theme/backend/adminlte/supplier/cost/view.blade.php @@ -48,7 +48,7 @@ ${{ number_format($a=$oo->sum('base'),2) }} ${{ number_format($oo->sum('excess'),2) }} ${{ number_format($x=$oo->sum('cost'),2) }} - ${{ number_format($b=$oo->first()->service->billing_charge_normalised,2) }} + ${{ number_format($b=$oo->first()->service->billing_charge_normalised_taxed,2) }} ${{ number_format($b-$a,2) }} @php($cost += $x) @@ -66,7 +66,7 @@ ${{ number_format($a=$oo->sum('base'),2) }} ${{ number_format($oo->sum('excess'),2) }} ${{ number_format($x=$oo->sum('cost'),2) }} - ${{ number_format($b=$oo->first()->service->billing_charge_normalised,2) }} + ${{ number_format($b=$oo->first()->service->billing_charge_normalised_taxed,2) }} ${{ number_format($b-$a,2) }} @php($cost += $x)