2018-05-20 12:53:14 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
2021-06-30 04:00:41 +00:00
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
2018-05-20 12:53:14 +00:00
|
|
|
use Illuminate\Database\Eloquent\Model;
|
2019-07-02 05:28:27 +00:00
|
|
|
use Illuminate\Support\Arr;
|
2021-06-29 06:36:34 +00:00
|
|
|
use Illuminate\Support\Facades\Log;
|
2018-08-11 05:09:41 +00:00
|
|
|
use Illuminate\Http\Request;
|
2018-05-20 12:53:14 +00:00
|
|
|
|
2021-06-29 06:36:34 +00:00
|
|
|
use App\Interfaces\IDs;
|
2019-07-02 05:28:27 +00:00
|
|
|
use App\Traits\NextKey;
|
|
|
|
|
2021-06-29 06:36:34 +00:00
|
|
|
/**
|
|
|
|
* Class Product
|
|
|
|
* Products that are available to sale, and appear on invoices
|
|
|
|
*
|
|
|
|
* Attributes for products:
|
|
|
|
* + lid : Local ID for product (part number)
|
|
|
|
*
|
|
|
|
* @package App\Models
|
|
|
|
*/
|
|
|
|
class Product extends Model implements IDs
|
2018-05-20 12:53:14 +00:00
|
|
|
{
|
2021-06-30 04:00:41 +00:00
|
|
|
use HasFactory,NextKey;
|
|
|
|
|
2019-07-02 05:28:27 +00:00
|
|
|
const RECORD_ID = 'product';
|
2020-02-09 12:12:34 +00:00
|
|
|
public $incrementing = FALSE;
|
2019-07-02 05:28:27 +00:00
|
|
|
|
|
|
|
const CREATED_AT = 'date_orig';
|
|
|
|
const UPDATED_AT = 'date_last';
|
2020-02-12 10:32:57 +00:00
|
|
|
|
2019-07-02 05:28:27 +00:00
|
|
|
public $dateFormat = 'U';
|
2020-02-12 10:32:57 +00:00
|
|
|
protected $table = 'ab_product';
|
|
|
|
|
|
|
|
protected $casts = [
|
|
|
|
// @todo convert existing data to a json array
|
|
|
|
// 'price_group'=>'array',
|
|
|
|
];
|
|
|
|
|
|
|
|
protected $with = ['descriptions'];
|
2019-07-02 05:28:27 +00:00
|
|
|
|
2021-02-17 13:22:50 +00:00
|
|
|
/* RELATIONS */
|
|
|
|
|
2018-05-20 12:53:14 +00:00
|
|
|
public function descriptions()
|
|
|
|
{
|
|
|
|
return $this->hasMany(ProductTranslate::class);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function services()
|
|
|
|
{
|
|
|
|
return $this->hasMany(Service::class);
|
|
|
|
}
|
|
|
|
|
2019-07-02 05:28:27 +00:00
|
|
|
/**
|
|
|
|
* Return a child model with details of the service
|
|
|
|
*
|
|
|
|
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
|
|
|
|
*/
|
|
|
|
public function type()
|
|
|
|
{
|
|
|
|
return $this->morphTo(null,'model','prod_plugin_data');
|
|
|
|
}
|
|
|
|
|
2021-02-17 13:22:50 +00:00
|
|
|
/* ATTRIBUTES */
|
|
|
|
|
2019-06-07 06:54:27 +00:00
|
|
|
/**
|
|
|
|
* Get the service category (from the product)
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
2018-08-09 14:10:51 +00:00
|
|
|
public function getCategoryAttribute()
|
|
|
|
{
|
2019-06-07 06:54:27 +00:00
|
|
|
return $this->prod_plugin_file ?: 'Other';
|
2018-08-09 14:10:51 +00:00
|
|
|
}
|
|
|
|
|
2018-08-11 05:09:41 +00:00
|
|
|
public function getContractTermAttribute()
|
|
|
|
{
|
|
|
|
switch ($this->prod_plugin_file) {
|
|
|
|
case 'ADSL': return $this->plugin()->contract_term;
|
|
|
|
// @todo Incorporate into DB
|
|
|
|
case 'VOIP': return 12;
|
|
|
|
|
|
|
|
// @todo Change this after contracts implemented.
|
|
|
|
default:
|
|
|
|
return 'TBA';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDefaultBillingAttribute()
|
|
|
|
{
|
2020-01-11 11:05:05 +00:00
|
|
|
return Arr::get($this->PricePeriods(),$this->price_recurr_default);
|
2018-08-11 05:09:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getDefaultCostAttribute()
|
|
|
|
{
|
|
|
|
// @todo Integrate this into a Tax::class
|
2020-01-11 11:05:05 +00:00
|
|
|
return Arr::get($this->price_array,sprintf('%s.1.price_base',$this->price_recurr_default))*1.1;
|
2018-08-11 05:09:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private function getDefaultLanguage()
|
|
|
|
{
|
2021-12-17 04:58:24 +00:00
|
|
|
return config('site')->language;
|
2018-08-11 05:09:41 +00:00
|
|
|
}
|
|
|
|
|
2018-08-09 14:10:51 +00:00
|
|
|
public function getDescriptionAttribute()
|
|
|
|
{
|
|
|
|
// @todo If the user has selected a specific language.
|
|
|
|
return $this->description($this->getDefaultLanguage());
|
|
|
|
}
|
|
|
|
|
2021-06-29 06:36:34 +00:00
|
|
|
/**
|
|
|
|
* Product Local ID
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getLIDattribute(): string
|
|
|
|
{
|
|
|
|
return sprintf('%04s',$this->id);
|
|
|
|
}
|
|
|
|
|
2018-08-11 05:09:41 +00:00
|
|
|
public function getMinimumCostAttribute()
|
|
|
|
{
|
|
|
|
$table = [
|
|
|
|
0=>4,
|
|
|
|
1=>1,
|
|
|
|
2=>1/3,
|
|
|
|
3=>1/6,
|
|
|
|
4=>1/12,
|
|
|
|
5=>1/24,
|
|
|
|
6=>1/36,
|
|
|
|
7=>1/48,
|
|
|
|
8=>1/60,
|
|
|
|
];
|
|
|
|
|
2020-01-11 11:05:05 +00:00
|
|
|
return $this->setup_cost + ( $this->default_cost * Arr::get($table,$this->price_recurr_default) * $this->contract_term);
|
2018-08-11 05:09:41 +00:00
|
|
|
}
|
|
|
|
|
2018-08-12 07:07:32 +00:00
|
|
|
public function getNameAttribute(Language $lo=NULL)
|
2018-08-09 14:10:51 +00:00
|
|
|
{
|
2018-08-12 07:07:32 +00:00
|
|
|
if (is_null($lo))
|
|
|
|
$lo = $this->getDefaultLanguage();
|
|
|
|
|
|
|
|
return $this->descriptions->where('language_id',$lo->id)->first()->description_short;
|
2018-08-09 14:10:51 +00:00
|
|
|
}
|
|
|
|
|
2019-07-02 05:28:27 +00:00
|
|
|
public function getNameShortAttribute(Language $lo=NULL)
|
|
|
|
{
|
|
|
|
if (is_null($lo))
|
|
|
|
$lo = $this->getDefaultLanguage();
|
|
|
|
|
|
|
|
return $this->descriptions->where('language_id',$lo->id)->first()->name;
|
|
|
|
}
|
|
|
|
|
2018-08-11 05:09:41 +00:00
|
|
|
public function getProductTypeAttribute()
|
|
|
|
{
|
|
|
|
return $this->plugin()->product->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getPriceArrayAttribute()
|
|
|
|
{
|
2020-02-18 11:35:20 +00:00
|
|
|
try {
|
|
|
|
return unserialize($this->attributes['price_group']);
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
Log::debug('Problem with Price array in product ',['pid'=>$this->id]);
|
|
|
|
return [];
|
|
|
|
}
|
2018-08-11 05:09:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getPriceTypeAttribute()
|
|
|
|
{
|
|
|
|
$table = [
|
|
|
|
0=>_('One-time Charge'),
|
|
|
|
1=>_('Recurring Membership/Subscription'),
|
|
|
|
2=>_('Trial for Membership/Subscription'),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2018-08-01 07:09:38 +00:00
|
|
|
public function getProductIdAttribute()
|
|
|
|
{
|
|
|
|
return sprintf('#%04s',$this->id);
|
|
|
|
}
|
|
|
|
|
2018-08-11 05:09:41 +00:00
|
|
|
public function getSetupCostAttribute()
|
|
|
|
{
|
|
|
|
// @todo Integrate this into a Tax::class
|
2020-01-11 11:05:05 +00:00
|
|
|
return Arr::get($this->price_array,sprintf('%s.1.price_setup',$this->price_recurr_default))*1.1;
|
2018-08-11 05:09:41 +00:00
|
|
|
}
|
|
|
|
|
2021-06-29 06:36:34 +00:00
|
|
|
/**
|
|
|
|
* Product System ID
|
|
|
|
*
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function getSIDattribute(): string
|
|
|
|
{
|
|
|
|
return sprintf('%02s-%s',$this->site_id,$this->getLIDattribute());
|
|
|
|
}
|
|
|
|
|
2021-02-17 13:22:50 +00:00
|
|
|
/**
|
|
|
|
* Return if this product captures usage data
|
|
|
|
*
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function hasUsage(): bool
|
|
|
|
{
|
|
|
|
// @todo This should be configured in the DB
|
|
|
|
return in_array($this->model, ['App\Models\Product\Adsl']);
|
|
|
|
}
|
|
|
|
|
2018-08-09 14:10:51 +00:00
|
|
|
public function scopeActive()
|
|
|
|
{
|
|
|
|
return $this->where('active',TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function description(Language $lo=NULL)
|
|
|
|
{
|
|
|
|
if (is_null($lo))
|
|
|
|
$lo = $this->getDefaultLanguage();
|
|
|
|
|
2018-08-12 07:07:32 +00:00
|
|
|
return $this->descriptions->where('language_id',$lo->id)->first()->description_full;
|
2018-08-09 14:10:51 +00:00
|
|
|
}
|
|
|
|
|
2018-08-11 05:09:41 +00:00
|
|
|
public function orderValidation(Request $request)
|
2018-08-09 14:10:51 +00:00
|
|
|
{
|
2018-08-11 05:09:41 +00:00
|
|
|
return $this->plugin()->orderValidation($request);
|
|
|
|
}
|
|
|
|
|
|
|
|
private function plugin()
|
|
|
|
{
|
|
|
|
switch ($this->prod_plugin_file) {
|
|
|
|
case 'ADSL':
|
|
|
|
return AdslPlan::findOrFail($this->prod_plugin_data);
|
|
|
|
case 'VOIP':
|
|
|
|
return new PlanVoip;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-04 04:55:05 +00:00
|
|
|
/**
|
|
|
|
* Get the price for this product based on the period being requested.
|
|
|
|
*
|
|
|
|
* If the price period doesnt exist, we'll take the default period (0) which should.
|
|
|
|
*
|
|
|
|
* @param int $period
|
|
|
|
* @return mixed
|
|
|
|
*/
|
2020-02-06 22:11:02 +00:00
|
|
|
public function price(int $period,string $key='price_base')
|
2019-07-02 05:28:27 +00:00
|
|
|
{
|
2019-07-04 04:55:05 +00:00
|
|
|
return Arr::get(
|
|
|
|
$this->price_array,
|
2020-02-06 22:11:02 +00:00
|
|
|
sprintf('%s.1.%s',$period,$key),
|
|
|
|
Arr::get($this->price_array,sprintf('%s.0.%s',$period,$key))
|
2019-07-04 04:55:05 +00:00
|
|
|
);
|
2019-07-02 05:28:27 +00:00
|
|
|
}
|
|
|
|
|
2018-08-11 05:09:41 +00:00
|
|
|
public function PricePeriods()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
0=>_('Weekly'),
|
|
|
|
1=>_('Monthly'),
|
|
|
|
2=>_('Quarterly'),
|
|
|
|
3=>_('Semi-Annually'),
|
|
|
|
4=>_('Annually'),
|
|
|
|
5=>_('Two years'),
|
|
|
|
6=>_('Three Years'),
|
|
|
|
7=>_('Four Years'),
|
|
|
|
8=>_('Five Years'),
|
|
|
|
];
|
2018-08-09 14:10:51 +00:00
|
|
|
}
|
|
|
|
|
2018-05-20 12:53:14 +00:00
|
|
|
/**
|
2018-08-09 14:10:51 +00:00
|
|
|
* Get the product name
|
2018-05-20 12:53:14 +00:00
|
|
|
*
|
|
|
|
* @param Language $lo
|
2018-08-01 07:09:38 +00:00
|
|
|
* @return string Product Name
|
2018-05-20 12:53:14 +00:00
|
|
|
*/
|
2018-08-09 14:10:51 +00:00
|
|
|
public function name(Language $lo=NULL)
|
2018-05-20 12:53:14 +00:00
|
|
|
{
|
2018-08-09 14:10:51 +00:00
|
|
|
if (is_null($lo))
|
|
|
|
$lo = $this->getDefaultLanguage();
|
|
|
|
|
2018-05-20 12:53:14 +00:00
|
|
|
return $this->descriptions->where('language_id',$lo->id)->first()->name;
|
|
|
|
}
|
|
|
|
}
|