Start work on updating services
This commit is contained in:
@@ -2,14 +2,34 @@
|
||||
|
||||
namespace App\Models\Base;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
use App\Models\Service;
|
||||
use App\Interfaces\ServiceItem;
|
||||
use App\Models\{Account,Service};
|
||||
use App\Models\Supplier\Type;
|
||||
use App\Traits\{ScopeServiceActive,ScopeServiceUserAuthorised};
|
||||
|
||||
abstract class ServiceType extends Model
|
||||
abstract class ServiceType extends Model implements ServiceItem
|
||||
{
|
||||
use ScopeServiceActive,ScopeServiceUserAuthorised;
|
||||
|
||||
protected $dates = [
|
||||
'expire_at',
|
||||
];
|
||||
public $timestamps = FALSE;
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
/**
|
||||
* Account this service belongs to
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOneThrough
|
||||
*/
|
||||
public function account()
|
||||
{
|
||||
return $this->hasOneThrough(Account::class,Service::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NOTE: The service_id column could be discarded, if the id column=service_id
|
||||
* @return \Illuminate\Database\Eloquent\Relations\MorphOne
|
||||
@@ -19,27 +39,61 @@ abstract class ServiceType extends Model
|
||||
return $this->morphOne(Service::class,'type','model','id','service_id');
|
||||
}
|
||||
|
||||
/** SCOPES */
|
||||
/* SCOPES */
|
||||
|
||||
/**
|
||||
* Search for a record
|
||||
*
|
||||
* @param $query
|
||||
* @param string $term
|
||||
* @return
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeSearch($query,string $term)
|
||||
{
|
||||
return $query
|
||||
->with(['service'])
|
||||
->join('ab_service','ab_service.id','=',$this->getTable().'.service_id')
|
||||
->Where('ab_service.id','like','%'.$term.'%');
|
||||
->join('services','services.id','=',$this->getTable().'.service_id')
|
||||
->Where('services.id','like','%'.$term.'%');
|
||||
}
|
||||
|
||||
/** ATTRIBUTES **/
|
||||
/* INTERFACE */
|
||||
|
||||
public function getContractTermAttribute(): int
|
||||
{
|
||||
return $this->service->offering->contract_term;
|
||||
}
|
||||
|
||||
public function getServiceExpireAttribute(): ?Carbon
|
||||
{
|
||||
return $this->expire_at ?: $this->service->invoice_next_at;
|
||||
}
|
||||
|
||||
public function hasExpired(): bool
|
||||
{
|
||||
return (! $this->inContract()) && ($this->service->invoice_next_at && $this->service->invoice_next_at->isPast());
|
||||
}
|
||||
|
||||
public function inContract(): bool
|
||||
{
|
||||
return $this->expire_at && $this->expire_at->isFuture();
|
||||
}
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
public function getTypeAttribute()
|
||||
{
|
||||
return strtolower((new \ReflectionClass($this))->getShortName());
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
/**
|
||||
* The supplier's service that we provide
|
||||
*
|
||||
* @return Type
|
||||
*/
|
||||
public function supplied(): Type
|
||||
{
|
||||
return $this->service->product->type->supplied;
|
||||
}
|
||||
}
|
@@ -163,7 +163,8 @@ class Invoice extends Model implements IDs
|
||||
public function items()
|
||||
{
|
||||
return $this->hasMany(InvoiceItem::class)
|
||||
->where('active',TRUE);
|
||||
->where('active',TRUE)
|
||||
->with(['taxes','product']);
|
||||
}
|
||||
|
||||
public function payments()
|
||||
@@ -402,8 +403,7 @@ class Invoice extends Model implements IDs
|
||||
$return->push($po);
|
||||
}
|
||||
|
||||
$lo = $this->account->user->language;
|
||||
return $return->sortBy(function ($item) use ($lo) {
|
||||
return $return->sortBy(function ($item) {
|
||||
return $item->name;
|
||||
});
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ use App\Models\Supplier;
|
||||
use App\Models\Service\Broadband as ServiceBroadband;
|
||||
use App\Models\Supplier\Broadband as SupplierBroadband;
|
||||
|
||||
// @todo does this need to extend Type? Perhaps have a ProductType consistent with ServiceType.
|
||||
final class Broadband extends Type implements ProductItem
|
||||
{
|
||||
use ScopeActive;
|
||||
@@ -44,7 +45,7 @@ final class Broadband extends Type implements ProductItem
|
||||
*/
|
||||
public function supplied()
|
||||
{
|
||||
return $this->hasOne(SupplierBroadband::class,'id','supplier_broadband_id');
|
||||
return $this->hasOne(SupplierBroadband::class,'id','supplier_item_id');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
@@ -24,7 +24,7 @@ final class Domain extends Type implements ProductItem
|
||||
*/
|
||||
public function supplied()
|
||||
{
|
||||
return $this->hasOne(SupplierDomain::class,'id','supplier_domain_id');
|
||||
return $this->hasOne(SupplierDomain::class,'id','supplier_item_id');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
@@ -24,7 +24,7 @@ final class Email extends Type implements ProductItem
|
||||
*/
|
||||
public function supplied()
|
||||
{
|
||||
return $this->hasOne(SupplierEmail::class,'id','supplier_email_id');
|
||||
return $this->hasOne(SupplierEmail::class,'id','supplier_item_id');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
@@ -24,7 +24,7 @@ final class Generic extends Type implements ProductItem
|
||||
*/
|
||||
public function supplied()
|
||||
{
|
||||
return $this->hasOne(SupplierGeneric::class,'id','supplier_generic_id');
|
||||
return $this->hasOne(SupplierGeneric::class,'id','supplier_item_id');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
@@ -24,7 +24,7 @@ final class Host extends Type implements ProductItem
|
||||
*/
|
||||
public function supplied()
|
||||
{
|
||||
return $this->hasOne(SupplierHost::class,'id','supplier_host_id');
|
||||
return $this->hasOne(SupplierHost::class,'id','supplier_item_id');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
@@ -5,18 +5,18 @@ namespace App\Models\Product;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Interfaces\ProductItem;
|
||||
use App\Models\Service\Voip as ServiceVoip;
|
||||
use App\Models\Supplier\Voip as SupplierVoip;
|
||||
use App\Models\Service\Phone as ServicePhone;
|
||||
use App\Models\Supplier\Phone as SupplierPhone;
|
||||
|
||||
final class Voip extends Type implements ProductItem
|
||||
final class Phone extends Type implements ProductItem
|
||||
{
|
||||
protected $table = 'product_voip';
|
||||
protected $table = 'product_phone';
|
||||
|
||||
protected array $order_attributes = [
|
||||
'options.phonenumber'=>[
|
||||
'request'=>'options.phonenumber',
|
||||
'key'=>'service_number',
|
||||
'validation'=>'nullable|size:10|unique:ab_service__voip,service_number',
|
||||
'validation'=>'nullable|size:10|unique:service_phone,service_number',
|
||||
'validation_message'=>'Phone Number is a required field.',
|
||||
],
|
||||
'options.supplier'=>[
|
||||
@@ -40,7 +40,7 @@ final class Voip extends Type implements ProductItem
|
||||
];
|
||||
|
||||
// The model that is referenced when this product is ordered
|
||||
protected string $order_model = ServiceVoip::class;
|
||||
protected string $order_model = ServicePhone::class;
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
@@ -51,19 +51,20 @@ final class Voip extends Type implements ProductItem
|
||||
*/
|
||||
public function supplied()
|
||||
{
|
||||
return $this->hasOne(SupplierVoip::class,'id','supplier_voip_id');
|
||||
return $this->hasOne(SupplierPhone::class,'id','supplier_item_id');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
public function getContractTermAttribute(): int
|
||||
{
|
||||
// @todo Get this from the DB
|
||||
return 12;
|
||||
}
|
||||
|
||||
public function getTypeAttribute()
|
||||
{
|
||||
return 'VOIP';
|
||||
return 'PHONE';
|
||||
}
|
||||
|
||||
public function hasUsage(): bool
|
@@ -24,7 +24,7 @@ final class SSL extends Type implements ProductItem
|
||||
*/
|
||||
public function supplied()
|
||||
{
|
||||
return $this->hasOne(SupplierSSL::class,'id','supplier_ssl_id');
|
||||
return $this->hasOne(SupplierSSL::class,'id','supplier_item_id');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
@@ -52,19 +52,9 @@ final class SSL extends Type implements ProductItem
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getProductAttribute()
|
||||
{
|
||||
$o = new \stdClass();
|
||||
$o->product_id = 'INT';
|
||||
$o->setup_cost = 0;
|
||||
$o->base_cost = 0;
|
||||
$o->contract_term = 0; // @todo
|
||||
|
||||
return $o;
|
||||
}
|
||||
|
||||
public function getSupplierAttribute()
|
||||
{
|
||||
abort(500,'deprecated');
|
||||
$o = new \stdClass();
|
||||
$o->name = 'Internal';
|
||||
|
||||
|
@@ -7,6 +7,10 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use App\Models\Product;
|
||||
use App\Traits\{OrderServiceOptions,SiteID};
|
||||
|
||||
/**
|
||||
* @todo These tables have a base_cost/setup_cost/contract_term columns - how is that different to the supplier_tables?
|
||||
* @todo Ensure our terminology is consistent - we have a "cost", we "charge" clients.
|
||||
*/
|
||||
abstract class Type extends Model
|
||||
{
|
||||
use SiteID,OrderServiceOptions;
|
||||
|
@@ -18,35 +18,35 @@ use Leenooks\Carbon;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
|
||||
use App\Interfaces\IDs;
|
||||
use App\Traits\NextKey;
|
||||
|
||||
/**
|
||||
* Class Service
|
||||
* Services that belong to an account
|
||||
*
|
||||
* Attributes for services:
|
||||
* + additional_cost : Pending additional charges for this service (excluding setup)
|
||||
* + additional_cost : Pending additional charges for this service (excluding setup) //@todo check all these are still valid
|
||||
* + billing_cost : Charge for this service each invoice period
|
||||
* + billing_interval : The period that this service is billed for by default
|
||||
* + billing_interval_string : The period that this service is billed for by default as a name
|
||||
* + contract_term : The term that this service must be active
|
||||
* + contract_end : The date that the contract ends for this service
|
||||
* + name : Service short name with service address
|
||||
* + name_short : Service Product short name, eg: phone number, domain name, certificate CN
|
||||
* + name_detail : Service Detail, eg: service_address
|
||||
* + sid : System ID for service
|
||||
*
|
||||
* = Terminology:
|
||||
* - Offering, what product we supply (we make offerings from supplier's supplied products) - in the DB these are products/*
|
||||
* - Supplied, our supplier's product that is providing the service - in the DB these are supplier/*
|
||||
* - Type, what service we are providing, made up of a product we supply - in the DB these are service/*
|
||||
*
|
||||
* @package App\Models
|
||||
* @todo "Billing Start Date" = "connection date" for sub types??
|
||||
*/
|
||||
// @todo All the methods/attributes in this file need to be checked.
|
||||
class Service extends Model implements IDs
|
||||
{
|
||||
use HasFactory,NextKey;
|
||||
|
||||
const RECORD_ID = 'service';
|
||||
public $incrementing = FALSE;
|
||||
|
||||
protected $table = 'ab_service';
|
||||
const CREATED_AT = 'date_orig';
|
||||
const UPDATED_AT = 'date_last';
|
||||
use HasFactory;
|
||||
|
||||
protected $appends = [
|
||||
'account_name',
|
||||
@@ -59,17 +59,16 @@ class Service extends Model implements IDs
|
||||
'status',
|
||||
];
|
||||
|
||||
protected $dates = [
|
||||
'date_last_invoice',
|
||||
'date_next_invoice',
|
||||
'date_start',
|
||||
'date_end',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'order_info'=>AsCollection::class,
|
||||
];
|
||||
public $dateFormat = 'U';
|
||||
|
||||
protected $dates = [
|
||||
'invoice_last_at',
|
||||
'invoice_next_at',
|
||||
'start_at',
|
||||
'stop_at',
|
||||
];
|
||||
|
||||
protected $visible = [
|
||||
'account_name',
|
||||
@@ -484,7 +483,6 @@ class Service extends Model implements IDs
|
||||
* Return the auto billing details
|
||||
*
|
||||
* @return mixed
|
||||
* @deprecated use billing directly?
|
||||
*/
|
||||
public function getAutoPayAttribute()
|
||||
{
|
||||
@@ -536,6 +534,33 @@ class Service extends Model implements IDs
|
||||
return Invoice::billing_name($this->getBillingIntervalAttribute());
|
||||
}
|
||||
|
||||
/**
|
||||
* The date the contract ends
|
||||
*
|
||||
* Service contracts end the later of the start_date + contract_term or the expire date.
|
||||
*
|
||||
* @return Carbon
|
||||
*/
|
||||
public function getContractEndAttribute(): ?\Carbon\Carbon
|
||||
{
|
||||
// If we have no start date or expire date, then NULL;
|
||||
if (! $this->start_at && ! $this->type->expire_at)
|
||||
return NULL;
|
||||
|
||||
// If we dont have a start date, use the expire date
|
||||
if (! $this->start_at)
|
||||
return $this->type->expire_at;
|
||||
|
||||
$end = $this->start_at->addMonths($this->getContractTermAttribute());
|
||||
|
||||
// If we dont have an expire date, use the start date + contract_term
|
||||
if (! $this->type->expire_at)
|
||||
return $end;
|
||||
|
||||
// We have both, so it's the later of the two.
|
||||
return ($end < $this->type->expire_at) ? $this->type->expire_at : $end;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will determine the minimum contract term for a service, which is the maximum of
|
||||
* this::type->contract_term, or the product->type->contract_term();
|
||||
@@ -544,7 +569,7 @@ class Service extends Model implements IDs
|
||||
*/
|
||||
public function getContractTermAttribute(): int
|
||||
{
|
||||
abort(500,'To implement (Dec 2021)');
|
||||
return $this->product->type->supplied->contract_term ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -570,7 +595,7 @@ class Service extends Model implements IDs
|
||||
$date = $last
|
||||
? $last->addDay()
|
||||
: ($this->date_next_invoice ? $this->date_next_invoice->clone()
|
||||
: ($this->date_start ?: Carbon::now()));
|
||||
: ($this->start_at ?: Carbon::now()));
|
||||
|
||||
return request()->wantsJson() ? $date->format('Y-m-d') : $date;
|
||||
}
|
||||
@@ -705,8 +730,9 @@ class Service extends Model implements IDs
|
||||
: NULL;
|
||||
|
||||
// For SSL Certificates, the invoice_to date is the expiry date of the Cert
|
||||
if (is_null($result) AND $this->type AND $this->type->type == 'ssl' AND $this->type->valid_to)
|
||||
return $this->type->valid_to;
|
||||
// @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;
|
||||
}
|
||||
@@ -751,6 +777,17 @@ class Service extends Model implements IDs
|
||||
return $this->getInvoiceNextAttribute();
|
||||
}
|
||||
|
||||
/**
|
||||
* The product we supply for this service
|
||||
*
|
||||
* @return Model
|
||||
* @todo Remove all references to product->type to use this method
|
||||
*/
|
||||
public function getOfferingAttribute(): Model
|
||||
{
|
||||
return $this->product->type;
|
||||
}
|
||||
|
||||
public function getOrderInfoNotesAttribute(): ?string
|
||||
{
|
||||
return $this->getOrderInfoValue('notes');
|
||||
@@ -954,6 +991,16 @@ class Service extends Model implements IDs
|
||||
return ($this->product->type && $this->product->type->supplied) ? $this->product->type->supplied->getTypeAttribute() : '** TBA **';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the service providers offering that we are providing for this service
|
||||
*
|
||||
* @return Model|null
|
||||
*/
|
||||
public function getSupplierProductAttribute(): ?Model
|
||||
{
|
||||
dd($this->product,$this->product->type,$this->product->type->supplied);
|
||||
}
|
||||
|
||||
/**
|
||||
* URL used by an admin to administer the record
|
||||
*
|
||||
@@ -1397,11 +1444,11 @@ class Service extends Model implements IDs
|
||||
|
||||
switch ($this->product->prod_plugin_file)
|
||||
{
|
||||
case 'ADSL': return $this->service_adsl;
|
||||
case 'BROADBAND': return $this->service_broadband;
|
||||
case 'DOMAIN': return $this->service_domain;
|
||||
case 'HOST': return $this->service_host;
|
||||
case 'SSL': return $this->service_ssl;
|
||||
case 'VOIP': return $this->service_voip;
|
||||
case 'PHONE': return $this->service_voip;
|
||||
|
||||
default: return NULL;
|
||||
}
|
||||
|
@@ -6,24 +6,64 @@ use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Leenooks\Carbon;
|
||||
|
||||
use App\Interfaces\{ServiceItem,ServiceUsage};
|
||||
use App\Interfaces\ServiceUsage;
|
||||
use App\Models\Base\ServiceType;
|
||||
use App\Models\Supplier\Broadband as SupplierBroadband;
|
||||
use App\Traits\NextKey;
|
||||
use App\Models\Supplier\Type;
|
||||
|
||||
class Broadband extends ServiceType implements ServiceItem,ServiceUsage
|
||||
/**
|
||||
* Class Broadband (Service)
|
||||
* Services that are Internet Broadband
|
||||
*/
|
||||
class Broadband extends ServiceType implements ServiceUsage
|
||||
{
|
||||
private const LOGKEY = 'MSA';
|
||||
|
||||
use NextKey;
|
||||
const RECORD_ID = 'service__adsl';
|
||||
private const LOGKEY = 'MSB';
|
||||
|
||||
protected $dates = [
|
||||
'service_connect_date',
|
||||
'service_contract_date'
|
||||
'connect_at',
|
||||
'expire_at',
|
||||
];
|
||||
public $dateFormat = 'U';
|
||||
protected $table = 'ab_service__adsl';
|
||||
protected $table = 'service_broadband';
|
||||
|
||||
/* ABSTRACT */
|
||||
|
||||
/**
|
||||
* Search for a record
|
||||
*
|
||||
* @param $query
|
||||
* @param string $term
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeSearch($query,string $term)
|
||||
{
|
||||
// Build our where clause
|
||||
return parent::scopeSearch($query,$term)
|
||||
->orwhere('service_number','like','%'.$term.'%')
|
||||
->orWhere('service_address','like','%'.$term.'%')
|
||||
->orWhere('ipaddress','like','%'.$term.'%');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
/**
|
||||
* Return the service address
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
{
|
||||
return strtoupper($this->service_address) ?: '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the service number
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceNameAttribute(): string
|
||||
{
|
||||
return $this->service_number ?: ($this->service_address ?: '-');
|
||||
}
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
@@ -38,79 +78,37 @@ class Broadband extends ServiceType implements ServiceItem,ServiceUsage
|
||||
return $this->hasMany(AdslTraffic::class,'ab_service_adsl_id');
|
||||
}
|
||||
|
||||
/* SCOPES */
|
||||
|
||||
/**
|
||||
* Search for a record
|
||||
*
|
||||
* @param $query
|
||||
* @param string $term
|
||||
* @return
|
||||
*/
|
||||
public function scopeSearch($query,string $term)
|
||||
{
|
||||
// Build our where clause
|
||||
return parent::scopeSearch($query,$term)
|
||||
->orwhere('service_number','like','%'.$term.'%')
|
||||
->orWhere('service_address','like','%'.$term.'%')
|
||||
->orWhere('ipaddress','like','%'.$term.'%');
|
||||
}
|
||||
/* ATTRIBUTES */
|
||||
|
||||
/**
|
||||
* @deprecated use $o->service_name;
|
||||
* @return mixed|string
|
||||
*/
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
public function getNameAttribute()
|
||||
{
|
||||
abort(500,'deprecated - use $o->service_name');
|
||||
return $this->service_number ?: $this->service_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the service address
|
||||
* The type of technology used to provide this Internet Service
|
||||
*
|
||||
* @return string
|
||||
* @param $value
|
||||
* @return null|string
|
||||
*/
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
public function getTechnologyAttribute($value): ?string
|
||||
{
|
||||
return strtoupper($this->service_address) ?: 'NO Service Address';
|
||||
}
|
||||
|
||||
public function getServiceExpireAttribute(): \Carbon\Carbon
|
||||
{
|
||||
// TODO: Implement getServiceExpireAttribute() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the service number
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceNameAttribute(): string
|
||||
{
|
||||
return $this->service_number ?: $this->service_address;
|
||||
return $value ?: $this->supplied()->technology;
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
/**
|
||||
* Is this service currently in a contract
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function inContract(): bool
|
||||
{
|
||||
return $this->service_contract_date AND $this->service_contract_date->addMonths($this->contract_term)->isFuture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the suppliers offering that this service is providing
|
||||
*
|
||||
* @return SupplierBroadband
|
||||
* @return Type
|
||||
*/
|
||||
public function supplied(): SupplierBroadband
|
||||
public function supplied(): Type
|
||||
{
|
||||
return $this->provided_adsl_plan_id
|
||||
? SupplierBroadband::findOrFail($this->provided_adsl_plan_id)
|
||||
@@ -184,4 +182,4 @@ class Broadband extends ServiceType implements ServiceItem,ServiceUsage
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,97 +2,25 @@
|
||||
|
||||
namespace App\Models\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
use App\Models\Base\ServiceType;
|
||||
use App\Models\{Account,DomainRegistrar,DomainTld,Service};
|
||||
use App\Interfaces\ServiceItem;
|
||||
use App\Traits\{NextKey,ScopeServiceActive,ScopeServiceUserAuthorised};
|
||||
use App\Traits\ServiceDomains;
|
||||
use App\Models\DomainRegistrar;
|
||||
|
||||
/**
|
||||
* Class Domain (Service)
|
||||
* Services that domain names
|
||||
*
|
||||
* Attributes for services:
|
||||
* + service_description : Description as shown in a Service Context
|
||||
* + service_expire : The date the service expires
|
||||
* + service_name : Name as shown in a Service Context
|
||||
*
|
||||
* @package App\Models\Service
|
||||
* Services that are managed Domain Names
|
||||
*/
|
||||
class Domain extends ServiceType implements ServiceItem
|
||||
class Domain extends ServiceType
|
||||
{
|
||||
use ScopeServiceActive,ScopeServiceUserAuthorised;
|
||||
use ServiceDomains;
|
||||
|
||||
protected $dates = [
|
||||
'domain_expire',
|
||||
];
|
||||
public $dateFormat = 'U';
|
||||
protected $table = 'service_domains';
|
||||
protected $table = 'service_domain';
|
||||
protected $with = ['tld'];
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
{
|
||||
// N/A
|
||||
return 'Domain Name';
|
||||
}
|
||||
|
||||
public function getServiceExpireAttribute(): Carbon
|
||||
{
|
||||
return $this->domain_expire;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the domain with its TLD
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceNameAttribute(): string
|
||||
{
|
||||
return strtoupper(sprintf('%s.%s',$this->domain_name,$this->tld->name));
|
||||
}
|
||||
|
||||
public function inContract(): bool
|
||||
{
|
||||
return $this->domain_expire->isFuture();
|
||||
}
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
public function account()
|
||||
{
|
||||
return $this->hasOneThrough(Account::class,Service::class);
|
||||
}
|
||||
|
||||
public function registrar()
|
||||
{
|
||||
return $this->belongsTo(DomainRegistrar::class,'domain_registrar_id');
|
||||
}
|
||||
public function tld()
|
||||
{
|
||||
return $this->belongsTo(DomainTld::class,'domain_tld_id');
|
||||
}
|
||||
|
||||
/* SCOPES */
|
||||
|
||||
/**
|
||||
* Search for a record
|
||||
*
|
||||
* @param $query
|
||||
* @param string $term
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeSearch($query,string $term)
|
||||
{
|
||||
// If we have a period in the name, we'll ignore everything after it.
|
||||
$term = strstr($term,'.',TRUE) ?: $term;
|
||||
|
||||
// Build our where clause
|
||||
return parent::scopeSearch($query,$term)
|
||||
->orwhere('domain_name','like','%'.$term.'%');
|
||||
}
|
||||
|
||||
/* ATTRIBUTES */
|
||||
}
|
@@ -2,64 +2,17 @@
|
||||
|
||||
namespace App\Models\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
use App\Models\Base\ServiceType;
|
||||
use App\Models\{Account, DomainRegistrar, DomainTld, Service, TLD};
|
||||
use App\Interfaces\ServiceItem;
|
||||
use App\Traits\{NextKey,ScopeServiceActive,ScopeServiceUserAuthorised};
|
||||
use App\Traits\ServiceDomains;
|
||||
|
||||
/**
|
||||
* Class Email (Service)
|
||||
* Services that email hostings
|
||||
*
|
||||
* Attributes for services:
|
||||
* + service_description : Description as shown in a Service Context
|
||||
* + service_expire : The date the service expires
|
||||
* + service_name : Name as shown in a Service Context
|
||||
*
|
||||
* @package App\Models\Service
|
||||
* Services that are Email Hosting
|
||||
*/
|
||||
class Email extends ServiceType implements ServiceItem
|
||||
class Email extends ServiceType
|
||||
{
|
||||
use ScopeServiceActive,ScopeServiceUserAuthorised;
|
||||
use ServiceDomains;
|
||||
|
||||
protected $dates = ['expire_at'];
|
||||
protected $table = 'service_emails';
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
{
|
||||
// N/A
|
||||
return 'Email Hosting';
|
||||
}
|
||||
|
||||
public function getServiceExpireAttribute(): Carbon
|
||||
{
|
||||
return $this->expire_at ?: $this->service->next_invoice;
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the domain with its TLD
|
||||
*
|
||||
* @return string
|
||||
* // @todo
|
||||
*/
|
||||
public function getServiceNameAttribute(): string
|
||||
{
|
||||
return strtoupper(sprintf('%s.%s',$this->domain_name,$this->tld->name));
|
||||
}
|
||||
|
||||
public function inContract(): bool
|
||||
{
|
||||
return $this->expire_at && $this->expire_at->isFuture();
|
||||
}
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
public function tld()
|
||||
{
|
||||
return $this->belongsTo(TLD::class);
|
||||
}
|
||||
protected $table = 'service_email';
|
||||
protected $with = ['tld'];
|
||||
}
|
@@ -4,8 +4,21 @@ namespace App\Models\Service;
|
||||
|
||||
use App\Models\Base\ServiceType;
|
||||
|
||||
// @todo Document how this is used.
|
||||
class Generic extends ServiceType
|
||||
{
|
||||
protected $table = 'service__generic';
|
||||
public $timestamps = FALSE;
|
||||
|
||||
/* INTERFACE */
|
||||
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
{
|
||||
return 'Generic';
|
||||
}
|
||||
|
||||
public function getServiceNameAttribute(): string
|
||||
{
|
||||
return 'Generic';
|
||||
}
|
||||
}
|
||||
|
@@ -2,55 +2,25 @@
|
||||
|
||||
namespace App\Models\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
|
||||
use App\Interfaces\ServiceItem;
|
||||
use App\Models\Base\ServiceType;
|
||||
use App\Models\DomainTld;
|
||||
use App\Traits\ServiceDomains;
|
||||
use App\Models\HostServer;
|
||||
use App\Traits\NextKey;
|
||||
use App\Traits\{ScopeServiceActive,ScopeServiceUserAuthorised};
|
||||
|
||||
class Host extends ServiceType implements ServiceItem
|
||||
/**
|
||||
* Class Host (Service)
|
||||
* Services that are Web Hosting
|
||||
*/
|
||||
class Host extends ServiceType
|
||||
{
|
||||
use ScopeServiceActive,ScopeServiceUserAuthorised;
|
||||
use NextKey;
|
||||
const RECORD_ID = 'service__hosting';
|
||||
use ServiceDomains;
|
||||
|
||||
protected $dates = [
|
||||
'host_expire',
|
||||
];
|
||||
public $dateFormat = 'U';
|
||||
protected $table = 'ab_service__hosting';
|
||||
protected $table = 'service_host';
|
||||
protected $with = ['tld'];
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
public function provider()
|
||||
{
|
||||
return $this->belongsTo(HostServer::class,'host_server_id');
|
||||
}
|
||||
|
||||
public function tld()
|
||||
{
|
||||
return $this->belongsTo(DomainTld::class,'domain_tld_id');
|
||||
}
|
||||
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
{
|
||||
// N/A
|
||||
return 'Hosting';
|
||||
}
|
||||
|
||||
public function getServiceExpireAttribute(): Carbon
|
||||
{
|
||||
return $this->host_expire;
|
||||
}
|
||||
|
||||
public function getServiceNameAttribute(): string
|
||||
{
|
||||
return sprintf('%s.%s',strtoupper($this->domain_name),strtoupper($this->tld->name));
|
||||
}
|
||||
|
||||
public function inContract(): bool
|
||||
{
|
||||
return $this->host_expire->isFuture();
|
||||
}
|
||||
}
|
70
app/Models/Service/Phone.php
Normal file
70
app/Models/Service/Phone.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Service;
|
||||
|
||||
use App\Models\Base\ServiceType;
|
||||
|
||||
/**
|
||||
* Class Phone (Service)
|
||||
* Services that are Voice Telephony
|
||||
*/
|
||||
class Phone extends ServiceType
|
||||
{
|
||||
protected $dates = [
|
||||
'connect_at',
|
||||
'expire_at',
|
||||
];
|
||||
protected $table = 'service_phone';
|
||||
|
||||
/* ABSTRACT */
|
||||
|
||||
/**
|
||||
* Search for a record
|
||||
*
|
||||
* @param $query
|
||||
* @param string $term
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeSearch($query,string $term)
|
||||
{
|
||||
// Build our where clause
|
||||
return parent::scopeSearch($query,$term)
|
||||
->orwhere('service_number','like','%'.$term.'%')
|
||||
->orWhere('service_address','like','%'.$term.'%');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
/**
|
||||
* Return the service address
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
{
|
||||
return strtoupper($this->service_address) ?: '-';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the service number
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceNameAttribute(): string
|
||||
{
|
||||
return $this->service_number ?: ($this->service_address ?: '-');
|
||||
}
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
/**
|
||||
* The type of technology used to provide this Internet Service
|
||||
*
|
||||
* @param $value
|
||||
* @return null|string
|
||||
*/
|
||||
public function getTechnologyAttribute($value): ?string
|
||||
{
|
||||
return $value ?: $this->supplied()->technology;
|
||||
}
|
||||
}
|
@@ -5,19 +5,20 @@ namespace App\Models\Service;
|
||||
use Illuminate\Support\Arr;
|
||||
use Carbon\Carbon;
|
||||
|
||||
use App\Interfaces\ServiceItem;
|
||||
use App\Models\Base\ServiceType;
|
||||
use App\Traits\NextKey;
|
||||
|
||||
class SSL extends ServiceType implements ServiceItem
|
||||
/**
|
||||
* Class SSL (Service)
|
||||
* Services that are provide an SSL Certificate
|
||||
*/
|
||||
class SSL extends ServiceType
|
||||
{
|
||||
use NextKey;
|
||||
const RECORD_ID = 'service__ssl';
|
||||
protected $table = 'service_ssl';
|
||||
|
||||
protected $table = 'ab_service__ssl';
|
||||
|
||||
protected $crt_parse = NULL;
|
||||
protected $public_key = NULL;
|
||||
protected $crt_parse = NULL;
|
||||
|
||||
/* STATIC */
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
@@ -33,11 +34,27 @@ class SSL extends ServiceType implements ServiceItem
|
||||
});
|
||||
}
|
||||
|
||||
public function getValidToAttribute()
|
||||
/* ABSTRACT */
|
||||
|
||||
/**
|
||||
* Search for a record
|
||||
*
|
||||
* @param $query
|
||||
* @param string $term
|
||||
* @return mixed
|
||||
*/
|
||||
public function scopeSearch($query,string $term)
|
||||
{
|
||||
return $this->cert ? Carbon::createFromTimestamp($this->crt_parse->get('validTo_time_t')) : NULL;
|
||||
// @todo
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
/**
|
||||
* Return the Cert DN
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
{
|
||||
if ($this->cert)
|
||||
@@ -58,11 +75,19 @@ class SSL extends ServiceType implements ServiceItem
|
||||
}
|
||||
}
|
||||
|
||||
public function getServiceExpireAttribute(): Carbon
|
||||
/**
|
||||
* Return the Certificate Expiry Date
|
||||
*/
|
||||
public function getServiceExpireAttribute(): ?Carbon
|
||||
{
|
||||
// TODO: Implement getServiceExpireAttribute() method.
|
||||
return $this->cert ? Carbon::createFromTimestamp($this->crt_parse->get('validTo_time_t')) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Cert Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceNameAttribute(): string
|
||||
{
|
||||
return $this->cert
|
||||
@@ -70,9 +95,24 @@ class SSL extends ServiceType implements ServiceItem
|
||||
: Arr::get(openssl_csr_get_subject($this->csr),'CN','');
|
||||
}
|
||||
|
||||
/**
|
||||
* Certificates have no contract and can be cancelled anytime.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function inContract(): bool
|
||||
{
|
||||
// N/A
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
/**
|
||||
* @return Carbon|null
|
||||
* @deprecated use getServiceExpireAttribute()
|
||||
*/
|
||||
public function getValidToAttribute()
|
||||
{
|
||||
abort(500,'use getServiceExpireAttribute');
|
||||
}
|
||||
}
|
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Service;
|
||||
|
||||
use App\Interfaces\ServiceItem;
|
||||
use App\Models\Base\ServiceType;
|
||||
use App\Traits\NextKey;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class Voip extends ServiceType implements ServiceItem
|
||||
{
|
||||
use NextKey;
|
||||
const RECORD_ID = 'service__adsl';
|
||||
|
||||
protected $dates = [
|
||||
'service_connect_date',
|
||||
'service_contract_date',
|
||||
];
|
||||
public $dateFormat = 'U';
|
||||
protected $table = 'ab_service__voip';
|
||||
|
||||
/* SCOPES */
|
||||
|
||||
/**
|
||||
* Search for a record
|
||||
*
|
||||
* @param $query
|
||||
* @param string $term
|
||||
* @return
|
||||
*/
|
||||
public function scopeSearch($query,string $term)
|
||||
{
|
||||
// Build our where clause
|
||||
return parent::scopeSearch($query,$term)
|
||||
->orwhere('service_number','like','%'.$term.'%')
|
||||
->orWhere('service_address','like','%'.$term.'%');
|
||||
}
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
/**
|
||||
* Return the service address
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
{
|
||||
return $this->service_address ?: 'VOIP';
|
||||
}
|
||||
|
||||
public function getServiceExpireAttribute(): Carbon
|
||||
{
|
||||
// TODO: Implement getServiceExpireAttribute() method.
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the service number
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getServiceNameAttribute(): string
|
||||
{
|
||||
return $this->service_number ?: ($this->service_address ?: 'Unknown');
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
public function inContract(): bool
|
||||
{
|
||||
return $this->service_contract_date AND $this->service_contract_date->addMonths($this->contract_term)->isFuture();
|
||||
}
|
||||
}
|
16
app/Models/ServiceChange.php
Normal file
16
app/Models/ServiceChange.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* This model records the changes made to services
|
||||
*
|
||||
* @package App\Models
|
||||
*/
|
||||
class ServiceChange extends Model
|
||||
{
|
||||
protected $table = 'service__change';
|
||||
public $timestamps = FALSE;
|
||||
}
|
@@ -7,7 +7,7 @@ use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Leenooks\Traits\ScopeActive;
|
||||
|
||||
use App\Models\Supplier\{Broadband,Domain,Email,Ethernet,Generic,Host,HSPA,Voip};
|
||||
use App\Models\Supplier\{Broadband,Domain,Email,Ethernet,Generic,Host,HSPA,Phone,SSL};
|
||||
|
||||
class Supplier extends Model
|
||||
{
|
||||
@@ -45,14 +45,21 @@ class Supplier extends Model
|
||||
'name' => 'Hosting',
|
||||
'class' => Host::class,
|
||||
],
|
||||
'voip' => [
|
||||
'name' => 'VOIP Telephone',
|
||||
'class' => Voip::class,
|
||||
'phone' => [
|
||||
'name' => 'Phone',
|
||||
'class' => Phone::class,
|
||||
],
|
||||
'ssl' => [
|
||||
'name' => 'SSL',
|
||||
'class' => SSL::class,
|
||||
],
|
||||
];
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
// @todo Need to put in an integrity constraint to support the hasOne()
|
||||
// @todo Some suppliers have multiple different configuration urls/passwords and contacts for different types of services, perhaps this should be hasMany()?
|
||||
// EG: Crazy Domains, "domains" and "hosting".
|
||||
public function detail()
|
||||
{
|
||||
return $this->hasOne(SupplierDetail::class);
|
||||
|
@@ -8,6 +8,7 @@ use Illuminate\Support\Collection;
|
||||
use App\Interfaces\SupplierItem;
|
||||
use App\Models\Product\Broadband as ProductBroadband;
|
||||
|
||||
// @todo does this need to extend Type? Perhaps have a SupplierType consistent with ServiceType.
|
||||
class Broadband extends Type implements SupplierItem
|
||||
{
|
||||
protected $casts = [
|
||||
@@ -37,7 +38,7 @@ class Broadband extends Type implements SupplierItem
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductBroadband::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
return $this->belongsToMany(ProductBroadband::class,$this->table,'id','id','id','supplier_item_id');
|
||||
}
|
||||
|
||||
public function getBillingIntervalAttribute(): int
|
||||
|
@@ -24,7 +24,7 @@ final class Domain extends Type implements SupplierItem
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductDomain::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
return $this->belongsToMany(ProductDomain::class,$this->table,'id','id','id','supplier_item_id');
|
||||
}
|
||||
|
||||
/* RELATIONS */
|
||||
|
@@ -18,6 +18,6 @@ final class Email extends Type implements SupplierItem
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductEmail::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
return $this->belongsToMany(ProductEmail::class,$this->table,'id','id','id','supplier_item_id');
|
||||
}
|
||||
}
|
@@ -13,7 +13,7 @@ final class Generic extends Type implements SupplierItem
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductGeneric::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
return $this->belongsToMany(ProductGeneric::class,$this->table,'id','id','id','supplier_item_id');
|
||||
}
|
||||
|
||||
public function getBillingIntervalAttribute(): int
|
||||
|
@@ -13,7 +13,7 @@ final class Host extends Type implements SupplierItem
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductHost::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
return $this->belongsToMany(ProductHost::class,$this->table,'id','id','id','supplier_item_id');
|
||||
}
|
||||
|
||||
public function getBillingIntervalAttribute(): int
|
||||
|
@@ -3,17 +3,17 @@
|
||||
namespace App\Models\Supplier;
|
||||
|
||||
use App\Interfaces\SupplierItem;
|
||||
use App\Models\Product\Voip as ProductVoip;
|
||||
use App\Models\Product\Phone as ProductVoip;
|
||||
|
||||
final class Voip extends Type implements SupplierItem
|
||||
final class Phone extends Type implements SupplierItem
|
||||
{
|
||||
protected $table = 'supplier_voip';
|
||||
protected $table = 'supplier_phone';
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductVoip::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
return $this->belongsToMany(ProductVoip::class,$this->table,'id','id','id','supplier_item_id');
|
||||
}
|
||||
|
||||
public function getBillingIntervalAttribute(): int
|
@@ -13,7 +13,7 @@ final class SSL extends Type implements SupplierItem
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductSSL::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
return $this->belongsToMany(ProductSSL::class,$this->table,'id','id','id','supplier_item_id');
|
||||
}
|
||||
|
||||
public function getBillingIntervalAttribute(): int
|
||||
|
Reference in New Issue
Block a user