From d965c8a93ebc9deb662976e144571076a2529bf3 Mon Sep 17 00:00:00 2001 From: manu Date: Thu, 16 May 2024 12:24:08 +0200 Subject: [PATCH] [MIG] l10n_es_vat_prorate: Migration to 17.0 --- l10n_es_vat_prorate/README.rst | 10 +- l10n_es_vat_prorate/__manifest__.py | 3 +- .../data/account_template_tax.xml | 239 ------------------ l10n_es_vat_prorate/models/__init__.py | 1 + l10n_es_vat_prorate/models/account_tax.py | 102 ++------ l10n_es_vat_prorate/models/prorate_taxes.py | 83 ++++++ l10n_es_vat_prorate/models/res_company.py | 19 ++ l10n_es_vat_prorate/readme/CONFIGURE.md | 6 +- l10n_es_vat_prorate/readme/CONTRIBUTORS.md | 2 + .../static/description/index.html | 10 +- l10n_es_vat_prorate/tests/test_prorate_sii.py | 9 +- l10n_es_vat_prorate/tests/test_vat_prorate.py | 17 +- .../views/account_tax_views.xml | 4 +- .../views/res_company_views.xml | 2 +- 14 files changed, 170 insertions(+), 337 deletions(-) delete mode 100644 l10n_es_vat_prorate/data/account_template_tax.xml create mode 100644 l10n_es_vat_prorate/models/prorate_taxes.py diff --git a/l10n_es_vat_prorate/README.rst b/l10n_es_vat_prorate/README.rst index b50d178fef7..633eb29d1df 100644 --- a/l10n_es_vat_prorate/README.rst +++ b/l10n_es_vat_prorate/README.rst @@ -39,10 +39,10 @@ Configuration ============= - Accede a la companía y marca que aplica prorrata -- Define el porcentaje de prorata (se aplica por fechas) +- Define el porcentaje de prorrata (se aplica por fechas) -Los impuestos de las facturas de cliente se dividiran según la prorata -activa. +Los impuestos de las facturas de proveedor se dividirán según la +prorrata activa. Known issues / Roadmap ====================== @@ -77,6 +77,10 @@ Contributors - Pedro M. Baeza - Carolina Fernandez +- `Sygel `__: + + - Manuel Regidor + Maintainers ----------- diff --git a/l10n_es_vat_prorate/__manifest__.py b/l10n_es_vat_prorate/__manifest__.py index c940f7393de..2ee7ec26dea 100644 --- a/l10n_es_vat_prorate/__manifest__.py +++ b/l10n_es_vat_prorate/__manifest__.py @@ -5,14 +5,13 @@ { "name": "Prorrata de IVA", "summary": "Prorrata de IVA para la localización española", - "version": "16.0.1.0.1", + "version": "17.0.1.0.0", "license": "AGPL-3", "author": "Creu Blanca, Tecnativa, Odoo Community Association (OCA)", "website": "https://github.com/OCA/l10n-spain", "depends": ["l10n_es_aeat"], "data": [ "security/ir.model.access.csv", - "data/account_template_tax.xml", "views/account_move_views.xml", "views/account_tax_views.xml", "views/res_company_prorate_views.xml", diff --git a/l10n_es_vat_prorate/data/account_template_tax.xml b/l10n_es_vat_prorate/data/account_template_tax.xml deleted file mode 100644 index 8ab3baece54..00000000000 --- a/l10n_es_vat_prorate/data/account_template_tax.xml +++ /dev/null @@ -1,239 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/l10n_es_vat_prorate/models/__init__.py b/l10n_es_vat_prorate/models/__init__.py index a37d73d1137..99a3f5fb2f8 100644 --- a/l10n_es_vat_prorate/models/__init__.py +++ b/l10n_es_vat_prorate/models/__init__.py @@ -1,3 +1,4 @@ from . import res_company from . import account_move from . import account_tax +from . import prorate_taxes diff --git a/l10n_es_vat_prorate/models/account_tax.py b/l10n_es_vat_prorate/models/account_tax.py index 92369d2b8bf..ca806dbcc9d 100644 --- a/l10n_es_vat_prorate/models/account_tax.py +++ b/l10n_es_vat_prorate/models/account_tax.py @@ -1,9 +1,12 @@ # Copyright 2022 Creu Blanca # Copyright 2023 Tecnativa - Pedro M. Baeza +# Copyright 2024 Sygel - Manuel Regidor # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + from odoo import api, fields, models -from odoo.tools import ormcache + +from .prorate_taxes import PRORATE_TAXES class AccountTax(models.Model): @@ -27,83 +30,22 @@ class AccountTax(models.Model): @api.depends("company_id.with_vat_prorate") def _compute_with_vat_prorate(self): for tax in self: - if tax.company_id.with_vat_prorate: - tax_template_ids = self.env[ - "account.tax.template" - ]._get_vat_prorate_template_xmlids() - xmlids = self.env["ir.model.data"].search_read( - [("model", "=", tax._name), ("res_id", "=", tax.id)], - ["name", "module"], - limit=1, + with_vat_prorate = False + prorate_account_ids = [] + if tax.company_with_vat_prorate and tax.get_external_id().get(tax.id): + xml_id = ( + tax.get_external_id() + .get(tax.id) + .split(f"account.{tax.company_id.id}_")[-1] ) - if xmlids: - xmlid = xmlids[0] - tax_ref = "{}.{}".format( - xmlid["module"], xmlid["name"].split("_", 1)[1] - ) - with_vat_prorate = tax_ref in tax_template_ids - prorate_account_ids = [(5, 0, 0)] - if with_vat_prorate: - tax_template = self.env.ref(tax_ref) - for ( - template_account - ) in tax_template.prorate_account_template_ids: - template_account_xmlids = self.env[ - "ir.model.data" - ].search_read( - [ - ("model", "=", template_account._name), - ("res_id", "=", template_account.id), - ], - ["name", "module"], - limit=1, - ) - if template_account_xmlids: - account = self.env.ref( - "{}.{}_{}".format( - template_account_xmlids[0]["module"], - tax.company_id.id, - template_account_xmlids[0]["name"], - ), - raise_if_not_found=False, - ) - if account: - prorate_account_ids.append((4, account.id)) - - tax.with_vat_prorate = with_vat_prorate - tax.prorate_account_ids = prorate_account_ids - continue - tax.with_vat_prorate = False - tax.prorate_account_ids = False - - -class AccountTaxTemplate(models.Model): - _inherit = "account.tax.template" - - template_with_vat_prorate = fields.Boolean() - - prorate_account_template_ids = fields.Many2many("account.account.template") - # Name must be different that the account.tax field in order to make it - # compatible with account_chart_update - - @ormcache() - def _get_vat_prorate_template_xmlids(self): - templates = self.env["account.tax.template"].search( - [("template_with_vat_prorate", "=", True)] - ) - data = templates._get_external_ids() - result = [] - for key in data: - result += data[key] - return result - - @api.model_create_multi - def create(self, vals_list): - result = super().create(vals_list) - self.clear_caches() - return result - - def write(self, vals): - result = super().write(vals) - self.clear_caches() - return result + if xml_id in PRORATE_TAXES: + with_vat_prorate = True + if PRORATE_TAXES.get(xml_id).get("prorate_account_template_ids"): + prorate_taxes = self.company_id._get_prorate_accounts() + prorate_account_ids = [(5, 0, 0)] + for account_from_tmpl_id in prorate_taxes.get(xml_id).get( + "prorate_account_ids" + ): + prorate_account_ids.append((4, account_from_tmpl_id)) + tax.with_vat_prorate = with_vat_prorate + tax.prorate_account_ids = prorate_account_ids diff --git a/l10n_es_vat_prorate/models/prorate_taxes.py b/l10n_es_vat_prorate/models/prorate_taxes.py new file mode 100644 index 00000000000..a1d71a7d67b --- /dev/null +++ b/l10n_es_vat_prorate/models/prorate_taxes.py @@ -0,0 +1,83 @@ +PRORATE_TAXES = { + "account_tax_template_p_iva21_bc": {}, + "account_tax_template_p_iva21_sc": {}, + "account_tax_template_p_iva4_bi": {}, + "account_tax_template_p_iva4_sc": {}, + "account_tax_template_p_iva21_bi": {}, + "account_tax_template_p_iva10_bc": {}, + "account_tax_template_p_iva4_bc": {}, + "account_tax_template_p_iva10_sc": {}, + "account_tax_template_p_iva105_gan": {}, + "account_tax_template_p_iva10_bi": {}, + "account_tax_template_p_iva12_agr": {}, + "account_tax_template_p_iva4_ibc": {}, + "account_tax_template_p_iva21_ibc": {}, + "account_tax_template_p_iva21_ibi": {}, + "account_tax_template_p_iva4_ibi": {}, + "account_tax_template_p_iva10_ibc": {}, + "account_tax_template_p_iva10_ibi": {}, + "account_tax_template_p_iva21_sp_in": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva21_ic_bc": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva21_ic_bi": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva4_sp_ex": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva10_sp_ex": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva21_sp_ex": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva4_ic_bc": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva4_ic_bi": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva10_ic_bc": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva10_ic_bi": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva5_ic_bc": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva5_ic_sc": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva5_ibc": {}, + "account_tax_template_p_iva5_isc": {}, + "account_tax_template_p_iva5_bc": {}, + "account_tax_template_p_iva5_sc": {}, + "account_tax_template_p_iva10_sp_in": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva4_sp_in": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva4_isp": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva10_isp": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva21_isp": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva4_isp_bi": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva10_isp_bi": { + "prorate_account_template_ids": ["account_common_472"], + }, + "account_tax_template_p_iva21_isp_bi": { + "prorate_account_template_ids": ["account_common_472"], + }, +} diff --git a/l10n_es_vat_prorate/models/res_company.py b/l10n_es_vat_prorate/models/res_company.py index a695efa4629..b40b177b1a8 100644 --- a/l10n_es_vat_prorate/models/res_company.py +++ b/l10n_es_vat_prorate/models/res_company.py @@ -4,6 +4,9 @@ from odoo import _, api, fields, models from odoo.exceptions import ValidationError +from odoo.tools import ormcache + +from .prorate_taxes import PRORATE_TAXES class ResCompany(models.Model): @@ -14,6 +17,22 @@ class ResCompany(models.Model): "res.company.vat.prorate", inverse_name="company_id" ) + @ormcache("self") + def _get_prorate_accounts(self): + prorate_taxes_mapping = {} + for tax_tmpl in PRORATE_TAXES: + if PRORATE_TAXES.get(tax_tmpl).get("prorate_account_template_ids"): + prorate_account_ids = [] + vals = PRORATE_TAXES.get(tax_tmpl) + for account_tmpl in vals.get("prorate_account_template_ids"): + account_from_tmpl_id = self._get_account_id_from_xmlid(account_tmpl) + if account_from_tmpl_id: + prorate_account_ids.append(account_from_tmpl_id) + prorate_taxes_mapping[tax_tmpl] = { + "prorate_account_ids": prorate_account_ids, + } + return prorate_taxes_mapping + def get_prorate(self, date): self.ensure_one() prorate = self.env["res.company.vat.prorate"].search( diff --git a/l10n_es_vat_prorate/readme/CONFIGURE.md b/l10n_es_vat_prorate/readme/CONFIGURE.md index c84d9b1a2eb..26a53191fb9 100644 --- a/l10n_es_vat_prorate/readme/CONFIGURE.md +++ b/l10n_es_vat_prorate/readme/CONFIGURE.md @@ -1,5 +1,5 @@ - Accede a la companía y marca que aplica prorrata -- Define el porcentaje de prorata (se aplica por fechas) +- Define el porcentaje de prorrata (se aplica por fechas) -Los impuestos de las facturas de cliente se dividiran según la prorata -activa. +Los impuestos de las facturas de proveedor se dividirán según la +prorrata activa. diff --git a/l10n_es_vat_prorate/readme/CONTRIBUTORS.md b/l10n_es_vat_prorate/readme/CONTRIBUTORS.md index 13cdbfe389b..239e35d9272 100644 --- a/l10n_es_vat_prorate/readme/CONTRIBUTORS.md +++ b/l10n_es_vat_prorate/readme/CONTRIBUTORS.md @@ -2,3 +2,5 @@ - [Tecnativa](https://www.tecnativa.com/): - Pedro M. Baeza - Carolina Fernandez +- [Sygel](https://www.sygel.es/): + - Manuel Regidor diff --git a/l10n_es_vat_prorate/static/description/index.html b/l10n_es_vat_prorate/static/description/index.html index b2f4b1f02f4..6a61d657595 100644 --- a/l10n_es_vat_prorate/static/description/index.html +++ b/l10n_es_vat_prorate/static/description/index.html @@ -388,10 +388,10 @@

Prorrata de IVA

Configuration

-

Los impuestos de las facturas de cliente se dividiran según la prorata -activa.

+

Los impuestos de las facturas de proveedor se dividirán según la +prorrata activa.

Known issues / Roadmap

@@ -425,6 +425,10 @@

Contributors

  • Carolina Fernandez
  • +
  • Sygel:
      +
    • Manuel Regidor
    • +
    +
  • diff --git a/l10n_es_vat_prorate/tests/test_prorate_sii.py b/l10n_es_vat_prorate/tests/test_prorate_sii.py index b9bf1d2b91d..28c5d19dc8b 100644 --- a/l10n_es_vat_prorate/tests/test_prorate_sii.py +++ b/l10n_es_vat_prorate/tests/test_prorate_sii.py @@ -2,11 +2,16 @@ from odoo.tests.common import tagged -from odoo.addons.l10n_es_aeat_sii_oca.tests import test_l10n_es_aeat_sii +try: + from odoo.addons.l10n_es_aeat_sii_oca.tests.test_l10n_es_aeat_sii import ( + TestL10nEsAeatSiiBase, + ) +except ImportError: + TestL10nEsAeatSiiBase = object @tagged("-at_install", "post_install") -class TestSIIVatProrate(test_l10n_es_aeat_sii.TestL10nEsAeatSiiBase): +class TestSIIVatProrate(TestL10nEsAeatSiiBase): @classmethod def setUpClass(cls): try: diff --git a/l10n_es_vat_prorate/tests/test_vat_prorate.py b/l10n_es_vat_prorate/tests/test_vat_prorate.py index f094a6a2404..85b15e434fc 100644 --- a/l10n_es_vat_prorate/tests/test_vat_prorate.py +++ b/l10n_es_vat_prorate/tests/test_vat_prorate.py @@ -18,7 +18,7 @@ class TestVatProrate(AccountTestInvoicingCommon): @classmethod def setUpClass(cls): - super().setUpClass(chart_template_ref="l10n_es.account_chart_template_pymes") + super().setUpClass(chart_template_ref="es_pymes") cls.env = cls.env( context=dict( cls.env.context, @@ -56,10 +56,12 @@ def setUpClass(cls): # gets incoherent after returning from the SQL constraint violation @mute_logger("odoo.sql_db") def test_zzz_company_vat_prorate_out_of_range(self): + vat_prorate_line = self.env.company.vat_prorate_ids[0] with self.assertRaises(IntegrityError): - self.env.company.vat_prorate_ids[0].vat_prorate = 200 + vat_prorate_line.vat_prorate = 200 def test_no_company_vat_prorate_information(self): + self.assertTrue(self.env.company.vat_prorate_ids) with self.assertRaises(exceptions.ValidationError): self.env.company.write({"vat_prorate_ids": False}) @@ -91,6 +93,17 @@ def test_prorate_different_accounts_in_invoice(self): ), ) + def test_prorate_tax_with_prorate_account(self): + # 21% EU S (Services) tax + tax = self.env.ref( + f"account.{self.env.company.id}_account_tax_template_p_iva21_sp_in" + ) + invoice = self.init_invoice( + "in_invoice", products=[self.product_a, self.product_b], taxes=[tax] + ) + self.assertEqual(7, len(invoice.line_ids)) + self.assertEqual(4, len(invoice.line_ids.filtered(lambda r: r.tax_line_id))) + def test_prorate_same_accounts_in_invoice(self): self.product_b.property_account_expense_id = self.company_data[ "default_account_expense" diff --git a/l10n_es_vat_prorate/views/account_tax_views.xml b/l10n_es_vat_prorate/views/account_tax_views.xml index 16c390f0ce0..2f28d3b246f 100644 --- a/l10n_es_vat_prorate/views/account_tax_views.xml +++ b/l10n_es_vat_prorate/views/account_tax_views.xml @@ -10,13 +10,13 @@ diff --git a/l10n_es_vat_prorate/views/res_company_views.xml b/l10n_es_vat_prorate/views/res_company_views.xml index 95279225cec..52864431687 100644 --- a/l10n_es_vat_prorate/views/res_company_views.xml +++ b/l10n_es_vat_prorate/views/res_company_views.xml @@ -11,7 +11,7 @@