array('model'=>'ADSL_Supplier_Plan','foreign_key'=>'adsl_supplier_plan_id'), ); /** * Filters used to format the display of values into friendlier values */ protected $_display_filters = array( 'extra_down_peak'=>array( array('Tax::add',array(':value')), array('Currency::display',array(':value')), ), 'extra_down_offpeak'=>array( array('Tax::add',array(':value')), array('Currency::display',array(':value')), ), 'extra_up_peak'=>array( array('Tax::add',array(':value')), array('Currency::display',array(':value')), ), 'extra_up_offpeak'=>array( array('Tax::add',array(':value')), array('Currency::display',array(':value')), ), 'extra_charged'=>array( array('StaticList_YesNo::get',array(':value',TRUE)), ), ); protected $_nullifempty = array( 'base_down_peak', 'base_down_offpeak', 'base_up_peak', 'base_up_offpeak', 'extra_down_peak', 'extra_down_offpeak', 'extra_up_peak', 'extra_up_offpeak', ); // Our required abstract methods public function cost($annual=FALSE) { $x = $this->supplier_plan->display('base_cost'); return $annual ? $x*12 : $x; } // @todo Select the ADSL Plan for this product. public function render_edit() { return ''; } public function supplier() { return $this->supplier_plan->supplier_id; } // Local functions // Map the table fields private $_map = array( 'base_up_offpeak'=>'extra_up_offpeak', 'base_down_offpeak'=>'extra_down_offpeak', 'base_up_peak'=>'extra_up_peak', 'base_down_peak'=>'extra_down_peak', ); /** * Calculate the allowance array or traffic used array * * 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: * * + 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 array Traffic Used in each metric. * @param bool Whether the output should be a string * @param bool Display the over allowance numbers * @param int Divide the numbers */ public function allowance(array $data=array(),$format=FALSE,$over=FALSE,$ceil=FALSE) { $result = $x = array(); // Do we invert the result - showing allowance $invert = $data ? FALSE : TRUE; // Map the NULL relationships $merge = array( 'extra_up_offpeak'=>'base_down_offpeak', 'extra_down_offpeak'=>'base_down_peak', 'extra_up_peak'=>'base_down_peak', 'extra_down_peak'=>'base_down_peak', ); // Work out if we charge each period foreach ($this->_map as $k => $v) { // Anything NULL is not counted if (is_null($this->{$k})) continue; if (! isset($data[$k])) $data[$k] = 0; if ($over) { // @todo This is an ugly hack - if our data has been passed it, it is assumed it has been reduced by $this->metric $z = $this->metric ? round($this->{$k}/$this->metric,2) : $this->{$k}; $data[$k] = $invert ? $z : $data[$k]-$z; // We need to return this back to base units as later, we'll return it back to metric $data[$k] = $this->metric ? $data[$k]*$this->metric : $data[$k]; } // Do we charge for extra, or merge it to another field if (! is_null($this->{$v})) { if (isset($x[$k])) $x[$k] += $data[$k]; else $x[$k] = $data[$k]; } else { if (isset($x[$merge[$v]])) { $x[$merge[$v]] += $data[$k]; } else { $x[$merge[$v]] = $data[$k]; // If we had any data already in A for this merge, we'll need to add it too. if (isset($x[$k])) { $x[$merge[$v]] += $x[$k]; unset($x[$k]); } } } } // Return the output sorted foreach (array_keys(Model_Service_Plugin_Adsl_Traffic::$metrics) as $k) { $k = 'base_'.$k; if (isset($x[$k])) { $result[$k] = $this->metric ? round($x[$k]/$this->metric,2) : $x[$k]; if ($ceil) $result[$k] = ceil($result[$k]); } } return $format ? join('/',array_values($result)) : $result; } public function cost_extra(array $data=array(),$format=FALSE) { $result = array(); foreach ($this->allowance($data) as $k => $v) $result[$k] = $format ? $this->display($this->_map[$k]) : $this->{$this->_map[$k]}; return $format ? join('/',array_values($result)) : $result; } public function hasOffpeak() { if ((($this->base_down_offpeak || $this->base_down_offpeak == 0) AND (! is_null($this->extra_down_offpeak))) OR (($this->base_up_offpeak || $this->base_up_offpeak == 0) AND (! is_null($this->extra_up_offpeak)))) return TRUE; } } ?>