From 61af2324fe6ea43ad24f033995a78ebfd3ef9d99 Mon Sep 17 00:00:00 2001 From: KevinKhao Date: Mon, 18 May 2020 08:14:39 +0200 Subject: [PATCH 01/21] [ADD] queue_job_chunk --- queue_job_chunk/README.rst | 1 + queue_job_chunk/__init__.py | 2 + queue_job_chunk/__manifest__.py | 17 +++++ queue_job_chunk/components/__init__.py | 1 + queue_job_chunk/components/processor.py | 11 ++++ queue_job_chunk/models/__init__.py | 1 + queue_job_chunk/models/queue_job_chunk.py | 67 ++++++++++++++++++++ queue_job_chunk/readme/CONTRIBUTORS.rst | 2 + queue_job_chunk/readme/CREDITS.rst | 3 + queue_job_chunk/readme/DESCRIPTION.rst | 1 + queue_job_chunk/readme/USAGE.rst | 2 + queue_job_chunk/security/ir.model.access.csv | 3 + queue_job_chunk/security/security.xml | 22 +++++++ queue_job_chunk/views/queue_job_chunk.xml | 50 +++++++++++++++ 14 files changed, 183 insertions(+) create mode 100644 queue_job_chunk/README.rst create mode 100644 queue_job_chunk/__init__.py create mode 100644 queue_job_chunk/__manifest__.py create mode 100644 queue_job_chunk/components/__init__.py create mode 100644 queue_job_chunk/components/processor.py create mode 100644 queue_job_chunk/models/__init__.py create mode 100644 queue_job_chunk/models/queue_job_chunk.py create mode 100644 queue_job_chunk/readme/CONTRIBUTORS.rst create mode 100644 queue_job_chunk/readme/CREDITS.rst create mode 100644 queue_job_chunk/readme/DESCRIPTION.rst create mode 100644 queue_job_chunk/readme/USAGE.rst create mode 100644 queue_job_chunk/security/ir.model.access.csv create mode 100644 queue_job_chunk/security/security.xml create mode 100644 queue_job_chunk/views/queue_job_chunk.xml diff --git a/queue_job_chunk/README.rst b/queue_job_chunk/README.rst new file mode 100644 index 0000000000..c1b0730e01 --- /dev/null +++ b/queue_job_chunk/README.rst @@ -0,0 +1 @@ +x \ No newline at end of file diff --git a/queue_job_chunk/__init__.py b/queue_job_chunk/__init__.py new file mode 100644 index 0000000000..0f00a6730d --- /dev/null +++ b/queue_job_chunk/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import components diff --git a/queue_job_chunk/__manifest__.py b/queue_job_chunk/__manifest__.py new file mode 100644 index 0000000000..393b83a479 --- /dev/null +++ b/queue_job_chunk/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright (c) Akretion 2020 +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) + +{ + "name": "Job Queue Chunk", + "version": "12.0.1.0.1", + "author": "Akretion", + "website": "https://github.com/OCA/queue", + "license": "AGPL-3", + "category": "Generic Modules", + "depends": ["queue_job", "component"], + "data": [ + "views/queue_job_chunk.xml", + "security/security.xml", + "security/ir.model.access.csv", + ], +} diff --git a/queue_job_chunk/components/__init__.py b/queue_job_chunk/components/__init__.py new file mode 100644 index 0000000000..ad6975d748 --- /dev/null +++ b/queue_job_chunk/components/__init__.py @@ -0,0 +1 @@ +from . import processor diff --git a/queue_job_chunk/components/processor.py b/queue_job_chunk/components/processor.py new file mode 100644 index 0000000000..c7722f946b --- /dev/null +++ b/queue_job_chunk/components/processor.py @@ -0,0 +1,11 @@ +# Copyright (c) Akretion 2020 +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) + +from odoo.addons.component.core import AbstractComponent + + +# DISCUSSION: abstractcomponent? +class Processor(AbstractComponent): + _name = "processor" + _inherit = "base" + _collection = "collection.base" diff --git a/queue_job_chunk/models/__init__.py b/queue_job_chunk/models/__init__.py new file mode 100644 index 0000000000..6ef57c378a --- /dev/null +++ b/queue_job_chunk/models/__init__.py @@ -0,0 +1 @@ +from . import queue_job_chunk diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py new file mode 100644 index 0000000000..443bd6b235 --- /dev/null +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -0,0 +1,67 @@ +# Copyright (c) Akretion 2020 +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) + +from odoo import api, fields, models + +from odoo.addons.queue_job.job import job + + +class QueueJobChunk(models.Model): + _name = "queue.job.chunk" + _description = "Queue Job Chunk" + + def _get_default_company_id(self): + for rec in self: + if rec.reference: + if "company_id" in rec.reference._fields: + rec.company_id = rec.reference.company_id + continue + rec.company_id = self.env.uid.company_id + + @api.depends("model_id", "record_id") + def _compute_reference(self): + for res in self: + res.reference = "{},{}".format(res.model, res.res_id) + + # component fields + usage = fields.Char("Usage") + apply_on_model = fields.Char("Apply on model") + + data_str = fields.Text(string="Editable data") + state = fields.Selection( + [("pending", "Pending"), ("done", "Done"), ("fail", "Failed")], + default="pending", + string="State", + ) + model_id = fields.Char("Model ID") + record_id = fields.Integer("Record ID") + reference = fields.Char(string="Reference", selection=_compute_reference) + company_id = fields.Many2one("res.company", default=_get_default_company_id) + + def create(self, vals): + result = super().create(vals) + result.enqueue_job() + return result + + def button_retry(self): + self.enqueue_job() + + def enqueue_job(self): + return self.with_delay()._enqueue_job() + + @job + def _enqueue_job(self): + self.ensure_one() + usage = self.usage + collection = self.env["collection.base"].new() + apply_on = self.apply_on_model + self.model_id = apply_on + with collection.work_on(apply_on) as work: + processor = work.component(usage=usage) + try: + result = processor.run(self.data_str) + self.state = "done" + except Exception: + self.state = "fail" + raise + return result diff --git a/queue_job_chunk/readme/CONTRIBUTORS.rst b/queue_job_chunk/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000000..79f515ed4a --- /dev/null +++ b/queue_job_chunk/readme/CONTRIBUTORS.rst @@ -0,0 +1,2 @@ +* Kevin Khao +* Sébastien Beau diff --git a/queue_job_chunk/readme/CREDITS.rst b/queue_job_chunk/readme/CREDITS.rst new file mode 100644 index 0000000000..93e871ee0e --- /dev/null +++ b/queue_job_chunk/readme/CREDITS.rst @@ -0,0 +1,3 @@ +The development of this module has been financially supported by: + +* Akretion diff --git a/queue_job_chunk/readme/DESCRIPTION.rst b/queue_job_chunk/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..c9306d238e --- /dev/null +++ b/queue_job_chunk/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Adds the notion of queue job chunks, essentially a queue job with some metadata. diff --git a/queue_job_chunk/readme/USAGE.rst b/queue_job_chunk/readme/USAGE.rst new file mode 100644 index 0000000000..60d2c2d8f7 --- /dev/null +++ b/queue_job_chunk/readme/USAGE.rst @@ -0,0 +1,2 @@ +Use it +TODO diff --git a/queue_job_chunk/security/ir.model.access.csv b/queue_job_chunk/security/ir.model.access.csv new file mode 100644 index 0000000000..94516efb23 --- /dev/null +++ b/queue_job_chunk/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_queue_job_chunk_manager,queue job manager,model_queue_job_chunk,queue_job.group_queue_job_manager,1,1,1,1 +access_queue_job_queue_job_chunk_user,queue job manager,queue_job.model_queue_job,group_queue_job_chunk_user,1,0,0,0 diff --git a/queue_job_chunk/security/security.xml b/queue_job_chunk/security/security.xml new file mode 100644 index 0000000000..be1466d87e --- /dev/null +++ b/queue_job_chunk/security/security.xml @@ -0,0 +1,22 @@ + + + + + Job Queue chunk User + + + + + + + + + Job Queue chunk multi-company + + ['|', ('company_id', '=', False), + ('company_id', 'child_of', [user.company_id.id])] + + + diff --git a/queue_job_chunk/views/queue_job_chunk.xml b/queue_job_chunk/views/queue_job_chunk.xml new file mode 100644 index 0000000000..883e4fbd51 --- /dev/null +++ b/queue_job_chunk/views/queue_job_chunk.xml @@ -0,0 +1,50 @@ + + + + + queue.job.chunk + +
+
+
+ + + + + + + + + + + + + +
+
+
+ + + queue.job.chunk + + + + + + + + + + + + Queue Job Chunks + ir.actions.act_window + queue.job.chunk + tree,form + + + + +
From 43f0321c39eebddb69e95914f0bbc482cb634bcf Mon Sep 17 00:00:00 2001 From: KevinKhao Date: Wed, 3 Jun 2020 22:41:33 +0200 Subject: [PATCH 02/21] [IMP] Creation logic and saving record state/id/model --- queue_job_chunk/components/processor.py | 22 +++++++- queue_job_chunk/models/queue_job_chunk.py | 15 +++-- queue_job_chunk/tests/__init__.py | 1 + queue_job_chunk/tests/test_queue_job_chunk.py | 56 +++++++++++++++++++ 4 files changed, 87 insertions(+), 7 deletions(-) create mode 100644 queue_job_chunk/tests/__init__.py create mode 100644 queue_job_chunk/tests/test_queue_job_chunk.py diff --git a/queue_job_chunk/components/processor.py b/queue_job_chunk/components/processor.py index c7722f946b..6b7409c547 100644 --- a/queue_job_chunk/components/processor.py +++ b/queue_job_chunk/components/processor.py @@ -1,11 +1,29 @@ # Copyright (c) Akretion 2020 # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) -from odoo.addons.component.core import AbstractComponent +import ast + +from odoo.addons.component.core import AbstractComponent, Component -# DISCUSSION: abstractcomponent? class Processor(AbstractComponent): _name = "processor" _inherit = "base" _collection = "collection.base" + + +class Creator( + Component +): # TODO resolve issue with in-module component tests, move to test + """ Just creates a record with given vals """ + + _inherit = "base" + _name = "basic.creator" + _collection = "collection.base" + _apply_on = ["res.partner", "ir.module.module"] + _usage = "basic_create" + + def run(self, data): + create_vals = ast.literal_eval(data) + result = self.model.create(create_vals) + return result diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index 443bd6b235..93ad66642e 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -33,14 +33,17 @@ def _compute_reference(self): default="pending", string="State", ) + state_info = fields.Text("Additional state information") model_id = fields.Char("Model ID") record_id = fields.Integer("Record ID") reference = fields.Char(string="Reference", selection=_compute_reference) company_id = fields.Many2one("res.company", default=_get_default_company_id) + @api.model_create_multi def create(self, vals): result = super().create(vals) - result.enqueue_job() + for rec in result: + rec.enqueue_job() return result def button_retry(self): @@ -55,13 +58,15 @@ def _enqueue_job(self): usage = self.usage collection = self.env["collection.base"].new() apply_on = self.apply_on_model - self.model_id = apply_on with collection.work_on(apply_on) as work: processor = work.component(usage=usage) try: result = processor.run(self.data_str) - self.state = "done" - except Exception: + except Exception as e: self.state = "fail" - raise + self.state_info = str(e) + return False + self.model_id = result._name + self.record_id = result.id + self.state = "done" return result diff --git a/queue_job_chunk/tests/__init__.py b/queue_job_chunk/tests/__init__.py new file mode 100644 index 0000000000..da23e049c7 --- /dev/null +++ b/queue_job_chunk/tests/__init__.py @@ -0,0 +1 @@ +from . import test_queue_job_chunk diff --git a/queue_job_chunk/tests/test_queue_job_chunk.py b/queue_job_chunk/tests/test_queue_job_chunk.py new file mode 100644 index 0000000000..b25fcccc9d --- /dev/null +++ b/queue_job_chunk/tests/test_queue_job_chunk.py @@ -0,0 +1,56 @@ +# Copyright (c) Akretion 2020 +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) + + +from odoo.addons.component.tests.common import TransactionComponentCase + + +class TestQueueJobChunk(TransactionComponentCase): + def setUp(self): + super().setUp() + self.env = self.env( + context=dict(self.env.context, test_queue_job_no_delay=True) + ) + + def test_create_chunk(self): + partner_count = self.env["res.partner"].search_count([]) + module_count = self.env["ir.module.module"].search_count([]) + + chunk_data_1 = "{'name': 'Steve Queue Job'}" + chunk_vals_1 = { + "apply_on_model": "res.partner", + "data_str": chunk_data_1, + "usage": "basic_create", + } + + chunk_data_2 = "{'name': 'New Module Name'}" + chunk_vals_2 = { + "apply_on_model": "ir.module.module", + "data_str": chunk_data_2, + "usage": "basic_create", + } + chunk_vals = [chunk_vals_1, chunk_vals_2] + self.env["queue.job.chunk"].create(chunk_vals) + new_partner_count = self.env["res.partner"].search_count([]) + new_module_count = self.env["ir.module.module"].search_count([]) + self.assertEqual(partner_count + 1, new_partner_count) + self.assertEqual(module_count + 1, new_module_count) + + def test_create_chunk_fail_retry(self): + partner_count = self.env["res.partner"].search_count([]) + chunk_data = "{':::'Bad json format}" + chunk_vals = { + "apply_on_model": "res.partner", + "data_str": chunk_data, + "usage": "basic_create", + } + + chunk = self.env["queue.job.chunk"].create(chunk_vals) + new_partner_count = self.env["res.partner"].search_count([]) + self.assertEqual(partner_count, new_partner_count) + self.assertEqual(chunk.state, "fail") + # retry with correct data + chunk.data_str = "{'name': 'Steve Queue Job'}" + chunk.button_retry() + new_partner_count = self.env["res.partner"].search_count([]) + self.assertEqual(partner_count + 1, new_partner_count) From 9dc67c51e032fc64518b9e1195873a00446c58ca Mon Sep 17 00:00:00 2001 From: KevinKhao Date: Wed, 3 Jun 2020 22:48:40 +0200 Subject: [PATCH 03/21] [IMP] Improved form view --- queue_job_chunk/views/queue_job_chunk.xml | 26 ++++++++++++++--------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/queue_job_chunk/views/queue_job_chunk.xml b/queue_job_chunk/views/queue_job_chunk.xml index 883e4fbd51..fa584a4cd5 100644 --- a/queue_job_chunk/views/queue_job_chunk.xml +++ b/queue_job_chunk/views/queue_job_chunk.xml @@ -6,19 +6,25 @@
-
- - - - - - - - - + + + + + + + + + + + +
From 887663d497cd3424a710f38f98754cc01c105545 Mon Sep 17 00:00:00 2001 From: KevinKhao Date: Thu, 4 Jun 2020 19:28:33 +0200 Subject: [PATCH 04/21] [IMP] Logic on queue.job.chunk, company_ids, tests, and component separation --- queue_job_chunk/components/__init__.py | 1 + queue_job_chunk/components/creator.py | 18 ++++ queue_job_chunk/components/processor.py | 23 +--- queue_job_chunk/models/queue_job_chunk.py | 32 +++--- queue_job_chunk/tests/test_queue_job_chunk.py | 101 +++++++++++++----- queue_job_chunk/views/queue_job_chunk.xml | 4 +- 6 files changed, 108 insertions(+), 71 deletions(-) create mode 100644 queue_job_chunk/components/creator.py diff --git a/queue_job_chunk/components/__init__.py b/queue_job_chunk/components/__init__.py index ad6975d748..067f394379 100644 --- a/queue_job_chunk/components/__init__.py +++ b/queue_job_chunk/components/__init__.py @@ -1 +1,2 @@ from . import processor +from . import creator diff --git a/queue_job_chunk/components/creator.py b/queue_job_chunk/components/creator.py new file mode 100644 index 0000000000..2c413136a3 --- /dev/null +++ b/queue_job_chunk/components/creator.py @@ -0,0 +1,18 @@ +# Copyright (c) Akretion 2020 +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) + +import json + +from odoo.addons.component.core import Component + + +class Creator(Component): + """ Just creates a record with given vals """ + + _inherit = "processor" + _name = "basic.creator" + _usage = "basic_create" + + def run(self, data): + data = json.loads(data) + return self.model.create(data) diff --git a/queue_job_chunk/components/processor.py b/queue_job_chunk/components/processor.py index 6b7409c547..c7b24187aa 100644 --- a/queue_job_chunk/components/processor.py +++ b/queue_job_chunk/components/processor.py @@ -1,29 +1,10 @@ # Copyright (c) Akretion 2020 # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) -import ast - -from odoo.addons.component.core import AbstractComponent, Component +from odoo.addons.component.core import AbstractComponent class Processor(AbstractComponent): _name = "processor" _inherit = "base" - _collection = "collection.base" - - -class Creator( - Component -): # TODO resolve issue with in-module component tests, move to test - """ Just creates a record with given vals """ - - _inherit = "base" - _name = "basic.creator" - _collection = "collection.base" - _apply_on = ["res.partner", "ir.module.module"] - _usage = "basic_create" - - def run(self, data): - create_vals = ast.literal_eval(data) - result = self.model.create(create_vals) - return result + _collection = "queue.job.chunk" diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index 93ad66642e..b365bf3f5b 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -9,19 +9,16 @@ class QueueJobChunk(models.Model): _name = "queue.job.chunk" _description = "Queue Job Chunk" + _inherit = "collection.base" - def _get_default_company_id(self): - for rec in self: - if rec.reference: - if "company_id" in rec.reference._fields: - rec.company_id = rec.reference.company_id - continue - rec.company_id = self.env.uid.company_id - - @api.depends("model_id", "record_id") + @api.depends("model_name", "record_id") def _compute_reference(self): - for res in self: - res.reference = "{},{}".format(res.model, res.res_id) + for rec in self: + if rec.model_name and rec.record_id: + rec.reference = "{},{}".format(rec.model_name, rec.record_id) + record = self.env[rec.model_name].browse(rec.record_id) + if "company_id" in record._fields: + rec.reference_company_id = record.company_id # component fields usage = fields.Char("Usage") @@ -34,10 +31,10 @@ def _compute_reference(self): string="State", ) state_info = fields.Text("Additional state information") - model_id = fields.Char("Model ID") + model_name = fields.Char("Model ID") record_id = fields.Integer("Record ID") - reference = fields.Char(string="Reference", selection=_compute_reference) - company_id = fields.Many2one("res.company", default=_get_default_company_id) + reference = fields.Char(string="Reference", compute=_compute_reference) + reference_company_id = fields.Many2one("res.company", compute=_compute_reference) @api.model_create_multi def create(self, vals): @@ -56,17 +53,14 @@ def enqueue_job(self): def _enqueue_job(self): self.ensure_one() usage = self.usage - collection = self.env["collection.base"].new() apply_on = self.apply_on_model - with collection.work_on(apply_on) as work: - processor = work.component(usage=usage) + with self.work_on(apply_on) as work: try: + processor = work.component(usage=usage) result = processor.run(self.data_str) except Exception as e: self.state = "fail" self.state_info = str(e) return False - self.model_id = result._name - self.record_id = result.id self.state = "done" return result diff --git a/queue_job_chunk/tests/test_queue_job_chunk.py b/queue_job_chunk/tests/test_queue_job_chunk.py index b25fcccc9d..a1bdbb9c17 100644 --- a/queue_job_chunk/tests/test_queue_job_chunk.py +++ b/queue_job_chunk/tests/test_queue_job_chunk.py @@ -11,46 +11,89 @@ def setUp(self): self.env = self.env( context=dict(self.env.context, test_queue_job_no_delay=True) ) - - def test_create_chunk(self): - partner_count = self.env["res.partner"].search_count([]) - module_count = self.env["ir.module.module"].search_count([]) - - chunk_data_1 = "{'name': 'Steve Queue Job'}" - chunk_vals_1 = { + self.main_company = self.env.ref("base.main_company") + self.another_company_partner = self.env["res.partner"].create( + {"name": "Company2"} + ) + self.another_company = self.env["res.company"].create( + { + "name": self.another_company_partner.name, + "partner_id": self.another_company_partner.id, + "currency_id": self.env.ref("base.main_company").currency_id.id, + } + ) + self.partner = self.env.ref("base.res_partner_3") + self.chunk_data_contact = [ + { + "apply_on_model": "res.partner", + "data_str": '{"name": "Steve Queue Job"}', + "usage": "basic_create", + "model_name": "res.partner", + "record_id": self.partner.id, + }, + { + "apply_on_model": "res.partner", + "data_str": '{"name": "Other"}', + "usage": "basic_create", + "model_name": "res.partner", + "record_id": self.partner.id, + }, + ] + self.chunk_data_bad = { "apply_on_model": "res.partner", - "data_str": chunk_data_1, + "data_str": "{''(;,),x*}", "usage": "basic_create", + "model_name": "res.partner", + "record_id": self.partner.id, } - - chunk_data_2 = "{'name': 'New Module Name'}" - chunk_vals_2 = { - "apply_on_model": "ir.module.module", - "data_str": chunk_data_2, + USA = self.env.ref("base.us") + self.chunk_data_state = { + "apply_on_model": "res.country.state", + "data_str": '{"name": "New Stateshire", "code": "NS", "country_id": %d}' + % USA.id, "usage": "basic_create", + "model_name": "res.country", + "record_id": USA.id, } - chunk_vals = [chunk_vals_1, chunk_vals_2] - self.env["queue.job.chunk"].create(chunk_vals) + + def test_create_chunk(self): + partner_count = self.env["res.partner"].search_count([]) + chunk = self.env["queue.job.chunk"].create(self.chunk_data_contact) new_partner_count = self.env["res.partner"].search_count([]) - new_module_count = self.env["ir.module.module"].search_count([]) - self.assertEqual(partner_count + 1, new_partner_count) - self.assertEqual(module_count + 1, new_module_count) + self.assertEqual(chunk[0].state, "done") + self.assertEqual(chunk[1].state, "done") + self.assertEqual(partner_count + 2, new_partner_count) def test_create_chunk_fail_retry(self): partner_count = self.env["res.partner"].search_count([]) - chunk_data = "{':::'Bad json format}" - chunk_vals = { - "apply_on_model": "res.partner", - "data_str": chunk_data, - "usage": "basic_create", - } - - chunk = self.env["queue.job.chunk"].create(chunk_vals) - new_partner_count = self.env["res.partner"].search_count([]) - self.assertEqual(partner_count, new_partner_count) + # fail with bad data + chunk = self.env["queue.job.chunk"].create(self.chunk_data_bad) self.assertEqual(chunk.state, "fail") + # retry with correct data - chunk.data_str = "{'name': 'Steve Queue Job'}" + chunk.data_str = '{"name": "Steve Queue Job"}' chunk.button_retry() new_partner_count = self.env["res.partner"].search_count([]) self.assertEqual(partner_count + 1, new_partner_count) + + def test_create_chunk_without_company_id(self): + chunk = self.env["queue.job.chunk"].create(self.chunk_data_state) + self.assertEqual(chunk.reference_company_id, self.env["res.company"]) + + def test_create_chunk_with_company_id(self): + company = self.partner.company_id + chunk = self.env["queue.job.chunk"].create(self.chunk_data_contact[0]) + self.assertEqual(company, chunk.reference_company_id) + + def test_reference(self): + chunk = self.env["queue.job.chunk"].create(self.chunk_data_contact[0]) + self.assertEqual(chunk.reference, "res.partner,%i" % self.partner.id) + + def test_create_chunk_job(self): + job_count = self.env["queue.job"].search_count([]) + self.env = self.env( + context=dict(self.env.context, test_queue_job_no_delay=False) + ) + self.env["queue.job.chunk"].create(self.chunk_data_contact[0]) + new_job_count = self.env["queue.job"].search_count([]) + self.assertEqual(job_count + 1, new_job_count) diff --git a/queue_job_chunk/views/queue_job_chunk.xml b/queue_job_chunk/views/queue_job_chunk.xml index fa584a4cd5..a86c8c0c27 100644 --- a/queue_job_chunk/views/queue_job_chunk.xml +++ b/queue_job_chunk/views/queue_job_chunk.xml @@ -15,7 +15,7 @@ - + @@ -37,7 +37,7 @@ - + From 1c10d3ffd6bb703683a458c0aa2265c6508825e9 Mon Sep 17 00:00:00 2001 From: KevinKhao Date: Fri, 5 Jun 2020 11:46:03 +0200 Subject: [PATCH 05/21] [IMP] Rename reference_company_id to company_id, add company calculation according to user, modify tests --- queue_job_chunk/models/queue_job_chunk.py | 9 +++++++-- queue_job_chunk/tests/test_queue_job_chunk.py | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index b365bf3f5b..484c79581a 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -18,7 +18,12 @@ def _compute_reference(self): rec.reference = "{},{}".format(rec.model_name, rec.record_id) record = self.env[rec.model_name].browse(rec.record_id) if "company_id" in record._fields: - rec.reference_company_id = record.company_id + rec.company_id = record.company_id + else: + rec.company_id = self.env.user.company_id + else: + rec.reference = False + rec.company_id = False # component fields usage = fields.Char("Usage") @@ -34,7 +39,7 @@ def _compute_reference(self): model_name = fields.Char("Model ID") record_id = fields.Integer("Record ID") reference = fields.Char(string="Reference", compute=_compute_reference) - reference_company_id = fields.Many2one("res.company", compute=_compute_reference) + company_id = fields.Many2one("res.company", compute=_compute_reference) @api.model_create_multi def create(self, vals): diff --git a/queue_job_chunk/tests/test_queue_job_chunk.py b/queue_job_chunk/tests/test_queue_job_chunk.py index a1bdbb9c17..b6a7147560 100644 --- a/queue_job_chunk/tests/test_queue_job_chunk.py +++ b/queue_job_chunk/tests/test_queue_job_chunk.py @@ -78,12 +78,12 @@ def test_create_chunk_fail_retry(self): def test_create_chunk_without_company_id(self): chunk = self.env["queue.job.chunk"].create(self.chunk_data_state) - self.assertEqual(chunk.reference_company_id, self.env["res.company"]) + self.assertEqual(chunk.company_id, self.env.user.company_id) def test_create_chunk_with_company_id(self): company = self.partner.company_id chunk = self.env["queue.job.chunk"].create(self.chunk_data_contact[0]) - self.assertEqual(company, chunk.reference_company_id) + self.assertEqual(company, chunk.company_id) def test_reference(self): chunk = self.env["queue.job.chunk"].create(self.chunk_data_contact[0]) From 1af01f9088e7ab22750f16bc39cfda14d95beb07 Mon Sep 17 00:00:00 2001 From: KevinKhao Date: Fri, 5 Jun 2020 12:07:17 +0200 Subject: [PATCH 06/21] [IMP] Change logic for company_id calculation --- queue_job_chunk/components/creator.py | 4 ++-- queue_job_chunk/models/queue_job_chunk.py | 24 ++++++++++--------- queue_job_chunk/tests/test_queue_job_chunk.py | 2 +- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/queue_job_chunk/components/creator.py b/queue_job_chunk/components/creator.py index 2c413136a3..4b4c2e0ecb 100644 --- a/queue_job_chunk/components/creator.py +++ b/queue_job_chunk/components/creator.py @@ -13,6 +13,6 @@ class Creator(Component): _name = "basic.creator" _usage = "basic_create" - def run(self, data): - data = json.loads(data) + def run(self): + data = json.loads(self.collection.data_str) return self.model.create(data) diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index 484c79581a..88480d8cd1 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -14,16 +14,14 @@ class QueueJobChunk(models.Model): @api.depends("model_name", "record_id") def _compute_reference(self): for rec in self: + rec.company_id = self.env.user.company_id if rec.model_name and rec.record_id: rec.reference = "{},{}".format(rec.model_name, rec.record_id) record = self.env[rec.model_name].browse(rec.record_id) if "company_id" in record._fields: rec.company_id = record.company_id - else: - rec.company_id = self.env.user.company_id else: - rec.reference = False - rec.company_id = False + rec.reference = None # component fields usage = fields.Char("Usage") @@ -38,8 +36,10 @@ def _compute_reference(self): state_info = fields.Text("Additional state information") model_name = fields.Char("Model ID") record_id = fields.Integer("Record ID") - reference = fields.Char(string="Reference", compute=_compute_reference) - company_id = fields.Many2one("res.company", compute=_compute_reference) + reference = fields.Reference( + selection=[], string="Reference", compute=_compute_reference, store=True + ) + company_id = fields.Many2one("res.company", compute=_compute_reference, store=True) @api.model_create_multi def create(self, vals): @@ -52,20 +52,22 @@ def button_retry(self): self.enqueue_job() def enqueue_job(self): - return self.with_delay()._enqueue_job() + return self.with_delay().process_chunk() @job - def _enqueue_job(self): + def process_chunk(self): self.ensure_one() usage = self.usage apply_on = self.apply_on_model with self.work_on(apply_on) as work: try: - processor = work.component(usage=usage) - result = processor.run(self.data_str) + with self.env.cr.savepoint(): + processor = work.component(usage=usage) + result = processor.run() except Exception as e: self.state = "fail" - self.state_info = str(e) + self.state_info = type(e).__name__ + str(e.args) return False + self.state_info = "" self.state = "done" return result diff --git a/queue_job_chunk/tests/test_queue_job_chunk.py b/queue_job_chunk/tests/test_queue_job_chunk.py index b6a7147560..07b42a0440 100644 --- a/queue_job_chunk/tests/test_queue_job_chunk.py +++ b/queue_job_chunk/tests/test_queue_job_chunk.py @@ -87,7 +87,7 @@ def test_create_chunk_with_company_id(self): def test_reference(self): chunk = self.env["queue.job.chunk"].create(self.chunk_data_contact[0]) - self.assertEqual(chunk.reference, "res.partner,%i" % self.partner.id) + self.assertEqual(chunk.reference, self.partner) def test_create_chunk_job(self): job_count = self.env["queue.job"].search_count([]) From 62290fa6797e5beb43d8708f662b634cb4cfacd1 Mon Sep 17 00:00:00 2001 From: KevinKhao Date: Sat, 4 Jul 2020 20:41:17 +0200 Subject: [PATCH 07/21] Cleanup/README --- queue_job_chunk/README.rst | 72 ++- queue_job_chunk/readme/USAGE.rst | 4 +- queue_job_chunk/static/description/index.html | 429 ++++++++++++++++++ 3 files changed, 502 insertions(+), 3 deletions(-) create mode 100644 queue_job_chunk/static/description/index.html diff --git a/queue_job_chunk/README.rst b/queue_job_chunk/README.rst index c1b0730e01..db6ad6d67b 100644 --- a/queue_job_chunk/README.rst +++ b/queue_job_chunk/README.rst @@ -1 +1,71 @@ -x \ No newline at end of file +=============== +Job Queue Chunk +=============== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-akretion%2Fodoo--incubator-lightgray.png?logo=github + :target: https://github.com/akretion/odoo-incubator/tree/12.0/queue_job_chunk + :alt: akretion/odoo-incubator + +|badge1| |badge2| |badge3| + +Adds the notion of queue job chunks, essentially a queue job with some metadata. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Use it +TODO + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Akretion + +Contributors +~~~~~~~~~~~~ + +* Kevin Khao +* Sébastien Beau + +Other credits +~~~~~~~~~~~~~ + +The development of this module has been financially supported by: + +* Akretion + +Maintainers +~~~~~~~~~~~ + +This module is part of the `akretion/odoo-incubator `_ project on GitHub. + +You are welcome to contribute. diff --git a/queue_job_chunk/readme/USAGE.rst b/queue_job_chunk/readme/USAGE.rst index 60d2c2d8f7..8c28e6d57d 100644 --- a/queue_job_chunk/readme/USAGE.rst +++ b/queue_job_chunk/readme/USAGE.rst @@ -1,2 +1,2 @@ -Use it -TODO +1. Create a queue job chunk using relevant fields to specify which service to use +2. Use menu to check its status and if you want to, modify its contents to re-run it diff --git a/queue_job_chunk/static/description/index.html b/queue_job_chunk/static/description/index.html new file mode 100644 index 0000000000..8ca347b305 --- /dev/null +++ b/queue_job_chunk/static/description/index.html @@ -0,0 +1,429 @@ + + + + + + +Job Queue Chunk + + + +
+

