diff --git a/account_product_fiscal_classification/models/product_template.py b/account_product_fiscal_classification/models/product_template.py index 350648e3f..af4525650 100644 --- a/account_product_fiscal_classification/models/product_template.py +++ b/account_product_fiscal_classification/models/product_template.py @@ -4,11 +4,13 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import json +import logging from lxml import etree -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) class ProductTemplate(models.Model): @@ -75,15 +77,58 @@ def _update_vals_fiscal_classification(self, vals): } ) elif vals.get("supplier_taxes_id") or vals.get("taxes_id"): - raise ValidationError( - _( - "You can not create or write products with" - " 'Customer Taxes' or 'Supplier Taxes'\n." - "Please, use instead the 'Fiscal Classification' field." - ) - ) + self._find_or_create_classification(vals) return vals @api.constrains("categ_id", "fiscal_classification_id") def _check_rules_fiscal_classification(self): self.env["account.product.fiscal.rule"].check_product_templates_integrity(self) + + def _find_or_create_classification(self, vals): + """Find the correct Fiscal classification, + depending of the taxes, or create a new one, if no one are found.""" + # search for matching classication + domain = [] + purchase_tax_ids = vals.get("supplier_taxes_id") + sale_tax_ids = vals.get("taxes_id") + for elm in ("supplier_taxes_id", "taxes_id"): + if elm in vals: + del vals[elm] + taxe_ids = [] + if sale_tax_ids: + if isinstance(sale_tax_ids, int): + sale_tax_ids = [sale_tax_ids] + domain.append(("sale_tax_ids", "in", sale_tax_ids)) + taxe_ids.extend(sale_tax_ids) + if purchase_tax_ids: + if isinstance(purchase_tax_ids, int): + purchase_tax_ids = [purchase_tax_ids] + domain.append(("purchase_tax_ids", "in", purchase_tax_ids)) + taxe_ids.extend(purchase_tax_ids) + classification = self.env["account.product.fiscal.classification"].search( + domain + ) + if not classification: + # Create a dedicate classification for these taxes combination + classif_vals = { + "name": " ".join( + [x.name for x in self.env["account.tax"].browse(taxe_ids)] + ), + "company_id": vals.get( + "company_id", self.company_id and self.company_id.id or False + ), + } + if purchase_tax_ids: + classif_vals["purchase_tax_ids"] = [ + (6, 0, [x for x in purchase_tax_ids]) + ] + if sale_tax_ids: + classif_vals["sale_tax_ids"] = [(6, 0, [x for x in sale_tax_ids])] + classification = self.env["account.product.fiscal.classification"].create( + classif_vals + ) + _logger.info( + f"Creating new Fiscal Classification '{classif_vals['name']}'" + f" for {self.display_name}" + ) + vals["fiscal_classification_id"] = classification[0].id diff --git a/account_product_fiscal_classification/tests/test_module.py b/account_product_fiscal_classification/tests/test_module.py index d4410a7a9..a49fe7c8d 100644 --- a/account_product_fiscal_classification/tests/test_module.py +++ b/account_product_fiscal_classification/tests/test_module.py @@ -1,7 +1,6 @@ # Copyright (C) 2014-Today GRAP (http://www.grap.coop) # @author: Sylvain LE GAL (https://twitter.com/legalsylvain) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - from odoo.exceptions import ValidationError from odoo.tests.common import TransactionCase @@ -167,6 +166,38 @@ def test_30_rules(self): self.fiscal_classification_B_company_1, ) + def test_no_classification_and_find_one(self): + classif = self.env.ref( + "account_product_fiscal_classification.fiscal_classification_A_company_1" + ) + vals = { + "name": "Test Product", + "company_id": self.env.company.id, + "categ_id": self.category_all.id, + "taxes_id": classif.sale_tax_ids.ids, + "supplier_taxes_id": classif.purchase_tax_ids.ids, + } + product = self.ProductTemplate.with_user(self.env.user).create(vals) + self.assertEqual(product.fiscal_classification_id, classif) + + def test_no_classification_and_create_one(self): + classif_co = self.env["account.product.fiscal.classification"].search_count([]) + my_tax = self.env["account.tax"].create( + {"name": "my_tax", "type_tax_use": "sale", "amount": 9.99} + ) + vals = { + "name": "Test Product", + "company_id": self.env.company.id, + "categ_id": self.category_all.id, + "taxes_id": my_tax.id, + } + product = self.ProductTemplate.with_user(self.env.user).create(vals) + self.assertNotEquals(product.fiscal_classification_id, False) + classif_co_after = self.env[ + "account.product.fiscal.classification" + ].search_count([]) + self.assertEqual(classif_co_after, classif_co + 1) + def _create_product(self, user, category, classification): vals = { "name": "Test Product",