From affe40ed8733eacee8935a95ae9ac9613cc8820b Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Mon, 15 Jun 2020 16:56:27 +0200 Subject: [PATCH 01/21] Add sale_automatic_workflow_job Use Queue Jobs to process the Sales Automatic Workflow actions. The default behavior of the automatic workflow module is to use a scheduled action that searches all the record that need a workflow action and sequentially process all of them. It can hit some limits when the number of records is too high. This module keeps the scheduled action to search the records, but instead of directly executing the actions (confirm a sales order, create invoices for a sales order, validate invoices, ...), it creates one job per operation to do. It uses an identity key on the jobs so it will not create the same job for the same record and same operation twice. ~ I needed to extract methods in `sale_automatic_workflow` in order to be able to execute them as jobs. A new decorator "job_auto_delay" (to eventually move in queue_job) makes these methods automatically delayed when called. --- sale_automatic_workflow_job/__init__.py | 1 + sale_automatic_workflow_job/__manifest__.py | 17 ++ .../models/__init__.py | 1 + .../models/automatic_workflow_job.py | 150 ++++++++++++++++++ .../readme/CONTRIBUTORS.rst | 1 + .../readme/DESCRIPTION.rst | 15 ++ sale_automatic_workflow_job/tests/__init__.py | 1 + .../tests/test_auto_workflow_job.py | 107 +++++++++++++ 8 files changed, 293 insertions(+) create mode 100644 sale_automatic_workflow_job/__init__.py create mode 100644 sale_automatic_workflow_job/__manifest__.py create mode 100644 sale_automatic_workflow_job/models/__init__.py create mode 100644 sale_automatic_workflow_job/models/automatic_workflow_job.py create mode 100644 sale_automatic_workflow_job/readme/CONTRIBUTORS.rst create mode 100644 sale_automatic_workflow_job/readme/DESCRIPTION.rst create mode 100644 sale_automatic_workflow_job/tests/__init__.py create mode 100644 sale_automatic_workflow_job/tests/test_auto_workflow_job.py diff --git a/sale_automatic_workflow_job/__init__.py b/sale_automatic_workflow_job/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/sale_automatic_workflow_job/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_automatic_workflow_job/__manifest__.py b/sale_automatic_workflow_job/__manifest__.py new file mode 100644 index 00000000000..2cf78e6d57c --- /dev/null +++ b/sale_automatic_workflow_job/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2020 Camptocamp (https://www.camptocamp.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Sale Automatic Workflow Job", + "summary": "Execute sale automatic workflows in queue jobs", + "version": "12.0.1.0.0", + "category": "Sales Management", + "license": "AGPL-3", + "author": "Camptocamp, " + "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/sale-workflow", + "depends": [ + "sale_automatic_workflow", + "queue_job", + ], +} diff --git a/sale_automatic_workflow_job/models/__init__.py b/sale_automatic_workflow_job/models/__init__.py new file mode 100644 index 00000000000..c1391151e42 --- /dev/null +++ b/sale_automatic_workflow_job/models/__init__.py @@ -0,0 +1 @@ +from . import automatic_workflow_job diff --git a/sale_automatic_workflow_job/models/automatic_workflow_job.py b/sale_automatic_workflow_job/models/automatic_workflow_job.py new file mode 100644 index 00000000000..0092fe4c702 --- /dev/null +++ b/sale_automatic_workflow_job/models/automatic_workflow_job.py @@ -0,0 +1,150 @@ +# Copyright 2020 Camptocamp (https://www.camptocamp.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import functools + +from odoo import _, models +from odoo.addons.queue_job.job import job, identity_exact + + +# TODO integrate in queue_job +def job_auto_delay(func=None, default_channel="root", retry_pattern=None): + """Decorator to automatically delay as job method when called + + The decorator applies ``odoo.addons.queue_job.job`` at the same time, + so the decorated method is listed in job functions. The arguments + are the same, propagated to the ``job`` decorator. + + When a method is decorated by ``job_auto_delay``, any call to the method + will not directly execute the method's body, but will instead enqueue a + job. + + The options of the job usually passed to ``with_delay()`` (priority, + description, identity_key, ...) can be returned in a dictionary by a method + named after the name of the method suffixed by ``_job_options`` which takes + the same parameters as the initial method. + + It is still possible to directly execute the method by setting a key + ``_job_force_sync`` to True in the environment context. + + Example: + + .. code-block:: python + + class ProductProduct(models.Model): + _inherit = 'product.product' + + def foo_job_options(self, arg1): + return { + "priority": 100, + "description": "Saying hello to {}".format(arg1) + } + + @job_auto_delay(default_channel="root.channel1") + def foo(self, arg1): + print("hello", arg1) + + def button_x(self): + foo("world") + + The result when ``button_x`` is called, is that a new job for ``foo`` is + delayed. + + """ + if func is None: + return functools.partial( + job_auto_delay, + default_channel=default_channel, + retry_pattern=retry_pattern + ) + + def auto_delay(self, *args, **kwargs): + if (self.env.context.get("job_uuid") or + self.env.context.get("_job_force_sync")): + # we are in the job execution + return func(self, *args, **kwargs) + else: + # replace the synchronous call by a job on itself + method_name = func.__name__ + job_options_method = getattr( + self, "{}_job_options".format(method_name), None + ) + job_options = {} + if job_options_method: + job_options.update(job_options_method(*args, **kwargs)) + else: + job_options = {} + delayed = self.with_delay(**job_options) + getattr(delayed, method_name)(*args, **kwargs) + + return functools.update_wrapper( + auto_delay, + job( + func, + default_channel=default_channel, + retry_pattern=retry_pattern + ), + ) + + +class AutomaticWorkflowJob(models.Model): + _inherit = "automatic.workflow.job" + + def _do_validate_sale_order_job_options(self, sale): + description = _("Validate sales order {}").format(sale.display_name) + return { + "description": description, + "identity_key": identity_exact, + } + + @job_auto_delay(default_channel="root.auto_workflow") + def _do_validate_sale_order(self, sale): + return super()._do_validate_sale_order(sale) + + def _do_create_invoice_job_options(self, sale): + description = _( + "Create invoices for sales order {}" + ).format(sale.display_name) + return { + "description": description, + "identity_key": identity_exact, + } + + @job_auto_delay(default_channel="root.auto_workflow") + def _do_create_invoice(self, sale): + return super()._do_create_invoice(sale) + + def _do_validate_invoice_job_options(self, invoice): + description = _("Validate invoice {}").format(invoice.display_name) + return { + "description": description, + "identity_key": identity_exact, + } + + @job_auto_delay(default_channel="root.auto_workflow") + def _do_validate_invoice(self, invoice): + return super()._do_validate_invoice(invoice) + + def _do_validate_picking_job_options(self, picking): + description = _("Validate transfer {}").format(picking.display_name) + return { + "description": description, + "identity_key": identity_exact, + } + + @job_auto_delay(default_channel="root.auto_workflow") + def _do_validate_picking(self, picking): + return super()._do_validate_picking(picking) + + def _do_sale_done_job_options(self, sale): + description = _( + "Mark sales order {} as done" + ).format(sale.display_name) + return { + "description": description, + "identity_key": identity_exact, + } + + @job_auto_delay(default_channel="root.auto_workflow") + def _do_sale_done(self, sale): + return super()._do_sale_done(sale) diff --git a/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst b/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000000..48286263cd3 --- /dev/null +++ b/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Guewen Baconnier diff --git a/sale_automatic_workflow_job/readme/DESCRIPTION.rst b/sale_automatic_workflow_job/readme/DESCRIPTION.rst new file mode 100644 index 00000000000..dad760e07c1 --- /dev/null +++ b/sale_automatic_workflow_job/readme/DESCRIPTION.rst @@ -0,0 +1,15 @@ +Use Queue Jobs to process the Sales Automatic Workflow actions. + +The default behavior of the automatic workflow module is to use a +scheduled action that searches all the record that need a workflow +action and sequentially process all of them. + +It can hit some limits when the number of records is too high. + +This module keeps the scheduled action to search the records, but +instead of directly executing the actions (confirm a sales order, +create invoices for a sales order, validate invoices, ...), it +creates one job per operation to do. + +It uses an identity key on the jobs so it will not create the same +job for the same record and same operation twice. diff --git a/sale_automatic_workflow_job/tests/__init__.py b/sale_automatic_workflow_job/tests/__init__.py new file mode 100644 index 00000000000..89a48ebc2e0 --- /dev/null +++ b/sale_automatic_workflow_job/tests/__init__.py @@ -0,0 +1 @@ +from . import test_auto_workflow_job diff --git a/sale_automatic_workflow_job/tests/test_auto_workflow_job.py b/sale_automatic_workflow_job/tests/test_auto_workflow_job.py new file mode 100644 index 00000000000..9b218a61fa1 --- /dev/null +++ b/sale_automatic_workflow_job/tests/test_auto_workflow_job.py @@ -0,0 +1,107 @@ +# Copyright 2020 Camptocamp (https://www.camptocamp.com) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests import tagged + +from odoo.addons.queue_job.job import identity_exact +from odoo.addons.queue_job.tests.common import mock_with_delay +from odoo.addons.sale_automatic_workflow.tests.test_automatic_workflow_base import ( # noqa + TestAutomaticWorkflowBase +) + + +@tagged('post_install', '-at_install') +class TestAutoWorkflowJob(TestAutomaticWorkflowBase): + + def setUp(self): + super().setUp() + workflow = self.create_full_automatic() + self.sale = self.create_sale_order(workflow) + + def assert_job_delayed(self, delayable_cls, delayable, method_name, args): + # .with_delay() has been called once + self.assertEqual(delayable_cls.call_count, 1) + delay_args, delay_kwargs = delayable_cls.call_args + # .with_delay() has been called on self.env["automatic.workflow.job"] + self.assertEqual(delay_args, (self.env["automatic.workflow.job"],)) + # .with_delay() with the following options + self.assertEqual(delay_kwargs.get("identity_key"), identity_exact) + # check what's passed to the job method + method = getattr(delayable, method_name) + self.assertEqual(method.call_count, 1) + delay_args, delay_kwargs = method.call_args + self.assertEqual(delay_args, args) + self.assertDictEqual(delay_kwargs, {}) + + def test_validate_sale_order(self): + with mock_with_delay() as (delayable_cls, delayable): + self.progress() # run automatic workflow cron + self.assert_job_delayed( + delayable_cls, + delayable, + "_do_validate_sale_order", + (self.sale,) + ) + + def test_create_invoice(self): + self.sale.action_confirm() + # don't care about transfers in this test + self.sale.picking_ids.state = "done" + with mock_with_delay() as (delayable_cls, delayable): + self.progress() # run automatic workflow cron + self.assert_job_delayed( + delayable_cls, + delayable, + "_do_create_invoice", + (self.sale,) + ) + + def test_validate_invoice(self): + self.sale.action_confirm() + # don't care about transfers in this test + self.sale.picking_ids.state = "done" + self.sale.action_invoice_create() + invoice = self.sale.invoice_ids + with mock_with_delay() as (delayable_cls, delayable): + self.progress() # run automatic workflow cron + self.assert_job_delayed( + delayable_cls, + delayable, + "_do_validate_invoice", + (invoice,) + ) + + def test_validate_picking(self): + self.sale.action_confirm() + picking = self.sale.picking_ids + # disable invoice creation in this test + self.sale.workflow_process_id.create_invoice = False + with mock_with_delay() as (delayable_cls, delayable): + self.progress() # run automatic workflow cron + self.assert_job_delayed( + delayable_cls, + delayable, + "_do_validate_picking", + (picking,) + ) + + def test_sale_done(self): + self.sale.action_confirm() + # don't care about transfers in this test + self.sale.picking_ids.state = "done" + self.sale.action_invoice_create() + + # disable invoice validation for we don't care + # in this test + self.sale.workflow_process_id.validate_invoice = False + # activate the 'sale done' workflow + self.sale.workflow_process_id.sale_done = True + + with mock_with_delay() as (delayable_cls, delayable): + self.progress() # run automatic workflow cron + self.assert_job_delayed( + delayable_cls, + delayable, + "_do_sale_done", + (self.sale,) + ) From 20a836a5b67c5b6244adc0c93743ca37f1ec9584 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Thu, 18 Jun 2020 13:27:55 +0000 Subject: [PATCH 02/21] [UPD] Update sale_automatic_workflow_job.pot --- .../i18n/sale_automatic_workflow_job.pot | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot diff --git a/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot new file mode 100644 index 00000000000..d593e68d289 --- /dev/null +++ b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot @@ -0,0 +1,50 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * sale_automatic_workflow_job +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: sale_automatic_workflow_job +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:105 +#, python-format +msgid "Create invoices for sales order {}" +msgstr "" + +#. module: sale_automatic_workflow_job +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:140 +#, python-format +msgid "Mark sales order {} as done" +msgstr "" + +#. module: sale_automatic_workflow_job +#: model:ir.model,name:sale_automatic_workflow_job.model_automatic_workflow_job +msgid "Scheduler that will play automatically the validation of invoices, pickings..." +msgstr "" + +#. module: sale_automatic_workflow_job +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:118 +#, python-format +msgid "Validate invoice {}" +msgstr "" + +#. module: sale_automatic_workflow_job +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:94 +#, python-format +msgid "Validate sales order {}" +msgstr "" + +#. module: sale_automatic_workflow_job +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:129 +#, python-format +msgid "Validate transfer {}" +msgstr "" + From a18990c06f47bc58f1d7cd64c9700d86c1cf7d6c Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 18 Jun 2020 13:45:19 +0000 Subject: [PATCH 03/21] [UPD] README.rst --- sale_automatic_workflow_job/README.rst | 87 ++++ .../static/description/index.html | 429 ++++++++++++++++++ 2 files changed, 516 insertions(+) create mode 100644 sale_automatic_workflow_job/README.rst create mode 100644 sale_automatic_workflow_job/static/description/index.html diff --git a/sale_automatic_workflow_job/README.rst b/sale_automatic_workflow_job/README.rst new file mode 100644 index 00000000000..71eba6a3ec1 --- /dev/null +++ b/sale_automatic_workflow_job/README.rst @@ -0,0 +1,87 @@ +=========================== +Sale Automatic Workflow Job +=========================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! 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-OCA%2Fsale--workflow-lightgray.png?logo=github + :target: https://github.com/OCA/sale-workflow/tree/12.0/sale_automatic_workflow_job + :alt: OCA/sale-workflow +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/sale-workflow-12-0/sale-workflow-12-0-sale_automatic_workflow_job + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/167/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Use Queue Jobs to process the Sales Automatic Workflow actions. + +The default behavior of the automatic workflow module is to use a +scheduled action that searches all the record that need a workflow +action and sequentially process all of them. + +It can hit some limits when the number of records is too high. + +This module keeps the scheduled action to search the records, but +instead of directly executing the actions (confirm a sales order, +create invoices for a sales order, validate invoices, ...), it +creates one job per operation to do. + +It uses an identity key on the jobs so it will not create the same +job for the same record and same operation twice. + +**Table of contents** + +.. contents:: + :local: + +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 +~~~~~~~ + +* Camptocamp + +Contributors +~~~~~~~~~~~~ + +* Guewen Baconnier + +Maintainers +~~~~~~~~~~~ + +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/sale-workflow `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/sale_automatic_workflow_job/static/description/index.html b/sale_automatic_workflow_job/static/description/index.html new file mode 100644 index 00000000000..8125e1b6fe2 --- /dev/null +++ b/sale_automatic_workflow_job/static/description/index.html @@ -0,0 +1,429 @@ + + + + + + +Sale Automatic Workflow Job + + + +
+

Sale Automatic Workflow Job

+ + +

Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runbot

+

Use Queue Jobs to process the Sales Automatic Workflow actions.

+

The default behavior of the automatic workflow module is to use a +scheduled action that searches all the record that need a workflow +action and sequentially process all of them.

+

It can hit some limits when the number of records is too high.

+

This module keeps the scheduled action to search the records, but +instead of directly executing the actions (confirm a sales order, +create invoices for a sales order, validate invoices, …), it +creates one job per operation to do.

+

It uses an identity key on the jobs so it will not create the same +job for the same record and same operation twice.

+

Table of contents

+ +
+

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

+
    +
  • Camptocamp
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

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-workflow project on GitHub.

+

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

+
+
+
+ + From c2a1498350dff8544ab3e05faf0755921c9fda2a Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 18 Jun 2020 13:45:20 +0000 Subject: [PATCH 04/21] [ADD] icon.png --- .../static/description/icon.png | Bin 0 -> 9455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 sale_automatic_workflow_job/static/description/icon.png diff --git a/sale_automatic_workflow_job/static/description/icon.png b/sale_automatic_workflow_job/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From 7fc5476f67eeca5629560be171f885fa10b79b38 Mon Sep 17 00:00:00 2001 From: Saran440 Date: Wed, 9 Sep 2020 15:57:29 +0700 Subject: [PATCH 05/21] [IMP] related_job to origin document --- .../models/__init__.py | 1 + .../models/automatic_workflow_job.py | 7 ++++++- .../models/queue_job.py | 20 +++++++++++++++++++ .../readme/CONTRIBUTORS.rst | 1 + 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 sale_automatic_workflow_job/models/queue_job.py diff --git a/sale_automatic_workflow_job/models/__init__.py b/sale_automatic_workflow_job/models/__init__.py index c1391151e42..6f2ac63f818 100644 --- a/sale_automatic_workflow_job/models/__init__.py +++ b/sale_automatic_workflow_job/models/__init__.py @@ -1 +1,2 @@ from . import automatic_workflow_job +from . import queue_job diff --git a/sale_automatic_workflow_job/models/automatic_workflow_job.py b/sale_automatic_workflow_job/models/automatic_workflow_job.py index 0092fe4c702..a264c9e54b3 100644 --- a/sale_automatic_workflow_job/models/automatic_workflow_job.py +++ b/sale_automatic_workflow_job/models/automatic_workflow_job.py @@ -4,7 +4,7 @@ import functools from odoo import _, models -from odoo.addons.queue_job.job import job, identity_exact +from odoo.addons.queue_job.job import job, identity_exact, related_action # TODO integrate in queue_job @@ -98,6 +98,7 @@ def _do_validate_sale_order_job_options(self, sale): } @job_auto_delay(default_channel="root.auto_workflow") + @related_action('_related_action_sale_automatic_workflow') def _do_validate_sale_order(self, sale): return super()._do_validate_sale_order(sale) @@ -111,6 +112,7 @@ def _do_create_invoice_job_options(self, sale): } @job_auto_delay(default_channel="root.auto_workflow") + @related_action('_related_action_sale_automatic_workflow') def _do_create_invoice(self, sale): return super()._do_create_invoice(sale) @@ -122,6 +124,7 @@ def _do_validate_invoice_job_options(self, invoice): } @job_auto_delay(default_channel="root.auto_workflow") + @related_action('_related_action_sale_automatic_workflow') def _do_validate_invoice(self, invoice): return super()._do_validate_invoice(invoice) @@ -133,6 +136,7 @@ def _do_validate_picking_job_options(self, picking): } @job_auto_delay(default_channel="root.auto_workflow") + @related_action('_related_action_sale_automatic_workflow') def _do_validate_picking(self, picking): return super()._do_validate_picking(picking) @@ -146,5 +150,6 @@ def _do_sale_done_job_options(self, sale): } @job_auto_delay(default_channel="root.auto_workflow") + @related_action('_related_action_sale_automatic_workflow') def _do_sale_done(self, sale): return super()._do_sale_done(sale) diff --git a/sale_automatic_workflow_job/models/queue_job.py b/sale_automatic_workflow_job/models/queue_job.py new file mode 100644 index 00000000000..122c7e8e3b3 --- /dev/null +++ b/sale_automatic_workflow_job/models/queue_job.py @@ -0,0 +1,20 @@ +# Copyright 2020 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, models + + +class QueueJob(models.Model): + """ Job status and result """ + _inherit = "queue.job" + + def _related_action_sale_automatic_workflow(self): + object = self.args[0] + action = { + "name": _("Sale Automatic Workflow Job"), + "type": "ir.actions.act_window", + "res_model": object._name, + "view_mode": "form", + "res_id": object.id, + } + return action diff --git a/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst b/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst index 48286263cd3..b6ac925af2d 100644 --- a/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst +++ b/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst @@ -1 +1,2 @@ * Guewen Baconnier +* Saran Lim. From a99e5995b55a26120960c799f4675b55eb0b40c3 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Fri, 11 Sep 2020 16:05:45 +0000 Subject: [PATCH 06/21] [UPD] Update sale_automatic_workflow_job.pot --- .../i18n/sale_automatic_workflow_job.pot | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot index d593e68d289..111f50ece00 100644 --- a/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot +++ b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot @@ -15,16 +15,29 @@ msgstr "" #. module: sale_automatic_workflow_job #: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:105 +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:106 #, python-format msgid "Create invoices for sales order {}" msgstr "" #. module: sale_automatic_workflow_job #: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:140 +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:144 #, python-format msgid "Mark sales order {} as done" msgstr "" +#. module: sale_automatic_workflow_job +#: model:ir.model,name:sale_automatic_workflow_job.model_queue_job +msgid "Queue Job" +msgstr "" + +#. module: sale_automatic_workflow_job +#: code:addons/sale_automatic_workflow_job/models/queue_job.py:14 +#, python-format +msgid "Sale Automatic Workflow Job" +msgstr "" + #. module: sale_automatic_workflow_job #: model:ir.model,name:sale_automatic_workflow_job.model_automatic_workflow_job msgid "Scheduler that will play automatically the validation of invoices, pickings..." @@ -32,6 +45,7 @@ msgstr "" #. module: sale_automatic_workflow_job #: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:118 +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:120 #, python-format msgid "Validate invoice {}" msgstr "" @@ -44,6 +58,7 @@ msgstr "" #. module: sale_automatic_workflow_job #: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:129 +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:132 #, python-format msgid "Validate transfer {}" msgstr "" From bb4f2dbe42062ef64f33c1c4b209f84598b2777f Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 11 Sep 2020 16:27:27 +0000 Subject: [PATCH 07/21] [UPD] README.rst --- sale_automatic_workflow_job/README.rst | 1 + sale_automatic_workflow_job/static/description/index.html | 1 + 2 files changed, 2 insertions(+) diff --git a/sale_automatic_workflow_job/README.rst b/sale_automatic_workflow_job/README.rst index 71eba6a3ec1..8722d89e884 100644 --- a/sale_automatic_workflow_job/README.rst +++ b/sale_automatic_workflow_job/README.rst @@ -68,6 +68,7 @@ Contributors ~~~~~~~~~~~~ * Guewen Baconnier +* Saran Lim. Maintainers ~~~~~~~~~~~ diff --git a/sale_automatic_workflow_job/static/description/index.html b/sale_automatic_workflow_job/static/description/index.html index 8125e1b6fe2..00b127ee9f5 100644 --- a/sale_automatic_workflow_job/static/description/index.html +++ b/sale_automatic_workflow_job/static/description/index.html @@ -411,6 +411,7 @@

Authors

Contributors

From 9771fae04e50e351ce038a5e766c833d846f4f82 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 11 Sep 2020 16:27:28 +0000 Subject: [PATCH 08/21] sale_automatic_workflow_job 12.0.1.0.1 --- sale_automatic_workflow_job/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sale_automatic_workflow_job/__manifest__.py b/sale_automatic_workflow_job/__manifest__.py index 2cf78e6d57c..b3df4d3ab21 100644 --- a/sale_automatic_workflow_job/__manifest__.py +++ b/sale_automatic_workflow_job/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Sale Automatic Workflow Job", "summary": "Execute sale automatic workflows in queue jobs", - "version": "12.0.1.0.0", + "version": "12.0.1.0.1", "category": "Sales Management", "license": "AGPL-3", "author": "Camptocamp, " From c461a2237a29d8f86cf9d54c5642900cf2281654 Mon Sep 17 00:00:00 2001 From: oca-travis Date: Fri, 11 Sep 2020 16:43:56 +0000 Subject: [PATCH 09/21] [UPD] Update sale_automatic_workflow_job.pot --- .../i18n/sale_automatic_workflow_job.pot | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot index 111f50ece00..859ff6450fc 100644 --- a/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot +++ b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot @@ -14,14 +14,12 @@ msgstr "" "Plural-Forms: \n" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:105 #: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:106 #, python-format msgid "Create invoices for sales order {}" msgstr "" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:140 #: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:144 #, python-format msgid "Mark sales order {} as done" @@ -44,7 +42,6 @@ msgid "Scheduler that will play automatically the validation of invoices, pickin msgstr "" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:118 #: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:120 #, python-format msgid "Validate invoice {}" @@ -57,7 +54,6 @@ msgid "Validate sales order {}" msgstr "" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:129 #: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:132 #, python-format msgid "Validate transfer {}" From 11c136c524a5e8fdc0ad19643473f2abf7ab15d3 Mon Sep 17 00:00:00 2001 From: Kitti U Date: Tue, 22 Sep 2020 22:00:15 +0700 Subject: [PATCH 10/21] [IMP] : black, isort, prettier --- sale_automatic_workflow_job/__manifest__.py | 8 ++--- .../models/automatic_workflow_job.py | 34 +++++++------------ .../models/queue_job.py | 1 + .../tests/test_auto_workflow_job.py | 30 ++++------------ 4 files changed, 22 insertions(+), 51 deletions(-) diff --git a/sale_automatic_workflow_job/__manifest__.py b/sale_automatic_workflow_job/__manifest__.py index b3df4d3ab21..54f9e350e4b 100644 --- a/sale_automatic_workflow_job/__manifest__.py +++ b/sale_automatic_workflow_job/__manifest__.py @@ -7,11 +7,7 @@ "version": "12.0.1.0.1", "category": "Sales Management", "license": "AGPL-3", - "author": "Camptocamp, " - "Odoo Community Association (OCA)", + "author": "Camptocamp, " "Odoo Community Association (OCA)", "website": "https://github.com/OCA/sale-workflow", - "depends": [ - "sale_automatic_workflow", - "queue_job", - ], + "depends": ["sale_automatic_workflow", "queue_job",], } diff --git a/sale_automatic_workflow_job/models/automatic_workflow_job.py b/sale_automatic_workflow_job/models/automatic_workflow_job.py index a264c9e54b3..02216c6b864 100644 --- a/sale_automatic_workflow_job/models/automatic_workflow_job.py +++ b/sale_automatic_workflow_job/models/automatic_workflow_job.py @@ -4,7 +4,8 @@ import functools from odoo import _, models -from odoo.addons.queue_job.job import job, identity_exact, related_action + +from odoo.addons.queue_job.job import identity_exact, job, related_action # TODO integrate in queue_job @@ -53,14 +54,11 @@ def button_x(self): """ if func is None: return functools.partial( - job_auto_delay, - default_channel=default_channel, - retry_pattern=retry_pattern + job_auto_delay, default_channel=default_channel, retry_pattern=retry_pattern ) def auto_delay(self, *args, **kwargs): - if (self.env.context.get("job_uuid") or - self.env.context.get("_job_force_sync")): + if self.env.context.get("job_uuid") or self.env.context.get("_job_force_sync"): # we are in the job execution return func(self, *args, **kwargs) else: @@ -79,11 +77,7 @@ def auto_delay(self, *args, **kwargs): return functools.update_wrapper( auto_delay, - job( - func, - default_channel=default_channel, - retry_pattern=retry_pattern - ), + job(func, default_channel=default_channel, retry_pattern=retry_pattern), ) @@ -98,21 +92,19 @@ def _do_validate_sale_order_job_options(self, sale): } @job_auto_delay(default_channel="root.auto_workflow") - @related_action('_related_action_sale_automatic_workflow') + @related_action("_related_action_sale_automatic_workflow") def _do_validate_sale_order(self, sale): return super()._do_validate_sale_order(sale) def _do_create_invoice_job_options(self, sale): - description = _( - "Create invoices for sales order {}" - ).format(sale.display_name) + description = _("Create invoices for sales order {}").format(sale.display_name) return { "description": description, "identity_key": identity_exact, } @job_auto_delay(default_channel="root.auto_workflow") - @related_action('_related_action_sale_automatic_workflow') + @related_action("_related_action_sale_automatic_workflow") def _do_create_invoice(self, sale): return super()._do_create_invoice(sale) @@ -124,7 +116,7 @@ def _do_validate_invoice_job_options(self, invoice): } @job_auto_delay(default_channel="root.auto_workflow") - @related_action('_related_action_sale_automatic_workflow') + @related_action("_related_action_sale_automatic_workflow") def _do_validate_invoice(self, invoice): return super()._do_validate_invoice(invoice) @@ -136,20 +128,18 @@ def _do_validate_picking_job_options(self, picking): } @job_auto_delay(default_channel="root.auto_workflow") - @related_action('_related_action_sale_automatic_workflow') + @related_action("_related_action_sale_automatic_workflow") def _do_validate_picking(self, picking): return super()._do_validate_picking(picking) def _do_sale_done_job_options(self, sale): - description = _( - "Mark sales order {} as done" - ).format(sale.display_name) + description = _("Mark sales order {} as done").format(sale.display_name) return { "description": description, "identity_key": identity_exact, } @job_auto_delay(default_channel="root.auto_workflow") - @related_action('_related_action_sale_automatic_workflow') + @related_action("_related_action_sale_automatic_workflow") def _do_sale_done(self, sale): return super()._do_sale_done(sale) diff --git a/sale_automatic_workflow_job/models/queue_job.py b/sale_automatic_workflow_job/models/queue_job.py index 122c7e8e3b3..a633ba32360 100644 --- a/sale_automatic_workflow_job/models/queue_job.py +++ b/sale_automatic_workflow_job/models/queue_job.py @@ -6,6 +6,7 @@ class QueueJob(models.Model): """ Job status and result """ + _inherit = "queue.job" def _related_action_sale_automatic_workflow(self): diff --git a/sale_automatic_workflow_job/tests/test_auto_workflow_job.py b/sale_automatic_workflow_job/tests/test_auto_workflow_job.py index 9b218a61fa1..e40069ff776 100644 --- a/sale_automatic_workflow_job/tests/test_auto_workflow_job.py +++ b/sale_automatic_workflow_job/tests/test_auto_workflow_job.py @@ -6,13 +6,12 @@ from odoo.addons.queue_job.job import identity_exact from odoo.addons.queue_job.tests.common import mock_with_delay from odoo.addons.sale_automatic_workflow.tests.test_automatic_workflow_base import ( # noqa - TestAutomaticWorkflowBase + TestAutomaticWorkflowBase, ) -@tagged('post_install', '-at_install') +@tagged("post_install", "-at_install") class TestAutoWorkflowJob(TestAutomaticWorkflowBase): - def setUp(self): super().setUp() workflow = self.create_full_automatic() @@ -37,10 +36,7 @@ def test_validate_sale_order(self): with mock_with_delay() as (delayable_cls, delayable): self.progress() # run automatic workflow cron self.assert_job_delayed( - delayable_cls, - delayable, - "_do_validate_sale_order", - (self.sale,) + delayable_cls, delayable, "_do_validate_sale_order", (self.sale,) ) def test_create_invoice(self): @@ -50,10 +46,7 @@ def test_create_invoice(self): with mock_with_delay() as (delayable_cls, delayable): self.progress() # run automatic workflow cron self.assert_job_delayed( - delayable_cls, - delayable, - "_do_create_invoice", - (self.sale,) + delayable_cls, delayable, "_do_create_invoice", (self.sale,) ) def test_validate_invoice(self): @@ -65,10 +58,7 @@ def test_validate_invoice(self): with mock_with_delay() as (delayable_cls, delayable): self.progress() # run automatic workflow cron self.assert_job_delayed( - delayable_cls, - delayable, - "_do_validate_invoice", - (invoice,) + delayable_cls, delayable, "_do_validate_invoice", (invoice,) ) def test_validate_picking(self): @@ -79,10 +69,7 @@ def test_validate_picking(self): with mock_with_delay() as (delayable_cls, delayable): self.progress() # run automatic workflow cron self.assert_job_delayed( - delayable_cls, - delayable, - "_do_validate_picking", - (picking,) + delayable_cls, delayable, "_do_validate_picking", (picking,) ) def test_sale_done(self): @@ -100,8 +87,5 @@ def test_sale_done(self): with mock_with_delay() as (delayable_cls, delayable): self.progress() # run automatic workflow cron self.assert_job_delayed( - delayable_cls, - delayable, - "_do_sale_done", - (self.sale,) + delayable_cls, delayable, "_do_sale_done", (self.sale,) ) From 63804d3c0db570a0aa6e0a25494a64ec95f3e03d Mon Sep 17 00:00:00 2001 From: Kitti U Date: Tue, 22 Sep 2020 22:02:05 +0700 Subject: [PATCH 11/21] [13.0][MIG] sale_automatic_workflow_job --- sale_automatic_workflow_job/__manifest__.py | 4 +- .../models/automatic_workflow_job.py | 108 +++--------------- .../models/queue_job.py | 6 +- .../readme/CONTRIBUTORS.rst | 1 + 4 files changed, 22 insertions(+), 97 deletions(-) diff --git a/sale_automatic_workflow_job/__manifest__.py b/sale_automatic_workflow_job/__manifest__.py index 54f9e350e4b..8447fdc0d16 100644 --- a/sale_automatic_workflow_job/__manifest__.py +++ b/sale_automatic_workflow_job/__manifest__.py @@ -4,10 +4,10 @@ { "name": "Sale Automatic Workflow Job", "summary": "Execute sale automatic workflows in queue jobs", - "version": "12.0.1.0.1", + "version": "13.0.1.0.0", "category": "Sales Management", "license": "AGPL-3", "author": "Camptocamp, " "Odoo Community Association (OCA)", "website": "https://github.com/OCA/sale-workflow", - "depends": ["sale_automatic_workflow", "queue_job",], + "depends": ["sale_automatic_workflow", "queue_job"], } diff --git a/sale_automatic_workflow_job/models/automatic_workflow_job.py b/sale_automatic_workflow_job/models/automatic_workflow_job.py index 02216c6b864..15f6ab46768 100644 --- a/sale_automatic_workflow_job/models/automatic_workflow_job.py +++ b/sale_automatic_workflow_job/models/automatic_workflow_job.py @@ -1,90 +1,14 @@ # Copyright 2020 Camptocamp (https://www.camptocamp.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -import functools - from odoo import _, models -from odoo.addons.queue_job.job import identity_exact, job, related_action - - -# TODO integrate in queue_job -def job_auto_delay(func=None, default_channel="root", retry_pattern=None): - """Decorator to automatically delay as job method when called - - The decorator applies ``odoo.addons.queue_job.job`` at the same time, - so the decorated method is listed in job functions. The arguments - are the same, propagated to the ``job`` decorator. - - When a method is decorated by ``job_auto_delay``, any call to the method - will not directly execute the method's body, but will instead enqueue a - job. - - The options of the job usually passed to ``with_delay()`` (priority, - description, identity_key, ...) can be returned in a dictionary by a method - named after the name of the method suffixed by ``_job_options`` which takes - the same parameters as the initial method. - - It is still possible to directly execute the method by setting a key - ``_job_force_sync`` to True in the environment context. - - Example: - - .. code-block:: python - - class ProductProduct(models.Model): - _inherit = 'product.product' - - def foo_job_options(self, arg1): - return { - "priority": 100, - "description": "Saying hello to {}".format(arg1) - } - - @job_auto_delay(default_channel="root.channel1") - def foo(self, arg1): - print("hello", arg1) - - def button_x(self): - foo("world") - - The result when ``button_x`` is called, is that a new job for ``foo`` is - delayed. - - """ - if func is None: - return functools.partial( - job_auto_delay, default_channel=default_channel, retry_pattern=retry_pattern - ) - - def auto_delay(self, *args, **kwargs): - if self.env.context.get("job_uuid") or self.env.context.get("_job_force_sync"): - # we are in the job execution - return func(self, *args, **kwargs) - else: - # replace the synchronous call by a job on itself - method_name = func.__name__ - job_options_method = getattr( - self, "{}_job_options".format(method_name), None - ) - job_options = {} - if job_options_method: - job_options.update(job_options_method(*args, **kwargs)) - else: - job_options = {} - delayed = self.with_delay(**job_options) - getattr(delayed, method_name)(*args, **kwargs) - - return functools.update_wrapper( - auto_delay, - job(func, default_channel=default_channel, retry_pattern=retry_pattern), - ) +from odoo.addons.queue_job.job import identity_exact, job_auto_delay, related_action class AutomaticWorkflowJob(models.Model): _inherit = "automatic.workflow.job" - def _do_validate_sale_order_job_options(self, sale): + def _do_validate_sale_order_job_options(self, sale, domain_filter): description = _("Validate sales order {}").format(sale.display_name) return { "description": description, @@ -93,10 +17,10 @@ def _do_validate_sale_order_job_options(self, sale): @job_auto_delay(default_channel="root.auto_workflow") @related_action("_related_action_sale_automatic_workflow") - def _do_validate_sale_order(self, sale): - return super()._do_validate_sale_order(sale) + def _do_validate_sale_order(self, sale, domain_filter): + return super()._do_validate_sale_order(sale, domain_filter) - def _do_create_invoice_job_options(self, sale): + def _do_create_invoice_job_options(self, sale, domain_filter): description = _("Create invoices for sales order {}").format(sale.display_name) return { "description": description, @@ -105,10 +29,10 @@ def _do_create_invoice_job_options(self, sale): @job_auto_delay(default_channel="root.auto_workflow") @related_action("_related_action_sale_automatic_workflow") - def _do_create_invoice(self, sale): - return super()._do_create_invoice(sale) + def _do_create_invoice(self, sale, domain_filter): + return super()._do_create_invoice(sale, domain_filter) - def _do_validate_invoice_job_options(self, invoice): + def _do_validate_invoice_job_options(self, invoice, domain_filter): description = _("Validate invoice {}").format(invoice.display_name) return { "description": description, @@ -117,10 +41,10 @@ def _do_validate_invoice_job_options(self, invoice): @job_auto_delay(default_channel="root.auto_workflow") @related_action("_related_action_sale_automatic_workflow") - def _do_validate_invoice(self, invoice): - return super()._do_validate_invoice(invoice) + def _do_validate_invoice(self, invoice, domain_filter): + return super()._do_validate_invoice(invoice, domain_filter) - def _do_validate_picking_job_options(self, picking): + def _do_validate_picking_job_options(self, picking, domain_filter): description = _("Validate transfer {}").format(picking.display_name) return { "description": description, @@ -129,10 +53,10 @@ def _do_validate_picking_job_options(self, picking): @job_auto_delay(default_channel="root.auto_workflow") @related_action("_related_action_sale_automatic_workflow") - def _do_validate_picking(self, picking): - return super()._do_validate_picking(picking) + def _do_validate_picking(self, picking, domain_filter): + return super()._do_validate_picking(picking, domain_filter) - def _do_sale_done_job_options(self, sale): + def _do_sale_done_job_options(self, sale, domain_filter): description = _("Mark sales order {} as done").format(sale.display_name) return { "description": description, @@ -141,5 +65,5 @@ def _do_sale_done_job_options(self, sale): @job_auto_delay(default_channel="root.auto_workflow") @related_action("_related_action_sale_automatic_workflow") - def _do_sale_done(self, sale): - return super()._do_sale_done(sale) + def _do_sale_done(self, sale, domain_filter): + return super()._do_sale_done(sale, domain_filter) diff --git a/sale_automatic_workflow_job/models/queue_job.py b/sale_automatic_workflow_job/models/queue_job.py index a633ba32360..b9ecf215cd6 100644 --- a/sale_automatic_workflow_job/models/queue_job.py +++ b/sale_automatic_workflow_job/models/queue_job.py @@ -10,12 +10,12 @@ class QueueJob(models.Model): _inherit = "queue.job" def _related_action_sale_automatic_workflow(self): - object = self.args[0] + obj = self.args[0] action = { "name": _("Sale Automatic Workflow Job"), "type": "ir.actions.act_window", - "res_model": object._name, + "res_model": obj._name, "view_mode": "form", - "res_id": object.id, + "res_id": obj.id, } return action diff --git a/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst b/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst index b6ac925af2d..25aba8b01b8 100644 --- a/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst +++ b/sale_automatic_workflow_job/readme/CONTRIBUTORS.rst @@ -1,2 +1,3 @@ * Guewen Baconnier * Saran Lim. +* Kitti U. From 190faf43a08e86d330ce4d606124f0ef0a9fc926 Mon Sep 17 00:00:00 2001 From: "khoivha@trobz.com" Date: Thu, 13 Jan 2022 16:47:59 +0700 Subject: [PATCH 12/21] [14.0][MIG] sale_automatic_workflow_job: Migration to 14.0 --- sale_automatic_workflow_job/__manifest__.py | 5 +- .../data/queue_job_data.xml | 76 ++++++++++++++++ .../models/automatic_workflow_job.py | 58 ++++++++----- .../tests/test_auto_workflow_job.py | 87 ++++++++++++++----- 4 files changed, 184 insertions(+), 42 deletions(-) create mode 100644 sale_automatic_workflow_job/data/queue_job_data.xml diff --git a/sale_automatic_workflow_job/__manifest__.py b/sale_automatic_workflow_job/__manifest__.py index 8447fdc0d16..a12e96cebc4 100644 --- a/sale_automatic_workflow_job/__manifest__.py +++ b/sale_automatic_workflow_job/__manifest__.py @@ -4,10 +4,13 @@ { "name": "Sale Automatic Workflow Job", "summary": "Execute sale automatic workflows in queue jobs", - "version": "13.0.1.0.0", + "version": "14.0.1.0.0", "category": "Sales Management", "license": "AGPL-3", "author": "Camptocamp, " "Odoo Community Association (OCA)", "website": "https://github.com/OCA/sale-workflow", "depends": ["sale_automatic_workflow", "queue_job"], + "data": [ + "data/queue_job_data.xml", + ], } diff --git a/sale_automatic_workflow_job/data/queue_job_data.xml b/sale_automatic_workflow_job/data/queue_job_data.xml new file mode 100644 index 00000000000..052a7543266 --- /dev/null +++ b/sale_automatic_workflow_job/data/queue_job_data.xml @@ -0,0 +1,76 @@ + + + + + + channel.sale.automatic.workflow + + + + + + + _do_validate_sale_order + + + + + + + _do_create_invoice + + + + + + + _do_validate_invoice + + + + + + + _do_validate_picking + + + + + + + _do_sale_done + + + + + diff --git a/sale_automatic_workflow_job/models/automatic_workflow_job.py b/sale_automatic_workflow_job/models/automatic_workflow_job.py index 15f6ab46768..51a9f79912c 100644 --- a/sale_automatic_workflow_job/models/automatic_workflow_job.py +++ b/sale_automatic_workflow_job/models/automatic_workflow_job.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import _, models -from odoo.addons.queue_job.job import identity_exact, job_auto_delay, related_action +from odoo.addons.queue_job.job import identity_exact class AutomaticWorkflowJob(models.Model): @@ -15,10 +15,11 @@ def _do_validate_sale_order_job_options(self, sale, domain_filter): "identity_key": identity_exact, } - @job_auto_delay(default_channel="root.auto_workflow") - @related_action("_related_action_sale_automatic_workflow") - def _do_validate_sale_order(self, sale, domain_filter): - return super()._do_validate_sale_order(sale, domain_filter) + def _validate_sale_orders(self, domain_filter): + with_context = self.with_context(auto_delay_do_validation=True) + return super(AutomaticWorkflowJob, with_context)._validate_sale_orders( + domain_filter + ) def _do_create_invoice_job_options(self, sale, domain_filter): description = _("Create invoices for sales order {}").format(sale.display_name) @@ -27,10 +28,9 @@ def _do_create_invoice_job_options(self, sale, domain_filter): "identity_key": identity_exact, } - @job_auto_delay(default_channel="root.auto_workflow") - @related_action("_related_action_sale_automatic_workflow") - def _do_create_invoice(self, sale, domain_filter): - return super()._do_create_invoice(sale, domain_filter) + def _create_invoices(self, domain_filter): + with_context = self.with_context(auto_delay_do_create_invoice=True) + return super(AutomaticWorkflowJob, with_context)._create_invoices(domain_filter) def _do_validate_invoice_job_options(self, invoice, domain_filter): description = _("Validate invoice {}").format(invoice.display_name) @@ -39,10 +39,11 @@ def _do_validate_invoice_job_options(self, invoice, domain_filter): "identity_key": identity_exact, } - @job_auto_delay(default_channel="root.auto_workflow") - @related_action("_related_action_sale_automatic_workflow") - def _do_validate_invoice(self, invoice, domain_filter): - return super()._do_validate_invoice(invoice, domain_filter) + def _validate_invoices(self, domain_filter): + with_context = self.with_context(auto_delay_do_validation=True) + return super(AutomaticWorkflowJob, with_context)._validate_invoices( + domain_filter + ) def _do_validate_picking_job_options(self, picking, domain_filter): description = _("Validate transfer {}").format(picking.display_name) @@ -51,10 +52,11 @@ def _do_validate_picking_job_options(self, picking, domain_filter): "identity_key": identity_exact, } - @job_auto_delay(default_channel="root.auto_workflow") - @related_action("_related_action_sale_automatic_workflow") - def _do_validate_picking(self, picking, domain_filter): - return super()._do_validate_picking(picking, domain_filter) + def _validate_pickings(self, domain_filter): + with_context = self.with_context(auto_delay_do_validation=True) + return super(AutomaticWorkflowJob, with_context)._validate_pickings( + domain_filter + ) def _do_sale_done_job_options(self, sale, domain_filter): description = _("Mark sales order {} as done").format(sale.display_name) @@ -63,7 +65,21 @@ def _do_sale_done_job_options(self, sale, domain_filter): "identity_key": identity_exact, } - @job_auto_delay(default_channel="root.auto_workflow") - @related_action("_related_action_sale_automatic_workflow") - def _do_sale_done(self, sale, domain_filter): - return super()._do_sale_done(sale, domain_filter) + def _sale_done(self, domain_filter): + with_context = self.with_context(auto_delay_do_sale_done=True) + return super(AutomaticWorkflowJob, with_context)._sale_done(domain_filter) + + def _register_hook(self): + mapping = { + "_do_validate_sale_order": "auto_delay_do_validation", + "_do_create_invoice": "auto_delay_do_create_invoice", + "_do_validate_invoice": "auto_delay_do_validation", + "_do_validate_picking": "auto_delay_do_validation", + "_do_sale_done": "auto_delay_do_sale_done", + } + for method_name, context_key in mapping.items(): + self._patch_method( + method_name, + self._patch_job_auto_delay(method_name, context_key=context_key), + ) + return super()._register_hook() diff --git a/sale_automatic_workflow_job/tests/test_auto_workflow_job.py b/sale_automatic_workflow_job/tests/test_auto_workflow_job.py index e40069ff776..480bcd04fdf 100644 --- a/sale_automatic_workflow_job/tests/test_auto_workflow_job.py +++ b/sale_automatic_workflow_job/tests/test_auto_workflow_job.py @@ -5,17 +5,18 @@ from odoo.addons.queue_job.job import identity_exact from odoo.addons.queue_job.tests.common import mock_with_delay -from odoo.addons.sale_automatic_workflow.tests.test_automatic_workflow_base import ( # noqa - TestAutomaticWorkflowBase, +from odoo.addons.sale_automatic_workflow.tests.common import ( + TestAutomaticWorkflowMixin, + TestCommon, ) @tagged("post_install", "-at_install") -class TestAutoWorkflowJob(TestAutomaticWorkflowBase): - def setUp(self): - super().setUp() - workflow = self.create_full_automatic() - self.sale = self.create_sale_order(workflow) +class TestAutoWorkflowJob(TestCommon, TestAutomaticWorkflowMixin): + def create_sale_order(self, workflow, override=None): + order = super().create_sale_order(workflow, override) + order.order_line.product_id.invoice_policy = "order" + return order def assert_job_delayed(self, delayable_cls, delayable, method_name, args): # .with_delay() has been called once @@ -33,50 +34,90 @@ def assert_job_delayed(self, delayable_cls, delayable, method_name, args): self.assertDictEqual(delay_kwargs, {}) def test_validate_sale_order(self): + workflow = self.create_full_automatic() + self.sale = self.create_sale_order(workflow) with mock_with_delay() as (delayable_cls, delayable): - self.progress() # run automatic workflow cron + self.run_job() # run automatic workflow cron + args = ( + self.sale, + [ + ("state", "=", "draft"), + ("workflow_process_id", "=", self.sale.workflow_process_id.id), + ], + ) self.assert_job_delayed( - delayable_cls, delayable, "_do_validate_sale_order", (self.sale,) + delayable_cls, delayable, "_do_validate_sale_order", args ) def test_create_invoice(self): + workflow = self.create_full_automatic() + self.sale = self.create_sale_order(workflow) self.sale.action_confirm() # don't care about transfers in this test self.sale.picking_ids.state = "done" with mock_with_delay() as (delayable_cls, delayable): - self.progress() # run automatic workflow cron + self.run_job() # run automatic workflow cron + args = ( + self.sale, + [ + ("state", "in", ["sale", "done"]), + ("invoice_status", "=", "to invoice"), + ("workflow_process_id", "=", self.sale.workflow_process_id.id), + ], + ) self.assert_job_delayed( - delayable_cls, delayable, "_do_create_invoice", (self.sale,) + delayable_cls, delayable, "_do_create_invoice", args ) def test_validate_invoice(self): + workflow = self.create_full_automatic() + self.sale = self.create_sale_order(workflow) self.sale.action_confirm() # don't care about transfers in this test self.sale.picking_ids.state = "done" - self.sale.action_invoice_create() + self.sale._create_invoices() invoice = self.sale.invoice_ids with mock_with_delay() as (delayable_cls, delayable): - self.progress() # run automatic workflow cron + self.run_job() # run automatic workflow cron + args = ( + invoice, + [ + ("state", "=", "draft"), + ("posted_before", "=", False), + ("workflow_process_id", "=", self.sale.workflow_process_id.id), + ], + ) self.assert_job_delayed( - delayable_cls, delayable, "_do_validate_invoice", (invoice,) + delayable_cls, delayable, "_do_validate_invoice", args ) def test_validate_picking(self): + workflow = self.create_full_automatic() + self.sale = self.create_sale_order(workflow) self.sale.action_confirm() picking = self.sale.picking_ids # disable invoice creation in this test self.sale.workflow_process_id.create_invoice = False with mock_with_delay() as (delayable_cls, delayable): - self.progress() # run automatic workflow cron + self.run_job() # run automatic workflow cron + args = ( + picking, + [ + ("state", "in", ["draft", "confirmed", "assigned"]), + ("workflow_process_id", "=", self.sale.workflow_process_id.id), + ], + ) self.assert_job_delayed( - delayable_cls, delayable, "_do_validate_picking", (picking,) + delayable_cls, delayable, "_do_validate_picking", args ) def test_sale_done(self): + workflow = self.create_full_automatic() + self.sale = self.create_sale_order(workflow) self.sale.action_confirm() # don't care about transfers in this test self.sale.picking_ids.state = "done" - self.sale.action_invoice_create() + self.sale._create_invoices() # disable invoice validation for we don't care # in this test @@ -85,7 +126,13 @@ def test_sale_done(self): self.sale.workflow_process_id.sale_done = True with mock_with_delay() as (delayable_cls, delayable): - self.progress() # run automatic workflow cron - self.assert_job_delayed( - delayable_cls, delayable, "_do_sale_done", (self.sale,) + self.run_job() # run automatic workflow cron + args = ( + self.sale, + [ + ("state", "=", "sale"), + ("invoice_status", "=", "invoiced"), + ("workflow_process_id", "=", self.sale.workflow_process_id.id), + ], ) + self.assert_job_delayed(delayable_cls, delayable, "_do_sale_done", args) From 2590bbf875462f9b6b87b843d92a3599483d517f Mon Sep 17 00:00:00 2001 From: oca-travis Date: Tue, 18 Jan 2022 07:47:55 +0000 Subject: [PATCH 13/21] [UPD] Update sale_automatic_workflow_job.pot --- .../i18n/sale_automatic_workflow_job.pot | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot index 859ff6450fc..1c98cf2a97f 100644 --- a/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot +++ b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot @@ -1,12 +1,12 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * sale_automatic_workflow_job +# * sale_automatic_workflow_job # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" +"Project-Id-Version: Odoo Server 14.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: <>\n" +"Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -14,13 +14,31 @@ msgstr "" "Plural-Forms: \n" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:106 +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:0 #, python-format msgid "Create invoices for sales order {}" msgstr "" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:144 +#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_automatic_workflow_job__display_name +#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_queue_job__display_name +msgid "Display Name" +msgstr "" + +#. module: sale_automatic_workflow_job +#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_automatic_workflow_job__id +#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_queue_job__id +msgid "ID" +msgstr "" + +#. module: sale_automatic_workflow_job +#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_automatic_workflow_job____last_update +#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_queue_job____last_update +msgid "Last Modified on" +msgstr "" + +#. module: sale_automatic_workflow_job +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:0 #, python-format msgid "Mark sales order {} as done" msgstr "" @@ -31,31 +49,32 @@ msgid "Queue Job" msgstr "" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/queue_job.py:14 +#: code:addons/sale_automatic_workflow_job/models/queue_job.py:0 #, python-format msgid "Sale Automatic Workflow Job" msgstr "" #. module: sale_automatic_workflow_job #: model:ir.model,name:sale_automatic_workflow_job.model_automatic_workflow_job -msgid "Scheduler that will play automatically the validation of invoices, pickings..." +msgid "" +"Scheduler that will play automatically the validation of invoices, " +"pickings..." msgstr "" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:120 +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:0 #, python-format msgid "Validate invoice {}" msgstr "" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:94 +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:0 #, python-format msgid "Validate sales order {}" msgstr "" #. module: sale_automatic_workflow_job -#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:132 +#: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:0 #, python-format msgid "Validate transfer {}" msgstr "" - From c0a40fec2c4cca2a66367d3847284e5de45e61cd Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 18 Jan 2022 08:02:57 +0000 Subject: [PATCH 14/21] [UPD] README.rst --- sale_automatic_workflow_job/README.rst | 11 ++++++----- .../static/description/index.html | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/sale_automatic_workflow_job/README.rst b/sale_automatic_workflow_job/README.rst index 8722d89e884..f3bf4c19e64 100644 --- a/sale_automatic_workflow_job/README.rst +++ b/sale_automatic_workflow_job/README.rst @@ -14,13 +14,13 @@ Sale Automatic Workflow Job :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github - :target: https://github.com/OCA/sale-workflow/tree/12.0/sale_automatic_workflow_job + :target: https://github.com/OCA/sale-workflow/tree/14.0/sale_automatic_workflow_job :alt: OCA/sale-workflow .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/sale-workflow-12-0/sale-workflow-12-0-sale_automatic_workflow_job + :target: https://translation.odoo-community.org/projects/sale-workflow-14-0/sale-workflow-14-0-sale_automatic_workflow_job :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/167/12.0 + :target: https://runbot.odoo-community.org/runbot/167/14.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -52,7 +52,7 @@ 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 `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -69,6 +69,7 @@ Contributors * Guewen Baconnier * Saran Lim. +* Kitti U. Maintainers ~~~~~~~~~~~ @@ -83,6 +84,6 @@ 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-workflow `_ project on GitHub. +This module is part of the `OCA/sale-workflow `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/sale_automatic_workflow_job/static/description/index.html b/sale_automatic_workflow_job/static/description/index.html index 00b127ee9f5..f9f8c0b5ef5 100644 --- a/sale_automatic_workflow_job/static/description/index.html +++ b/sale_automatic_workflow_job/static/description/index.html @@ -367,7 +367,7 @@

Sale Automatic Workflow Job

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

Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runbot

Use Queue Jobs to process the Sales Automatic Workflow actions.

The default behavior of the automatic workflow module is to use a scheduled action that searches all the record that need a workflow @@ -396,7 +396,7 @@

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.

+feedback.

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

@@ -412,6 +412,7 @@

Contributors

@@ -421,7 +422,7 @@

Maintainers

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-workflow project on GitHub.

+

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

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

From c9c14a6bfde4e4f9cb1cd389266795c7ed4a3d81 Mon Sep 17 00:00:00 2001 From: oca-git-bot Date: Thu, 31 Mar 2022 17:32:47 +0200 Subject: [PATCH 15/21] [IMP] update dotfiles [ci skip] --- sale_automatic_workflow_job/models/queue_job.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sale_automatic_workflow_job/models/queue_job.py b/sale_automatic_workflow_job/models/queue_job.py index b9ecf215cd6..02e856a782d 100644 --- a/sale_automatic_workflow_job/models/queue_job.py +++ b/sale_automatic_workflow_job/models/queue_job.py @@ -5,7 +5,7 @@ class QueueJob(models.Model): - """ Job status and result """ + """Job status and result""" _inherit = "queue.job" From 12ab0db222f085ca94bb26bc3812e5466daec6dd Mon Sep 17 00:00:00 2001 From: Vimal Patel Date: Tue, 7 Jun 2022 15:41:06 +0530 Subject: [PATCH 16/21] [ADD] Initial commit --- sale_automatic_workflow_job/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sale_automatic_workflow_job/__manifest__.py b/sale_automatic_workflow_job/__manifest__.py index a12e96cebc4..e12c638daa8 100644 --- a/sale_automatic_workflow_job/__manifest__.py +++ b/sale_automatic_workflow_job/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Sale Automatic Workflow Job", "summary": "Execute sale automatic workflows in queue jobs", - "version": "14.0.1.0.0", + "version": "15.0.1.0.0", "category": "Sales Management", "license": "AGPL-3", "author": "Camptocamp, " "Odoo Community Association (OCA)", From 8288679836fb82d4c369093586629c2f2bdb1a90 Mon Sep 17 00:00:00 2001 From: Vimal Patel Date: Tue, 7 Jun 2022 17:27:50 +0530 Subject: [PATCH 17/21] [MIG] sale_automatic_workflow_job: Migration into v15 --- .../data/queue_job_data.xml | 134 +++++++++--------- 1 file changed, 66 insertions(+), 68 deletions(-) diff --git a/sale_automatic_workflow_job/data/queue_job_data.xml b/sale_automatic_workflow_job/data/queue_job_data.xml index 052a7543266..66f75cca078 100644 --- a/sale_automatic_workflow_job/data/queue_job_data.xml +++ b/sale_automatic_workflow_job/data/queue_job_data.xml @@ -1,76 +1,74 @@ - - - - channel.sale.automatic.workflow - - + + + channel.sale.automatic.workflow + + - - - - _do_validate_sale_order - - - + + + + _do_validate_sale_order + + + - - - _do_create_invoice - - - + + + _do_create_invoice + + + - - - _do_validate_invoice - - - + + + _do_validate_invoice + + + - - - _do_validate_picking - - - + + + _do_validate_picking + + + - - - _do_sale_done - - - - + + + _do_sale_done + + + From 584815fb389ad8dacb51c2add0987bc83668bc47 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Thu, 11 Aug 2022 21:24:19 +0000 Subject: [PATCH 18/21] [UPD] Update sale_automatic_workflow_job.pot --- .../i18n/sale_automatic_workflow_job.pot | 20 +------------------ 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot index 1c98cf2a97f..ca3f191bf9c 100644 --- a/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot +++ b/sale_automatic_workflow_job/i18n/sale_automatic_workflow_job.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" +"Project-Id-Version: Odoo Server 15.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" @@ -19,24 +19,6 @@ msgstr "" msgid "Create invoices for sales order {}" msgstr "" -#. module: sale_automatic_workflow_job -#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_automatic_workflow_job__display_name -#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_queue_job__display_name -msgid "Display Name" -msgstr "" - -#. module: sale_automatic_workflow_job -#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_automatic_workflow_job__id -#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_queue_job__id -msgid "ID" -msgstr "" - -#. module: sale_automatic_workflow_job -#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_automatic_workflow_job____last_update -#: model:ir.model.fields,field_description:sale_automatic_workflow_job.field_queue_job____last_update -msgid "Last Modified on" -msgstr "" - #. module: sale_automatic_workflow_job #: code:addons/sale_automatic_workflow_job/models/automatic_workflow_job.py:0 #, python-format From 3dac8682235ac741b5dd99cb6cee9a480294ce21 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Thu, 11 Aug 2022 21:31:13 +0000 Subject: [PATCH 19/21] [UPD] README.rst --- sale_automatic_workflow_job/README.rst | 10 +++++----- .../static/description/index.html | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sale_automatic_workflow_job/README.rst b/sale_automatic_workflow_job/README.rst index f3bf4c19e64..5023f8717f3 100644 --- a/sale_automatic_workflow_job/README.rst +++ b/sale_automatic_workflow_job/README.rst @@ -14,13 +14,13 @@ Sale Automatic Workflow Job :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github - :target: https://github.com/OCA/sale-workflow/tree/14.0/sale_automatic_workflow_job + :target: https://github.com/OCA/sale-workflow/tree/15.0/sale_automatic_workflow_job :alt: OCA/sale-workflow .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/sale-workflow-14-0/sale-workflow-14-0-sale_automatic_workflow_job + :target: https://translation.odoo-community.org/projects/sale-workflow-15-0/sale-workflow-15-0-sale_automatic_workflow_job :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/167/14.0 + :target: https://runbot.odoo-community.org/runbot/167/15.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -52,7 +52,7 @@ 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 `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -84,6 +84,6 @@ 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-workflow `_ project on GitHub. +This module is part of the `OCA/sale-workflow `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/sale_automatic_workflow_job/static/description/index.html b/sale_automatic_workflow_job/static/description/index.html index f9f8c0b5ef5..ad84f62e493 100644 --- a/sale_automatic_workflow_job/static/description/index.html +++ b/sale_automatic_workflow_job/static/description/index.html @@ -367,7 +367,7 @@

Sale Automatic Workflow Job

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

Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runbot

+

Beta License: AGPL-3 OCA/sale-workflow Translate me on Weblate Try me on Runbot

Use Queue Jobs to process the Sales Automatic Workflow actions.

The default behavior of the automatic workflow module is to use a scheduled action that searches all the record that need a workflow @@ -396,7 +396,7 @@

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.

+feedback.

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

@@ -422,7 +422,7 @@

Maintainers

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-workflow project on GitHub.

+

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

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

From 90795228240dd794a8b05b393d11fde8f07b09ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro?= Date: Mon, 23 Jan 2023 18:21:06 +0100 Subject: [PATCH 20/21] [IMP] sale_automatic_workflow_job: pre-commit stuff --- .../odoo/addons/sale_automatic_workflow_job | 1 + setup/sale_automatic_workflow_job/setup.py | 6 ++++++ 2 files changed, 7 insertions(+) create mode 120000 setup/sale_automatic_workflow_job/odoo/addons/sale_automatic_workflow_job create mode 100644 setup/sale_automatic_workflow_job/setup.py diff --git a/setup/sale_automatic_workflow_job/odoo/addons/sale_automatic_workflow_job b/setup/sale_automatic_workflow_job/odoo/addons/sale_automatic_workflow_job new file mode 120000 index 00000000000..babf49076bc --- /dev/null +++ b/setup/sale_automatic_workflow_job/odoo/addons/sale_automatic_workflow_job @@ -0,0 +1 @@ +../../../../sale_automatic_workflow_job \ No newline at end of file diff --git a/setup/sale_automatic_workflow_job/setup.py b/setup/sale_automatic_workflow_job/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/sale_automatic_workflow_job/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 901c51b9527282d3c437a6272ef3d06dea9e1abd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro?= Date: Mon, 23 Jan 2023 18:23:03 +0100 Subject: [PATCH 21/21] [MIG] sale_automatic_workflow_job: Migration to 16.0 --- sale_automatic_workflow_job/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sale_automatic_workflow_job/__manifest__.py b/sale_automatic_workflow_job/__manifest__.py index e12c638daa8..b2ca9e514d5 100644 --- a/sale_automatic_workflow_job/__manifest__.py +++ b/sale_automatic_workflow_job/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Sale Automatic Workflow Job", "summary": "Execute sale automatic workflows in queue jobs", - "version": "15.0.1.0.0", + "version": "16.0.1.0.0", "category": "Sales Management", "license": "AGPL-3", "author": "Camptocamp, " "Odoo Community Association (OCA)",