Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Available addons
addon | version | maintainers | summary
--- | --- | --- | ---
[edi_component_oca](edi_component_oca/) | 19.0.1.1.0 | <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> <a href='https://github.com/etobella'><img src='https://github.com/etobella.png' width='32' height='32' style='border-radius:50%;' alt='etobella'/></a> | Allow to use Connector as a source in EDI
[edi_core_oca](edi_core_oca/) | 19.0.1.2.0 | <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> <a href='https://github.com/etobella'><img src='https://github.com/etobella.png' width='32' height='32' style='border-radius:50%;' alt='etobella'/></a> | Define backends, exchange types, exchange records, basic automation and views for handling EDI exchanges.
[edi_core_oca](edi_core_oca/) | 19.0.1.2.1 | <a href='https://github.com/simahawk'><img src='https://github.com/simahawk.png' width='32' height='32' style='border-radius:50%;' alt='simahawk'/></a> <a href='https://github.com/etobella'><img src='https://github.com/etobella.png' width='32' height='32' style='border-radius:50%;' alt='etobella'/></a> | Define backends, exchange types, exchange records, basic automation and views for handling EDI exchanges.
[edi_endpoint_oca](edi_endpoint_oca/) | 19.0.1.1.1 | | Base module allowing configuration of custom endpoints for EDI framework.
[edi_product_oca](edi_product_oca/) | 19.0.1.0.0 | | EDI framework configuration and base logic for products and units of measure
[edi_purchase_oca](edi_purchase_oca/) | 19.0.1.0.0 | | Define EDI Configuration for Purchase Orders
Expand Down
2 changes: 1 addition & 1 deletion edi_core_oca/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ EDI
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:46139d4cc31684944b8784e2503633ab59a96d8b072b42ee5ab30cd8f2177930
!! source digest: sha256:de90b9bf70f5e4c8e52326e5549c47a2a3d9b91843ffb0a101d442d6fce3f8c3
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand Down
2 changes: 1 addition & 1 deletion edi_core_oca/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
Define backends, exchange types, exchange records,
basic automation and views for handling EDI exchanges.
""",
"version": "19.0.1.2.0",
"version": "19.0.1.2.1",
"website": "https://github.com/OCA/edi-framework",
"development_status": "Beta",
"license": "LGPL-3",
Expand Down
22 changes: 15 additions & 7 deletions edi_core_oca/i18n/it.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-05-25 22:46+0000\n"
"PO-Revision-Date: 2026-06-05 09:46+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
Expand Down Expand Up @@ -157,7 +157,7 @@ msgstr ""
#. module: edi_core_oca
#: model:ir.model.fields,field_description:edi_core_oca.field_edi_exchange_type__exchange_record_count
msgid "# Exchange Records"
msgstr ""
msgstr "N° record scambio"

#. module: edi_core_oca
#: model_terms:ir.ui.view,arch_db:edi_core_oca.edi_exchange_consumer_mixin_buttons
Expand Down Expand Up @@ -319,7 +319,7 @@ msgstr "Applica a questo modello"
#. module: edi_core_oca
#: model:ir.actions.server,name:edi_core_oca.ir_cron_archive_old_edi_records_ir_actions_server
msgid "Archive Old EDI Exchange Records"
msgstr ""
msgstr "Archivia i vecchi record EDI"

#. module: edi_core_oca
#: model_terms:ir.ui.view,arch_db:edi_core_oca.edi_backend_view_form
Expand Down Expand Up @@ -352,26 +352,30 @@ msgstr ""
#. module: edi_core_oca
#: model:ir.model.fields,field_description:edi_core_oca.field_edi_backend__auto_archive_records_after_days
msgid "Auto-archive records after (days)"
msgstr ""
msgstr "Auto archivia i record dopo (giorni)"

#. module: edi_core_oca
#: model:ir.model.fields,field_description:edi_core_oca.field_edi_backend__auto_delete_records_after_days
msgid "Auto-delete archived records after (days)"
msgstr ""
msgstr "Auto cancella i record archiviati dopo (giorni)"

#. module: edi_core_oca
#: model:ir.model.fields,help:edi_core_oca.field_edi_backend__auto_archive_records_after_days
msgid ""
"Automatically archive EDI exchange records after X days. Set to <= 0 to "
"disable auto-archiving."
msgstr ""
"Archivia automaticamente i record di scambio EDI dopo X giorni. Impostare "
"inferiore o uguale a 0 per disabilitare l'auto archiviazione."

#. module: edi_core_oca
#: model:ir.model.fields,help:edi_core_oca.field_edi_backend__auto_delete_records_after_days
msgid ""
"Automatically delete archived EDI exchange records after X days. Set to <= 0 "
"to disable auto-deletion."
msgstr ""
"Cancella automaticamente i record di scambio EDI archiviati dopo X giorni. "
"Impostare inferiore o uguale a 0 per disabilitare l'auto cancellazione."

#. module: edi_core_oca
#: model:ir.model.fields,field_description:edi_core_oca.field_edi_configuration__backend_id
Expand Down Expand Up @@ -528,7 +532,7 @@ msgstr "Gestore errore decodifica"
#. module: edi_core_oca
#: model:ir.actions.server,name:edi_core_oca.ir_cron_delete_old_archived_edi_records_ir_actions_server
msgid "Delete Old Archived EDI Exchange Records"
msgstr ""
msgstr "Cancella i vecchi record di scambio EDI archiviati"

#. module: edi_core_oca
#: model:ir.model.fields,help:edi_core_oca.field_edi_configuration__description
Expand Down Expand Up @@ -1547,7 +1551,7 @@ msgstr "Record ID=%d non è previsto che sia inviato!"
#. module: edi_core_oca
#: model_terms:ir.ui.view,arch_db:edi_core_oca.edi_backend_view_form
msgid "Records retention"
msgstr ""
msgstr "Cancellazione record"

#. module: edi_core_oca
#: model_terms:ir.ui.view,arch_db:edi_core_oca.edi_exchange_record_view_form
Expand Down Expand Up @@ -1808,6 +1812,10 @@ msgid ""
"waiting for the cron to pass by. Requires auto generate flag to be active as "
"well. The cron will skip these records unless forced."
msgstr ""
"Quando attivi, i record di questo tipo verranno elaborati immediatamente, "
"senza attendere il completamento del cron. Richiede che anche il flag di "
"generazione automatica sia attivo. Il cron ignorerà questi record, a meno "
"che non venga forzato."

#. module: edi_core_oca
#: model:ir.model.fields,help:edi_core_oca.field_edi_exchange_consumer_mixin__edi_disable_auto
Expand Down
24 changes: 18 additions & 6 deletions edi_core_oca/models/edi_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ def exchange_generate(self, exchange_record, store=True, force=False, **kw):
:param kw: keyword args to be propagated to output generate handler
"""
self.ensure_one()
old_state = exchange_record.edi_exchange_state
if force and exchange_record.exchange_file:
# Remove file to regenerate
exchange_record.exchange_file = False
Expand Down Expand Up @@ -148,14 +149,22 @@ def exchange_generate(self, exchange_record, store=True, force=False, **kw):
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
state = "validate_error"
message = exchange_record._exchange_status_message("validate_ko")
exchange_record.update(
{
"edi_exchange_state": state,
"exchange_error": error,
"exchange_error_traceback": traceback,
}
)
if old_state != state:
exchange_record._notify_error("validate_ko")
# At this point `message` still holds the "generate_ok" success
# text set before validation ran. Generation succeeded but
# validation failed, so clear it: `_notify_error` has already
# posted the validation error (and fired the error event), and
# we must not let `notify_action_complete` below post the stale
# success message on top of it.
message = None
exchange_record.notify_action_complete("generate", message=message)
return message

