From c5b679e9459387b53cd2120e5b3433500441db24 Mon Sep 17 00:00:00 2001 From: duongtq Date: Wed, 10 Jul 2024 12:14:22 +0700 Subject: [PATCH 1/3] [IMP] edi_oca: update docs for EDI Jobs --- edi_oca/README.rst | 11 +++- edi_oca/readme/CONFIGURE.rst | 9 ++++ edi_oca/static/description/index.html | 75 +++++++++++++++------------ 3 files changed, 60 insertions(+), 35 deletions(-) diff --git a/edi_oca/README.rst b/edi_oca/README.rst index 5f36f5d2d2..65507fa579 100644 --- a/edi_oca/README.rst +++ b/edi_oca/README.rst @@ -7,7 +7,7 @@ EDI !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:94c4f16b777e3058e707246c83141fbbefa255b7797d1f5131313f5c1b4bce9b + !! source digest: sha256:b91a993abd09a6569e0356331dda03f0d008aecd1e1e2bb36791d606a4a24c48 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png @@ -59,6 +59,15 @@ In order to define a new Exchange Record, we need to configure: * Backend * Components +Jobs +~~~~~~~~~~~~~~~~~~~~ + +1. 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. + +2. EDI User: more conscious EDI user that might sometimes need to debug things a bit further and thus needs access to related queue jobs. + +3. EDI Manager: full configuration access. + Component definition ~~~~~~~~~~~~~~~~~~~~ diff --git a/edi_oca/readme/CONFIGURE.rst b/edi_oca/readme/CONFIGURE.rst index acf6a0d286..9a2a834fc9 100644 --- a/edi_oca/readme/CONFIGURE.rst +++ b/edi_oca/readme/CONFIGURE.rst @@ -10,6 +10,15 @@ In order to define a new Exchange Record, we need to configure: * Backend * Components +Jobs +~~~~~~~~~~~~~~~~~~~~ + +1. 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. + +2. EDI User: more conscious EDI user that might sometimes need to debug things a bit further and thus needs access to related queue jobs. + +3. EDI Manager: full configuration access. + Component definition ~~~~~~~~~~~~~~~~~~~~ diff --git a/edi_oca/static/description/index.html b/edi_oca/static/description/index.html index 1f7897d692..bed134c5ad 100644 --- a/edi_oca/static/description/index.html +++ b/edi_oca/static/description/index.html @@ -1,3 +1,4 @@ + @@ -8,11 +9,10 @@ /* :Author: David Goodger (goodger@python.org) -:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $ +:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $ :Copyright: This stylesheet has been placed in the public domain. Default cascading style sheet for the HTML output of Docutils. -Despite the name, some widely supported CSS2 features are used. See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to customize this style sheet. @@ -275,7 +275,7 @@ margin-left: 2em ; margin-right: 2em } -pre.code .ln { color: gray; } /* line numbers */ +pre.code .ln { color: grey; } /* line numbers */ pre.code, code { background-color: #eeeeee } pre.code .comment, code .comment { color: #5C6576 } pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } @@ -301,7 +301,7 @@ span.pre { white-space: pre } -span.problematic, pre.problematic { +span.problematic { color: red } span.section-subtitle { @@ -367,7 +367,7 @@

EDI

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:94c4f16b777e3058e707246c83141fbbefa255b7797d1f5131313f5c1b4bce9b +!! source digest: sha256:b91a993abd09a6569e0356331dda03f0d008aecd1e1e2bb36791d606a4a24c48 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

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

Base EDI backend.

@@ -383,25 +383,26 @@

EDI

-

Usage

+

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

+

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:

@@ -475,7 +484,7 @@

Output Exchange records

-

Input Exchange records

+

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:

-

Known issues / Roadmap

+

Known issues / Roadmap

-

14.0.1.0.0

+

14.0.1.0.0

The module name has been changed from edi to edi_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 @@ -502,9 +511,9 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • ACSONE
  • Creu Blanca
  • @@ -512,18 +521,16 @@

    Authors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

- -Odoo Community Association - +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.

From a08eed6638322bebd7371f4dd948b534eecd6691 Mon Sep 17 00:00:00 2001 From: Quoc Duong Date: Tue, 23 Jul 2024 10:06:54 +0700 Subject: [PATCH 2/3] [IMP] edi_oca: add smart button in record form to show all related queue jobs --- edi_oca/README.rst | 2 +- edi_oca/models/edi_exchange_record.py | 35 +++++++++++++++++++++ edi_oca/readme/CONFIGURE.rst | 2 +- edi_oca/security/ir_model_access.xml | 12 +++++++ edi_oca/tests/test_backend_jobs.py | 16 ++++++++++ edi_oca/tests/test_security.py | 2 +- edi_oca/views/edi_exchange_record_views.xml | 17 ++++++++++ 7 files changed, 83 insertions(+), 3 deletions(-) diff --git a/edi_oca/README.rst b/edi_oca/README.rst index 65507fa579..b46fe387d4 100644 --- a/edi_oca/README.rst +++ b/edi_oca/README.rst @@ -60,7 +60,7 @@ In order to define a new Exchange Record, we need to configure: * Components Jobs -~~~~~~~~~~~~~~~~~~~~ +~~~~ 1. 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. diff --git a/edi_oca/models/edi_exchange_record.py b/edi_oca/models/edi_exchange_record.py index 13b3c94322..e49bc6c6ce 100644 --- a/edi_oca/models/edi_exchange_record.py +++ b/edi_oca/models/edi_exchange_record.py @@ -5,6 +5,7 @@ import base64 import logging +from ast import literal_eval from collections import defaultdict from odoo import _, api, exceptions, fields, models @@ -112,6 +113,10 @@ class EDIExchangeRecord(models.Model): compute="_compute_retryable", help="The record state can be rolled back manually in case of failure.", ) + related_queue_jobs_count = fields.Integer( + compute="_compute_related_queue_jobs_count" + ) + company_id = fields.Many2one("res.company", string="Company") _sql_constraints = [ ("identifier_uniq", "unique(identifier)", "The identifier must be unique."), @@ -620,3 +625,33 @@ def _inverse_res_id(self): }) except (KeyError, ValueError, MissingError): continue + + def _compute_related_queue_jobs_count(self): + for rec in self: + # TODO: We should refactor the object field on queue_job to use jsonb field + # so that we can search directly into it. + rec.related_queue_jobs_count = rec.env["queue.job"].search_count( + [("func_string", "like", str(rec))] + ) + + def action_view_related_queue_jobs(self): + self.ensure_one() + xmlid = "queue_job.action_queue_job" + action = self.env.ref(xmlid).read()[0] + # Searching based on task name. + # Ex: `edi.exchange.record(1,).action_exchange_send()` + # TODO: We should refactor the object field on queue_job to use jsonb field + # so that we can search directly into it. + action["domain"] = [("func_string", "like", str(self))] + # Purge default search filters from ctx to avoid hiding records + ctx = action.get("context", {}) + if isinstance(ctx, str): + ctx = literal_eval(ctx) + # Update the current contexts + ctx.update(self.env.context) + action["context"] = { + k: v for k, v in ctx.items() if not k.startswith("search_default_") + } + # Drop ID otherwise the context will be loaded from the action's record + action.pop("id") + return action diff --git a/edi_oca/readme/CONFIGURE.rst b/edi_oca/readme/CONFIGURE.rst index 9a2a834fc9..de8331ad77 100644 --- a/edi_oca/readme/CONFIGURE.rst +++ b/edi_oca/readme/CONFIGURE.rst @@ -11,7 +11,7 @@ In order to define a new Exchange Record, we need to configure: * Components Jobs -~~~~~~~~~~~~~~~~~~~~ +~~~~ 1. 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. diff --git a/edi_oca/security/ir_model_access.xml b/edi_oca/security/ir_model_access.xml index 90b3461145..a398ca8269 100644 --- a/edi_oca/security/ir_model_access.xml +++ b/edi_oca/security/ir_model_access.xml @@ -45,6 +45,18 @@ + + + + access_queue_job edi user + + + + + + + + access_edi_backend_type user diff --git a/edi_oca/tests/test_backend_jobs.py b/edi_oca/tests/test_backend_jobs.py index ac23a298ad..e0f70a4909 100644 --- a/edi_oca/tests/test_backend_jobs.py +++ b/edi_oca/tests/test_backend_jobs.py @@ -16,6 +16,12 @@ class EDIBackendTestJobsCase(EDIBackendCommonTestCase, JobMixin): def _setup_context(cls): return dict(super()._setup_context(), test_queue_job_no_delay=None) + def _get_related_jobs(self, record): + # Use domain in action to find all related jobs + record.ensure_one() + action = record.action_view_related_queue_jobs() + return self.env["queue.job"].search(action["domain"]) + def test_output(self): job_counter = self.job_counter() vals = { @@ -30,6 +36,8 @@ def test_output(self): self.assertEqual( created.name, "Generate output content for given exchange record." ) + # Check related jobs + self.assertEqual(created, self._get_related_jobs(record)) with mock.patch.object( type(self.backend), "_exchange_generate" ) as mocked_generate, mock.patch.object( @@ -48,6 +56,9 @@ def test_output(self): self.assertEqual(res, "Exchange sent") self.assertEqual(record.edi_exchange_state, "output_sent") self.assertEqual(created[0].name, "Send exchange file.") + # Check related jobs + record.invalidate_cache() + self.assertEqual(created, self._get_related_jobs(record)) def test_output_fail_retry(self): job_counter = self.job_counter() @@ -76,6 +87,8 @@ def test_input(self): created = job_counter.search_created() self.assertEqual(len(created), 1) self.assertEqual(created.name, "Retrieve an incoming document.") + # Check related jobs + self.assertEqual(created, self._get_related_jobs(record)) with mock.patch.object( type(self.backend), "_exchange_receive" ) as mocked_receive, mock.patch.object( @@ -115,3 +128,6 @@ def test_input_processed_error(self): new_created = job_counter.search_created() - created # Should not create new job self.assertEqual(len(new_created), 0) + # Check related jobs + record.invalidate_cache() + self.assertEqual(created, self._get_related_jobs(record)) diff --git a/edi_oca/tests/test_security.py b/edi_oca/tests/test_security.py index 84bcc4e05b..b6dda46426 100644 --- a/edi_oca/tests/test_security.py +++ b/edi_oca/tests/test_security.py @@ -49,7 +49,7 @@ def _setup_records(cls): "name": "Poor Partner (not integrating one)", "email": "poor.partner@ododo.com", "login": "poorpartner", - "groups_id": [(6, 0, [cls.env.ref("base.group_user").id])], + "groups_id": [(6, 0, [cls.env.ref("base_edi.group_edi_user").id])], } ) ) diff --git a/edi_oca/views/edi_exchange_record_views.xml b/edi_oca/views/edi_exchange_record_views.xml index aa2d022fa0..67d9097bba 100644 --- a/edi_oca/views/edi_exchange_record_views.xml +++ b/edi_oca/views/edi_exchange_record_views.xml @@ -87,6 +87,23 @@ /> +
+ +