Job Queue Chunk

+ + +

Beta License: AGPL-3 akretion/odoo-incubator

+

Adds the notion of queue job chunks, essentially a queue job with some metadata.

+

Table of contents

+ +
+

Usage

+

Use it +TODO

+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

The development of this module has been financially supported by:

+
    +
  • Akretion <www.akretion.com>
  • +
+
+
+

Maintainers

+

This module is part of the akretion/odoo-incubator project on GitHub.

+

You are welcome to contribute.

+
+
+
+ + From 2cc2a31ca34c333273e02b27a6d8ccb9f8e347f1 Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Thu, 26 Nov 2020 14:53:19 +0100 Subject: [PATCH 08/21] [IMP] run pre-commit --- queue_job_chunk/__manifest__.py | 1 + queue_job_chunk/security/security.xml | 13 +++---- queue_job_chunk/views/queue_job_chunk.xml | 43 +++++++++++++---------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/queue_job_chunk/__manifest__.py b/queue_job_chunk/__manifest__.py index 393b83a479..658d821d5a 100644 --- a/queue_job_chunk/__manifest__.py +++ b/queue_job_chunk/__manifest__.py @@ -14,4 +14,5 @@ "security/security.xml", "security/ir.model.access.csv", ], + "installable": False, } diff --git a/queue_job_chunk/security/security.xml b/queue_job_chunk/security/security.xml index be1466d87e..6ee28a57c0 100644 --- a/queue_job_chunk/security/security.xml +++ b/queue_job_chunk/security/security.xml @@ -1,20 +1,21 @@ - + Job Queue chunk User - + - + Job Queue chunk multi-company - + ['|', ('company_id', '=', False), ('company_id', 'child_of', [user.company_id.id])] diff --git a/queue_job_chunk/views/queue_job_chunk.xml b/queue_job_chunk/views/queue_job_chunk.xml index a86c8c0c27..b6012da7c9 100644 --- a/queue_job_chunk/views/queue_job_chunk.xml +++ b/queue_job_chunk/views/queue_job_chunk.xml @@ -1,4 +1,4 @@ - + @@ -6,24 +6,27 @@
-
- - - - - - + + + + + + - - + + @@ -35,10 +38,10 @@ queue.job.chunk - - - - + + + + @@ -50,7 +53,11 @@ tree,form - + From 8987eda41033385589ab11e5775e46e5cf78fa4d Mon Sep 17 00:00:00 2001 From: Kevin Khao Date: Wed, 25 Nov 2020 18:14:00 +0100 Subject: [PATCH 09/21] [14.0][MIG] Migration to 14.0 --- queue_job_chunk/README.rst | 16 ++--- queue_job_chunk/__manifest__.py | 10 +-- queue_job_chunk/components/creator.py | 4 +- queue_job_chunk/components/processor.py | 2 +- queue_job_chunk/models/queue_job_chunk.py | 62 ++++++++++++++----- queue_job_chunk/static/description/index.html | 21 ++++--- queue_job_chunk/tests/test_queue_job_chunk.py | 2 +- 7 files changed, 78 insertions(+), 39 deletions(-) diff --git a/queue_job_chunk/README.rst b/queue_job_chunk/README.rst index db6ad6d67b..36dafebd0e 100644 --- a/queue_job_chunk/README.rst +++ b/queue_job_chunk/README.rst @@ -13,9 +13,9 @@ Job Queue Chunk .. |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-akretion%2Fodoo--incubator-lightgray.png?logo=github - :target: https://github.com/akretion/odoo-incubator/tree/12.0/queue_job_chunk - :alt: akretion/odoo-incubator +.. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fsale--import-lightgray.png?logo=github + :target: https://github.com/akretion/sale-import/tree/14.0/queue_job_chunk + :alt: akretion/sale-import |badge1| |badge2| |badge3| @@ -29,16 +29,16 @@ Adds the notion of queue job chunks, essentially a queue job with some metadata. Usage ===== -Use it -TODO +1. Create a queue job chunk using relevant fields to specify which service to use +2. Use menu to check its status and if you want to, modify its contents to re-run it Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. +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 smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -66,6 +66,6 @@ The development of this module has been financially supported by: Maintainers ~~~~~~~~~~~ -This module is part of the `akretion/odoo-incubator `_ project on GitHub. +This module is part of the `akretion/sale-import `_ project on GitHub. You are welcome to contribute. diff --git a/queue_job_chunk/__manifest__.py b/queue_job_chunk/__manifest__.py index 658d821d5a..6b7c5e690b 100644 --- a/queue_job_chunk/__manifest__.py +++ b/queue_job_chunk/__manifest__.py @@ -1,11 +1,11 @@ # Copyright (c) Akretion 2020 -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) { "name": "Job Queue Chunk", - "version": "12.0.1.0.1", - "author": "Akretion", - "website": "https://github.com/OCA/queue", + "version": "14.0.1.0.1", + "author": "Akretion, Odoo Community Association (OCA)", + "website": "https://github.com/akretion/sale-import", "license": "AGPL-3", "category": "Generic Modules", "depends": ["queue_job", "component"], @@ -14,5 +14,5 @@ "security/security.xml", "security/ir.model.access.csv", ], - "installable": False, + "installable": True, } diff --git a/queue_job_chunk/components/creator.py b/queue_job_chunk/components/creator.py index 4b4c2e0ecb..e314fc6f8b 100644 --- a/queue_job_chunk/components/creator.py +++ b/queue_job_chunk/components/creator.py @@ -1,5 +1,5 @@ # Copyright (c) Akretion 2020 -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) import json @@ -7,7 +7,7 @@ class Creator(Component): - """ Just creates a record with given vals """ + """Just creates a record with given vals""" _inherit = "processor" _name = "basic.creator" diff --git a/queue_job_chunk/components/processor.py b/queue_job_chunk/components/processor.py index c7b24187aa..17298c48cd 100644 --- a/queue_job_chunk/components/processor.py +++ b/queue_job_chunk/components/processor.py @@ -1,5 +1,5 @@ # Copyright (c) Akretion 2020 -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) from odoo.addons.component.core import AbstractComponent diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index 88480d8cd1..a86b95c0f3 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -1,9 +1,13 @@ # Copyright (c) Akretion 2020 -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) + +from psycopg2 import OperationalError from odoo import api, fields, models +from odoo.service.model import PG_CONCURRENCY_ERRORS_TO_RETRY -from odoo.addons.queue_job.job import job +# Use to bypass chunks entirely for easier debugging +DEBUG_MODE = False class QueueJobChunk(models.Model): @@ -11,17 +15,22 @@ class QueueJobChunk(models.Model): _description = "Queue Job Chunk" _inherit = "collection.base" + @api.model + def _selection_target_model(self): + models = self.env["ir.model"].search([]) + return [(model.model, model.name) for model in models] + @api.depends("model_name", "record_id") def _compute_reference(self): for rec in self: rec.company_id = self.env.user.company_id if rec.model_name and rec.record_id: - rec.reference = "{},{}".format(rec.model_name, rec.record_id) + rec.reference = "{},{}".format(rec.model_name, rec.record_id or 0) record = self.env[rec.model_name].browse(rec.record_id) if "company_id" in record._fields: rec.company_id = record.company_id else: - rec.reference = None + rec.reference = False # component fields usage = fields.Char("Usage") @@ -37,7 +46,10 @@ def _compute_reference(self): model_name = fields.Char("Model ID") record_id = fields.Integer("Record ID") reference = fields.Reference( - selection=[], string="Reference", compute=_compute_reference, store=True + string="Reference", + selection="_selection_target_model", + compute=_compute_reference, + store=True, ) company_id = fields.Many2one("res.company", compute=_compute_reference, store=True) @@ -52,22 +64,42 @@ def button_retry(self): self.enqueue_job() def enqueue_job(self): - return self.with_delay().process_chunk() + if DEBUG_MODE: + return self.process_chunk() + else: + return self.with_delay().process_chunk() - @job def process_chunk(self): self.ensure_one() usage = self.usage apply_on = self.apply_on_model with self.work_on(apply_on) as work: - try: + if DEBUG_MODE: with self.env.cr.savepoint(): processor = work.component(usage=usage) result = processor.run() - except Exception as e: - self.state = "fail" - self.state_info = type(e).__name__ + str(e.args) - return False - self.state_info = "" - self.state = "done" - return result + self.state_info = "" + self.state = "done" + return result + else: + try: + with self.env.cr.savepoint(): + processor = work.component(usage=usage) + result = processor.run() + except Exception as e: + # TODO maybe it will be simplier to have a kind of inherits + #  on queue.job to avoid a double error management + # so a failling chunk will have a failling job + if ( + isinstance(e, OperationalError) + and e.pgcode in PG_CONCURRENCY_ERRORS_TO_RETRY + ): + # In that case we raise an error so queue_job + # will do a RetryableJobError + raise + self.state = "fail" + self.state_info = type(e).__name__ + str(e.args) + return False + self.state_info = "" + self.state = "done" + return result diff --git a/queue_job_chunk/static/description/index.html b/queue_job_chunk/static/description/index.html index 8ca347b305..d167d2e3f8 100644 --- a/queue_job_chunk/static/description/index.html +++ b/queue_job_chunk/static/description/index.html @@ -367,7 +367,7 @@

