OCA/edi-framework · 18.0
EDI
edi_core_oca
EDI
Base EDI backend.
Provides following models:
- EDI Backend, to centralize configuration
- EDI Backend Type, to classify EDI backends (eg: UBL, GS1, e-invoice, pick-yours)
- EDI Exchange Type, to define file types of exchange
- EDI Exchange Record, to define a record exchanged between systems
Also define a mixin to be inherited by records that will generate EDIs.
In addition, the module ships an edi.configuration mechanism that lets
users react to EDI events declaratively, by writing small Python
snippets attached to event triggers. This can be used as a lightweight
alternative to component event listeners: configurations can react
globally (on any exchange) or be scoped to a specific partner (or any
related record), exchange type, backend and target model. See
CONFIGURE.md for details.
Table of contents
Configuration
This module aims to provide an infrastructure to simplify interchangability of documents between systems providing a configuration platform. It will be inherited by other modules in order to define the proper implementations of components.
In order to define a new Exchange Record, we need to configure:
- Backend Type
- Exchange Type
- Backend
- Components
Jobs
- Internal User: might be an EDI user without even knowing about it, triggering EDI flows by some of his actions on business records; does not need access to related queue jobs.
- EDI User: more conscious EDI user that might sometimes need to debug things a bit further and thus needs access to related queue jobs.
- EDI Manager: full configuration access.
Code to execute
By default, EDI Framework uses fields on edi.backend to get the right
function to execute. Each function is related to a model where the
specific function is defined. This models needs to inherit the specific
handler of each case.
- receive: model
edi.oca.handler.receivewith function receive. - process: model
edi.oca.handler.processwith function process. - generate: model
edi.oca.handler.generatewith function generate. - send: model
edi.oca.handler.sendwith function send. - check: model
edi.oca.handler.checkwith function check. - validate on inputs: model
edi.oca.handler.input.validatewith function input_validate. - validate on outputs: model
edi.oca.handler.output.validatewith function input_validate.
You can see an example on the tests fake_models.
For a more complex behaviour, you can use edi_component_oca module to
use components.
User EDI generation
On the exchange type, it might be possible to define a set of models, a domain and a snippet of code. After defining this fields, we will automatically see buttons on the view to generate the exchange records. This configuration is useful to define a way of generation managed by user.
Exchange type rules configuration
Exchange types can be further configured with rules. You can use rules to:
- make buttons automatically appear in forms
- define your own custom logic
Go to an exchange type and go to the tab "Model rules". There you can add one or more rule, one per model. On each rule you can define a domain or a snippet to activate it. In case of a "Form button" kind, if the domain and/ the snippet is/are satisfied, a form btn will appear on the top of the form. This button can be used by the end user to manually generate an exchange. If there's more than a backend and the exchange type has not a backend set, a wizard will appear asking to select a backend to be used for the exchange.
In case of "Custom" kind, you'll have to define your own logic to do something.
Custom event handlers via edi.configuration
The framework can dispatch EDI lifecycle events to user-defined
configurations, providing a declarative alternative to component events.
Each edi.configuration record links a trigger (an
edi.configuration.trigger code) to a snippet (snippet_do) that
is executed every time the matching event fires on an exchange record.
Built-in events fired by EDIExchangeRecord include:
on_edi_exchange_done— exchange processed successfullyon_edi_exchange_error— exchange ended in erroron_edi_exchange_done_ack_received— ACK file receivedon_edi_exchange_done_ack_missing— expected ACK not receivedon_edi_exchange_done_ack_received_error— ACK received with errorson_edi_exchange_<action>_complete— generic action completion (e.g.generate_complete,send_complete), fired once on the exchange record and once on its related record when present
The snippet receives at least two variables in its evaluation context:
conf— the currentedi.configurationrecordrecord— the target of the event (either theedi.exchange.recorditself or its related business record)
Plus the standard edi_exec_snippet_do extras (operation,
edi_action, old_value, vals, ...).
Two complementary lookup modes are available, and they can be combined freely on the same flow.
Global event configurations
Use this mode when you want a configuration to react to events on any business record that travels through EDI, with no per-partner setup.
Tick Global Configuration (is_global) on the edi.configuration.
When an event fires, the framework calls
edi.configuration.edi_get_conf_global(exchange_record, trigger) which
selects all active global configurations whose trigger matches the
event code, filtered by the originating exchange record:
- Exchange type (
type_id): must match the exchange record's type, or be left empty to apply to every type - Backend (
backend_id): must match the exchange record's backend, or be left empty to apply to every backend - Model (
model_id/model_name): must match the related record model (e.g.sale.order,account.move), or be left empty to apply to every model
Empty values mean "applies to all". Inactive configurations and non-global configurations are ignored. All matching configurations are executed in sequence.
Typical use cases:
- Posting a generic chatter message on every exchange that ends in error
- Pushing a notification to an external system every time an ACK is received for a given backend
- Logging extra audit information for every exchange of a given type
Partner-specific (relation-based) event configurations
Use this mode when the reaction must depend on the partner (or any other related record) involved in the exchange.
In this case configurations are not marked as global. Instead, the
business record exposes an edi_config_ids relation (via
edi.exchange.consumer.mixin._edi_config_field_relation, which by
default returns self.env["edi.configuration"] and can be overridden,
for example to point at self.partner_id.edi_config_ids). When an event
fires on the business record (e.g. on create, on write, on
send-via-email/EDI), the framework calls
edi_confs.edi_get_conf(trigger) on that relation and runs the matching
snippets.
Compared with global configurations:
- Discovery comes from the record's own relation, not from a database-wide search; this is the right place to model "this partner wants this behaviour" rules
- Filtering is reduced to
triggerand (optionally)backend_id, since the recordset is already narrowed by the relation - The same
snippet_doAPI applies, so a snippet can be reused verbatim between global and partner-specific configurations
Typical use cases:
- Sending a specific EDI flow only for a subset of partners
- Customising the document generation per customer (e.g. different email template, different transport)
- Switching between EDI and email delivery based on partner preferences
Usage
After certain operations or manual execution, Exchange records will be generated. This Exchange records might be input records or outputs records.
The change of state can be manually executed by the system or be managed through by ir.cron.
Output Exchange records
An output record is intended to be used for exchange information from Odoo to another system.
The flow of an output record should be:
- Creation
- Generation of data
- Validation of data
- Sending data
- Validation of data processed properly by the other party
Input Exchange records
An input record is intended to be used for exchange information another system to odoo.
The flow of an input record should be:
- Creation
- Reception of data
- Checking data
- Processing data
Known issues / Roadmap
14.0.1.0.0
The module name has been changed from edi to edi_oca.
18.0.1.4.0
Components dependancy has been removed and set on a new dependant module
edi_component_oca. Module edi_oca has been_renamed to
edi_core_oca.
Changelog
18.0.1.7.0 (2026-05-20)
Features
-
Introduce a new system for global EDI events based on
edi.configurationthat can replace the use of component events.Any
edi.configurationflagged asis_globalis now picked up byEDIExchangeRecord._trigger_edi_eventand itssnippet_dois executed whenever the matching event fires (done,error,ack_received,ack_missing,ack_received_error,<action>_complete, ...).Filtering is performed via the new
edi.configuration.edi_get_conf_globalmodel method, which selects active global configurations matching the event trigger code and, when set, the exchange type, the backend and the related record model carried by the exchange record (empty values still mean "applies to all"). This lets integrators subscribe to EDI events declaratively from the UI instead of writing component listeners.Full test coverage is included for the dispatch on all
notify_*events (both on the exchange record and on the related record target) and for the new filtering rules.Last but not lease: add minimal docs for edi.configuration. (#global-edi-conf-events)
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
- Dixmit
- Camptocamp
Contributors
- Simone Orsi <<simahawk@gmail.com>>
- Enric Tobella <<enric.tobella@dixmit.com>>
- Manuel Regidor <<manuel.regidor@sygel.es>>
- Thien Vo <<thienvh@trobz.com>>
- Jordi Masvidal <<jordi.masvidal@forgeflow.com>>
Maintainers
This module is maintained by the OCA.
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.
Current maintainers:
This module is part of the OCA/edi-framework project on GitHub.
You are welcome to contribute. To learn how please visit <https://odoo-community.org/page/Contribute>.







