From a6ec1d837cf12bd2ecf1aa51a6ec3a1f1784612c Mon Sep 17 00:00:00 2001 From: lreficent Date: Thu, 14 Dec 2017 16:26:43 +0100 Subject: [PATCH 01/23] [9.0][ADD] ddmrp_product_replace --- ddmrp_product_replace/README.rst | 41 ++++++++ ddmrp_product_replace/__init__.py | 5 + ddmrp_product_replace/__openerp__.py | 22 ++++ ddmrp_product_replace/models/__init__.py | 4 + .../models/stock_warehouse_orderpoint.py | 27 +++++ .../static/description/icon.png | Bin 0 -> 5000 bytes ddmrp_product_replace/wizards/__init__.py | 4 + .../wizards/ddmrp_product_replace.py | 95 ++++++++++++++++++ .../wizards/ddmrp_product_replace_view.xml | 58 +++++++++++ 9 files changed, 256 insertions(+) create mode 100644 ddmrp_product_replace/README.rst create mode 100644 ddmrp_product_replace/__init__.py create mode 100644 ddmrp_product_replace/__openerp__.py create mode 100644 ddmrp_product_replace/models/__init__.py create mode 100644 ddmrp_product_replace/models/stock_warehouse_orderpoint.py create mode 100644 ddmrp_product_replace/static/description/icon.png create mode 100644 ddmrp_product_replace/wizards/__init__.py create mode 100644 ddmrp_product_replace/wizards/ddmrp_product_replace.py create mode 100644 ddmrp_product_replace/wizards/ddmrp_product_replace_view.xml diff --git a/ddmrp_product_replace/README.rst b/ddmrp_product_replace/README.rst new file mode 100644 index 000000000..f8ef71dd6 --- /dev/null +++ b/ddmrp_product_replace/README.rst @@ -0,0 +1,41 @@ +.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg + :alt: License AGPL-3 + +===================== +DDMRP Product Replace +===================== + +Provides a tool for product replacement. + +Usage +===== + +Go to *Inventory > Configuration > DDMRP > Product Replacement Tool*. + +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. + +Roadmap +======= + +* Option to create new buffer and make old ones inactive. +* Consider Demand estimates in the replacement. + +Credits +======= + +Contributors +------------ + +* Lois Rilo +* Jordi Ballester + +Maintainer +---------- + +This module is maintained by the Eficent. diff --git a/ddmrp_product_replace/__init__.py b/ddmrp_product_replace/__init__.py new file mode 100644 index 000000000..fbe944470 --- /dev/null +++ b/ddmrp_product_replace/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import models +from . import wizards diff --git a/ddmrp_product_replace/__openerp__.py b/ddmrp_product_replace/__openerp__.py new file mode 100644 index 000000000..bd3150b18 --- /dev/null +++ b/ddmrp_product_replace/__openerp__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Eficent Business and IT Consulting Services S.L. +# (http://www.eficent.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +{ + "name": "DDMRP Product Replace", + "summary": "Provides a assisting tool for product replacement.", + "version": "9.0.1.0.0", + "author": "Eficent", + "website": "http://www.eficent.com", + "category": "Warehouse Management", + "depends": [ + "ddmrp", + "stock_putaway_product", + ], + "data": [ + "wizards/ddmrp_product_replace_view.xml", + ], + "license": "AGPL-3", + 'installable': True, +} diff --git a/ddmrp_product_replace/models/__init__.py b/ddmrp_product_replace/models/__init__.py new file mode 100644 index 000000000..6654fecb0 --- /dev/null +++ b/ddmrp_product_replace/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import stock_warehouse_orderpoint diff --git a/ddmrp_product_replace/models/stock_warehouse_orderpoint.py b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py new file mode 100644 index 000000000..e817be6c0 --- /dev/null +++ b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Eficent Business and IT Consulting Services S.L. +# (http://www.eficent.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + + +from openerp import api, fields, models + + +class StockWarehouseOrderpoint(models.Model): + _inherit = 'stock.warehouse.orderpoint' + + demand_product_ids = fields.Many2many( + comodel_name="product.product", string="Considered As Demand", + help="This field is used for a correct product replacement within a " + "DDMRP buffer.", readonly=True, + ) + + @api.multi + def _past_moves_domain(self, date_from, locations): + if not self.demand_product_ids: + return super(StockWarehouseOrderpoint, self)._past_moves_domain( + date_from, locations) + return [('state', '=', 'done'), ('location_id', 'in', locations.ids), + ('location_dest_id', 'not in', locations.ids), + ('product_id', 'in', self.demand_product_ids.ids), + ('date', '>=', date_from)] diff --git a/ddmrp_product_replace/static/description/icon.png b/ddmrp_product_replace/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a0b0ed73ac91bdb4ca8c2269d6c63bb8588f5d6d GIT binary patch literal 5000 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 C40@jc literal 0 HcmV?d00001 diff --git a/ddmrp_product_replace/wizards/__init__.py b/ddmrp_product_replace/wizards/__init__.py new file mode 100644 index 000000000..9a50a45a1 --- /dev/null +++ b/ddmrp_product_replace/wizards/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import ddmrp_product_replace diff --git a/ddmrp_product_replace/wizards/ddmrp_product_replace.py b/ddmrp_product_replace/wizards/ddmrp_product_replace.py new file mode 100644 index 000000000..0a8a7afc2 --- /dev/null +++ b/ddmrp_product_replace/wizards/ddmrp_product_replace.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Eficent Business and IT Consulting Services S.L. +# (http://www.eficent.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from openerp import api, fields, models, _ + + +class DdmrpProductReplace(models.TransientModel): + _name = "ddmrp.product.replace" + + @api.multi + @api.depends("old_product_id") + def _compute_orderpoint_ids(self): + for rec in self: + rec.orderpoint_ids = self.env['stock.warehouse.orderpoint'].search([ + ('product_id', '=', rec.old_product_id.id)]) + + old_product_id = fields.Many2one( + comodel_name="product.product", string="Replaced Product", + help="Product to be replaced.", required=True, ondelete="cascade", + ) + orderpoint_ids = fields.Many2many( + comodel_name="stock.warehouse.orderpoint", + string="Affected Buffers", + readonly=True, compute="_compute_orderpoint_ids", + ) + new_product_id = fields.Many2one( + comodel_name="product.product", string="Substitute Product", + help="Product that is going to replace the other one.", + ) + use_existing = fields.Selection( + string="Use Existing/New Product", required=True, + selection=[("existing", "Use Existing Product"), + ("new", "Create New Product")], + ) + new_product_name = fields.Char(string="New Product Name") + new_product_default_code = fields.Char(string="New Product Internal Ref.") + copy_route = fields.Boolean(string="Copy Routes") + copy_putaway = fields.Boolean(string="Copy Put Away Strategy") + consider_past_demand = fields.Boolean( + string="Consider Old Product Demand", + help="Consider Old product moves as demand for new product", + default=True, + ) + + @api.multi + def button_validate(self): + self.ensure_one() + if self.use_existing == 'new': + default = dict( + name=self.new_product_name, + default_code=self.new_product_default_code, + ) + if not self.copy_route: + default['route_ids'] = None + if (self.copy_putaway and ( + self.old_product_id.product_putaway_ids or + self.old_product_id.product_tmpl_id.product_putaway_ids)): + default['product_putaway_ids'] = [ + (6, 0, self.old_product_id.product_putaway_ids.ids or + self.old_product_id.product_tmpl_id. + product_putaway_ids.ids)] + self.new_product_id = self.old_product_id.copy( + default=default) + elif self.use_existing == 'existing': + if self.copy_route: + self.new_product_id.write({ + 'route_ids': [(6, 0, self.old_product_id.route_ids.ids)], + }) + if (self.copy_putaway and ( + self.old_product_id.product_putaway_ids or + self.old_product_id.product_tmpl_id.product_putaway_ids)): + self.new_product_id.write({ + 'product_putaway_ids': [ + (6, 0, self.old_product_id.product_putaway_ids.ids or + self.old_product_id.product_tmpl_id. + product_putaway_ids.ids)], + }) + if self.orderpoint_ids: + vals = { + 'product_id': self.new_product_id.id, + } + if self.consider_past_demand: + vals['demand_product_ids'] = [ + (6, 0, (self.old_product_id + self.new_product_id).ids)] + self.orderpoint_ids.write(vals) + return { + 'name': _('Replacing Product'), + 'res_id': self.new_product_id.id, + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'product.product', + 'type': 'ir.actions.act_window' + } diff --git a/ddmrp_product_replace/wizards/ddmrp_product_replace_view.xml b/ddmrp_product_replace/wizards/ddmrp_product_replace_view.xml new file mode 100644 index 000000000..6a7d3703e --- /dev/null +++ b/ddmrp_product_replace/wizards/ddmrp_product_replace_view.xml @@ -0,0 +1,58 @@ + + + + + + ddmrp.product.replace.form + ddmrp.product.replace + +
+ + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+ + + + + +
From df1fbde42fb9e8cc89f1690933fc2a772961bef1 Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Wed, 24 Jan 2018 14:25:40 +0100 Subject: [PATCH 02/23] [10.0][MIG] ddmrp_product_replace --- ddmrp_product_replace/{__openerp__.py => __manifest__.py} | 4 ++-- ddmrp_product_replace/models/stock_warehouse_orderpoint.py | 2 +- ddmrp_product_replace/wizards/ddmrp_product_replace.py | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) rename ddmrp_product_replace/{__openerp__.py => __manifest__.py} (84%) diff --git a/ddmrp_product_replace/__openerp__.py b/ddmrp_product_replace/__manifest__.py similarity index 84% rename from ddmrp_product_replace/__openerp__.py rename to ddmrp_product_replace/__manifest__.py index bd3150b18..153a844ab 100644 --- a/ddmrp_product_replace/__openerp__.py +++ b/ddmrp_product_replace/__manifest__.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- -# Copyright 2017 Eficent Business and IT Consulting Services S.L. +# Copyright 2017-18 Eficent Business and IT Consulting Services S.L. # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). { "name": "DDMRP Product Replace", "summary": "Provides a assisting tool for product replacement.", - "version": "9.0.1.0.0", + "version": "10.0.1.0.0", "author": "Eficent", "website": "http://www.eficent.com", "category": "Warehouse Management", diff --git a/ddmrp_product_replace/models/stock_warehouse_orderpoint.py b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py index e817be6c0..f0a29645e 100644 --- a/ddmrp_product_replace/models/stock_warehouse_orderpoint.py +++ b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py @@ -4,7 +4,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from openerp import api, fields, models +from odoo import api, fields, models class StockWarehouseOrderpoint(models.Model): diff --git a/ddmrp_product_replace/wizards/ddmrp_product_replace.py b/ddmrp_product_replace/wizards/ddmrp_product_replace.py index 0a8a7afc2..2247b065a 100644 --- a/ddmrp_product_replace/wizards/ddmrp_product_replace.py +++ b/ddmrp_product_replace/wizards/ddmrp_product_replace.py @@ -3,7 +3,7 @@ # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from openerp import api, fields, models, _ +from odoo import api, fields, models, _ class DdmrpProductReplace(models.TransientModel): @@ -13,8 +13,8 @@ class DdmrpProductReplace(models.TransientModel): @api.depends("old_product_id") def _compute_orderpoint_ids(self): for rec in self: - rec.orderpoint_ids = self.env['stock.warehouse.orderpoint'].search([ - ('product_id', '=', rec.old_product_id.id)]) + rec.orderpoint_ids = self.env['stock.warehouse.orderpoint'].search( + [('product_id', '=', rec.old_product_id.id)]) old_product_id = fields.Many2one( comodel_name="product.product", string="Replaced Product", From 949ae797224120b760fdcde9c9add11ce61c6dfe Mon Sep 17 00:00:00 2001 From: Akim Juillerat Date: Mon, 16 Apr 2018 16:21:45 +0200 Subject: [PATCH 03/23] [11.0][MIG] ddmrp_product_replace (#51) * Migration to 11.0 * Add unittest * Ensure putaway stategies are correctly copied --- ddmrp_product_replace/README.rst | 1 + ddmrp_product_replace/__init__.py | 1 - ddmrp_product_replace/__manifest__.py | 7 +-- ddmrp_product_replace/models/__init__.py | 1 - .../models/stock_warehouse_orderpoint.py | 4 +- ddmrp_product_replace/tests/__init__.py | 0 .../tests/test_product_replace.py | 56 +++++++++++++++++++ ddmrp_product_replace/wizards/__init__.py | 1 - .../wizards/ddmrp_product_replace.py | 32 +++++++---- 9 files changed, 82 insertions(+), 21 deletions(-) create mode 100644 ddmrp_product_replace/tests/__init__.py create mode 100644 ddmrp_product_replace/tests/test_product_replace.py diff --git a/ddmrp_product_replace/README.rst b/ddmrp_product_replace/README.rst index f8ef71dd6..330411266 100644 --- a/ddmrp_product_replace/README.rst +++ b/ddmrp_product_replace/README.rst @@ -34,6 +34,7 @@ Contributors * Lois Rilo * Jordi Ballester +* Akim Juillerat Maintainer ---------- diff --git a/ddmrp_product_replace/__init__.py b/ddmrp_product_replace/__init__.py index fbe944470..e1e144406 100644 --- a/ddmrp_product_replace/__init__.py +++ b/ddmrp_product_replace/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from . import models diff --git a/ddmrp_product_replace/__manifest__.py b/ddmrp_product_replace/__manifest__.py index 153a844ab..296e7afac 100644 --- a/ddmrp_product_replace/__manifest__.py +++ b/ddmrp_product_replace/__manifest__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017-18 Eficent Business and IT Consulting Services S.L. # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). @@ -6,9 +5,9 @@ { "name": "DDMRP Product Replace", "summary": "Provides a assisting tool for product replacement.", - "version": "10.0.1.0.0", - "author": "Eficent", - "website": "http://www.eficent.com", + "version": "11.0.1.0.0", + "author": "Eficent, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/ddmrp", "category": "Warehouse Management", "depends": [ "ddmrp", diff --git a/ddmrp_product_replace/models/__init__.py b/ddmrp_product_replace/models/__init__.py index 6654fecb0..14b7c7a48 100644 --- a/ddmrp_product_replace/models/__init__.py +++ b/ddmrp_product_replace/models/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from . import stock_warehouse_orderpoint diff --git a/ddmrp_product_replace/models/stock_warehouse_orderpoint.py b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py index f0a29645e..af1ac8b91 100644 --- a/ddmrp_product_replace/models/stock_warehouse_orderpoint.py +++ b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Eficent Business and IT Consulting Services S.L. # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). @@ -19,8 +18,7 @@ class StockWarehouseOrderpoint(models.Model): @api.multi def _past_moves_domain(self, date_from, locations): if not self.demand_product_ids: - return super(StockWarehouseOrderpoint, self)._past_moves_domain( - date_from, locations) + return super()._past_moves_domain(date_from, locations) return [('state', '=', 'done'), ('location_id', 'in', locations.ids), ('location_dest_id', 'not in', locations.ids), ('product_id', 'in', self.demand_product_ids.ids), diff --git a/ddmrp_product_replace/tests/__init__.py b/ddmrp_product_replace/tests/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/ddmrp_product_replace/tests/test_product_replace.py b/ddmrp_product_replace/tests/test_product_replace.py new file mode 100644 index 000000000..80caae1e7 --- /dev/null +++ b/ddmrp_product_replace/tests/test_product_replace.py @@ -0,0 +1,56 @@ +# Copyright 2018 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.tests import TransactionCase + + +class TestDDMRPProductReplace(TransactionCase): + + def setUp(self): + super().setUp() + self.orderpoint = self.env.ref('ddmrp.stock_warehouse_orderpoint_901p') + self.old_product = self.env.ref('ddmrp.product_product_901p') + self.putaway = self.env['product.putaway'].create({ + 'name': 'Test per product', + # 'method': 'per_product' + }) + self.old_product.write({ + 'route_ids': [(6, 0, [ + self.env.ref('mrp.route_warehouse0_manufacture').id + ])], + 'product_putaway_ids': [(0, 0, { + 'putaway_id': self.putaway.id, + 'product_tmpl_id': self.old_product.product_tmpl_id.id, + 'fixed_location_id': self.env.ref( + 'stock.stock_location_components').id + })] + }) + + def test_product_replace(self): + self.assertEqual(self.orderpoint.product_id, self.old_product) + self.assertEqual(len(self.orderpoint.demand_product_ids), 0) + + wiz = self.env['ddmrp.product.replace'].create({ + 'old_product_id': self.orderpoint.product_id.id, + 'use_existing': 'new', + 'new_product_name': '901p Replacement', + 'new_product_default_code': 'ABCDE012345', + 'copy_route': True, + 'copy_putaway': True, + }) + self.assertEqual(wiz.orderpoint_ids, self.orderpoint) + new_product_id = wiz.button_validate().get('res_id') + new_product = self.env['product.product'].browse(new_product_id) + + self.assertEqual(new_product.name, '901p Replacement') + self.assertEqual(new_product.default_code, 'ABCDE012345') + self.assertEqual(new_product.route_ids, self.old_product.route_ids) + + new_product_putaways = [(p.putaway_id, p.fixed_location_id) for p in + new_product.product_putaway_ids] + for putaway in self.old_product.product_putaway_ids: + putaway_tuple = (putaway.putaway_id, putaway.fixed_location_id) + self.assertIn(putaway_tuple, new_product_putaways) + + self.assertEqual(self.orderpoint.product_id, new_product) + self.assertIn(self.old_product, self.orderpoint.demand_product_ids) diff --git a/ddmrp_product_replace/wizards/__init__.py b/ddmrp_product_replace/wizards/__init__.py index 9a50a45a1..94e8c6754 100644 --- a/ddmrp_product_replace/wizards/__init__.py +++ b/ddmrp_product_replace/wizards/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from . import ddmrp_product_replace diff --git a/ddmrp_product_replace/wizards/ddmrp_product_replace.py b/ddmrp_product_replace/wizards/ddmrp_product_replace.py index 2247b065a..83679d2e9 100644 --- a/ddmrp_product_replace/wizards/ddmrp_product_replace.py +++ b/ddmrp_product_replace/wizards/ddmrp_product_replace.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # Copyright 2017 Eficent Business and IT Consulting Services S.L. # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). @@ -44,6 +43,19 @@ def _compute_orderpoint_ids(self): default=True, ) + def _prepare_copy_putaway_dict(self, from_product, to_product): + putaways = ( + from_product.product_putaway_ids or + from_product.product_tmpl_id.product_putaway_ids + ) + return [ + (0, 0, { + 'putaway_id': p.putaway_id.id, + 'fixed_location_id': p.fixed_location_id.id, + 'product_tmpl_id': to_product.product_tmpl_id.id + }) for p in putaways + ] + @api.multi def button_validate(self): self.ensure_one() @@ -54,15 +66,15 @@ def button_validate(self): ) if not self.copy_route: default['route_ids'] = None + self.new_product_id = self.old_product_id.copy( + default=default) if (self.copy_putaway and ( self.old_product_id.product_putaway_ids or self.old_product_id.product_tmpl_id.product_putaway_ids)): - default['product_putaway_ids'] = [ - (6, 0, self.old_product_id.product_putaway_ids.ids or - self.old_product_id.product_tmpl_id. - product_putaway_ids.ids)] - self.new_product_id = self.old_product_id.copy( - default=default) + self.new_product_id.write({ + 'product_putaway_ids': self._prepare_copy_putaway_dict( + self.old_product_id, self.new_product_id) + }) elif self.use_existing == 'existing': if self.copy_route: self.new_product_id.write({ @@ -72,10 +84,8 @@ def button_validate(self): self.old_product_id.product_putaway_ids or self.old_product_id.product_tmpl_id.product_putaway_ids)): self.new_product_id.write({ - 'product_putaway_ids': [ - (6, 0, self.old_product_id.product_putaway_ids.ids or - self.old_product_id.product_tmpl_id. - product_putaway_ids.ids)], + 'product_putaway_ids': self._prepare_copy_putaway_dict( + self.old_product_id, self.new_product_id), }) if self.orderpoint_ids: vals = { From 089d929f9c7403864a94f836e1c71b344febbabf Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Tue, 30 Oct 2018 10:33:23 +0100 Subject: [PATCH 04/23] [11.0][MIG] ddmrp_product_replace: move to OCA/ddmrp --- ddmrp_product_replace/README.rst | 90 ++++++++++++++---- ddmrp_product_replace/__init__.py | 2 - ddmrp_product_replace/__manifest__.py | 2 + ddmrp_product_replace/models/__init__.py | 2 - ddmrp_product_replace/readme/CONTRIBUTORS.rst | 3 + ddmrp_product_replace/readme/CREDITS.rst | 3 + ddmrp_product_replace/readme/DESCRIPTION.rst | 1 + ddmrp_product_replace/readme/ROADMAP.rst | 2 + ddmrp_product_replace/readme/USAGE.rst | 1 + .../static/description/icon.png | Bin 5000 -> 2440 bytes ddmrp_product_replace/tests/__init__.py | 1 + .../tests/test_product_replace.py | 8 +- ddmrp_product_replace/wizards/__init__.py | 2 - 13 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 ddmrp_product_replace/readme/CONTRIBUTORS.rst create mode 100644 ddmrp_product_replace/readme/CREDITS.rst create mode 100644 ddmrp_product_replace/readme/DESCRIPTION.rst create mode 100644 ddmrp_product_replace/readme/ROADMAP.rst create mode 100644 ddmrp_product_replace/readme/USAGE.rst diff --git a/ddmrp_product_replace/README.rst b/ddmrp_product_replace/README.rst index 330411266..38d635a16 100644 --- a/ddmrp_product_replace/README.rst +++ b/ddmrp_product_replace/README.rst @@ -1,42 +1,100 @@ -.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg - :alt: License AGPL-3 - ===================== DDMRP Product Replace ===================== +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! 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%2Fddmrp-lightgray.png?logo=github + :target: https://github.com/OCA/ddmrp/tree/11.0/ddmrp_product_replace + :alt: OCA/ddmrp +.. |badge4| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/255/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| + Provides a tool for product replacement. +**Table of contents** + +.. contents:: + :local: + Usage ===== Go to *Inventory > Configuration > DDMRP > Product Replacement Tool*. +Known issues / Roadmap +====================== + +* Option to create new buffer and make old ones inactive. +* Consider Demand estimates in the replacement. + 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. +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. -Roadmap -======= - -* Option to create new buffer and make old ones inactive. -* Consider Demand estimates in the replacement. +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* Eficent + Contributors ------------- +~~~~~~~~~~~~ * Lois Rilo * Jordi Ballester * Akim Juillerat -Maintainer ----------- +Other credits +~~~~~~~~~~~~~ + +The initial development of this module has been financially supported by: + +* Aleph Objects, Inc. + +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. + +.. |maintainer-jbeficent| image:: https://github.com/jbeficent.png?size=40px + :target: https://github.com/jbeficent + :alt: jbeficent +.. |maintainer-lreficent| image:: https://github.com/lreficent.png?size=40px + :target: https://github.com/lreficent + :alt: lreficent + +Current `maintainers `__: + +|maintainer-jbeficent| |maintainer-lreficent| + +This module is part of the `OCA/ddmrp `_ project on GitHub. -This module is maintained by the Eficent. +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/ddmrp_product_replace/__init__.py b/ddmrp_product_replace/__init__.py index e1e144406..aee8895e7 100644 --- a/ddmrp_product_replace/__init__.py +++ b/ddmrp_product_replace/__init__.py @@ -1,4 +1,2 @@ -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). - from . import models from . import wizards diff --git a/ddmrp_product_replace/__manifest__.py b/ddmrp_product_replace/__manifest__.py index 296e7afac..c5d7da931 100644 --- a/ddmrp_product_replace/__manifest__.py +++ b/ddmrp_product_replace/__manifest__.py @@ -6,7 +6,9 @@ "name": "DDMRP Product Replace", "summary": "Provides a assisting tool for product replacement.", "version": "11.0.1.0.0", + "development_status": "Beta", "author": "Eficent, Odoo Community Association (OCA)", + "maintainers": ['jbeficent', 'lreficent'], "website": "https://github.com/OCA/ddmrp", "category": "Warehouse Management", "depends": [ diff --git a/ddmrp_product_replace/models/__init__.py b/ddmrp_product_replace/models/__init__.py index 14b7c7a48..5024fb8c7 100644 --- a/ddmrp_product_replace/models/__init__.py +++ b/ddmrp_product_replace/models/__init__.py @@ -1,3 +1 @@ -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). - from . import stock_warehouse_orderpoint diff --git a/ddmrp_product_replace/readme/CONTRIBUTORS.rst b/ddmrp_product_replace/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..da4f4c3cf --- /dev/null +++ b/ddmrp_product_replace/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* Lois Rilo +* Jordi Ballester +* Akim Juillerat diff --git a/ddmrp_product_replace/readme/CREDITS.rst b/ddmrp_product_replace/readme/CREDITS.rst new file mode 100644 index 000000000..259e3b85f --- /dev/null +++ b/ddmrp_product_replace/readme/CREDITS.rst @@ -0,0 +1,3 @@ +The initial development of this module has been financially supported by: + +* Aleph Objects, Inc. diff --git a/ddmrp_product_replace/readme/DESCRIPTION.rst b/ddmrp_product_replace/readme/DESCRIPTION.rst new file mode 100644 index 000000000..136e83fbc --- /dev/null +++ b/ddmrp_product_replace/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Provides a tool for product replacement. diff --git a/ddmrp_product_replace/readme/ROADMAP.rst b/ddmrp_product_replace/readme/ROADMAP.rst new file mode 100644 index 000000000..63104b15b --- /dev/null +++ b/ddmrp_product_replace/readme/ROADMAP.rst @@ -0,0 +1,2 @@ +* Option to create new buffer and make old ones inactive. +* Consider Demand estimates in the replacement. diff --git a/ddmrp_product_replace/readme/USAGE.rst b/ddmrp_product_replace/readme/USAGE.rst new file mode 100644 index 000000000..23dddc68c --- /dev/null +++ b/ddmrp_product_replace/readme/USAGE.rst @@ -0,0 +1 @@ +Go to *Inventory > Configuration > DDMRP > Product Replacement Tool*. diff --git a/ddmrp_product_replace/static/description/icon.png b/ddmrp_product_replace/static/description/icon.png index a0b0ed73ac91bdb4ca8c2269d6c63bb8588f5d6d..f95fc7269c40d169477766bae2f39ae6eccee046 100644 GIT binary patch literal 2440 zcmb7G`9Bl>AK!*7=E@y0N{-xeN!q zEh&nRWNdC9Ifu!yk7J+hPx!tckJsz8up#Eyyq000RWgo779 z;spji#P=W027l!TVT`?t512nvz}N5c=Z9ku{uls29VIZ}>)3zd`AKE0qaW5gIt&{h z9E%3T$HyDqjEca72FIWcqhrHM*tSRcLJ=2-b3O^BD`j83Rh-rEu*1j8Ek=TjB@H*~ z-Uhhmv0_K+-gIyqn|2;y>b8s+)R5H?oJN-2sz#RW&y$UoP?ZqE0|_gowBBp;CJ&vG zJ%NjA8G&YYME0r$^=M7<@7?+G;&OJj-RMEQNP6SP{d#;SiU4>LD%`Jn96zT7Jlzd` zdd3ORX9BvBBLm0$|Ij!2CP^%A%?PrITl_f%Dat){>>YVK{Zw~swTPd4Jtriw^TB!L zCzG_%xD~%+;^a~!8oh3S>8W77AU-?n)nY!JGn5CY?Ga_zAwuO1uIQm(5Ce4cjlz*O zfy`mRUp+9b%|G**mbKp+n;6r{lxS+)A9{jKgW`g_Aa-!prEKCQX zM)-yW7qCHv$uvgCq@O!uMcKEZYrq8+WF$GaAQeJtRBoto zo9covNY-YR{yBiLaJy<9XWCPUaZiA zyb@k)bq4yE?I|O+BgbQ8RHg!1EZ+I)Gj+gafi}poT`54l-a8pdG-KZwhx|hRxX7Lx zJ9bdG?t>4%Pps~mb~9Z-=RFI%r`w&$agX{iXlf@<)APUnwp+0LW*)AjGJsYyd$YKF zqUcR@_OOx@{@>4vJ%JG3mu3s2r)pG#zIASIQ8;tB<(p+n`bsCw>2bDf_~T%WxuKbf ztG0@h+e5#6^eh?}iJ_ra(?0pUAfwjUz<%9waR3?jzPt9kdHT7Z)~fr?jssIuqe6&M z81S_uFNt^rI3C$P{c7YWu=Q-(b9KN*OQoL4&fs~C*c;V_1+QnP+V}h(*J~hHzL&68 z2v+@p_YZQ}275i)z*QJgZK+#W%`B!E`N$oUteWVmXViNDUS_?WYAFj?xYbDUzw9Vl zk$MS_0rPT5axBEM`D(-SX2{d@U|xm*_I`(>B4v-{zn>y@Zw^JLaW`rPS&ZOt;P9X-(Bm%Bvdb$qq zk7xv{+HTT)R7KChwyMNHc#nDtbC#Bu4Jds-SqC~76Z#kIJ*|f$UB>v_XpsJ!lXUp1 zUH1#W6WLmI$MNO~4O<@XbP~1KH0K_|HYUI0Y@|N622Z0B8YJDxcWuVg89gMfw|t5m z6!rPx*YJg<6`0hg-KR&^6&*vT$K3z7?#xpd*}4e8Z@)BWyN$!7s=U_5;twt(L?%+j zLqo$$ivK>)vPmYAF2tQEs<@ZdV4|e7R%@y^znY~oJu`tlkgCx0re6Un1lnQr^?H0V zDn#8pY+CWe#J^^ErWCOtriHWeg2dwmu!lPbvEUID$g*5tmi)a}F{Q`1(>A%+? zpQ1R~vr$2(^-DvfQ06blL0PeIG_i|)f3Z?A#? z%j^rX8s^ea6eoP=%1LQZ`_*elg!1#Hr5uJ>8VawsP_7$P7{GA7;PJ8Y1RiVX@90e} z(J%(-Q_2;Enxf8WPI;hNRc&pfB0tDWoF<+%AG7t}BPq=<-p&T6U}9q5CK;Mn-AdSR zQ%jSfy%j4(OsEnZETLuR2O4!o#tjb`Vrepfpz~LKOpkziU!eH62WipvzM|-~c^$}| zgsrtnD1iWeh7DYq{q7{}imxuL!X#MrzM&EJZe`qCQpd3i;D>`kF){k)dBFTAm>MMoIcJ1)9m;tFZNMUvMda|2}=B4ZX@qJuOEd_$&pUm%f8TgS2ULTZhnz zmwJpFL0&x6O9q7sNRmmD1q6kA9Mu(n4)7|&pm8;+=9;;n_9X38j4}4ZhjlBK!m$1L z#u^h>Ho4S}PqGc%$)l!jPTJ-oXk%?di9*3ak&vV+y81go*MMnqlk>B=w+m~vFPYsr zSPR~Vfvo~@f_5R*OGoD)aK@X6KOKP zzduufBko|4yyk5>Bt9(tmbeN-0lJ)_!3`2#%OIanCjjbYYi84BXqUSlr5J;nos{yW zoB&tA5u8qNze%wBStX#g=5mkdaX8aKAi8n?g+OE=Tg?|e)v6STPG6Mci|{pf{}70B zb+q|}q9dCEf}yp5typ=1k4(aA`6)QOiSH*N#{~PpCj^Ry)+`REG-R6m(snofWRW%u%LkMBBhJu(jX-uh;&E^ zOD`Rd-+%ATyfbs|=ghr#?#wxJ@8^7O98^c0ikyuc0063I8Y-|Gw7zjGQsSGDrLG+U z0OZO}%F57Z%F5i(Hy-v*uCD;Ve=1+!&m{GjS$_Wb6^)V76{OLB=Oxf3vz#Sa!{P%g& zTHe~lP{1$^oQ_^FWfkcRNWr3Ir6;+Pbu~Ksn&Dt3jRit(+SUGc2cj+j*d++?5B086 zxBz|e0KkCf_(OjBp2h3P2B@Ghz?}jt@Y1hQfDkaC_n|>ABhbqVRO#2gBnQ#}z%?LP zi5K`p1#BHYlP3ZuD^h1zfJx--3Q`~u1Z3Y;=LbU?0c*o>*aI-O9VkLUcpnmCD?xD6 zZ({0Tcry{;n`DBZfmj3ZY^4VS0QXZcpv=iINWiT{P$W9qx=>-|8C|ad0@)TBW+ht6%cEye-~Hn z*IaiFyO38dyB@sqJbUw3P4B>j0IkmO&Xm>4$^?OD52(tg)uqA=m@)z!=T9xfr^$+5 zkpB!kO$c~;0pTnthW5&G+$N`>zzNtEH;XPO$X|;udMqS_9^I^7O$Y7*uX7;TXlzO3 zVPM|g!^#vfI2g2{zC{h4g2MMu&V*p5PJxzuP zfq=ox(q#Z>T4yycPh-*QCItYMqVW4wiX@b6j3_L1UK>XfmIZ7>tOB9r$I8+w5&wnX zCNE~qP`qV;m7XO0T1CKCM3=KjTi5pJDb?Bny?OYiCkwGPYe73}Qw$lQVlOF!4UhC& zI@_d4-XT(!>?A^78x4u~@KWxLw~TtcUA=Eg!4*o*DHa-h`@(M+r4r2{XNc)uZn5}_ z_$Kv7Y2h_`1i!#OkniPOZ1LSiUL)QTG#2m-q{|3f9j6@p8?tQV`MQrc5E7qc2OoJv zZU63%jrqG+RqHqtHo+cdyA=~jqhv`t4wEOoOzhYKn;lYqZ~~lRi_|iTw%s)XflxQm zGEpuU*y5|BZy+@$i;Q~Ieup=;T(?djkp8sO-&VRBVWNf-+~(orDG;!{L(O27s=-g) z_x`UAIgbEB>>0%~7maBR;Zprl`B7S@JT1XZgj?U-U(y;liaRp}gP=j^zCZ8l_={nb z?s~hVMTX>um8Q{aO1@H9A^cD%rj%XuNpG;C;1}tqx6*|#p1BqILPhjrD;Okvas&o* znU(uXg-gbN<~TVx9XpC_csG#EMsliV{>&V8Str?8+lV~$qoj(VitN#_y?e{$R?w|7 zR?IDtY^{$(W0~2#2BN>k*s~q7XtF#EP3|Av4`xdFL7y(2Zj>IHzV^w$(92L^Jm3?B z!DmC7&z43ZAJq(Nq01FyznDLdS8y0MRy?j8g89Lcp~HGsB`sE$5odN(H8Ig@MKKyB z26mY4TZuf(-D0oyOq3?x7!hnfaLLlPHLE$@(()xbXZIBe($ZJ<`ecu?PqEKmeLV=G z?yg?gmHLyXIm9zWH54RFAgmxiVDM~9-HOa)H0Oxfbz;FxinQ#(GM`H=hv`FLqJ z>0=+VhQ|$h4bctLKEway$Lux(HpuWl@YEZ#BkFj!!xB8pznzJl5w0hq5~Pn2w_G1R zwc8y)*sZ%{In|HsMlF`p^*c7CbUK!dJS(|VFSs4+uq^4%B5#lKxNVD)n0qzjB5Pyo zBsN{zS=#lt<=$YLOOAcRNZpwCz(DVV8Pp`IZ!1Y^JkO=TrsYr5^hILy2i3eT&4kAZ zJsDFO!Tm%T+8M{FEF*cN03*E7Z`891^UVjFZWG3?P7%3SH({%_^zTy&>zuG>80 z5@Yhc(R+A(_o+u)7hB|8Ia|aysUw>sfg`u0VUB^@^c)j1-ZH^&ynP0IT|JvNOBW?N zDmp7VHjEwE9g4m34-EourRjeV+-%RTnk_5L}+#>$wk4r%vt|s@=5Drz&`Vy z4v{se4YUGk4rdFmC2%3&BFrZIKq5($NYqFyLMhLrL`g8qkEdE21K&vBE~vY{t><#OmCbS*!g%k#*r$j8 z^y>7zUwa=vm_YqCJ$GnM+Doo@_g!Y%`P&;`2b8lb%++oyw;o>qsXp94_C$3rlir(w zp9~lGw{x;nE^gTiyyluCp7%G$Aj8|Pa%Bejon>`nsK3BZ)>P6I5&Sedi$1ePVI`7V z2`a*>yHe(^&B3rAl^dQ!UvHD%wg<{PCSJ)M;aQ9g5w(N**57AMn%2?eCw zdjFm8K-)-VVh%O@=k*_9skFSbyb>6dQ%0T8Z&A!$jIOwHN5n9+8qt)ckHjpxP&g5zzp}D17`Mjr-e5=h!e;>-rVp{DnX zAD0{j=7(AI8(pG5V_NNCeF!2sQr+2f_V#d{`O?~2L*@p1oXDvm?YWW*_n6AX<@kN|d~u(; zU2&!D&iu#Vpk?TK@leN1$KZT+7zR(esSzMFD&6XX5-xEok}GcBS$|iO&tb`--h#Of z-FdWZ=hGvZY+O*3e^+kr^lwD!a@otWf_xnXxnJ2c0moVw*)A4(7R?UI!vzW~-rHIj ztK+_dxwT}A-6qdN-ecQo0nBr>T&0|PsOROP#uqb>%~!|$IAhsL??dfPnUS5burp`u zxYzHK-w!Pc1Dbcbx7ac6g0r{l1sd=tzDGC~Kk{v@8H>PV|1TFUQG; z!n!S-SYxe+J4|VIsL5gruF|f@Vi!l%2h_*;)c6vU^SQX#so0wLUk;@%merIo4F3o< zx(?X%`n)!Oxpe+~*yLhzm*O;GxV18%;^58B=ZY`VJ$yY}O+x{4dmk^*L(?HU^*aso zJwtT0|kL&Z~S$Y4Tx%Zg))Qv*kMC-@iO^K<}KP=g-iI$WNc*4ccBJ zFc2^TDCGypAe#R-fY+orwO%8%1hWeY?A_gU=FlPD3s_J@8~5W}-1W7950{&}`=`u@ z7BEl%&MQEc(zSG5T2O!;ot=>wOy>FVP9#`@ zK>KZBzt594!X{7);gWUjA65>I!K>TAg12;>S_v2qVkHc%xLnrx&L;24b&?H0Ei48n zCr#V|10y3bSy|NJk13KKASfFw3J77X!hQB&At7?j&CTB_lrKXSVyQXk69pC)InVE5 zHYUnJC%F>|+JfM4AU!?(JHgFa`A79nu=D-?-z34Gu}_d2zKv3T+ve^pw!V$|8vML$ z(^I6A6M{=`Y73w43h#=|O3BE`cu`jBm;F<+q^y+04ULUb{=3%O z`gHD?-0<-5Ix20a0u!AQY^in=jmp@fr>MMqL7_RKV^Jgag~wQPktbB_UOT8n`X|TiJI9ouBAp96U zC{|slZLL$wgI(V9JX{~S0E@Cx9v&UREG&dA{Xw!1Q|DS8@GhdP>swo$?wBbzi?S5d#nx7aAxw1?ejOWpv6ozXcy(+2N4ij>>Hd-LuMYwShQer}Y{=#K7rjBM4UX_(`SWPD ztR_7`KhY$WWMIAv|iCQB~O45jUNz}8?=_p;~C%|Gpf*MXn!LZMgHh30cb zK!J@FiNq&}J-IJdAZY&KL87&-HOipQ;x^skMABBKCrSltux+o|_O_dI?o3H$z3T*YbK0fHX z!!_~~S|$P*eNKmPS8Zln$w#5lORcAU{93~hSu+04?jU~pwwGcX6maC-Lp*+Da*`A~ zN*|0j+#@itj9|yK83;`A71K2|G}JskwWosIXNyL?*%kl0tNC+Ld&*?*CMUNwc>8*Y$N##kyk$EQu#XVi=yJ<;;yc5^=P%z z2N~NQCbp4^SYq+)wDYuWs>a5~I>SA$nBcSS4&L5r{h1;R32i%}G-LBljjXBw);4@? zcwv=_o7&LFFi$S%amf!%6Ihfjk&=>f;f-N+P0c`|pmhkCQWaK-1Sqg-Vsc+jgIn@W zTRmeQ2r(yAI1J_Kf$#*-!uTO8iQgWIl5Cwt&7O-94J|E|t1we8Go3OoztmO9-B{cB zP{w-us8XXB4CK*sn={63NN(C5e8-}wU`a~Ag7YH~ASj8^V~k#1U7eYtkqR_X_wo`C zMcZGIA(6T}Q=o$Ks>;(a3AVxV?baf|{2|No$X#wt^&LhKoQcStwXNLeWUNfL^}vqA zn*eKHOE*gG8%7gsNx4BnBtO4=ee))zs1&@&A$p8A{I=&W%TL=iHZ4uEdr5uqyta@} zJ*nw;h2Jay=!vIk4hh!=m8)b<0q*ypiqdB{ySu2cH@qh%2FA+ns^?D+OY*tiQ9Wy0 zJJ7qa8DPL({DxPu2JMZ)pK%bF0Gy7g9zj7e%gf7BGzwnSK&Mws68@NA>1CK!>=T7J z|9|Znk57rgpo`G3IeCRLAWvtlk_!FrR}AbZ^1hmzDC@w_>yXb~zpp1@APB%5MsW#DM zz|QHf2ua7qWH8n{(;khDj<$CtupGE61Q6U@^IM#pYI=;8JT)a`D%35sndHGFTf#Ql zA+5ne9=*+$B5rPO14BdmwDpuGz1MALzw}8s%d65En-xCcEEtsn2%tBO<>cgPZEdYA zNoZw>qvNp?;sYf&-m@_-j_ft~g&sK@)xDhSZy3z7ZzILA-2Q2g?C*(*tn6$>!|{j{ zTv+O$ea9w#Rrt~z3c!fsBmO^q@V^xU7;(S+ih!9_tt?a_#^gT*^h{MprBcZ{;(q`g C40@jc diff --git a/ddmrp_product_replace/tests/__init__.py b/ddmrp_product_replace/tests/__init__.py index e69de29bb..74c5eae89 100644 --- a/ddmrp_product_replace/tests/__init__.py +++ b/ddmrp_product_replace/tests/__init__.py @@ -0,0 +1 @@ +from . import test_product_replace diff --git a/ddmrp_product_replace/tests/test_product_replace.py b/ddmrp_product_replace/tests/test_product_replace.py index 80caae1e7..495a6546c 100644 --- a/ddmrp_product_replace/tests/test_product_replace.py +++ b/ddmrp_product_replace/tests/test_product_replace.py @@ -8,8 +8,8 @@ class TestDDMRPProductReplace(TransactionCase): def setUp(self): super().setUp() - self.orderpoint = self.env.ref('ddmrp.stock_warehouse_orderpoint_901p') - self.old_product = self.env.ref('ddmrp.product_product_901p') + self.orderpoint = self.env.ref('ddmrp.stock_warehouse_orderpoint_rm01') + self.old_product = self.env.ref('ddmrp.product_product_rm01') self.putaway = self.env['product.putaway'].create({ 'name': 'Test per product', # 'method': 'per_product' @@ -33,7 +33,7 @@ def test_product_replace(self): wiz = self.env['ddmrp.product.replace'].create({ 'old_product_id': self.orderpoint.product_id.id, 'use_existing': 'new', - 'new_product_name': '901p Replacement', + 'new_product_name': 'RM-01 Replacement', 'new_product_default_code': 'ABCDE012345', 'copy_route': True, 'copy_putaway': True, @@ -42,7 +42,7 @@ def test_product_replace(self): new_product_id = wiz.button_validate().get('res_id') new_product = self.env['product.product'].browse(new_product_id) - self.assertEqual(new_product.name, '901p Replacement') + self.assertEqual(new_product.name, 'RM-01 Replacement') self.assertEqual(new_product.default_code, 'ABCDE012345') self.assertEqual(new_product.route_ids, self.old_product.route_ids) diff --git a/ddmrp_product_replace/wizards/__init__.py b/ddmrp_product_replace/wizards/__init__.py index 94e8c6754..2aff6d37f 100644 --- a/ddmrp_product_replace/wizards/__init__.py +++ b/ddmrp_product_replace/wizards/__init__.py @@ -1,3 +1 @@ -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). - from . import ddmrp_product_replace From 7afb3bd112876878ed7f391c6014621b08997cea Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Wed, 31 Oct 2018 10:33:06 +0100 Subject: [PATCH 05/23] [11.0][IMP] ddmrp_product_replace: the products considered as demand are visible after a executing a product replacement. --- ddmrp_product_replace/__manifest__.py | 3 ++- .../models/stock_warehouse_orderpoint.py | 13 +++++++++-- .../views/stock_warehouse_orderpoint_view.xml | 23 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 ddmrp_product_replace/views/stock_warehouse_orderpoint_view.xml diff --git a/ddmrp_product_replace/__manifest__.py b/ddmrp_product_replace/__manifest__.py index c5d7da931..1d74aac9b 100644 --- a/ddmrp_product_replace/__manifest__.py +++ b/ddmrp_product_replace/__manifest__.py @@ -5,7 +5,7 @@ { "name": "DDMRP Product Replace", "summary": "Provides a assisting tool for product replacement.", - "version": "11.0.1.0.0", + "version": "11.0.1.0.1", "development_status": "Beta", "author": "Eficent, Odoo Community Association (OCA)", "maintainers": ['jbeficent', 'lreficent'], @@ -17,6 +17,7 @@ ], "data": [ "wizards/ddmrp_product_replace_view.xml", + "views/stock_warehouse_orderpoint_view.xml", ], "license": "AGPL-3", 'installable': True, diff --git a/ddmrp_product_replace/models/stock_warehouse_orderpoint.py b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py index af1ac8b91..bc9c34258 100644 --- a/ddmrp_product_replace/models/stock_warehouse_orderpoint.py +++ b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py @@ -3,7 +3,8 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import api, fields, models +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError class StockWarehouseOrderpoint(models.Model): @@ -12,9 +13,17 @@ class StockWarehouseOrderpoint(models.Model): demand_product_ids = fields.Many2many( comodel_name="product.product", string="Considered As Demand", help="This field is used for a correct product replacement within a " - "DDMRP buffer.", readonly=True, + "DDMRP buffer.", ) + @api.constrains('demand_product_ids') + def _check_demand_product_ids(self): + for rec in self: + if (rec.demand_product_ids and + rec.product_id not in rec.demand_product_ids): + raise ValidationError( + _("Buffered product must be considered as demand.")) + @api.multi def _past_moves_domain(self, date_from, locations): if not self.demand_product_ids: diff --git a/ddmrp_product_replace/views/stock_warehouse_orderpoint_view.xml b/ddmrp_product_replace/views/stock_warehouse_orderpoint_view.xml new file mode 100644 index 000000000..302ac2a38 --- /dev/null +++ b/ddmrp_product_replace/views/stock_warehouse_orderpoint_view.xml @@ -0,0 +1,23 @@ + + + + + + stock.warehouse.orderpoint.form - ddmrp_product_replace + stock.warehouse.orderpoint + + + + + + + + + + + + + From 0a4249f35133484c58be1f601c3b2eed8f037d89 Mon Sep 17 00:00:00 2001 From: Lois Rilo Date: Sun, 9 Dec 2018 17:13:37 +0100 Subject: [PATCH 06/23] fix arguments on _past_moves_domain --- ddmrp_product_replace/models/stock_warehouse_orderpoint.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ddmrp_product_replace/models/stock_warehouse_orderpoint.py b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py index bc9c34258..2ab81c7d0 100644 --- a/ddmrp_product_replace/models/stock_warehouse_orderpoint.py +++ b/ddmrp_product_replace/models/stock_warehouse_orderpoint.py @@ -25,10 +25,11 @@ def _check_demand_product_ids(self): _("Buffered product must be considered as demand.")) @api.multi - def _past_moves_domain(self, date_from, locations): + def _past_moves_domain(self, date_from, date_to, locations): if not self.demand_product_ids: - return super()._past_moves_domain(date_from, locations) + return super()._past_moves_domain(date_from, date_to, locations) return [('state', '=', 'done'), ('location_id', 'in', locations.ids), ('location_dest_id', 'not in', locations.ids), ('product_id', 'in', self.demand_product_ids.ids), - ('date', '>=', date_from)] + ('date', '>=', date_from), + ('date', '<=', date_to)] From e1e868b90dd1592696fa77dc2087d89a52c3a055 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 8 Mar 2019 00:18:19 +0000 Subject: [PATCH 07/23] [UPD] README.rst [UPD] Update ddmrp_product_replace.pot --- ddmrp_product_replace/README.rst | 10 +- .../i18n/ddmrp_product_replace.pot | 189 ++++++++ .../static/description/index.html | 444 ++++++++++++++++++ 3 files changed, 640 insertions(+), 3 deletions(-) create mode 100644 ddmrp_product_replace/i18n/ddmrp_product_replace.pot create mode 100644 ddmrp_product_replace/static/description/index.html diff --git a/ddmrp_product_replace/README.rst b/ddmrp_product_replace/README.rst index 38d635a16..875912025 100644 --- a/ddmrp_product_replace/README.rst +++ b/ddmrp_product_replace/README.rst @@ -16,11 +16,14 @@ DDMRP Product Replace .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fddmrp-lightgray.png?logo=github :target: https://github.com/OCA/ddmrp/tree/11.0/ddmrp_product_replace :alt: OCA/ddmrp -.. |badge4| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/ddmrp-11-0/ddmrp-11-0-ddmrp_product_replace + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png :target: https://runbot.odoo-community.org/runbot/255/11.0 :alt: Try me on Runbot -|badge1| |badge2| |badge3| |badge4| +|badge1| |badge2| |badge3| |badge4| |badge5| Provides a tool for product replacement. @@ -45,7 +48,8 @@ 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. +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. diff --git a/ddmrp_product_replace/i18n/ddmrp_product_replace.pot b/ddmrp_product_replace/i18n/ddmrp_product_replace.pot new file mode 100644 index 000000000..631b571ad --- /dev/null +++ b/ddmrp_product_replace/i18n/ddmrp_product_replace.pot @@ -0,0 +1,189 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * ddmrp_product_replace +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.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: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_orderpoint_ids +msgid "Affected Buffers" +msgstr "" + +#. module: ddmrp_product_replace +#: code:addons/ddmrp_product_replace/models/stock_warehouse_orderpoint.py:25 +#, python-format +msgid "Buffered product must be considered as demand." +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.ui.view,arch_db:ddmrp_product_replace.view_ddmrp_adjustment_sheet_wizard_form +msgid "Cancel" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_consider_past_demand +msgid "Consider Old Product Demand" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,help:ddmrp_product_replace.field_ddmrp_product_replace_consider_past_demand +msgid "Consider Old product moves as demand for new product" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_stock_warehouse_orderpoint_demand_product_ids +msgid "Considered As Demand" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_copy_putaway +msgid "Copy Put Away Strategy" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_copy_route +msgid "Copy Routes" +msgstr "" + +#. module: ddmrp_product_replace +#: selection:ddmrp.product.replace,use_existing:0 +msgid "Create New Product" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_create_uid +msgid "Created by" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_create_date +msgid "Created on" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_display_name +msgid "Display Name" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_id +msgid "ID" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace___last_update +msgid "Last Modified on" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_write_uid +msgid "Last Updated by" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_write_date +msgid "Last Updated on" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_new_product_default_code +msgid "New Product Internal Ref." +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_new_product_name +msgid "New Product Name" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.ui.view,arch_db:ddmrp_product_replace.view_warehouse_orderpoint_form +msgid "Product Replacement" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.actions.act_window,name:ddmrp_product_replace.action_ddmrp_product_replace_wizard +#: model:ir.ui.menu,name:ddmrp_product_replace.menu_ddmrp_product_replace +#: model:ir.ui.view,arch_db:ddmrp_product_replace.view_ddmrp_adjustment_sheet_wizard_form +msgid "Product Replacement Tool" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,help:ddmrp_product_replace.field_ddmrp_product_replace_new_product_id +msgid "Product that is going to replace the other one." +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,help:ddmrp_product_replace.field_ddmrp_product_replace_old_product_id +msgid "Product to be replaced." +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_old_product_id +msgid "Replaced Product" +msgstr "" + +#. module: ddmrp_product_replace +#: code:addons/ddmrp_product_replace/wizards/ddmrp_product_replace.py:99 +#, python-format +msgid "Replacing Product" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.ui.view,arch_db:ddmrp_product_replace.view_ddmrp_adjustment_sheet_wizard_form +msgid "Select Replaced Products" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.ui.view,arch_db:ddmrp_product_replace.view_ddmrp_adjustment_sheet_wizard_form +msgid "Select Replacing Product" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model,name:ddmrp_product_replace.model_stock_warehouse_orderpoint +msgid "Stock Buffer" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_new_product_id +msgid "Substitute Product" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,help:ddmrp_product_replace.field_stock_warehouse_orderpoint_demand_product_ids +msgid "This field is used for a correct product replacement within a DDMRP buffer." +msgstr "" + +#. module: ddmrp_product_replace +#: selection:ddmrp.product.replace,use_existing:0 +msgid "Use Existing Product" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model.fields,field_description:ddmrp_product_replace.field_ddmrp_product_replace_use_existing +msgid "Use Existing/New Product" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.ui.view,arch_db:ddmrp_product_replace.view_ddmrp_adjustment_sheet_wizard_form +msgid "Validate" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.model,name:ddmrp_product_replace.model_ddmrp_product_replace +msgid "ddmrp.product.replace" +msgstr "" + +#. module: ddmrp_product_replace +#: model:ir.ui.view,arch_db:ddmrp_product_replace.view_ddmrp_adjustment_sheet_wizard_form +msgid "or" +msgstr "" + diff --git a/ddmrp_product_replace/static/description/index.html b/ddmrp_product_replace/static/description/index.html new file mode 100644 index 000000000..38b7ef3ee --- /dev/null +++ b/ddmrp_product_replace/static/description/index.html @@ -0,0 +1,444 @@ + + + + + + +DDMRP Product Replace + + + +
+

DDMRP Product Replace

+ + +

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

+

Provides a tool for product replacement.

+

Table of contents

+ +
+

Usage

+

Go to Inventory > Configuration > DDMRP > Product Replacement Tool.

+
+
+

Known issues / Roadmap

+
    +
  • Option to create new buffer and make old ones inactive.
  • +
  • Consider Demand estimates in the replacement.
  • +
+
+
+

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

+
    +
  • Eficent
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+

The initial development of this module has been financially supported by:

+
    +
  • Aleph Objects, Inc.
  • +
+
+
+

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.

+

Current maintainers:

+

jbeficent lreficent

+

This module is part of the OCA/ddmrp project on GitHub.

+

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

+
+
+
+ + From 646e2d09197003f95176e833dc6732279d9d2d53 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 29 Jul 2019 02:50:24 +0000 Subject: [PATCH 08/23] [UPD] README.rst --- ddmrp_product_replace/static/description/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ddmrp_product_replace/static/description/index.html b/ddmrp_product_replace/static/description/index.html index 38b7ef3ee..51e541102 100644 --- a/ddmrp_product_replace/static/description/index.html +++ b/ddmrp_product_replace/static/description/index.html @@ -3,7 +3,7 @@ - + DDMRP Product Replace