<?php defined('SYSPATH') or die('No direct access allowed.');

/**
 * This class provides OSB exporting capabilities for Quickbooks.
 *
 * @package    OSB
 * @subpackage Export/Quicken
 * @category   Controllers/Admin
 * @author     Deon George
 * @copyright  (c) 2010 Open Source Billing
 * @license    http://dev.osbill.net/license.html
 */
class Export_Quicken extends Export {
	public function export() {
		if (! empty($_POST['id']) AND count($_POST['id'])) {
			$qo = new Quicken;

			foreach ($_POST['id'] as $pid) {
				$po = ORM::factory('Payment',$pid);

				if ($po->loaded()) {
					$invoice_ids = array();

					foreach ($po->payment_item->find_all() as $pio) {
						// If our invoice ID is not blank, then the payment was applied to an invoice
						if ($pio->invoice->id) {
							// Record our invoice IDs for the summary
							array_push($invoice_ids,$pio->invoice->id);

							$qio = new Quicken_Invoice;
							$qio->TRNSID = sprintf('%06s',$pio->invoice->id);
							$qio->DATE = date('m/d/Y',$pio->invoice->date_orig);
							$qio->MEMO = 'Import from OSB';
							$qio->CLEAR = 'N';
							$qio->TOPRINT = 'N';
							$qio->PAID = 'N';
							$qio->ADDR1 = $po->account->address1;
							$qio->ADDR2 = $po->account->address2;
							$qio->ADDR3 = sprintf('%s, %s %s',$po->account->city,$po->account->state,$po->account->zip);
							// @todo - should be configurable
							$qio->TERMS = '7 Days';
							// @todo - should be configurable
							$qio->INVTITLE = Company::name().' Invoice';
							// @todo - should be configurable
							$qio->INVMEMO = 'Thank you for using '.Company::name();
							$qio->DOCNUM = sprintf('%06s',$pio->invoice->id);
							$qio->DUEDATE = date('m/d/Y',$pio->invoice->due_date);
							$qio->AMOUNT = sprintf('%3.2f',$pio->invoice->total());

							if ($po->account->company)
								$qio->NAME = $po->account->company;
							else
								$qio->NAME = sprintf('%s %s',$po->account->last_name,$po->account->first_name);

							// Other Quicken fields not used.
							#$qio->CLASS = '';
							#$qio->SHIPVIA = '';
							#$qio->SHIPDATE = '';
							#$qio->OTHER1 = '';
							#$qio->REP = '';
							#$qio->FOB = '';
							#$qio->PONUM = '';
							#$qio->SADDR1 = '';
							#$qio->SADDR2 = '';
							#$qio->SADDR3 = '';
							#$qio->SADDR4 = '';
							#$qio->SADDR5 = '';

							// Add the items to the invoice
							foreach ($pio->invoice->invoice_item->find_all() as $iio) {
								$qto = new Quicken_InvoiceItem;

								if ($iio->period())
									$daterange = $iio->period();

								// @todo This should go.
								elseif ($iio->product_attr && preg_match('/^a/',$iio->product_attr)) {
									echo 'Uncaptured';die();

								// @todo This should go.
								} elseif ($iio->product_attr && preg_match('/^s/',$iio->product_attr))
									$daterange = preg_replace("/\r?\n/",' ',unserialize($iio->product_attr));

								else
									$daterange = '';

								if ($iio->product_id) {
									$mo = ORM::factory('Module',array('name'=>'product'));
									$eo = ORM::factory('Export')
										->where('plugin_name','=',strtolower($this->plugin))
										->and_where('module_id','=',$mo->id)
										->and_where('item_id','=',$iio->product_id)
										->find();

									if ($eo->loaded()) {
										$qto->ACCNT = $eo->map_data['account'];
										$qto->INVITEM = $eo->map_data['item'];

									} else {
										throw new Kohana_Exception('Missing product map data for :product (:id)',
											array(':product'=>$iio->product->name(),':id'=>$iio->product_id));

										$qto->ACCNT = 'Other Income';
										$qto->INVITEM = 'Product:Unknown';
									}

									$qto->MEMO = sprintf('%s (%s)',
										$iio->product->product_translate->find()->name,$daterange);

								} else {
									$qto->ACCNT = 'Other Income';
									$qto->INVITEM = 'Unknown';
									$qto->MEMO = sprintf('%s (%s)',
										$iio->product->product_translate->find()->name,$daterange);
								}

								$qto->CLEAR = 'N';
								$qto->QNTY = -1;

								if ($pio->invoice->tax()) {
									$qto->TAXABLE = 'Y';
									# @todo, get this from OSB
									$qto->TAXCODE = 'GST';
									$qto->TAXRATE = sprintf('%3.2f%%','0.10');
									$qto->TAXAMOUNT = sprintf('%3.2f',$iio->tax()*-1);
								} else {
									$qto->TAXAMOUNT = 0;
								}

								// @todo This rounding should be a system config.
								$qto->PRICE = sprintf('%3.2f',round($iio->subtotal()-$iio->discount(),2));
								$qto->AMOUNT = sprintf('%3.2f',round($iio->subtotal()-$iio->discount(),2)*-1);

								$qio->addInvoiceItem($qto);
							}

							// Add credits as a other item
							$qto = new Quicken_InvoiceItem;
							$qto->ACCNT = 'Other Income';
							$qto->INVITEM = 'Product:Unknown';
							$qto->CLEAR = 'N';
							$qto->QNTY = 1;
							$qto->MEMO = 'Credit Item';

							if ($pio->invoice->tax()) {
								$qto->TAXABLE = 'Y';
								# @todo, get this from OSB
								$qto->TAXCODE = 'GST';
								$qto->TAXRATE = sprintf('%3.2f%%','0.10');
								$tax = round($pio->invoice->credit_amt/11,2);
								$qto->TAXAMOUNT = sprintf('%3.2f',$tax);
							} else {
								$qto->TAXAMOUNT = 0;
							}

							$qto->PRICE = sprintf('%3.2f',round(($pio->invoice->credit_amt-$tax)*-1,2));
							$qto->AMOUNT = sprintf('%3.2f',round(($pio->invoice->credit_amt-$tax),2));
							$qio->addInvoiceItem($qto);

							$qo->addInvoice($qio);
						}
					}

					$qpo = new Quicken_Payment;
					$qpo->AMOUNT = sprintf('%3.2f',$po->total_amt);
					$qpo->TRNSID = sprintf('P%06s',$po->id);
					$qpo->DATE = date('m/d/Y',$po->date_payment);

					// @todo this should be from a function - when no invoice is paid we cant use $qio
					if ($po->account->company)
						$qpo->NAME = $po->account->company;
					else
						$qpo->NAME = sprintf('%s %s',$po->account->last_name,$po->account->first_name);

					$qpo->CLEAR = 'N';
					$qpo->MEMO = sprintf('Payment for invoice(s) %s (%s)',implode(':',$invoice_ids),$po->checkout->name);

					// @todo Accounts/Payment should be configurable
					switch ($po->checkout->checkout_plugin) {
						// @todo this is direct debit
						case 'MANUAL':
							$qpo->PAYMETH = 'DirectDebit';
							$qpo->ACCNT = 'Ezypay';
							break;

						case 'REMIT_CHECK':
							$qpo->PAYMETH = 'Cheque';
							$qpo->ACCNT = 'Undeposited Funds';
							break;

						case 'REMIT_BANK_WIRE':
							$qpo->PAYMETH = 'DirectCredit';
							$qpo->ACCNT = 'Bendigo Bank';
							break;

						case 'PAYPAL':
							$qpo->PAYMETH = 'Paypal';
							$qpo->ACCNT = 'Paypal';
							break;

						default:
							$qpo->PAYMETH = 'TBA';
							$qpo->ACCNT = 'Undeposited Funds';
					}

					if (isset($qio))
						$qio->addPayment($qpo);
				}
			}
		}

		if (! empty($qo))
			$this->response->body($qo->export());

		$this->response->send_file(TRUE,'quicken-import.iif',array('mime_type'=>'text/plain'));
	}
}
?>