Move more product::class methods into __get(), no functional changes
All checks were successful
Create Docker Image / Build Docker Image (x86_64) (push) Successful in 43s
Create Docker Image / Final Docker Image Manifest (push) Successful in 10s

This commit is contained in:
2025-05-22 14:01:17 +10:00
parent 5ef1a27a64
commit a988720340
13 changed files with 84 additions and 167 deletions

View File

@@ -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,

View File

@@ -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);
}
}

View File

@@ -10,7 +10,7 @@ use App\Traits\{OrderServiceOptions,ProductDetails,SiteID};
abstract class Type extends Model
{
use SiteID,ProductDetails,OrderServiceOptions;
use SiteID,OrderServiceOptions;
/* RELATIONS */

View File

@@ -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;

View File

@@ -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),

View File

@@ -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());
}
}