diff --git a/application/bootstrap.php b/application/bootstrap.php
index bb024a19..32e476a2 100644
--- a/application/bootstrap.php
+++ b/application/bootstrap.php
@@ -117,6 +117,7 @@ Kohana::modules(array(
// 'codebench' => SMDPATH.'codebench', // Benchmarking tool
'database' => SMDPATH.'database', // Database access
'gchart' => MODPATH.'gchart', // Google Chart Module
+ 'highchart' => MODPATH.'highchart', // Highcharts Chart Module
// 'image' => SMDPATH.'image', // Image manipulation
'khemail' => SMDPATH.'khemail', // Email module for Kohana 3 PHP Framework
'minion' => SMDPATH.'minion', // CLI Tasks
diff --git a/application/classes/Company.php b/application/classes/Company.php
index 0ff9b283..dd0dc4f3 100644
--- a/application/classes/Company.php
+++ b/application/classes/Company.php
@@ -10,6 +10,8 @@
* @license http://dev.osbill.net/license.html
*/
class Company {
+ public static $instance = array();
+
// Our Company Setup object
private $so;
@@ -23,7 +25,12 @@ class Company {
}
public static function instance() {
- return new Company(ORM::factory('Setup',array('url'=>URL::base('http'))));
+ $x = URL::base('http');
+
+ if (! isset(Company::$instance[$x]))
+ Company::$instance[$x] = new Company(ORM::factory('Setup',array('url'=>$x)));
+
+ return Company::$instance[$x];
}
public function admin() {
diff --git a/application/classes/ORM/OSB.php b/application/classes/ORM/OSB.php
index f46840d7..fe3f218b 100644
--- a/application/classes/ORM/OSB.php
+++ b/application/classes/ORM/OSB.php
@@ -136,9 +136,8 @@ abstract class ORM_OSB extends ORM {
else
$array[$k] = $x;
- } else
- if (! $v)
- unset($array[$k]);
+ } elseif (! $v AND $v !== 0 AND $v !== '0')
+ unset($array[$k]);
}
@@ -207,15 +206,6 @@ abstract class ORM_OSB extends ORM {
// Find any fields that have changed, and process them.
if ($this->_changed)
foreach ($this->_changed as $c) {
- // Convert to NULL
- if (in_array($c,$this->_nullifempty)) {
- if (is_array($this->_object[$c]))
- $this->_object[$c] = $this->_nullifempty($this->_object[$c]);
-
- elseif (! $this->_object[$c])
- $this->_object[$c] = NULL;
- }
-
// Any fields that are blobs, and encode them.
if (! is_null($this->_object[$c]) AND $this->_table_columns[$c]['data_type'] == 'blob') {
$this->_object[$c] = $this->_blob($this->_object[$c],TRUE);
@@ -246,6 +236,24 @@ abstract class ORM_OSB extends ORM {
return TRUE;
}
+ /**
+ * Override the Kohana processing so we can null values if required.
+ */
+ public function values(array $values,array $expected=NULL) {
+ foreach ($values as $k=>$v) {
+ // Convert to NULL
+ if (in_array($k,$this->_nullifempty)) {
+ if (is_array($v))
+ $values[$k] = $this->_nullifempty($v);
+
+ elseif (! $v AND $v !== 0 AND $v !== '0')
+ $values[$k] = NULL;
+ }
+ }
+
+ return parent::values($values,$expected);
+ }
+
/**
* Function help to find records that are active
*/
diff --git a/modules/adsl/classes/ADSL.php b/modules/adsl/classes/ADSL.php
index f7135d6c..d599fcc0 100644
--- a/modules/adsl/classes/ADSL.php
+++ b/modules/adsl/classes/ADSL.php
@@ -32,7 +32,7 @@ class ADSL {
if (preg_match('/^a:/',$data))
throw new Kohana_Exception('Data shouldnt be a serialized array');
- $ao = ORM::factory('ADSL_Plan',$data);
+ $ao = ORM::factory('Product_Plugin_Adsl',$data);
$output = View::factory('adsl/contract_view')
->set('record',$ao)
->set('price_base',$price_base)
diff --git a/modules/adsl/classes/Adsl/Billing/Exetelvisp.php b/modules/adsl/classes/Adsl/Billing/Exetelvisp.php
index 12ac310b..8dbe52cd 100644
--- a/modules/adsl/classes/Adsl/Billing/Exetelvisp.php
+++ b/modules/adsl/classes/Adsl/Billing/Exetelvisp.php
@@ -73,6 +73,7 @@ class ADSL_Billing_Exetelvisp {
$start = $end = FALSE;
$result = array();
+ $c = 0;
foreach (preg_split("/\n/",$data) as $line) {
// Items start after "Item ID"
if (! $start && preg_match('/^Item ID,/',$line)) {
@@ -113,7 +114,7 @@ class ADSL_Billing_Exetelvisp {
list($service,$description) = explode(':',(preg_replace('/([0-9]+)\s+-\s+(.*)$/',"$1:$2",$record[3])));
$result[$service]['cost'] = str_replace('$','',$record[6]);
- } elseif (preg_match('/Monthly Charge On Plan /',$record[3])) {
+ } elseif (preg_match('/([0-9]+)\s+-\s+Monthly Charge On Plan /',$record[3])) {
list($service,$description) = explode(':',(preg_replace('/([0-9]+)\s+-\s+(.*)$/',"$1:$2",$record[3])));
$result[$service]['cost'] = str_replace('$','',$record[6]);
$result[$service]['info'] = 'Other Service';
@@ -139,7 +140,7 @@ class ADSL_Billing_Exetelvisp {
list($service,$description) = explode(':',(preg_replace('/([0-9]+)\s+-\s+(.*)$/',"$1:$2",$record[3])));
$result[$service]['info'] = $line;
} catch (Exception $e) {
- $result['000']['info'] = $line;
+ $result["000-".$c++]['info'] = $line;
}
}
}
@@ -148,7 +149,7 @@ class ADSL_Billing_Exetelvisp {
// @todo This could be optimised better.
foreach ($aso->services(TRUE) as $so)
- $this->haveService($so->plugin()->service_number,$so->plugin()->product()->adsl_supplier_plan->total());
+ $this->haveService($so->plugin()->service_number,$so->plugin()->admin_plan()->adsl_supplier_plan->display('base_cost'));
return $this;
}
diff --git a/modules/adsl/classes/Controller/Admin/Adsl.php b/modules/adsl/classes/Controller/Admin/Adsl.php
index e852ed4d..722202e8 100644
--- a/modules/adsl/classes/Controller/Admin/Adsl.php
+++ b/modules/adsl/classes/Controller/Admin/Adsl.php
@@ -12,6 +12,8 @@
class Controller_Admin_Adsl extends Controller_Adsl {
protected $secure_actions = array(
'index'=>TRUE,
+ 'edit'=>TRUE,
+ 'list'=>TRUE,
'traffic'=>TRUE,
);
@@ -29,6 +31,94 @@ class Controller_Admin_Adsl extends Controller_Adsl {
->body($output);
}
+ public function action_list() {
+ Block::factory()
+ ->title('ADSL Plans')
+ ->title_icon('icon-th-list')
+ ->body(Table::factory()
+ ->data(ORM::factory('Product_Plugin_Adsl')->find_all())
+ ->jssort('adsl')
+ ->columns(array(
+ 'id'=>'ID',
+ 'adsl_supplier_plan->name()'=>'Plan',
+ 'adsl_supplier_plan->display("status")'=>'Avail',
+ 'base_down_peak'=>'PD',
+ 'base_down_offpeak'=>'OPD',
+ 'base_up_peak'=>'PU',
+ 'base_up_offpeak'=>'OPU',
+ 'extra_charged'=>'$',
+ 'extra_down_peak'=>'EPD',
+ 'extra_down_offpeak'=>'EOPD',
+ 'extra_up_peak'=>'EPU',
+ 'extra_up_offpeak'=>'EOPU',
+ 'contract_term'=>'Cont',
+ ))
+ ->prepend(array(
+ 'id'=>array('url'=>URL::link('admin','adsl/edit/')),
+ ))
+ );
+ }
+
+ public function action_edit() {
+ $apo = ORM::factory('Product_Plugin_Adsl',$this->request->param('id'));
+ $test_result = array();
+
+ if (! $apo->loaded())
+ HTTP::redirect(URL::link('admin','adsl/list'));
+
+ if ($_POST) {
+ // Entry updated
+ if ($apo->values($_POST)->check() AND $apo->changed()) {
+ try {
+ if ($apo->save())
+ SystemMessage::factory()
+ ->title('Record updated')
+ ->type('success')
+ ->body(_('Your Charge record has been recorded/updated.'));
+
+ } catch (ORM_Validation_Exception $e) {
+ $errors = $e->errors('models');
+
+ SystemMessage::factory()
+ ->title('Record NOT updated')
+ ->type('error')
+ ->body(join('
',array_values($errors)));
+
+ $sco->reload();
+ }
+ }
+
+ if (isset($_POST['test'])) {
+ $charge = isset($_POST['test']['charge']) ? $_POST['test']['charge'] : FALSE;
+ $test_result = $apo->allowance($_POST['test'],FALSE,$charge,1000);
+ }
+ }
+
+ Block::factory()
+ ->type('form-horizontal')
+ ->title('Update ADSL Plan')
+ ->title_icon('icon-wrench')
+ ->body(View::factory('adsl/admin/edit')
+ ->set('test_result',$test_result)
+ ->set('o',$apo));
+
+ Block::factory()
+ ->title('Products Using this Plan')
+ ->title_icon('icon-th-list')
+ ->body(Table::factory()
+ ->jssort('traffic')
+ ->data($apo->products()->find_all())
+ ->columns(array(
+ 'id'=>'ID',
+ 'title()'=>'Name',
+ 'status'=>'Active',
+ ))
+ ->prepend(array(
+ 'id'=>array('url'=>URL::link('admin','product/edit/')),
+ ))
+ );
+ }
+
/**
* Reconcile billing for an ADSL supplier
*/
diff --git a/modules/adsl/classes/Controller/Reseller/Adsl.php b/modules/adsl/classes/Controller/Reseller/Adsl.php
index 0ee4cff4..214fef5b 100644
--- a/modules/adsl/classes/Controller/Reseller/Adsl.php
+++ b/modules/adsl/classes/Controller/Reseller/Adsl.php
@@ -31,6 +31,7 @@ class Controller_Reseller_Adsl extends Controller_Adsl {
->rule('csv','Upload::type',array(':value',array('csv')))
->rule('csv','Upload::size',array(':value','10M'));
+ $csv = NULL;
if ($files->check())
foreach ($files->data() as $file) {
$csv = $aso->billing()->process($aso,$file);
diff --git a/modules/adsl/classes/Controller/Reseller/Service/Adsl.php b/modules/adsl/classes/Controller/Reseller/Service/Adsl.php
index dcde6671..e8780b3c 100644
--- a/modules/adsl/classes/Controller/Reseller/Service/Adsl.php
+++ b/modules/adsl/classes/Controller/Reseller/Service/Adsl.php
@@ -14,68 +14,64 @@ class Controller_Reseller_Service_Adsl extends Controller_Service {
'list'=>TRUE,
);
- private function consoltraffic($svs,$date) {
- $data = array();
+ private function consoltraffic($period) {
+ $result = array();
- foreach ($svs as $so) {
- $c = array();
- foreach ($so->plugin()->get_traffic_data_monthly($date) as $metric => $ma) {
- foreach ($ma as $month => $traffic) {
- // Only count the service once, not for each metric.
- if (! isset($c[$month])) {
- if (isset($data['svs'][$month]))
- $data['svs'][$month] += 1;
- else
- $data['svs'][$month] = 1;
+ $periodstart = mktime(0,0,0,date('m',$period),1,date('Y',$period)-1);
- $c[$month] = 1;
- }
+ $t = ORM::factory('Service_Plugin_Adsl_Traffic')
+ ->select(array('date_format(date,\'%y-%m\')','month'))
+ ->selectsummetric()
+ ->join('service__adsl','INNER')
+ ->on('service__adsl.service_username','=','service_plugin_adsl_traffic.service')
+ ->on('service__adsl.site_id','=','service_plugin_adsl_traffic.site_id')
+ ->join('service','INNER')
+ ->on('service__adsl.service_id','=','service.id')
+ ->on('service__adsl.site_id','=','service.site_id')
+ ->where_authorised($this->ao,'service.account_id')
+ ->and_where('date','>=',date('Y-m-d',$periodstart))
+ ->and_where('date','<=',date('Y-m-d',strtotime('last day of '.date('M Y',$period))))
+ ->group_by('date_format(date,\'%Y-%m\')');
- if (isset($data['data'][$metric][$month]))
- $data['data'][$metric][$month] += (int)$traffic;
- else
- $data['data'][$metric][$month] = (int)$traffic;
- }
- }
- }
+ foreach ($t->find_all() as $to)
+ foreach ($to->traffic_data() as $metric => $v)
+ $result[$metric][$to->month] = $v;
- ksort($data['svs']);
- foreach ($data['data'] as $metric => $details)
- ksort($data['data'][$metric]);
-
- return $data;
+ return $result;
}
public function action_list() {
- $svs = ORM::factory('Service')->where_authorised($this->ao)->list_byplugin('ADSL');
+ $highchart = HighChart::factory('Combo');
+ $highchart->title(sprintf('Monthly DSL traffic usage as at %s',date('Y-m-d',strtotime('yesterday'))));
- $data = $this->consoltraffic($svs,time());
+ $c = 0;
+ foreach ($this->consoltraffic(time()) as $k => $details) {
+ $highchart->series('column','yl')
+ ->name($k)
+ ->data($details)
+ ->index($c)
+ ->order($c++*-1); // This is a kludge to get around highcharts rendering from the bottom up.
- $google = GoogleChart::factory('Legacy')
- ->type('vertical_bar')
- ->title(sprintf('ADSL traffic as at %s',date('Y-m-d',strtotime('yesterday'))));
+ $highchart->autopie($k);
+ }
- foreach ($data['data'] as $key => $values)
- $google->sdata(array('yl'=>$key),array($key=>$values));
-
- $google->sdata(array('yr'=>'services'),array('services'=>$data['svs']));
-
- Block::add(array('body'=>(string)$google));
+ Block::factory()
+ ->body((string)$highchart);
Block::factory()
->title('ADSL Services')
->title_icon('icon-th-list')
->body(Table::factory()
->jssort('adsl')
- ->data($svs)
+ ->data(ORM::factory('Service')->where_authorised($this->ao)->list_byplugin('ADSL'))
->columns(array(
'id'=>'ID',
'name()'=>'Service',
'plugin()->ipaddress()'=>'IP Address',
- 'product->plugin()->adsl_supplier_plan->speed'=>'Speed',
- 'product->plugin()->allowance()'=>'Allowance',
- 'plugin()->traffic_thismonth()'=>'This Month',
- 'plugin()->traffic_lastmonth()'=>'Last Month',
+ 'product->plugin()->supplier_plan->speed'=>'Speed',
+ 'product->plugin()->allowance(array(),TRUE,TRUE,1000)'=>'Allowance',
+ 'plugin()->traffic_month(strtotime("yesterday"),TRUE,1000)'=>'This Month',
+ 'plugin()->traffic_month(strtotime("last month"),TRUE,1000)'=>'Last Month',
'recur_schedule'=>'Billing',
'price(TRUE,TRUE)'=>'Price',
'account->accnum()'=>'Cust ID',
diff --git a/modules/adsl/classes/Model/ADSL/Plan.php b/modules/adsl/classes/Model/ADSL/Plan.php
deleted file mode 100644
index 655bda18..00000000
--- a/modules/adsl/classes/Model/ADSL/Plan.php
+++ /dev/null
@@ -1,48 +0,0 @@
-array('model'=>'ADSL_Supplier_Plan'),
- );
-
- 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')),
- ),
- );
-
- public function products($active) {
- $x = ORM::factory('Product')
- ->where('prod_plugin_file','=','ADSL')
- ->and_where('prod_plugin_data','=',$this);
-
- if ($active)
- $x->where_active();
-
- return $x;
- }
-}
-?>
diff --git a/modules/adsl/classes/Model/ADSL/Supplier.php b/modules/adsl/classes/Model/ADSL/Supplier.php
index 492183a0..182b068d 100644
--- a/modules/adsl/classes/Model/ADSL/Supplier.php
+++ b/modules/adsl/classes/Model/ADSL/Supplier.php
@@ -28,7 +28,7 @@ class Model_ADSL_Supplier extends ORM_OSB {
$result = array();
foreach ($this->find_plans($active)->find_all() as $po)
- foreach ($po->adsl_plan->find_all() as $apo)
+ foreach ($po->admin_plan()->find_all() as $apo)
$result[$apo->id] = $apo;
return $result;
@@ -62,7 +62,7 @@ class Model_ADSL_Supplier extends ORM_OSB {
$result = array();
foreach ($this->find_plans(FALSE)->find_all() as $aspo) {
- foreach ($aspo->adsl_plan->find_all() as $apo) {
+ foreach ($aspo->plan->find_all() as $apo) {
foreach ($apo->products(FALSE)->find_all() as $po) {
foreach ($po->services($active)->find_all() as $so) {
array_push($result,$so);
diff --git a/modules/adsl/classes/Model/ADSL/Supplier/Plan.php b/modules/adsl/classes/Model/ADSL/Supplier/Plan.php
index 8fea1a51..17ee7e22 100644
--- a/modules/adsl/classes/Model/ADSL/Supplier/Plan.php
+++ b/modules/adsl/classes/Model/ADSL/Supplier/Plan.php
@@ -11,30 +11,100 @@
*/
class Model_ADSL_Supplier_Plan extends ORM_OSB {
// Relationships
- protected $_has_many = array(
- 'adsl_plan'=>array('model'=>'ADSL_Plan','far_key'=>'id'),
- );
protected $_belongs_to = array(
- 'adsl_supplier'=>array('model'=>'ADSL_Supplier','foreign_key'=>'supplier_id'),
+ 'supplier'=>array('model'=>'ADSL_Supplier'),
+ );
+ protected $_has_many = array(
+ 'plan'=>array('model'=>'Product_Plugin_Adsl','far_key'=>'id'),
+ );
+
+ protected $_sorting = array(
+ 'product_id'=>'ASC',
+ 'product_desc'=>'ASC',
+ );
+
+ protected $_form = array('id'=>'id','value'=>'name()');
+
+ /**
+ * Filters used to format the display of values into friendlier values
+ */
+ protected $_display_filters = array(
+ 'base_cost'=>array(
+ array('Tax::add',array(':value')),
+ array('Currency::display',array(':value')),
+ ),
+ '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')),
+ ),
+ 'status'=>array(
+ array('StaticList_YesNo::get',array(':value',TRUE)),
+ ),
+ );
+
+ // 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',
+ );
+
+ private $_metrics = array(
+ 'base_up_peak'=>'base_up_peak',
+ 'base_up_offpeak'=>'base_up_offpeak',
+ 'base_down_peak'=>'base_down_peak',
+ 'base_down_offpeak'=>'base_down_offpeak',
);
/**
- * Show the ADSL allowance as a peak/offpeak metric
+ * Display the cost for extra traffic
*/
- public function allowance() {
- return sprintf('%s/%s',$this->base_down_peak+$this->base_up_peak,$this->base_down_offpeak+$this->base_up_offpeak);
+ public function cost_extra(array $data=array(),$format=FALSE) {
+ $result = array();
+
+ if (! $data)
+ $data = $this->traffic_data();
+
+ foreach ($data as $k => $v)
+ $result[$k] = $this->display($this->_map[$k]);
+
+ return $format ? join('/',array_values($result)) : $result;
}
+ /**
+ * ADSL Plan Name
+ */
public function name() {
- return $this->product_id;
+ return sprintf('%s: %s',$this->product_id,$this->product_desc);
}
- public function tax() {
- return Tax::amount($this->base_cost);
- }
+ /**
+ * Collapse our traffic data into an array as per $this->_metric
+ */
+ public function traffic_data() {
+ $result = array();
- public function total($format=FALSE) {
- return $format ? Currency::display($this->base_cost+$this->tax()) : Currency::round($this->base_cost+$this->tax());
+ foreach ($this->_metrics as $metric=>$v) {
+ if (! isset($result[$v]))
+ $result[$v] = 0;
+
+ $result[$v] += $this->{$metric};
+ }
+
+ return $result;
}
}
?>
diff --git a/modules/adsl/classes/Model/Product/Plugin/Adsl.php b/modules/adsl/classes/Model/Product/Plugin/Adsl.php
index deed99c1..12ead200 100644
--- a/modules/adsl/classes/Model/Product/Plugin/Adsl.php
+++ b/modules/adsl/classes/Model/Product/Plugin/Adsl.php
@@ -12,10 +12,20 @@
class Model_Product_Plugin_Adsl extends Model_Product_Plugin {
protected $_table_name = 'adsl_plan';
+ // We dont use the update column
+ protected $_updated_column = FALSE;
+
+ // Relationships
protected $_belongs_to = array(
- 'adsl_supplier_plan'=>array('model'=>'ADSL_Supplier_Plan'),
+ 'supplier_plan'=>array('model'=>'ADSL_Supplier_Plan','foreign_key'=>'adsl_supplier_plan_id'),
+ );
+ protected $_has_many = array(
+ 'product'=>array('far_key'=>'id','foreign_key'=>'prod_plugin_data'),
);
+ /**
+ * Filters used to format the display of values into friendlier values
+ */
protected $_display_filters = array(
'extra_down_peak'=>array(
array('Tax::add',array(':value')),
@@ -25,45 +35,178 @@ class Model_Product_Plugin_Adsl extends Model_Product_Plugin {
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',
+ );
+
+ // 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',
+ );
+
+ // Our required abstract methods
public function admin_update() {
return '';
}
- // Our required abstract methods
public function cost($annual=FALSE) {
- $x = $this->adsl_supplier_plan->total();
+ $x = $this->supplier_plan->display('base_cost');
return $annual ? $x*12 : $x;
}
public function feature_summary() {
- // @todo This view should render based on the the results of this::allowance();
- return View::factory('product/plugin/adsl/feature_summary')
- ->set('po',$this);
+ return View::factory(sprintf('product/plugin/%s/feature_summary',$this->plugin()))
+ ->set('o',$this);
}
public function supplier() {
- return $this->adsl_supplier_plan->supplier_id;
+ return $this->supplier_plan->supplier_id;
+ }
+
+ /** LOCAL FUNCTIONS **/
+
+ /**
+ * 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 alloance numbers
+ * @param int Divide the numbers
+ */
+ public function allowance(array $data=array(),$format=FALSE,$over=FALSE,$divide=0) {
+ $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)
+ $data[$k] = $invert ? $this->{$k} : $data[$k]-$this->{$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] = $divide ? ceil($x[$k]/$divide) : $x[$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;
}
/**
- * Show the ADSL allowance as a peak/offpeak metric
+ * Get all the products using this plan
*/
- public function allowance($string=TRUE) {
- $output = ADSL::allowance(array(
- 'base_down_peak'=>$this->base_down_peak,
- 'base_down_offpeak'=>$this->base_down_offpeak,
- 'base_up_peak'=>$this->base_up_peak,
- 'base_up_offpeak'=>$this->base_up_offpeak,
- 'extra_down_peak'=>$this->extra_down_peak,
- 'extra_down_offpeak'=>$this->extra_down_offpeak,
- 'extra_up_peak'=>$this->extra_up_peak,
- 'extra_up_offpeak'=>$this->extra_up_offpeak,
- ));
+ public function products($active=FALSE) {
+ $x = ORM::factory('Product')
+ ->where('prod_plugin_file','=','ADSL')
+ ->and_where('prod_plugin_data','=',$this);
- return $string ? implode('/',$output) : $output;
+ if ($active)
+ $x->where_active();
+
+ return $x;
}
}
?>
diff --git a/modules/adsl/classes/Model/Service/Plugin/Adsl.php b/modules/adsl/classes/Model/Service/Plugin/Adsl.php
index 91eeb904..91b904c9 100644
--- a/modules/adsl/classes/Model/Service/Plugin/Adsl.php
+++ b/modules/adsl/classes/Model/Service/Plugin/Adsl.php
@@ -19,7 +19,11 @@ class Model_Service_Plugin_Adsl extends Model_Service_Plugin {
);
protected $_has_one = array(
- 'adsl_plan'=>array('model'=>'ADSL_Plan','far_key'=>'provided_adsl_plan_id','foreign_key'=>'id'),
+ 'provided_plan'=>array('model'=>'Product_Plugin_Adsl','far_key'=>'provided_adsl_plan_id','foreign_key'=>'id'),
+ );
+
+ protected $_has_many = array(
+ 'traffic'=>array('model'=>'Service_Plugin_Adsl_Traffic','foreign_key'=>'service','far_key'=>'service_username'),
);
protected $_display_filters = array(
@@ -33,7 +37,7 @@ class Model_Service_Plugin_Adsl extends Model_Service_Plugin {
// Required abstract functions
public function expire() {
- // @todo This should work out if the invoices are currently due, then the expire is the invoice date, otherwise the next invoice date.
+ // We'll leave it to the Service record to determine when this service expires
return NULL;
}
@@ -41,6 +45,15 @@ class Model_Service_Plugin_Adsl extends Model_Service_Plugin {
return $this->service_number;
}
+ public function username_value() {
+ return $this->service_username;
+ }
+
+ public function password_value() {
+ return $this->service_password;
+ }
+
+ // Override our parent function to include some JS.
public function admin_update() {
Script::factory()
->type('stdin')
@@ -68,24 +81,130 @@ $(document).ready(function() {
return parent::admin_update();
}
- public function product() {
- if ($this->provided_adsl_plan_id)
- return $this->adsl_plan;
- else
- return $this->service->product->plugin();
+ /** LOCAL FUNCTIONS **/
+
+ /**
+ * If we override the plan that the customers gets (from what the supplier provides).
+ */
+ public function admin_plan() {
+ return $this->provided_adsl_plan_id ? $this->provided_plan : $this->service->product->plugin();
}
- public function service_view() {
- return View::factory('service/user/plugin/adsl/view')
- ->set('o',$this);
+ /**
+ * Calculate our contract start and end dates
+ */
+ public function contract_date_start($format=FALSE) {
+ return $format ? Config::date($this->service_contract_date) : $this->service_contract_date;
}
- public function username_value() {
- return $this->service_username;
+ public function contract_date_end($format=FALSE) {
+ $x = strtotime(sprintf('+%s months',$this->contract_term),$this->service_contract_date);
+
+ return $format ? Config::date($x) : $x;
}
- public function password_value() {
- return $this->service_password;
+ /**
+ * This function will return the months that have traffic data.
+ * This array can be used in a select list to display the traffic for that month
+ */
+ public function get_traffic_months() {
+ $x = array_keys($this->get_traffic_monthlytype());
+
+ if (! $x)
+ return array();
+
+ $months = array_combine($x,$x);
+
+ arsort($months);
+
+ return $months;
+ }
+
+ /**
+ * Get daily traffic data, broken down by type
+ * @todo This needs to get the plan that was invoiced, not the current plan..
+ */
+ public function get_traffic_dailytype($period) {
+ $result = array();
+
+ if (is_null($period))
+ $period = strtotime('yesterday');
+
+ $t = $this->traffic
+ ->where('date','>=',date('Y-m-d',mktime(0,0,0,date('m',$period),1,date('Y',$period))))
+ ->and_where('date','<=',date('Y-m-d',strtotime('last day of '.date('M Y',$period))));
+
+ foreach ($t->find_all() as $to) {
+ $day = date('j',strtotime($to->date));
+
+ $result[$day] = $this->plan()->allowance($to->traffic_data());
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get monthly traffic data, broken down by type
+ * @todo This needs to get the plan that was invoiced, not the current plan..
+ */
+ public function get_traffic_monthlytype($period=NULL,$periodstart=NULL,$format=FALSE,$divide=0) {
+ $result = array();
+
+ if (is_null($period))
+ $period = strtotime('yesterday');
+ if (is_null($periodstart))
+ $periodstart = mktime(0,0,0,date('m',$period),1,date('Y',$period)-1);
+
+ $t = $this->traffic
+ ->select(array('date_format(date,\'%y-%m\')','month'))
+ ->selectsummetric()
+ ->and_where('date','>=',date('Y-m-d',$periodstart))
+ ->and_where('date','<=',date('Y-m-d',strtotime('last day of '.date('M Y',$period))))
+ ->group_by('date_format(date,\'%Y-%m\')');
+
+ foreach ($t->find_all() as $to) {
+ $index = $to->month;
+
+ $result[$index] = $this->plan()->allowance($to->traffic_data(),$format,FALSE,$divide);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Get traffic type data, broken down by day
+ */
+ public function get_traffic_typedaily($period=NULL) {
+ $result = array();
+
+ if (is_null($period))
+ $period = strtotime('yesterday');
+
+ foreach ($this->get_traffic_dailytype($period) as $day => $data)
+ foreach ($data as $metric => $value)
+ $result[$metric][$day] = $value;
+
+ return $result;
+ }
+
+ /**
+ * Get traffic type data, broken down by month
+ */
+ public function get_traffic_typemonthly($period=NULL) {
+ $result = array();
+
+ if (is_null($period))
+ $period = strtotime('yesterday');
+
+ foreach ($this->get_traffic_monthlytype($period) as $day => $data)
+ foreach ($data as $metric => $value)
+ $result[$metric][$day] = $value;
+
+ return $result;
+ }
+
+ public function hasOffPeak() {
+ return $this->plan()->hasOffPeak();
}
/**
@@ -95,147 +214,130 @@ $(document).ready(function() {
return $this->ipaddress ? $this->ipaddress : _('Dynamic');
}
- public function contract_date_start() {
- return Config::date($this->service_contract_date);
- }
-
- public function contract_date_end($format=FALSE) {
- $x = strtotime(sprintf('+%s months',$this->contract_term),$this->service_contract_date);
-
- return $format ? Config::date($x) : $x;
- }
-
- public function hasOffpeak() {
- return ((is_null($this->product()->base_down_offpeak) OR $this->product()->base_down_offpeak) AND (is_null($this->product()->base_up_offpeak) OR $this->product()->base_up_offpeak)) ? TRUE : FALSE;
+ /**
+ * If we override the plan that the customers gets (from what the supplier provides).
+ * @todo This needs to get the plan that was invoiced, not the current plan..
+ */
+ public function plan($month=NULL) {
+ return is_null($month) ? $this->service->product->plugin() : $this->plandate($month);
}
/**
- * This function will return the months that have traffic data.
- * This array can be used in a select list to display the traffic for that month
+ * For a particular month, select the PLAN that the user was on
*/
- public function get_traffic_months() {
- $keys = $months = array();
-
- foreach ($this->get_traffic_data_monthly() as $metric => $data)
- $keys = array_unique(array_merge($keys,array_keys($data)));
-
- foreach ($keys as $v)
- $months[$v] = $v;
-
- arsort($months);
-
- return $months;
+ public function plandate($month) {
+ throw new Kohana_Exception('This function hasnt been written yet.');
}
/**
- * Calculate the total traffic used in a month
+ * Calculate the Excess Traffic Charges
*/
- private function get_traffic_data_month($period=NULL,$cache=0) {
+ public function traffic_excess($period=NULL,$charge=FALSE,$format=FALSE) {
$result = array();
- foreach ($this->get_traffic_data_daily($period,TRUE,$cache) as $tdata)
- foreach ($tdata as $k => $v)
- if (isset($result[$k]))
- $result[$k] += $v;
- else
- $result[$k] = $v;
+ if ($this->plan()->extra_charged) {
+ if (is_null($period))
+ $period = strtotime('yesterday');
- return $result;
- }
+ if ($x=$this->get_traffic_monthlytype(strtotime('last day of '.date('M Y',$period)),strtotime('first day of '.date('M Y',$period)))) {
- /**
- * Return an array of the data used in a month by day
- */
- public function get_traffic_data_daily($period=NULL,$bydate=FALSE,$cache=0) {
- $result = array();
+ $c = $this->plan()->cost_extra();
+ foreach ($this->plan()->allowance(array_pop($x),FALSE,TRUE,1000) as $k=>$v)
+ if (isset($c[$k]) AND $v > 0) {
+ $result[$k] = $charge ? $c[$k]*$v : $v;
- if (is_null($period))
- $period = strtotime('yesterday');
-
- $t = ORM::factory('Service_Plugin_Adsl_Traffic')
- ->where('service','=',$this->service_username)
- ->and_where('date','>=',date('Y-m-d',mktime(0,0,0,date('m',$period),1,date('Y',$period))))
- ->and_where('date','<=',date('Y-m-d',strtotime('last day of '.date('M Y',$period))))
- ->cached($cache);
-
- foreach ($t->find_all() as $to) {
- $day = date('d',strtotime($to->date));
-
- if ($bydate)
- $result[$day] = $to->traffic($this->service->product->plugin());
- else
- foreach ($to->traffic($this->service->product->plugin()) as $k => $v)
- $result[$k][$day] = $v;
- }
-
- return $result;
- }
-
- /**
- * Return an array of the data used in a year by month
- */
- public function get_traffic_data_monthly($period=NULL,$bydate=FALSE) {
- $result = array();
-
- if (is_null($period))
- $period = strtotime('yesterday');
-
- $t = ORM::factory('Service_Plugin_Adsl_Traffic')
- ->select(
- array('date_format(date,\'%y-%m\')','month'),
- array('sum(up_peak)','up_peak'),
- array('sum(up_offpeak)','up_offpeak'),
- array('sum(down_peak)','down_peak'),
- array('sum(down_offpeak)','down_offpeak')
- )
- ->where('service','=',$this->service_username)
- ->and_where('date','>=',date('Y-m-d',mktime(0,0,0,date('m',$period),1,date('Y',$period)-1)))
- ->and_where('date','<=',date('Y-m-d',strtotime('last day of '.date('M Y',$period))))
- ->group_by('date_format(date,\'%Y-%m\')');
-
- foreach ($t->find_all() as $to)
- if ($bydate)
- $result[$to->month] = $to->traffic($this->service->product->plugin());
- else
- foreach ($to->traffic($this->service->product->plugin()) as $k => $v)
- $result[$k][$to->month] = $v;
-
- return $result;
- }
-
- public function traffic_month($month,$string=TRUE,$cache=0) {
- return $string ? implode('/',$this->get_traffic_data_month($month,$cache)) :
- $this->get_traffic_data_month($month,$cache);
- }
-
- public function traffic_lastmonth($string=TRUE) {
- // We need it to be last month as of yesterday
- return $this->traffic_month(strtotime('last month')-86400,$string);
- }
-
- public function traffic_thismonth($string=TRUE) {
- return $this->traffic_month(strtotime('yesterday'),$string);
- }
-
- public function traffic_lastmonth_exceed($all=FALSE,$date=NULL) {
- $result = array();
-
- if (is_null($date))
- $date = strtotime('last month')-86400;
-
- foreach ($this->traffic_month($date,FALSE,0) as $k => $v) {
- // We shouldnt need to eval for nulls, since the traffic calc does that
- if ($all OR ($v > $this->service->product->plugin()->$k)) {
- $result[$k]['allowance'] = $this->service->product->plugin()->$k;
- $result[$k]['used'] = $v;
- $result[$k]['shaped'] = (! empty($this->service->product->plugin()->extra_shaped) AND $this->service->product->plugin()->extra_shaped AND $v > $this->service->product->plugin()->$k) ? TRUE : FALSE;
- $result[$k]['excess'] = (! empty($this->service->product->plugin()->extra_charged) AND $this->service->product->plugin()->extra_charged AND $v > $this->service->product->plugin()->$k) ? $v-$this->service->product->plugin()->$k : 0;
- $result[$k]['rate'] = $this->service->product->plugin()->{ADSL::map($k)};
- $result[$k]['charge'] = ceil(($result[$k]['excess'])/1000)*$result[$k]['rate'];
+ if ($charge AND $format)
+ $result[$k] = Currency::display(Tax::add($result[$k]));
+ }
}
}
- return $result;
+ if (! $result AND $charge AND $format)
+ $result = array(Currency::display(0));
+
+ return $format ? join('/',$result) : $result;
+ }
+
+ /**
+ * Render a chart of traffic
+ */
+ public function traffic_graph($month=NULL) {
+ $highchart = HighChart::factory('Combo');
+
+ $c=0;
+ // If we came in via a post to show a particular month, then show that, otherwise show the yearly result
+ if (! is_null($month) AND trim($month)) {
+ $highchart->title(sprintf('DSL traffic usage for %s',$_POST['month']));
+ $x = $this->get_traffic_typedaily(strtotime($_POST['month'].'-01'));
+
+ } else {
+ $highchart->title(sprintf('Monthly DSL traffic usage as at %s',$this->traffic->find_last()->date));
+ $x = $this->get_traffic_typemonthly();
+ }
+
+ foreach ($x as $k => $details) {
+ $highchart->series('column','yl')
+ ->name($this->traffic->friendly($k))
+ ->data($x[$k])
+ ->index($c)
+ ->order($c++*-1); // This is a kludge to get around highcharts rendering from the bottom up.
+
+ $highchart->autopie($k);
+ }
+
+
+ return (string)$highchart;
+ }
+
+ /**
+ * Get the traffic for a month
+ */
+ public function traffic_month($period,$format=FALSE,$divide=0) {
+ $x = $this->get_traffic_monthlytype(strtotime('last day of '.date('M Y',$period)),strtotime('first day of '.date('M Y',$period)),$format,$divide);
+
+ return $x ? array_pop($x) : 0;
+ }
+
+ /**
+ * Render a table of traffic
+ */
+ public function traffic_table($month=NULL) {
+ // If we came in via a post to show a particular month, then show that, otherwise show the yearly result
+ if (! is_null($month) AND trim($month)) {
+ $x = $this->get_traffic_dailytype(strtotime($_POST['month'].'-01'));
+ $index = 'Date';
+
+ } else {
+ $x = $this->get_traffic_monthlytype();
+ $index = 'Month';
+ }
+
+ return View::factory(sprintf('service/user/plugin/%s/table_traffic',$this->plugin()))
+ ->set('index',$index)
+ ->set('th',array_keys($this->plan()->allowance()))
+ ->set('td',$x)
+ ->set('o',$this->traffic);
+ }
+
+ /**
+ * Search for services matching a term
+ */
+ public function list_autocomplete($term,$index,$value,array $label,array $limit=array(),array $options=NULL) {
+ // We only show service numbers.
+ if (! is_numeric($term))
+ return array();
+
+ $ao = Auth::instance()->get_user();
+
+ $options['key'] = 'id';
+ $options['object'] = DB::select($this->_table_name.'.id',$this->_table_name.'.service_number')
+ ->from($this->_table_name)
+ ->join('service')
+ ->on('service.id','=',$this->_table_name.'.service_id')
+ ->where('service.account_id','IN',$ao->RTM->customers($ao->RTM))
+ ->and_where($this->_table_name.'.service_number','like','%'.$term.'%');
+
+ return parent::list_autocomplete($term,$index,$value,$label,$limit,$options);
}
public function template_variables($array) {
@@ -307,7 +409,7 @@ $(document).ready(function() {
/**
* This function will take an array of numbers and change it into a cumulative array
*/
- public function cumulative($array) {
+ private function cumulative($array) {
$result = array();
$s = 0;
@@ -330,7 +432,6 @@ $(document).ready(function() {
throw new Kohana_Exception('Huh? How did this get called, for a non ADSL product (:ppf)',array(':ppf'=>$this->service_id));
$allowance = $this->service->product->plugin()->allowance(FALSE);
-
$period = strtotime('yesterday');
$traffic_data = $this->get_traffic_data_daily($period,FALSE);
$traffic = $this->get_traffic_data_month($period);
@@ -379,59 +480,45 @@ $(document).ready(function() {
}
/**
- * Render a google chart of traffic
+ * Return an array of the data used in a month by day
*/
- public function graph_traffic($month=NULL) {
- $google = GoogleChart::factory('Legacy')
- ->type('vertical_bar');
+ private function get_traffic_data_daily($period=NULL,$bydate=FALSE) {
+ $result = array();
- // If we came in via a post to show a particular month, then show that, otherwise show the yearly result
- if (! is_null($month) AND trim($month)) {
- $google->title(sprintf('DSL traffic usage for %s',$_POST['month']));
- $traffic_data = $this->get_traffic_data_daily(strtotime($_POST['month'].'-01'));
+ if (is_null($period))
+ $period = strtotime('yesterday');
- foreach ($traffic_data as $k => $details)
- $google->sdata(array('yl'=>($x=isset($friendly[$k]) ? $friendly[$k] : $k)),array($x=>$traffic_data[$k]));
+ $t = ORM::factory('Service_Plugin_Adsl_Traffic')
+ ->where('service','=',$this->service_username)
+ ->and_where('date','>=',date('Y-m-d',mktime(0,0,0,date('m',$period),1,date('Y',$period))));
- foreach ($traffic_data as $k => $details)
- $google->sdata(array('yr'=>($x=isset($friendly['cumulative'.$k]) ? $friendly['cumulative'.$k] : 'cumulative'.$k)),array($x=>$this->cumulative($traffic_data[$k])));
+ foreach ($t->find_all() as $to) {
+ $day = (string)date('d',strtotime($to->date));
- } else {
- // @todo Change the date to the last record date
- $google->title(sprintf('Monthly DSL traffic usage as at %s',Config::date(strtotime('yesterday'))));
- $traffic_data = $this->get_traffic_data_monthly();
-
- foreach ($traffic_data as $k => $details)
- $google->sdata(array('yl'=>($x=isset($friendly[$k]) ? $friendly[$k] : $k)),array($x=>$traffic_data[$k]));
+ if ($bydate)
+ $result[$day] = $to->traffic($this->service->product->plugin());
+ else
+ foreach ($to->traffic($this->service->product->plugin()) as $k => $v)
+ $result[$k][$day] = (int)$v;
}
- return (string)$google;
- }
-
- public function table_traffic($month=NULL) {
- return View::factory('service/user/plugin/adsl/table_traffic')
- ->set('traffic',$this->traffic_month((! is_null($month) AND trim($month)) ? strtotime($month.'-01') : NULL,FALSE));
+ return $result;
}
/**
- * Search for services matching a term
+ * Calculate the total traffic used in a month
*/
- public function list_autocomplete($term,$index,$value,array $label,array $limit=array(),array $options=NULL) {
- // We only show invoice numbers.
- if (! is_numeric($term))
- return array();
+ private function get_traffic_data_month($period=NULL,$cache=0) {
+ $result = array();
- $ao = Auth::instance()->get_user();
+ foreach ($this->get_traffic_data_daily($period,TRUE,$cache) as $tdata)
+ foreach ($tdata as $k => $v)
+ if (isset($result[$k]))
+ $result[$k] += $v;
+ else
+ $result[$k] = $v;
- $options['key'] = 'id';
- $options['object'] = DB::select($this->_table_name.'.id',$this->_table_name.'.service_number')
- ->from($this->_table_name)
- ->join('service')
- ->on('service.id','=',$this->_table_name.'.service_id')
- ->where('service.account_id','IN',$ao->RTM->customers($ao->RTM))
- ->and_where($this->_table_name.'.service_number','like','%'.$term.'%');
-
- return parent::list_autocomplete($term,$index,$value,$label,$limit,$options);
+ return $result;
}
}
?>
diff --git a/modules/adsl/classes/Model/Service/Plugin/Adsl/Traffic.php b/modules/adsl/classes/Model/Service/Plugin/Adsl/Traffic.php
index 33723b01..1635a387 100644
--- a/modules/adsl/classes/Model/Service/Plugin/Adsl/Traffic.php
+++ b/modules/adsl/classes/Model/Service/Plugin/Adsl/Traffic.php
@@ -21,13 +21,22 @@ class Model_Service_Plugin_Adsl_Traffic extends ORM_OSB {
'plan'=>array('model'=>'Service_Plugin_Adsl','foreign_key'=>'service_username','far_key'=>'service'),
);
- private $metrics = array(
- 'up_peak',
- 'up_offpeak',
- 'down_peak',
- 'down_offpeak',
- 'peer',
- 'internal',
+ public static $metrics = array(
+ 'down_peak'=>'base_down_peak',
+ 'down_offpeak'=>'base_down_offpeak',
+ 'up_peak'=>'base_up_peak',
+ 'up_offpeak'=>'base_up_offpeak',
+ 'peer'=>'base_down_peak',
+ 'internal'=>'base_down_offpeak',
+ );
+
+ private $_friendly = array(
+ 'base_up_peak'=>'UP Peak',
+ 'base_up_offpeak'=>'UP Offpeak',
+ 'base_down_peak'=>'DOWN Peak',
+ 'base_down_offpeak'=>'DOWN Offpeak',
+ 'base_peer'=>'Peer',
+ 'base_internal'=>'Internal',
);
public function rules() {
@@ -39,12 +48,16 @@ class Model_Service_Plugin_Adsl_Traffic extends ORM_OSB {
return $result;
}
+ public function friendly($name) {
+ return isset($this->_friendly[$name]) ? $this->_friendly[$name] : $name;
+ }
+
public function save(Validation $validation = NULL) {
// If all our values are zero/NULL, we'll ignore if our previous one was.
if ($this->total() !== 0)
return parent::save($validation);
- $l = ORM::factory($this->_object_name)->where('service','=',$this->service)->where('supplier_id','=',$this->supplier_id)->list_last();
+ $l = ORM::factory($this->_object_name)->where('service','=',$this->service)->where('supplier_id','=',$this->supplier_id)->find_last();
if ($l->total() !== 0)
return parent::save($validation);
@@ -57,10 +70,23 @@ class Model_Service_Plugin_Adsl_Traffic extends ORM_OSB {
return $this;
}
+ /**
+ * Generate the select statements to SUM up the traffic metrics that we use
+ */
+ public function selectsummetric() {
+ foreach (Model_Service_Plugin_Adsl_Traffic::$metrics as $metric=>$v)
+ $this->select(array("sum(".$metric.")",$metric));
+
+ return $this;
+ }
+
+ /**
+ * Total up the traffic into the metrics we use
+ */
public function total() {
$result = 0;
- foreach ($this->metrics as $metric) {
+ foreach (array_keys(Model_Service_Plugin_Adsl_Traffic::$metrics) as $metric) {
if (is_null($this->$metric))
$this->$metric = 0;
@@ -70,21 +96,26 @@ class Model_Service_Plugin_Adsl_Traffic extends ORM_OSB {
return $result;
}
- public function traffic(Model_Product_Plugin_Adsl $plan) {
- // Roll up the charges according to the product plan configuration
- return ADSL::allowance(array(
- 'base_down_peak'=>is_null($plan->base_down_peak) ? NULL : $this->down_peak,
- 'base_down_offpeak'=>is_null($plan->base_down_offpeak) ? NULL : $this->down_offpeak,
- 'base_up_peak'=>is_null($plan->base_up_peak) ? NULL : $this->up_peak,
- 'base_up_offpeak'=>is_null($plan->base_up_offpeak) ? NULL : $this->up_offpeak,
- 'extra_down_peak'=>$plan->extra_down_peak,
- 'extra_down_offpeak'=>$plan->extra_down_offpeak,
- 'extra_up_peak'=>$plan->extra_up_peak,
- 'extra_up_offpeak'=>$plan->extra_up_offpeak,
- ));
+ /**
+ * Collapse our traffic data into an array as per $this->_metric
+ */
+ public function traffic_data() {
+ $result = array();
+
+ foreach (Model_Service_Plugin_Adsl_Traffic::$metrics as $metric=>$v) {
+ if (! isset($result[$v]))
+ $result[$v] = 0;
+
+ $result[$v] += $this->{$metric};
+ }
+
+ return $result;
}
- public function list_last() {
+ /**
+ * Find the last traffic record
+ */
+ public function find_last() {
return $this->order_by('date','DESC')->order_by('time','DESC')->find();
}
}
diff --git a/modules/adsl/classes/Service/Traffic/Adsl.php b/modules/adsl/classes/Service/Traffic/Adsl.php
index 16516dc0..644db4c3 100644
--- a/modules/adsl/classes/Service/Traffic/Adsl.php
+++ b/modules/adsl/classes/Service/Traffic/Adsl.php
@@ -106,42 +106,6 @@ abstract class Service_Traffic_Adsl {
}
}
- public function charge_excess_traffic() {
- $date = strtotime('last month');
-
- // @todo need a way to find out services that have traffic charges dynamically.
- foreach ($this->aso->services() as $so) {
- if ($charge = $so->plugin()->traffic_lastmonth_exceed(FALSE,$date)) {
- foreach ($charge as $metric => $details) {
- $co = ORM::factory('Charge');
-
- $co->status = 0;
- $co->sweep_type = 6;
- $co->account_id = $so->account_id;
- $co->service_id = $so->id;
- // @todo This needs to be calculated.
- $co->type = 5;
- $co->amount = $details['rate'];
- // @todo This needs to be calculated.
- $co->taxable = TRUE;
- $co->quantity = ceil($details['excess']/1000);
- $co->description = _('Excess Traffic');
- // @todo This need to be improved = strtotime function should be the one used in the function call
- $co->attributes = implode("\n",array(
- sprintf('ADSL Service==%s',$so->plugin()->service_number),
- sprintf('Allowance==%s',$details['allowance']),
- sprintf('Metric==%s',$metric),
- sprintf('Used==%s',$details['used']),
- sprintf('Month==%s',date('Y-m',$date)),
- ));
-
- $co->check();
- $co->save();
- }
- }
- }
- }
-
public function alert_traffic() {
foreach ($this->aso->services() as $so) {
if (! $so->plugin()->report_traffic())
diff --git a/modules/adsl/classes/Task/Adsl/Trafficcharge.php b/modules/adsl/classes/Task/Adsl/Trafficcharge.php
index 9ee75983..c1b822e9 100644
--- a/modules/adsl/classes/Task/Adsl/Trafficcharge.php
+++ b/modules/adsl/classes/Task/Adsl/Trafficcharge.php
@@ -15,12 +15,50 @@ class Task_Adsl_Trafficcharge extends Task_Adsl_Trafficget {
);
protected function _execute(array $params) {
- foreach ($this->_traffic_suppliers(TRUE) as $aso) {
- if ($params['verbose'])
- echo $aso->name."\n";
+ $date = strtotime('last month');
+ $c = array();
- Service_Traffic_Adsl::instance($aso->name)->charge_excess_traffic();
+ // @todo Pick up services that are no longer active, but were inactive < 30 days ago.
+ foreach (ORM::factory('Service')->list_byplugin('ADSL') as $so) {
+ if ($params['verbose'])
+ echo $so->service_name()."\n";
+
+ if ($x=$so->plugin()->traffic_excess($date)) {
+ $po = $so->plugin()->plan();
+ $cost = $po->cost_extra();
+ $allowance = $po->allowance(array(),FALSE,TRUE,1000);
+ $used = $so->plugin()->traffic_month($date,FALSE,1000);
+
+ foreach ($x as $k=>$v) {
+ $co = ORM::factory('Charge');
+
+ // @todo This needs to be calculated.
+ $co->type = 5;
+ $co->sweep_type = 6;
+
+ $co->account_id = $so->account_id;
+ $co->service_id = $so->id;
+ $co->amount = $cost[$k];
+ $co->taxable = $so->product->taxable;
+ $co->quantity = $v;
+ $co->date_charge = time();
+ $co->description = sprintf('Excess Traffic %s',date('Y-m',$date));
+
+ $co->attributes = array(
+ 'Allowance'=>$allowance[$k],
+ 'Used'=>$used[$k],
+ 'Metric'=>$so->plugin()->traffic->friendly($k),
+ 'Month'=>date('Y-m',$date),
+ );
+
+ $co->save();
+ }
+
+ array_push($c,$so->id);
+ }
}
+
+ return sprintf('%s excess charges created (%s)',count($c),join('|',$c));
}
}
?>
diff --git a/modules/adsl/views/adsl/reseller/billing.php b/modules/adsl/views/adsl/reseller/billing.php
index 393cfec9..62ae3e7d 100644
--- a/modules/adsl/views/adsl/reseller/billing.php
+++ b/modules/adsl/views/adsl/reseller/billing.php
@@ -12,16 +12,16 @@
services(TRUE) as $so) : ?>
- plugin(); $po = $p->product(); $service_number = $p->service_number; ?>
+ plugin(); $po = $p->admin_plan(); $service_number = $p->service_number; ?>
-
+
|
id),$so->id); ?> |
adsl_supplier_plan->name().($p->provided_adsl_plan_id ? '*' : ''); ?> |
contract_date_start(TRUE); ?> |
contract_date_end(TRUE); ?> |
- adsl_supplier_plan->total()); ?> |
+ adsl_supplier_plan->display('base_cost'); ?> |
charge($service_number)); ?> |
excess($service_number)); ?> |
diff --git a/modules/adsl/views/product/plugin/adsl/feature_summary.php b/modules/adsl/views/product/plugin/adsl/feature_summary.php
index ba5d04b7..f1c2190c 100644
--- a/modules/adsl/views/product/plugin/adsl/feature_summary.php
+++ b/modules/adsl/views/product/plugin/adsl/feature_summary.php
@@ -4,14 +4,14 @@
Speed
- adsl_supplier_plan->display('speed'); ?>
+ supplier_plan->display('speed'); ?>
Peak Downloads Included
- base_down_peak/1000; ?> GB, excess display('extra_down_peak'); ?>/GB.
+ base_down_peak/1000; ?> GB, excess display('extra_down_peak'); ?>/GB.
- base_down_offpeak OR $po->extra_down_offpeak) : ?>
+ hasOffpeak()) : ?>
OffPeak Downloads Included
- base_down_offpeak/1000; ?> GB, excess display('extra_down_offpeak'); ?>/GB.
+ base_down_offpeak/1000; ?> GB, excess display('extra_down_offpeak'); ?>/GB.
diff --git a/modules/adsl/views/service/user/plugin/adsl/table_traffic.php b/modules/adsl/views/service/user/plugin/adsl/table_traffic.php
index a90e29e8..4ef2b235 100644
--- a/modules/adsl/views/service/user/plugin/adsl/table_traffic.php
+++ b/modules/adsl/views/service/user/plugin/adsl/table_traffic.php
@@ -1,9 +1,19 @@
-
-
- $usage) { ?>
-
- |
- |
-
-
+
+
+ |
+
+ friendly($i); ?> |
+
+
+
+ $details) : ?>
+
+ |
+
+
+ |
+
+
+
+
diff --git a/modules/adsl/views/service/user/plugin/adsl/view.php b/modules/adsl/views/service/user/plugin/adsl/view.php
index ebc6f5d8..b035c141 100644
--- a/modules/adsl/views/service/user/plugin/adsl/view.php
+++ b/modules/adsl/views/service/user/plugin/adsl/view.php
@@ -39,22 +39,42 @@
-
This Month
- traffic_month(NULL); ?>
-
Last Month
- traffic_lastmonth(); ?>
+ traffic_month(strtotime('last month'),TRUE,1000); ?> GB
+
+ This Month
+ traffic_month(strtotime('yesterday'),TRUE,1000); ?> GB
+
+ Excess Traffic
+ $traffic_excess(strtotime('yesterday'),TRUE,TRUE); ?>
diff --git a/modules/charge/classes/Model/Charge.php b/modules/charge/classes/Model/Charge.php
index 8098f6ff..b422e33c 100644
--- a/modules/charge/classes/Model/Charge.php
+++ b/modules/charge/classes/Model/Charge.php
@@ -42,7 +42,7 @@ class Model_Charge extends ORM_OSB {
array('StaticList_SweepType::get',array(':value')),
),
'void'=>array(
- array('StaticList_YesNo::get',array(':value')),
+ array('StaticList_YesNo::get',array(':value',TRUE)),
),
);
diff --git a/modules/domain/classes/Model/Service/Plugin/Domain.php b/modules/domain/classes/Model/Service/Plugin/Domain.php
index a514acd4..a3553b08 100644
--- a/modules/domain/classes/Model/Service/Plugin/Domain.php
+++ b/modules/domain/classes/Model/Service/Plugin/Domain.php
@@ -52,11 +52,6 @@ class Model_Service_Plugin_Domain extends Model_Service_Plugin {
return sprintf('%s - %s',_('Domain Name License'),$this->name());
}
- public function service_view() {
- return View::factory('service/user/plugin/domain/view')
- ->set('o',$this);
- }
-
public function username_value() {
return $this->registrar_username;
}
diff --git a/modules/email/classes/Model/Email/Template.php b/modules/email/classes/Model/Email/Template.php
index de015a4f..9e1d8cc4 100644
--- a/modules/email/classes/Model/Email/Template.php
+++ b/modules/email/classes/Model/Email/Template.php
@@ -23,7 +23,7 @@ class Model_Email_Template extends ORM_OSB {
protected $_display_filters = array(
'status'=>array(
- array('StaticList_YesNo::get',array(':value')),
+ array('StaticList_YesNo::get',array(':value',TRUE)),
),
);
diff --git a/modules/export/views/export/module/admin/edit.php b/modules/export/views/export/module/admin/edit.php
index 336db3fb..b2437c12 100644
--- a/modules/export/views/export/module/admin/edit.php
+++ b/modules/export/views/export/module/admin/edit.php
@@ -3,7 +3,7 @@