Expand Down Expand Up @@ -228,7 +237,7 @@ def exchange_send(self, exchange_record):
check = self._output_check_send(exchange_record)
if not check:
return self._failed_output_check_send_msg()
state = exchange_record.edi_exchange_state
old_state = state = exchange_record.edi_exchange_state
error = traceback = False
message = None
res = ""
Expand All @@ -248,7 +257,6 @@ def exchange_send(self, exchange_record):
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
state = "output_error_on_send"
message = exchange_record._exchange_status_message("send_ko")
res = f"Error: {error}"
_logger.debug(
"%s send failed. Marked as errored.", exchange_record.identifier
Expand Down Expand Up @@ -281,6 +289,8 @@ def exchange_send(self, exchange_record):
"exchanged_on": fields.Datetime.now(),
}
)
if old_state != state and state == "output_error_on_send":
exchange_record._notify_error("send_ko")
exchange_record.notify_action_complete("send", message=message)
return res

Expand Down Expand Up @@ -514,7 +524,7 @@ def exchange_receive(self, exchange_record):
check = self._exchange_receive_check(exchange_record)
if not check:
return "Nothing to do. Likely already received."
state = exchange_record.edi_exchange_state
old_state = state = exchange_record.edi_exchange_state
error = traceback = False
message = None
content = None
Expand All @@ -528,15 +538,13 @@ def exchange_receive(self, exchange_record):
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
state = "validate_error"
message = exchange_record._exchange_status_message("validate_ko")
res = f"Validation error: {error}"
except self._swallable_exceptions() as err:
if self.env.context.get("_edi_receive_break_on_error"):
raise
traceback = _get_exception_traceback()
error = _get_exception_msg(err)
state = "input_receive_error"
message = exchange_record._exchange_status_message("receive_ko")
res = f"Input error: {error}"
except (OperationalError, IntegrityError):
# We don't want the finally block to be executed in this case as
Expand All @@ -561,6 +569,10 @@ def exchange_receive(self, exchange_record):
"exchanged_on": fields.Datetime.now(),
}
)
if old_state != state and state == "input_receive_error":
exchange_record._notify_error("receive_ko")
if old_state != state and state == "validate_error":
exchange_record._notify_error("validate_ko")
exchange_record.notify_action_complete("receive", message=message)
return res

