Product Model optimisation

This commit is contained in:
2023-05-05 10:32:04 +10:00
parent 0f91ce4940
commit 96f799f535
13 changed files with 145 additions and 115 deletions

View File

@@ -6,11 +6,12 @@ use Awobaz\Compoships\Compoships;
use Illuminate\Container\Container;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Leenooks\Traits\ScopeActive;
use App\Interfaces\{IDs,ProductItem};
@@ -166,7 +167,7 @@ class Product extends Model implements IDs
*/
public function getBaseChargeAttribute(int $timeperiod=NULL,Group $go=NULL): float
{
return $this->getCharge('base',$timeperiod,$go);
return $this->_charge('base',$timeperiod,$go);
}
/**
@@ -176,6 +177,7 @@ class Product extends Model implements IDs
* @param Group|null $go
* @param Collection|NULL $taxes
* @return float
* @deprecated move to account::tax_calc
*/
public function getBaseChargeTaxableAttribute(int $timeperiod=NULL,Group $go=NULL,Collection $taxes=NULL): float
{
@@ -189,7 +191,7 @@ class Product extends Model implements IDs
*/
public function getBaseCostAttribute(): float
{
return round($this->getSuppliedAttribute()->base_cost*Invoice::billing_change($this->getSuppliedAttribute()->getBillingIntervalAttribute(),$this->getBillingIntervalAttribute()) ?: 0,2);
return $this->supplied->base_cost*Invoice::billing_change($this->supplied->billing_interval,$this->billing_interval) ?: 0;
}
/**
@@ -197,6 +199,7 @@ class Product extends Model implements IDs
*
* @param Collection|NULL $taxes
* @return float
* @deprecated move to account::tax_calc
*/
public function getBaseCostTaxableAttribute(Collection $taxes=NULL): float
{
@@ -211,20 +214,22 @@ class Product extends Model implements IDs
*/
public function getBillingIntervalAttribute(): int
{
return max($this->price_recur_default,$this->getSuppliedAttribute()->getBillingIntervalAttribute());
return max($this->price_recur_default,$this->supplied->billing_interval);
}
/**
* This will return the category of the product (eg: domain, webhosting, etc) which is the basis for all
* other logic of these types.
*
* @return string
*/
public function getCategoryAttribute(): string
{
return strtolower(Str::studly($this->category_name));
}
/**
* Return the type of service is provided. eg: Broadband, Phone.
*
* @return string|null
*/
public function getCategoryAttribute(): ?string
{
return $this->supplied ? $this->supplied->getCategoryAttribute() : NULL;
}
/**
* This will return the category of the product (eg: domain, hosting, etc) which is the basis for all
* other logic of these types.
*
@@ -232,7 +237,7 @@ class Product extends Model implements IDs
*/
public function getCategoryNameAttribute(): string
{
return $this->supplied->getCategoryNameAttribute();
return $this->supplied->category_name;
}
/**
@@ -242,7 +247,7 @@ class Product extends Model implements IDs
*/
public function getContractTermAttribute(): int
{
return $this->type->getContractTermAttribute();
return $this->type->contract_term;
}
/**
@@ -252,11 +257,11 @@ class Product extends Model implements IDs
*/
public function getDescriptionAttribute(): string
{
return (($x=$this->translate) && $x->description) ? $x->description : 'No Description';
return $this->translate->description;
}
/**
* Get the minimum cost of this product
* Get the minimum charge for this product
*
* @param int|null $timeperiod
* @param Group|null $go
@@ -264,7 +269,7 @@ class Product extends Model implements IDs
*/
public function getMinChargeAttribute(int $timeperiod=NULL,Group $go=NULL): float
{
return $this->getSetupChargeAttribute($timeperiod,$go)+$this->getBaseChargeAttribute($timeperiod,$go)*Invoice::billing_term($this->getContractTermAttribute(),$this->getBillingIntervalAttribute());
return $this->getSetupChargeAttribute($timeperiod,$go)+$this->getBaseChargeAttribute($timeperiod,$go)*Invoice::billing_term($this->type->contract_term,$this->getBillingIntervalAttribute());
}
/**
@@ -274,6 +279,7 @@ class Product extends Model implements IDs
* @param Group|null $go
* @param Collection|NULL $taxes
* @return float
* @deprecated move to account::tax_calc
*/
public function getMinChargeTaxableAttribute(int $timeperiod=NULL,Group $go=NULL,Collection $taxes=NULL): float
{
@@ -297,7 +303,7 @@ class Product extends Model implements IDs
*/
public function getNameDetailAttribute(): string
{
return $this->translate ? $this->translate->name_detail : 'Unknown Name';
return $this->translate->name_detail;
}
/**
@@ -307,30 +313,29 @@ class Product extends Model implements IDs
*/
public function getNameShortAttribute(): string
{
return $this->translate ? $this->translate->name_short : 'Unknown PID';
}
/**
* Suppliers
*
* @return Model|null
*/
public function getSupplierAttribute(): ?Model
{
return $this->getSuppliedAttribute() ? $this->getSuppliedAttribute()->supplier_detail->supplier : NULL;
return $this->translate->name_short;
}
/**
* Suppliers product
*
* @return Model
* @todo make internal as other values off this attribute are used, not the model itself
*/
public function getSuppliedAttribute(): Model
{
return $this->type->supplied;
}
/**
* Suppliers of this product
*
* @return Model|null
*/
public function getSupplierAttribute(): ?Model
{
return $this->supplied->supplier;
}
/**
* The charge to setup this service
*
@@ -340,7 +345,7 @@ class Product extends Model implements IDs
*/
public function getSetupChargeAttribute(int $timeperiod=NULL,Group $go=NULL): float
{
return $this->getCharge('setup',$timeperiod,$go);
return $this->_charge('setup',$timeperiod,$go);
}
/**
@@ -350,6 +355,7 @@ class Product extends Model implements IDs
* @param Group|null $go
* @param Collection|null $taxes
* @return float
* @deprecated move to account::tax_calc
*/
public function getSetupChargeTaxableAttribute(int $timeperiod=NULL,Group $go=NULL,Collection $taxes=NULL): float
{
@@ -357,13 +363,13 @@ class Product extends Model implements IDs
}
/**
* The charge to setup this service
* The cost to setup this service
*
* @return float
*/
public function getSetupCostAttribute(): float
{
return $this->getSuppliedAttribute()->setup_cost ?: 0;
return $this->supplied->setup_cost ?: 0;
}
/**
@@ -371,6 +377,7 @@ class Product extends Model implements IDs
*
* @param Collection|null $taxes
* @return float
* @deprecated move to account::tax_calc
*/
public function getSetupCostTaxableAttribute(Collection $taxes=NULL): float
{
@@ -379,6 +386,48 @@ class Product extends Model implements IDs
/* METHODS */
/**
* Get a charge value from the pricing array
*
* This will traverse the groups to the parent group to find an appropriate charge, if one is not found,
* it will extrapolate a charge from the parent group, from another time period.
*
* @param string $type
* @param int|NULL $timeperiod
* @param Group|NULL $go
* @return float
*/
private function _charge(string $type,int $timeperiod=NULL,Group $go=NULL): float
{
// We'll cache this for performance
static $default = NULL;
// All public users
if (is_null($default))
$default = Group::whereNull('parent_id')->firstOrFail();
if (! $go)
$go = $default;
if (is_null($timeperiod))
$timeperiod = $this->getBillingIntervalAttribute();
// If the price doesnt exist for $go->id, use $go->id = 0 which is all users.
if (! $price=$this->charge($timeperiod,$go,$type)) {
$alt_tp = $timeperiod;
// Traverse up our timeperiods if the default group to see if there is another time period that has the value
while (is_null($price=$this->charge($alt_tp,$default,$type)) && ($alt_tp >= 0))
$alt_tp--;
// If we havent got a price, we'll extrapolate one, except for setup charges
if (! is_null($price) && ($alt_tp !== $timeperiod) && ($type !== 'setup'))
$price = $price*Invoice::billing_change($alt_tp,$timeperiod);
}
return round($price,2);
}
/**
* Return the charge from the pricing table for the specific time period and group
*
@@ -408,50 +457,13 @@ class Product extends Model implements IDs
*
* @note: By definition products are normalised, as their cost price is based on the default billing interval
* @return float
* @todo Move tax calculations out
*/
public function cost_normalized(): float
{
return number_format(Tax::tax_calc($this->supplied->base_cost,config('site')->taxes),2);
}
/**
* Get a charge value from the pricing array
*
* @param string $type
* @param int|NULL $timeperiod
* @param Group|NULL $go
* @return float
* @todo use self::charge()
*/
private function getCharge(string $type,int $timeperiod=NULL,Group $go=NULL): float
{
static $default = NULL;
if (! $go) {
if (is_null($default))
$default = Group::whereNull('parent_id')->firstOrFail(); // All public users
$go = $default;
}
if (is_null($timeperiod))
$timeperiod = $this->getBillingIntervalAttribute();
// If the price doesnt exist for $go->id, use $go->id = 0 which is all users.
if (! $price=Arr::get($this->pricing,sprintf('%d.%d.%s',$timeperiod,$go->id,$type))) {
$alt_tp = $timeperiod;
while (is_null($price=Arr::get($this->pricing,sprintf('%d.%d.%s',$alt_tp,0,$type))) && ($alt_tp >= 0)) {
$alt_tp--;
}
// If we havent got a price, we'll extrapolate one, except for setup charges
if (! is_null($price) && ($alt_tp !== $timeperiod) && ($type !== 'setup'))
$price = $price*Invoice::billing_change($alt_tp,$timeperiod);
}
return round($price,2);
}
/**
* Return if this product captures usage data
*
@@ -466,7 +478,7 @@ class Product extends Model implements IDs
* When receiving an order, validate that we have all the required information for the product type
*
* @param Request $request
* @return mixed
* @return Model|null
*/
public function orderValidation(Request $request): ?Model
{