Compare commits
5 Commits
c4809a311d
...
931f930766
Author | SHA1 | Date | |
---|---|---|---|
931f930766 | |||
5ef1a27a64 | |||
04ae35b1dd | |||
c8f1c97078 | |||
36e379d876 |
@ -52,7 +52,7 @@ class ServiceList extends Command
|
||||
if ((! $this->option('inactive')) && (! $o->is_active))
|
||||
continue;
|
||||
|
||||
if ($this->option('type') && ($o->product->getCategoryAttribute() !== $this->option('type')))
|
||||
if ($this->option('type') && ($o->product->category_lc !== strtolower($this->option('type'))))
|
||||
continue;
|
||||
|
||||
$c = $o->invoiced_items
|
||||
@ -67,8 +67,8 @@ class ServiceList extends Command
|
||||
|
||||
$this->info(sprintf($header,
|
||||
$o->lid,
|
||||
$o->product->getCategoryNameAttribute(),
|
||||
substr($o->product->getNameAttribute(),0,35),
|
||||
$o->product->category_name,
|
||||
substr($o->product->name,0,35),
|
||||
substr($o->name_short,0,40),
|
||||
$o->active ? 'active' : 'inactive',
|
||||
$o->status,
|
||||
|
@ -343,7 +343,7 @@ class ServiceController extends Controller
|
||||
$co->type = $iio->item_type;
|
||||
$co->start_at = $start_at;
|
||||
$co->stop_at = $iio->stop_at;
|
||||
$co->amount = Arr::get($request->broadband,'price') ?: $po->base_charge;
|
||||
$co->amount = Arr::get($request->broadband,'price') ?: $po->base_charge();
|
||||
$co->taxable = TRUE; // @todo this should be determined
|
||||
$co->quantity = $start_at->diffInDays($iio->stop_at)/$iio->start_at->diffInDays($iio->stop_at);
|
||||
$charges->push($co);
|
||||
@ -401,10 +401,10 @@ class ServiceController extends Controller
|
||||
$request->post(),
|
||||
collect($o->type->validation())
|
||||
->keys()
|
||||
->map(fn($item)=>sprintf('%s.%s',$o->product->category,$item))
|
||||
->map(fn($item)=>sprintf('%s.%s',$o->product->category_lc,$item))
|
||||
->combine(array_values($o->type->validation()))
|
||||
->map(fn($item)=>is_string($item)
|
||||
? preg_replace('/^exclude_without:/',sprintf('exclude_without:%s.',$o->product->category),$item)
|
||||
? preg_replace('/^exclude_without:/',sprintf('exclude_without:%s.',$o->product->category_lc),$item)
|
||||
: $item)
|
||||
->merge(
|
||||
[
|
||||
@ -416,7 +416,7 @@ class ServiceController extends Controller
|
||||
'price' => 'nullable|numeric|min:0', // Price we charge the client, if we dont charge supplied/price
|
||||
'cost' => 'nullable|numeric|min:0', // Price we are charged by supplier, if we arent charged supplier/price
|
||||
'supplierid' => 'nullable|string|min:1', // As used on invoices
|
||||
$o->product->category => 'array|min:1',
|
||||
$o->product->category_lc => 'array|min:1',
|
||||
]
|
||||
)
|
||||
->toArray()
|
||||
@ -432,13 +432,13 @@ class ServiceController extends Controller
|
||||
$validated = collect($validator->validated());
|
||||
|
||||
// Store our service type values
|
||||
$o->type->forceFill($validated->get($o->product->category));
|
||||
$o->type->forceFill($validated->get($o->product->category_lc));
|
||||
|
||||
// Some special handling
|
||||
switch ($o->product->category) {
|
||||
switch ($o->product->category_lc) {
|
||||
case 'broadband':
|
||||
// If pppoe is not set, then we dont need username/password
|
||||
$o->type->pppoe = ($x=data_get($validated,$o->product->category.'.pppoe',FALSE));
|
||||
$o->type->pppoe = ($x=data_get($validated,$o->product->category_lc.'.pppoe',FALSE));
|
||||
|
||||
if (! $x) {
|
||||
$o->type->service_username = NULL;
|
||||
@ -470,7 +470,7 @@ class ServiceController extends Controller
|
||||
|
||||
else {
|
||||
// For broadband, start_at is connect_at in the type record
|
||||
switch ($o->product->category) {
|
||||
switch ($o->product->category_lc) {
|
||||
case 'broadband':
|
||||
$o->start_at = $o->type->connect_at;
|
||||
break;
|
||||
|
@ -131,7 +131,7 @@ class ImportCosts implements ShouldQueue
|
||||
if ($so) {
|
||||
// r[1] = Monthly Charge or Extra Charge,r[2] = "On Plan", r[3] = Plan Info
|
||||
$r = [];
|
||||
switch ($so->product->category) {
|
||||
switch ($so->product->category_lc) {
|
||||
case 'broadband':
|
||||
$to = Cost\Broadband::where('site_id',$this->co->site_id)
|
||||
->where('cost_id',$this->co->id)
|
||||
|
@ -31,19 +31,17 @@ class OrderRequestApprove extends Mailable
|
||||
|
||||
/**
|
||||
* Build the message.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function build()
|
||||
{
|
||||
Config::set('site',$this->so->site);
|
||||
|
||||
// @todo This is not consistent with Cancel/Change Request
|
||||
switch ($this->so->product->category) {
|
||||
case 'broadband': $subject = sprintf('%s: %s',$this->so->product->category,$this->so->type->service_address);
|
||||
switch ($this->so->product->category_lc) {
|
||||
case 'broadband': $subject = sprintf('%s: %s',$this->so->product->category_name,$this->so->type->service_address);
|
||||
break;
|
||||
|
||||
case 'phone': $subject = sprintf('%s: %s',$this->so->product->category,$this->so->type->service_number);
|
||||
case 'phone': $subject = sprintf('%s: %s',$this->so->product->category_name,$this->so->type->service_number);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -10,14 +10,13 @@ use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Str;
|
||||
use Intuit\Exceptions\NotTokenException;
|
||||
use Intuit\Traits\ProviderTokenTrait;
|
||||
use Leenooks\Traits\ScopeActive;
|
||||
|
||||
use App\Casts\CollectionOrNull;
|
||||
use App\Interfaces\{IDs,ProductItem};
|
||||
use App\Traits\{ProductDetails,ProviderRef};
|
||||
use App\Traits\ProviderRef;
|
||||
|
||||
/**
|
||||
* Class Product
|
||||
@ -33,16 +32,28 @@ use App\Traits\{ProductDetails,ProviderRef};
|
||||
* Attributes for products:
|
||||
* + lid : Local ID for product (part number)
|
||||
* + sid : System ID for product (part number)
|
||||
*
|
||||
* + base_charge : Default billing amount
|
||||
* + billing_interval : Default Billing Interval
|
||||
* + billing_interval_string: Default Billing Interval in human-readable form
|
||||
* + base_cost : Cost for this service
|
||||
*
|
||||
* + billing_interval : Its the max of what we define, or what the supplier bills us at
|
||||
*
|
||||
* + category : Type of product supplied
|
||||
* + category_lc : Category name in lower case
|
||||
* + category_name : Type of product supplied (Friendly Name for display, not for internal logic)
|
||||
*
|
||||
* + contract_term : Contract term for this product
|
||||
*
|
||||
* + description : Product description (description.description_full => description_full)
|
||||
* + min_charge : Minimum charge taking into account billing interval and setup charges
|
||||
* + has_usage : Does this product instrument usage
|
||||
*
|
||||
* + min_cost : Minimum cost for this product
|
||||
*
|
||||
* + name : Details of our product (description.description_short => name_detail)
|
||||
* + pid : Product ID for our Product (description.name => name_short)
|
||||
* + setup_charge : Charge to setup this product
|
||||
*
|
||||
* + setup_cost : Charge by supplier to setup this product
|
||||
*
|
||||
* + supplier : Supplier for this offering
|
||||
*
|
||||
* Attributes for product types (type - Product/*)
|
||||
@ -62,17 +73,45 @@ use App\Traits\{ProductDetails,ProviderRef};
|
||||
* group => [ pricing/setup ]
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
* @package App\Models
|
||||
*/
|
||||
class Product extends Model implements IDs
|
||||
{
|
||||
use HasFactory,ProductDetails,ScopeActive,ProviderRef,ProviderTokenTrait;
|
||||
use HasFactory,ScopeActive,ProviderRef,ProviderTokenTrait;
|
||||
|
||||
protected $casts = [
|
||||
'pricing' => CollectionOrNull::class,
|
||||
];
|
||||
|
||||
public function __get($key): mixed
|
||||
{
|
||||
return match ($key) {
|
||||
'base_cost' => round($this->supplied->base_cost,2)*Invoice::billing_change($this->type->billing_interval,$this->billing_interval) ?: 0,
|
||||
|
||||
'billing_interval' => max($this->price_recur_default,$this->type->billing_interval),
|
||||
'billing_interval_name' => Invoice::billing_name($this->billing_interval),
|
||||
|
||||
'category' => $this->supplied->category,
|
||||
'category_lc' => strtolower($this->category),
|
||||
'category_name' => $this->supplied->category_name,
|
||||
|
||||
'contract_term' => $this->type->contract_term,
|
||||
|
||||
'description' => $this->translate->description,
|
||||
|
||||
'has_usage' => $this->type->hasUsage(),
|
||||
|
||||
'min_cost' => $this->supplied->min_cost,
|
||||
|
||||
'name' => $this->translate->name_detail,
|
||||
|
||||
'pid' => $this->translate->name_short,
|
||||
|
||||
'setup_cost' => $this->supplied->setup_cost ?: 0,
|
||||
|
||||
default => parent::__get($key),
|
||||
};
|
||||
}
|
||||
|
||||
/* STATIC */
|
||||
|
||||
/**
|
||||
@ -162,125 +201,6 @@ class Product extends Model implements IDs
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
/**
|
||||
* The amount we invoice each time period for this service
|
||||
*
|
||||
* @param int|NULL $timeperiod
|
||||
* @param Group|NULL $go
|
||||
* @return float
|
||||
*/
|
||||
public function getBaseChargeAttribute(int $timeperiod=NULL,Group $go=NULL): float
|
||||
{
|
||||
return $this->_charge('base',$timeperiod,$go);
|
||||
}
|
||||
|
||||
/**
|
||||
* The base cost of this product at the appropriate billing interval
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getBaseCostAttribute(): float
|
||||
{
|
||||
return round($this->supplied->base_cost,2)*Invoice::billing_change($this->type->billing_interval,$this->billing_interval) ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our default billing interval
|
||||
* Its the max of what we define, or what the supplier bills us at
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getBillingIntervalAttribute(): int
|
||||
{
|
||||
return max($this->price_recur_default,$this->type->billing_interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will return the category of the product (eg: domain, webhosting, etc) which is the basis for all
|
||||
* other logic of these types.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getCategoryAttribute(): string
|
||||
{
|
||||
return strtolower(Str::studly($this->category_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of service is provided. eg: Broadband, Phone.
|
||||
* 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
|
||||
*/
|
||||
public function getCategoryNameAttribute(): string
|
||||
{
|
||||
return $this->supplied->category_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* How long must this product be purchased for as a service.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getContractTermAttribute(): int
|
||||
{
|
||||
return $this->type->contract_term;
|
||||
}
|
||||
|
||||
/**
|
||||
* This product full description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDescriptionAttribute(): string
|
||||
{
|
||||
return $this->translate->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum charge for this product
|
||||
*
|
||||
* @param int|null $timeperiod
|
||||
* @param Group|null $go
|
||||
* @return float
|
||||
*/
|
||||
public function getMinChargeAttribute(int $timeperiod=NULL,Group $go=NULL): float
|
||||
{
|
||||
return $this->getSetupChargeAttribute($timeperiod,$go)
|
||||
+ $this->getBaseChargeAttribute($timeperiod,$go)*Invoice::billing_change($this->billing_interval,$this->type->billing_interval)*$this->type->contract_term;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the minimum cost for this product
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getMinCostAttribute(): float
|
||||
{
|
||||
return $this->supplied->min_cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our products short descriptive name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getNameAttribute(): string
|
||||
{
|
||||
return $this->translate->name_detail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Our products PID
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPIDAttribute(): string
|
||||
{
|
||||
return $this->translate->name_short;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suppliers product
|
||||
*
|
||||
@ -301,28 +221,6 @@ class Product extends Model implements IDs
|
||||
return $this->supplied->supplier;
|
||||
}
|
||||
|
||||
/**
|
||||
* The charge to setup this service
|
||||
*
|
||||
* @param int|null $timeperiod
|
||||
* @param Group|null $go
|
||||
* @return float
|
||||
*/
|
||||
public function getSetupChargeAttribute(int $timeperiod=NULL,Group $go=NULL): float
|
||||
{
|
||||
return $this->_charge('setup',$timeperiod,$go);
|
||||
}
|
||||
|
||||
/**
|
||||
* The cost to setup this service
|
||||
*
|
||||
* @return float
|
||||
*/
|
||||
public function getSetupCostAttribute(): float
|
||||
{
|
||||
return $this->supplied->setup_cost ?: 0;
|
||||
}
|
||||
|
||||
/* METHODS */
|
||||
|
||||
/**
|
||||
@ -383,6 +281,18 @@ class Product extends Model implements IDs
|
||||
->values();
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount we invoice each time period for this service
|
||||
*
|
||||
* @param int|NULL $timeperiod
|
||||
* @param Group|NULL $go
|
||||
* @return float
|
||||
*/
|
||||
public function base_charge(?int $timeperiod=NULL,?Group $go=NULL): float
|
||||
{
|
||||
return $this->_charge('base',$timeperiod,$go);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the charge from the pricing table for the specific time period and group
|
||||
*
|
||||
@ -408,24 +318,16 @@ class Product extends Model implements IDs
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a normalize price dependent on the product, ie: Broadband = Monthly, Domain = Yearly, etc
|
||||
* Get the minimum charge for this product
|
||||
*
|
||||
* @note: By definition products are normalised, as their cost price is based on the default billing interval
|
||||
* @param int|null $timeperiod
|
||||
* @param Group|null $go
|
||||
* @return float
|
||||
*/
|
||||
public function cost_normalized(): float
|
||||
public function min_charge(int $timeperiod=NULL,Group $go=NULL): float
|
||||
{
|
||||
return number_format(config('site')->taxed($this->supplied->base_cost),2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if this product captures usage data
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasUsage(): bool
|
||||
{
|
||||
return $this->type->hasUsage();
|
||||
return $this->setup_charge($timeperiod,$go)
|
||||
+ $this->base_charge($timeperiod,$go)*Invoice::billing_change($this->billing_interval,$this->type->billing_interval)*$this->contract_term;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -438,4 +340,16 @@ class Product extends Model implements IDs
|
||||
{
|
||||
return $this->type->orderValidation($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* The charge to setup this service
|
||||
*
|
||||
* @param int|null $timeperiod
|
||||
* @param Group|null $go
|
||||
* @return float
|
||||
*/
|
||||
public function setup_charge(?int $timeperiod=NULL,?Group $go=NULL): float
|
||||
{
|
||||
return $this->_charge('setup',$timeperiod,$go);
|
||||
}
|
||||
}
|
@ -10,7 +10,7 @@ use App\Traits\{OrderServiceOptions,ProductDetails,SiteID};
|
||||
|
||||
abstract class Type extends Model
|
||||
{
|
||||
use SiteID,ProductDetails,OrderServiceOptions;
|
||||
use SiteID,OrderServiceOptions;
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
|
@ -291,7 +291,7 @@ class Service extends Model implements IDs
|
||||
'billing_cost_orig_normalised_taxed' => $this->billing_cost_orig_taxed*Invoice::billing_change($this->product->type->billing_interval,Invoice::BILL_MONTHLY),
|
||||
'billing_cost_orig_taxed' => $this->account->taxed($this->billing_cost_orig),
|
||||
|
||||
'billing_charge_orig' => $this->product->getBaseChargeAttribute($this->billing_interval,$this->account->group),
|
||||
'billing_charge_orig' => $this->product->base_charge($this->billing_interval,$this->account->group),
|
||||
'billing_charge_orig_normalised_taxed' => $this->billing_charge_orig_taxed*Invoice::billing_change($this->billing_interval,Invoice::BILL_MONTHLY),
|
||||
'billing_charge_orig_taxed' => $this->account->taxed($this->billing_charge_orig),
|
||||
'billing_charge' => $this->billing_charge(),
|
||||
@ -301,7 +301,7 @@ class Service extends Model implements IDs
|
||||
'billing_interval' => $this->recur_schedule ?: $this->product->billing_interval,
|
||||
'billing_interval_name' => Invoice::billing_name($this->billing_interval),
|
||||
|
||||
'contract_term' => max($this->supplied->contract_term,$this->product->type->contract_term),
|
||||
'contract_term' => max($this->product->contract_term,$this->supplied->contract_term),
|
||||
|
||||
'is_active' => $this->active || ($this->order_status && (! in_array($this->order_status,self::INACTIVE_STATUS))),
|
||||
'is_billed' => (! ($this->external_billing || $this->suspend_billing || ($this->price === 0))),
|
||||
@ -608,12 +608,15 @@ class Service extends Model implements IDs
|
||||
{
|
||||
$last = $this->getInvoicedToAttribute();
|
||||
|
||||
if ($this->stop_at && $last->greaterThan($this->stop_at))
|
||||
return NULL;
|
||||
if ($last) {
|
||||
return ($this->stop_at && $last->greaterThan($this->stop_at))
|
||||
? NULL
|
||||
: $last->addDay();
|
||||
}
|
||||
|
||||
return $last
|
||||
? $last->addDay()
|
||||
: (min($this->start_at,$this->invoice_next_at) ?: Carbon::now());
|
||||
return ($this->invoice_next_at)
|
||||
? $this->invoice_next_at
|
||||
: ($this->start_at ?: Carbon::now());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -905,7 +908,7 @@ class Service extends Model implements IDs
|
||||
private function billing_cost(): float
|
||||
{
|
||||
return is_null($this->cost)
|
||||
? $this->product->getBaseCostAttribute()
|
||||
? $this->product->base_cost
|
||||
: $this->cost*Invoice::billing_change($this->product->type->billing_interval,$this->billing_interval);
|
||||
}
|
||||
|
||||
@ -1055,7 +1058,7 @@ class Service extends Model implements IDs
|
||||
// Connection charges are only charged once, so ignore if if we have already billed them
|
||||
if ((! $this->invoiced_items()->where('item_type',InvoiceItem::INVOICEITEM_SETUP)->count())
|
||||
&& (InvoiceItem::distinct('invoice_id')->where('service_id',$this->id)->count() < 2)
|
||||
&& $this->product->getSetupChargeAttribute($this->billing_interval,$this->account->group))
|
||||
&& $this->product->setup_charge($this->billing_interval,$this->account->group))
|
||||
{
|
||||
$ii = new InvoiceItem;
|
||||
|
||||
@ -1063,7 +1066,7 @@ class Service extends Model implements IDs
|
||||
$ii->service_id = $this->id;
|
||||
$ii->product_id = $this->product_id;
|
||||
$ii->item_type = InvoiceItem::INVOICEITEM_SETUP;
|
||||
$ii->price_base = $this->product->getSetupChargeAttribute($this->billing_interval,$this->account->group);
|
||||
$ii->price_base = $this->product->setup_charge($this->billing_interval,$this->account->group);
|
||||
$ii->start_at = $this->invoice_next;
|
||||
$ii->stop_at = $this->invoice_next;
|
||||
$ii->quantity = 1;
|
||||
|
@ -49,8 +49,8 @@ class Supplier extends Model
|
||||
|
||||
if ($so) {
|
||||
// If we have a connections configuration for that supplier, then build the child relationships
|
||||
if (Arr::get($so->detail->connections,$class->category)) {
|
||||
$result->put($class->category,(object)[
|
||||
if (Arr::get($so->detail->connections,$class->category_lc)) {
|
||||
$result->put($class->category_lc,(object)[
|
||||
'type' => $class->category_name,
|
||||
'items' => $class->where('supplier_detail_id',$so->detail->id),
|
||||
]);
|
||||
@ -63,13 +63,13 @@ class Supplier extends Model
|
||||
$o->where('supplier_detail_id',$so->detail->id);
|
||||
|
||||
if ($o->count())
|
||||
$result->put($class->category,(object)[
|
||||
$result->put($class->category_lc,(object)[
|
||||
'type' => $class->category_name,
|
||||
'items' => $class->where('supplier_detail_id',$so->detail->id),
|
||||
]);
|
||||
|
||||
} else {
|
||||
$result->put($class->category_name,$class);
|
||||
$result->put($class->category_lc,$class);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,10 +10,31 @@ use Leenooks\Traits\ScopeActive;
|
||||
use App\Models\{Invoice, Supplier, SupplierDetail};
|
||||
use App\Traits\SiteID;
|
||||
|
||||
/**
|
||||
* Class Supplier\Type
|
||||
*
|
||||
* Attributes for supplier types:
|
||||
* + category : This will return the category of the product (eg: domain, hosting, etc), based on the class, which is the basis for all other logic of these types.
|
||||
* + category_name : A friendly name that can override category
|
||||
*/
|
||||
|
||||
abstract class Type extends Model
|
||||
{
|
||||
use SiteID,ScopeActive;
|
||||
|
||||
protected const category_name = NULL;
|
||||
|
||||
public function __get($key): mixed
|
||||
{
|
||||
return match ($key) {
|
||||
'category' => (new \ReflectionClass($this))->getShortName(),
|
||||
'category_lc' => strtolower($this->category),
|
||||
'category_name' => static::category_name ?: $this->category,
|
||||
|
||||
default => parent::__get($key),
|
||||
};
|
||||
}
|
||||
|
||||
/* RELATIONS */
|
||||
|
||||
/**
|
||||
@ -33,32 +54,6 @@ abstract class Type extends Model
|
||||
|
||||
/* ATTRIBUTES */
|
||||
|
||||
public function getBaseCostAttribute(?float $val): float
|
||||
{
|
||||
return $val ?: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
final public function getContractTermAttribute(?int $val): int
|
||||
{
|
||||
return $val ?: 1;
|
||||
|
@ -1,21 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Consistent Details on Products
|
||||
*/
|
||||
namespace App\Traits;
|
||||
|
||||
use App\Models\Invoice;
|
||||
|
||||
trait ProductDetails
|
||||
{
|
||||
/**
|
||||
* Return a human friendly name for the billing interval
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBillingIntervalStringAttribute(): string
|
||||
{
|
||||
return Invoice::billing_name(static::getBillingIntervalAttribute());
|
||||
}
|
||||
}
|
@ -24,7 +24,6 @@ return new class extends Migration
|
||||
$table->boolean('external_billing')->default(false);
|
||||
|
||||
$table->float('price', 10, 0)->nullable();
|
||||
$table->float('price_override', 10, 0)->nullable();
|
||||
$table->boolean('taxable')->default(true);
|
||||
|
||||
$table->integer('recur_schedule')->nullable();
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ Please order the following...
|
||||
| Account | {{ $service->account->name }} |
|
||||
| Service ID | {{ $service->sid }} |
|
||||
| Product | {{ $service->product->name }} |
|
||||
@switch($service->product->category)
|
||||
@switch($service->product->category_lc)
|
||||
@case('broadband')
|
||||
| Address | {{ $service->type->service_address }} |
|
||||
@break;
|
||||
|
@ -7,7 +7,7 @@
|
||||
| Account | {{ $service->account->name }} |
|
||||
| Service ID | {{ $service->sid }} |
|
||||
| Product | {{ $service->product->name }} |
|
||||
@switch($service->product->category)
|
||||
@switch($service->product->category_lc)
|
||||
@case('broadband')
|
||||
| Address | {{ is_object($service->type) ? $service->type->service_address : 'Not Supplied' }} |
|
||||
@break;
|
||||
|
@ -9,7 +9,7 @@ Please cancel the following...
|
||||
| Service ID | {{ $service->sid }} |
|
||||
| Cancel Date | {{ $service->stop_at->format('Y-m-d') }} |
|
||||
| Product | {{ $service->product->name }} |
|
||||
@switch($service->product->category)
|
||||
@switch($service->product->category_lc)
|
||||
@case('broadband')
|
||||
| Address | {{ $service->type->service_address }} |
|
||||
@break;
|
||||
|
@ -8,7 +8,7 @@ Please change the following...
|
||||
| Account | {{ $service->account->name }} |
|
||||
| Service ID | {{ $service->sid }} |
|
||||
| Product | {{ $service->product->name }} |
|
||||
@switch($service->product->category)
|
||||
@switch($service->product->category_lc)
|
||||
@case('broadband')
|
||||
| Address | {{ $service->type->service_address }} |
|
||||
@break;
|
||||
|
@ -59,10 +59,12 @@
|
||||
<span class="h5">Accounting</span>
|
||||
<hr>
|
||||
|
||||
<!-- @todo When returning with a bad value old() is not selecting the previous value, may need to have the full html here instead of a component -->
|
||||
@foreach (ProviderOauth::providers() as $apo)
|
||||
<x-leenooks::form.select :id="sprintf('acc_%d',$apo->id)" :name="sprintf('accounting[%d]',$apo->id)" icon="fa-calculator" :label="ucfirst($apo->name)" :choose="true" :value="$pdo->provider_ref($apo)" old="accounting" :options="$pdo->accounting($apo->name)"/>
|
||||
@endforeach
|
||||
@production
|
||||
<!-- @todo When returning with a bad value old() is not selecting the previous value, may need to have the full html here instead of a component -->
|
||||
@foreach (ProviderOauth::providers() as $apo)
|
||||
<x-leenooks::form.select :id="sprintf('acc_%d',$apo->id)" :name="sprintf('accounting[%d]',$apo->id)" icon="fa-calculator" :label="ucfirst($apo->name)" :choose="true" :value="$pdo->provider_ref($apo)" old="accounting" :options="$pdo->accounting($apo->name)"/>
|
||||
@endforeach
|
||||
@endproduction
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,7 +25,7 @@
|
||||
<td>{{ $so->invoice_to ? $so->invoice_to->format('Y-m-d') : '-' }}</td>
|
||||
<td>{{ $so->active ? 'YES' : 'NO' }}</td>
|
||||
<td class="text-right">{{ $a=number_format($so->billing_charge_normalised_taxed,2) }}</td>
|
||||
<td class="text-right">{{ $b=number_format($so->product->cost_normalized(),2) }}</td>
|
||||
<td class="text-right">{{ $b=number_format($so->billing_cost_normalised_taxed,2) }}</td>
|
||||
<td><button class="btn btn-sm @if($a<$b)btn-danger @else btn-success @endif"><small>@if($a<$b)<i class="fas fa-fw fa-exclamation"></i> @else <i class="fas fa-fw fa-check"></i> @endif</small></button></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
@ -42,7 +42,7 @@
|
||||
<!-- PRODUCT -->
|
||||
<x-leenooks::form.select id="product_id" name="broadband[product_id]" icon="fa-list" label="Product" :helper="$o->product->category_name" groupby="active"
|
||||
:value="$np->id"
|
||||
:options="Product::get()->filter(fn($item)=>$item->category === $np->category)->sortBy('name')->sortByDesc('active')->map(fn($item)=>['id'=>$item->id,'active'=>$item->active,'value'=>$item->name])" required/>
|
||||
:options="Product::get()->filter(fn($item)=>$item->category_lc === $np->category_lc)->sortBy('name')->sortByDesc('active')->map(fn($item)=>['id'=>$item->id,'active'=>$item->active,'value'=>$item->name])" required/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$so->product->category.'.change',['o'=>$so->type])
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$so->product->category_lc.'.change',['o'=>$so->type])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
<div class="row">
|
||||
<!-- Service Details -->
|
||||
<div class="col-12 col-md-5">
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$o->product->category.'.details',['o'=>$o->type])
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$o->product->category_lc.'.details',['o'=>$o->type])
|
||||
@include('theme.backend.adminlte.service.widget.information')
|
||||
</div>
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
<li class="nav-item"><a @class(['nav-link','active'=>! (session()->has('service_update') || session()->has('charge_add'))]) href="#pending_items" data-toggle="tab">Pending Items</a></li>
|
||||
@endif
|
||||
|
||||
@if($o->product->hasUsage())
|
||||
@if($o->product->has_usage)
|
||||
<li class="nav-item"><a @class(['nav-link','active'=>! ($x || (session()->has('service_update') || session()->has('charge_add')))]) href="#traffic" data-toggle="tab">Traffic</a></li>
|
||||
@endif
|
||||
|
||||
@ -70,10 +70,10 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if($o->product->hasUsage())
|
||||
@if($o->product->has_usage)
|
||||
<div @class(['tab-pane','fade','show active'=>! ($x || (session()->has('service_update') || session()->has('charge_add')))]) id="traffic">
|
||||
@if($o->type->usage(30)->count())
|
||||
@include('theme.backend.adminlte.service.widget.'.$o->product->category.'.usagegraph',['o'=>$o->type])
|
||||
@include('theme.backend.adminlte.service.widget.'.$o->product->category_lc.'.usagegraph',['o'=>$o->type])
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
@ -38,7 +38,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$o->product->category.'.order',['o'=>$o->type])
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$o->product->category_lc.'.order',['o'=>$o->type])
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="notes" class="col-sm-2 col-form-label text-right">Notes</label>
|
||||
|
@ -38,7 +38,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$o->product->category.'.order',['o'=>$o->type])
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$o->product->category_lc.'.order',['o'=>$o->type])
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="notes" class="col-sm-2 col-form-label text-right">Notes</label>
|
||||
|
@ -42,7 +42,7 @@
|
||||
<td>{{ $o->supplierid }}</td>
|
||||
<td class="text-right">{{ number_format($o->billing_charge_normalised_taxed,2) }}</td>
|
||||
<td class="text-right">{{ number_format($o->billing_cost_normalised_taxed,2) }}</td>
|
||||
<td class="text-right">{{ $o->product->hasUsage() ? number_format($o->type->usage_summary(0)->sum()/1000,1) : '-' }}</td>
|
||||
<td class="text-right">{{ $o->product->has_usage ? number_format($o->type->usage_summary(0)->sum()/1000,1) : '-' }}</td>
|
||||
<td>{{ $o->product->supplier->name }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
@ -34,22 +34,22 @@
|
||||
<tr>
|
||||
<th>Product</th>
|
||||
<td><a href="{{ route('product',['pdo'=>$o->product_id]) }}">#{{ $o->product_id }}: {{ $o->product->name }}</a></td>
|
||||
<td><a href="{{ route('supplier.product.type',['id'=>$c->supplied->id,'spo'=>$c->supplied->supplier_detail_id,'type'=>$c->supplied->category]) }}">#{{ $c->supplied->id }}: {{ $c->supplied->name_long }}</a></td>
|
||||
<td><a href="{{ route('supplier.product.type',['id'=>$c->supplied->id,'spo'=>$c->supplied->supplier_detail_id,'type'=>$c->category_lc]) }}">#{{ $c->supplied->id }}: {{ $c->supplied->name_long }}</a></td>
|
||||
<td>{{ $c->category_name }}</td>
|
||||
@if($p->exists)
|
||||
<th><a href="{{ route('product',['pdo'=>$p->id]) }}">#{{ $p->id }}: {{ $p->name }}</a></th>
|
||||
<td class="text-center"><a href="{{ route('supplier.product.type',['id'=>$p->supplied->id,'spo'=>$p->supplied->supplier_detail_id,'type'=>$p->supplied->category]) }}">#{{ $p->supplied->id }}: {{ $p->supplied->name_long }}</a></td>
|
||||
<td class="text-center"><a href="{{ route('supplier.product.type',['id'=>$p->supplied->id,'spo'=>$p->supplied->supplier_detail_id,'type'=>$p->category_lc]) }}">#{{ $p->supplied->id }}: {{ $p->supplied->name_long }}</a></td>
|
||||
<td> </td>
|
||||
@endif
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>Setup</th>
|
||||
<td>${{ number_format($b=$o->account->taxed($c->setup_charge),2) }}</td>
|
||||
<td>${{ number_format($b=$o->account->taxed($c->setup_charge()),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($c->setup_cost),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@if($p->exists)
|
||||
<td>${{ number_format($b=$o->account->taxed($p->setup_charge),2) }}</td>
|
||||
<td>${{ number_format($b=$o->account->taxed($p->setup_charge()),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($p->setup_cost),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@endif
|
||||
@ -58,11 +58,11 @@
|
||||
<tr>
|
||||
<th>Billed</th>
|
||||
<td>{{ $o->billing_interval_name }}</td>
|
||||
<td>{{ $c->type->billing_interval_string }}</td>
|
||||
<td>{{ $c->billing_interval_name }}</td>
|
||||
<td> </td>
|
||||
@if($p->exists)
|
||||
<td>{{ $o->billing_interval_name }}</td>
|
||||
<td>{{ $p->type->billing_interval_string }}</td>
|
||||
<td>{{ $p->billing_interval_name }}</td>
|
||||
<td> </td>
|
||||
@endif
|
||||
</tr>
|
||||
@ -73,7 +73,7 @@
|
||||
<td @class(['text-danger'=>$o->is_cost_overridden])>${{ number_format($a=$o->billing_cost_taxed,2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@if($p->exists)
|
||||
<td @if($o->is_charge_overridden)class="text-danger"@endif>${{ number_format($b=$o->account->taxed($p->base_charge),2) }}</td>
|
||||
<td @if($o->is_charge_overridden)class="text-danger"@endif>${{ number_format($b=$o->account->taxed($p->base_charge()),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($p->base_cost),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@endif
|
||||
@ -97,7 +97,7 @@
|
||||
</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@if($p->exists)
|
||||
<td @class(['text-danger'=>$o->is_charge_overridden])>${{ number_format($b=$o->account->taxed($p->base_charge)*Invoice::billing_change($o->billing_interval,Invoice::BILL_MONTHLY),2) }}</td>
|
||||
<td @class(['text-danger'=>$o->is_charge_overridden])>${{ number_format($b=$o->account->taxed($p->base_charge())*Invoice::billing_change($o->billing_interval,Invoice::BILL_MONTHLY),2) }}</td>
|
||||
<td @class(['text-danger'=>$o->is_cost_overridden])>${{ number_format($a=$o->account->taxed($p->base_cost)*Invoice::billing_change($o->billing_interval,Invoice::BILL_MONTHLY),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@endif
|
||||
@ -118,13 +118,13 @@
|
||||
<tr>
|
||||
<th>Min Price</th>
|
||||
<!-- @todo change this to $o->min_charge when implemented -->
|
||||
<td>${{ number_format($b=$o->account->taxed($o->product->min_charge),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($c->supplied->min_cost),2) }}</td>
|
||||
<td>${{ number_format($b=$o->account->taxed($o->product->min_charge()),2) }}ZZ</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($c->min_cost),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
|
||||
@if($p->exists)
|
||||
<td>${{ number_format($a=$o->account->taxed($p->min_charge),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($p->supplied->min_cost ?? 0),2) }}</td>
|
||||
<td>${{ number_format($a=$o->account->taxed($p->min_cost),2) }}</td>
|
||||
<td>{!! markup($a,$b) !!}</td>
|
||||
@endif
|
||||
</tr>
|
||||
|
@ -51,13 +51,13 @@
|
||||
:value="$o->product_id"
|
||||
:options="Product::with(['type.supplied','translate'])
|
||||
->get()
|
||||
->filter(fn($item)=>($item->category === $o->product->category))
|
||||
->filter(fn($item)=>($item->category_lc === $o->product->category_lc))
|
||||
->sortBy('name')
|
||||
->map(fn($item)=>[
|
||||
'id'=>$item->id,
|
||||
'value'=>sprintf('%s $%3.2f [%s/%3.2f]',
|
||||
$item->name,
|
||||
$o->account->taxed($item->base_charge)*Invoice::billing_change($item->billing_interval,Invoice::BILL_MONTHLY),
|
||||
$o->account->taxed($item->base_charge())*Invoice::billing_change($item->billing_interval,Invoice::BILL_MONTHLY),
|
||||
$item->supplied->name,
|
||||
$o->account->taxed($item->base_cost)*Invoice::billing_change($item->billing_interval,Invoice::BILL_MONTHLY),
|
||||
)])" :required="true"/>
|
||||
@ -65,7 +65,7 @@
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$o->product->category.'.update',['o'=>$o->type])
|
||||
@includeIf('theme.backend.adminlte.service.widget.'.$o->product->category_lc.'.update',['o'=>$o->type])
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
|
@ -53,7 +53,7 @@ if(isset($spo)) {
|
||||
|
||||
<div class="col-4">
|
||||
<!-- Offering Type -->
|
||||
<x-leenooks::form.select name="offering_type" icon="fa-cogs" label="Type" helper="Offering Type" :choose="true" :value="$oo?->category ?? ''" :options="Supplier::offeringTypes()->sortBy(fn($item)=>$item->category_name)->map(fn($item)=>['id'=>$item->category,'value'=>$item->category_name])"/>
|
||||
<x-leenooks::form.select name="offering_type" icon="fa-cogs" label="Type" helper="Offering Type" :choose="true" :value="$oo?->category_lc ?? ''" :options="Supplier::offeringTypes()->sortBy(fn($item)=>$item->category_name)->map(fn($item)=>['id'=>$item->category_lc,'value'=>$item->category_name])"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -180,7 +180,7 @@ if(isset($spo)) {
|
||||
$(document).ready(function() {
|
||||
@if(isset($oo) && $oo->exists)
|
||||
$('#offering_type').attr('style','pointer-events: none;');
|
||||
load_type('{{$oo->category}}',{{$oo->id}})
|
||||
load_type('{{$oo->category_lc}}',{{$oo->id}})
|
||||
@endif
|
||||
|
||||
$('#offering_type').on('change',function() {
|
||||
|
@ -37,7 +37,7 @@
|
||||
<tbody>
|
||||
@foreach($xx=$offering->items->with(['products.products.services'])->get() as $oo)
|
||||
<tr>
|
||||
<td><a href="{{ route('supplier.product.type',['id'=>$oo->id,'spo'=>$oo->supplier_detail_id,'type'=>$oo->category]) }}">{{ $oo->id }}</a></td>
|
||||
<td><a href="{{ route('supplier.product.type',['id'=>$oo->id,'spo'=>$oo->supplier_detail_id,'type'=>$oo->category_lc]) }}">{{ $oo->id }}</a></td>
|
||||
<td>{{ $oo->name }}</td>
|
||||
<td>{{ $oo->name_long }}</td>
|
||||
<td class="text-right">{{ $oo->active ? 'YES' : 'NO' }}</td>
|
||||
|
@ -40,14 +40,14 @@
|
||||
@foreach($oo->products->pluck('products')->flatten()->filter() as $po)
|
||||
<tr>
|
||||
<td><a href="{{ route('product',['pdo'=>$po->id]) }}">{{ $po->lid }}</a></td>
|
||||
<td>{{ $po->pid }} <small>[<a href="{{ route('supplier.product.type',['id'=>$po->supplied->id,'spo'=>$po->supplier->id,'type'=>$po->supplied->category]) }}">{{ $po->supplied->name }}</a>]</small></td>
|
||||
<td>{{ $po->pid }} <small>[<a href="{{ route('supplier.product.type',['id'=>$po->supplied->id,'spo'=>$po->supplier->id,'type'=>$po->category_lc]) }}">{{ $po->supplied->name }}</a>]</small></td>
|
||||
<td>{{ $po->name }}</td>
|
||||
<td class="text-right">{{ $po->active ? 'YES' : 'NO' }}</td>
|
||||
<td class="text-right">{{ $po->billing_interval_string }}</td>
|
||||
<td class="text-right">{{ $po->billing_interval_name }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->setup_cost),2) }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->base_cost),2) }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->setup_charge),2) }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->base_charge),2) }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->setup_charge()),2) }}</td>
|
||||
<td class="text-right">{{ number_format($site->taxed($po->base_charge()),2) }}</td>
|
||||
<td class="text-right">{{ number_format($po->services->count()) }}</td>
|
||||
<td class="text-right">{{ number_format($po->services->where('active')->count()) }}</td>
|
||||
</tr>
|
||||
|
@ -1,9 +1,9 @@
|
||||
<!-- $pdo=Product::class [{{$pdo->category}}]-->
|
||||
@if(View::exists('theme.frontend.metronic.order.widget.info.'.$pdo->category))
|
||||
@if(View::exists('theme.frontend.metronic.order.widget.info.'.$pdo->category_lc))
|
||||
<div class="box box-primary">
|
||||
<div class="box-body">
|
||||
{{-- Return Category Requirements --}}
|
||||
@include('theme.frontend.metronic.order.widget.info.'.$pdo->category)
|
||||
@include('theme.frontend.metronic.order.widget.info.'.$pdo->category_lc)
|
||||
|
||||
{{-- Return Supplier Requirements --}}
|
||||
{{-- Return Product Requirements --}}
|
||||
|
@ -10,21 +10,21 @@
|
||||
<th>Type</th>
|
||||
<td class="text-right">{{ $pdo->category_name }}</td>
|
||||
</tr>
|
||||
@if ($pdo->setup_charge)
|
||||
@if ($pdo->setup_charge())
|
||||
<tr>
|
||||
<th>Setup Charges <sup>*</sup></th>
|
||||
{{-- @todo this should use account::taxed() when the user is known --}}
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->setup_charge) : Config::get('site')->taxed($pdo->setup_charge),2) }}</td>
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->setup_charge()) : Config::get('site')->taxed($pdo->setup_charge()),2) }}</td>
|
||||
</tr>
|
||||
@endif
|
||||
<tr>
|
||||
<th>Cost <sup>+</sup></th>
|
||||
{{-- @todo this should use account::taxed() when the user is known --}}
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->base_charge) : Config::get('site')->taxed($pdo->base_charge),2) }}</td>
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->base_charge()) : Config::get('site')->taxed($pdo->base_charge()),2) }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Default Billing</th>
|
||||
<td class="text-right">{{ $pdo->billing_interval_string }}</td>
|
||||
<td class="text-right">{{ $pdo->billing_interval_name }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Contract Term</th>
|
||||
@ -33,7 +33,7 @@
|
||||
<tr>
|
||||
<th>Minimum Costs <sup>+*</sup></th>
|
||||
{{-- @todo this should use account::taxed() when the user is known --}}
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->min_charge) : Config::get('site')->taxed($pdo->min_charge),2) }}</td>
|
||||
<td class="text-right">${{ number_format($user->exists ? Config::get('site')->taxed($pdo->min_charge()) : Config::get('site')->taxed($pdo->min_charge()),2) }}</td>
|
||||
</tr>
|
||||
|
||||
<tfoot>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!-- $pdo=Product::class [{{$pdo->category}}] -->
|
||||
@if(View::exists('theme.frontend.metronic.order.widget.order.'.$pdo->category))
|
||||
@if(View::exists('theme.frontend.metronic.order.widget.order.'.$pdo->category_lc))
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Order Configuration</h3>
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
<div class="box-body">
|
||||
{{-- Return Category Requirements --}}
|
||||
@include('theme.frontend.metronic.order.widget.order.'.$pdo->category)
|
||||
@include('theme.frontend.metronic.order.widget.order.'.$pdo->category_lc)
|
||||
|
||||
{{-- Return Supplier Requirements --}}
|
||||
{{-- Return Product Requirements --}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user