Expand Down
2 changes: 1 addition & 1 deletion edi_core_oca/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ <h1>EDI</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:46139d4cc31684944b8784e2503633ab59a96d8b072b42ee5ab30cd8f2177930
!! source digest: sha256:de90b9bf70f5e4c8e52326e5549c47a2a3d9b91843ffb0a101d442d6fce3f8c3
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/license-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/edi-framework/tree/19.0/edi_core_oca"><img alt="OCA/edi-framework" src="https://img.shields.io/badge/github-OCA%2Fedi--framework-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/edi-framework-19-0/edi-framework-19-0-edi_core_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/edi-framework&amp;target_branch=19.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Base EDI backend.</p>
Expand Down
23 changes: 23 additions & 0 deletions edi_core_oca/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,26 @@ def setUpClass(cls):
super().setUpClass()
cls._setup_env()
cls._setup_records()

def _make_global_error_conf(self, exchange_type):
"""Register a global ``edi.configuration`` bound to the
``on_edi_exchange_error`` event.

Its snippet writes a marker on the configuration so a test can assert
the error event actually fired. This is the observable behaviour that
distinguishes an errored exchange (which must notify, e.g. create the
activities handled by ``edi_notification_oca``) from one that merely
posts a chatter message via ``notify_action_complete``.
"""
trigger = self.env.ref("edi_core_oca.edi_config_trigger_record_error")
return self.env["edi.configuration"].create(
{
"name": "Test notify on error",
"active": True,
"backend_id": self.backend.id,
"type_id": exchange_type.id,
"trigger_id": trigger.id,
"is_global": True,
"snippet_do": "conf.write({'description': 'error-event-fired'})",
}
)
10 changes: 10 additions & 0 deletions edi_core_oca/tests/test_backend_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ def test_receive_no_allow_empty_file_record(self):
self.record, [{"edi_exchange_state": "input_receive_error"}]
)

def test_receive_no_allow_empty_file_triggers_notify_error(self):
self.record.edi_exchange_state = "input_pending"
conf = self._make_global_error_conf(self.record.type_id)
self.backend.with_context(
fake_output="", _edi_receive_break_on_error=False
).exchange_receive(self.record)
# The error event must fire so downstream notifications (e.g.
# edi_notification_oca activities) are triggered.
self.assertEqual(conf.description, "error-event-fired")

