<?php
/**
 * AgileBill - Open Billing Software
 *
 * This body of work is free software; you can redistribute it and/or
 * modify it under the terms of the Open AgileBill License
 * License as published at http://www.agileco.com/agilebill/license1-4.txt
 *
 * Originally authored by Tony Landis, AgileBill LLC
 *
 * Recent modifications by Deon George
 *
 * @author Deon George <deonATleenooksDOTnet>
 * @copyright 2009 Deon George
 * @link http://osb.leenooks.net
 *
 * @link http://www.agileco.com/
 * @copyright 2004-2008 Agileco, LLC.
 * @license http://www.agileco.com/agilebill/license1-4.txt
 * @author Tony Landis <tony@agileco.com>
 * @package AgileBill
 * @subpackage Module:Invoice
 */

/**
 * The main AgileBill Invoice Item Class
 *
 * @package AgileBill
 * @subpackage Module:Invoice
 */
class invoice_item extends OSB_module {
	# Hold the Tax information for this object
	private $tax_arr;
	# Hold the Discount information for this object
	private $discount_arr;
	# The prorate rate for this item
	private $prorata = 1;
	# Set the base price - used to work out the recurring amount
	private $base = 0;

	private function setBase() {
		if ($this->base && $this->prorata)
			$this->setRecordAttr('price_base',$this->base*$this->prorata);
	}

	public function setProRata($amt) {
		$this->prorata = $amt;

		# Automatically reduce the base rate
		$this->setBase();
	}

	public function setBaseRate($amt) {
		$this->base = $amt;

		# Automatically reduce the base rate
		$this->setBase();
	}

	/**
	 * Calculate the tax for an item record
	 *
 	 * @uses account
 	 * @uses tax
	 */
	private function pCalcTax() {
		$total = 0;

		foreach ($this->getTaxArr() as $tax)
			$total += $tax['rate'];

		return $total;
	}

	public function getTaxArr() {
		if (! is_array($this->tax_arr)) {
			# If we dont have an Account ID we cant calculate tax
			if (is_null($this->getRecordAttr('account_id')))
				return false;

			include_once(PATH_MODULES.'tax/tax.inc.php');
			$to = new tax;

			include_once(PATH_MODULES.'account/account.inc.php');
			$ao = new account($this->getRecordAttr('account_id'));

			$total = ($this->getRecordAttr('price_base')+$this->getRecordAttr('price_setup'))*$this->getRecordAttr('quantity')-$this->getRecordAttr('discount_amt');
			$this->tax_arr = $to->calculate($total,$ao->getRecordAttr('country_id'),$ao->getRecordAttr('state'));

			$this->setRecordAttr('tax_amt',$this->pCalcTax());
		}

		return $this->tax_arr;
	}

	public function sGetTaxAmt() {
		return $this->pCalcTax();
	}

	/**
	 * Calculate Discounts applicable for item
	 *
	 * @uses discount
	 */
	private function pCalcDiscount($iamt) {
		$total = 0;

		foreach ($this->getDiscountArr($iamt) as $discount)
			$total += $discount['amount'];

		return $total;
	}

	public function getDiscountArr($iamt) {
		if (! is_array($this->discount_arr)) {
			include_once(PATH_MODULES.'discount/discount.inc.php');
			$do = new discount;

			$total = ($this->getRecordAttr('price_base')+$this->getRecordAttr('price_setup'))*$this->getRecordAttr('quantity');
			$this->discount_arr = $do->calc_all_discounts(1,$this->getRecordAttr('product_id'),$total,$this->getRecordAttr('account_id'),$iamt);

			$this->setRecordAttr('discount_amt',$this->pCalcDiscount($iamt));
		}

		return $this->discount_arr;
	}

	/**
	 * Get the Discount Total for this Item
	 */
	public function sGetDiscountAmt($total=0) {
		return $this->pCalcDiscount($total);
	}

	public function sGetSubTotalAmt() {
		return ($this->getRecordAttr('price_base')+$this->getRecordAttr('price_setup'))*$this->getRecordAttr('quantity');
	}

	public function sGetTotalAmt($recalc=false) {
		static $total;

		if ($total && ! $recalc)
			return $total;
		else
			$total = 0;

		# Work out our discount if we havent already
		if (is_null($this->getRecordAttr('discount_amt')))
			$this->setRecordAttr('discount_amt',$this->pCalcDiscount($this->sGetSubTotalAmt()));

		# Work out our tax if we havent already
		if (is_null($this->getRecordAttr('tax_amt')))
			$this->setRecordAttr('tax_amt',$this->sGetTaxAmt());

		$total = ($this->getRecordAttr('price_base')+$this->getRecordAttr('price_setup'))*$this->getRecordAttr('quantity')
			-$this->getRecordAttr('discount_amt')
			+$this->getRecordAttr('tax_amt');

		$this->setRecordAttr('total_amt',$total);

		return $total;
	}

	/**
	 * Work out the recurring amount
	 *
	 * This amount excludes taxes and discounts
	 *
	 * @uses product
	 */
	public function sGetRecurAmt() {
		if ($this->getRecordAttr('price_type') != 1)
			return 0;

		return $this->base*$this->getRecordAttr('quantity');
	}

	/**
	 * Save records
	 *
	 * Taxes and discounts should already be set and configured.
	 *
	 * @uses discount
	 * @uses tax
	 */
	public function sql_SaveRecord($noconvert=false,$calc=true) {
		# If our discounts and taxes were calculated already we can skip them
		if ($calc) {
			$this->setRecordAttr('discount_amt',$this->pCalcDiscount($this->sGetSubTotalAmt()));
			$this->setRecordAttr('tax_amt',$this->sGetTaxAmt());
			$this->setRecordAttr('total_amt',$this->sGetTotalAmt(true));
		}

		if ($id = parent::sql_SaveRecord($noconvert)) {
			# Save the Discount Object
			include_once(PATH_MODULES.'discount/discount.inc.php');
			$do = new discount;

			include_once(PATH_MODULES.'tax/tax.inc.php');
			$to = new tax;

			# Save the Tax & Discount Details
			if ($this->discount_arr)
				$do->invoice_item($this->getRecordAttr('invoice_id'),$id,$this->getRecordAttr('account_id'),$this->discount_arr);

			if ($this->tax_arr)
				$to->invoice_item($this->getRecordAttr('invoice_id'),$id,$this->getRecordAttr('account_id'),$this->tax_arr);
		}

		return $id;
	}

	/**
	 * Return the items on an invoice
	 */
	public function sInvoiceItems($id) {
		return $this->sql_GetRecords(array('where'=>array('invoice_id'=>$id)));
	}
}
?>