diff --git a/l10n_es_aeat/models/l10n_es_aeat_map_tax_line.py b/l10n_es_aeat/models/l10n_es_aeat_map_tax_line.py index 299f53d46a4..f8a3371bd1c 100644 --- a/l10n_es_aeat/models/l10n_es_aeat_map_tax_line.py +++ b/l10n_es_aeat/models/l10n_es_aeat_map_tax_line.py @@ -56,15 +56,7 @@ class L10nEsAeatMapTaxLine(models.Model): def get_taxes_for_company(self, company): """Obtain the taxes corresponding to this line according the given company.""" self.ensure_one() - tax_obj = self.env["account.tax"] - tax_ids = set() - for tax_xmlid in self.tax_xmlid_ids: - tax_id = company._get_tax_id_from_xmlid(tax_xmlid.name) - if tax_id: - tax_ids.add(tax_id) - return tax_obj.browse(list(tax_ids)) + tax_obj.search( - [("aeat_equivalent_tax_id", "in", list(tax_ids))] - ) + return company._get_taxes_from_xmlids(self.tax_xmlid_ids.mapped("name")) def get_accounts_for_company(self, company): """Obtain the accounts corresponding to the line according the given company.""" diff --git a/l10n_es_aeat/models/res_company.py b/l10n_es_aeat/models/res_company.py index 995dd091c35..17aba1ef5fd 100644 --- a/l10n_es_aeat/models/res_company.py +++ b/l10n_es_aeat/models/res_company.py @@ -39,7 +39,11 @@ def create(self, vals_list): @ormcache("self", "xmlid") def _get_tax_id_from_xmlid(self, xmlid): - """Low level cached search for a tax given its template XML-ID and company.""" + """Low level cached search for a tax given its template XML-ID and company. + + WARNING: It doesn't return equivalent taxes. Call `_get_taxes_from_xmlids` for + that. + """ self.ensure_one() return ( xmlid @@ -60,6 +64,20 @@ def _get_tax_id_from_xmlid(self, xmlid): or False ) + def _get_taxes_from_xmlids(self, xmlids): + """Search for the taxes (direct or equivalent), given the company and the tax + template XML-IDs. + + :returns: Company taxes recordset. + """ + self.ensure_one() + tax_ids = set(self._get_tax_id_from_xmlid(x) for x in xmlids) + if False in tax_ids: # for avoiding that incorrect XML-IDs breaks the rest + tax_ids.remove(False) + tax_obj = self.env["account.tax"] + extra_taxes = tax_obj.search([("aeat_equivalent_tax_id", "in", list(tax_ids))]) + return tax_obj.browse(tax_ids) | extra_taxes + @ormcache("self", "xmlid") def _get_account_id_from_xmlid(self, xmlid): """Low level cached search for a tax given its account template and diff --git a/l10n_es_aeat_mod349/models/account_tax.py b/l10n_es_aeat_mod349/models/account_tax.py index 75f803261b2..35601394ee2 100644 --- a/l10n_es_aeat_mod349/models/account_tax.py +++ b/l10n_es_aeat_mod349/models/account_tax.py @@ -23,16 +23,11 @@ def _selection_operation_key(self): ) def _taxes_without_operation_key(self): - map_349_lines = self.env["aeat.349.map.line"].search([]) # pylint: disable=no-search-all - all_349_taxes_xmlid = map_349_lines.mapped("tax_xmlid_ids") - all_349_taxes = map_349_lines._get_tax_ids_from_xmlids(all_349_taxes_xmlid) - return list( - set( - self.env["account.tax"] - .search([("id", "not in", set(all_349_taxes))]) - .ids - ) - ) + xmlids = self.env["aeat.349.map.line"].search([]).tax_xmlid_ids.mapped("name") # pylint: disable=W8163 + taxes = self.env["account.tax"].search([]) # pylint: disable=W8163 + for company in self.env.companies: + taxes -= company._get_taxes_from_xmlids(xmlids) + return taxes.ids def _search_l10n_es_aeat_349_operation_key(self, operator, value): tax_ids = [] @@ -46,10 +41,11 @@ def _search_l10n_es_aeat_349_operation_key(self, operator, value): [("operation_key", operator, value)] ) if map_349_lines: - taxes_xmlid = map_349_lines.mapped("tax_xmlid_ids") - tax_ids = map_349_lines._get_tax_ids_from_xmlids( - taxes_xmlid, self.env.company - ) + xmlids = map_349_lines.tax_xmlid_ids.mapped("name") + taxes = self.env["account.tax"] + for company in self.env.companies: + taxes |= company._get_taxes_from_xmlids(xmlids) + tax_ids = taxes.ids if is_not_in: tax_ids = list( set( @@ -64,14 +60,8 @@ def _search_l10n_es_aeat_349_operation_key(self, operator, value): return [("id", "in", tax_ids)] def _compute_l10n_es_aeat_349_operation_key(self): - # TODO: Improve performance - map_349 = self.env["aeat.349.map.line"].search([]) # pylint: disable=no-search-all - for tax in self: - tax.l10n_es_aeat_349_operation_key = False - for line in map_349: - taxes_ids = line._get_tax_ids_from_xmlids( - line.tax_xmlid_ids, tax.company_id - ) - if taxes_ids and tax.id in taxes_ids: - tax.l10n_es_aeat_349_operation_key = line.operation_key - break + self.l10n_es_aeat_349_operation_key = False + for company in self.company_id: + for rec in self.env["aeat.349.map.line"].search([]): # pylint: disable=W8163 + taxes = company._get_taxes_from_xmlids(rec.tax_xmlid_ids.mapped("name")) + (self & taxes).l10n_es_aeat_349_operation_key = rec.operation_key diff --git a/l10n_es_aeat_mod349/models/aeat_349_map_line.py b/l10n_es_aeat_mod349/models/aeat_349_map_line.py index 5177a88cd23..16613bbab4c 100644 --- a/l10n_es_aeat_mod349/models/aeat_349_map_line.py +++ b/l10n_es_aeat_mod349/models/aeat_349_map_line.py @@ -2,7 +2,7 @@ # Copyright 2018 Tecnativa - Pedro M. Baeza # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +from odoo import fields, models class Aeat349MapLines(models.Model): @@ -28,17 +28,3 @@ def _selection_operation_key(self): selection=_selection_operation_key, required=True, ) - - @api.model - def _get_tax_ids_from_xmlids(self, tax_templates, company=False): - if not company: - companies = self.env.user.company_ids - else: - companies = company - taxes_ids = [] - for tax_template in tax_templates: - for company in companies: - tax_id = company._get_tax_id_from_xmlid(tax_template.name) - if tax_id: - taxes_ids.append(tax_id) - return taxes_ids diff --git a/l10n_es_aeat_mod349/models/mod349.py b/l10n_es_aeat_mod349/models/mod349.py index 8c226530640..5d8ba0e4e19 100644 --- a/l10n_es_aeat_mod349/models/mod349.py +++ b/l10n_es_aeat_mod349/models/mod349.py @@ -323,14 +323,11 @@ def _account_move_line_domain(self, taxes): @api.model def _get_taxes(self): """Obtain all the taxes to be considered for 349.""" - map_lines = self.env["aeat.349.map.line"].search([]) # pylint: disable=no-search-all - tax_templates = map_lines.mapped("tax_xmlid_ids") + map_lines = self.env["aeat.349.map.line"].search([]) # pylint: disable=W8163 + tax_templates = map_lines.tax_xmlid_ids if not tax_templates: raise exceptions.UserError(self.env._("No Tax Mapping was found")) - taxes_ids = self.env["aeat.349.map.line"]._get_tax_ids_from_xmlids( - tax_templates, self.company_id - ) - return self.env["account.tax"].search([("id", "in", taxes_ids)]) + return self.company_id._get_taxes_from_xmlids(tax_templates.mapped("name")) def _cleanup_report(self): """Remove previous partner records and partner refunds in report.""" diff --git a/l10n_es_aeat_sii_oca/models/account_move.py b/l10n_es_aeat_sii_oca/models/account_move.py index 3530b15b092..590db18d735 100644 --- a/l10n_es_aeat_sii_oca/models/account_move.py +++ b/l10n_es_aeat_sii_oca/models/account_move.py @@ -111,16 +111,14 @@ def _compute_macrodata(self): @api.depends("company_id", "fiscal_position_id", "invoice_line_ids.tax_ids") def _compute_dua_invoice(self): for invoice in self: - taxes = self.env["account.tax"] - for template in [ + xmlids = [ "account_tax_template_p_iva4_ibc_group", "account_tax_template_p_iva10_ibc_group", "account_tax_template_p_iva21_ibc_group", - ]: - tax_id = invoice.company_id._get_tax_id_from_xmlid(template) - taxes |= self.env["account.tax"].browse(tax_id) + ] + taxes = invoice.company_id._get_taxes_from_xmlids(xmlids) invoice.sii_dua_invoice = invoice.line_ids.filtered( - lambda x, taxes=taxes: any([tax in taxes for tax in x.tax_ids]) + lambda x, taxes=taxes: bool(taxes & x.tax_ids) ) def _aeat_get_partner(self): @@ -690,7 +688,7 @@ def _compute_sii_description(self): def _compute_sii_enabled(self): """Compute if the invoice is enabled for the SII""" for invoice in self: - dua_sii_exempt_taxes = invoice._get_dua_sii_exempt_taxes() + dua_taxes = invoice._get_dua_sii_exempt_taxes() if ( invoice.company_id.sii_enabled and invoice.journal_id.sii_enabled @@ -705,11 +703,9 @@ def _compute_sii_enabled(self): or not invoice.fiscal_position_id ) and ( - not dua_sii_exempt_taxes + not dua_taxes or not invoice.invoice_line_ids.filtered( - lambda x, dua_taxes=dua_sii_exempt_taxes: any( - [tax.id in dua_taxes for tax in x.tax_ids] - ) + lambda x, dua_taxes=dua_taxes: bool(dua_taxes & x.tax_ids) ) ) and ( diff --git a/l10n_es_aeat_sii_oca/models/sii_mixin.py b/l10n_es_aeat_sii_oca/models/sii_mixin.py index 2af5cb4b19f..6294003b0a1 100644 --- a/l10n_es_aeat_sii_oca/models/sii_mixin.py +++ b/l10n_es_aeat_sii_oca/models/sii_mixin.py @@ -202,21 +202,13 @@ def _get_aeat_taxes_map(self, codes, date): tax_templates = sii_map.map_lines.filtered( lambda x: x.code in codes ).tax_xmlid_ids - taxes = self.env["account.tax"] - for template in tax_templates: - tax_id = self.company_id._get_tax_id_from_xmlid(template.name) - taxes |= self.env["account.tax"].browse(tax_id) - return taxes + return self.company_id._get_taxes_from_xmlids(tax_templates.mapped("name")) def _get_dua_sii_exempt_taxes(self): self.ensure_one() - taxes = [] - dua_exempt_tax = self.company_id._get_tax_id_from_xmlid( - "account_tax_template_p_dua_exempt" + return self.company_id._get_taxes_from_xmlids( + ["account_tax_template_p_dua_exempt"] ) - if dua_exempt_tax: - taxes.append(dua_exempt_tax) - return taxes def _get_aeat_header(self, tipo_comunicacion=False, cancellation=False): """Builds SII send header diff --git a/l10n_es_aeat_sii_oca/tests/test_l10n_es_aeat_sii.py b/l10n_es_aeat_sii_oca/tests/test_l10n_es_aeat_sii.py index dda794cfd0c..b1f2e3bdbb1 100644 --- a/l10n_es_aeat_sii_oca/tests/test_l10n_es_aeat_sii.py +++ b/l10n_es_aeat_sii_oca/tests/test_l10n_es_aeat_sii.py @@ -51,12 +51,9 @@ def _create_and_test_invoice_sii_dict( vals = [] tax_names = [] for line in lines: - taxes = self.env["account.tax"] - for tax in line[1]: - xml_id = f"account_tax_template_{tax}" - tax_id = self.company._get_tax_id_from_xmlid(xml_id) - taxes += self.env["account.tax"].browse(tax_id) - tax_names.append(tax) + xml_ids = [f"account_tax_template_{x}" for x in line[1]] + taxes = self.company._get_taxes_from_xmlids(xml_ids) + tax_names += line[1] vals.append({"price_unit": line[0], "taxes": taxes}) return self._compare_sii_dict( "sii_{}_{}_dict.json".format(inv_type, "_".join(tax_names)),