165 lines
5.0 KiB
PHP
165 lines
5.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models\Supplier;
|
|
|
|
use Illuminate\Support\Arr;
|
|
use Illuminate\Support\Collection;
|
|
|
|
use App\Interfaces\SupplierItem;
|
|
use App\Models\Product\Broadband as ProductBroadband;
|
|
|
|
class Broadband extends Type implements SupplierItem
|
|
{
|
|
protected const category_name = 'Broadband';
|
|
|
|
protected $casts = [
|
|
'offpeak_start' => 'datetime:H:i',
|
|
'offpeak_end' => 'datetime:H:i',
|
|
];
|
|
|
|
protected $table = 'supplier_broadband';
|
|
|
|
// Map the table fields, with the extra fields
|
|
public const traffic_map = [
|
|
'base_up_offpeak' => 'extra_up_offpeak',
|
|
'base_down_offpeak' => 'extra_down_offpeak',
|
|
'base_up_peak' => 'extra_up_peak',
|
|
'base_down_peak' => 'extra_down_peak',
|
|
];
|
|
|
|
// Map the NULL relationships - and where traffic gets applied if NULL
|
|
public const traffic_merge = [
|
|
'extra_up_offpeak' => 'base_down_offpeak',
|
|
'extra_down_offpeak' => 'base_down_peak',
|
|
'extra_up_peak' => 'base_down_peak',
|
|
'extra_down_peak' => 'base_down_peak',
|
|
];
|
|
|
|
/* INTERFACES */
|
|
|
|
/**
|
|
* @return int
|
|
* @deprecated use Product::normalizeBillingInterval()
|
|
*/
|
|
public function getBillingIntervalAttribute(): int
|
|
{
|
|
return 1; // Monthly
|
|
}
|
|
|
|
public function products()
|
|
{
|
|
return $this->hasMany(ProductBroadband::class,'supplier_item_id','id');
|
|
}
|
|
|
|
/* METHODS */
|
|
|
|
/**
|
|
* Determine how traffic is counted for Broadband links.
|
|
*
|
|
* Configuration allows for traffic to fit into the following categories:
|
|
* + down_peak, when not NULL, traffic is included to value of this metric, extra traffic is charged per extra_peak
|
|
* + down_offpeak, when not NULL, traffic is included to the value of metric, extra traffic is charged per extra_offpeak
|
|
*
|
|
* If:
|
|
* + UPLOADS are charged and there are no PEAK/OFFPEAK periods (therefore all
|
|
* traffic is charged), the allowance will be shown as 1 metric - TRAFFIC.
|
|
* + UPLOADS are charged and there are PEAK/OFFPEAK periods the allowance
|
|
* will be shown as 2 metrics - PEAK/OFFPEAK.
|
|
* + UPLOADS are NOT charged and there are no PEAK/OFFPEAK periods the allowance
|
|
* will be shown as 1 metrics - TRAFFIC.
|
|
* + UPLOADS are NOT charged and there are PEAK/OFFPEAK periods the allowance
|
|
* will be shown as 2 metrics - PEAK/OFFPEAK.
|
|
*
|
|
* Thus:
|
|
* (x = up/down, Y=peak/offpeak)
|
|
*
|
|
* + If base_x_Y is NULL, all Y traffic is FREE (ignore respective extra_x_Y setting).
|
|
* + If base_x_Y is a number, all Y traffic is FREE up to the number (evaluate extra_x_Y setting).
|
|
* + If extra_x_Y is a number, charge this amount for traffic over base_x_Y.
|
|
*
|
|
* + If extra_down_peak is NULL this is invalid, treat base_down_peak as NULL
|
|
* + If extra_down_offpeak is NULL add traffic_down_offpeak to traffic_down_peak
|
|
* + If extra_up_peak is NULL add traffic_up_peak to traffic_down_peak
|
|
* + If extra_up_offpeak is NULL add traffic_up_offpeak to traffic_down_offpeak
|
|
*
|
|
* @param Collection|null $config The configuration of the link, if NULL assume the supplieres configuration
|
|
* @param array $data The traffic used on this link, determine whats left or over
|
|
* @param bool $ceil Round the numbers to integers
|
|
* @return array|string
|
|
*/
|
|
public function allowance(Collection $config=NULL,array $data=[],bool $ceil=TRUE)
|
|
{
|
|
$map = collect(self::traffic_map);
|
|
$merge = collect(self::traffic_merge);
|
|
|
|
if (is_null($config))
|
|
$config = collect($config);
|
|
|
|
// If config is null, use the configuration from this Model
|
|
if (! $config->count()) {
|
|
// Base Config
|
|
foreach ($map->keys() as $k)
|
|
$config->put($k,$this->{$k});
|
|
|
|
// Excess Config
|
|
foreach ($map->values() as $k)
|
|
$config->put($k,$this->{$k});
|
|
|
|
// Shaped or Charge
|
|
$config->put('shaped',$this->extra_shaped);
|
|
$config->put('charged',$this->extra_charged);
|
|
|
|
// Metric - used to round down data in $data.
|
|
$config->put('metric',$this->metric);
|
|
}
|
|
|
|
$result = collect();
|
|
|
|
// If data is empty, we'll report on allowance, otherwise we'll report on consumption
|
|
$report = ! $data;
|
|
|
|
// Work out if we charge each period
|
|
foreach ($map as $k => $v) {
|
|
// Anything NULL is not counted
|
|
if (is_null($config->get($k)))
|
|
continue;
|
|
|
|
$x = $report ? $config->get($k) : ($config->get($k)-Arr::get($data,$k,0));
|
|
|
|
if ($ceil)
|
|
$x = (int)ceil($x);
|
|
|
|
// Non-NULL entries are counted as is
|
|
if (! is_null($config->get($v))) {
|
|
// Existing value for this item to be added
|
|
$value = $result->has($k) ? $result->get($k) : 0;
|
|
$result->put($k,$value+$x);
|
|
|
|
// NULL entries are merged into another key
|
|
} else {
|
|
// New Key for this item
|
|
$key = $merge->get($v);
|
|
|
|
// Existing value for this item to be added
|
|
$value = $result->has($key) ? $result->get($key) : 0;
|
|
|
|
// Any value in the existing key, add it too.
|
|
if ($k !== $key AND $result->has($k)) {
|
|
$value += $result->get($k);
|
|
$result->forget($k);
|
|
}
|
|
|
|
$result->put($key,$value+$x);
|
|
}
|
|
}
|
|
|
|
if ($config->has('metric') AND $config->get('metric'))
|
|
$result->transform(function($item) use ($config,$ceil) {
|
|
return $ceil
|
|
? (int)ceil($item/$config->get('metric'))
|
|
: $item/$config->get('metric');
|
|
});
|
|
|
|
return $result;
|
|
}
|
|
} |