mirror of
https://github.com/opensourcepos/opensourcepos.git
synced 2026-04-12 02:48:48 -04:00
Fix wrong tax and subtotal calculation in Summary reports (#976)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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');
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user