Open Source Billing
This commit is contained in:
914
modules/service/classes/Controller/Admin/Service.php
Normal file
914
modules/service/classes/Controller/Admin/Service.php
Normal file
@@ -0,0 +1,914 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides Admin Service functions
|
||||
*
|
||||
* @package Service
|
||||
* @category Controllers/Admin
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Controller_Admin_Service extends Controller_TemplateDefault_Admin {
|
||||
// @todo This "module" menu items should belong in the module dir.
|
||||
protected $secure_actions = array(
|
||||
'ajaxlist'=>TRUE,
|
||||
'ajaxjson_traffic'=>TRUE,
|
||||
'adslstat'=>TRUE,
|
||||
'list'=>TRUE,
|
||||
'listbycheckout'=>TRUE,
|
||||
'listadslbilling'=>TRUE,
|
||||
'listadslservices'=>TRUE,
|
||||
'listexpiring'=>TRUE,
|
||||
'listdomainservices'=>TRUE,
|
||||
'listdomainservicesbysupplier'=>TRUE,
|
||||
'listdomainservicesbydnshost'=>TRUE,
|
||||
'listhostservices'=>TRUE,
|
||||
'listhostservicesbysupplier'=>TRUE,
|
||||
'listhspaservices'=>TRUE,
|
||||
'listwebservices'=>TRUE,
|
||||
'listinvoicesoon'=>TRUE,
|
||||
'update'=>TRUE,
|
||||
'view'=>TRUE,
|
||||
);
|
||||
|
||||
public function action_ajaxlist() {
|
||||
$result = array();
|
||||
|
||||
$result += ORM::factory('Service')->list_autocomplete(
|
||||
isset($_REQUEST['term']) ? $_REQUEST['term'] : '',
|
||||
'id',
|
||||
isset($_REQUEST['aid']) ? array(array('account_id','=',$_REQUEST['aid'])) : array());
|
||||
|
||||
$this->auto_render = FALSE;
|
||||
$this->response->headers('Content-Type','application/json');
|
||||
$this->response->body(json_encode(array_values($result)));
|
||||
}
|
||||
|
||||
public function action_ajaxjson_traffic() {
|
||||
$result = array();
|
||||
$svs = ORM::factory('Service')->list_bylistgroup('ADSL');
|
||||
$data = $this->consoltraffic($svs,time());
|
||||
|
||||
$google = GoogleChart::factory('ComboChart')
|
||||
->stacked(TRUE);
|
||||
|
||||
foreach ($data['data'] as $key => $values)
|
||||
$google->sdata(array('yl'=>$key),array($key=>$values));
|
||||
|
||||
$google->sdata(array('yr'=>'services'),array('services'=>$data['svs']));
|
||||
|
||||
$this->auto_render = FALSE;
|
||||
$this->response->headers('Content-Type','application/json');
|
||||
$this->response->body($google->json());
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a list of services
|
||||
*/
|
||||
public function action_list() {
|
||||
$id = $this->request->param('id');
|
||||
|
||||
$svs = ORM::factory('Service');
|
||||
|
||||
if ($id)
|
||||
$svs->where_active()->and_where('account_id','=',$id);
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('Customer Services'),
|
||||
'body'=>Table::display(
|
||||
$svs->find_all(),
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'status'=>array('label'=>'Active'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* List all services by their default checkout method
|
||||
*/
|
||||
public function action_listbycheckout() {
|
||||
$svs = array();
|
||||
// @todo This needs to be configurable
|
||||
$go = ORM::factory('Group',array('name'=>'Personal'));
|
||||
|
||||
foreach (ORM::factory('Account')->list_active() as $ao)
|
||||
if ($ao->has_any('group',array($go)))
|
||||
foreach ($ao->service->list_active() as $so)
|
||||
if (! $so->service_billing->checkout_plugin_id)
|
||||
array_push($svs,$so);
|
||||
|
||||
if ($svs)
|
||||
Block::add(array(
|
||||
'title'=>'Services that should be auto-billed',
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'status'=>array('label'=>'Active'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'date_next_invoice'=>array('label'=>'Next Invoice'),
|
||||
'account->invoices_due_total(NULL,TRUE)'=>array('label'=>'Due Invoices'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
|
||||
foreach (ORM::factory('Checkout')->list_active() as $co) {
|
||||
$svs = array();
|
||||
|
||||
foreach ($co->account->find_all() as $ao)
|
||||
foreach ($ao->service->list_active() as $so)
|
||||
if ($so->service_billing->checkout_plugin_id == $co->id)
|
||||
array_push($svs,$so);
|
||||
|
||||
if ($svs)
|
||||
Block::add(array(
|
||||
'title'=>$co->name,
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'status'=>array('label'=>'Active'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'date_next_invoice'=>array('label'=>'Next Invoice'),
|
||||
'account->invoices_due_total(NULL,TRUE)'=>array('label'=>'Due Invoices'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private function consoltraffic($svs,$date) {
|
||||
$data = 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;
|
||||
|
||||
$c[$month] = 1;
|
||||
}
|
||||
|
||||
if (isset($data['data'][$metric][$month]))
|
||||
$data['data'][$metric][$month] += (int)$traffic;
|
||||
else
|
||||
$data['data'][$metric][$month] = (int)$traffic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort($data['svs']);
|
||||
foreach ($data['data'] as $metric => $details)
|
||||
ksort($data['data'][$metric]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function action_listadslservices() {
|
||||
$id = $this->request->param('id');
|
||||
|
||||
$svs = $list = ORM::factory('Service')->list_bylistgroup('ADSL');
|
||||
|
||||
if ($id) {
|
||||
$svs = array();
|
||||
foreach ($list as $so)
|
||||
if ($so->account_id == $id)
|
||||
array_push($svs,$so);
|
||||
}
|
||||
|
||||
$google = GoogleChart::factory('ComboChart')
|
||||
->dataurl(URL::link('admin','service/ajaxjson_traffic',TRUE))
|
||||
->title(sprintf('ADSL traffic as at %s',date('Y-m-d',strtotime('yesterday'))));
|
||||
|
||||
Block::add(array('body'=>(string)$google));
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('ADSL Services'),
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
NULL,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'name()'=>array('label'=>'Service'),
|
||||
'plugin()->ipaddress()'=>array('label'=>'IP Address'),
|
||||
'product->plugin()->speed'=>array('label'=>'Speed'),
|
||||
'product->plugin()->allowance()'=>array('label'=>'Allowance'),
|
||||
'plugin()->traffic_thismonth()'=>array('label'=>'This Month'),
|
||||
'plugin()->traffic_lastmonth()'=>array('label'=>'Last Month'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'date_next_invoice'=>array('label'=>'Next Invoice'),
|
||||
'product->display("status")'=>array('label'=>'Current'),
|
||||
),
|
||||
array(
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a list of services that are expiring or have expired
|
||||
*/
|
||||
public function action_listexpiring() {
|
||||
$svs = ORM::factory('Service')->list_expiring();
|
||||
|
||||
Sort::MAsort($svs,'expire()');
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('ADSL Services'),
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
NULL,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Service'),
|
||||
'expire(TRUE)'=>array('label'=>'Expires'),
|
||||
'due(TRUE)'=>array('label'=>'Due'),
|
||||
),
|
||||
array(
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listhspaservices() {
|
||||
$svs = ORM::factory('Service')->list_bylistgroup('HSPA');
|
||||
$data = $this->consoltraffic($svs,time());
|
||||
|
||||
$google = GoogleChart::factory('Legacy')
|
||||
->type('vertical_bar')
|
||||
->title(sprintf('HSPA traffic as at %s',date('Y-m-d',strtotime('yesterday'))));
|
||||
|
||||
foreach ($data['data'] as $key => $values)
|
||||
$google->data(array('yl'=>$key),array($key=>$values));
|
||||
|
||||
$google->data(array('yr'=>'services'),array('services'=>$data['svs']));
|
||||
|
||||
Block::add(array('body'=>(string)$google));
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('HSPA Services'),
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
NULL,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'name()'=>array('label'=>'Service'),
|
||||
'plugin()->ipaddress()'=>array('label'=>'IP Address'),
|
||||
'product->plugin()->speed'=>array('label'=>'Speed'),
|
||||
'product->plugin()->allowance()'=>array('label'=>'Allowance'),
|
||||
'plugin()->traffic_thismonth()'=>array('label'=>'This Month'),
|
||||
'plugin()->traffic_lastmonth()'=>array('label'=>'Last Month'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'date_next_invoice'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listdomainservices() {
|
||||
$svs = ORM::factory('Service')->list_bylistgroup('DOMAIN');
|
||||
Sort::MAsort($svs,'name()');
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('Domain Names'),
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'plugin()->display("domain_expire")'=>array('label'=>'Expire'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'display("date_next_invoice")'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listdomainservicesbysupplier() {
|
||||
$svs = ORM::factory('Service')->list_bylistgroup('DOMAIN');
|
||||
Sort::MAsort($svs,'plugin()->domain_registrar_id,name()');
|
||||
|
||||
$list = array();
|
||||
|
||||
foreach ($svs as $so)
|
||||
$list[$so->plugin()->domain_registrar_id][] = $so;
|
||||
|
||||
foreach (array_keys($list) as $sid)
|
||||
Block::add(array(
|
||||
'title'=>sprintf(_('Domain Names by Supplier %s'),$sid),
|
||||
'body'=>Table::display(
|
||||
$list[$sid],
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'plugin()->display("domain_expire")'=>array('label'=>'Expire'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'display("date_next_invoice")'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listdomainservicesbydnshost() {
|
||||
$svs = ORM::factory('Service')->list_bylistgroup('DOMAIN');
|
||||
Sort::MAsort($svs,'plugin()->service_plugin_host,name()');
|
||||
|
||||
$list = array();
|
||||
|
||||
foreach ($svs as $so)
|
||||
$list[$so->plugin()->service_plugin_host->host_server_id][] = $so;
|
||||
|
||||
foreach (array_keys($list) as $sid)
|
||||
Block::add(array(
|
||||
'title'=>sprintf(_('Domain Names by DNS Host [%s]'),$sid),
|
||||
'body'=>Table::display(
|
||||
$list[$sid],
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'plugin()->domain_registrar->id'=>array('label'=>'SID'),
|
||||
'plugin()->domain_registrar->name'=>array('label'=>'Supplier'),
|
||||
'display("date_next_invoice")'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listhostservices() {
|
||||
$svs = ORM::factory('Service')->list_bylistgroup('HOST');
|
||||
Sort::MAsort($svs,'name()');
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('Hosting Services'),
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'plugin()->display("host_expire")'=>array('label'=>'Expire'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'display("date_next_invoice")'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listhostservicesbysupplier() {
|
||||
$svs = ORM::factory('Service')->list_bylistgroup('HOST');
|
||||
Sort::MAsort($svs,'plugin()->host_server,name()');
|
||||
|
||||
$list = array();
|
||||
|
||||
foreach ($svs as $so)
|
||||
$list[$so->plugin()->host_server_id][] = $so;
|
||||
|
||||
foreach (array_keys($list) as $sid)
|
||||
Block::add(array(
|
||||
'title'=>sprintf(_('Hosting by Supplier %s'),$sid),
|
||||
'body'=>Table::display(
|
||||
$list[$sid],
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'plugin()->display("host_expire")'=>array('label'=>'Expire'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'display("date_next_invoice")'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listwebservices() {
|
||||
$svs = ORM::factory('Service')->list_bylistgroup('WEB');
|
||||
Sort::MAsort($svs,'name()');
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('SSL Services'),
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'display("date_next_invoice")'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconcile billing for an ADSL supplier
|
||||
*
|
||||
* @todo this should really be in a different class, since adsl wont be part of the main app
|
||||
*/
|
||||
public function action_listadslbilling() {
|
||||
$id = $this->request->param('id');
|
||||
|
||||
$aso = ORM::factory('ADSL_Supplier',$id);
|
||||
|
||||
// Process upload
|
||||
// @todo This should be separated out by supplier in case each supplier has a different format
|
||||
if ($_FILES) {
|
||||
$files = Validation::factory($_FILES)
|
||||
->rule('csv','Upload::valid')
|
||||
->rule('csv','Upload::not_empty')
|
||||
->rule('csv','Upload::type',array(':value',array('csv')))
|
||||
->rule('csv','Upload::size',array(':value','10M'));
|
||||
|
||||
if ($files->check())
|
||||
foreach ($files->data() as $file)
|
||||
$csv = $this->process($file);
|
||||
}
|
||||
|
||||
// @todo add a display if there are no items
|
||||
$i = $j = 0;
|
||||
$total = 0;
|
||||
$summary = '';
|
||||
$output = View::factory($this->viewpath().'/head');
|
||||
$output .= '<table class="box-left">';
|
||||
foreach ($aso->services(TRUE) as $so) {
|
||||
$po = $so->plugin()->product();
|
||||
|
||||
// Reset our uploaded data
|
||||
$uploaded = array();
|
||||
$uploaded['excess'] = empty($csv[$so->plugin()->service_number]['excess']) ? 0 : $csv[$so->plugin()->service_number]['excess'];
|
||||
|
||||
// If our uploaded file has some cost data.
|
||||
if (! empty($csv[$so->plugin()->service_number])) {
|
||||
$uploaded['amount'] =
|
||||
(empty($csv[$so->plugin()->service_number]['cost']) ? 0 : $csv[$so->plugin()->service_number]['cost']) +
|
||||
(empty($csv[$so->plugin()->service_number]['credit']) ? 0 : $csv[$so->plugin()->service_number]['credit']);
|
||||
|
||||
// Record the the exception if the cost is not expected
|
||||
if (round($po->adsl_supplier_plan->base_cost+$po->adsl_supplier_plan->tax(),2) != $uploaded['amount']) {
|
||||
$summary .= View::factory($this->viewpath().'/summary')
|
||||
->set('service',$so)
|
||||
->set('plan',$po)
|
||||
->set('planoverride',$so->plugin()->provided_adsl_plan_id ? TRUE : FALSE)
|
||||
->set('amount',$uploaded['amount'])
|
||||
->set('i',$j++%2);
|
||||
|
||||
$uploaded['checked'] = '';
|
||||
} else {
|
||||
$uploaded['checked'] = 'checked="checked"';
|
||||
}
|
||||
|
||||
unset($csv[$so->plugin()->service_number]);
|
||||
|
||||
} else {
|
||||
$uploaded['checked'] = '';
|
||||
$uploaded['amount'] = 0;
|
||||
}
|
||||
|
||||
$total += $uploaded['amount'];
|
||||
|
||||
$output .= View::factory($this->viewpath().'/body')
|
||||
->set('service',$so)
|
||||
->set('plan',$po)
|
||||
->set('planoverride',$so->plugin()->provided_adsl_plan_id ? TRUE : FALSE)
|
||||
->set('checked',$uploaded['checked'])
|
||||
->set('amount',$uploaded['amount'])
|
||||
->set('excess',$uploaded['excess'])
|
||||
->set('adsl',$so->plugin())
|
||||
->set('i',$i++%2);
|
||||
}
|
||||
|
||||
$output .= View::factory($this->viewpath().'/foot')
|
||||
->set('total',$total);
|
||||
|
||||
$output .= '</table>';
|
||||
|
||||
// Summary Report of remaining CSV items.
|
||||
if (! empty($csv))
|
||||
foreach ($csv as $service => $item) {
|
||||
$summary .= View::factory($this->viewpath().'/summary_exception')
|
||||
->set('service',$service)
|
||||
->set('item',$item)
|
||||
->set('i',$j++%2);
|
||||
}
|
||||
|
||||
$output .= Form::open(NULL,array('enctype'=>'multipart/form-data'));
|
||||
$output .= '<div>';
|
||||
$output .= Form::file('csv');
|
||||
$output .= Form::submit('submit','upload',array('class'=>'form_button'));
|
||||
$output .= '</div>';
|
||||
$output .= Form::close();
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('ADSL Services'),
|
||||
'body'=>$output,
|
||||
));
|
||||
|
||||
if ($summary)
|
||||
Block::add(array(
|
||||
'title'=>_('Exception Charges'),
|
||||
'body'=>'<table class="box-left">'.$summary.'</table>',
|
||||
));
|
||||
|
||||
Style::add(array(
|
||||
'type'=>'file',
|
||||
'data'=>'css/list.css',
|
||||
));
|
||||
}
|
||||
|
||||
private function process(array $file) {
|
||||
$data = file_get_contents($file['tmp_name']);
|
||||
|
||||
if (! $data)
|
||||
return;
|
||||
|
||||
$start = $end = FALSE;
|
||||
$result = array();
|
||||
foreach (preg_split("/\n/",$data) as $line) {
|
||||
// Items start after "Item ID"
|
||||
if (! $start && preg_match('/^Item ID,/',$line)) {
|
||||
$start = true;
|
||||
continue;
|
||||
|
||||
// Items end after "Subtotal"
|
||||
} elseif ($start && ! $end && preg_match('/^Subtotal:,/',$line)) {
|
||||
$end = true;
|
||||
continue;
|
||||
|
||||
// If we havent started or not ended, continue
|
||||
} elseif (! $start || $end) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$record = explode(',',$line);
|
||||
|
||||
// 1 = Item ID (ignore)
|
||||
// 2 = Reference ID (ignore - its not useful for us)
|
||||
// 3 = Category (always appears blank)
|
||||
// 4 = Item Description (has our service number, rental and excess charges description)
|
||||
// 0nnnnnnnnn - Monthly Internet Charge On Plan XXXXX For billing period (dd/mm/yyyy - dd/mm/yyyy) (7 FIELDED LINES)
|
||||
// 0nnnnnnnnn - Excess usage charges for March 2013 (8 FIELDED LINES)
|
||||
// 5 = Quantity
|
||||
// Always 1 for Plan Fees
|
||||
// 0nnnnnnnnn@graytech.net.au Excess Usage y GB (for excess charges)
|
||||
// 6 = Unit Price
|
||||
// Always 1 for Excess Usage (probably quantity)
|
||||
// 7 = Total Price
|
||||
// Unit price for Excess Usage
|
||||
// 8 = Total Price for Excess Usage
|
||||
|
||||
if (! count($record) >= 7)
|
||||
throw Kohana_Exception('Format of CSV file changed? (:record)',array(':record'=>$record));
|
||||
|
||||
|
||||
if (preg_match('/Monthly Internet 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]);
|
||||
|
||||
} elseif (preg_match('/VISP Credit/',$record[3])) {
|
||||
list($service,$description) = explode(':',(preg_replace('/([0-9]+)\s+-\s+(.*)$/',"$1:$2",$record[3])));
|
||||
$result[$service]['credit'] = str_replace('$','',$record[6]);
|
||||
|
||||
} elseif (preg_match('/Excess usage charges for /',$record[3])) {
|
||||
list($service,$description) = explode(':',(preg_replace('/([0-9]+)\s+-\s+(.*)$/',"$1:$2",$record[3])));
|
||||
$result[$service]['excess'] = str_replace('$','',$record[7]);
|
||||
|
||||
// Ignore Payment For Invoice lines
|
||||
} elseif (preg_match('/Payment For Invoice:/',$record[3])) {
|
||||
|
||||
} else {
|
||||
try {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* List services that need to be invoiced.
|
||||
*/
|
||||
public function action_listinvoicesoon() {
|
||||
Block::add(array(
|
||||
'title'=>_('Services to Invoice'),
|
||||
'body'=>Table::display(
|
||||
ORM::factory('Service')->list_invoicesoon(ORM::factory('Invoice')->config('GEN_SOON_DAYS')),
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'date_next_invoice'=>array('label'=>'Next Invoice'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'charges_new()'=>array('label'=>'Charges','class'=>'right'),
|
||||
'status'=>array('label'=>'Active'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_update() {
|
||||
$id = $this->request->param('id');
|
||||
$so = ORM::factory('Service',$id);
|
||||
|
||||
if (! $so->loaded())
|
||||
HTTP::redirect('welcome/index');
|
||||
|
||||
if ($_POST) {
|
||||
if (isset($_POST['plugin']) AND $_POST['plugin'])
|
||||
if (! $so->plugin()->values($_POST['plugin'])->update()->saved())
|
||||
throw new Kohana_Exception('Failed to save updates to plugin data for record :record',array(':record'=>$so->id()));
|
||||
|
||||
if (! $so->values($_POST)->update()->saved())
|
||||
throw new Kohana_Exception('Failed to save updates to service data for record :record',array(':record'=>$so->id()));
|
||||
}
|
||||
|
||||
Block::add(array(
|
||||
'title'=>sprintf('%s %s:%s',_('Update Service'),$so->id(),$so->name()),
|
||||
'body'=>View::factory($this->viewpath())
|
||||
->set('so',$so)
|
||||
->set('mediapath',Route::get('default/media'))
|
||||
->set('plugin_form',$so->admin_update()),
|
||||
));
|
||||
|
||||
// @todo Investigate a better way of preparing for jscalendar
|
||||
Script::add(array(
|
||||
'type'=>'file',
|
||||
'data'=>'js/dhtml.calendar.js',
|
||||
));
|
||||
Script::add(array(
|
||||
'type'=>'file',
|
||||
'data'=>'js/dhtml.calendar-setup.js',
|
||||
));
|
||||
Script::add(array(
|
||||
'type'=>'file',
|
||||
'data'=>'js/dhtml.calendar-en.js',
|
||||
));
|
||||
Script::add(array(
|
||||
'type'=>'file',
|
||||
'data'=>'js/dhtml.date_selector.js',
|
||||
));
|
||||
Style::add(array(
|
||||
'type'=>'file',
|
||||
'data'=>'css/dhtml.calendar.css',
|
||||
));
|
||||
}
|
||||
|
||||
public function action_view() {
|
||||
list($id,$output) = Table::page(__METHOD__);
|
||||
|
||||
$so = ORM::factory('Service',$id);
|
||||
|
||||
if (! $so->loaded() OR ! Auth::instance()->authorised($so->account)) {
|
||||
$this->template->content = 'Unauthorised or doesnt exist?';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$doutput = $loutput = '';
|
||||
|
||||
$loutput .= View::factory($this->viewpath())
|
||||
->set('so',$so);
|
||||
|
||||
// Validate the transactions
|
||||
$bt = NULL;
|
||||
$save = (isset($_REQUEST['go']) && $_REQUEST['go']=1) ? 1 : 0;
|
||||
$xsid=197;
|
||||
foreach ($so->transactions()->where('item_type','=',0)->find_all() as $iio) {
|
||||
if (! $iio->invoice->status) continue;
|
||||
// @todo This hard coding of 3070 should be removed.
|
||||
if ($iio->service_id == $xsid AND $iio->invoice_id < 3070) continue;
|
||||
if ($iio->quantity < 0 OR $iio->price_base < 0)
|
||||
continue;
|
||||
if (in_array($iio->id,array(960)))
|
||||
continue;
|
||||
|
||||
if ($iio->invoice_id > 4000 OR $iio->product->prod_plugin_file=="ADSL")
|
||||
$a = FALSE;
|
||||
else
|
||||
$a = TRUE;
|
||||
|
||||
if (is_null($bt))
|
||||
$bt = $iio->date_start;
|
||||
|
||||
// $doutput .= sprintf('%s: BT is: %s [%s]<br/>',$iio->id,Config::date($bt),$bt);
|
||||
|
||||
$pdata = Period::details($iio->recurring_schedule,$a ? NULL : $iio->product->price_recurr_weekday,$bt,TRUE);
|
||||
|
||||
switch ($iio->recurring_schedule) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 5:
|
||||
if ($iio->date_start != $pdata['start_time']) {
|
||||
$doutput .= sprintf('%s: Set start_time: %s [%s]<br/>',$iio->id,Config::date($pdata['start_time']),$pdata['start_time']);
|
||||
$iio->date_start=$pdata['start_time'];
|
||||
}
|
||||
|
||||
if ($iio->date_stop != $pdata['end_time']) {
|
||||
$doutput .= sprintf('%s: Set end_time: %s [%s] <br/>',$iio->id,Config::date($pdata['end_time']),$pdata['end_time']);
|
||||
$iio->date_stop=$pdata['end_time'];
|
||||
}
|
||||
$bt = $pdata['end_time']+86400;
|
||||
|
||||
//$doutput .= sprintf('%s: BT now: %s (%s) [%s]<br/>',$iio->id,Config::date($bt),Config::date($pdata['end_time']),$bt);
|
||||
break;
|
||||
|
||||
default:
|
||||
$doutput .= sprintf('%s: %s Not handled',$iio->id,$iio->recurring_schedule);
|
||||
}
|
||||
//$doutput .= '<br/>';
|
||||
if ($save) {
|
||||
$iio->save();
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_REQUEST['go']))
|
||||
HTTP::redirect(URL::link('admin','service/view/'.$so->id));
|
||||
|
||||
Block::add(array(
|
||||
'title'=>sprintf('Transaction History for %s: %s',$so->id(),$so->name()),
|
||||
'body'=>$loutput,
|
||||
));
|
||||
|
||||
Block::add(array(
|
||||
'title'=>sprintf('Transaction Debug for %s: %s',$so->id(),$so->name()),
|
||||
'body'=>$doutput,
|
||||
));
|
||||
|
||||
$output .= View::factory('service/user/view')
|
||||
->set('so',$so);
|
||||
|
||||
Block::add(array(
|
||||
'title'=>sprintf('%s: %s',$so->id(),$so->service_name()),
|
||||
'body'=>$output,
|
||||
));
|
||||
}
|
||||
|
||||
public function action_adslstat() {
|
||||
$output = '';
|
||||
$svs = ORM::factory('Service')->list_bylistgroup('ADSL');
|
||||
$stats = array();
|
||||
// @todo This needs to be configurable.
|
||||
$traffic = array(1000,2000,5000,10000,25000,50000,75000,100000);
|
||||
$ts = 0;
|
||||
|
||||
foreach ($svs as $a=>$so) {
|
||||
// Number of services
|
||||
if (! isset($stats[$so->product->plugin()->speed]['c']))
|
||||
$stats[$so->product->plugin()->speed]['c'] = 0;
|
||||
|
||||
$stats[$so->product->plugin()->speed]['c']++;
|
||||
$ts++;
|
||||
|
||||
// Amount of traffic
|
||||
$t = array_sum($so->plugin()->traffic_lastmonth(FALSE));
|
||||
$a = 0;
|
||||
foreach (array_reverse($traffic) as $i) {
|
||||
if ($i < $t)
|
||||
break;
|
||||
$a = $i;
|
||||
}
|
||||
|
||||
if (! isset($stats[$so->product->plugin()->speed]['d'][$a]))
|
||||
$stats[$so->product->plugin()->speed]['d'][$a] = 0;
|
||||
|
||||
$stats[$so->product->plugin()->speed]['d'][$a]++;
|
||||
}
|
||||
|
||||
if (count($stats)) {
|
||||
$output .= View::factory($this->viewpath().'/head')
|
||||
->set('name','SPEED');
|
||||
$output .= View::factory($this->viewpath().'/head_data')
|
||||
->set('name','#');
|
||||
foreach ($traffic as $i)
|
||||
$output .= View::factory($this->viewpath().'/head_data')
|
||||
->set('name',$i);
|
||||
$output .= View::factory($this->viewpath().'/head_data')
|
||||
->set('name','Other');
|
||||
$output .= View::factory($this->viewpath().'/head_end');
|
||||
|
||||
foreach ($stats as $speed => $details) {
|
||||
$output .= View::factory($this->viewpath().'/body_head')
|
||||
->set('count',$details['c'])
|
||||
->set('percent',sprintf('%2.1f',$details['c']/$ts*100))
|
||||
->set('speed',$speed);
|
||||
|
||||
foreach ($traffic as $i) {
|
||||
$output .= View::factory($this->viewpath().'/body_data')
|
||||
->set('count',$c=isset($details['d'][$i]) ? $details['d'][$i] : 0)
|
||||
->set('percent',sprintf('%2.1f',$c/$details['c']*100));
|
||||
}
|
||||
|
||||
$output .= View::factory($this->viewpath().'/body_data')
|
||||
->set('count',$c=isset($details['d'][0]) ? $details['d'][0] : 0)
|
||||
->set('percent',sprintf('%2.1f',$c/$details['c']*100));
|
||||
$output .= View::factory($this->viewpath().'/body_end');
|
||||
}
|
||||
|
||||
$output .= View::factory($this->viewpath().'/foot');
|
||||
}
|
||||
|
||||
Block::add(array(
|
||||
'title'=>_('ADSL Traffic Summary Stats - Last Month'),
|
||||
'body'=>$output,
|
||||
));
|
||||
}
|
||||
}
|
||||
?>
|
287
modules/service/classes/Controller/Affiliate/Service.php
Normal file
287
modules/service/classes/Controller/Affiliate/Service.php
Normal file
@@ -0,0 +1,287 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides Affiliate Service functions
|
||||
*
|
||||
* @package Service
|
||||
* @category Controllers/Affiliate
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Controller_Affiliate_Service extends Controller_TemplateDefault_Affiliate {
|
||||
protected $secure_actions = array(
|
||||
'list'=>TRUE,
|
||||
'listbycheckout'=>TRUE,
|
||||
'listadslservices'=>TRUE,
|
||||
'listdomainservices'=>TRUE,
|
||||
'listhostservices'=>TRUE,
|
||||
'listhspaservices'=>TRUE,
|
||||
);
|
||||
|
||||
/**
|
||||
* Show a list of services
|
||||
*/
|
||||
public function action_list() {
|
||||
Block::add(array(
|
||||
'title'=>_('Customer Services'),
|
||||
'body'=>Table::display(
|
||||
$this->filter(ORM::factory('Service')->list_active(),$this->ao->RTM->customers($this->ao->RTM),NULL,'account_id'),
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'status'=>array('label'=>'Active'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* List all services by their default checkout method
|
||||
*/
|
||||
public function action_listbycheckout() {
|
||||
$svs = array();
|
||||
// @todo This needs to be configurable
|
||||
$go = ORM::factory('Group',array('name'=>'Personal'));
|
||||
|
||||
foreach (ORM::factory('Account')->list_active() as $ao)
|
||||
if ($ao->has_any('group',array($go)))
|
||||
foreach ($this->filter($ao->service->list_active(),$this->ao->RTM->customers($this->ao->RTM),NULL,'account_id') as $so)
|
||||
if (! $so->service_billing->checkout_plugin_id)
|
||||
array_push($svs,$so);
|
||||
|
||||
if ($svs)
|
||||
Block::add(array(
|
||||
'title'=>'Services that should be auto-billed',
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'status'=>array('label'=>'Active'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'date_next_invoice'=>array('label'=>'Next Invoice'),
|
||||
'account->invoices_due_total(NULL,TRUE)'=>array('label'=>'Due Invoices'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
else
|
||||
Block::add(array(
|
||||
'title'=>'Services that should be auto-billed',
|
||||
'body'=>_('None found'),
|
||||
));
|
||||
|
||||
foreach (ORM::factory('Checkout')->list_active() as $co) {
|
||||
$svs = array();
|
||||
|
||||
foreach ($co->account->find_all() as $ao)
|
||||
foreach ($this->filter($ao->service->list_active(),$this->ao->RTM->customers($this->ao->RTM),NULL,'account_id') as $so)
|
||||
if ($so->service_billing->checkout_plugin_id == $co->id)
|
||||
array_push($svs,$so);
|
||||
|
||||
if ($svs)
|
||||
Block::add(array(
|
||||
'title'=>$co->name,
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'status'=>array('label'=>'Active'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'date_next_invoice'=>array('label'=>'Next Invoice'),
|
||||
'account->invoices_due_total(NULL,TRUE)'=>array('label'=>'Due Invoices'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
private function consoltraffic($svs,$date) {
|
||||
$data = 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;
|
||||
|
||||
$c[$month] = 1;
|
||||
}
|
||||
|
||||
if (isset($data['data'][$metric][$month]))
|
||||
$data['data'][$metric][$month] += (int)$traffic;
|
||||
else
|
||||
$data['data'][$metric][$month] = (int)$traffic;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ksort($data['svs']);
|
||||
foreach ($data['data'] as $metric => $details)
|
||||
ksort($data['data'][$metric]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function action_listadslservices() {
|
||||
$svs = $this->filter(ORM::factory('Service')->list_bylistgroup('ADSL'),$this->ao->RTM->customers($this->ao->RTM),'name()','account_id');
|
||||
$data = $this->consoltraffic($svs,time());
|
||||
|
||||
$google = GoogleChart::factory('Legacy')
|
||||
->type('vertical_bar')
|
||||
->title(sprintf('ADSL traffic as at %s',date('Y-m-d',strtotime('yesterday'))));
|
||||
|
||||
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::add(array(
|
||||
'title'=>_('ADSL Services'),
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
NULL,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'name()'=>array('label'=>'Service'),
|
||||
'plugin()->ipaddress()'=>array('label'=>'IP Address'),
|
||||
'product->plugin()->speed'=>array('label'=>'Speed'),
|
||||
'product->plugin()->allowance()'=>array('label'=>'Allowance'),
|
||||
'plugin()->traffic_thismonth()'=>array('label'=>'This Month'),
|
||||
'plugin()->traffic_lastmonth()'=>array('label'=>'Last Month'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'date_next_invoice'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listhspaservices() {
|
||||
$svs = $this->filter(ORM::factory('Service')->list_bylistgroup('HSPA'),$this->ao->RTM->customers($this->ao->RTM),'name()','account_id');
|
||||
$data = $this->consoltraffic($svs,time());
|
||||
|
||||
$google = GoogleChart::factory('Legacy')
|
||||
->type('vertical_bar')
|
||||
->title(sprintf('HSPA traffic as at %s',date('Y-m-d',strtotime('yesterday'))));
|
||||
|
||||
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::add(array(
|
||||
'title'=>_('HSPA Services'),
|
||||
'body'=>Table::display(
|
||||
$svs,
|
||||
NULL,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'name()'=>array('label'=>'Service'),
|
||||
'plugin()->ipaddress()'=>array('label'=>'IP Address'),
|
||||
'product->plugin()->speed'=>array('label'=>'Speed'),
|
||||
'product->plugin()->allowance()'=>array('label'=>'Allowance'),
|
||||
'plugin()->traffic_thismonth()'=>array('label'=>'This Month'),
|
||||
'plugin()->traffic_lastmonth()'=>array('label'=>'Last Month'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'date_next_invoice'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listdomainservices() {
|
||||
Block::add(array(
|
||||
'title'=>_('Domain Names'),
|
||||
'body'=>Table::display(
|
||||
$this->filter(ORM::factory('Service')->list_bylistgroup('DOMAIN'),$this->ao->RTM->customers($this->ao->RTM),'name()','account_id'),
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'plugin()->display("domain_expire")'=>array('label'=>'Expire'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'display("date_next_invoice")'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_listhostservices() {
|
||||
Block::add(array(
|
||||
'title'=>_('Hosting Services'),
|
||||
'body'=>Table::display(
|
||||
$this->filter(ORM::factory('Service')->list_bylistgroup('HOST'),$this->ao->RTM->customers($this->ao->RTM),'name()','account_id'),
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'plugin()->display("host_expire")'=>array('label'=>'Expire'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'account->accnum()'=>array('label'=>'Cust ID'),
|
||||
'account->name()'=>array('label'=>'Customer'),
|
||||
'display("date_next_invoice")'=>array('label'=>'Next Invoice'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
}
|
||||
?>
|
14
modules/service/classes/Controller/Service.php
Normal file
14
modules/service/classes/Controller/Service.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides service management
|
||||
*
|
||||
* @package Service
|
||||
* @category Controllers
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Controller_Service extends Controller_TemplateDefault {
|
||||
}
|
||||
?>
|
47
modules/service/classes/Controller/Task/Service.php
Normal file
47
modules/service/classes/Controller/Task/Service.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides OSB service task capabilities.
|
||||
*
|
||||
* @package Service
|
||||
* @category Controllers/Task
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Controller_Task_Service extends Controller_Task {
|
||||
private function _traffic_suppliers($active=FALSE) {
|
||||
$suppliers = ORM::factory('ADSL_Supplier');
|
||||
|
||||
return $active ? $suppliers->list_active() : $suppliers->find_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* List all services by their default checkout method
|
||||
*/
|
||||
public function action_gettraffic() {
|
||||
foreach ($this->_traffic_suppliers(TRUE) as $aso) {
|
||||
if (Minion_CLI::options('verbose'))
|
||||
echo $aso->name."\n";
|
||||
|
||||
$traffic = Service_Traffic_Adsl::instance($aso->name)->update_traffic();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Charges for excess traffic usage
|
||||
*/
|
||||
public function action_chargetraffic() {
|
||||
foreach ($this->_traffic_suppliers(TRUE) as $aso)
|
||||
$traffic = Service_Traffic_Adsl::instance($aso->name)->charge_excess_traffic();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send alerts to users when they exceed their traffic allowance
|
||||
*/
|
||||
public function action_alerttraffic() {
|
||||
foreach ($this->_traffic_suppliers(TRUE) as $aso)
|
||||
$traffic = Service_Traffic_Adsl::instance($aso->name)->alert_traffic();
|
||||
}
|
||||
}
|
||||
?>
|
78
modules/service/classes/Controller/User/Service.php
Normal file
78
modules/service/classes/Controller/User/Service.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides User Service functions
|
||||
*
|
||||
* @package Service
|
||||
* @category Controllers/User
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Controller_User_Service extends Controller_TemplateDefault_User {
|
||||
protected $secure_actions = array(
|
||||
'ajaxmanage'=>TRUE,
|
||||
'list'=>TRUE,
|
||||
'view'=>TRUE,
|
||||
);
|
||||
|
||||
public function action_ajaxmanage() {
|
||||
$this->auto_render = FALSE;
|
||||
|
||||
$so = ORM::factory('Service',$this->request->param('id'));
|
||||
$k = Session::instance()->get_once('manage_button');
|
||||
$amo = $so->plugin(isset($_REQUEST['t']) ? $_REQUEST['t'] : '');
|
||||
|
||||
$o = array(
|
||||
'u'=>$amo->username_value() ? $amo->username_value() : strtolower($amo->name()),
|
||||
'p'=>(! $k OR ! $this->request->is_ajax() OR ! $so->loaded() OR ! isset($_REQUEST['k']) OR $k != $_REQUEST['k']) ? Random::char() : $amo->password_value(),
|
||||
);
|
||||
|
||||
$this->response->headers('Content-Type','application/json');
|
||||
$this->response->body(json_encode($o));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a list of services
|
||||
*/
|
||||
public function action_list() {
|
||||
Block::add(array(
|
||||
'title'=>sprintf('%s: %s - %s',_('Services For'),$this->ao->accnum(),$this->ao->name(TRUE)),
|
||||
'body'=>Table::display(
|
||||
$this->ao->service->find_all(),
|
||||
25,
|
||||
array(
|
||||
'id'=>array('label'=>'ID','url'=>URL::link('user','service/view/')),
|
||||
'service_name()'=>array('label'=>'Details'),
|
||||
'recur_schedule'=>array('label'=>'Billing'),
|
||||
'price(TRUE,TRUE)'=>array('label'=>'Price','class'=>'right'),
|
||||
'status'=>array('label'=>'Active'),
|
||||
),
|
||||
array(
|
||||
'page'=>TRUE,
|
||||
'type'=>'select',
|
||||
'form'=>URL::link('user','service/view'),
|
||||
)),
|
||||
));
|
||||
}
|
||||
|
||||
public function action_view() {
|
||||
list($id,$output) = Table::page(__METHOD__);
|
||||
|
||||
$so = ORM::factory('Service',$id);
|
||||
|
||||
if (! $so->loaded() OR ! Auth::instance()->authorised($so->account)) {
|
||||
$this->template->content = 'Unauthorised or doesnt exist?';
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$output .= View::factory($this->viewpath())
|
||||
->set('so',$so);
|
||||
|
||||
Block::add(array(
|
||||
'title'=>sprintf('%s: %s',$so->id(),$so->service_name()),
|
||||
'body'=>$output,
|
||||
));
|
||||
}
|
||||
}
|
||||
?>
|
268
modules/service/classes/Model/Service.php
Normal file
268
modules/service/classes/Model/Service.php
Normal file
@@ -0,0 +1,268 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class supports Services
|
||||
*
|
||||
* @package Service
|
||||
* @category Models
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*
|
||||
* Fields:
|
||||
* + queue: PROVISION (to be provisioned)
|
||||
*/
|
||||
class Model_Service extends ORM_OSB {
|
||||
// Relationships
|
||||
protected $_has_one = array(
|
||||
'service_billing'=>array('far_key'=>'account_billing_id','foreign_key'=>'id'),
|
||||
);
|
||||
protected $_has_many = array(
|
||||
'invoice_item'=>array('far_key'=>'id'),
|
||||
'invoice'=>array('through'=>'invoice_item'),
|
||||
'service_change'=>array('far_key'=>'id'),
|
||||
);
|
||||
protected $_belongs_to = array(
|
||||
'product'=>array(),
|
||||
'account'=>array(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters used to format the display of values into friendlier values
|
||||
*/
|
||||
protected $_display_filters = array(
|
||||
'date_last_invoice'=>array(
|
||||
array('Config::date',array(':value')),
|
||||
),
|
||||
'date_next_invoice'=>array(
|
||||
array('Config::date',array(':value')),
|
||||
),
|
||||
'recur_schedule'=>array(
|
||||
array('StaticList_RecurSchedule::display',array(':value')),
|
||||
),
|
||||
'status'=>array(
|
||||
array('StaticList_YesNo::display',array(':value')),
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Return the object of the product plugin
|
||||
*/
|
||||
public function plugin($type='') {
|
||||
if (! $this->product->prod_plugin_file)
|
||||
return NULL;
|
||||
|
||||
if (! is_numeric($this->product->prod_plugin_data))
|
||||
throw new Kohana_Exception('Missing plugin_id for :product (:type)',array(':product'=>$this->product->id,':type'=>$this->product->prod_plugin_file));
|
||||
|
||||
$o = ORM::factory(Kohana::classname(sprintf('Service_Plugin_%s',$this->product->prod_plugin_file)),array('service_id'=>$this->id));
|
||||
|
||||
return $type ? $o->$type : $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the service number
|
||||
*/
|
||||
public function id() {
|
||||
return sprintf('%05s',$this->id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the service product name
|
||||
*/
|
||||
public function name() {
|
||||
return is_null($plugin=$this->plugin()) ? $this->product->name() : $plugin->name();
|
||||
}
|
||||
|
||||
public function pending_change() {
|
||||
return count($this->service_change->where_active()->where_open()->and_where('complete','!=',1)->or_where('complete','IS',null)->where_close()->find_all()->as_array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display how much is due on this service
|
||||
*/
|
||||
public function due($format=FALSE) {
|
||||
$total = 0;
|
||||
|
||||
foreach ($this->list_invoices(TRUE) as $io)
|
||||
$total += $io->due();
|
||||
|
||||
return $format ? Currency::display($total) : $total;
|
||||
}
|
||||
|
||||
/**
|
||||
* When does this service expire
|
||||
*/
|
||||
public function expire($format=FALSE) {
|
||||
// For plugins the plugin determins expiry
|
||||
$expire = (is_null($plugin=$this->plugin()) ? NULL : $plugin->expire());
|
||||
|
||||
// If $expire is NULL, we'll use the next invoice date
|
||||
$expire = is_null($expire) ? $this->date_next_invoice-86400 : $expire;
|
||||
|
||||
return $format ? Config::date($expire) : $expire;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a service expires in the next $days.
|
||||
*/
|
||||
public function expiring($days) {
|
||||
return time()+$days*86400 > $this->expire();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the service charge
|
||||
*/
|
||||
public function price($tax=FALSE,$format=FALSE) {
|
||||
$x = $this->product->keyget('price_group',$this->recur_schedule);
|
||||
|
||||
// @todo This index shouldnt be hard coded.
|
||||
$p = $this->price ? $this->price : $x[$this->price_group]['price_base'];
|
||||
|
||||
if ($tax)
|
||||
$p = Tax::add($p);
|
||||
|
||||
return $format ? Currency::display($p) : $p;
|
||||
}
|
||||
|
||||
public function service_name() {
|
||||
return is_null($plugin=$this->plugin()) ? $this->name() : $plugin->service_name();
|
||||
}
|
||||
|
||||
public function service_view() {
|
||||
return is_null($plugin=$this->plugin()) ? HTML::nbsp('') : $plugin->service_view();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the product feature summary
|
||||
*/
|
||||
public function product_feature_summary() {
|
||||
return $this->product->feature_summary();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render some details for specific calls, eg: invoice
|
||||
*/
|
||||
public function details($type) {
|
||||
switch ($type) {
|
||||
case 'invoice_detail_items':
|
||||
if (is_null($plugin = $this->plugin()))
|
||||
return array();
|
||||
else
|
||||
return $plugin->_details($type);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Kohana_Exception('Unkown detail request :type',array(':type'=>$type));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable the plugin to store data
|
||||
*/
|
||||
public function admin_update() {
|
||||
if (is_null($plugin = $this->plugin()))
|
||||
return NULL;
|
||||
else
|
||||
return $plugin->admin_update();
|
||||
}
|
||||
|
||||
public function transactions() {
|
||||
return $this->invoice_item->order_by('date_start,date_stop');
|
||||
}
|
||||
|
||||
// @todo To implement
|
||||
public function charges_new() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** LIST FUNCTIONS **/
|
||||
|
||||
/**
|
||||
* Search for services matching a term
|
||||
*/
|
||||
public function list_autocomplete($term,$index='id',array $limit=array()) {
|
||||
$result = array();
|
||||
|
||||
$this->clear();
|
||||
$this->where_active();
|
||||
$value = 'service_name()';
|
||||
|
||||
// Build our where clause
|
||||
$this->where_open()
|
||||
->where('id','like','%'.$term.'%')
|
||||
->where_close();
|
||||
|
||||
foreach ($limit as $w) {
|
||||
list($k,$s,$v) = $w;
|
||||
|
||||
$this->and_where($k,$s,$v);
|
||||
}
|
||||
|
||||
foreach ($this->find_all() as $o)
|
||||
$result[$o->$index] = array(
|
||||
'value'=>$o->$index,
|
||||
'label'=>sprintf('SVC %s: %s',$o->id,Table::resolve($o,$value)),
|
||||
);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function list_bylistgroup($cat) {
|
||||
$result = array();
|
||||
|
||||
$cats = ORM::factory('Product_Category')->list_bylistgroup($cat);
|
||||
|
||||
foreach ($this->list_active() as $so)
|
||||
if (array_intersect($so->product->avail_category,array_keys($cats)))
|
||||
array_push($result,$so);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* List services expiring
|
||||
*/
|
||||
public function list_expiring($days=14) {
|
||||
$result = array();
|
||||
|
||||
foreach ($this->list_active() as $so)
|
||||
if ($so->expiring($days))
|
||||
array_push($result,$so);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* List invoices for this service
|
||||
*/
|
||||
public function list_invoices($due=FALSE) {
|
||||
$result = array();
|
||||
|
||||
foreach ($this->invoice->find_all() as $io)
|
||||
if (! $due OR $io->due())
|
||||
array_push($result,$io);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* List services that need to be billed.
|
||||
*
|
||||
* @param $days int Additional number of days to add to the query, above the module config.
|
||||
*/
|
||||
public function list_invoicesoon($days=0) {
|
||||
return $this->_where_active()
|
||||
->where_open()->where('suspend_billing','IS',NULL)->or_where('suspend_billing','=','0')->where_close()
|
||||
->where('date_next_invoice','<',time()+(ORM::factory('Invoice')->config('GEN_DAYS')+$days)*86400)
|
||||
->find_all();
|
||||
}
|
||||
|
||||
/**
|
||||
* List services that need to be provisioned
|
||||
*/
|
||||
public function list_provision() {
|
||||
return $this->_where_active()->where('queue','=','PROVISION');
|
||||
}
|
||||
}
|
||||
?>
|
20
modules/service/classes/Model/Service/Billing.php
Normal file
20
modules/service/classes/Model/Service/Billing.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class supports Service Billing.
|
||||
*
|
||||
* @package Service
|
||||
* @category Models
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Model_Service_Billing extends ORM_OSB {
|
||||
protected $_table_name = 'account_billing';
|
||||
|
||||
// Relationships
|
||||
protected $_has_one = array(
|
||||
'checkout'=>array('far_key'=>'checkout_plugin_id','foreign_key'=>'id'),
|
||||
);
|
||||
}
|
||||
?>
|
48
modules/service/classes/Model/Service/Change.php
Normal file
48
modules/service/classes/Model/Service/Change.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class supports Service Product Changes.
|
||||
*
|
||||
* @package Service
|
||||
* @category Models
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Model_Service_Change extends ORM_OSB {
|
||||
protected $_table_name = 'service_change';
|
||||
|
||||
// Relationships
|
||||
protected $_belongs_to = array(
|
||||
'product'=>array(),
|
||||
'service'=>array(),
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters used to format the display of values into friendlier values
|
||||
*/
|
||||
protected $_display_filters = array(
|
||||
'date_ordered'=>array(
|
||||
array('Config::date',array(':value')),
|
||||
),
|
||||
'date_effective'=>array(
|
||||
array('Config::date',array(':value')),
|
||||
),
|
||||
);
|
||||
|
||||
public function list_details() {
|
||||
if ($this->_db_pending) {
|
||||
$output = array();
|
||||
|
||||
foreach ($this->find_all() as $sco) {
|
||||
array_push($output,sprintf('%s %s',$sco->product->name(),$sco->display('date_effective')));
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new Kohana_Exception('Shouldnt be here!');
|
||||
}
|
||||
|
||||
return join('|',$output);
|
||||
}
|
||||
}
|
||||
?>
|
97
modules/service/classes/Model/Service/Plugin.php
Normal file
97
modules/service/classes/Model/Service/Plugin.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class supports Service Plugins.
|
||||
*
|
||||
* @package Service
|
||||
* @category Models
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
abstract class Model_Service_Plugin extends ORM_OSB {
|
||||
// Reset any sorting that may be defined in our parent
|
||||
protected $_sorting = array();
|
||||
|
||||
/**
|
||||
* Form info for admins to update
|
||||
*/
|
||||
abstract public function admin_update();
|
||||
|
||||
/**
|
||||
* Our service name as defined in the DB
|
||||
*/
|
||||
abstract public function name();
|
||||
|
||||
/**
|
||||
* When does our service expire
|
||||
*/
|
||||
abstract public function expire();
|
||||
|
||||
/**
|
||||
* Show our service name as defined in the DB with product suffix.
|
||||
*/
|
||||
public function service_name() {
|
||||
return sprintf('%s - %s',$this->service->product->name(),$this->name());
|
||||
}
|
||||
|
||||
/**
|
||||
* View details of the service
|
||||
*/
|
||||
abstract public function service_view();
|
||||
|
||||
/**
|
||||
* The table attributes that provide username/password values
|
||||
*/
|
||||
abstract public function username_value();
|
||||
abstract public function password_value();
|
||||
|
||||
public function manage_button() {
|
||||
if (! $this->service->status)
|
||||
return FALSE;
|
||||
|
||||
static $k = '';
|
||||
|
||||
// If $k is already set, we've rendered this JS
|
||||
if ($k)
|
||||
return TRUE;
|
||||
|
||||
$k = Random::char();
|
||||
Session::instance()->set('manage_button',$k);
|
||||
|
||||
Script::add(array('type'=>'stdin','data'=>'
|
||||
$(document).ready(function() {
|
||||
var x=0;
|
||||
$("button[name=submit]").click(function() {
|
||||
var t=$(this).val().split(":");
|
||||
if (x++) { alert("Session expired, please refresh the page!"); return false; }
|
||||
$.getJSON("'.URL::link('user','service/ajaxmanage/'.$this->service_id,TRUE).'", { k: "'.$k.'",t: t[1] }, function(data) {
|
||||
$.each(data, function(key, val) { $("#"+key+"_"+t[0]+"_"+t[1]).val(val); });
|
||||
}).error(function() { alert("There was a problem with the request"); return false; }).success(
|
||||
function() { $("form[id=id_"+t[0]+"_"+t[1]+"]").submit(); });
|
||||
});
|
||||
});'
|
||||
));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specific service details for use in other modules
|
||||
* For Example: Invoice
|
||||
*
|
||||
* @todo Make the rendered items configurable
|
||||
* @todo Change this method name, now that it is public
|
||||
*/
|
||||
public function _details($type) {
|
||||
switch ($type) {
|
||||
// Nothing to add for invoices
|
||||
case 'invoice_detail_items':
|
||||
return array();
|
||||
|
||||
default:
|
||||
throw new Kohana_Exception('Unkown detail request :type',array(':type'=>$type));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
64
modules/service/views/service/admin/update.php
Normal file
64
modules/service/views/service/admin/update.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<!-- @todo NEEDS TO BE TRANSLATED -->
|
||||
<?php echo Form::open(); ?>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td style="width: 50%; vertical-align: top;">
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td style="width: 40%;">Service Active</td>
|
||||
<td style="width: 60%;" class="data"><?php echo StaticList_YesNo::form('status',$so->status); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Queue</td>
|
||||
<td class="data"><?php echo $so->display('queue'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Billing Period</td>
|
||||
<td class="data"><?php echo StaticList_RecurSchedule::form('recure_schedule',$so->product,$so->recur_schedule);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date Last Invoice</td>
|
||||
<td class="data"><?php echo $so->display('date_last_invoice'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Date Next Invoice</td>
|
||||
<td class="data">
|
||||
<?php echo Form::input('date_next_invoice',$so->date_next_invoice,array('id'=>'date_next_invoice')); ?>
|
||||
<?php echo HTML::anchor('#',
|
||||
HTML::image($mediapath->uri(array('file'=>'img/calendar.png')),array('alt'=>_('Calendar'),'style'=>'cursor: pointer;')),
|
||||
array('title'=>'Click to popup a dialog to select a date graphically','onclick'=>"dateSelector('date_next_invoice')")); ?>
|
||||
<script type="text/javascript">defaults['date_next_invoice'] = '%s';</script>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Taxable</td>
|
||||
<td class="data"><?php echo StaticList_YesNo::form('taxable',$so->taxable); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td class="data"><?php echo StaticList_RecurType::display($so->recur_type); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>User Can Change Schedule</td>
|
||||
<td class="data"><?php echo StaticList_YesNo::form('recur_schedule_change',$so->recur_schedule_change); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>User Can Cancel</td>
|
||||
<td class="data"><?php echo StaticList_YesNo::form('recur_cancel',$so->recur_cancel); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>User Can Modify</td>
|
||||
<td class="data"><?php echo StaticList_YesNo::form('recur_modify',$so->recur_modify); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Suspend Billing</td>
|
||||
<td class="data"><?php echo StaticList_YesNo::form('suspend_billing',$so->suspend_billing); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php if ($plugin_form) { echo '<br/>'.$plugin_form; } ?>
|
||||
<!-- END Service Information -->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php echo Form::submit('submit',_('Update'),array('class'=>'form_button')); ?>
|
||||
<?php echo Form::close(); ?>
|
40
modules/service/views/service/admin/view.php
Normal file
40
modules/service/views/service/admin/view.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php if ($so->pending_change()) {?>
|
||||
Pending change to: <?php echo $so->service_change->list_details(); ?>
|
||||
<?php } ?>
|
||||
<br/>
|
||||
<!-- @todo NEEDS TO BE TRANSLATED -->
|
||||
<table class="list-box-left">
|
||||
<tr class="list-head">
|
||||
<th>ID</th>
|
||||
<th>Invoice</th>
|
||||
<th>Product</th>
|
||||
<th>IT</th>
|
||||
<th>RS</th>
|
||||
<th>Start</th>
|
||||
<th>Stop</th>
|
||||
<th>Desc</th>
|
||||
<th>Quantity</th>
|
||||
<th>Charge</th>
|
||||
</tr>
|
||||
<?php $lp=NULL; foreach ($so->transactions()->find_all() as $iio) { ?>
|
||||
<?php if (! is_null($iio->product_id) AND $lp != $iio->product_id) {
|
||||
$lp = $iio->product_id; ?>
|
||||
<tr class="list-sub-head">
|
||||
<th class="id"><?php echo $iio->product_id; ?></th>
|
||||
<th colspan="9"><?php echo $iio->product->name(); ?></th>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<tr class="list-data">
|
||||
<td class="id"><?php echo $iio->id; ?></td>
|
||||
<td><?php echo HTML::anchor(URL::link('user','invoice/view/'.$iio->invoice_id),$iio->invoice_id); ?></td>
|
||||
<td><?php echo $iio->display('product_id'); ?></td>
|
||||
<td><?php echo $iio->display('item_type'); ?></td>
|
||||
<td><?php echo $iio->display('recurring_schedule'); ?></td>
|
||||
<td><?php echo $iio->display('date_start'); ?></td>
|
||||
<td><?php echo $iio->display('date_stop'); ?></td>
|
||||
<td><?php echo $iio->display('product_name'); ?></td>
|
||||
<td><?php echo $iio->display('quantity'); ?></td>
|
||||
<td class="right"><?php echo $iio->display('price_base'); ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
80
modules/service/views/service/user/view.php
Normal file
80
modules/service/views/service/user/view.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<!-- @todo NEEDS TO BE TRANSLATED -->
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<!-- Service Information -->
|
||||
<table class="box-full">
|
||||
<tr>
|
||||
<td style="width: 40%;">Account</td>
|
||||
<td style="width: 60%;" class="data"><?php printf('%s (%s)',$so->account->name(),$so->account->accnum()); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Service Active</td>
|
||||
<td class="data"><?php echo $so->display('status'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Billing Period</td>
|
||||
<td class="data"><?php echo $so->display('recur_schedule');?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Cost</td>
|
||||
<td class="data"><?php echo $so->price(TRUE,TRUE); if ($so->pending_change()) echo ' *'; ?></td>
|
||||
</tr>
|
||||
<?php if (is_null($so->price) OR ($so->price<=$so->product->price($so->price_group,$so->recur_schedule,'price_base'))) { ?>
|
||||
<tr>
|
||||
<td>Service</td>
|
||||
<td class="data"><?php echo HTML::anchor('product/view/'.$so->product_id,$so->product->name()); ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
<tr>
|
||||
<td>Date Next Invoice</td>
|
||||
<td class="data"><?php echo $so->display('date_next_invoice'); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Current Invoices Due</td>
|
||||
<td class="data"><?php echo Currency::display($so->account->invoices_due_total()); ?></td>
|
||||
</tr>
|
||||
<?php if ($so->service_billing->loaded()) { ?>
|
||||
<tr>
|
||||
<td>Direct Debit</td>
|
||||
<td class="data"><?php echo $so->service_billing->checkout->name; ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<!-- END Service Information -->
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<!-- Product Summary Info -->
|
||||
<?php echo $so->product_feature_summary(); ?>
|
||||
<!-- END Product Summary Info -->
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
<?php echo $so->service_view(); ?>
|
||||
<br/>
|
||||
<table class="box-left" width="50%">
|
||||
<tr>
|
||||
<td class="head" colspan="2">Invoices for this service</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">Number</td>
|
||||
<td>Invoice Date</td>
|
||||
<td>Due Date</td>
|
||||
<td>Total</td>
|
||||
<td>Balance</td>
|
||||
</tr>
|
||||
<?php $i=0; foreach ($so->invoice->distinct('id')->order_by('id DESC')->find_all() as $io) { ?>
|
||||
<tr class="<?php echo $i++%2 ? 'odd' : 'even'; ?>">
|
||||
<td class="icon" width="20px"><?php echo HTML::anchor(URL::link('user','invoice/download/'.$io->id),HTML::image('media/img/gnome-pdf.png',array('alt'=>_('Download'),'width'=>20))); ?></td>
|
||||
<td class="data"><?php echo HTML::anchor(URL::link('user','invoice/view/'.$io->id),$io->id()); ?></td>
|
||||
<td class="data"><?php echo $io->display('date_orig'); ?></td>
|
||||
<td class="data"><?php echo $io->display('due_date'); ?></td>
|
||||
<td class="data"><?php echo $io->total(TRUE); ?></td>
|
||||
<td class="data"><?php echo $io->due(TRUE); ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
Reference in New Issue
Block a user