Job Queue Chunk

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 akretion/odoo-incubator

+

Beta License: AGPL-3 OCA/sale-import Translate me on Weblate

Adds the notion of queue job chunks, essentially a queue job with some metadata.

Table of contents

@@ -385,15 +385,17 @@

Job Queue Chunk

Usage

-

Use it -TODO

+
    +
  1. Create a queue job chunk using relevant fields to specify which service to use
  2. +
  3. Use menu to check its status and if you want to, modify its contents to re-run it
  4. +

Bug Tracker

-

Bugs are tracked on GitHub Issues. +

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 smashing it by providing a detailed and welcomed -feedback.

+feedback.

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

@@ -420,8 +422,13 @@

Other credits

Maintainers

-

This module is part of the akretion/odoo-incubator project on GitHub.

-

You are welcome to contribute.

+

This module is maintained by the OCA.

+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.

+

This module is part of the OCA/sale-import project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/queue_job_chunk/tests/test_queue_job_chunk.py b/queue_job_chunk/tests/test_queue_job_chunk.py index 07b42a0440..a5efa83ef2 100644 --- a/queue_job_chunk/tests/test_queue_job_chunk.py +++ b/queue_job_chunk/tests/test_queue_job_chunk.py @@ -1,5 +1,5 @@ # Copyright (c) Akretion 2020 -# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) from odoo.addons.component.tests.common import TransactionComponentCase From 7dd7a3a265425c8644c2c2c8e73b87946b5e2760 Mon Sep 17 00:00:00 2001 From: Matthieu Saison Date: Fri, 15 Apr 2022 11:49:42 +0200 Subject: [PATCH 10/21] new field stack trace to help failed chunk job --- queue_job_chunk/__manifest__.py | 4 ++-- queue_job_chunk/models/queue_job_chunk.py | 4 ++++ queue_job_chunk/views/queue_job_chunk.xml | 5 +++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/queue_job_chunk/__manifest__.py b/queue_job_chunk/__manifest__.py index 6b7c5e690b..19c9ec8104 100644 --- a/queue_job_chunk/__manifest__.py +++ b/queue_job_chunk/__manifest__.py @@ -5,7 +5,7 @@ "name": "Job Queue Chunk", "version": "14.0.1.0.1", "author": "Akretion, Odoo Community Association (OCA)", - "website": "https://github.com/akretion/sale-import", + "website": "https://github.com/OCA/sale-channel", "license": "AGPL-3", "category": "Generic Modules", "depends": ["queue_job", "component"], @@ -14,5 +14,5 @@ "security/security.xml", "security/ir.model.access.csv", ], - "installable": True, + "installable": False, } diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index a86b95c0f3..70c0c6fd2c 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -1,6 +1,8 @@ # Copyright (c) Akretion 2020 # License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) +import traceback + from psycopg2 import OperationalError from odoo import api, fields, models @@ -52,6 +54,7 @@ def _compute_reference(self): store=True, ) company_id = fields.Many2one("res.company", compute=_compute_reference, store=True) + stack_trace = fields.Text("Stack trace") @api.model_create_multi def create(self, vals): @@ -99,6 +102,7 @@ def process_chunk(self): raise self.state = "fail" self.state_info = type(e).__name__ + str(e.args) + self.stack_trace = traceback.format_exc() return False self.state_info = "" self.state = "done" diff --git a/queue_job_chunk/views/queue_job_chunk.xml b/queue_job_chunk/views/queue_job_chunk.xml index b6012da7c9..0b6ced2bed 100644 --- a/queue_job_chunk/views/queue_job_chunk.xml +++ b/queue_job_chunk/views/queue_job_chunk.xml @@ -23,6 +23,11 @@ + From c0a3dc6072ef633c344646e0447ad56553d239c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Fri, 30 Dec 2022 11:23:40 +0100 Subject: [PATCH 11/21] queue_job_chunk: Migration to 16.0 --- queue_job_chunk/__manifest__.py | 4 ++-- queue_job_chunk/models/queue_job_chunk.py | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/queue_job_chunk/__manifest__.py b/queue_job_chunk/__manifest__.py index 19c9ec8104..84c37a156e 100644 --- a/queue_job_chunk/__manifest__.py +++ b/queue_job_chunk/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Job Queue Chunk", - "version": "14.0.1.0.1", + "version": "16.0.0.0.0", "author": "Akretion, Odoo Community Association (OCA)", "website": "https://github.com/OCA/sale-channel", "license": "AGPL-3", @@ -14,5 +14,5 @@ "security/security.xml", "security/ir.model.access.csv", ], - "installable": False, + "installable": True, } diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index 70c0c6fd2c..1eb4172b6a 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -35,26 +35,24 @@ def _compute_reference(self): rec.reference = False # component fields - usage = fields.Char("Usage") - apply_on_model = fields.Char("Apply on model") + usage = fields.Char() + apply_on_model = fields.Char() data_str = fields.Text(string="Editable data") state = fields.Selection( [("pending", "Pending"), ("done", "Done"), ("fail", "Failed")], default="pending", - string="State", ) state_info = fields.Text("Additional state information") - model_name = fields.Char("Model ID") - record_id = fields.Integer("Record ID") + model_name = fields.Char() + record_id = fields.Integer() reference = fields.Reference( - string="Reference", selection="_selection_target_model", compute=_compute_reference, store=True, ) company_id = fields.Many2one("res.company", compute=_compute_reference, store=True) - stack_trace = fields.Text("Stack trace") + stack_trace = fields.Text() @api.model_create_multi def create(self, vals): From 842983cd67c657d195f0bd8a85b4fc61ccb12f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Fri, 30 Dec 2022 15:46:36 +0100 Subject: [PATCH 12/21] queue_job_chunk: refactor remove dependency on component --- queue_job_chunk/__init__.py | 1 - queue_job_chunk/__manifest__.py | 2 +- queue_job_chunk/components/__init__.py | 2 - queue_job_chunk/components/creator.py | 18 --- queue_job_chunk/components/processor.py | 10 -- queue_job_chunk/models/queue_job_chunk.py | 103 +++++++++--------- queue_job_chunk/tests/models.py | 41 +++++++ queue_job_chunk/tests/test_queue_job_chunk.py | 62 ++++++----- queue_job_chunk/views/queue_job_chunk.xml | 5 +- 9 files changed, 126 insertions(+), 118 deletions(-) delete mode 100644 queue_job_chunk/components/__init__.py delete mode 100644 queue_job_chunk/components/creator.py delete mode 100644 queue_job_chunk/components/processor.py create mode 100644 queue_job_chunk/tests/models.py diff --git a/queue_job_chunk/__init__.py b/queue_job_chunk/__init__.py index 0f00a6730d..0650744f6b 100644 --- a/queue_job_chunk/__init__.py +++ b/queue_job_chunk/__init__.py @@ -1,2 +1 @@ from . import models -from . import components diff --git a/queue_job_chunk/__manifest__.py b/queue_job_chunk/__manifest__.py index 84c37a156e..6ea21f12ae 100644 --- a/queue_job_chunk/__manifest__.py +++ b/queue_job_chunk/__manifest__.py @@ -8,7 +8,7 @@ "website": "https://github.com/OCA/sale-channel", "license": "AGPL-3", "category": "Generic Modules", - "depends": ["queue_job", "component"], + "depends": ["queue_job"], "data": [ "views/queue_job_chunk.xml", "security/security.xml", diff --git a/queue_job_chunk/components/__init__.py b/queue_job_chunk/components/__init__.py deleted file mode 100644 index 067f394379..0000000000 --- a/queue_job_chunk/components/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from . import processor -from . import creator diff --git a/queue_job_chunk/components/creator.py b/queue_job_chunk/components/creator.py deleted file mode 100644 index e314fc6f8b..0000000000 --- a/queue_job_chunk/components/creator.py +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (c) Akretion 2020 -# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) - -import json - -from odoo.addons.component.core import Component - - -class Creator(Component): - """Just creates a record with given vals""" - - _inherit = "processor" - _name = "basic.creator" - _usage = "basic_create" - - def run(self): - data = json.loads(self.collection.data_str) - return self.model.create(data) diff --git a/queue_job_chunk/components/processor.py b/queue_job_chunk/components/processor.py deleted file mode 100644 index 17298c48cd..0000000000 --- a/queue_job_chunk/components/processor.py +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) Akretion 2020 -# License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) - -from odoo.addons.component.core import AbstractComponent - - -class Processor(AbstractComponent): - _name = "processor" - _inherit = "base" - _collection = "queue.job.chunk" diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index 1eb4172b6a..a6c03918a4 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -1,6 +1,7 @@ # Copyright (c) Akretion 2020 # License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) +import json import traceback from psycopg2 import OperationalError @@ -15,7 +16,27 @@ class QueueJobChunk(models.Model): _name = "queue.job.chunk" _description = "Queue Job Chunk" - _inherit = "collection.base" + + processor = fields.Char() + data_str = fields.Text(string="Editable data") + state = fields.Selection( + [("pending", "Pending"), ("done", "Done"), ("fail", "Failed")], + default="pending", + ) + state_info = fields.Text("Additional state information") + model_name = fields.Char() + record_id = fields.Integer() + reference = fields.Reference( + selection="_selection_target_model", + compute="_compute_reference", + store=True, + ) + company_id = fields.Many2one( + "res.company", + compute="_compute_reference", + store=True, + ) + stack_trace = fields.Text() @api.model def _selection_target_model(self): @@ -34,26 +55,6 @@ def _compute_reference(self): else: rec.reference = False - # component fields - usage = fields.Char() - apply_on_model = fields.Char() - - data_str = fields.Text(string="Editable data") - state = fields.Selection( - [("pending", "Pending"), ("done", "Done"), ("fail", "Failed")], - default="pending", - ) - state_info = fields.Text("Additional state information") - model_name = fields.Char() - record_id = fields.Integer() - reference = fields.Reference( - selection="_selection_target_model", - compute=_compute_reference, - store=True, - ) - company_id = fields.Many2one("res.company", compute=_compute_reference, store=True) - stack_trace = fields.Text() - @api.model_create_multi def create(self, vals): result = super().create(vals) @@ -70,38 +71,34 @@ def enqueue_job(self): else: return self.with_delay().process_chunk() + def _get_processor(self): + # return here whatever class you want + # it can be a pure python class, an odoo TransientModel ... + raise NotImplementedError + def process_chunk(self): self.ensure_one() - usage = self.usage - apply_on = self.apply_on_model - with self.work_on(apply_on) as work: + try: + with self.env.cr.savepoint(): + processor = self._get_processor() + result = processor.run(json.loads(self.data_str)) + except Exception as e: if DEBUG_MODE: - with self.env.cr.savepoint(): - processor = work.component(usage=usage) - result = processor.run() - self.state_info = "" - self.state = "done" - return result - else: - try: - with self.env.cr.savepoint(): - processor = work.component(usage=usage) - result = processor.run() - except Exception as e: - # TODO maybe it will be simplier to have a kind of inherits - #  on queue.job to avoid a double error management - # so a failling chunk will have a failling job - if ( - isinstance(e, OperationalError) - and e.pgcode in PG_CONCURRENCY_ERRORS_TO_RETRY - ): - # In that case we raise an error so queue_job - # will do a RetryableJobError - raise - self.state = "fail" - self.state_info = type(e).__name__ + str(e.args) - self.stack_trace = traceback.format_exc() - return False - self.state_info = "" - self.state = "done" - return result + raise + # TODO maybe it will be simplier to have a kind of inherits + #  on queue.job to avoid a double error management + # so a failling chunk will have a failling job + if ( + isinstance(e, OperationalError) + and e.pgcode in PG_CONCURRENCY_ERRORS_TO_RETRY + ): + # In that case we raise an error so queue_job + # will do a RetryableJobError + raise + self.state = "fail" + self.state_info = type(e).__name__ + str(e.args) + self.stack_trace = traceback.format_exc() + return False + self.state_info = "" + self.state = "done" + return result diff --git a/queue_job_chunk/tests/models.py b/queue_job_chunk/tests/models.py new file mode 100644 index 0000000000..9441c77a1e --- /dev/null +++ b/queue_job_chunk/tests/models.py @@ -0,0 +1,41 @@ +# Copyright 2022 Akretion (https://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +# Exemple of pure python processor (inherit is not possible) +class TestPythonPartnerProcessor: + def __init__(self, env): + super().__init__() + self.env = env + + def run(self, data): + return self.env["res.partner"].create(data) + + +# Exemple of odoo processor (inherit is possible) +class TestOdooStateProcessor(models.TransientModel): + _name = "test.odoo.state.processor" + _description = "Chunk Processor State Create" + + def run(self, data): + return self.env["res.country.state"].create(data) + + +class QueueJobChunk(models.Model): + _inherit = "queue.job.chunk" + + processor = fields.Selection( + [ + ("test_partner", "Test create Partner"), + ("test_state", "Test create Country State"), + ], + ) + + def _get_processor(self): + if self.processor == "test_partner": + return TestPythonPartnerProcessor(self.env) + elif self.processor == "test_state": + return self.env["test.odoo.state.processor"] diff --git a/queue_job_chunk/tests/test_queue_job_chunk.py b/queue_job_chunk/tests/test_queue_job_chunk.py index a5efa83ef2..a47ba8c651 100644 --- a/queue_job_chunk/tests/test_queue_job_chunk.py +++ b/queue_job_chunk/tests/test_queue_job_chunk.py @@ -2,56 +2,60 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html) -from odoo.addons.component.tests.common import TransactionComponentCase +from odoo_test_helper import FakeModelLoader +from odoo.tests import TransactionCase -class TestQueueJobChunk(TransactionComponentCase): - def setUp(self): - super().setUp() - self.env = self.env( - context=dict(self.env.context, test_queue_job_no_delay=True) - ) - self.main_company = self.env.ref("base.main_company") - self.another_company_partner = self.env["res.partner"].create( + +class TestQueueJobChunk(TransactionCase, FakeModelLoader): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + from .models import QueueJobChunk, TestOdooStateProcessor + + cls.loader.update_registry((TestOdooStateProcessor, QueueJobChunk)) + + cls.env = cls.env(context=dict(cls.env.context, test_queue_job_no_delay=True)) + cls.main_company = cls.env.ref("base.main_company") + cls.another_company_partner = cls.env["res.partner"].create( {"name": "Company2"} ) - self.another_company = self.env["res.company"].create( + cls.another_company = cls.env["res.company"].create( { - "name": self.another_company_partner.name, - "partner_id": self.another_company_partner.id, - "currency_id": self.env.ref("base.main_company").currency_id.id, + "name": cls.another_company_partner.name, + "partner_id": cls.another_company_partner.id, + "currency_id": cls.env.ref("base.main_company").currency_id.id, } ) - self.partner = self.env.ref("base.res_partner_3") - self.chunk_data_contact = [ + cls.partner = cls.env.ref("base.res_partner_3") + cls.chunk_data_contact = [ { - "apply_on_model": "res.partner", "data_str": '{"name": "Steve Queue Job"}', - "usage": "basic_create", + "processor": "test_partner", "model_name": "res.partner", - "record_id": self.partner.id, + "record_id": cls.partner.id, }, { - "apply_on_model": "res.partner", "data_str": '{"name": "Other"}', - "usage": "basic_create", + "processor": "test_partner", "model_name": "res.partner", - "record_id": self.partner.id, + "record_id": cls.partner.id, }, ] - self.chunk_data_bad = { - "apply_on_model": "res.partner", + cls.chunk_data_bad = { "data_str": "{''(;,),x*}", - "usage": "basic_create", + "processor": "test_partner", "model_name": "res.partner", - "record_id": self.partner.id, + "record_id": cls.partner.id, } - USA = self.env.ref("base.us") - self.chunk_data_state = { - "apply_on_model": "res.country.state", + USA = cls.env.ref("base.us") + cls.chunk_data_state = { + "processor": "test_state", "data_str": '{"name": "New Stateshire", "code": "NS", "country_id": %d}' % USA.id, - "usage": "basic_create", "model_name": "res.country", "record_id": USA.id, } diff --git a/queue_job_chunk/views/queue_job_chunk.xml b/queue_job_chunk/views/queue_job_chunk.xml index 0b6ced2bed..cb0460009e 100644 --- a/queue_job_chunk/views/queue_job_chunk.xml +++ b/queue_job_chunk/views/queue_job_chunk.xml @@ -17,6 +17,7 @@ + @@ -29,10 +30,6 @@ attrs="{'readonly': 1}" /> - - - - From 146e6357e4d111a899a917d1507d7e8818dc029f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Sun, 1 Jan 2023 17:33:17 +0100 Subject: [PATCH 13/21] sale_import_base: refactor and migration to V16 --- queue_job_chunk/models/queue_job_chunk.py | 7 +++++-- queue_job_chunk/tests/models.py | 21 ++++++++++++--------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index a6c03918a4..e177e92bc6 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -17,7 +17,7 @@ class QueueJobChunk(models.Model): _name = "queue.job.chunk" _description = "Queue Job Chunk" - processor = fields.Char() + processor = fields.Selection([]) data_str = fields.Text(string="Editable data") state = fields.Selection( [("pending", "Pending"), ("done", "Done"), ("fail", "Failed")], @@ -76,12 +76,15 @@ def _get_processor(self): # it can be a pure python class, an odoo TransientModel ... raise NotImplementedError + def _get_data(self): + return json.loads(self.data_str) + def process_chunk(self): self.ensure_one() try: with self.env.cr.savepoint(): processor = self._get_processor() - result = processor.run(json.loads(self.data_str)) + result = processor.run() except Exception as e: if DEBUG_MODE: raise diff --git a/queue_job_chunk/tests/models.py b/queue_job_chunk/tests/models.py index 9441c77a1e..37c6e8af6f 100644 --- a/queue_job_chunk/tests/models.py +++ b/queue_job_chunk/tests/models.py @@ -7,12 +7,13 @@ # Exemple of pure python processor (inherit is not possible) class TestPythonPartnerProcessor: - def __init__(self, env): + def __init__(self, chunk): super().__init__() - self.env = env + self.env = chunk.env + self.chunk = chunk - def run(self, data): - return self.env["res.partner"].create(data) + def run(self): + return self.env["res.partner"].create(self.chunk._get_data()) # Exemple of odoo processor (inherit is possible) @@ -20,15 +21,17 @@ class TestOdooStateProcessor(models.TransientModel): _name = "test.odoo.state.processor" _description = "Chunk Processor State Create" - def run(self, data): - return self.env["res.country.state"].create(data) + chunk_id = fields.Many2one("queue.job.chunk", "Chunk") + + def run(self): + return self.env["res.country.state"].create(self.chunk_id._get_data()) class QueueJobChunk(models.Model): _inherit = "queue.job.chunk" processor = fields.Selection( - [ + selection_add=[ ("test_partner", "Test create Partner"), ("test_state", "Test create Country State"), ], @@ -36,6 +39,6 @@ class QueueJobChunk(models.Model): def _get_processor(self): if self.processor == "test_partner": - return TestPythonPartnerProcessor(self.env) + return TestPythonPartnerProcessor(self) elif self.processor == "test_state": - return self.env["test.odoo.state.processor"] + return self.env["test.odoo.state.processor"].new({"chunk_id": self.id}) From a25418e4f43cf7ab77287a3095a9595a641df191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20BEAU?= Date: Tue, 3 Jan 2023 23:48:57 +0100 Subject: [PATCH 14/21] queue_job_chunk: improve code --- queue_job_chunk/models/queue_job_chunk.py | 12 ++++--- queue_job_chunk/views/queue_job_chunk.xml | 41 ++++++++++++++++------- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index e177e92bc6..3d820565a9 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -16,27 +16,31 @@ class QueueJobChunk(models.Model): _name = "queue.job.chunk" _description = "Queue Job Chunk" + _order = "id desc" processor = fields.Selection([]) data_str = fields.Text(string="Editable data") state = fields.Selection( [("pending", "Pending"), ("done", "Done"), ("fail", "Failed")], default="pending", + readonly=True, ) - state_info = fields.Text("Additional state information") - model_name = fields.Char() - record_id = fields.Integer() + state_info = fields.Text("Additional state information", readonly=True) + model_name = fields.Char(readonly=True) + record_id = fields.Integer(readonly=True) reference = fields.Reference( selection="_selection_target_model", compute="_compute_reference", store=True, + readonly=True, ) company_id = fields.Many2one( "res.company", compute="_compute_reference", store=True, + readonly=True, ) - stack_trace = fields.Text() + stack_trace = fields.Text(readonly=True) @api.model def _selection_target_model(self): diff --git a/queue_job_chunk/views/queue_job_chunk.xml b/queue_job_chunk/views/queue_job_chunk.xml index cb0460009e..ed7d7c1b31 100644 --- a/queue_job_chunk/views/queue_job_chunk.xml +++ b/queue_job_chunk/views/queue_job_chunk.xml @@ -13,22 +13,16 @@ attrs="{'invisible': [('state', '=', 'done')]}" class="btn-primary" /> + + + + - - - - - - @@ -40,14 +34,35 @@ queue.job.chunk - + + + - - +
+ + queue.job.chunk + + + + + + + + + + Queue Job Chunks ir.actions.act_window From c6ec51350c45c9006c4ef7a241aa3c40792bcf20 Mon Sep 17 00:00:00 2001 From: Florian da Costa Date: Tue, 30 May 2023 10:57:03 +0200 Subject: [PATCH 15/21] [IMP] queue_job_chunk : Manage retryable Errors --- queue_job_chunk/models/queue_job_chunk.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/queue_job_chunk/models/queue_job_chunk.py b/queue_job_chunk/models/queue_job_chunk.py index 3d820565a9..80e1516b0d 100644 --- a/queue_job_chunk/models/queue_job_chunk.py +++ b/queue_job_chunk/models/queue_job_chunk.py @@ -9,6 +9,8 @@ from odoo import api, fields, models from odoo.service.model import PG_CONCURRENCY_ERRORS_TO_RETRY +from odoo.addons.queue_job.exception import RetryableJobError + # Use to bypass chunks entirely for easier debugging DEBUG_MODE = False @@ -89,6 +91,8 @@ def process_chunk(self): with self.env.cr.savepoint(): processor = self._get_processor() result = processor.run() + except RetryableJobError: + raise except Exception as e: if DEBUG_MODE: raise From bea479cc8535ec6dce7fad68cbe05a33f444300b Mon Sep 17 00:00:00 2001 From: hparfr Date: Thu, 6 Jul 2023 14:06:51 +0200 Subject: [PATCH 16/21] queue_job_chunk: fix multicompany rule --- queue_job_chunk/security/security.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/queue_job_chunk/security/security.xml b/queue_job_chunk/security/security.xml index 6ee28a57c0..02ae675177 100644 --- a/queue_job_chunk/security/security.xml +++ b/queue_job_chunk/security/security.xml @@ -16,8 +16,9 @@ Job Queue chunk multi-company - ['|', ('company_id', '=', False), - ('company_id', 'child_of', [user.company_id.id])] + ['|', ('company_id','=',False), ('company_id','in',company_ids)]
From 412a1c6c18f8b06ba2473dc9ffd61177406c89bc Mon Sep 17 00:00:00 2001 From: Github GRAP Bot Date: Thu, 6 Jul 2023 12:13:26 +0000 Subject: [PATCH 17/21] queue_job_chunk 16.0.0.1.0 --- queue_job_chunk/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/queue_job_chunk/__manifest__.py b/queue_job_chunk/__manifest__.py index 6ea21f12ae..6580850c64 100644 --- a/queue_job_chunk/__manifest__.py +++ b/queue_job_chunk/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Job Queue Chunk", - "version": "16.0.0.0.0", + "version": "16.0.0.1.0", "author": "Akretion, Odoo Community Association (OCA)", "website": "https://github.com/OCA/sale-channel", "license": "AGPL-3", From 6d4830744ef20ff791c4b68799039a70493c7530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Mombereau?= Date: Fri, 17 Jan 2025 13:15:12 -0300 Subject: [PATCH 18/21] [FIX] run pre-commit for OCA --- queue_job_chunk/README.rst | 41 ++++++++++---- queue_job_chunk/__manifest__.py | 2 +- queue_job_chunk/static/description/index.html | 56 ++++++++++--------- 3 files changed, 61 insertions(+), 38 deletions(-) diff --git a/queue_job_chunk/README.rst b/queue_job_chunk/README.rst index 36dafebd0e..fa3bafab7f 100644 --- a/queue_job_chunk/README.rst +++ b/queue_job_chunk/README.rst @@ -2,10 +2,13 @@ Job Queue Chunk =============== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:2ec876f81add7cb79bdb91363bbf23f50aeea267b12cc9e76f6da9cca47d2931 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -13,11 +16,17 @@ Job Queue Chunk .. |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-akretion%2Fsale--import-lightgray.png?logo=github - :target: https://github.com/akretion/sale-import/tree/14.0/queue_job_chunk - :alt: akretion/sale-import - -|badge1| |badge2| |badge3| +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fqueue-lightgray.png?logo=github + :target: https://github.com/OCA/queue/tree/16.0/queue_job_chunk + :alt: OCA/queue +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/queue-16-0/queue-16-0-queue_job_chunk + :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/queue&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| Adds the notion of queue job chunks, essentially a queue job with some metadata. @@ -35,10 +44,10 @@ Usage Bug Tracker =========== -Bugs are tracked on `GitHub Issues `_. +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 smashing it by providing a detailed and welcomed -`feedback `_. +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. @@ -66,6 +75,16 @@ The development of this module has been financially supported by: Maintainers ~~~~~~~~~~~ -This module is part of the `akretion/sale-import `_ project on GitHub. +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/queue `_ project on GitHub. -You are welcome to contribute. +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/queue_job_chunk/__manifest__.py b/queue_job_chunk/__manifest__.py index 6580850c64..8823c03bb2 100644 --- a/queue_job_chunk/__manifest__.py +++ b/queue_job_chunk/__manifest__.py @@ -5,7 +5,7 @@ "name": "Job Queue Chunk", "version": "16.0.0.1.0", "author": "Akretion, Odoo Community Association (OCA)", - "website": "https://github.com/OCA/sale-channel", + "website": "https://github.com/OCA/queue", "license": "AGPL-3", "category": "Generic Modules", "depends": ["queue_job"], diff --git a/queue_job_chunk/static/description/index.html b/queue_job_chunk/static/description/index.html index d167d2e3f8..3f4e58939a 100644 --- a/queue_job_chunk/static/description/index.html +++ b/queue_job_chunk/static/description/index.html @@ -1,20 +1,20 @@ - - + Job Queue Chunk