Added in email hosting, and other misc cosmetic fixes
This commit is contained in:
@@ -9,7 +9,6 @@ use App\Models\Service;
|
||||
abstract class ServiceType extends Model
|
||||
{
|
||||
public $timestamps = FALSE;
|
||||
public $dateFormat = 'U';
|
||||
|
||||
/**
|
||||
* @NOTE: The service_id column could be discarded, if the id column=service_id
|
||||
|
@@ -2,16 +2,18 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Container\Container;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
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\Facades\Log;
|
||||
use Leenooks\Traits\ScopeActive;
|
||||
|
||||
use App\Interfaces\IDs;
|
||||
use App\Interfaces\{IDs,ProductItem};
|
||||
use App\Traits\{ProductDetails,SiteID};
|
||||
|
||||
/**
|
||||
@@ -23,6 +25,7 @@ use App\Traits\{ProductDetails,SiteID};
|
||||
*
|
||||
* Attributes for products:
|
||||
* + lid : Local ID for product (part number)
|
||||
* + sid : System ID for product (part number)
|
||||
* + supplied : Supplier product provided for this offering
|
||||
* + supplier : Supplier for this offering
|
||||
* + name : Brief Name for our product
|
||||
@@ -36,6 +39,7 @@ use App\Traits\{ProductDetails,SiteID};
|
||||
* + base_charge_taxable : Default billing amount including taxes
|
||||
* + min_charge : Minimum cost taking into account billing interval and setup costs
|
||||
* + min_charge_taxable : Minimum cost taking into account billing interval and setup costs including taxes
|
||||
* + type : Returns the underlying product object, representing the type of product
|
||||
*
|
||||
* Attributes for product types (type - Product/*)
|
||||
* + name : Short Name for our Product
|
||||
@@ -66,6 +70,8 @@ class Product extends Model implements IDs
|
||||
'pricing'=>'collection',
|
||||
];
|
||||
|
||||
protected $with = ['description'];
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
/**
|
||||
@@ -145,7 +151,7 @@ class Product extends Model implements IDs
|
||||
*/
|
||||
public function getBaseCostAttribute(): float
|
||||
{
|
||||
return round($this->type->supplied->base_cost*Invoice::billing_change($this->type->supplied->getBillingIntervalAttribute(),$this->getBillingIntervalAttribute()) ?: 0,2);
|
||||
return round($this->getSuppliedAttribute()->base_cost*Invoice::billing_change($this->getSuppliedAttribute()->getBillingIntervalAttribute(),$this->getBillingIntervalAttribute()) ?: 0,2);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -167,7 +173,7 @@ class Product extends Model implements IDs
|
||||
*/
|
||||
public function getBillingIntervalAttribute(): int
|
||||
{
|
||||
return max($this->price_recur_default,$this->type->supplied->getBillingIntervalAttribute());
|
||||
return max($this->price_recur_default,$this->getSuppliedAttribute()->getBillingIntervalAttribute());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -239,10 +245,31 @@ class Product extends Model implements IDs
|
||||
* Get our product type
|
||||
*
|
||||
* @return string
|
||||
* @todo is the test of type and type->supplied necessary?
|
||||
*/
|
||||
public function getProductTypeAttribute(): string
|
||||
{
|
||||
return ($this->type && $this->type->supplied) ? $this->type->supplied->getTypeAttribute() : 'Unknown';
|
||||
return ($this->type && $this->type->supplied) ? $this->getSuppliedAttribute()->getTypeAttribute() : 'Unknown';
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppliers
|
||||
*
|
||||
* @return Model
|
||||
*/
|
||||
public function getSupplierAttribute(): Model
|
||||
{
|
||||
return $this->getSuppliedAttribute()->supplier_detail->supplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppliers product
|
||||
*
|
||||
* @return Model
|
||||
*/
|
||||
public function getSuppliedAttribute(): Model
|
||||
{
|
||||
return $this->type->supplied;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,7 +304,7 @@ class Product extends Model implements IDs
|
||||
*/
|
||||
public function getSetupCostAttribute(): float
|
||||
{
|
||||
return $this->type->supplied->setup_cost ?: 0;
|
||||
return $this->getSuppliedAttribute()->setup_cost ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -294,13 +321,33 @@ class Product extends Model implements IDs
|
||||
/* METHODS */
|
||||
|
||||
/**
|
||||
* Return if this product captures usage data
|
||||
* Return a list of available product types
|
||||
*
|
||||
* @return bool
|
||||
* @return Collection
|
||||
*/
|
||||
public function hasUsage(): bool
|
||||
function availableTypes(): Collection
|
||||
{
|
||||
return $this->type->hasUsage();
|
||||
$models = collect(File::allFiles(app_path()))
|
||||
->map(function ($item) {
|
||||
$path = $item->getRelativePathName();
|
||||
$class = sprintf('%s%s',
|
||||
Container::getInstance()->getNamespace(),
|
||||
strtr(substr($path, 0, strrpos($path, '.')), '/', '\\'));
|
||||
|
||||
return $class;
|
||||
})
|
||||
->filter(function ($class) {
|
||||
$valid = FALSE;
|
||||
|
||||
if (class_exists($class)) {
|
||||
$reflection = new \ReflectionClass($class);
|
||||
$valid = $reflection->isSubclassOf(ProductItem::class) && (! $reflection->isAbstract());
|
||||
}
|
||||
|
||||
return $valid;
|
||||
});
|
||||
|
||||
return $models->values();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -347,6 +394,16 @@ class Product extends Model implements IDs
|
||||
return round($price,2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if this product captures usage data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUsage(): bool
|
||||
{
|
||||
return $this->type->hasUsage();
|
||||
}
|
||||
|
||||
/**
|
||||
* When receiving an order, validate that we have all the required information for the product type
|
||||
*
|
||||
|
@@ -3,6 +3,7 @@
|
||||
namespace App\Models\Product;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Leenooks\Traits\ScopeActive;
|
||||
|
||||
use App\Interfaces\ProductItem;
|
||||
use App\Models\Supplier;
|
||||
@@ -11,6 +12,8 @@ use App\Models\Supplier\Broadband as SupplierBroadband;
|
||||
|
||||
final class Broadband extends Type implements ProductItem
|
||||
{
|
||||
use ScopeActive;
|
||||
|
||||
protected $table = 'product_broadband';
|
||||
|
||||
// Information required during the order process
|
||||
@@ -44,17 +47,6 @@ final class Broadband extends Type implements ProductItem
|
||||
return $this->hasOne(SupplierBroadband::class,'id','supplier_broadband_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* The supplier
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOneThrough
|
||||
*/
|
||||
// @todo To check
|
||||
public function supplier()
|
||||
{
|
||||
return $this->hasOneThrough(Supplier::class,SupplierBroadband::class,'id','id','adsl_supplier_plan_id','supplier_id');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
/**
|
||||
|
69
app/Models/Product/Email.php
Normal file
69
app/Models/Product/Email.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Product;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
use App\Interfaces\ProductItem;
|
||||
use App\Models\Service\Email as ServiceEmail;
|
||||
use App\Models\Supplier\Email as SupplierEmail;
|
||||
|
||||
final class Email extends Type implements ProductItem
|
||||
{
|
||||
protected $table = 'product_email';
|
||||
|
||||
// The model that is referenced when this product is ordered
|
||||
protected string $order_model = ServiceEmail::class;
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
/**
|
||||
* The offering supplied with this product
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasOne
|
||||
*/
|
||||
public function supplied()
|
||||
{
|
||||
return $this->hasOne(SupplierEmail::class,'id','supplier_email_id');
|
||||
}
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
public function allowance(): Collection
|
||||
{
|
||||
// N/A
|
||||
return collect();
|
||||
}
|
||||
|
||||
public function allowance_string(): string
|
||||
{
|
||||
// N/A
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getContractTermAttribute(): int
|
||||
{
|
||||
return 12;
|
||||
}
|
||||
|
||||
public function getCostAttribute(): float
|
||||
{
|
||||
// N/A
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getSupplierAttribute()
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getTypeAttribute()
|
||||
{
|
||||
return 'Domain Name';
|
||||
}
|
||||
|
||||
public function hasUsage(): bool
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
@@ -8,6 +8,8 @@ class ProductTranslate extends Model
|
||||
{
|
||||
protected $table = 'ab_product_translate';
|
||||
|
||||
public $timestamps = FALSE;
|
||||
|
||||
public function getDescriptionFullAttribute($value)
|
||||
{
|
||||
return unserialize($value);
|
||||
|
@@ -27,6 +27,7 @@ use App\Interfaces\IDs;
|
||||
* + additional_cost : Pending additional charges for this service (excluding setup)
|
||||
* + 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
|
||||
* + 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
|
||||
@@ -880,11 +881,11 @@ class Service extends Model implements IDs
|
||||
* This is used for view specific details
|
||||
*
|
||||
* @return string
|
||||
* @todo I think this can be removed - and dynamically determined
|
||||
*/
|
||||
public function getSTypeAttribute(): string
|
||||
{
|
||||
switch($this->product->model) {
|
||||
case 'App\Models\Product\Broadband': return 'broadband';
|
||||
default: return $this->type->type;
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ class AdslTraffic extends Model
|
||||
protected $table = 'ab_service__adsl_traffic';
|
||||
public $timestamps = FALSE;
|
||||
protected $dates = ['date'];
|
||||
public $dateFormat = 'U';
|
||||
private $traffic_end = 14;
|
||||
|
||||
public function broadband()
|
||||
|
@@ -22,6 +22,7 @@ class Broadband extends ServiceType implements ServiceItem,ServiceUsage
|
||||
'service_connect_date',
|
||||
'service_contract_date'
|
||||
];
|
||||
public $dateFormat = 'U';
|
||||
protected $table = 'ab_service__adsl';
|
||||
|
||||
/* RELATIONS */
|
||||
|
@@ -27,46 +27,11 @@ class Domain extends ServiceType implements ServiceItem
|
||||
protected $dates = [
|
||||
'domain_expire',
|
||||
];
|
||||
public $dateFormat = 'U';
|
||||
protected $table = 'service_domains';
|
||||
protected $with = ['tld'];
|
||||
|
||||
/* 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 */
|
||||
/* INTERFACES */
|
||||
|
||||
public function getServiceDescriptionAttribute(): string
|
||||
{
|
||||
@@ -93,4 +58,41 @@ class Domain extends ServiceType implements ServiceItem
|
||||
{
|
||||
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 */
|
||||
}
|
65
app/Models/Service/Email.php
Normal file
65
app/Models/Service/Email.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
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};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
class Email extends ServiceType implements ServiceItem
|
||||
{
|
||||
use ScopeServiceActive,ScopeServiceUserAuthorised;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
@@ -17,6 +17,7 @@ class Host extends ServiceType implements ServiceItem
|
||||
protected $dates = [
|
||||
'host_expire',
|
||||
];
|
||||
public $dateFormat = 'U';
|
||||
protected $table = 'ab_service__hosting';
|
||||
|
||||
public function provider()
|
||||
|
@@ -16,6 +16,7 @@ class Voip extends ServiceType implements ServiceItem
|
||||
'service_connect_date',
|
||||
'service_contract_date',
|
||||
];
|
||||
public $dateFormat = 'U';
|
||||
protected $table = 'ab_service__voip';
|
||||
|
||||
/* SCOPES */
|
||||
|
@@ -7,7 +7,7 @@ use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Leenooks\Traits\ScopeActive;
|
||||
|
||||
use App\Models\Supplier\{Broadband,Domain,Ethernet,Generic,Host,HSPA,Voip};
|
||||
use App\Models\Supplier\{Broadband,Domain,Email,Ethernet,Generic,Host,HSPA,Voip};
|
||||
|
||||
class Supplier extends Model
|
||||
{
|
||||
@@ -33,6 +33,10 @@ class Supplier extends Model
|
||||
'name' => 'Domain Name',
|
||||
'class' => Domain::class,
|
||||
],
|
||||
'email' => [
|
||||
'name' => 'Email Hosting',
|
||||
'class' => Email::class,
|
||||
],
|
||||
'generic' => [
|
||||
'name' => 'Generic',
|
||||
'class' => Generic::class,
|
||||
|
@@ -12,11 +12,6 @@ final class Domain extends Type implements SupplierItem
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductDomain::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
}
|
||||
|
||||
public function getBillingIntervalAttribute(): int
|
||||
{
|
||||
return 4; // Yearly
|
||||
@@ -27,6 +22,11 @@ final class Domain extends Type implements SupplierItem
|
||||
return sprintf('%s: %s',$this->product_id,$this->tld->name);
|
||||
}
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductDomain::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
}
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
public function tld()
|
||||
|
23
app/Models/Supplier/Email.php
Normal file
23
app/Models/Supplier/Email.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Supplier;
|
||||
|
||||
use App\Interfaces\SupplierItem;
|
||||
use App\Models\Product\Email as ProductEmail;
|
||||
|
||||
final class Email extends Type implements SupplierItem
|
||||
{
|
||||
protected $table = 'supplier_email';
|
||||
|
||||
/* INTERFACES */
|
||||
|
||||
public function getBillingIntervalAttribute(): int
|
||||
{
|
||||
return 4; // Yearly
|
||||
}
|
||||
|
||||
public function types()
|
||||
{
|
||||
return $this->belongsToMany(ProductEmail::class,$this->table,'id','id','id',$this->table.'_id');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user