Introduce cost and cost override into service model. Update service internal view to show cost/billing left on contracted services
This commit is contained in:
parent
48d7968d0c
commit
4c24f09195
@ -45,6 +45,7 @@ use App\Traits\{ScopeAccountUserAuthorised,ScopeServiceActive,SiteID};
|
||||
*
|
||||
* Methods:
|
||||
* + isChargeOverridden : Has the price been overridden?
|
||||
* + isCostOverridden : Has the cost been overridden?
|
||||
* + isPending : Is this a pending active service
|
||||
*
|
||||
* @package App\Models
|
||||
@ -535,6 +536,11 @@ class Service extends Model implements IDs
|
||||
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
|
||||
*
|
||||
@ -543,7 +549,16 @@ class Service extends Model implements IDs
|
||||
*/
|
||||
public function getBillingChargeNormalisedAttribute(): float
|
||||
{
|
||||
return number_format($this->getBillingChargeAttribute()*Invoice::billing_change($this->getBillingIntervalAttribute(),$this->offering->billing_interval),2);
|
||||
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),
|
||||
2);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -567,7 +582,7 @@ class Service extends Model implements IDs
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the earliest date that the service can be cancelled
|
||||
* Return the earliest date that the service can be canceled as per contract/billing intervals
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
@ -916,17 +931,21 @@ class Service extends Model implements IDs
|
||||
/**
|
||||
* Provide billing charge to a future date
|
||||
*
|
||||
* If $date is earlier than our contract end date, then our charge is to the contract end date.
|
||||
* If $date is after our contract end date:
|
||||
* + and we are still in contract, then our charge is to contract end date plus additional time, else
|
||||
* + then our charge is the months to the $date
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @return float
|
||||
* @throws Exception
|
||||
*/
|
||||
public function billing_charge_to(Carbon $date): float
|
||||
{
|
||||
// if the date is less than the paid to, but less than the cancel date to, return cancel-paid to charge
|
||||
// If the date is greater than the paid to, and less than the cancel date to, return cancel-paid to charge
|
||||
if ($this->getPaidToAttribute()->lessThan($this->getCancelDateAttribute())) {
|
||||
$max = max($date,$this->getPaidToAttribute())->clone();
|
||||
$d = $max->diffInDays($this->getCancelDateAttribute());
|
||||
$max = max($date,$this->getCancelDateAttribute())->clone();
|
||||
|
||||
if ($this->getPaidToAttribute()->lessThan($max)) {
|
||||
$d = $this->getPaidToAttribute()->diffInDays($max);
|
||||
|
||||
return $this->account->taxed($d/30*$this->getBillingChargeNormalisedAttribute());
|
||||
}
|
||||
@ -934,6 +953,42 @@ class Service extends Model implements IDs
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount we are charged for the client to have this service
|
||||
* @return float
|
||||
*/
|
||||
public function billing_cost(): float
|
||||
{
|
||||
return is_null($this->cost)
|
||||
? $this->product->getBaseCostAttribute()
|
||||
: $this->cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate our costs to keep this service to a future date
|
||||
*
|
||||
* If $date is earlier than the contract end date, then our cost is to the contract end date.
|
||||
* If $date is after the contract end date:
|
||||
* + and we are still in contract, then our cost is to contract end date plus additional time, else
|
||||
* + then our cost is the months to the $date
|
||||
*
|
||||
* @param Carbon $date
|
||||
* @return float
|
||||
* @throws Exception
|
||||
*/
|
||||
public function billing_cost_to(Carbon $date): float
|
||||
{
|
||||
$max = max($date,$this->getCancelDateAttribute())->clone();
|
||||
|
||||
if ($this->getInvoicedToAttribute()->lessThan($max)) {
|
||||
$d = $this->getInvoicedToAttribute()->diffInDays($max);
|
||||
|
||||
return $this->account->taxed($d/30*$this->getBillingCostNormalisedAttribute());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the stage parameters
|
||||
*
|
||||
@ -1065,6 +1120,11 @@ class Service extends Model implements IDs
|
||||
return ! is_null($this->price);
|
||||
}
|
||||
|
||||
public function isCostOverridden(): bool
|
||||
{
|
||||
return ! is_null($this->cost);
|
||||
}
|
||||
|
||||
public function isContract(): bool
|
||||
{
|
||||
return $this->getContractEndAttribute()->greaterThan(Carbon::now());
|
||||
|
@ -1,4 +1,6 @@
|
||||
@use(App\Models\Invoice)
|
||||
@use(Carbon\CarbonInterface)
|
||||
|
||||
@php($c=$o->product)
|
||||
|
||||
<!-- $o=Service::class, $p=Product::class -->
|
||||
@ -29,7 +31,8 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Product</th>
|
||||
<td class="text-center" colspan="2"><a href="{{ url('a/product/details',$c->id) }}">#{{ $c->supplied->id }}: {{ $c->supplied->name_long }}</a></td>
|
||||
<td><a href="{{ url('a/product/details',$o->product_id) }}">#{{ $o->product_id }}: {{ $o->product->name }}</a></td>
|
||||
<td><a href="{{ url('a/product/details',$c->id) }}">#{{ $c->supplied->id }}: {{ $c->supplied->name_long }}</a></td>
|
||||
@if($p->exists)
|
||||
<th> </th>
|
||||
<td class="text-center" colspan="2">#{{ $p->supplied->id }}: {{ $p->supplied->name_long }}</td>
|
||||
@ -79,10 +82,16 @@
|
||||
@if($x)
|
||||
<abbr title="${{ number_format($b=$o->account->taxed($c->base_charge)*Invoice::billing_change($o->billing_interval,Invoice::BILL_MONTHLY),2) }}">${{ number_format($b=$o->billing_charge_normalised,2) }}
|
||||
@else
|
||||
{{ number_format($b=$o->billing_charge_normalised,2) }}
|
||||
${{ number_format($b=$o->billing_charge_normalised,2) }}
|
||||
@endif
|
||||
</td>
|
||||
<td @if($x=$o->isCostOverridden()) class="text-danger" @endif>
|
||||
@if($x)
|
||||
<abbr title="${{ number_format($a=$o->account->taxed($c->base_cost)*Invoice::billing_change($o->billing_interval,Invoice::BILL_MONTHLY),2) }}">${{ number_format($b=$o->billing_cost_normalised,2) }}
|
||||
@else
|
||||
${{ number_format($o->billing_cost_normalised,2) }}
|
||||
@endif
|
||||
</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($c->base_cost)*Invoice::billing_change($o->billing_interval,Invoice::BILL_MONTHLY),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@if($p->exists)
|
||||
<td @if($x=$o->isChargeOverridden()) class="text-danger" @endif>${{ number_format($b=$o->account->taxed($p->base_charge)*Invoice::billing_change($o->billing_interval,Invoice::BILL_MONTHLY),2) }}</td>
|
||||
@ -109,11 +118,25 @@
|
||||
<td>${{ number_format($b=$o->account->taxed($o->product->min_charge),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($c->supplied->min_cost),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
|
||||
@if($p->exists)
|
||||
<td>${{ number_format($a=$o->account->taxed($p->min_charge),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($p->supplied->min_cost ?? 0),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@endif
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Contract Left</th>
|
||||
@if($o->isContract())
|
||||
<td>${{ number_format($o->billing_charge_to($o->contract_end),2) }} (<small>{{ $o->paid_to->format('Y-m-d') }}</small>)</td>
|
||||
<td>${{ number_format($o->billing_cost_to($o->contract_end),2) }} (<small>{{ $o->invoiced_to->format('Y-m-d') }}</small>)</td>
|
||||
<td>{{ $o->contract_end->format('Y-m-d') }}<br><small>({{ $o->contract_end->diffForHumans(now(),CarbonInterface::DIFF_RELATIVE_TO_OTHER,FALSE,2) }} today)</small></td>
|
||||
|
||||
@else
|
||||
<td colspan="2" class="text-center">Not on contract</td>
|
||||
<td> </td>
|
||||
@endif
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
Loading…
x
Reference in New Issue
Block a user