Spade

Mini Shell

Directory:~$ /home/lmsyaran/public_html/administrator/components/com_invoices/models/
Upload File

[Home] [System Details] [Kill Me]
Current File:~$ /home/lmsyaran/public_html/administrator/components/com_invoices/models/invoice.php

<?php

/*------------------------------------------------------------------------
# com_invoices - Invoice Manager for Joomla
# ------------------------------------------------------------------------
# author				Germinal Camps
# copyright 			Copyright (C) 2012 - 2016 JoomlaThat.com. All Rights
Reserved.
# @license				http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
# Websites: 			http://www.joomlathat.com
# Technical Support:	Forum - http://www.joomlathat.com/support
-------------------------------------------------------------------------*/

//no direct access
defined('_JEXEC') or die('Restricted access.');

jimport('joomla.application.component.model');

class InvoicesModelInvoice extends JModelLegacy
{

	var $input;

	function __construct()
	{
		parent::__construct();

		$mainframe = JFactory::getApplication();
		$this->input = $mainframe->input;

		$array = $this->input->get('cid',  0, '',
'array');
		$this->setId((int)$array[0]);

		$this->params = JComponentHelper::getParams( 'com_invoices'
);

	}

	function setId($id)
	{
		// Set id and wipe data
		$this->_id		= $id;
		$this->_data	= null;

	}

	function &getData()
	{
		// Load the data

		$query = ' SELECT i.*, co.name as contact_name, u.username,
co.user_id AS joomla_user_id FROM #__invoices_invoices as i '.
							' LEFT JOIN #__invoices_contacts AS co ON co.id = i.user_id
'.
							' LEFT JOIN #__users AS u ON u.id = co.user_id '.
							' WHERE i.id = '.$this->_id;
		$this->_db->setQuery( $query );
		$this->_data = $this->_db->loadObject();

		if(!empty($this->_data)) $this->_data->vincular_cliente_checkbox
= 1;

		if (!$this->_data) {
			$this->_data = new stdClass();
			$this->_data->id = 0;

			$this->_data->from_name =
$this->params->get('from_name');
			$this->_data->from_address =
$this->params->get('from_address');
			$this->_data->from_num =
$this->params->get('from_num');
			$this->_data->from_url =
$this->params->get('from_url');
			$this->_data->from_phone =
$this->params->get('from_phone');
			$this->_data->from_email =
$this->params->get('from_email');
			$this->_data->currency_before =
$this->params->get('currency_before');
			$this->_data->currency_after =
$this->params->get('currency_after');

			$this->_data->taxes = "";
			$this->_data->to_name = "";
			$this->_data->to_company = "";
			$this->_data->to_address = "";
			$this->_data->to_zipcode = "";
			$this->_data->to_city = "";
			$this->_data->to_country = "";
			$this->_data->to_state = "";
			$this->_data->to_email = "";
			$this->_data->to_phone = "";
			$this->_data->to_vatid = "";
			$this->_data->contact_name = "";
			$this->_data->user_id = 0;
			$this->_data->template_id =
$this->params->get('invoice_template', 0);

			$this->_data->username = "";
			$this->_data->joomla_user_id = "";

			$this->_data->start_publish = "";
			$this->_data->end_publish = "";
			$this->_data->notes = "";
			$this->_data->admin_notes = "";

			$this->_data->discount = "";

			$this->_data->publish = 1;
			$this->_data->status = "";

			$this->_data->is_recurrent = 0;
			$this->_data->rec_nextdate = "";
			$this->_data->rec_year = 0;
			$this->_data->rec_month = 0;
			$this->_data->rec_day = 0;
			$this->_data->rec_email = 0;

			$this->_data->auth_code = "";

			$this->_data->vincular_cliente_checkbox = 2;

			$query = ' SELECT i.real_invoice_num FROM #__invoices_invoices as i
WHERE type = 1 '.
					 		 ' ORDER BY i.id DESC ';
			$this->_db->setQuery( $query );
			$this->_data->real_invoice_num = $this->_db->loadResult() +
1;
			$this->_data->invoice_num =
InvoicesHelper::getInvoiceNum($this->_data->real_invoice_num) ;

			$this->_data->invoice_date = date("Y-m-d");

			$this->_data->invoice_duedate = "";

			$this->_data->language =
$this->params->get('default_language');

      $this->_data->rec_email = false;

			$this->_data->currency_id =
$this->params->get('currency_id', 1);

			$from_id = $this->input->getInt('from') ;
			if($from_id){
				$query = ' SELECT co.*, u.username FROM #__invoices_contacts as co
'.
								 ' LEFT JOIN #__users AS u ON u.id = co.user_id '.
								 ' WHERE co.id = '.$from_id;
				$this->_db->setQuery( $query );
				$from = $this->_db->loadObject();

				$this->_data->to_name = $from->name;
				$this->_data->to_address = $from->address;
				$this->_data->to_company = $from->company;
				$this->_data->to_email = $from->email;

				$this->_data->to_country = $from->country;
				$this->_data->to_state = $from->state;
				$this->_data->to_city = $from->city;
				$this->_data->to_zipcode = $from->zipcode;
				$this->_data->to_vatid = $from->vatid;
				$this->_data->to_phone = $from->phone;

				$this->_data->user_id = $from_id;
				$this->_data->contact_name = $from->name;
				$this->_data->vincular_cliente_checkbox = 1;

				$this->_data->username = $from->username;
				$this->_data->joomla_user_id = $from->user_id;
			}

			$query = 	' SELECT id '.
								' FROM #__invoices_taxes '.
								' WHERE checked = 1 '.
								' ORDER BY ordering, name '
								;
			$this->_db->setQuery( $query );
			$this->_data->taxes = $this->_db->loadColumn();

			$this->_data->taxes = implode(",",
$this->_data->taxes);

			$this->_data->external_type = "";
			$this->_data->external_id = "";
			$this->_data->external_ref = "";

		}
		else{
			$this->_data->vincular_cliente_checkbox = 0;
		}

		$this->_data->taxes = explode(",",
$this->_data->taxes);

		$this->_data->invoice_date = str_replace(" 00:00:00",
"", $this->_data->invoice_date);
		$this->_data->invoice_duedate = str_replace(" 00:00:00",
"", $this->_data->invoice_duedate);

		$this->_data->start_publish = str_replace(" 00:00:00",
"", $this->_data->start_publish);
		$this->_data->end_publish = str_replace(" 00:00:00",
"", $this->_data->end_publish);
		$this->_data->rec_nextdate = str_replace(" 00:00:00",
"", $this->_data->rec_nextdate);

		if($this->_data->invoice_date == "0000-00-00")
$this->_data->invoice_date = "";
		if($this->_data->invoice_duedate == "0000-00-00")
$this->_data->invoice_duedate = "";
		if($this->_data->start_publish == "0000-00-00")
$this->_data->start_publish = "";
		if($this->_data->end_publish == "0000-00-00")
$this->_data->end_publish = "";
		if($this->_data->rec_nextdate == "0000-00-00")
$this->_data->rec_nextdate = "";

		$this->_data->edit_link 	=
JRoute::_('index.php?option=com_invoices&controller=invoice&tmpl=component&task=edit&cid[]='
. $this->_data->id . '&layout=form&modal=1' ,
false);

		$this->_data->pdf_link 	=
InvoicesHelper::download_pdf_link($this->_data->id);

		$this->_data->public_link 		=
InvoicesHelper::getInvoicePublicLink($this->_data->id) ;

		$this->_data->items = $this->getItems();

		$this->_data->payments = $this->getPayments();

		$this->_data->taxes = $this->getTaxes();

		return $this->_data;
	}