def test_receive_allow_empty_file_record(self):
self.record.edi_exchange_state = "input_pending"
self.record.type_id.allow_empty_files_on_receive = True
Expand Down
11 changes: 11 additions & 0 deletions edi_core_oca/tests/test_backend_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@ def test_send_record_with_error(self):
"OOPS! Something went wrong :(", self.record.exchange_error_traceback
)

def test_send_record_with_error_triggers_notify_error(self):
self.record.write({"edi_exchange_state": "output_pending"})
self.record._set_file_content(f"TEST {self.record.id}")
conf = self._make_global_error_conf(self.record.type_id)
self.record.with_context(
test_break_send="OOPS! Something went wrong :("
).action_exchange_send()
# The error event must fire so downstream notifications (e.g.
# edi_notification_oca activities) are triggered.
self.assertEqual(conf.description, "error-event-fired")

def test_send_invalid_direction(self):
vals = {
"model": self.partner._name,
Expand Down
22 changes: 22 additions & 0 deletions edi_core_oca/tests/test_backend_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ def test_receive_validate_record_error(self):
)
self.assertIn("Data seems wrong!", self.record_in.exchange_error_traceback)

def test_receive_validate_record_error_triggers_notify_error(self):
self.record_in.write({"edi_exchange_state": "input_pending"})
exc = EDIValidationError("Data seems wrong!")
conf = self._make_global_error_conf(self.record_in.type_id)
self.backend.with_context(test_break_input_validate=exc).exchange_receive(
self.record_in
)
# The error event must fire so downstream notifications (e.g.
# edi_notification_oca activities) are triggered.
self.assertEqual(conf.description, "error-event-fired")

def test_generate_validate_record(self):
self.record_out.write({"edi_exchange_state": "new"})
self.backend.exchange_generate(self.record_out)
Expand Down Expand Up @@ -119,6 +130,17 @@ def test_generate_validate_record_error(self):
)
self.assertIn("Data seems wrong!", self.record_out.exchange_error_traceback)

def test_generate_validate_record_error_triggers_notify_error(self):
self.record_out.write({"edi_exchange_state": "new"})
exc = EDIValidationError("Data seems wrong!")
conf = self._make_global_error_conf(self.record_out.type_id)
self.backend.with_context(test_break_output_validate=exc).exchange_generate(
self.record_out
)
# The error event must fire so downstream notifications (e.g.
# edi_notification_oca activities) are triggered.
self.assertEqual(conf.description, "error-event-fired")

def test_validate_record_error_regenerate(self):
self.record_out.write({"edi_exchange_state": "new"})
exc = EDIValidationError("Data seems wrong!")
Expand Down
6 changes: 3 additions & 3 deletions edi_endpoint_oca/i18n/it.po
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2026-05-25 22:46+0000\n"
"PO-Revision-Date: 2026-06-05 09:46+0000\n"
"Last-Translator: mymage <stefano.consolaro@mymage.it>\n"
"Language-Team: none\n"
"Language: it\n"
Expand Down Expand Up @@ -71,7 +71,7 @@ msgstr "Documenti esempio codice"
#. module: edi_endpoint_oca
#: model:ir.model.fields,help:edi_endpoint_oca.field_edi_endpoint__cors
msgid "Comma-separated list of allowed origins"
msgstr ""
msgstr "Elenco separato da virgola delle origini consentite"

#. module: edi_endpoint_oca
#: model:ir.model.fields,field_description:edi_endpoint_oca.field_edi_endpoint__company_id
Expand All @@ -81,7 +81,7 @@ msgstr "Azienda"
#. module: edi_endpoint_oca
#: model:ir.model.fields,field_description:edi_endpoint_oca.field_edi_endpoint__cors
msgid "Cors"
msgstr ""
msgstr "Cors"

#. module: edi_endpoint_oca
#. odoo-python
Expand Down
Loading