diff --git a/account_edi_ubl_cii_additional_document/README.rst b/account_edi_ubl_cii_additional_document/README.rst new file mode 100644 index 0000000000..405abd51e8 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/README.rst @@ -0,0 +1,108 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +================================ +Account EDI Additional Documents +================================ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:0e7679896d10ed80af24162c3f256173501ce8ee1640286069fbd4c86d4d7aa0 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fedi-lightgray.png?logo=github + :target: https://github.com/OCA/edi/tree/16.0/account_edi_ubl_cii_additional_document + :alt: OCA/edi +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/edi-16-0/edi-16-0-account_edi_ubl_cii_additional_document + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/edi&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends ``account_edi_ubl_cii`` to import all attachments +included in UBL invoices, not only PDF files. + +During the import process, additional documents provided by the supplier +(e.g. XLSX, CSV, images) are extracted from the UBL payload and linked +to the generated vendor bill. + +**Table of contents** + +.. contents:: + :local: + +Use Cases / Context +=================== + +In the standard behavior of ``account_edi_ubl_cii``, only PDF +attachments from UBL invoices are imported and linked to the vendor +bill. + +However, suppliers may include additional documents (e.g. XLSX, CSV, +images) in the UBL payload that are relevant for accounting or +reconciliation. + +These attachments are currently ignored, creating a need to make all +provided documents available in Odoo. + +Known issues / Roadmap +====================== + +This limitation has been addressed in standard Odoo starting from +version 17. + +For newer versions, the native behavior of ``account_edi_ubl_cii`` +already supports importing all attachments from UBL invoices. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* ACSONE SA/NV + +Contributors +------------ + +- Souheil Bejaoui souheil.bejaoui@acsone.eu + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/edi `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_edi_ubl_cii_additional_document/__init__.py b/account_edi_ubl_cii_additional_document/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/account_edi_ubl_cii_additional_document/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/account_edi_ubl_cii_additional_document/__manifest__.py b/account_edi_ubl_cii_additional_document/__manifest__.py new file mode 100644 index 0000000000..5dabe0a994 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/__manifest__.py @@ -0,0 +1,15 @@ +# Copyright 2026 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Account EDI Additional Documents", + "summary": """Extends account_edi_ubl_cii to import all attachments from UBL + invoices (not only PDFs) and link them to the vendor bill.""", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/edi", + "depends": ["account_edi_ubl_cii"], + "data": [], + "demo": [], +} diff --git a/account_edi_ubl_cii_additional_document/models/__init__.py b/account_edi_ubl_cii_additional_document/models/__init__.py new file mode 100644 index 0000000000..8a6879b522 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/models/__init__.py @@ -0,0 +1 @@ +from . import account_edi_common diff --git a/account_edi_ubl_cii_additional_document/models/account_edi_common.py b/account_edi_ubl_cii_additional_document/models/account_edi_common.py new file mode 100644 index 0000000000..bab72d1492 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/models/account_edi_common.py @@ -0,0 +1,52 @@ +# Copyright 2026 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + +SUPPORTED_FILE_TYPES = { + "application/pdf": ".pdf", + "application/vnd.oasis.opendocument.spreadsheet": ".ods", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": ".xlsx", + "image/jpeg": ".jpeg", + "image/png": ".png", + "text/csv": ".csv", +} + + +class AccountEdiCommon(models.AbstractModel): + + _inherit = "account.edi.common" + + def _import_invoice(self, journal, filename, tree, existing_invoice=None): + invoice = super()._import_invoice( + journal, filename, tree, existing_invoice=existing_invoice + ) + additional_docs = tree.findall("./{*}AdditionalDocumentReference") + for document in additional_docs: + attachment_name = document.find("{*}ID") + attachment_data = document.find( + "{*}Attachment/{*}EmbeddedDocumentBinaryObject" + ) + if attachment_data is None: + continue + mime_code = attachment_data.attrib.get("mimeCode") + if mime_code == "application/pdf": + # already covered by base module + continue + if not (extension := SUPPORTED_FILE_TYPES.get(mime_code)): + continue + text = attachment_data.text + name = (attachment_name.text or "invoice").split("\\")[-1].split("/")[ + -1 + ].split(".")[0] + extension + self.env["ir.attachment"].create( + { + "name": name, + "res_id": invoice.id, + "res_model": "account.move", + "datas": text + "=" * (len(text) % 3), # Fix incorrect padding + "type": "binary", + "mimetype": mime_code, + } + ) + return invoice diff --git a/account_edi_ubl_cii_additional_document/readme/CONTEXT.md b/account_edi_ubl_cii_additional_document/readme/CONTEXT.md new file mode 100644 index 0000000000..1bf1382777 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/readme/CONTEXT.md @@ -0,0 +1,8 @@ +In the standard behavior of `account_edi_ubl_cii`, only PDF attachments from +UBL invoices are imported and linked to the vendor bill. + +However, suppliers may include additional documents (e.g. XLSX, CSV, images) +in the UBL payload that are relevant for accounting or reconciliation. + +These attachments are currently ignored, creating a need to make all provided +documents available in Odoo. \ No newline at end of file diff --git a/account_edi_ubl_cii_additional_document/readme/CONTRIBUTORS.md b/account_edi_ubl_cii_additional_document/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..50e6298db5 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +* Souheil Bejaoui diff --git a/account_edi_ubl_cii_additional_document/readme/DESCRIPTION.md b/account_edi_ubl_cii_additional_document/readme/DESCRIPTION.md new file mode 100644 index 0000000000..23aecd23d0 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/readme/DESCRIPTION.md @@ -0,0 +1,6 @@ +This module extends `account_edi_ubl_cii` to import all attachments included +in UBL invoices, not only PDF files. + +During the import process, additional documents provided by the supplier +(e.g. XLSX, CSV, images) are extracted from the UBL payload and linked to +the generated vendor bill. diff --git a/account_edi_ubl_cii_additional_document/readme/ROADMAP.md b/account_edi_ubl_cii_additional_document/readme/ROADMAP.md new file mode 100644 index 0000000000..37c8d11ff5 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/readme/ROADMAP.md @@ -0,0 +1,4 @@ +This limitation has been addressed in standard Odoo starting from version 17. + +For newer versions, the native behavior of `account_edi_ubl_cii` already supports +importing all attachments from UBL invoices. \ No newline at end of file diff --git a/account_edi_ubl_cii_additional_document/static/description/icon.png b/account_edi_ubl_cii_additional_document/static/description/icon.png new file mode 100644 index 0000000000..3a0328b516 Binary files /dev/null and b/account_edi_ubl_cii_additional_document/static/description/icon.png differ diff --git a/account_edi_ubl_cii_additional_document/static/description/index.html b/account_edi_ubl_cii_additional_document/static/description/index.html new file mode 100644 index 0000000000..9b3b42c0ac --- /dev/null +++ b/account_edi_ubl_cii_additional_document/static/description/index.html @@ -0,0 +1,453 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Account EDI Additional Documents

