Move more product::class methods into __get(), no functional changes
This commit is contained in:
parent
5ef1a27a64
commit
a988720340
@ -68,7 +68,7 @@ class ServiceList extends Command
|
||||
$this->info(sprintf($header,
|
||||
$o->lid,
|
||||
$o->product->category_name,
|
||||
substr($o->product->getNameAttribute(),0,35),
|
||||
substr($o->product->name,0,35),
|
||||
substr($o->name_short,0,40),
|
||||
$o->active ? 'active' : 'inactive',
|
||||
$o->status,
|
||||
|
@ -10,14 +10,13 @@ use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
use Intuit\Exceptions\NotTokenException;
|
||||
use Intuit\Traits\ProviderTokenTrait;
|
||||
use Leenooks\Traits\ScopeActive;
|
||||
|
||||
use App\Casts\CollectionOrNull;
|
||||
use App\Interfaces\{IDs,ProductItem};
|
||||
use App\Traits\{ProductDetails,ProviderRef};
|
||||
use App\Traits\ProviderRef;
|
||||
|
||||
/**
|
||||
* Class Product
|
||||
@ -33,17 +32,28 @@ use App\Traits\{ProductDetails,ProviderRef};
|
||||
* Attributes for products:
|
||||
* + lid : Local ID for product (part number)
|
||||
* + sid : System ID for product (part number)
|
||||
* + base_charge : Default billing amount
|
||||
*
|
||||
* + billing_interval : Default Billing Interval
|
||||
* + billing_interval_string: Default Billing Interval in human-readable form
|
||||
* + base_charge : Default billing amount
|
||||
* + base_cost : Cost for this service
|
||||
*
|
||||
* + billing_interval : Its the max of what we define, or what the supplier bills us at
|
||||
*
|
||||
* + category : Type of product supplied
|
||||
* + category_lc : Category name in lower case
|
||||
* + category_name : Type of product supplied (Friendly Name for display, not for internal logic)
|
||||
*
|
||||
* + contract_term : Contract term for this product
|
||||
*
|
||||
* + description : Product description (description.description_full => description_full)
|
||||
* + min_charge : Minimum charge taking into account billing interval and setup charges
|
||||
* + has_usage : Does this product instrument usage
|
||||
*
|
||||
* + min_cost : Minimum cost for this product
|
||||
*
|
||||
* + name : Details of our product (description.description_short => name_detail)
|
||||
* + pid : Product ID for our Product (description.name => name_short)
|
||||
* + setup_charge : Charge to setup this product
|
||||
*
|
||||
* + setup_cost : Charge by supplier to setup this product
|
||||
*
|
||||
* + supplier : Supplier for this offering
|
||||
*
|
||||
* Attributes for product types (type - Product/*)
|
||||
@ -66,7 +76,7 @@ use App\Traits\{ProductDetails,ProviderRef};
|
||||
*/
|
||||
class Product extends Model implements IDs
|
||||
{
|
||||
use HasFactory,ProductDetails,ScopeActive,ProviderRef,ProviderTokenTrait;
|
||||
use HasFactory,ScopeActive,ProviderRef,ProviderTokenTrait;
|
||||
|
||||
protected $casts = [
|
||||
'pricing' => CollectionOrNull::class,
|
||||
@ -77,10 +87,27 @@ class Product extends Model implements IDs
|
||||
return match ($key) {
|
||||
'base_cost' => round($this->supplied->base_cost,2)*Invoice::billing_change($this->type->billing_interval,$this->billing_interval) ?: 0,
|
||||
|
||||
'billing_interval' => max($this->price_recur_default,$this->type->billing_interval),
|
||||
'billing_interval_name' => Invoice::billing_name($this->billing_interval),
|
||||
|
||||
'category' => $this->supplied->category,
|
||||
'category_lc' => strtolower($this->category),
|
||||
'category_name' => $this->supplied->category_name,
|
||||
|
||||
'contract_term' => $this->type->contract_term,
|
||||
|
||||
'description' => $this->translate->description,
|
||||
|
||||
'has_usage' => $this->type->hasUsage(),
|
||||
|
||||
'min_cost' => $this->supplied->min_cost,
|
||||
|
||||
'name' => $this->translate->name_detail,
|
||||
|
||||
'pid' => $this->translate->name_short,
|
||||
|
||||
'setup_cost' => $this->supplied->setup_cost ?: 0,
|
||||
|
||||
default => parent::__get($key),
|
||||
};
|
||||
}
|
||||
@ -174,80 +201,6 @@ class Product extends Model implements IDs
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
/**
|
||||
* Our default billing interval
|
||||
* Its the max of what we define, or what the supplier bills us at
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getBillingIntervalAttribute(): int
|
||||
{
|
||||
return max($this->price_recur_default,$this->type->billing_interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* How long must this product be purchased for as a service.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getContractTermAttribute(): int
|
||||
{
|
||||
return $this->type->contract_term;
|
||||
}
|
||||
|
||||
/**
|
||||
* This product full description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescriptionAttribute(): string
|
||||
{
|
||||
return $this->translate->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum charge for this product
|
||||
*
|
||||
* @param int|null $timeperiod
|
||||
* @param Group|null $go
|
||||
* @return float
|
||||
*/
|
||||
public function getMinChargeAttribute(int $timeperiod=NULL,Group $go=NULL): float
|
||||
{
|
||||
return $this->getSetupChargeAttribute($timeperiod,$go)
|
||||
+ $this->base_charge($timeperiod,$go)*Invoice::billing_change($this->billing_interval,$this->type->billing_interval)*$this->type->contract_term;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum cost for this product
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getMinCostAttribute(): float
|
||||
{
|
||||
return $this->supplied->min_cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our products short descriptive name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute(): string
|
||||
{
|
||||
return $this->translate->name_detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our products PID
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPIDAttribute(): string
|
||||
{
|
||||
return $this->translate->name_short;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppliers product
|
||||
*
|
||||
@ -268,28 +221,6 @@ class Product extends Model implements IDs
|
||||
return $this->supplied->supplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* The charge to setup this service
|
||||
*
|
||||
* @param int|null $timeperiod
|
||||
* @param Group|null $go
|
||||
* @return float
|
||||
*/
|
||||
public function getSetupChargeAttribute(int $timeperiod=NULL,Group $go=NULL): float
|
||||
{
|
||||
return $this->_charge('setup',$timeperiod,$go);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cost to setup this service
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getSetupCostAttribute(): float
|
||||
{
|
||||
return $this->supplied->setup_cost ?: 0;
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
/**
|
||||
@ -387,24 +318,16 @@ class Product extends Model implements IDs
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a normalize price dependent on the product, ie: Broadband = Monthly, Domain = Yearly, etc
|
||||
* Get the minimum charge for this product
|
||||
*
|
||||
* @note: By definition products are normalised, as their cost price is based on the default billing interval
|
||||
* @param int|null $timeperiod
|
||||
* @param Group|null $go
|
||||
* @return float
|
||||
*/
|
||||
public function cost_normalized(): float
|
||||
public function min_charge(int $timeperiod=NULL,Group $go=NULL): float
|
||||
{
|
||||
return number_format(config('site')->taxed($this->supplied->base_cost),2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if this product captures usage data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUsage(): bool
|
||||
{
|
||||
return $this->type->hasUsage();
|
||||
return $this->setup_charge($timeperiod,$go)
|
||||
+ $this->base_charge($timeperiod,$go)*Invoice::billing_change($this->billing_interval,$this->type->billing_interval)*$this->contract_term;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -417,4 +340,16 @@ class Product extends Model implements IDs
|
||||
{
|
||||
return $this->type->orderValidation($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* The charge to setup this service
|
||||
*
|
||||
* @param int|null $timeperiod
|
||||
* @param Group|null $go
|
||||
* @return float
|
||||
*/
|
||||
public function setup_charge(?int $timeperiod=NULL,?Group $go=NULL): float
|
||||
{
|
||||
return $this->_charge('setup',$timeperiod,$go);
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ use App\Traits\{OrderServiceOptions,ProductDetails,SiteID};
|
||||
|
||||
abstract class Type extends Model
|
||||
{
|
||||
use SiteID,ProductDetails,OrderServiceOptions;
|
||||
use SiteID,OrderServiceOptions;
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
|
@ -301,7 +301,7 @@ class Service extends Model implements IDs
|
||||
'billing_interval' => $this->recur_schedule ?: $this->product->billing_interval,
|
||||
'billing_interval_name' => Invoice::billing_name($this->billing_interval),
|
||||
|
||||
'contract_term' => max($this->supplied->contract_term,$this->product->type->contract_term),
|
||||
'contract_term' => max($this->product->contract_term,$this->supplied->contract_term),
|
||||
|
||||
'is_active' => $this->active || ($this->order_status && (! in_array($this->order_status,self::INACTIVE_STATUS))),
|
||||
'is_billed' => (! ($this->external_billing || $this->suspend_billing || ($this->price === 0))),
|
||||
@ -1058,7 +1058,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->billing_interval,$this->account->group))
|
||||
&& $this->product->setup_charge($this->billing_interval,$this->account->group))
|
||||
{
|
||||
$ii = new InvoiceItem;
|
||||
|
||||
@ -1066,7 +1066,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->billing_interval,$this->account->group);
|
||||
$ii->price_base = $this->product->setup_charge($this->billing_interval,$this->account->group);
|
||||
$ii->start_at = $this->invoice_next;
|
||||
$ii->stop_at = $this->invoice_next;
|
||||
$ii->quantity = 1;
|
||||
|
@ -28,6 +28,7 @@ abstract class Type extends Model
|
||||
{
|
||||
return match ($key) {
|
||||
'category' => (new \ReflectionClass($this))->getShortName(),
|
||||
'category_lc' => strtolower($this->category),
|
||||
'category_name' => static::category_name ?: $this->category,
|
||||
|
||||
default => parent::__get($key),
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Consistent Details on Products
|
||||
*/
|
||||
namespace App\Traits;
|
||||
|
||||
use App\Models\Invoice;
|
||||
|
||||
trait ProductDetails
|
||||
{
|
||||
/**
|
||||
* Return a human friendly name for the billing interval
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBillingIntervalStringAttribute(): string
|
||||
{
|
||||
return Invoice::billing_name(static::getBillingIntervalAttribute());
|
||||
}
|
||||
}
|
@ -59,10 +59,12 @@
|
||||
<span class="h5">Accounting</span>
|
||||
<hr>
|
||||
|
||||
<!-- @todo When returning with a bad value old() is not selecting the previous value, may need to have the full html here instead of a component -->
|
||||
@foreach (ProviderOauth::providers() as $apo)
|
||||
<x-leenooks::form.select :id="sprintf('acc_%d',$apo->id)" :name="sprintf('accounting[%d]',$apo->id)" icon="fa-calculator" :label="ucfirst($apo->name)" :choose="true" :value="$pdo->provider_ref($apo)" old="accounting" :options="$pdo->accounting($apo->name)"/>
|
||||
@endforeach
|
||||
@production
|
||||
<!-- @todo When returning with a bad value old() is not selecting the previous value, may need to have the full html here instead of a component -->
|
||||
@foreach (ProviderOauth::providers() as $apo)
|
||||
<x-leenooks::form.select :id="sprintf('acc_%d',$apo->id)" :name="sprintf('accounting[%d]',$apo->id)" icon="fa-calculator" :label="ucfirst($apo->name)" :choose="true" :value="$pdo->provider_ref($apo)" old="accounting" :options="$pdo->accounting($apo->name)"/>
|
||||
@endforeach
|
||||
@endproduction
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,7 +25,7 @@
|
||||
<td>{{ $so->invoice_to ? $so->invoice_to->format('Y-m-d') : '-' }}</td>
|
||||
<td>{{ $so->active ? 'YES' : 'NO' }}</td>
|
||||
<td class="text-right">{{ $a=number_format($so->billing_charge_normalised_taxed,2) }}</td>
|
||||
<td class="text-right">{{ $b=number_format($so->product->cost_normalized(),2) }}</td>
|
||||
<td class="text-right">{{ $b=number_format($so->billing_cost_normalised_taxed,2) }}</td>
|
||||
<td><button class="btn btn-sm @if($a<$b)btn-danger @else btn-success @endif"><small>@if($a<$b)<i class="fas fa-fw fa-exclamation"></i> @else <i class="fas fa-fw fa-check"></i> @endif</small></button></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
@ -32,7 +32,7 @@
|
||||
<li class="nav-item"><a @class(['nav-link','active'=>! (session()->has('service_update') || session()->has('charge_add'))]) href="#pending_items" data-toggle="tab">Pending Items</a></li>
|
||||
@endif
|
||||
|
||||
@if($o->product->hasUsage())
|
||||
@if($o->product->has_usage)
|
||||
<li class="nav-item"><a @class(['nav-link','active'=>! ($x || (session()->has('service_update') || session()->has('charge_add')))]) href="#traffic" data-toggle="tab">Traffic</a></li>
|
||||
@endif
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($o->product->hasUsage())
|
||||
@if($o->product->has_usage)
|
||||
<div @class(['tab-pane','fade','show active'=>! ($x || (session()->has('service_update') || session()->has('charge_add')))]) id="traffic">
|
||||
@if($o->type->usage(30)->count())
|
||||
@include('theme.backend.adminlte.service.widget.'.$o->product->category_lc.'.usagegraph',['o'=>$o->type])
|
||||
|
@ -42,7 +42,7 @@
|
||||
<td>{{ $o->supplierid }}</td>
|
||||
<td class="text-right">{{ number_format($o->billing_charge_normalised_taxed,2) }}</td>
|
||||
<td class="text-right">{{ number_format($o->billing_cost_normalised_taxed,2) }}</td>
|
||||
<td class="text-right">{{ $o->product->hasUsage() ? number_format($o->type->usage_summary(0)->sum()/1000,1) : '-' }}</td>
|
||||
<td class="text-right">{{ $o->product->has_usage ? number_format($o->type->usage_summary(0)->sum()/1000,1) : '-' }}</td>
|
||||
<td>{{ $o->product->supplier->name }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
@ -45,11 +45,11 @@
|
||||
|
||||
<tr>
|
||||
<th>Setup</th>
|
||||
<td>${{ number_format($b=$o->account->taxed($c->setup_charge),2) }}</td>
|
||||
<td>${{ number_format($b=$o->account->taxed($c->setup_charge()),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($c->setup_cost),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@if($p->exists)
|
||||
<td>${{ number_format($b=$o->account->taxed($p->setup_charge),2) }}</td>
|
||||
<td>${{ number_format($b=$o->account->taxed($p->setup_charge()),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($p->setup_cost),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@endif
|
||||
@ -58,11 +58,11 @@
|
||||
<tr>
|
||||
<th>Billed</th>
|
||||
<td>{{ $o->billing_interval_name }}</td>
|
||||
<td>{{ $c->type->billing_interval_string }}</td>
|
||||
<td>{{ $c->billing_interval_name }}</td>
|
||||
<td> </td>
|
||||
@if($p->exists)
|
||||
<td>{{ $o->billing_interval_name }}</td>
|
||||
<td>{{ $p->type->billing_interval_string }}</td>
|
||||
<td>{{ $p->billing_interval_name }}</td>
|
||||
<td> </td>
|
||||
@endif
|
||||
</tr>
|
||||
@ -118,13 +118,13 @@
|
||||
<tr>
|
||||
<th>Min Price</th>
|
||||
<!-- @todo change this to $o->min_charge when implemented -->
|
||||
<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>${{ number_format($b=$o->account->taxed($o->product->min_charge()),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($c->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>${{ number_format($a=$o->account->taxed($p->min_charge()),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($p->min_cost),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@endif
|
||||
</tr>
|
||||
|
@ -40,13 +40,13 @@
|
||||
@foreach($oo->products->pluck('products')->flatten()->filter() as $po)
|
||||
<tr>
|
||||
<td><a href="{{ route('product',['pdo'=>$po->id]) }}">{{ $po->lid }}</a></td>
|
||||
<td>{{ $po->pid }} <small>[<a href="{{ route('supplier.product.type',['id'=>$po->supplied->id,'spo'=>$po->supplier->id,'type'=>$po->supplied->category_lc]) }}">{{ $po->supplied->name }}</a>]</small></td>
|
||||
<td>{{ $po->pid }} <small>[<a href="{{ route('supplier.product.type',['id'=>$po->supplied->id,'spo'=>$po->supplier->id,'type'=>$po->category_lc]) }}">{{ $po->supplied->name }}</a>]</small></td>
|
||||
<td>{{ $po->name }}</td>
|
||||
<td class="text-right">{{ $po->active ? 'YES' : 'NO' }}</td>
|
||||
<td class="text-right">{{ $po->billing_interval_string }}</td>
|
||||
<td class="text-right">{{ $po->billing_interval_name }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->setup_cost),2) }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->base_cost),2) }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->setup_charge),2) }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->setup_charge()),2) }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->base_charge()),2) }}</td>
|
||||
<td class="text-right">{{ number_format($po->services->count()) }}</td>
|
||||
<td class="text-right">{{ number_format($po->services->where('active')->count()) }}</td>
|
||||
|
@ -10,11 +10,11 @@
|
||||
<th>Type</th>
|
||||
<td class="text-right">{{ $pdo->category_name }}</td>
|
||||
</tr>
|
||||
@if ($pdo->setup_charge)
|
||||
@if ($pdo->setup_charge())
|
||||
<tr>
|
||||
<th>Setup Charges <sup>*</sup></th>
|
||||
{{-- @todo this should use account::taxed() when the user is known --}}
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->setup_charge) : Config::get('site')->taxed($pdo->setup_charge),2) }}</td>
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->setup_charge()) : Config::get('site')->taxed($pdo->setup_charge()),2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
<tr>
|
||||
@ -24,7 +24,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Default Billing</th>
|
||||
<td class="text-right">{{ $pdo->billing_interval_string }}</td>
|
||||
<td class="text-right">{{ $pdo->billing_interval_name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Contract Term</th>
|
||||
@ -33,7 +33,7 @@
|
||||
<tr>
|
||||
<th>Minimum Costs <sup>+*</sup></th>
|
||||
{{-- @todo this should use account::taxed() when the user is known --}}
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->min_charge) : Config::get('site')->taxed($pdo->min_charge),2) }}</td>
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->min_charge()) : Config::get('site')->taxed($pdo->min_charge()),2) }}</td>
|
||||
</tr>
|
||||
|
||||
<tfoot>
|
||||
|
Loading…
x
Reference in New Issue
Block a user