From e3b22264d85aba157483dcf637bcc99fb1660a32 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Mon, 8 Jun 2020 16:32:37 +0000 Subject: [PATCH] [FIX] point_of_sale: mix of sale and refund - Set rounding policy to 'Round Globally' - Create a Tax T Amount: 21.0% Different tax tags for invoice and credit notes Set any account Repartition Line Advanced Options => Included in Price - Create a Product P1 Sales Price: 11.8 Customer Taxes: T - Create a Product P2 Sales Price: 15.3 Customer Taxes: T - Create a new POS Session - Create a POS order: P1, Quantity: -6, Discount: 5% P2, Quantity: 6, Discount: 5% - Validate and close the session A difference of 0.01 prevents from closing the session. The error arises because the tax tags are different for an invoice and a refund. In the following: https://github.com/odoo/odoo/blob/1a9e147639012cc847099e69fc964f3669a36cbb/addons/point_of_sale/models/pos_session.py#L394 Both lines have different `tag_ids`, therefore their amount is not summed when closing the session. On the other hand, the POS UI is not aware of the `tag_ids`, so it sums then round the amounts. The situation is quite unusual: from SO or Invoices, it is possible to create either an invoice or a refund, but not a mixed object as the POS is doing. Moreover, if a user invoices the POS order, there is no problem to close the session since a regular invoice is created and tax amounts are summed. We consider a refund if all lines have negative quantities. We only do it in 'Round Globally' configuration to avoid impacting non-problematic use cases. opw-2254211 closes odoo/odoo#52704 X-original-commit: 5f25be8eef9a9efc18a995f2c6405d08a657ac96 Signed-off-by: Nicolas Martinelli (nim) --- addons/point_of_sale/models/pos_session.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/addons/point_of_sale/models/pos_session.py b/addons/point_of_sale/models/pos_session.py index c96a445164e..ff0b8ca215c 100644 --- a/addons/point_of_sale/models/pos_session.py +++ b/addons/point_of_sale/models/pos_session.py @@ -680,7 +680,14 @@ class PosSession(models.Model): .filtered(lambda t: t.company_id.id == order_line.order_id.company_id.id) sign = -1 if order_line.qty >= 0 else 1 price = sign * order_line.price_unit * (1 - (order_line.discount or 0.0) / 100.0) - taxes = tax_ids.compute_all(price_unit=price, quantity=abs(order_line.qty), currency=self.currency_id, is_refund=order_line.qty<0).get('taxes', []) + # The 'is_refund' parameter is used to compute the tax tags. Ultimately, the tags are part + # of the key used for summing taxes. Since the POS UI doesn't support the tags, inconsistencies + # may arise in 'Round Globally'. + if self.company_id.tax_calculation_rounding_method == 'round_globally': + is_refund = all(line.qty < 0 for line in order_line.order_id.lines) + else: + is_refund = order_line.qty < 0 + taxes = tax_ids.compute_all(price_unit=price, quantity=abs(order_line.qty), currency=self.currency_id, is_refund=is_refund).get('taxes', []) date_order = order_line.order_id.date_order taxes = [{'date_order': date_order, **tax} for tax in taxes] return {