From 079bfe934e268e2aad15c368a72c0941fe9723a0 Mon Sep 17 00:00:00 2001 From: Guewen Baconnier Date: Mon, 29 May 2017 22:45:25 +0200 Subject: [PATCH] [IMP] stock_orderpoint_generator: Add Automatic Reordering Rules (#258) And improve the wording * Add an option to automatically generate rules When a product variant is created with a (or several) rule template(s), it automatically generates (on the fly) the corresponding rule(s). When a rule template is modified, it automatically updates the existing rules of the linked products (it uses the mechanism in place, disable the old and create a fresh one). The latter update is done by a cron because it might take a long time to update all the products reordering rules. * Add documentation * Copy orderpoint views to orderpoint templates Unfortunately we cannot rely on the possibility to copy a view with "inherit_id" + "mode=primary" in Odoo 9.0 in this use case (precisely with a model that is a "copy by prototype"). The explanation: We "copy by prototype" the model "stock.warehouse.orderpoint" to a new "stock.warehouse.orderpoint.template" model (with both _inherit and different _name). Before this commit, we were reusing the stock.warehouse.orderpoint's views, just making the changes needed for the templates. Thing is: when a third (unrelated) addon adds a column on the model, the ORM doesn't add the column in the stock.warehouse.orderpoint.template model. So the templates' views complains about this unexisting field. Therefore, copy-pasting the view ensure that changes on 'stock.warehouse.orderpoint' does not have any side effect on the templates. From Odoo 10.0, the "copy by prototype" reports the changes made on the "prototype" model to the "copy" so we should be able to revert to the "inherit_id" + "mode=primary" views. --- stock_orderpoint_generator/README.rst | 37 +++++- stock_orderpoint_generator/__openerp__.py | 5 +- stock_orderpoint_generator/data/ir_cron.xml | 16 +++ stock_orderpoint_generator/models/__init__.py | 1 + .../models/orderpoint_template.py | 29 +++++ stock_orderpoint_generator/models/product.py | 33 ++++++ .../views/orderpoint_template_views.xml | 106 ++++++++++++++++++ .../views/product_views.xml | 14 +++ .../wizard/orderpoint_generator.py | 2 +- .../wizard/orderpoint_generator_view.xml | 11 +- 10 files changed, 245 insertions(+), 9 deletions(-) create mode 100644 stock_orderpoint_generator/data/ir_cron.xml create mode 100644 stock_orderpoint_generator/models/product.py create mode 100644 stock_orderpoint_generator/views/orderpoint_template_views.xml create mode 100644 stock_orderpoint_generator/views/product_views.xml diff --git a/stock_orderpoint_generator/README.rst b/stock_orderpoint_generator/README.rst index 0c0b1e234900..8f8ec38f6b3e 100644 --- a/stock_orderpoint_generator/README.rst +++ b/stock_orderpoint_generator/README.rst @@ -6,7 +6,40 @@ Order point generator ===================== -Add a wizard to configure order points for multiple products in one go. +Add a wizard to configure reordering rules for multiple products in one go, +and allow to automatically update reordering rules from rule templates. + +Configuration +============= + +Reordering rule templates can be configured in "Inventory > Configuration > +Products > Reordering Rule Templates". + +The frequency of the cron that updates the Reordering Rules can be configured +in "Settings > Technical > Actions > Scheduled Actions". The name of the +scheduled action is "Reordering Rule Templates Generator". + +Usage +===== + +By activating the "Create Rules Automatically" on a reordering rule template, +you are able to select a list of products. Any change on the template will then +be replicated on the products Reordering Rules. The change is not immediate as +it is processed by a scheduled action. + +On a product, you can also choose one or more Reordering Rule Templates. Any +template added or removed on the product is immediately reflected on its +Reordering Rules. + +Lastly, you can promptly create Reordering Rules for a product or a product +template using the "Reordering Rules Generator". Note that it will replace all +the existing rules for the product. You will usually not want to use this +feature on products that have Automatic Reordering Rules Templates. + + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/153/9.0 Bug Tracker @@ -22,9 +55,11 @@ Credits Contributors ------------ + * Yannick Vaucher * Matthieu Dietrich * Cyril Gaudin + * Guewen Baconnier Maintainer ---------- diff --git a/stock_orderpoint_generator/__openerp__.py b/stock_orderpoint_generator/__openerp__.py index 1bee4185dce0..71e33923f0ec 100644 --- a/stock_orderpoint_generator/__openerp__.py +++ b/stock_orderpoint_generator/__openerp__.py @@ -5,14 +5,17 @@ { 'name': 'Order point generator', 'summary': 'Mass configuration of stock order points', - 'version': '9.0.1.0.0', + 'version': '9.0.1.1.0', 'author': "Camptocamp, Odoo Community Association (OCA)", 'category': 'Warehouse', 'license': 'AGPL-3', 'website': "http://www.camptocamp.com", 'depends': ['stock'], 'data': [ + 'views/orderpoint_template_views.xml', + 'views/product_views.xml', "wizard/orderpoint_generator_view.xml", + "data/ir_cron.xml", "security/ir.model.access.csv", ], 'installable': True, diff --git a/stock_orderpoint_generator/data/ir_cron.xml b/stock_orderpoint_generator/data/ir_cron.xml new file mode 100644 index 000000000000..d9913dcdca96 --- /dev/null +++ b/stock_orderpoint_generator/data/ir_cron.xml @@ -0,0 +1,16 @@ + + + + + Reordering Rule Templates Generator + 1 + hours + -1 + + + + + + + + diff --git a/stock_orderpoint_generator/models/__init__.py b/stock_orderpoint_generator/models/__init__.py index 04f38969980f..d1390f64f706 100644 --- a/stock_orderpoint_generator/models/__init__.py +++ b/stock_orderpoint_generator/models/__init__.py @@ -1,3 +1,4 @@ # -*- coding: utf-8 -*- from . import orderpoint_template +from . import product diff --git a/stock_orderpoint_generator/models/orderpoint_template.py b/stock_orderpoint_generator/models/orderpoint_template.py index 2428cbb72507..9754b7e347ea 100644 --- a/stock_orderpoint_generator/models/orderpoint_template.py +++ b/stock_orderpoint_generator/models/orderpoint_template.py @@ -18,6 +18,7 @@ class OrderpointTemplate(models.Model): _table is redefined to separate templates from orderpoints """ _name = 'stock.warehouse.orderpoint.template' + _description = 'Reordering Rule Templates' _inherit = 'stock.warehouse.orderpoint' _table = 'stock_warehouse_orderpoint_template' @@ -28,6 +29,20 @@ class OrderpointTemplate(models.Model): product_id = fields.Many2one(required=False) product_uom = fields.Many2one(required=False) + auto_generate = fields.Boolean( + string='Create Rules Automatically', + help="When checked, the 'Reordering Rule Templates Generator' " + "scheduled action will automatically update the rules of a " + "selection of products." + ) + auto_product_ids = fields.Many2many( + comodel_name='product.product', + string='Products', + help="A reordering rule will be automatically created by the " + "scheduled action for every product in this list." + ) + auto_last_generation = fields.Datetime(string='Last Automatic Generation') + def _disable_old_instances(self, product_ids): """ Clean old instance by setting those inactives """ @@ -53,3 +68,17 @@ def create_orderpoints(self, product_ids): """ self._disable_old_instances(product_ids) self._create_instances(product_ids) + + @api.multi + def create_auto_orderpoints(self): + for template in self: + if not template.auto_generate: + continue + if (not template.auto_last_generation or + template.write_date > template.auto_last_generation): + template.auto_last_generation = fields.Datetime.now() + template.create_orderpoints(template.auto_product_ids.ids) + + @api.model + def _cron_create_auto_orderpoints(self): + self.search([('auto_generate', '=', True)]).create_auto_orderpoints() diff --git a/stock_orderpoint_generator/models/product.py b/stock_orderpoint_generator/models/product.py new file mode 100644 index 000000000000..74b26b532b48 --- /dev/null +++ b/stock_orderpoint_generator/models/product.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) + +from openerp import api, fields, models + + +class ProductProduct(models.Model): + _inherit = 'product.product' + + auto_orderpoint_template_ids = fields.Many2many( + comodel_name='stock.warehouse.orderpoint.template', + string="Automatic Reordering Rules", + domain=[('auto_generate', '=', True)], + help="When one or several automatic reordering rule is selected, " + "a Scheduled Action will automatically generate or update " + "the reordering rules of the product." + ) + + @api.model + def create(self, vals): + record = super(ProductProduct, self).create(vals) + if vals.get('auto_orderpoint_template_ids'): + record.auto_orderpoint_template_ids.create_orderpoints(record.ids) + return record + + @api.multi + def write(self, vals): + result = super(ProductProduct, self).write(vals) + if vals.get('auto_orderpoint_template_ids'): + orderpoint_templates = self.mapped('auto_orderpoint_template_ids') + orderpoint_templates.create_orderpoints(self.ids) + return result diff --git a/stock_orderpoint_generator/views/orderpoint_template_views.xml b/stock_orderpoint_generator/views/orderpoint_template_views.xml new file mode 100644 index 000000000000..c9b59aaece4f --- /dev/null +++ b/stock_orderpoint_generator/views/orderpoint_template_views.xml @@ -0,0 +1,106 @@ + + + + + stock.warehouse.orderpoint.template.tree + stock.warehouse.orderpoint.template + primary + + + + + + + + + + + + + + stock.warehouse.orderpoint.template.search + stock.warehouse.orderpoint.template + primary + + + + + + + + + + + + + + + + stock.warehouse.orderpoint.template.form + stock.warehouse.orderpoint.template + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + Reordering Rule Templates + stock.warehouse.orderpoint.template + ir.actions.act_window + form + tree,form + + + +

+ Click to add a reordering rule template. +

+
+
+ + + +
diff --git a/stock_orderpoint_generator/views/product_views.xml b/stock_orderpoint_generator/views/product_views.xml new file mode 100644 index 000000000000..2550e4b20884 --- /dev/null +++ b/stock_orderpoint_generator/views/product_views.xml @@ -0,0 +1,14 @@ + + + + product.product.form + product.product + + + + + + + + + diff --git a/stock_orderpoint_generator/wizard/orderpoint_generator.py b/stock_orderpoint_generator/wizard/orderpoint_generator.py index afb6f14bd62f..54eb8ce15eef 100644 --- a/stock_orderpoint_generator/wizard/orderpoint_generator.py +++ b/stock_orderpoint_generator/wizard/orderpoint_generator.py @@ -21,7 +21,7 @@ class OrderpointGenerator(models.TransientModel): orderpoint_template_id = fields.Many2many( 'stock.warehouse.orderpoint.template', rel='order_point_generator_rel', - string='Stock rule template' + string='Reordering Rule Templates' ) @api.multi diff --git a/stock_orderpoint_generator/wizard/orderpoint_generator_view.xml b/stock_orderpoint_generator/wizard/orderpoint_generator_view.xml index 1b42b3c22870..887b2fcbebdc 100644 --- a/stock_orderpoint_generator/wizard/orderpoint_generator_view.xml +++ b/stock_orderpoint_generator/wizard/orderpoint_generator_view.xml @@ -5,21 +5,20 @@ stock.warehouse.orderpoint.generator stock.warehouse.orderpoint.generator -
+
- -