Optimising product category and category names

This commit is contained in:
Deon George
2022-06-12 11:21:20 +10:00
parent 360c1e46a1
commit cc94426902
36 changed files with 269 additions and 156 deletions

View File

@@ -149,6 +149,11 @@ class Account extends Model implements IDs
return $this->company ?: ($this->user_id ? $this->user->getSurFirstNameAttribute() : 'LID:'.$this->id);
}
/**
* Return the type of account this is - if it has a company name, then its a business account.
*
* @return string
*/
public function getTypeAttribute()
{
return $this->company ? 'Business' : 'Private';

View File

@@ -26,6 +26,8 @@ use App\Traits\{ProductDetails,SiteID};
* Attributes for products:
* + lid : Local ID for product (part number)
* + sid : System ID for product (part number)
* + category : Type of product supplied
* + category_name : Type of product supplied (Friendly Name for display, not for internal logic)
* + supplied : Supplier product provided for this offering
* + supplier : Supplier for this offering
* + name : Brief Name for our product // @todo we should change this to be consistent with service
@@ -97,6 +99,7 @@ class Product extends Model implements IDs
/**
* Return a child model with details of the service
* This will return a product/* model.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
@@ -176,6 +179,29 @@ class Product extends Model implements IDs
return max($this->price_recur_default,$this->getSuppliedAttribute()->getBillingIntervalAttribute());
}
/**
* Return the type of service is provided. eg: Broadband, Phone.
*
* @return string
* @todo Does type need to be a mandatory attribute on a model - then we can remove this condition
*/
public function getCategoryAttribute(): string
{
return $this->type ? $this->type->getCategoryAttribute() : 'generic';
}
/**
* This will return the category of the product (eg: domain, hosting, etc) which is the basis for all
* other logic of these types.
*
* @return string
* @todo Does type need to be a mandatory attribute on a model - then we can remove this condition
*/
public function getCategoryNameAttribute(): string
{
return $this->type ? $this->type->getCategoryNameAttribute() : 'Generic';
}
/**
* How long must this product be purchased for as a service.
*
@@ -241,17 +267,6 @@ class Product extends Model implements IDs
return $this->description->description_full;
}
/**
* Get our product type
*
* @return string
* @todo is the test of type and type->supplied necessary? (It seems some hosting entries have no type, are they old?)
*/
public function getProductTypeAttribute(): string
{
return ($this->type && $this->type->supplied) ? $this->getSuppliedAttribute()->getTypeAttribute() : 'Unknown';
}
/**
* Suppliers
*

View File

@@ -15,6 +15,8 @@ final class Broadband extends Type implements ProductItem
protected $table = 'product_broadband';
protected const category_name = 'Broadband';
// Information required during the order process
protected array $order_attributes = [
'options.address'=>[

View File

@@ -12,6 +12,8 @@ final class Domain extends Type implements ProductItem
{
protected $table = 'product_domain';
protected const category_name = 'Domain Name';
// The model that is referenced when this product is ordered
protected string $order_model = ServiceDomain::class;
@@ -57,11 +59,6 @@ final class Domain extends Type implements ProductItem
return '';
}
public function getTypeAttribute()
{
return 'Domain Name';
}
public function hasUsage(): bool
{
return FALSE;

View File

@@ -12,6 +12,8 @@ final class Email extends Type implements ProductItem
{
protected $table = 'product_email';
protected const category_name = 'Email Hosting';
// The model that is referenced when this product is ordered
protected string $order_model = ServiceEmail::class;
@@ -57,11 +59,6 @@ final class Email extends Type implements ProductItem
return '';
}
public function getTypeAttribute()
{
return 'Domain Name';
}
public function hasUsage(): bool
{
return FALSE;

View File

@@ -12,6 +12,8 @@ final class Generic extends Type implements ProductItem
{
protected $table = 'product_generic';
protected const category_name = 'Generic';
// The model that is referenced when this product is ordered
protected string $order_model = ServiceGeneric::class;
@@ -34,11 +36,6 @@ final class Generic extends Type implements ProductItem
return 0;
}
public function getTypeAttribute()
{
return 'Generic';
}
public function hasUsage(): bool
{
return FALSE;

View File

@@ -12,6 +12,8 @@ final class Host extends Type implements ProductItem
{
protected $table = 'product_host';
protected const category_name = 'Web Hosting';
// The model that is referenced when this product is ordered
protected string $order_model = ServiceHost::class;
@@ -34,11 +36,6 @@ final class Host extends Type implements ProductItem
return 12;
}
public function getTypeAttribute()
{
return 'Hosting';
}
public function hasUsage(): bool
{
return FALSE;

View File

@@ -12,6 +12,8 @@ final class Phone extends Type implements ProductItem
{
protected $table = 'product_phone';
protected const category_name = 'Telephone';
protected array $order_attributes = [
'options.phonenumber'=>[
'request'=>'options.phonenumber',
@@ -62,11 +64,6 @@ final class Phone extends Type implements ProductItem
return 12;
}
public function getTypeAttribute()
{
return 'PHONE';
}
public function hasUsage(): bool
{
return FALSE;

View File

@@ -12,6 +12,8 @@ final class SSL extends Type implements ProductItem
{
protected $table = 'product_ssl';
protected const category_name = 'SSL Certificate';
// The model that is referenced when this product is ordered
protected string $order_model = ServiceSSL::class;
@@ -61,11 +63,6 @@ final class SSL extends Type implements ProductItem
return $o;
}
public function getTypeAttribute()
{
return 'SSL Certificate';
}
public function hasUsage(): bool
{
return FALSE;

View File

@@ -26,4 +26,25 @@ abstract class Type extends Model
{
return $this->morphOne(Product::class, null,'model','model_id');
}
/**
* This will return the category of the product (eg: domain, hosting, etc) which is the basis for all
* other logic of these types.
*
* @return string
*/
final public function getCategoryAttribute(): string
{
return strtolower((new \ReflectionClass($this))->getShortName());
}
/**
* Return a friendly name for this product, used for display
*
* @return string
*/
final public function getCategoryNameAttribute(): string
{
return static::category_name;
}
}

