<?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 $excess = 0;
	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->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()->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;
	}
}
?>
