diff options
| author | Mohamed GadAlrab <myah@odoo.com> | 2025-01-28 15:57:39 +0100 |
|---|---|---|
| committer | Mohamed GadAlrab <myah@odoo.com> | 2025-02-06 10:44:05 +0000 |
| commit | 36f3f346744ef82bb76bf7593b2cd071f27570c1 (patch) | |
| tree | 1962cb4a286dd58c04d946865fd2ab2e88757b0e | |
| parent | fa2b3e4700a426ebf4fa11021c0ce92e18c620e2 (diff) | |
[FIX] l10n_es_edi_tbai fix total_amount calculation in TBAI xml.
Steps to reproduce:
-------------------
- In a Spanish company, make sure l10n_es_edi_tbai is installed.
- Create an invoice with one product and add 2 taxes for that line (for example, the 21% goods and the 5.2 ES tax).
- Confirm and send the invoice with TBAI.
- In the TBAI xml you will find the total amount wrong as the base amount was calculated twice, one time for each tax.
Cause:
-----
Since (#180062), the tax details calculation process was reworked.
the total amount is calculated inside a loop with this formula
for values in values_per_grouping_key.values():
total_amount += values['base_amount'] + values['tax_amount']
In case one invoice line has 2 taxes of different tax groups, this code will add the base_amount twice in the total_amount calculation.
Fix
---
Move the base amount addition in a separate loop with a new aggregation (with no grouping) to add the base amount to the total.
opw-4501051
closes odoo/odoo#195561
Signed-off-by: Laurent Smet (las) <las@odoo.com>
| -rw-r--r-- | addons/l10n_es_edi_tbai/models/l10n_es_edi_tbai_document.py | 62 | ||||
| -rw-r--r-- | addons/l10n_es_edi_tbai/tests/test_edi_xml.py | 19 |
2 files changed, 61 insertions, 20 deletions
diff --git a/addons/l10n_es_edi_tbai/models/l10n_es_edi_tbai_document.py b/addons/l10n_es_edi_tbai/models/l10n_es_edi_tbai_document.py index 0b5d773124b..5d60fc0c1e0 100644 --- a/addons/l10n_es_edi_tbai/models/l10n_es_edi_tbai_document.py +++ b/addons/l10n_es_edi_tbai/models/l10n_es_edi_tbai_document.py @@ -530,7 +530,7 @@ class L10nEsEdiTbaiDocument(models.Model): def _get_importe_desglose_es_partner(self, base_lines, is_refund): AccountTax = self.env['account.tax'] - def grouping_function(base_line, tax_data): + def tax_details_info_grouping_function(base_line, tax_data): tax = tax_data['tax'] return { @@ -542,17 +542,9 @@ class L10nEsEdiTbaiDocument(models.Model): 'tax_scope': tax.tax_scope, } - base_lines_aggregated_values = AccountTax._aggregate_base_lines_tax_details(base_lines, grouping_function) + base_lines_aggregated_values = AccountTax._aggregate_base_lines_tax_details(base_lines, tax_details_info_grouping_function) values_per_grouping_key = AccountTax._aggregate_base_lines_aggregated_values(base_lines_aggregated_values) - total_amount = 0.0 - total_retention = 0.0 - for values in values_per_grouping_key.values(): - if values['grouping_key'] and values['grouping_key']['l10n_es_type'] == 'retencion': - total_retention += values['tax_amount'] - else: - total_amount += values['base_amount'] + values['tax_amount'] - tax_details_info = self._build_tax_details_info(values_per_grouping_key.values()) invoice_info = { 'DesgloseFactura': { @@ -561,6 +553,25 @@ class L10nEsEdiTbaiDocument(models.Model): 'S2': tax_details_info['sujeto_isp'], }, } + + total_amount = 0.0 + total_retention = 0.0 + for values in values_per_grouping_key.values(): + if values['grouping_key'] and values['grouping_key']['l10n_es_type'] == 'retencion': + total_retention += values['tax_amount'] + else: + total_amount += values['tax_amount'] + + # Aggregate the base lines again (with no grouping) to add the base amount to the total. + def totals_grouping_function(base_line, tax_data): + return True + + base_lines_aggregated_values = AccountTax._aggregate_base_lines_tax_details(base_lines, totals_grouping_function) + values_per_grouping_key = AccountTax._aggregate_base_lines_aggregated_values(base_lines_aggregated_values) + + for values in values_per_grouping_key.values(): + total_amount += values['base_amount'] + return { 'invoice_info': invoice_info, 'total_amount': total_amount, @@ -571,7 +582,7 @@ class L10nEsEdiTbaiDocument(models.Model): def _get_importe_desglose_foreign_partner(self, base_lines, is_refund): AccountTax = self.env['account.tax'] - def grouping_function(base_line, tax_data): + def tax_details_info_grouping_function(base_line, tax_data): tax = tax_data['tax'] return { @@ -583,17 +594,9 @@ class L10nEsEdiTbaiDocument(models.Model): 'tax_scope': tax.tax_scope, } - base_lines_aggregated_values = AccountTax._aggregate_base_lines_tax_details(base_lines, grouping_function) + base_lines_aggregated_values = AccountTax._aggregate_base_lines_tax_details(base_lines, tax_details_info_grouping_function) values_per_grouping_key = AccountTax._aggregate_base_lines_aggregated_values(base_lines_aggregated_values) - total_amount = 0.0 - total_retention = 0.0 - for values in values_per_grouping_key.values(): - if values['grouping_key'] and values['grouping_key']['l10n_es_type'] == 'retencion': - total_retention += values['tax_amount'] - else: - total_amount += values['base_amount'] + values['tax_amount'] - invoice_info = {} for scope, target_key in (('service', 'PrestacionServicios'), ('consu', 'Entrega')): service_values_list = [ @@ -608,6 +611,25 @@ class L10nEsEdiTbaiDocument(models.Model): 'S1': tax_details_info['sujeto'], 'S2': tax_details_info['sujeto_isp'], } + + total_amount = 0.0 + total_retention = 0.0 + for values in values_per_grouping_key.values(): + if values['grouping_key'] and values['grouping_key']['l10n_es_type'] == 'retencion': + total_retention += values['tax_amount'] + else: + total_amount += values['tax_amount'] + + # Aggregate the base lines again (with no grouping) to add the base amount to the total. + def totals_grouping_function(base_line, tax_data): + return True + + base_lines_aggregated_values = AccountTax._aggregate_base_lines_tax_details(base_lines, totals_grouping_function) + values_per_grouping_key = AccountTax._aggregate_base_lines_aggregated_values(base_lines_aggregated_values) + + for values in values_per_grouping_key.values(): + total_amount += values['base_amount'] + return { 'invoice_info': invoice_info, 'total_amount': total_amount, diff --git a/addons/l10n_es_edi_tbai/tests/test_edi_xml.py b/addons/l10n_es_edi_tbai/tests/test_edi_xml.py index a159a93918c..7bab31853ab 100644 --- a/addons/l10n_es_edi_tbai/tests/test_edi_xml.py +++ b/addons/l10n_es_edi_tbai/tests/test_edi_xml.py @@ -150,6 +150,25 @@ class TestEdiTbaiXmls(TestEsEdiTbaiCommon): xml_expected = self.with_applied_xpath(xml_expected_base, xpath) self.assertXmlTreeEqual(xml_doc, xml_expected) + def test_xml_tree_post_multitax(self): + self.out_invoice.invoice_line_ids.tax_ids = [self._get_tax_by_xml_id('s_req52').id, self._get_tax_by_xml_id('s_iva21b').id] + with freeze_time(self.frozen_today): + edi_document = self.out_invoice._l10n_es_tbai_create_edi_document(cancel=False) + edi_document._generate_xml(self.out_invoice._l10n_es_tbai_get_values(cancel=False)) + xml_doc = edi_document._get_xml() + xml_doc.remove(xml_doc.find("Signature", namespaces=NS_MAP)) + xml_expected_base = etree.fromstring(super()._get_sample_xml('xml_post.xml')) + xpath = """ + <xpath expr="//ImporteTotal" position="replace"> + <ImporteTotal>5048.00000000</ImporteTotal> + </xpath> + <xpath expr="//ImporteTotalFactura" position="replace"> + <ImporteTotalFactura>5048.00</ImporteTotalFactura> + </xpath> + """ + xml_expected = self.with_applied_xpath(xml_expected_base, xpath) + self.assertXmlTreeEqual(xml_doc, xml_expected) + def test_xml_tree_in_post(self): """Test XML of vendor bill for LROE Batuz""" self.company_data['company'].l10n_es_tbai_tax_agency = 'bizkaia' |
