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->excess += $this->excess($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(); $c = 0; 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('/([0-9]+)\s+-\s+Monthly Charge On Plan /',$record[3])) { list($service,$description) = explode(':',(preg_replace('/([0-9]+)\s+-\s+(.*)$/',"$1:$2",$record[3]))); $result[$service]['cost'] = str_replace('$','',$record[6]); $result[$service]['info'] = 'Other Service'; } 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-".$c++]['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()->admin_plan()->adsl_supplier_plan->display('base_cost')); return $this; } public function totalcharge($format=FALSE) { return $format ? Currency::display($this->total) : $this->total; } public function totalexcess($format=FALSE) { return $format ? Currency::display($this->excess) : $this->excess; } } ?>