From edbfa79611bccb15d691ece18024afc9aac64295 Mon Sep 17 00:00:00 2001 From: "Pedro M. Baeza" Date: Fri, 3 Jul 2020 17:44:29 +0200 Subject: [PATCH] [FIX] sale_global_discount: Constraint tax lines combinations Not all taxes combinations are possible with global discounts when they are later invoiced and posted, so we need to constraint them early. OCA/account-invoicing#745 addresses the problem at invoice level, posting correctly taxes for supported cases, and constraining the rest. We apply here the same constraints at sales order level. Existing tests have been changed because they were using one of the forbidden taxes combination, and 2 new tests have been added for covering the new constraints. --- sale_global_discount/README.rst | 7 +++ sale_global_discount/__manifest__.py | 2 +- sale_global_discount/i18n/es.po | 12 +++++ .../i18n/sale_global_discount.pot | 12 +++++ sale_global_discount/models/sale_order.py | 35 ++++++++++--- sale_global_discount/readme/ROADMAP.rst | 3 ++ .../static/description/index.html | 29 +++++++---- .../tests/test_sale_global_discount.py | 51 +++++++++++-------- 8 files changed, 113 insertions(+), 38 deletions(-) create mode 100644 sale_global_discount/readme/ROADMAP.rst diff --git a/sale_global_discount/README.rst b/sale_global_discount/README.rst index 7d111259f9c..08389981d06 100644 --- a/sale_global_discount/README.rst +++ b/sale_global_discount/README.rst @@ -64,6 +64,13 @@ To use this module, you need to: #. When you create an invoice from the order, the proper global discounts will be applied on it. +Known issues / Roadmap +====================== + +* Not all the taxes combination can be compatible with global discounts. An + error is raised in that cases. +* Currently, taxes in invoice lines are mandatory with global discounts. + Bug Tracker =========== diff --git a/sale_global_discount/__manifest__.py b/sale_global_discount/__manifest__.py index 7341e88dd76..2f25f62b2bf 100644 --- a/sale_global_discount/__manifest__.py +++ b/sale_global_discount/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { 'name': 'Sale Global Discount', - 'version': '11.0.1.0.2', + 'version': '11.0.1.0.3', 'category': 'Sales Management', 'author': 'Tecnativa,' 'Odoo Community Association (OCA)', diff --git a/sale_global_discount/i18n/es.po b/sale_global_discount/i18n/es.po index a7915602d83..9bba9a4d7ae 100644 --- a/sale_global_discount/i18n/es.po +++ b/sale_global_discount/i18n/es.po @@ -33,6 +33,12 @@ msgstr "Subtl. antes desc." msgid "Amount Untaxed Before Discounts" msgstr "Base Imponible sin Descuentos" +#. module: sale_global_discount +#: code:addons/sale_global_discount/models/sale_order.py:62 +#, python-format +msgid "Incompatible taxes found for global discounts." +msgstr "" + #. module: sale_global_discount #: model:ir.model,name:sale_global_discount.model_sale_order msgid "Quotation" @@ -48,5 +54,11 @@ msgstr "Descuentos de venta globales" msgid "Total Global Discounts" msgstr "Total Descuentos Globales" +#. module: sale_global_discount +#: code:addons/sale_global_discount/models/sale_order.py:55 +#, python-format +msgid "With global discounts, taxes in lines are required." +msgstr "" + #~ msgid "Global Discount" #~ msgstr "Descuento Global" diff --git a/sale_global_discount/i18n/sale_global_discount.pot b/sale_global_discount/i18n/sale_global_discount.pot index a915a589ed2..f676dc0ad84 100644 --- a/sale_global_discount/i18n/sale_global_discount.pot +++ b/sale_global_discount/i18n/sale_global_discount.pot @@ -29,6 +29,12 @@ msgstr "" msgid "Amount Untaxed Before Discounts" msgstr "" +#. module: sale_global_discount +#: code:addons/sale_global_discount/models/sale_order.py:62 +#, python-format +msgid "Incompatible taxes found for global discounts." +msgstr "" + #. module: sale_global_discount #: model:ir.model,name:sale_global_discount.model_sale_order msgid "Quotation" @@ -44,3 +50,9 @@ msgstr "" msgid "Total Global Discounts" msgstr "" +#. module: sale_global_discount +#: code:addons/sale_global_discount/models/sale_order.py:55 +#, python-format +msgid "With global discounts, taxes in lines are required." +msgstr "" + diff --git a/sale_global_discount/models/sale_order.py b/sale_global_discount/models/sale_order.py index 311d94e9186..7d0de34a5cb 100644 --- a/sale_global_discount/models/sale_order.py +++ b/sale_global_discount/models/sale_order.py @@ -1,6 +1,6 @@ # Copyright 2020 Tecnativa - David Vidal # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +from odoo import _, api, exceptions, fields, models class SaleOrder(models.Model): @@ -42,10 +42,34 @@ def get_discounted_global(self, price=0, discounts=None): price *= 1 - (discount / 100) return self.get_discounted_global(price, discounts) + def _check_global_discounts_sanity(self): + """Perform a sanity check for discarding cases that will lead to + incorrect data in discounts. + """ + self.ensure_one() + if not self.global_discount_ids: + return True + taxes_keys = {} + for line in self.order_line: + if not line.tax_id: + raise exceptions.UserError(_( + "With global discounts, taxes in lines are required." + )) + for key in taxes_keys: + if key == line.tax_id: + break + elif key & line.tax_id: + raise exceptions.UserError(_( + "Incompatible taxes found for global discounts." + )) + else: + taxes_keys[line.tax_id] = True + @api.depends('order_line.price_total', 'global_discount_ids') def _amount_all(self): res = super()._amount_all() for order in self: + order._check_global_discounts_sanity() amount_untaxed_before_global_discounts = order.amount_untaxed amount_total_before_global_discounts = order.amount_total discounts = order.global_discount_ids.mapped('discount') @@ -79,11 +103,10 @@ def _amount_all(self): @api.onchange('partner_id') def onchange_partner_id(self): res = super().onchange_partner_id() - if self.partner_id.customer_global_discount_ids: - self.global_discount_ids = ( - self.partner_id.customer_global_discount_ids or - self.partner_id.commercial_partner_id - .customer_global_discount_ids) + self.global_discount_ids = ( + self.partner_id.customer_global_discount_ids or + self.partner_id.commercial_partner_id + .customer_global_discount_ids) return res def _prepare_invoice(self): diff --git a/sale_global_discount/readme/ROADMAP.rst b/sale_global_discount/readme/ROADMAP.rst new file mode 100644 index 00000000000..8e5c2e79bc8 --- /dev/null +++ b/sale_global_discount/readme/ROADMAP.rst @@ -0,0 +1,3 @@ +* Not all the taxes combination can be compatible with global discounts. An + error is raised in that cases. +* Currently, taxes in invoice lines are mandatory with global discounts. diff --git a/sale_global_discount/static/description/index.html b/sale_global_discount/static/description/index.html index 128d08cbfdb..3bc0c5e2046 100644 --- a/sale_global_discount/static/description/index.html +++ b/sale_global_discount/static/description/index.html @@ -375,11 +375,12 @@

Sale Global Discount