diff --git a/edi_queue_oca/README.rst b/edi_queue_oca/README.rst index c9b6f4945..dd84a7d8d 100644 --- a/edi_queue_oca/README.rst +++ b/edi_queue_oca/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ============= Edi Queue Oca ============= @@ -17,7 +13,7 @@ Edi Queue Oca .. |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-LGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fedi--framework-lightgray.png?logo=github @@ -65,11 +61,11 @@ Authors Contributors ------------ -- Simone Orsi -- Enric Tobella -- Manuel Regidor -- Thien Vo -- Jordi Masvidal +- Simone Orsi +- Enric Tobella +- Manuel Regidor +- Thien Vo +- Jordi Masvidal Maintainers ----------- diff --git a/edi_queue_oca/__manifest__.py b/edi_queue_oca/__manifest__.py index dec27cca5..e34d4ddf2 100644 --- a/edi_queue_oca/__manifest__.py +++ b/edi_queue_oca/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Edi Queue Oca", "summary": """Set Queue Jobs on EDI""", - "version": "18.0.1.0.2", + "version": "18.0.1.0.3", "license": "LGPL-3", "author": "Dixmit,Camptocamp,Odoo Community Association (OCA)", "website": "https://github.com/OCA/edi-framework", diff --git a/edi_queue_oca/data/job_function.xml b/edi_queue_oca/data/job_function.xml index aedc76dec..6183d9c3b 100644 --- a/edi_queue_oca/data/job_function.xml +++ b/edi_queue_oca/data/job_function.xml @@ -2,21 +2,25 @@ action_exchange_generate + _job_on_fail_generate action_exchange_send + _job_on_fail_send action_exchange_receive + _job_on_fail_receive action_exchange_process + _job_on_fail_process diff --git a/edi_queue_oca/migrations/18.0.1.0.3/post-migration.py b/edi_queue_oca/migrations/18.0.1.0.3/post-migration.py new file mode 100644 index 000000000..c0d734735 --- /dev/null +++ b/edi_queue_oca/migrations/18.0.1.0.3/post-migration.py @@ -0,0 +1,30 @@ +# Copyright 2026 Camptocamp SA (http://www.camptocamp.com) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +import logging + +from odoo import SUPERUSER_ID, api + +_logger = logging.getLogger(__name__) + +# The job functions are declared in a ``noupdate`` data file, so databases +# created before the on fail hooks were added never got ``on_fail_method``. +ON_FAIL_METHODS = { + "edi_queue_oca.job_fun_exchange_record_generate": "_job_on_fail_generate", + "edi_queue_oca.job_fun_exchange_record_send": "_job_on_fail_send", + "edi_queue_oca.job_fun_exchange_record_receive": "_job_on_fail_receive", + "edi_queue_oca.job_fun_exchange_record_process": "_job_on_fail_process", +} + + +def migrate(cr, version): + env = api.Environment(cr, SUPERUSER_ID, {}) + for xmlid, method in ON_FAIL_METHODS.items(): + job_function = env.ref(xmlid, raise_if_not_found=False) + if not job_function: + _logger.warning("Job function %s not found, skipping", xmlid) + continue + if job_function.on_fail_method: + continue + _logger.info("Setting on_fail_method=%s on %s", method, xmlid) + job_function.on_fail_method = method diff --git a/edi_queue_oca/models/edi_exchange_record.py b/edi_queue_oca/models/edi_exchange_record.py index 58915fa5a..6f420947f 100644 --- a/edi_queue_oca/models/edi_exchange_record.py +++ b/edi_queue_oca/models/edi_exchange_record.py @@ -91,3 +91,30 @@ def action_exchange_generate_send_chained(self): # Raise prio to max to send the record out as fast as possible. job1.on_done(self.delayable(priority=0).action_exchange_send()) job1.delay() + + def _job_on_fail_generate(self, **kw): + return self._job_on_fail_update("validate_error", **kw) + + def _job_on_fail_send(self, **kw): + return self._job_on_fail_update("output_error_on_send", **kw) + + def _job_on_fail_receive(self, **kw): + return self._job_on_fail_update("input_receive_error", **kw) + + def _job_on_fail_process(self, **kw): + return self._job_on_fail_update("input_processed_error", **kw) + + def _job_on_fail_update(self, failed_state, **kw): + self.ensure_one() + # ``exc_message`` is the first argument of the exception: it is not + # always a string (e.g. the errno of an ``OSError``) and may be missing. + error = ": ".join( + str(kw[k]) for k in ("exc_name", "exc_message") if kw.get(k) is not None + ) + self.write( + { + "edi_exchange_state": failed_state, + "exchange_error": error, + "exchange_error_traceback": kw.get("exc_info"), + } + ) diff --git a/edi_queue_oca/static/description/index.html b/edi_queue_oca/static/description/index.html index c65aff333..de5c87ae6 100644 --- a/edi_queue_oca/static/description/index.html +++ b/edi_queue_oca/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +Edi Queue Oca -
+
+

Edi Queue Oca

- - -Odoo Community Association - -
-

Edi Queue Oca

-

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

+

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

This module integrates EDI with Queue Job and now the edi exchange records are generated using queue.

No need of doing a configuration on it, however, we can specify priority @@ -392,7 +387,7 @@

Edi Queue Oca

-

Bug Tracker

+

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 @@ -400,16 +395,16 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Dixmit
  • Camptocamp
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -432,6 +427,5 @@

Maintainers

-
diff --git a/edi_queue_oca/tests/test_backend_jobs.py b/edi_queue_oca/tests/test_backend_jobs.py index 44c90eac7..71521d12a 100644 --- a/edi_queue_oca/tests/test_backend_jobs.py +++ b/edi_queue_oca/tests/test_backend_jobs.py @@ -159,3 +159,59 @@ def test_input_processed_error(self): # Check related jobs record.invalidate_recordset() self.assertEqual(created, self._get_related_jobs(record)) + + def test_on_fail_job(self): + vals = { + "model": self.partner._name, + "res_id": self.partner.id, + } + record = self.backend.create_record("test_csv_output", vals) + self.assertEqual(record.edi_exchange_state, "new") + job = record.action_exchange_generate() + exc_vals = { + "exc_info": "Dummy traceback", + "exc_name": "Dummy exception", + "exc_message": "Dummy message", + } + job.on_fail(exc_vals) + self.assertEqual(record.edi_exchange_state, "validate_error") + self.assertEqual( + record.exchange_error, + ": ".join([exc_vals["exc_name"], exc_vals["exc_message"]]), + ) + self.assertEqual(record.exchange_error_traceback, exc_vals["exc_info"]) + + def test_on_fail_job_non_string_message(self): + # The message is the first argument of the exception, which is the + # errno for an OSError, or may be missing altogether. + vals = { + "model": self.partner._name, + "res_id": self.partner.id, + } + record = self.backend.create_record("test_csv_output", vals) + job = record.action_exchange_generate() + job.on_fail( + { + "exc_info": "Dummy traceback", + "exc_name": "PermissionError", + "exc_message": 13, + } + ) + self.assertEqual(record.edi_exchange_state, "validate_error") + self.assertEqual(record.exchange_error, "PermissionError: 13") + job.on_fail( + { + "exc_info": "Dummy traceback", + "exc_name": "JobFoundDead", + "exc_message": None, + } + ) + self.assertEqual(record.exchange_error, "JobFoundDead") + job.on_fail( + { + "exc_info": "Dummy traceback", + "exc_name": None, + "exc_message": "Something went wrong", + } + ) + self.assertEqual(record.exchange_error, "Something went wrong")