	function getItems(){
		$this->items = array();
		if ($this->_id){
			$query = 	' SELECT it.*, tax.name AS tax_name FROM
#__invoices_items AS it '.
						' LEFT JOIN #__invoices_taxes AS tax ON tax.id = it.tax_id
'.
						' WHERE it.invoice_id = ' . $this->_id .
						' ORDER BY it.ordering ';
			$this->_db->setQuery( $query );
			$this->items = $this->_db->loadObjectList();

		}

		return $this->items;

	}

	function getPayments(){
		$this->payments = array();
		if (empty( $this->payments ) && $this->_id){
			$query = 	' SELECT * FROM #__invoices_payments '.
						' WHERE invoice_id = ' . $this->_id .
						' ORDER BY ordering ';
			$this->_db->setQuery( $query );
			$this->payments = $this->_db->loadObjectList();

		}

		return $this->payments;

	}

	function getPaymentsInvoice()
	{

		$query = 	' SELECT pa.* '.
					' FROM #__invoices_payments as pa '.
					' WHERE pa.invoice_id = ' . $this->_id .
					' AND pa.payment_status = 1 '.
					' ORDER BY ordering ';
					;
		$this->_db->setQuery( $query );
		$this->payments_invoice = $this->_db->loadObjectList();

		return $this->payments_invoice;
	}

	function getPaymentsInvoice2()
	{

		$query = 	' SELECT pa.* '.
					' FROM #__invoices_payments as pa '.
					' WHERE pa.invoice_id = ' . $this->_id .
					' AND pa.payment_status = 0 '.
					' ORDER BY ordering ';
					;
		$this->_db->setQuery( $query );
		$this->payments_invoice2 = $this->_db->loadObjectList();

		return $this->payments_invoice2;
	}

