-
-
Notifications
You must be signed in to change notification settings - Fork 343
[18.0][ADD] account_edi_ubl_cii_payment_unece #1337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 18.0
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| ================================================= | ||
| Electronic invoices with UBL/CII - UNECE payments | ||
| ================================================= | ||
|
|
||
| .. | ||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| !! This file is generated by oca-gen-addon-readme !! | ||
| !! changes will be overwritten. !! | ||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| !! source digest: sha256:2700b6157b3804b70aebf0ab3ce069449a78393795880a288a0178e0a9dff400 | ||
| !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
|
|
||
| .. |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/licence-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/18.0/account_edi_ubl_cii_payment_unece | ||
| :alt: OCA/edi | ||
| .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png | ||
| :target: https://translation.odoo-community.org/projects/edi-18-0/edi-18-0-account_edi_ubl_cii_payment_unece | ||
| :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=18.0 | ||
| :alt: Try me on Runboat | ||
|
|
||
| |badge1| |badge2| |badge3| |badge4| |badge5| | ||
|
|
||
| Integrate UNECE Payment Means (module ``account_payment_unece`` from | ||
| `OCA/community-data-files | ||
| project <https://github.com/OCA/community-data-files/>`__) with Odoo | ||
| standard UBL/CII electronic invoices (module ``account_edi_ubl_cii``). | ||
|
|
||
| When using for example SEPA direct debit, your can configure the | ||
| corresponding UNECE code on the payment method and this will be declared | ||
| properly in the electronic invoice. Also, when receiving an invoice | ||
| declared with a payment means SEPA direct debit, you can configure an | ||
| outbound payment means with that UNECE code and the created invoice will | ||
| have that payment means set so that you know you don't have to pay it. | ||
|
|
||
| **Table of contents** | ||
|
|
||
| .. contents:: | ||
| :local: | ||
|
|
||
| Bug Tracker | ||
| =========== | ||
|
|
||
| Bugs are tracked on `GitHub Issues <https://github.com/OCA/edi/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 <https://github.com/OCA/edi/issues/new?body=module:%20account_edi_ubl_cii_payment_unece%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. | ||
|
|
||
| Do not contact contributors directly about support or help with technical issues. | ||
|
|
||
| Credits | ||
| ======= | ||
|
|
||
| Authors | ||
| ------- | ||
|
|
||
| * BCIM | ||
| * Akretion | ||
|
|
||
| Contributors | ||
| ------------ | ||
|
|
||
| - Jacques-Etienne Baudoux <je@bcim.be> | ||
| - Sébastien Alix <sebastien.alix@akretion.com> | ||
|
|
||
| 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 <https://github.com/OCA/edi/tree/18.0/account_edi_ubl_cii_payment_unece>`_ project on GitHub. | ||
|
|
||
| You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| from . import models |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # Copyright 2026 Akretion (https://www.akretion.com). | ||
| # @author Sébastien Alix <sebastien.alix@akretion.com> | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) | ||
| { | ||
| "name": "Electronic invoices with UBL/CII - UNECE payments", | ||
| "version": "18.0.1.0.0", | ||
| "category": "Accounting & Finance", | ||
| "license": "AGPL-3", | ||
| "summary": "Import/Export UNECE payment codes in UBL and CII XML documents.", | ||
| "author": "BCIM, Akretion, Odoo Community Association (OCA)", | ||
| "website": "https://github.com/OCA/edi", | ||
| "depends": [ | ||
| # Odoo | ||
| "account_edi_ubl_cii", | ||
| # OCA/community-data-files | ||
| "account_payment_unece", | ||
| ], | ||
| "data": [ | ||
| "data/account_payment_method.xml", | ||
| ], | ||
| "installable": True, | ||
| "auto_install": True, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| <?xml version="1.0" encoding="utf-8" ?> | ||
| <!-- Copyright 2026 Akretion (https://www.akretion.com). | ||
| License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> | ||
| <odoo noupdate="1"> | ||
| <record id="direct_debit" model="account.payment.method"> | ||
| <field name="name">Direct Debit to suppliers</field> | ||
| <field name="code">direct_debit</field> | ||
| <field name="payment_type">outbound</field> | ||
| <field name="unece_id" ref="account_payment_unece.payment_means_49" /> | ||
| </record> | ||
|
|
||
| <record id="direct_debit_sepa_" model="account.payment.method"> | ||
| <field name="name">SEPA Direct Debit to suppliers</field> | ||
| <field name="code">direct_debit_sepa</field> | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alexis-via As we need different code for sepa direct debit inbound and outbound (because inbound requires a pain version and outbound doesn't - also it is in different modules) and you already used
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For me, for SEPA direct debit outbound, the code is "manual", using the native account.payment.method declared in the account module here: https://github.com/odoo/odoo/blob/18.0/addons/account/data/account_data.xml#L135
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alexis-via The issue is that the unece code is on account.payment.method and there is a unicity constrain per code, payment_type (in/out). So we have to put a different code for each account.payment.method having a different unece code. |
||
| <field name="payment_type">outbound</field> | ||
| <field name="unece_id" ref="account_payment_unece.payment_means_59" /> | ||
| </record> | ||
| </odoo> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| from . import account_edi_ubl | ||
| from . import account_edi_xml_cii | ||
| from . import account_edi_xml_ubl_bis3 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # Copyright 2026 Akretion (https://www.akretion.com). | ||
| # @author Sébastien Alix <sebastien.alix@akretion.com> | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) | ||
|
|
||
| from odoo import models | ||
|
|
||
|
|
||
| class AccountEdiUBL(models.AbstractModel): | ||
| _inherit = "account.edi.ubl" | ||
|
|
||
| def _import_ubl_invoice_add_payment_reference(self, collected_values): | ||
| # NOTE: we override this method to access `collected_values`. It could | ||
| # have been any method called in '<account.edi.ubl>._ubl_import_invoice()'. | ||
| res = super()._import_ubl_invoice_add_payment_reference(collected_values) | ||
| self._import_ubl_invoice_add_unece_payment_mean(collected_values) | ||
| return res | ||
|
|
||
| def _import_ubl_invoice_add_unece_payment_mean(self, collected_values): | ||
| tree = collected_values["tree"] | ||
| payment_mean_code = None | ||
| for node in tree.findall("./{*}PaymentMeans/{*}PaymentMeansCode"): | ||
| if note := node.text: | ||
| payment_mean_code = note | ||
| break | ||
| if not payment_mean_code: | ||
| return | ||
| # Look for a matching payment method line | ||
| payment_method_line = self.env["account.payment.method.line"].search( | ||
| [ | ||
|
sebalix marked this conversation as resolved.
|
||
| ("journal_id.type", "in", ("cash", "bank", "credit")), | ||
| ("payment_type", "=", "outbound"), | ||
| ("payment_method_id.unece_code", "=", payment_mean_code), | ||
| ], | ||
| limit=1, | ||
| ) | ||
| if not payment_method_line: | ||
| return | ||
| collected_values["to_write"]["preferred_payment_method_line_id"] = ( | ||
| payment_method_line.id | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| # Copyright 2026 Akretion (https://www.akretion.com). | ||
| # @author Sébastien Alix <sebastien.alix@akretion.com> | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) | ||
|
|
||
| from odoo import models | ||
|
|
||
|
|
||
| class AccountEdiXmlCII(models.AbstractModel): | ||
| _inherit = "account.edi.xml.cii" | ||
|
|
||
| def _export_invoice_vals(self, invoice): | ||
| template_values = super()._export_invoice_vals(invoice) | ||
| payment_method_line = invoice.preferred_payment_method_line_id | ||
| payment_method = payment_method_line.payment_method_id | ||
| if payment_method.unece_id: | ||
| # Integrate UNECE payment means | ||
| template_values["payment_means_code"] = payment_method.unece_id.code | ||
| return template_values | ||
|
|
||
| def _import_fill_invoice(self, invoice, tree, qty_factor): | ||
| res = super()._import_fill_invoice(invoice, tree, qty_factor) | ||
| invoice_values = self._extract_invoice_unece_payment_mean(invoice, tree) | ||
| if invoice_values: | ||
| invoice.write(invoice_values) | ||
| return res | ||
|
|
||
| def _extract_invoice_unece_payment_mean(self, invoice, tree): | ||
| payment_mean_code = None | ||
| for node in tree.findall( | ||
| ".//{*}SpecifiedTradeSettlementPaymentMeans/{*}TypeCode" | ||
| ): | ||
| if payment_mean_code := node.text: | ||
| break | ||
| if not payment_mean_code: | ||
| return {} | ||
| # Look for a matching payment method line | ||
| payment_method_line = self.env["account.payment.method.line"].search( | ||
| [ | ||
| ("journal_id.type", "in", ("cash", "bank", "credit")), | ||
| ("payment_type", "=", "outbound"), | ||
| ("payment_method_id.unece_code", "=", payment_mean_code), | ||
| ], | ||
| limit=1, | ||
| ) | ||
| if not payment_method_line: | ||
| return | ||
| return {"preferred_payment_method_line_id": payment_method_line.id} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| # Copyright 2026 Akretion (https://www.akretion.com). | ||
| # @author Sébastien Alix <sebastien.alix@akretion.com> | ||
| # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) | ||
|
|
||
| from odoo import models | ||
|
|
||
|
|
||
| class AccountEdiXmlUBLBIS3(models.AbstractModel): | ||
| _inherit = "account.edi.xml.ubl_bis3" | ||
|
|
||
| def _ubl_add_payment_means_nodes(self, vals): | ||
| super()._ubl_add_payment_means_nodes(vals) | ||
| nodes = vals["document_node"]["cac:PaymentMeans"] | ||
| invoice = vals.get("invoice") | ||
| if not invoice: | ||
| return | ||
| payment_method_line = invoice.preferred_payment_method_line_id | ||
| payment_method = payment_method_line.payment_method_id | ||
| if payment_method.unece_id: | ||
| # Integrate UNECE payment means | ||
| for node in nodes: | ||
| node["cbc:PaymentMeansCode"] = { | ||
| "_text": payment_method.unece_id.code, | ||
| "name": payment_method.unece_id.name, | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| [build-system] | ||
| requires = ["whool"] | ||
| build-backend = "whool.buildapi" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| - Jacques-Etienne Baudoux \<<je@bcim.be>\> | ||
| - Sébastien Alix \<<sebastien.alix@akretion.com>\> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| Integrate UNECE Payment Means (module `account_payment_unece` from | ||
| [OCA/community-data-files project](https://github.com/OCA/community-data-files/)) | ||
| with Odoo standard UBL/CII electronic invoices (module `account_edi_ubl_cii`). | ||
|
|
||
| When using for example SEPA direct debit, your can configure the corresponding | ||
| UNECE code on the payment method and this will be declared properly in the | ||
| electronic invoice. | ||
| Also, when receiving an invoice declared with a payment means SEPA direct debit, | ||
| you can configure an outbound payment means with that UNECE code and the created | ||
| invoice will have that payment means set so that you know you don't have to pay it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the code you use here, you need to extend the method in AccountPaymentMethod to have the AccountPaymentMethodLine created
like here:
https://github.com/OCA/bank-payment-alternative/blob/18.0/account_payment_sepa_direct_debit/models/account_payment_method.py#L41