From 0c857ef7ac20b5f79b7ee42aa4531f34ca8a1a9e Mon Sep 17 00:00:00 2001 From: Laurent Smet Date: Mon, 17 May 2021 10:08:31 +0000 Subject: [PATCH] [REVERT] sale: Fix fiscal pos. mapping taxes to price included This reverts commit d89562e8fe473692296cb209651beb2ce7a715e4. Since this commit, the taxes mapped by fiscal position wasn't managed by the _fix_tax_included_price_company method anymore. Otherwise, some customizations exist on this method that are no longer called. The 2527940 issue is also due to a remaining bug: the total_excluded price should be divided by the quantity but: - what if the quantity & price_unit are both signed? - what if the number of digits for price_unit and the currency are different? Should we skip the rounding of taxes? Since this commit is not perfect and has a lot of dependencies in others modules, we decided to revert it. Original PR: https://github.com/odoo/odoo/pull/68997 Revert PR: https://github.com/odoo/odoo/pull/70858 closes odoo/odoo#70914 Issue: 2527940 X-original-commit: def7d7bb0231fef38e044803b245c9b990a90216 Signed-off-by: Victor Feyens (vfe) Signed-off-by: Laurent Smet --- addons/sale/models/sale.py | 43 +----- addons/sale/tests/__init__.py | 1 - .../sale/tests/test_sale_fiscal_position.py | 131 ------------------ 3 files changed, 3 insertions(+), 172 deletions(-) delete mode 100644 addons/sale/tests/test_sale_fiscal_position.py diff --git a/addons/sale/models/sale.py b/addons/sale/models/sale.py index c7f57adce10..60bca5a2749 100644 --- a/addons/sale/models/sale.py +++ b/addons/sale/models/sale.py @@ -1637,43 +1637,6 @@ class SaleOrderLine(models.Model): # negative discounts (= surcharge) are included in the display price return max(base_price, final_price) - def _get_default_price_unit_from_product(self, product): - self.ensure_one() - - currency = self.order_id.currency_id - fiscal_position = self.order_id.fiscal_position_id or self.order_id.partner_id.property_account_position_id - product_taxes = self.product_id.taxes_id.filtered(lambda r: r.company_id == self.order_id.company_id) - product_taxes_after_fp = fiscal_position.map_tax(product_taxes, partner=self.order_id.partner_id) - price_unit = self._get_display_price(product) - - if set(product_taxes.ids) != set(product_taxes_after_fp.ids): - flattened_taxes = product_taxes._origin.flatten_taxes_hierarchy() - if any(tax.price_include for tax in flattened_taxes): - taxes_res = flattened_taxes.compute_all( - price_unit, - quantity=self.product_uom_qty, - currency=currency, - product=self.product_id, - partner=self.order_id.partner_id, - ) - price_unit = currency.round(taxes_res['total_excluded']) - - flattened_taxes = product_taxes_after_fp._origin.flatten_taxes_hierarchy() - if any(tax.price_include for tax in flattened_taxes): - taxes_res = flattened_taxes.compute_all( - price_unit, - quantity=self.product_uom_qty, - currency=currency, - product=self.product_id, - partner=self.order_id.partner_id, - handle_price_include=False, - ) - for tax_res in taxes_res['taxes']: - tax = self.env['account.tax'].browse(tax_res['id']) - if tax.price_include: - price_unit += tax_res['amount'] - return price_unit - @api.onchange('product_id') def product_id_change(self): if not self.product_id: @@ -1702,13 +1665,13 @@ class SaleOrderLine(models.Model): pricelist=self.order_id.pricelist_id.id, uom=self.product_uom.id ) + vals.update(name=self.get_sale_order_line_multiline_description_sale(product)) self._compute_tax_id() if self.order_id.pricelist_id and self.order_id.partner_id: - vals['price_unit'] = self._get_default_price_unit_from_product(product) - + vals['price_unit'] = self.env['account.tax']._fix_tax_included_price_company(self._get_display_price(product), product.taxes_id, self.tax_id, self.company_id) self.update(vals) title = False @@ -1741,7 +1704,7 @@ class SaleOrderLine(models.Model): uom=self.product_uom.id, fiscal_position=self.env.context.get('fiscal_position') ) - self.price_unit = self._get_default_price_unit_from_product(product) + self.price_unit = self.env['account.tax']._fix_tax_included_price_company(self._get_display_price(product), product.taxes_id, self.tax_id, self.company_id) def name_get(self): result = [] diff --git a/addons/sale/tests/__init__.py b/addons/sale/tests/__init__.py index eae9a15c3bd..5407beaa852 100644 --- a/addons/sale/tests/__init__.py +++ b/addons/sale/tests/__init__.py @@ -12,4 +12,3 @@ from . import test_access_rights from . import test_sale_refund from . import test_sale_signature from . import test_sale_flow -from . import test_sale_fiscal_position diff --git a/addons/sale/tests/test_sale_fiscal_position.py b/addons/sale/tests/test_sale_fiscal_position.py deleted file mode 100644 index 2bc1e8c5126..00000000000 --- a/addons/sale/tests/test_sale_fiscal_position.py +++ /dev/null @@ -1,131 +0,0 @@ -# -*- coding: utf-8 -*- -from odoo import fields -from odoo.addons.account.tests.common import AccountTestInvoicingCommon -from odoo.tests import tagged -from odoo.tests.common import Form - - -@tagged('post_install', '-at_install') -class TestSaleFiscalPosition(AccountTestInvoicingCommon): - - def test_fiscal_pos_taxes_mapping_price_included_to_price_excluded(self): - ''' Test mapping a price-included tax (10%) with a price-excluded tax (20%) on a price_unit of 110.0. - The price_unit should be 100.0 after applying the fiscal position. - ''' - tax_price_include = self.env['account.tax'].create({ - 'name': '10% incl', - 'type_tax_use': 'sale', - 'amount_type': 'percent', - 'amount': 10, - 'price_include': True, - 'include_base_amount': True, - }) - tax_price_exclude = self.env['account.tax'].create({ - 'name': '15% excl', - 'type_tax_use': 'sale', - 'amount_type': 'percent', - 'amount': 15, - }) - - fiscal_position = self.env['account.fiscal.position'].create({ - 'name': 'fiscal_pos_a', - 'tax_ids': [ - (0, None, { - 'tax_src_id': tax_price_include.id, - 'tax_dest_id': tax_price_exclude.id, - }), - ], - }) - - product = self.env['product.product'].create({ - 'name': 'product', - 'uom_id': self.env.ref('uom.product_uom_unit').id, - 'lst_price': 110.0, - 'taxes_id': [(6, 0, tax_price_include.ids)], - }) - - so_form = Form(self.env['sale.order']) - so_form.partner_id = self.partner_a - so_form.date_order = fields.Date.from_string('2019-01-01') - so_form.fiscal_position_id = fiscal_position - so_form.pricelist_id = self.env.ref('product.list0') - with so_form.order_line.new() as line: - line.product_id = product - so = so_form.save() - - self.assertRecordValues(so.order_line, [{ - 'price_unit': 100.0, - 'tax_id': tax_price_exclude.ids, - }]) - - uom_dozen = self.env.ref('uom.product_uom_dozen') - with Form(so) as so_form: - with so_form.order_line.edit(0) as line_form: - line_form.product_uom = uom_dozen - - self.assertRecordValues(so.order_line, [{ - 'price_unit': 1200.0, - 'tax_id': tax_price_exclude.ids, - }]) - - def test_fiscal_pos_taxes_mapping_price_included_to_price_included(self): - ''' Test mapping a price-included tax (10%) with another price-included tax (20%) on a price_unit of 110.0. - The price_unit should be 120.0 after applying the fiscal position. - ''' - tax_price_include_1 = self.env['account.tax'].create({ - 'name': '10% incl', - 'type_tax_use': 'sale', - 'amount_type': 'percent', - 'amount': 10, - 'price_include': True, - 'include_base_amount': True, - }) - tax_price_include_2 = self.env['account.tax'].create({ - 'name': '20% incl', - 'type_tax_use': 'sale', - 'amount_type': 'percent', - 'amount': 20, - 'price_include': True, - 'include_base_amount': True, - }) - - fiscal_position = self.env['account.fiscal.position'].create({ - 'name': 'fiscal_pos_a', - 'tax_ids': [ - (0, None, { - 'tax_src_id': tax_price_include_1.id, - 'tax_dest_id': tax_price_include_2.id, - }), - ], - }) - - product = self.env['product.product'].create({ - 'name': 'product', - 'uom_id': self.env.ref('uom.product_uom_unit').id, - 'lst_price': 110.0, - 'taxes_id': [(6, 0, tax_price_include_1.ids)], - }) - - so_form = Form(self.env['sale.order']) - so_form.partner_id = self.partner_a - so_form.date_order = fields.Date.from_string('2019-01-01') - so_form.fiscal_position_id = fiscal_position - so_form.pricelist_id = self.env.ref('product.list0') - with so_form.order_line.new() as line: - line.product_id = product - so = so_form.save() - - self.assertRecordValues(so.order_line, [{ - 'price_unit': 120.0, - 'tax_id': tax_price_include_2.ids, - }]) - - uom_dozen = self.env.ref('uom.product_uom_dozen') - with Form(so) as so_form: - with so_form.order_line.edit(0) as line_form: - line_form.product_uom = uom_dozen - - self.assertRecordValues(so.order_line, [{ - 'price_unit': 1440.0, - 'tax_id': tax_price_include_2.ids, - }])