diff --git a/application/models/Sale.php b/application/models/Sale.php index 4cdc5d995..5e4f8b33b 100644 --- a/application/models/Sale.php +++ b/application/models/Sale.php @@ -3,28 +3,10 @@ class Sale extends CI_Model { public function get_info($sale_id) { - if($this->config->item('tax_included')) - { - $total = '1'; - $subtotal = '(1 - (SUM(1 - 100 / (100 + sales_items_taxes.percent))))'; - $tax = '(SUM(1 - 100 / (100 + sales_items_taxes.percent)))'; - } - else - { - $tax = '(SUM(sales_items_taxes.percent) / 100)'; - $total = '(1 + (SUM(sales_items_taxes.percent / 100)))'; - $subtotal = '1'; - } - - $sale_total = 'SUM(sales_items.item_unit_price * sales_items.quantity_purchased - sales_items.item_unit_price * sales_items.quantity_purchased * sales_items.discount_percent / 100)'; - $sale_cost = 'SUM(sales_items.item_cost_price * sales_items.quantity_purchased)'; - - $decimals = totals_decimals(); - - // create payments temp table to speed up the sales listing + // NOTE: temporary tables are created to speed up searches due to the fact that are ortogonal to the main query + // create a temporary table to contain all the payments per sale item $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_payments_temp') . - ' (PRIMARY KEY(sale_id), INDEX(sale_id)) - ( + '( SELECT payments.sale_id AS sale_id, IFNULL(SUM(payments.payment_amount), 0) AS sale_payment_amount, GROUP_CONCAT(CONCAT(payments.payment_type, " ", payments.payment_amount) SEPARATOR ", ") AS payment_type @@ -36,6 +18,37 @@ class Sale extends CI_Model )' ); + // create a temporary table to contain all the sum of taxes per sale item + $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_taxes_temp') . + '( + SELECT sales_items_taxes.sale_id AS sale_id, + sales_items_taxes.item_id AS item_id, + SUM(sales_items_taxes.percent) AS percent + FROM ' . $this->db->dbprefix('sales_items_taxes') . ' AS sales_items_taxes + INNER JOIN ' . $this->db->dbprefix('sales') . ' AS sales + ON sales.sale_id = sales_items_taxes.sale_id + INNER JOIN ' . $this->db->dbprefix('sales_items') . ' AS sales_items + ON sales_items.sale_id = sales_items_taxes.sale_id AND sales_items.line = sales_items_taxes.line + WHERE sales.sale_id = ' . $this->db->escape($sale_id) . ' + GROUP BY sales_items_taxes.sale_id, sales_items_taxes.item_id + )' + ); + + if($this->config->item('tax_included')) + { + $sale_total = 'SUM(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100))'; + $sale_subtotal = 'SUM(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (100 / (100 + sales_items_taxes.percent)))'; + $sale_tax = 'SUM(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (1 - 100 / (100 + sales_items_taxes.percent)))'; + } + else + { + $sale_total = 'SUM(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (1 + (sales_items_taxes.percent / 100)))'; + $sale_subtotal = 'SUM(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100))'; + $sale_tax = 'SUM(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (sales_items_taxes.percent / 100))'; + } + + $decimals = totals_decimals(); + $this->db->select(' sales.sale_id AS sale_id, DATE(sales.sale_time) AS sale_date, @@ -49,9 +62,10 @@ class Sale extends CI_Model customer_p.last_name AS last_name, customer_p.email AS email, customer_p.comments AS comments, - payments.sale_payment_amount AS amount_tendered, ' . " - IFNULL(ROUND($sale_total * $total, $decimals), ROUND($sale_total * $subtotal, $decimals)) AS amount_due, + IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals)) AS amount_due, + payments.sale_payment_amount AS amount_tendered, + (payments.sale_payment_amount - IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals))) AS change_due, " . ' payments.payment_type AS payment_type '); @@ -61,9 +75,10 @@ class Sale extends CI_Model $this->db->join('people AS customer_p', 'sales.customer_id = customer_p.person_id', 'left'); $this->db->join('customers AS customer', 'sales.customer_id = customer.person_id', 'left'); $this->db->join('sales_payments_temp AS payments', 'sales.sale_id = payments.sale_id', 'left outer'); - $this->db->join('sales_items_taxes AS sales_items_taxes', 'sales_items.sale_id = sales_items_taxes.sale_id AND sales_items.item_id = sales_items_taxes.item_id AND sales_items.line = sales_items_taxes.line', 'left outer'); + $this->db->join('sales_items_taxes_temp AS sales_items_taxes', 'sales_items.sale_id = sales_items_taxes.sale_id AND sales_items.item_id = sales_items_taxes.item_id', 'left outer'); $this->db->where('sales.sale_id', $sale_id); + $this->db->group_by('sales.sale_id'); $this->db->order_by('sales.sale_time', 'asc'); @@ -137,6 +152,7 @@ class Sale extends CI_Model sales.sale_id AS sale_id, DATE(sales.sale_time) AS sale_date, sales.sale_time AS sale_time, + sales.invoice_number AS invoice_number, SUM(sales_items.quantity_purchased) AS items_purchased, CONCAT(customer_p.first_name, " ", customer_p.last_name) AS customer_name, customer.company_name AS company_name, @@ -147,11 +163,10 @@ class Sale extends CI_Model ROUND($sale_cost, $decimals) AS cost, ROUND($sale_total - IFNULL($sale_tax, 0) - $sale_cost, $decimals) AS profit, IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals)) AS amount_due, + payments.sale_payment_amount AS amount_tendered, (payments.sale_payment_amount - IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals))) AS change_due, " . ' - payments.sale_payment_amount AS amount_tendered, - payments.payment_type AS payment_type, - sales.invoice_number AS invoice_number + payments.payment_type AS payment_type '); $this->db->from('sales_items AS sales_items'); @@ -716,7 +731,7 @@ class Sale extends CI_Model $sale_cost = '(sales_items.item_cost_price * sales_items.quantity_purchased)'; - // increase the rounding of one decimals on top of the selected ones to avoid accumulative rounding errors in the totals + // increase the rounding of one decimal on top of the selected ones to avoid accumulative rounding errors in the totals $decimals = totals_decimals() + 1; if(empty($input['sale_id']))