From 807ca26d0afdc25769235febd88975c5daa29fe7 Mon Sep 17 00:00:00 2001 From: Laurent Smet Date: Fri, 14 Jan 2022 14:13:16 +0000 Subject: [PATCH] [FIX] l10n_be_edi: Fix wrong anchor for AdditionalDocumentReference (E-FFF EDI) AdditionalDocumentReference is currently injected right after DocumentCurrencyCode. However, in 15.0, OrderReference is implemented and then, AdditionalDocumentReference is no longer injected at the right place. To fix this, we inject now this field just before AccountingSupplierReference that must be always there and Signature is not implemented. For more details, see: http://www.datypic.com/sc/ubl20/e-ns19_Invoice.html closes odoo/odoo#82897 X-original-commit: ce4d52fbbf400d911901e09d562e06984447639a Signed-off-by: Florian Gilbert Signed-off-by: Laurent Smet --- .../l10n_be_edi/models/ir_actions_report.py | 7 +- addons/l10n_be_edi/tests/__init__.py | 1 + addons/l10n_be_edi/tests/test_efff_export.py | 182 ++++++++++++++++++ 3 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 addons/l10n_be_edi/tests/test_efff_export.py diff --git a/addons/l10n_be_edi/models/ir_actions_report.py b/addons/l10n_be_edi/models/ir_actions_report.py index 0ba1ce4cbea..da85872ef5c 100644 --- a/addons/l10n_be_edi/models/ir_actions_report.py +++ b/addons/l10n_be_edi/models/ir_actions_report.py @@ -21,9 +21,9 @@ class IrActionsReport(models.Model): if edi_attachment: old_xml = base64.b64decode(edi_attachment.with_context(bin_size=False).datas, validate=True) tree = etree.fromstring(old_xml) - document_currency_code_elements = tree.xpath("//*[local-name()='DocumentCurrencyCode']") + anchor_elements = tree.xpath("//*[local-name()='AccountingSupplierParty']") additional_document_elements = tree.xpath("//*[local-name()='AdditionalDocumentReference']") - if document_currency_code_elements and not additional_document_elements: + if anchor_elements and not additional_document_elements: pdf = base64.b64encode(buffer.getvalue()).decode() pdf_name = '%s.pdf' % record._get_efff_name() to_inject = ''' @@ -40,7 +40,8 @@ class IrActionsReport(models.Model): ''' % (escape(pdf_name), quoteattr(pdf_name), pdf) - document_currency_code_elements[0].addnext(etree.fromstring(to_inject)) + anchor_index = tree.index(anchor_elements[0]) + tree.insert(anchor_index, etree.fromstring(to_inject)) new_xml = etree.tostring(tree, pretty_print=True) edi_attachment.write({ 'res_model': 'account.move', diff --git a/addons/l10n_be_edi/tests/__init__.py b/addons/l10n_be_edi/tests/__init__.py index 0952f9b8bc2..cdb02837935 100644 --- a/addons/l10n_be_edi/tests/__init__.py +++ b/addons/l10n_be_edi/tests/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- from . import test_ubl +from . import test_efff_export diff --git a/addons/l10n_be_edi/tests/test_efff_export.py b/addons/l10n_be_edi/tests/test_efff_export.py new file mode 100644 index 00000000000..b8a660ffd17 --- /dev/null +++ b/addons/l10n_be_edi/tests/test_efff_export.py @@ -0,0 +1,182 @@ +# -*- coding: utf-8 -*- +import base64 +import io +from PyPDF2 import PdfFileWriter + +from odoo.addons.account_edi.tests.common import AccountEdiTestCommon +from odoo.tests import tagged + + +@tagged('post_install_l10n', 'post_install', '-at_install') +class TestUBLBE(AccountEdiTestCommon): + + @classmethod + def setUpClass(cls, chart_template_ref='l10n_be.l10nbe_chart_template', edi_format_ref='l10n_be_edi.edi_efff_1'): + super().setUpClass(chart_template_ref=chart_template_ref, edi_format_ref=edi_format_ref) + + cls.partner_a.write({ + 'street': "Chaussée de Namur 40", + 'zip': "1367", + 'city': "Ramillies", + 'vat': 'BE0202239951', + 'country_id': cls.env.ref('base.be').id, + }) + + cls.env.company.write({ + 'street': "Rue des Bourlottes 9", + 'zip': "1367", + 'city': "Ramillies", + 'vat': 'BE0477472701', + 'country_id': cls.env.ref('base.be').id, + }) + + cls.tax_21 = cls.env['account.tax'].create({ + 'name': 'tax_21', + 'amount_type': 'percent', + 'amount': 21, + 'type_tax_use': 'sale', + }) + + def test_out_invoice_efff(self): + invoice = self.env['account.move'].create({ + 'move_type': 'out_invoice', + 'partner_id': self.partner_a.id, + 'invoice_payment_term_id': self.pay_terms_b.id, + 'invoice_date': '2017-01-01', + 'date': '2017-01-01', + 'invoice_origin': 'test invoice origin', + 'narration': 'test narration', + 'invoice_line_ids': [(0, 0, { + 'price_unit': 1000.0, + 'product_id': self.product_a.id, + 'tax_ids': [(6, 0, self.tax_21.ids)], + })], + }) + invoice.action_post() + + # Print the invoice to append AdditionalDocumentReference. + pdf_buffer = io.BytesIO() + pdf_writer = PdfFileWriter() + pdf_writer.addBlankPage(42, 42) + pdf_writer.write(pdf_buffer) + self.env.ref('account.account_invoices_without_payment')._postprocess_pdf_report(invoice, pdf_buffer) + pdf_buffer.close() + + attachment = invoice._get_edi_attachment(self.edi_format) + self.assertTrue(attachment) + xml_content = base64.b64decode(attachment.datas) + + current_etree = self.get_xml_tree_from_string(xml_content) + expected_etree = self.get_xml_tree_from_string(f''' + + 2.0 + {invoice.name} + 2017-01-01 + 380 + test narration + EUR + + test invoice origin + + + efff_BE0477472701_INV201700001.pdf + + ___ignore___ + + + + + + company_1_data + + + en_US + + + Rue des Bourlottes 9 + Ramillies + 1367 + + BE + Belgium + + + + company_1_data + BE0477472701 + + VAT + + + + company_1_data + + + + + + + partner_a + + + en_US + + + Chaussée de Namur 40 + Ramillies + 1367 + + BE + Belgium + + + + partner_a + BE0202239951 + + VAT + + + + partner_a + + + + + 31 + 2017-02-28 + {invoice.name} + + + 30% Advance End of Following Month + + + 210.00 + + + 1000.00 + 1000.00 + 1210.00 + 0.00 + 1210.00 + + + ___ignore___ + 1.0 + 1000.00 + + 210.00 + + + product_a + product_a + + + 1000.00 + + + + ''') + self.assertXmlTreeEqual(current_etree, expected_etree)