View File

@@ -20,6 +20,7 @@ use Leenooks\Carbon as LeenooksCarbon;
use App\Interfaces\IDs;
use App\Traits\ScopeServiceUserAuthorised;
use App\Traits\SiteID;
/**
* Class Service
@@ -50,7 +51,7 @@ use App\Traits\ScopeServiceUserAuthorised;
*/
class Service extends Model implements IDs
{
use HasFactory,ScopeServiceUserAuthorised;
use HasFactory,ScopeServiceUserAuthorised,SiteID;
protected $casts = [
'order_info'=>AsCollection::class,
@@ -472,25 +473,6 @@ class Service extends Model implements IDs
return number_format($this->getBillingChargeAttribute()/Arr::get(Invoice::billing_periods,$this->recur_schedule.'.interval',1),2);
}
/**
* Return the type of service is provided. eg: Broadband, Phone.
*
* @return string
*/
public function getCategoryAttribute(): string
{
switch ($x=$this->type->getTypeAttribute()) {
case 'ssl':
$type = 'SSL';
break;
default:
$type = ucfirst($x);
}
return $type;
}
/**
* The date the contract ends
*
@@ -707,16 +689,9 @@ class Service extends Model implements IDs
*/
public function getInvoiceToAttribute(): ?LeenooksCarbon
{
$result = ($x=$this->invoice_items->filter(function($item) { return $item->item_type === 0;}))->count()
return ($x=$this->invoice_items->filter(function($item) { return $item->item_type === 0;}))->count()
? $x->last()->stop_at
: NULL;
// For SSL Certificates, the invoice_to date is the expiry date of the Cert
// @todo can we use the expire_at attribute?
if (is_null($result) AND $this->type AND $this->type->type == 'ssl' AND $this->type->expire_at)
return $this->type->expire_at;
return $result;
}
/**

View File

@@ -105,12 +105,13 @@ class Broadband extends Type implements ServiceUsage
* Return the suppliers offering that this service is providing
*
* @return SupplierType
* @todo This column provided_adsl_plan_id should either be deprecated or renamed.
*/
public function supplied(): SupplierType
{
return $this->provided_adsl_plan_id
? SupplierBroadband::findOrFail($this->provided_adsl_plan_id)
: $this->service->product->type->supplied;
: $this->service->offering->supplied;
}
/**

View File

@@ -91,11 +91,6 @@ abstract class Type extends Model implements ServiceItem
return LeenooksCarbon::create($value);
}
public function getTypeAttribute()
{
return strtolower((new \ReflectionClass($this))->getShortName());
}
/* METHODS */
/**
@@ -105,6 +100,6 @@ abstract class Type extends Model implements ServiceItem
*/
public function supplied(): SupplierType
{
return $this->service->product->type->supplied;
return $this->service->offering->supplied ?: new \App\Models\Supplier\Generic();
}
}

View File

@@ -16,7 +16,11 @@ class Supplier extends Model
public $timestamps = FALSE;
/* The offerings we provide */
/**
* The offerings we provide
* @todo Use the product/* category instead of this const. The assumption is the supplier/* type is the same as the product/* type.
* @deprecated - use the product/* category instead.
*/
public const offering_types = [
'broadband' => [
'name' => 'Broadband',

View File

@@ -63,9 +63,4 @@ abstract class Type extends Model
{
return Tax::tax_calc($this->attributes['setup_cost'],config('site')->taxes);
}
public function getTypeAttribute(): string
{
return Arr::get(collect(Supplier::offering_types)->firstWhere('class',get_class($this)),'name','Unknown');
}
}