+ +

Beta License: AGPL-3 OCA/edi Translate me on Weblate Try me on Runboat

+

This module extends account_edi_ubl_cii to import all attachments +included in UBL invoices, not only PDF files.

+

During the import process, additional documents provided by the supplier +(e.g. XLSX, CSV, images) are extracted from the UBL payload and linked +to the generated vendor bill.

+

Table of contents

+ +
+

Use Cases / Context

+

In the standard behavior of account_edi_ubl_cii, only PDF +attachments from UBL invoices are imported and linked to the vendor +bill.

+

However, suppliers may include additional documents (e.g. XLSX, CSV, +images) in the UBL payload that are relevant for accounting or +reconciliation.

+

These attachments are currently ignored, creating a need to make all +provided documents available in Odoo.

+
+
+

Known issues / Roadmap

+

This limitation has been addressed in standard Odoo starting from +version 17.

+

For newer versions, the native behavior of account_edi_ubl_cii +already supports importing all attachments from UBL invoices.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/edi project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+
+ + diff --git a/account_edi_ubl_cii_additional_document/tests/__init__.py b/account_edi_ubl_cii_additional_document/tests/__init__.py new file mode 100644 index 0000000000..a2c52e029a --- /dev/null +++ b/account_edi_ubl_cii_additional_document/tests/__init__.py @@ -0,0 +1 @@ +from . import test_account_edi_ubl_cii_multi_attachment diff --git a/account_edi_ubl_cii_additional_document/tests/test_account_edi_ubl_cii_multi_attachment.py b/account_edi_ubl_cii_additional_document/tests/test_account_edi_ubl_cii_multi_attachment.py new file mode 100644 index 0000000000..47d16baf98 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/tests/test_account_edi_ubl_cii_multi_attachment.py @@ -0,0 +1,45 @@ +# Copyright 2026 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo.tests import tagged +from odoo.tools import file_open + +from odoo.addons.account.tests.common import AccountTestInvoicingCommon + + +@tagged("post_install", "-at_install") +class TestAccountEdiUblCiiMultiAttachment(AccountTestInvoicingCommon): + def _import_invoice(self): + journal = self.company_data["default_journal_purchase"] + file_path = ( + "account_edi_ubl_cii_additional_document/tests/" + "test_files/bis3_bill_example.xml" + ) + with file_open(file_path, "rb") as file: + xml_attachment = self.env["ir.attachment"].create( + { + "mimetype": "application/xml", + "name": "test_invoice.xml", + "raw": file.read(), + } + ) + move = ( + self.env["account.journal"] + .with_context(default_journal_id=journal.id) + ._create_document_from_attachment(xml_attachment.id) + ) + return move + + def test_0(self): + bill = self._import_invoice() + self.assertSetEqual( + set(bill.attachment_ids.mapped("name")), + { + "FAC_2023_00052.csv", + "FAC_2023_00052.png", + "FAC_2023_00052.xlsx", + "FAC_2023_00052.pdf", + "test_invoice.xml", + }, + ) + self.assertEqual(bill.message_main_attachment_id.name, "FAC_2023_00052.pdf") diff --git a/account_edi_ubl_cii_additional_document/tests/test_files/bis3_bill_example.xml b/account_edi_ubl_cii_additional_document/tests/test_files/bis3_bill_example.xml new file mode 100644 index 0000000000..8035590ca5 --- /dev/null +++ b/account_edi_ubl_cii_additional_document/tests/test_files/bis3_bill_example.xml @@ -0,0 +1,174 @@ + + + + urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0 + + urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 + FAC/2023/00052 + 2023-08-04 + 2023-09-04 + 380 + EUR + + FAC/2023/00052 + S00012 + + + FAC_2023_00052.pdf + + JVBERi0xLjQKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyA+PgplbmRvYmoKdHJhaWxlcgo8PCA+PgolJUVPRg== + + + + FAC_2023_00052.xlsx + + UEsFBgAAAAAAAAAAAAAAAAAAAAAAAA== + + + + FAC_2023_00052.png + + iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGNgYAAAAAMAASsJTYQAAAAASUVORK5CYII= + + + + FAC_2023_00052.csv + + Y29sMSxjb2wyCg== + + + + + LU25587702 + + ALD Automotive LU + + + 270 rte d'Arlon + Strassen + 8010 + + LU + + + + LU12977109 + + VAT + + + + ALD Automotive LU + LU12977109 + + + ALD Automotive LU + adl@test.com + + + + + + LU25587702 + + Odoo Lu + + + Rue de l'industrie 13 + Windhof + + LU + + + + LU25587702 + + VAT + + + + Odoo Lu + LU25587702 + + + Odoo Lu + odoo@test.com + + + + + + + Rue de l'industrie 13 + Windhof + + LU + + + + + + 30 + FAC/2023/00052 + + LU071241358706500000 + + + + 105.12 + + 657.00 + 105.12 + + S + 16.0 + + VAT + + + + + + 657.00 + 657.00 + 762.12 + 0.00 + 762.12 + + + 1 + 1.0 + 657.00 + + Locations et leasing opérationnel - Véhicule HG6542 + + Locations et leasing opérationnel + + S + 16.0 + + VAT + + + + + 657.00 + + + diff --git a/setup/account_edi_ubl_cii_additional_document/odoo/addons/account_edi_ubl_cii_additional_document b/setup/account_edi_ubl_cii_additional_document/odoo/addons/account_edi_ubl_cii_additional_document new file mode 120000 index 0000000000..b410114e79 --- /dev/null +++ b/setup/account_edi_ubl_cii_additional_document/odoo/addons/account_edi_ubl_cii_additional_document @@ -0,0 +1 @@ +../../../../account_edi_ubl_cii_additional_document \ No newline at end of file diff --git a/setup/account_edi_ubl_cii_additional_document/setup.py b/setup/account_edi_ubl_cii_additional_document/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/account_edi_ubl_cii_additional_document/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)