[FIX] point_of_sale: correct computation of product total with discount
Before this commit, if a product had a discount applied in two different orders, it could lead to incorrect calculations in the report For instance, if a product priced at 14.45 had a 30% discount applied, the discounted value would be 10.115, which rounds to 10.12. However, if there were two orders with the same discount, the report calculation would count the quantity of a product with the same discount and calculate the product total amount in one place. This would result in a discounted value of 10.115 * 2 = 20.23, while in the two different orders we had two 10.12 which sums to 20.24. With this commit, the calculation method has been changed. Now, the product amount total for each line is calculated first, and then the sum of these amounts is used to calculate the total for all of the orders. This change ensures accurate computation of the product total sum when discounts are applied across multiple orders. opw-3721376 closes odoo/odoo#156160 X-original-commit: bb71f77e117a8a07c1e161f583d136cd5c16a078 Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com> Signed-off-by: Pedram Bi Ria (pebr) <pebr@odoo.com>
This commit is contained in:
@@ -198,8 +198,9 @@ class ReportSaleDetails(models.AbstractModel):
|
||||
'quantity': qty,
|
||||
'price_unit': price_unit,
|
||||
'discount': discount,
|
||||
'uom': product.uom_id.name
|
||||
} for (product, price_unit, discount), qty in product_list.items()], key=lambda l: l['product_name']),
|
||||
'uom': product.uom_id.name,
|
||||
'total_paid': product_total
|
||||
} for (product, price_unit, discount), (qty, product_total) in product_list.items()], key=lambda l: l['product_name']),
|
||||
}
|
||||
products.append(category_dictionnary)
|
||||
products = sorted(products, key=lambda l: str(l['name']))
|
||||
@@ -214,8 +215,9 @@ class ReportSaleDetails(models.AbstractModel):
|
||||
'quantity': qty,
|
||||
'price_unit': price_unit,
|
||||
'discount': discount,
|
||||
'uom': product.uom_id.name
|
||||
} for (product, price_unit, discount), qty in product_list.items()], key=lambda l: l['product_name']),
|
||||
'uom': product.uom_id.name,
|
||||
'total_paid': product_total
|
||||
} for (product, price_unit, discount), (qty, product_total) in product_list.items()], key=lambda l: l['product_name']),
|
||||
}
|
||||
refund_products.append(category_dictionnary)
|
||||
refund_products = sorted(refund_products, key=lambda l: str(l['name']))
|
||||
@@ -287,8 +289,9 @@ class ReportSaleDetails(models.AbstractModel):
|
||||
keys1 = line.product_id.product_tmpl_id.pos_categ_ids.mapped("name") or [_('Not Categorized')]
|
||||
for key1 in keys1:
|
||||
products.setdefault(key1, {})
|
||||
products[key1].setdefault(key2, 0.0)
|
||||
products[key1][key2] += line.qty
|
||||
products[key1].setdefault(key2, [0.0, 0.0])
|
||||
products[key1][key2][0] += line.qty
|
||||
products[key1][key2][1] += line.currency_id.round(line.price_unit * line.qty * (100 - line.discount) / 100.0)
|
||||
|
||||
if line.tax_ids_after_fiscal_position:
|
||||
line_taxes = line.tax_ids_after_fiscal_position.sudo().compute_all(line.price_unit * (1-(line.discount or 0.0)/100.0), currency, line.qty, product=line.product_id, partner=line.order_id.partner_id or False)
|
||||
@@ -309,20 +312,18 @@ class ReportSaleDetails(models.AbstractModel):
|
||||
def _get_total_and_qty_per_category(self, categories):
|
||||
all_qty = 0
|
||||
all_total = 0
|
||||
total = lambda product: (product['quantity'] * product['price_unit']) * (100 - product['discount']) / 100
|
||||
for category_dict in categories:
|
||||
qty_cat = 0
|
||||
total_cat = 0
|
||||
for product in category_dict['products']:
|
||||
qty_cat += product['quantity']
|
||||
product['total_paid'] = total(product)
|
||||
total_cat += product['total_paid']
|
||||
category_dict['total'] = total_cat
|
||||
category_dict['qty'] = qty_cat
|
||||
# IMPROVEMENT: It would be better if the `products` are grouped by pos.order.line.id.
|
||||
unique_products = list({tuple(sorted(product.items())): product for category in categories for product in category['products']}.values())
|
||||
all_qty = sum([product['quantity'] for product in unique_products])
|
||||
all_total = sum([total(product) for product in unique_products])
|
||||
all_total = sum([product['total_paid'] for product in unique_products])
|
||||
|
||||
return categories, {'total': all_total, 'qty': all_qty}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user