Optimising product category and category names
This commit is contained in:
@@ -40,22 +40,23 @@ class ServiceList extends Command
|
||||
'Type',
|
||||
'Product',
|
||||
'Name',
|
||||
'active',
|
||||
'status',
|
||||
'invoice next',
|
||||
'start date',
|
||||
'stop date',
|
||||
'connect date',
|
||||
'first invoice'
|
||||
'Active',
|
||||
'Status',
|
||||
'Next Invoice',
|
||||
'Start Date',
|
||||
'Stop Date',
|
||||
'Connect Date',
|
||||
'First Invoice'
|
||||
));
|
||||
|
||||
foreach (Service::withoutGlobalScope(\App\Models\Scopes\SiteScope::class)->with(['site'])->cursor() as $o) {
|
||||
//dd($o,$o->site);
|
||||
if ((! $this->option('inactive')) AND ! $o->isActive())
|
||||
continue;
|
||||
|
||||
Config::set('site',$o->site);
|
||||
|
||||
if ($this->option('type') AND ($o->product->getProductTypeAttribute() !== $this->option('type')))
|
||||
if ($this->option('type') AND ($o->product->getCategoryAttribute() !== $this->option('type')))
|
||||
continue;
|
||||
|
||||
$c = $o->invoice_items->filter(function($item) {return $item->item_type === 0; })->sortby('start_at')->first();
|
||||
@@ -67,14 +68,14 @@ class ServiceList extends Command
|
||||
|
||||
$this->info(sprintf($header,
|
||||
$o->sid,
|
||||
$o->product->getProductTypeAttribute(),
|
||||
$o->product->getCategoryNameAttribute(),
|
||||
substr($o->product->getNameAttribute(),0,35),
|
||||
substr($o->name_short,0,40),
|
||||
$o->active ? 'active' : 'inactive',
|
||||
$o->status,
|
||||
$o->invoice_next ? $o->invoice_next->format('Y-m-d') : NULL,
|
||||
$o->start_at ? $o->start_at->format('Y-m-d') : NULL,
|
||||
$o->stop_at ? $o->stop_at->format('Y-m-d') : NULL,
|
||||
$o->invoice_next?->format('Y-m-d'),
|
||||
$o->start_at?->format('Y-m-d'),
|
||||
$o->stop_at?->format('Y-m-d'),
|
||||
($o->type AND $o->type->connect_at) ? $o->type->connect_at->format('Y-m-d') : NULL,
|
||||
($c && $c->date_start) ? $c->date_start->format('Y-m-d') : NULL,
|
||||
));
|
||||
|
@@ -294,12 +294,12 @@ class ServiceController extends Controller
|
||||
*/
|
||||
public function update(Request $request,Service $o)
|
||||
{
|
||||
if ($request->post($o->type->type)) {
|
||||
$o->type->forceFill($request->post($o->type->type))->save();
|
||||
if ($request->post($o->product->category)) {
|
||||
$o->type->forceFill($request->post($o->product->category))->save();
|
||||
}
|
||||
|
||||
if ($request->post('start_at'))
|
||||
$o->date_start = $request->start_at;
|
||||
$o->start_at = $request->start_at;
|
||||
|
||||
$o->save();
|
||||
|
||||
|
@@ -77,11 +77,4 @@ interface SupplierItem
|
||||
* @return float
|
||||
*/
|
||||
public function getSetupCostTaxableAttribute(): float;
|
||||
|
||||
/**
|
||||
* Return the type of offering this is.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTypeAttribute();
|
||||
}
|
@@ -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';
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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'=>[
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
@@ -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',
|
||||
|
@@ -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');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user