diff --git a/application/models/Sale.php b/application/models/Sale.php index 3bcbdf603..deaffc089 100644 --- a/application/models/Sale.php +++ b/application/models/Sale.php @@ -686,22 +686,22 @@ class Sale extends CI_Model { 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)))'; + $sale_total = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100))'; + $sale_subtotal = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (100 / (100 + SUM(sales_items_taxes.percent))))'; + $sale_tax = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (1 - 100 / (100 + SUM(sales_items_taxes.percent))))'; } else { - $tax = '(SUM(sales_items_taxes.percent) / 100)'; - $total = '(1 + (SUM(sales_items_taxes.percent / 100)))'; - $subtotal = '1'; + $sale_total = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (1 + (SUM(sales_items_taxes.percent) / 100)))'; + $sale_subtotal = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100))'; + $sale_tax = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (SUM(sales_items_taxes.percent) / 100))'; } - $sale_total = '(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 = '(sales_items.item_cost_price * sales_items.quantity_purchased)'; - $decimals = totals_decimals(); - + // increase the rounding of two decimals on top of the selected ones to avoid accumulative rounding errors in the totals + $decimals = totals_decimals() + 2; + if(empty($input['sale_id'])) { $where = 'WHERE DATE(sales.sale_time) BETWEEN ' . $this->db->escape($inputs['start_date']) . ' AND ' . $this->db->escape($inputs['end_date']); @@ -762,11 +762,11 @@ class Sale extends CI_Model payments.sale_payment_amount, IFNULL(SUM(sales_items_taxes.percent), 0) AS item_tax_percent, ' . " - IFNULL(ROUND($sale_total * $total, $decimals), ROUND($sale_total * $subtotal, $decimals)) AS total, - IFNULL(ROUND($sale_total * $tax, $decimals), 0) AS tax, - ROUND($sale_total * $subtotal, $decimals) AS subtotal, - ROUND($sale_total - $sale_cost, $decimals) AS profit, - ROUND($sale_cost, $decimals) AS cost + ROUND($sale_subtotal, $decimals) AS subtotal, + IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals)) AS total, + IFNULL(ROUND($sale_tax, $decimals), 0) AS tax, + ROUND($sale_cost, $decimals) AS cost, + ROUND($sale_total - IFNULL($sale_tax, 0) - $sale_cost, $decimals) AS profit " . ' FROM ' . $this->db->dbprefix('sales_items') . ' AS sales_items INNER JOIN ' . $this->db->dbprefix('sales') . ' AS sales diff --git a/application/models/reports/Detailed_sales.php b/application/models/reports/Detailed_sales.php index c8391b8ed..ac2ac4fe3 100644 --- a/application/models/reports/Detailed_sales.php +++ b/application/models/reports/Detailed_sales.php @@ -6,13 +6,13 @@ class Detailed_sales extends Report { parent::__construct(); } - + public function create(array $inputs) { //Create our temp tables to work with the data in our report $this->Sale->create_temp_table($inputs); } - + public function getDataColumns() { return array( @@ -44,7 +44,7 @@ class Detailed_sales extends Report $this->lang->line('reports_discount')) ); } - + public function getDataBySaleId($sale_id) { $this->db->select('sale_id, sale_date, SUM(quantity_purchased) AS items_purchased, employee_name, customer_name, SUM(subtotal) AS subtotal, SUM(total) AS total, SUM(tax) AS tax, SUM(cost) AS cost, SUM(profit) AS profit, payment_type, comment'); @@ -53,7 +53,7 @@ class Detailed_sales extends Report return $this->db->get()->row_array(); } - + public function getData(array $inputs) { $this->db->select('sale_id, sale_date, SUM(quantity_purchased) AS items_purchased, employee_name, customer_name, SUM(subtotal) AS subtotal, SUM(total) AS total, SUM(tax) AS tax, SUM(cost) AS cost, SUM(profit) AS profit, payment_type, comment'); @@ -79,7 +79,7 @@ class Detailed_sales extends Report $data = array(); $data['summary'] = $this->db->get()->result_array(); $data['details'] = array(); - + foreach($data['summary'] as $key=>$value) { $this->db->select('name, category, quantity_purchased, item_location, serialnumber, description, subtotal, total, tax, cost, profit, discount_percent'); @@ -87,10 +87,10 @@ class Detailed_sales extends Report $this->db->where('sale_id', $value['sale_id']); $data['details'][$key] = $this->db->get()->result_array(); } - + return $data; } - + public function getSummaryData(array $inputs) { $this->db->select('SUM(subtotal) AS subtotal, SUM(total) AS total, SUM(tax) AS tax, SUM(cost) AS cost, SUM(profit) AS profit'); diff --git a/application/models/reports/Summary_categories.php b/application/models/reports/Summary_categories.php index 482de4914..dbd34594f 100644 --- a/application/models/reports/Summary_categories.php +++ b/application/models/reports/Summary_categories.php @@ -21,10 +21,9 @@ class Summary_categories extends Summary_report SUM(sales_items.quantity_purchased) AS quantity_purchased '); - $this->db->from('sales_items AS sales_items'); - $this->db->join('sales AS sales', 'sales_items.sale_id = sales.sale_id', 'inner'); + $this->commonFrom(); + $this->db->join('items AS items', 'sales_items.item_id = items.item_id', 'inner'); - $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->commonWhere($inputs); diff --git a/application/models/reports/Summary_customers.php b/application/models/reports/Summary_customers.php index bbe7accf9..a479e8f61 100644 --- a/application/models/reports/Summary_customers.php +++ b/application/models/reports/Summary_customers.php @@ -21,10 +21,9 @@ class Summary_customers extends Summary_report SUM(sales_items.quantity_purchased) AS quantity_purchased '); - $this->db->from('sales_items AS sales_items'); - $this->db->join('sales AS sales', 'sales_items.sale_id = sales.sale_id', 'inner'); + $this->commonFrom(); + $this->db->join('people AS customer_p', 'sales.customer_id = customer_p.person_id'); - $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->commonWhere($inputs); diff --git a/application/models/reports/Summary_employees.php b/application/models/reports/Summary_employees.php index e42f05d45..1cc275670 100644 --- a/application/models/reports/Summary_employees.php +++ b/application/models/reports/Summary_employees.php @@ -21,10 +21,9 @@ class Summary_employees extends Summary_report SUM(sales_items.quantity_purchased) AS quantity_purchased '); - $this->db->from('sales_items AS sales_items'); - $this->db->join('sales AS sales', 'sales_items.sale_id = sales.sale_id', 'inner'); + $this->commonFrom(); + $this->db->join('people AS employee_p', 'sales.employee_id = employee_p.person_id'); - $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->commonWhere($inputs); diff --git a/application/models/reports/Summary_items.php b/application/models/reports/Summary_items.php index 4a2c3ffa1..9da526a58 100644 --- a/application/models/reports/Summary_items.php +++ b/application/models/reports/Summary_items.php @@ -21,10 +21,9 @@ class Summary_items extends Summary_report SUM(sales_items.quantity_purchased) AS quantity_purchased '); - $this->db->from('sales_items AS sales_items'); - $this->db->join('sales AS sales', 'sales_items.sale_id = sales.sale_id', 'inner'); + $this->commonFrom(); + $this->db->join('items AS items', 'sales_items.item_id = items.item_id', 'inner'); - $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->commonWhere($inputs); diff --git a/application/models/reports/Summary_report.php b/application/models/reports/Summary_report.php index b1e40c1ff..2e4b9dd1e 100644 --- a/application/models/reports/Summary_report.php +++ b/application/models/reports/Summary_report.php @@ -9,33 +9,56 @@ abstract class Summary_report extends Report protected function commonSelect(array $inputs) { + // create a temporary table to contain all the payment types and amount + $this->db->query('CREATE TEMPORARY TABLE IF NOT EXISTS ' . $this->db->dbprefix('sales_items_taxes_temp') . + ' (INDEX(sale_id), INDEX(item_id)) + ( + 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 DATE(sale_time) BETWEEN ' . $this->db->escape($inputs['start_date']) . ' AND ' . $this->db->escape($inputs['end_date']) . ' + GROUP BY sales_items_taxes.sale_id, sales_items_taxes.item_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)))'; + $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 { - $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 * (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))'; } - $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)'; + $sale_cost = 'SUM(sales_items.item_cost_price * sales_items.quantity_purchased)'; $decimals = totals_decimals(); $this->db->select(" - ROUND($sale_total * $subtotal, $decimals) AS subtotal, - IFNULL(ROUND($sale_total * $total, $decimals), ROUND($sale_total * $subtotal, $decimals)) AS total, - IFNULL(ROUND($sale_total * $tax, $decimals), 0) AS tax, + ROUND($sale_subtotal, $decimals) AS subtotal, + IFNULL(ROUND($sale_total, $decimals), ROUND($sale_subtotal, $decimals)) AS total, + IFNULL(ROUND($sale_tax, $decimals), 0) AS tax, ROUND($sale_cost, $decimals) AS cost, - ROUND($sale_total - $sale_cost, $decimals) AS profit + ROUND($sale_total - IFNULL($sale_tax, 0) - $sale_cost, $decimals) AS profit "); } - + + protected function commonFrom() + { + $this->db->from('sales_items AS sales_items'); + $this->db->join('sales AS sales', 'sales_items.sale_id = sales.sale_id', 'inner'); + $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'); + } + protected function commonWhere(array $inputs) { $this->db->where('DATE(sales.sale_time) BETWEEN ' . $this->db->escape($inputs['start_date']) . ' AND ' . $this->db->escape($inputs['end_date'])); @@ -54,14 +77,12 @@ abstract class Summary_report extends Report $this->db->where('quantity_purchased < 0'); } } - + public function getSummaryData(array $inputs) { $this->commonSelect($inputs); - $this->db->from('sales_items AS sales_items'); - $this->db->join('sales AS sales', 'sales_items.sale_id = sales.sale_id', 'inner'); - $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->commonFrom(); $this->commonWhere($inputs); diff --git a/application/models/reports/Summary_sales.php b/application/models/reports/Summary_sales.php index 9fd6027ae..fafb3da51 100644 --- a/application/models/reports/Summary_sales.php +++ b/application/models/reports/Summary_sales.php @@ -21,12 +21,10 @@ class Summary_sales extends Summary_report SUM(sales_items.quantity_purchased) AS quantity_purchased '); - $this->db->from('sales_items AS sales_items'); - $this->db->join('sales AS sales', 'sales_items.sale_id = sales.sale_id', 'inner'); - $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->commonFrom(); $this->commonWhere($inputs); - + $this->db->group_by('sale_date'); $this->db->order_by('sale_date'); diff --git a/application/models/reports/Summary_suppliers.php b/application/models/reports/Summary_suppliers.php index f91e521b0..b073bef4d 100644 --- a/application/models/reports/Summary_suppliers.php +++ b/application/models/reports/Summary_suppliers.php @@ -21,12 +21,11 @@ class Summary_suppliers extends Summary_report SUM(sales_items.quantity_purchased) AS quantity_purchased '); - $this->db->from('sales_items AS sales_items'); - $this->db->join('sales AS sales', 'sales_items.sale_id = sales.sale_id', 'inner'); + $this->commonFrom(); + $this->db->join('items AS items', 'sales_items.item_id = items.item_id', 'inner'); $this->db->join('suppliers AS supplier_c', 'supplier_c.person_id = items.supplier_id'); $this->db->join('people AS supplier_p', 'supplier_c.person_id = supplier_p.person_id'); - $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->commonWhere($inputs); diff --git a/application/models/reports/Summary_taxes.php b/application/models/reports/Summary_taxes.php index 045b16dd0..f57fb696b 100644 --- a/application/models/reports/Summary_taxes.php +++ b/application/models/reports/Summary_taxes.php @@ -29,36 +29,37 @@ class Summary_taxes extends Summary_report $quantity_cond .= 'AND item_location = '. $this->db->escape($inputs['location_id']); } - if ($this->config->item('tax_included')) + if($this->config->item('tax_included')) { - $total = '1'; - $subtotal = '(100/(100+percent))'; - $tax = '(1 - (100/(100 +percent)))'; + $sale_total = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100))'; + $sale_subtotal = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (100 / (100 + sales_items_taxes.percent)))'; + $sale_tax = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (1 - 100 / (100 + sales_items_taxes.percent)))'; } else { - $tax = '(percent/100)'; - $total = '(1+(percent/100))'; - $subtotal = '1'; + $sale_total = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (1 + (sales_items_taxes.percent / 100)))'; + $sale_subtotal = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100))'; + $sale_tax = '(sales_items.item_unit_price * sales_items.quantity_purchased * (1 - sales_items.discount_percent / 100) * (sales_items_taxes.percent / 100))'; } $decimals = totals_decimals(); - $query = $this->db->query("SELECT percent, count(*) AS count, SUM(subtotal) AS subtotal, SUM(total) AS total, SUM(tax) AS tax + $query = $this->db->query("SELECT percent, count(*) AS count, ROUND(SUM(subtotal), $decimals) AS subtotal, ROUND(SUM(total), $decimals) AS total, ROUND(SUM(tax), $decimals) AS tax FROM ( SELECT - CONCAT(ROUND(percent, $decimals), '%') AS percent, - ROUND((item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent /100) * $subtotal, $decimals) AS subtotal, - ROUND((item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent /100) * $total, $decimals) AS total, - ROUND((item_unit_price * quantity_purchased - item_unit_price * quantity_purchased * discount_percent /100) * $tax, $decimals) AS tax - FROM ".$this->db->dbprefix('sales_items_taxes')." - JOIN ".$this->db->dbprefix('sales_items')." ON " - .$this->db->dbprefix('sales_items').'.sale_id='.$this->db->dbprefix('sales_items_taxes').'.sale_id'." AND " - .$this->db->dbprefix('sales_items').'.item_id='.$this->db->dbprefix('sales_items_taxes').'.item_id'." AND " - .$this->db->dbprefix('sales_items').'.line='.$this->db->dbprefix('sales_items_taxes').'.line'." - JOIN ".$this->db->dbprefix('sales')." ON ".$this->db->dbprefix('sales_items_taxes').".sale_id=".$this->db->dbprefix('sales').".sale_id - WHERE date(sale_time) BETWEEN " . $this->db->escape($inputs['start_date']) . " AND " . $this->db->escape($inputs['end_date']) . " $quantity_cond) AS temp_taxes - GROUP BY percent"); + CONCAT(IFNULL(ROUND(percent, $decimals), 0), '%') AS percent, + $sale_subtotal AS subtotal, + IFNULL($sale_total, $sale_subtotal) AS total, + IFNULL($sale_tax, 0) AS tax + FROM " . $this->db->dbprefix('sales_items') . ' AS sales_items + INNER JOIN ' . $this->db->dbprefix('sales') . ' AS sales + ON sales_items.sale_id = sales.sale_id + LEFT OUTER JOIN ' . $this->db->dbprefix('sales_items_taxes') . ' AS sales_items_taxes + ON 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 + WHERE DATE(sale_time) BETWEEN ' . $this->db->escape($inputs['start_date']) . ' AND ' . $this->db->escape($inputs['end_date']) . " $quantity_cond + ) AS temp_taxes + GROUP BY percent" + ); return $query->result_array(); }