	function getTaxes(){

		if($this->_id){ //is not new
			$query = 	' SELECT tax.*, tai.value AS tax_value, tai.active FROM
#__invoices_taxes AS tax '
						.' LEFT JOIN #__invoices_tax_invoice AS tai ON (tai.tax_id =
tax.id AND tai.reference_id = ' . $this->_id . ' AND tai.type
= 1) '
						.' ORDER BY ordering, name ';
		}
		else{ //is new
			$query = 	' SELECT tax.*, tax.value AS tax_value, tax.checked AS
active FROM #__invoices_taxes AS tax '
						.' ORDER BY ordering, name ';
		}
		$this->_db->setQuery( $query );
		$this->taxes = $this->_db->loadObjectList('id');

		return $this->taxes;

	}

	function getTaxesInvoice(){

		$query = ' SELECT tax.*, tai.value AS value '
				.' FROM #__invoices_taxes AS tax '
				.' LEFT JOIN #__invoices_tax_invoice AS tai ON (tai.tax_id =
tax.id AND tai.reference_id = ' . $this->_data->id . ' AND
tai.type = 1) '
				.' WHERE tai.active = 1 '
				.' ORDER BY ordering, name ' ;
		$this->_db->setQuery( $query );
		$this->taxes = $this->_db->loadObjectList();

		return $this->taxes;
	}

	function getStatus(){

		if (empty( $this->status )){
			$this->status = InvoicesHelper::getStatus();

		}

		return $this->status;

	}

	function getTemplatesData()
		{
			// Lets load the data if it doesn't already exist
			if (empty( $this->_templates_data )){
				$query = ' SELECT * FROM #__invoices_templates '.
						 ' ORDER BY name ';
				$this->_db->setQuery( $query );
				$this->_templates_data = $this->_db->loadObjectList();
			}

		return $this->_templates_data;

	}

	function &getTemplate()
	{

		$query = 	' SELECT te.* '.
					' FROM #__invoices_templates as te '.
					' WHERE te.id = ' . $this->_data->template_id
					;
		$this->_db->setQuery( $query );
		$this->template = $this->_db->loadObject();

		return $this->template;
	}

	function duplicate($invoice_id, $type = false){

		$params = JComponentHelper::getParams( 'com_invoices' );

		//get the current data
		$query = ' SELECT i.*, co.name as contact_name FROM
#__invoices_invoices as i '.
				 ' LEFT JOIN #__invoices_contacts AS co ON co.id = i.user_id
'.
				 ' WHERE i.id = '.$invoice_id;
		$this->_db->setQuery( $query );
		$invoice = $this->_db->loadAssoc();

		if(!$type){
			$type = $invoice['type'] ;
		}
		else{ //we are forcing type, this means probably creating invoice from
quote

			$invoice['type'] = $type ;
			if($type == 1) {
				$invoice['template_id'] =
$params->get('invoice_template') ;
				$invoice['status'] = "";
			}

		}

		$query = 	' SELECT * FROM #__invoices_items '.
					' WHERE invoice_id = ' . $invoice_id .
					' ORDER BY ordering ';
		$this->_db->setQuery( $query );
		$items = $this->_db->loadAssocList();

		$query = 	' SELECT * FROM #__invoices_payments '.
					' WHERE invoice_id = ' . $invoice_id .
					' ORDER BY ordering ';
		$this->_db->setQuery( $query );
		$payments = $this->_db->loadAssocList();

		//prepare the invoice

		$query = ' SELECT i.real_invoice_num FROM #__invoices_invoices as i
WHERE type =  '. $type .
				 ' ORDER BY i.id DESC ';
		$this->_db->setQuery( $query );
		$real_invoice_num = $this->_db->loadResult() + 1;

		$invoice_num = InvoicesHelper::getInvoiceNum($real_invoice_num, $type) ;

		$invoice['id'] = 0 ;
		if($invoice['user_id'])
$invoice['vincular_cliente_checkbox'] = 1 ;
		else $invoice['vincular_cliente_checkbox'] = 0 ;

		$invoice['taxes'] = explode(",",
$invoice['taxes']);

		$invoice['status'] = "" ;
		$invoice['invoice_date'] = date('Y-m-d H:i:s');

		$invoice['invoice_num'] = $invoice_num ;
		$invoice['real_invoice_num'] = $real_invoice_num ;

		$invoice['is_recurrent'] = 0 ;
		$invoice['rec_nextdate'] = "" ;
		$invoice['rec_year'] = 0 ;
		$invoice['rec_month'] = 0 ;
		$invoice['rec_day'] = 0 ;

		$invoice['external_type'] = "" ;
		$invoice['external_id'] = NULL ;
		$invoice['auth_code'] = "" ;

		$invoice['last_sent'] = NULL ;

		//taxes v 2.1
		$query = 	' SELECT * FROM #__invoices_tax_invoice '.
					' WHERE reference_id = ' . $invoice_id .
					' AND type = 1 ';
		$this->_db->setQuery( $query );
		$taxes_in_invoice = $this->_db->loadObjectList('tax_id');

		for($i = 0, $n = count($invoice['taxes']); $i < $n; $i++){
			$tax_id = $invoice['taxes'][$i];
			if($tax_id) $invoice['tax_value_'.$tax_id] =
$taxes_in_invoice[$tax_id]->value;
		}

		//prepare items
		for($i = 0, $n = count($items); $i < $n; $i++){
			$items[$i]['id'] = 0;
		}

		//prepare payments
		for($i = 0, $n = count($payments); $i < $n; $i++){
			$payments[$i]['id'] = 0;
			$payments[$i]['payment_status'] = 0;
			$payments[$i]['payment_datetime'] = "";
			$payments[$i]['payment_duedate'] = "";
			$payments[$i]['payment_type'] = "";
			$payments[$i]['payment_details'] = "";
		}

		//save the invoice
		return $this->store($invoice, $items, $payments);

	}

	function create_recurring(){
		$query = ' SELECT i.* FROM #__invoices_invoices as i '.
				 ' WHERE i.is_recurrent = 1 AND rec_nextdate =
"'.date("Y-m-d").'" ';

		$this->_db->setQuery( $query );
		$invoices = $this->_db->loadAssocList();

		foreach($invoices as $invoice){
			$new_id = $this->duplicate($invoice["id"]) ;

			//set the next recurrency date
			$nextdate = InvoicesHelper::getNextRecurrencyDate($invoice);

			$query = ' UPDATE #__invoices_invoices '.
					 ' SET rec_nextdate = "'.$nextdate.'" '
.
				 	 ' WHERE id = '.$invoice["id"];
			$this->_db->setQuery( $query );
			$this->_db->query();

			if($invoice['rec_email']) $this->sendMail($new_id);

		}

		return count($invoices);
	}

	function store($data = false, $items = false, $payments = false)
	{

		$mainframe = JFactory::getApplication();
		$row = $this->getTable('invoice');

		if(!$data) {
			$data = $this->input->post->getArray();
			$data['notes'] =
$this->input->post->getRaw('notes');
			$data['admin_notes'] =
$this->input->post->getRaw('admin_notes');
		}

		if(!isset($data['vincular_cliente_checkbox']))
$data['vincular_cliente_checkbox'] = 0 ;

		switch($data['vincular_cliente_checkbox']){
			case 2: case 3 ;

				if($data['vincular_cliente_checkbox'] == 2){
					$new_contact['id'] = 0 ;
				}
				else{
					$new_contact['id'] = $data['user_id'] ;
				}
				//$new_contact['user_id'] = $user->id ;
				$new_contact['name'] = $data['to_name'] ;
				$new_contact['company'] = $data['to_company'] ;
				$new_contact['email'] = $data['to_email'] ;
				$new_contact['address'] = $data['to_address'] ;
				$new_contact['user_id'] = $data['joomla_user_id'] ;

				$new_contact['city'] = $data['to_city'] ;
				$new_contact['state'] = $data['to_state'] ;
				$new_contact['country'] = $data['to_country'] ;
				$new_contact['zipcode'] = $data['to_zipcode'] ;
				$new_contact['vatid'] = $data['to_vatid'] ;
				$new_contact['phone'] = $data['to_phone'] ;

				$row_contact= $this->getTable('contact');

				if (!$row_contact->bind($new_contact)) {
					$this->setError($this->_db->getErrorMsg());
					return false;
				}

				if (!$row_contact->check()) {
					$this->setError($this->_db->getErrorMsg());
					return false;
				}

				if (!$row_contact->store()) {
					$mainframe->enqueueMessage($this->_db->getErrorMsg(),
"error");
					$this->setError( $this->_db->getErrorMsg() );
					return false;
				}

				$data['user_id'] = $row_contact->id ;
			break;
			case 0:
				$data['user_id'] = 0 ;
			break;
		}

		//check if we need to calculate recurrency
		if(isset($data["is_recurrent"]) &&
$data["is_recurrent"] == 1){

			if($data["rec_nextdate"] == "0000-00-00" ||
!$data["rec_nextdate"] ){
				if($data["invoice_date"]) $data["rec_nextdate"] =
$data["invoice_date"] ;
				else $data["rec_nextdate"] = date("Y-m-d");

				$nextdate = InvoicesHelper::getNextRecurrencyDate($data);
				$data["rec_nextdate"] = $nextdate ;

			}
		}

		// Bind the form fields to the album table
		if (!$row->bind($data)) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		if (!$row->check()) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		if (!$row->store()) {
			$this->setError( $this->_db->getErrorMsg() );
			return false;
		}

		$isNew = false;

		if(!$data["id"]){ // it's a new invoice
			$isNew = true;
			$data["id"] = $row->id;
		}

		//new in v 2.1 - Tax calculation
		if(isset($data['taxes'])) $taxes = $data['taxes'];
		else $taxes = array();
		//unset current taxes in invoice
		$query = "UPDATE #__invoices_tax_invoice SET active = 0,
computed_value = 0 WHERE reference_id = " . $row->id . " AND
type = 1 ";
		$this->_db->setQuery($query);
		$this->_db->query();

		//we loop through the taxes to set them active and set its value
		for($i = 0, $n = count($taxes); $i < $n; $i++){
			$tax_id = $taxes[$i];
			if($tax_id){
				$tax_value = $data['tax_value_'.$tax_id];
				$this->add_tax_to_invoice($tax_id, $tax_value, $row->id);
			}
		}

		$i = 1 ;

		if(!$items){
			//the items
			foreach($data as $key => $value){
				if(substr($key,0,5) == "name_")	{
					$item_id = (int)substr($key,5);
					$item_data = array(
									   "id" => $item_id ,
									   "name" => $data["name_" . $item_id],
									   "desc" => $data["description_" .
$item_id],
									   "value" => $data["value_" . $item_id],
									   "amount" => $data["amount_" .
$item_id]	,
									   "discount" => $data["discount_" .
$item_id]	,
									   "tax" => $data["tax_" . $item_id]	,
									   "tax_id" => $data["tax_id_" .
$item_id]	,
									   "sku" => $data["sku_" . $item_id]	,
									   "product_id" => $data["product_id_" .
$item_id]	,
									   "external_type" =>
$data["external_type_" . $item_id]	,
									   "ordering" => $i

									   );
					$this->save_item($item_data);
					$i++;
				} //new items
				else if(substr($key,0,7) == "0_name_")	{
					$item_id = (int)substr($key,7);
					$item_data = array(
									   "id" => 0 ,
									   "name" => $data["0_name_" . $item_id],
									   "desc" => $data["0_description_" .
$item_id],
									   "value" => $data["0_value_" . $item_id],
									   "amount" => $data["0_amount_" .
$item_id],
									   "discount" => $data["0_discount_" .
$item_id],
									   "tax" => $data["0_tax_" . $item_id],
									   "tax_id" => $data["0_tax_id_" .
$item_id],
									   "sku" => $data["0_sku_" . $item_id],
									   "product_id" => $data["0_product_id_" .
$item_id]	,
									   "external_type" =>
$data["0_external_type_" . $item_id]	,
									   "ordering" => $i + 100,
									   "invoice_id" => $data["id"]
									   );
					$this->save_item($item_data);
					$i++;
				}



			}
		}
		else{
			foreach($items as $item){
				//$item["id"] = 0 ;
				$item["invoice_id"] = $row->id ;
				$item["ordering"] = $i ;

				$this->save_item($item);

				$i++;
			}
		}

		//compute total
		$row->computed_total = InvoicesHelper::get_total_from_id($row->id,
true) ;
		$row->computed_subtotal =
InvoicesHelper::get_subtotal_items($row->id);

		$computed = new StdClass();
		$computed->total = $row->computed_total;
		$computed->subtotal = InvoicesHelper::get_subtotal($row->id);
		$computed->subtotal_items = $row->computed_subtotal;

		//we process the payments
		if(isset($data["automatic_payment"]) &&
$data["automatic_payment"]){
			//create 1 payment for the full amount
			$payments = array();
			$payments[0]["id"] = 0 ;
			$payments[0]["payment_amount"] = $row->computed_total ;

		}

		$i = 1 ;

		if(!$payments){
			//the payments
			foreach($data as $key => $value){
				if(substr($key,0,20) == "payment_description_")	{
					$payment_id = (int)substr($key,20);
					$payment_data = array(
									   "id" => $payment_id ,
									   "payment_description" =>
$data["payment_description_" . $payment_id],
									   "payment_duedate" =>
$data["payment_duedate_" . $payment_id],
									   "payment_amount" =>
$data["payment_value_" . $payment_id],
									   "payment_status" =>
$data["payment_status_" . $payment_id],
									   "payment_datetime" =>
$data["payment_datetime_" . $payment_id],
									   "ordering" => $i
									   );
					$this->save_payment($payment_data);
					$i++;
				} //new payments
				else if(substr($key,0,22) == "0_payment_description_")	{
					$payment_id = (int)substr($key,22);
					$payment_data = array(
									   "id" => 0 ,
									   "payment_description" =>
$data["0_payment_description_" . $payment_id],
									   "payment_duedate" =>
$data["0_payment_duedate_" . $payment_id],
									   "payment_amount" =>
$data["0_payment_value_" . $payment_id],
									   "payment_status" =>
$data["0_payment_status_" . $payment_id],
									   "payment_datetime" =>
$data["0_payment_datetime_" . $payment_id],
									   "ordering" => $i + 100,
									   "invoice_id" => $data["id"]
									   );
					$this->save_payment($payment_data);
					$i++;
				}

			}
		}
		else{
			foreach($payments as $payment){

				$payment["invoice_id"] = $row->id ;
				$payment["ordering"] = $i ;

				$this->save_payment($payment);

				$i++;
			}
		}

		//compute status
		$row->computed_status = InvoicesHelper::getComputedInvoiceStatus($row,
$row->computed_total) ;

		//compute payments
		$query = ' SELECT SUM(pa.payment_amount) AS total_paid,
COUNT(DISTINCT pa.id) AS paid_payments FROM #__invoices_payments AS pa
WHERE pa.invoice_id = '.$row->id.' AND pa.payment_status = 1
' ;
		$this->_db->setQuery($query);
		$computed->total_paid = $this->_db->loadObject();

		$query = ' SELECT SUM(pa.payment_amount) AS total_unpaid,
COUNT(DISTINCT pa.id) AS unpaid_payments FROM #__invoices_payments AS pa
WHERE pa.invoice_id = '.$row->id.' AND pa.payment_status = 0
' ;
		$this->_db->setQuery($query);
		$computed->total_unpaid = $this->_db->loadObject();

		//store taxes in json
		$row->subtotal = $computed->subtotal;
		$row->subtotal_items = $computed->subtotal_items;
		$computed->taxes = InvoicesHelper::get_display_taxes($row);
		$row->subtotal = null;
		$row->subtotal_items = null;

		$row->computed = json_encode($computed);

		if (!$row->store()) {
			$this->setError( $this->_db->getErrorMsg() );
			return false;
		}

		$import = JPluginHelper::importPlugin( 'invoices' );
		$dispatcher = JDispatcher::getInstance();
		$dispatcher->trigger( 'onAfterSaveInvoice', array( $row,
$isNew ) );

		if(isset($data['sendemail']) &&
$data['sendemail']) $this->sendMail($row->id) ;

		return $row->id;
	}

	function add_tax_to_invoice($tax_id, $tax_value, $invoice_id){

		$query = "SELECT id FROM #__invoices_tax_invoice WHERE tax_id =
". $tax_id ." AND reference_id = ". $invoice_id . " AND
type = 1 ";
		$this->_db->setQuery($query);
		$exists = (int)$this->_db->loadResult();

		$data = array();
		$data['id'] = $exists;
		$data['tax_id'] = $tax_id;
		$data['reference_id'] = $invoice_id;
		$data['value'] = $tax_value;
		$data['type'] = 1;
		$data['active'] = 1;
		$data['computed_value'] = 0;

		$this->save_tax($data);

	}

	function save_tax($data)
	{
		$row = $this->getTable('taxinvoice');

		if (!$row->bind($data)) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		if (!$row->check()) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		if (!$row->store()) {

			$this->setError( $this->_db->getErrorMsg() );
			return false;
		}

		return true;
	}

	function save_item($data)
	{
		$row = $this->getTable('item');

		if (!$row->bind($data)) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		if (!$row->check()) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		if (!$row->store()) {

			$this->setError( $this->_db->getErrorMsg() );
			return false;
		}

		return true;
	}

	function save_payment($data)
	{
		$row = $this->getTable('payment');

		if (!$row->bind($data)) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		if (!$row->check()) {
			$this->setError($this->_db->getErrorMsg());
			return false;
		}

		if (!$row->store()) {

			$this->setError( $this->_db->getErrorMsg() );
			return false;
		}

		$import = JPluginHelper::importPlugin( strtolower( 'Invoices' )
);
		$dispatcher = JDispatcher::getInstance();
		$dispatcher->trigger( 'onAfterSavePayment', array( $row ) );

		return true;
	}

	function delete()
	{
		$cids = $this->input->get( 'cid', array(0),
'default', 'array' );

		$row = $this->getTable();

		$import = JPluginHelper::importPlugin( strtolower( 'Invoices' )
);
		$dispatcher = JDispatcher::getInstance();

		if (count( $cids )) {
			foreach($cids as $cid) {
				$query = ' DELETE FROM #__invoices_items WHERE invoice_id = '
. $cid ;
				$this->_db->setQuery($query) ;
				$this->_db->query();

				$query = ' DELETE FROM #__invoices_payments WHERE invoice_id =
' . $cid ;
				$this->_db->setQuery($query) ;
				$this->_db->query();

				$query = ' DELETE FROM #__invoices_tax_invoice WHERE reference_id
= ' . $cid ;
				$this->_db->setQuery($query) ;
				$this->_db->query();

				$dispatcher->trigger( 'onBeforeDeleteInvoice', array( $cid
) );

				if (!$row->delete( $cid )) {
					$this->setError( $row->getErrorMsg() );
					return false;
				}
			}
		}
		return true;
	}

	function publish()
	{
		$cids = $this->input->get( 'cid', array(0),
'default', 'array' );

		$import = JPluginHelper::importPlugin( 'invoices' );
		$dispatcher = JDispatcher::getInstance();

		if (count( $cids )) {
			foreach($cids as $cid) {
				$query = ' UPDATE #__invoices_invoices SET publish = 1 WHERE id =
'. $cid . ' LIMIT 1 ';
				$this->_db->setQuery($query);
				$this->_db->query();

				$dispatcher->trigger( 'onPublishInvoice', array( $cid ) );
			}
		}
		return true;
	}

	function unpublish()
	{
		$cids = $this->input->get( 'cid', array(0),
'default', 'array' );

		$import = JPluginHelper::importPlugin( 'invoices' );
		$dispatcher = JDispatcher::getInstance();

		if (count( $cids )) {
			foreach($cids as $cid) {
				$query = ' UPDATE #__invoices_invoices SET publish = 0 WHERE id =
'. $cid . ' LIMIT 1 ';
				$this->_db->setQuery($query);
				$this->_db->query();

				$dispatcher->trigger( 'onUnpublishInvoice', array( $cid )
);
			}
		}
		return true;
	}

	function change_status()
	{
		$cids = $this->input->get( 'cid', array(0),
'default', 'array' );

		$import = JPluginHelper::importPlugin( 'invoices' );
		$dispatcher = JDispatcher::getInstance();

		$status = $this->input->getWord('status');

		if (count( $cids )) {
			foreach($cids as $cid) {
				$query = ' UPDATE #__invoices_invoices SET status =
"'.$status.'" WHERE id = '. $cid . ' LIMIT 1
';
				$this->_db->setQuery($query);
				$this->_db->query();

				$dispatcher->trigger( 'onChangeInvoiceStatus', array(
$cid, $status ) );
			}
		}
		return true;
	}

	function sendMail($id = false){

		if(!$id) $id = $this->input->getInt( 'id' ) ;
		if($id) $this->setId($id) ;

		$data = $this->getData();

		$params = JComponentHelper::getParams( 'com_invoices' );

		$from = $params->get('email_email') ;
		$from_name = $params->get('email_name') ;

		switch($data->type){
			case 1: //invoice
			$subject = $params->get('email_subject') ;
			break;
			case 2: //quote
			$subject = $params->get('email_subject_quote') ;
			break;
		}

		$subject = str_replace("{invoice_num}", $data->invoice_num,
$subject) ;

		$view		= $this->getInvoiceView();

		$view->invoice		= $data;
		$view->template		= $this->getTemplate();
		$view->items		= $this->getItems();
		$view->taxes		= $this->getTaxesInvoice();
		$view->payments		= $this->getPaymentsInvoice();
		$view->payments2	= $this->getPaymentsInvoice2();
		$view->params		= $params;

		if($view->template->content_email) $view->template->content =
$view->template->content_email ;

		$view->_path['template'][1] =
JPATH_SITE.DS.'components'.DS.'com_invoices'.DS.'views'.DS.'invoice'.DS.'tmpl'
;

		$plantilla = 'email' ;

		$message = $view->loadTemplate( $plantilla );

		$styles =
"<style>".$view->template->styles."</style>"
;
		$message = $styles . $message ;

		$to = $data->to_email;

		$toBlock = str_replace(" ", "", $to); //Delete spaces
between emails
		$toMails = explode(",", $toBlock);

		$mail = JFactory::getMailer();
		$mail->addRecipient($toMails);
		$mail->setsender(array($from, $from_name));
		$mail->setSubject($subject);
		$mail->setbody($message);
		$mail->isHTML(true);

		if($params->get('pdfemail') &&
InvoicesHelper::PDFavailable()){
			//create PDF
			$viewpdf		= $this->getInvoiceView('dompdf');

			$viewpdf->invoice		= $view->invoice	;
			$viewpdf->template		= $this->getTemplate();
			$viewpdf->items			= $view->items	;
			$viewpdf->taxes			= $view->taxes	;
			$viewpdf->payments		= $view->payments;
			$viewpdf->payments2		= $view->payments2;
			$viewpdf->params		= $params;

			if($viewpdf->template->content_pdf)
$viewpdf->template->content = $viewpdf->template->content_pdf ;

      $viewpdf->_path['template'][1] =
JPATH_SITE.DS.'components'.DS.'com_invoices'.DS.'views'.DS.'invoice'.DS.'tmpl'
;

			if($viewpdf->invoice->invoice_num) $pdfname =
$viewpdf->invoice->invoice_num;
			else $pdfname = rand();

			$pdfname = str_replace("/", "-", $pdfname);

			$location =
JPATH_SITE.DS.$params->get('pdffolder','pdfinvoices').DS.$pdfname
. ".pdf" ;
			$pdf = InvoicesHelper::storepdf($location, $viewpdf);

			if($pdf) $mail->addAttachment($location,
$viewpdf->invoice->invoice_num . ".pdf") ;

		}

		$sent = $mail->Send();
		if($sent && $to){
			InvoicesHelper::updateSentDate($data->id);

			//trigger event
			$import = JPluginHelper::importPlugin( 'invoices' );
			$dispatcher = JDispatcher::getInstance();
			$dispatcher->trigger( 'onAfterSendInvoice', array( $data )
);
		}
		else{
			$sent = false;
		}
		return $sent ;

	}

	function getInvoiceView($type = "html")
	{
		if (!class_exists( 'InvoicesViewInvoice' ))
		{
			// Build the path to the model based upon a supplied base path
			$path =
JPATH_SITE.DS.'components'.DS.'com_invoices'.DS.'views'.DS.'invoice'.DS.'view.'.$type.'.php';
			$false = false;

			// If the model file exists include it and try to instantiate the object
			if (file_exists( $path )) {
				require_once( $path );
				if (!class_exists( 'InvoicesViewInvoice' )) {
					JError::raiseWarning( 0, 'View class InvoicesViewInvoice not
found in file.' );
					return $false;
				}
			} else {
				JError::raiseWarning( 0, 'View InvoicesViewInvoice not supported.
File not found.' );
				return $false;
			}
		}

		$view = new InvoicesViewInvoice();
		return $view;
	}

	function accept_quote(){
		$query = ' UPDATE #__invoices_invoices SET status =
"accepted_client" WHERE id = '. $this->_id ;
		$this->_db->setQuery($query);
		$this->_db->query();

		return true;
	}

	function reject_quote(){
		$query = ' UPDATE #__invoices_invoices SET status =
"rejected_client" WHERE id = '. $this->_id ;
		$this->_db->setQuery($query);
		$this->_db->query();

		return true;
	}

	function getTaxesToShow(){

		$query = 	' SELECT * FROM #__invoices_taxes WHERE show_column = 1
ORDER BY ordering, name ';
		$this->_db->setQuery( $query );
		$taxes = $this->_db->loadObjectList();

		return $taxes;

	}

	function getDataDisplay($id = false)
	{
		$id = (int)$id;
		if($id) $this->setId($id);

		$query = ' SELECT i.*, u.name as username, co.name as contact_name,
co.user_id as joomla_user_id '
						.' FROM #__invoices_invoices as i '
						.' LEFT JOIN #__invoices_contacts as co ON co.id = i.user_id
'
						.' LEFT JOIN #__users as u ON u.id = co.user_id '
						.' WHERE i.id = ' .$this->_id
						;
		$this->_db->setQuery( $query );
		$row = $this->_db->loadObject();

		if(!is_object($row)){
			$row = new stdClass();
			$row->id = $this->_id;
		}

		//items v2.2
		$row->items = $this->getItems();
		$row->payments = $this->getPayments();
		$row->taxes = $this->getTaxes();

		if(InvoicesHelper::allowEdit($row->id, $row->created_by))
$row->allow_edit = 1 ;
		else $row->allow_edit = 0 ;

		if($row->joomla_user_id) $row->username =  $row->username .
" [".$row->joomla_user_id."]";
		else $row->username =  JText::_('JNO');

		switch($row->type){
			case 1: //invoice
				$row->is_quote = 0 ;
				$row->edit_link =
JRoute::_('index.php?option=com_invoices&controller=invoice&tmpl=component&task=edit&cid[]='
. $row->id . '&layout=form&modal=1' , false);

			break;
			case 2: //quote
				$row->is_quote = 1 ;
				$row->edit_link =
JRoute::_('index.php?option=com_invoices&controller=quote&tmpl=component&task=edit&cid[]='
. $row->id . '&layout=form&modal=1' , false);

			break;
		}

		$row->link 				=
JRoute::_('index.php?option=com_invoices&controller=invoice&view=invoice&cid[]='.$row->id.'&tmpl=component',
false);
		$row->link_contact 		= JRoute::_(
'index.php?option=com_invoices&controller=contact&task=edit&cid[]='.
$row->user_id , false);
    $row->link_payments 	= JRoute::_(
'index.php?option=com_invoices&controller=payments&invoice_id='.
$row->id , false);
    $row->link_new_payment 	= JRoute::_(
'index.php?option=com_invoices&controller=payment&task=edit&cid[]=0&invoice_id='.
$row->id .'&from=invoices' , false);
    $row->pdf_link 			= InvoicesHelper::download_pdf_link($row->id);
    $row->email_link 		= InvoicesHelper::send_email_link($row->id) .
"&ajax=1";
		$row->public_link 			=
InvoicesHelper::getInvoicePublicLink($row->id);

		if(!$row->currency_id) $row->currency_id =
$this->params->get('currency_id', 1);

		if($row->last_sent != "0000-00-00 00:00:00") {
			$row->sent = 1;
		}
		else {
			$row->sent = 0;
		}

		return $row ;
	}

}