Improved ADSL Billing Review
This commit is contained in:
parent
ab3735914b
commit
638d123739
158
modules/adsl/classes/Adsl/Billing/Exetelvisp.php
Normal file
158
modules/adsl/classes/Adsl/Billing/Exetelvisp.php
Normal file
@ -0,0 +1,158 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides Exetel VISP ADSL functions
|
||||
*
|
||||
* @package ADSL
|
||||
* @category Helpers
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class ADSL_Billing_Exetelvisp {
|
||||
private $data = NULL;
|
||||
private $data_exception = NULL;
|
||||
private $exception = array();
|
||||
private $total = 0;
|
||||
|
||||
public function excess($service) {
|
||||
return empty($this->data[$service]['excess']) ? 0 : $this->data[$service]['excess'];
|
||||
}
|
||||
|
||||
public function form() {
|
||||
$result = '';
|
||||
|
||||
$result .= Form::open(URL::link('reseller','adsl/billing'),array('enctype'=>'multipart/form-data','class'=>'form-horizontal'));
|
||||
$result .= View::factory('adsl/reseller/billing/exetelvisp');
|
||||
$result .= Form::close();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function charge($service) {
|
||||
return $this->cost($service)+$this->credit($service);
|
||||
}
|
||||
|
||||
public function cost($service) {
|
||||
return empty($this->data[$service]['cost']) ? 0 : $this->data[$service]['cost'];
|
||||
}
|
||||
|
||||
public function credit($service) {
|
||||
return empty($this->data[$service]['credit']) ? 0 : $this->data[$service]['credit'];
|
||||
}
|
||||
|
||||
public function exception() {
|
||||
return Arr::merge($this->data_exception,$this->exception);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is key to parsing an invoice and calculating totals, exceptions and missed items
|
||||
*/
|
||||
private function haveService($service,$cost) {
|
||||
if (isset($this->data[$service])) {
|
||||
if (isset($this->data_exception[$service]))
|
||||
unset($this->data_exception[$service]);
|
||||
|
||||
if ($cost != $this->charge($service))
|
||||
$this->exception[$service]['info'] = 'Charging difference: '.Currency::display($cost-$this->charge($service));
|
||||
|
||||
$this->total += $this->charge($service);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a CSV Invoice
|
||||
*/
|
||||
public function process(Model_ADSL_Supplier $aso,array $file) {
|
||||
$data = file_get_contents($file['tmp_name']);
|
||||
|
||||
if (! $data)
|
||||
return NULL;
|
||||
|
||||
$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 HTTP_Exception::factory(501,'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('/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';
|
||||
|
||||
} elseif (preg_match('/VOIP Monthly Charges /',$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'] = 'VOIP Service';
|
||||
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->data_exception = $this->data = $result;
|
||||
|
||||
// @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());
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function total($format=FALSE) {
|
||||
return $format ? Currency::display($this->total) : $this->total;
|
||||
}
|
||||
}
|
||||
?>
|
14
modules/adsl/classes/Controller/Adsl.php
Normal file
14
modules/adsl/classes/Controller/Adsl.php
Normal file
@ -0,0 +1,14 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides adsl management
|
||||
*
|
||||
* @package ADSL
|
||||
* @category Controllers
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Controller_ADSL extends Controller_TemplateDefault {
|
||||
}
|
||||
?>
|
89
modules/adsl/classes/Controller/Reseller/Adsl.php
Normal file
89
modules/adsl/classes/Controller/Reseller/Adsl.php
Normal file
@ -0,0 +1,89 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
/**
|
||||
* This class provides Reseller ADSL functions
|
||||
*
|
||||
* @package ADSL
|
||||
* @category Controllers/Reseller
|
||||
* @author Deon George
|
||||
* @copyright (c) 2009-2013 Open Source Billing
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Controller_Reseller_Adsl extends Controller_Adsl {
|
||||
protected $secure_actions = array(
|
||||
'billing'=>TRUE,
|
||||
'index'=>TRUE,
|
||||
);
|
||||
|
||||
/**
|
||||
* Reconcile billing for an ADSL supplier
|
||||
*/
|
||||
public function action_billing() {
|
||||
if (empty($_POST['sid']) OR ! $_FILES)
|
||||
HTTP::redirect(URL::link('reseller','adsl/index'));
|
||||
|
||||
$aso = ORM::factory('ADSL_Supplier',$_POST['sid']);
|
||||
|
||||
// Process upload
|
||||
$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 = $aso->billing()->process($aso,$file);
|
||||
// We should only have 1 file
|
||||
break;
|
||||
}
|
||||
|
||||
if (! $csv)
|
||||
throw HTTP_Exception::factory(501,'No CSV data ?');
|
||||
|
||||
Block::factory()
|
||||
->title('ADSL Service Invoicing')
|
||||
->title_icon('icon-th-list')
|
||||
->body(View::factory('adsl/reseller/billing')->set('o',$csv)->set('aso',$aso));
|
||||
|
||||
Block::factory()
|
||||
->title('ADSL Service Exception Charges')
|
||||
->title_icon('icon-th-list')
|
||||
->body(View::factory('adsl/reseller/billingexception')->set('o',$csv));
|
||||
}
|
||||
|
||||
/**
|
||||
* Select our primary export target
|
||||
*/
|
||||
public function action_index() {
|
||||
$output = '';
|
||||
|
||||
if ($_POST and isset($_POST['sid'])) {
|
||||
$aso = ORM::factory('ADSL_Supplier',$_POST['sid']);
|
||||
if (! $aso->loaded())
|
||||
HTTP::redirect('adsl/index');
|
||||
|
||||
$c = Kohana::classname('Adsl_Billing_'.$aso->name);
|
||||
$o = new $c();
|
||||
|
||||
$output .= $o->form();
|
||||
|
||||
Block::factory()
|
||||
->title('Upload ADSL Supplier Invoice')
|
||||
->title_icon('icon-share')
|
||||
->body($output);
|
||||
|
||||
} else {
|
||||
$output .= Form::open();
|
||||
$output .= Form::select('sid',ORM::factory('ADSL_Supplier')->list_select());
|
||||
$output .= Form::button('submit','Submit',array('class'=>'btn btn-primary'));
|
||||
$output .= Form::close();
|
||||
|
||||
Block::factory()
|
||||
->title('Select ADSL Supplier')
|
||||
->title_icon('icon-share')
|
||||
->body($output);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
@ -17,27 +17,41 @@ class Model_ADSL_Supplier extends ORM_OSB {
|
||||
'adsl_supplier_plan'=>array('model'=>'ADSL_Supplier_Plan','foreign_key'=>'supplier_id','far_key'=>'id'),
|
||||
);
|
||||
|
||||
/**
|
||||
* Return a list of plans that this supplier makes available
|
||||
*/
|
||||
public function plans($active=TRUE) {
|
||||
return $active ? $this->adsl_supplier_plan->where_active() : $this->adsl_supplier_plan;
|
||||
}
|
||||
protected $_form = array('id'=>'id','value'=>'name');
|
||||
|
||||
/**
|
||||
* Return a list of plans that we provide by this supplier
|
||||
* @deprecated
|
||||
*/
|
||||
public function adsl_plans($active=TRUE) {
|
||||
public function plans($active=TRUE) {
|
||||
$result = array();
|
||||
|
||||
foreach ($this->plans($active)->find_all() as $po)
|
||||
foreach ($this->find_plans($active)->find_all() as $po)
|
||||
foreach ($po->adsl_plan->find_all() as $apo)
|
||||
$result[$apo->id] = $apo;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the class that takes care of processing invoices
|
||||
*/
|
||||
public function billing() {
|
||||
$b = Kohana::classname('ADSL_Billing_'.$this->name);
|
||||
|
||||
if (! class_exists($b))
|
||||
throw HTTP_Exception::factory(501,'Billing class doesnt exist for :name',array(':name'=>$this->name));
|
||||
|
||||
return new $b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of plans that this supplier makes available
|
||||
*/
|
||||
public function find_plans($active=TRUE) {
|
||||
return $active ? $this->adsl_supplier_plan->where_active() : $this->adsl_supplier_plan;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of services for this supplier
|
||||
*
|
||||
@ -46,7 +60,7 @@ class Model_ADSL_Supplier extends ORM_OSB {
|
||||
public function services($active=TRUE) {
|
||||
$result = array();
|
||||
|
||||
foreach ($this->plans(FALSE)->find_all() as $aspo) {
|
||||
foreach ($this->find_plans(FALSE)->find_all() as $aspo) {
|
||||
foreach ($aspo->adsl_plan->find_all() as $apo) {
|
||||
foreach ($apo->products(FALSE)->find_all() as $po) {
|
||||
foreach ($po->services($active)->find_all() as $so) {
|
||||
|
@ -25,14 +25,16 @@ class Model_ADSL_Supplier_Plan extends ORM_OSB {
|
||||
return sprintf('%s/%s',$this->base_down_peak+$this->base_up_peak,$this->base_down_offpeak+$this->base_up_offpeak);
|
||||
}
|
||||
|
||||
public function tax() {
|
||||
// @todo This should be taken from the users session
|
||||
// @todo rounding should be a system default
|
||||
return round($this->base_cost*.1,2);
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return $this->product_id;
|
||||
}
|
||||
|
||||
public function tax() {
|
||||
return Tax::amount($this->base_cost);
|
||||
}
|
||||
|
||||
public function total($format=FALSE) {
|
||||
return $format ? Currency::display($this->base_cost+$this->tax()) : Currency::round($this->base_cost+$this->tax());
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
31
modules/adsl/views/adsl/reseller/billing.php
Normal file
31
modules/adsl/views/adsl/reseller/billing.php
Normal file
@ -0,0 +1,31 @@
|
||||
<table class="table table-striped table-condensed table-hover" id="list-table">
|
||||
<thead><tr>
|
||||
<th>Service</th>
|
||||
<th>Supplier Plan</th>
|
||||
<th>Contract Start</th>
|
||||
<th>Contract End</th>
|
||||
<th>Supplier Cost</th>
|
||||
<th>Invoiced</th>
|
||||
<th>Extras</th>
|
||||
</tr></thead>
|
||||
|
||||
<tbody>
|
||||
<?php foreach ($aso->services(TRUE) as $so) : ?>
|
||||
<?php $p = $so->plugin(); $po = $p->product(); $service_number = $p->service_number; ?>
|
||||
|
||||
<tr class="<?php echo $o->charge($service_number) == $po->adsl_supplier_plan->total() ? '' : 'error'; ?>">
|
||||
|
||||
<td><?php echo $service_number; ?></td>
|
||||
<td><?php echo $po->adsl_supplier_plan->name().($p->provided_adsl_plan_id ? '*' : ''); ?></td>
|
||||
<td><?php echo $p->contract_date_start(TRUE); ?></td>
|
||||
<td><?php echo $p->contract_date_end(TRUE); ?></td>
|
||||
<td><?php echo Currency::display($po->adsl_supplier_plan->total()); ?></td>
|
||||
<td><?php echo Currency::display($o->charge($service_number)); ?></td>
|
||||
<td><?php echo Currency::display($o->excess($service_number)); ?></td>
|
||||
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
|
||||
<tr class="info"><td colspan="5"> </td><td><?php echo $o->total(TRUE); ?></td><td> </td></tr>
|
||||
</tbody>
|
||||
</table>
|
12
modules/adsl/views/adsl/reseller/billing/exetelvisp.php
Normal file
12
modules/adsl/views/adsl/reseller/billing/exetelvisp.php
Normal file
@ -0,0 +1,12 @@
|
||||
<div class="row">
|
||||
<div class="span9 offset1">
|
||||
<fieldset>
|
||||
<legend>Exetel VISP Billing</legend>
|
||||
|
||||
<?php echo Form::hidden('sid',$_POST['sid']); ?>
|
||||
<?php echo Form::file('csv',array('label'=>'Invoice File','required')); ?>
|
||||
</fieldset>
|
||||
|
||||
<?php echo Form::button('submit','Submit',array('class'=>'btn btn-primary')); ?>
|
||||
</div> <!-- /span -->
|
||||
</div> <!-- /row -->
|
21
modules/adsl/views/adsl/reseller/billingexception.php
Normal file
21
modules/adsl/views/adsl/reseller/billingexception.php
Normal file
@ -0,0 +1,21 @@
|
||||
<table class="table table-striped table-condensed table-hover" id="list-table">
|
||||
<thead><tr>
|
||||
<th>Service</th>
|
||||
<th>Cost</th>
|
||||
<th>Extras</th>
|
||||
<th>Line</th>
|
||||
</tr></thead>
|
||||
|
||||
<tbody>
|
||||
<?php foreach ($o->exception() as $service => $line) : ?>
|
||||
<tr class="warn">
|
||||
|
||||
<td><?php echo $service ? $service : 'unknown'; ?></td>
|
||||
<td><?php echo isset($line['cost']) ? $line['cost'] : 'unknown'; ?></td>
|
||||
<td><?php echo isset($line['excess']) ? $line['excess'] : 0; ?></td>
|
||||
<td><?php echo isset($line['info']) ? $line['info'] : ''; ?></td>
|
||||
|
||||
</tr>
|
||||
<?php endforeach ?>
|
||||
</tbody>
|
||||
</table>
|
@ -1,11 +0,0 @@
|
||||
<tr class="<?php echo $i ? 'odd' : 'even'; ?>">
|
||||
<td><?php echo $service->plugin()->display('service_number'); ?></td>
|
||||
<td><?php echo $plan->adsl_supplier_plan->name().($planoverride ? '*' : ''); ?></td>
|
||||
<td><?php echo $service->plugin()->contract_date_start(TRUE); ?></td>
|
||||
<td><?php echo $service->plugin()->contract_date_end(TRUE); ?></td>
|
||||
<td><?php echo Currency::display($plan->adsl_supplier_plan->base_cost); ?></td>
|
||||
<td><?php echo Currency::display($plan->adsl_supplier_plan->base_cost+$plan->adsl_supplier_plan->tax()); ?></td>
|
||||
<td><input type="checkbox" <?php echo $checked; ?> onchange="paid(this);"/></td>
|
||||
<td><input type="text" name="payment[<?php echo $service->plugin()->service_number; ?>]" value="<?php echo $amount; ?>" id="p<?php echo $service->plugin()->id; ?>" size="8"/></td>
|
||||
<td><?php echo $excess ? sprintf('(%s)',$excess) : ' '; ?></td>
|
||||
</tr>
|
@ -1,4 +0,0 @@
|
||||
<tr class="head">
|
||||
<td colspan="7"> </td>
|
||||
<td><?php echo $total; ?></td>
|
||||
</tr>
|
@ -1,7 +0,0 @@
|
||||
<script type="text/javascript" >
|
||||
<!--
|
||||
function paid(form) {
|
||||
alert(form);
|
||||
}
|
||||
//-->
|
||||
</script>
|
@ -1,10 +0,0 @@
|
||||
<tr class="<?php echo $i ? 'odd' : 'even'; ?>">
|
||||
<td><?php echo $service->plugin()->display('service_number'); ?></td>
|
||||
<td><?php echo $plan->adsl_supplier_plan->name().($planoverride ? '*' : ''); ?></td>
|
||||
<td><?php echo $service->plugin()->contract_date_start(); ?></td>
|
||||
<td><?php echo $service->plugin()->contract_date_end(); ?></td>
|
||||
<td><?php echo Currency::display($service->product->plugin()->adsl_supplier_plan->base_cost); ?></td>
|
||||
<td><?php echo Currency::display($service->product->plugin()->adsl_supplier_plan->base_cost+$service->product->plugin()->adsl_supplier_plan->tax()); ?></td>
|
||||
<td><?php echo $amount; ?></td>
|
||||
<td><?php echo $service->product->plugin()->adsl_supplier_plan->base_cost+$service->product->plugin()->adsl_supplier_plan->tax()-$amount; ?></td>
|
||||
</tr>
|
@ -1,6 +0,0 @@
|
||||
<tr class="<?php echo $i ? 'odd' : 'even'; ?>">
|
||||
<td><?php echo $service; ?></td>
|
||||
<td><?php echo empty($item['info']) ? ' ' : $item['info']; ?></td>
|
||||
<td><?php echo empty($item['cost']) ? ' ' : $item['cost']; ?></td>
|
||||
<td><?php echo empty($item['credit']) ? ' ' : $item['credit']; ?></td>
|
||||
</tr>
|
@ -13,7 +13,6 @@ class Controller_Admin_Service extends Controller_Service {
|
||||
protected $secure_actions = array(
|
||||
'ajaxjson_traffic'=>TRUE,
|
||||
'adslstat'=>TRUE,
|
||||
'listadslbilling'=>TRUE,
|
||||
'listexpiring'=>TRUE,
|
||||
'listdomainservicesbysupplier'=>TRUE,
|
||||
'listdomainservicesbydnshost'=>TRUE,
|
||||
@ -221,194 +220,6 @@ class Controller_Admin_Service extends Controller_Service {
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
@ -10,6 +10,17 @@
|
||||
* @license http://dev.osbill.net/license.html
|
||||
*/
|
||||
class Tax {
|
||||
public static function add($value) {
|
||||
return Currency::round($value+static::amount($value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the total of tax for an amount
|
||||
*/
|
||||
public static function amount($value) {
|
||||
return Currency::round(static::total(Company::instance()->country()->id,NULL,$value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of taxes
|
||||
*
|
||||
@ -48,11 +59,5 @@ class Tax {
|
||||
|
||||
return $total;
|
||||
}
|
||||
|
||||
public static function add($value) {
|
||||
// @todo Tax details should come from session
|
||||
// @todo Rounding should be a global config
|
||||
return round($value+static::total(61,NULL,$value),2);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
Reference in New Issue
Block a user