From 8f6e89bdd7b94a70e90c640d7241b05f003a2731 Mon Sep 17 00:00:00 2001 From: Arnold Moyaux Date: Mon, 27 Nov 2023 15:48:08 +0100 Subject: [PATCH] [FIX] mrp, purchase_stock: default route on replenishment Usecase to reproduce: - Install purchase and mrp - On a product set both routes manufacture and buy - Create a BoM for the product and define a seller - Sell a unit - Open the replenishment. Buy or manufacture is set as route - Go to the settings and set the route not sellected to the smallest sequence - Delete the orderpoint and open the replenishment menu again. Expected behavior: The new route with smallest sequence is selected Current behavior: The same rule is selected and the order used by _get_rule and to compute the lead time is bypass It happens because both override of the method are at the same level (super of stock) and are call arbitrary one before the other. In order to fix it uses rule_ids that was computed before calling the function and it contains the real rules used to compute the lead time closes odoo/odoo#146051 X-original-commit: cad38a349c3486cb199ef8079bdd46cffefd5b2e Signed-off-by: William Henrotin (whe) --- addons/mrp/models/stock_orderpoint.py | 14 +++++++++----- addons/mrp/tests/test_bom.py | 3 ++- addons/purchase_stock/models/stock.py | 14 +++++++++----- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/addons/mrp/models/stock_orderpoint.py b/addons/mrp/models/stock_orderpoint.py index 1550eeee22a..911df09ab21 100644 --- a/addons/mrp/models/stock_orderpoint.py +++ b/addons/mrp/models/stock_orderpoint.py @@ -123,12 +123,16 @@ class StockWarehouseOrderpoint(models.Model): return qty_multiple_to_order def _set_default_route_id(self): - route_id = self.env['stock.rule'].search([ + route_ids = self.env['stock.rule'].search([ ('action', '=', 'manufacture') - ], limit=1).route_id - orderpoint_wh_bom = self.filtered(lambda o: o.product_id.bom_ids) - if route_id and orderpoint_wh_bom and (not self.product_id.route_ids or route_id in self.product_id.route_ids): - orderpoint_wh_bom.route_id = route_id[0].id + ]).route_id + for orderpoint in self: + if not orderpoint.product_id.bom_ids: + continue + route_id = orderpoint.rule_ids.route_id & route_ids + if not route_id: + continue + orderpoint.route_id = route_id[0].id return super()._set_default_route_id() def _prepare_procurement_values(self, date=False, group=False): diff --git a/addons/mrp/tests/test_bom.py b/addons/mrp/tests/test_bom.py index 2c552a8ec4f..adb2de73511 100644 --- a/addons/mrp/tests/test_bom.py +++ b/addons/mrp/tests/test_bom.py @@ -1150,12 +1150,14 @@ class TestBoM(TestMrpCommon): uom_kg = self.env.ref('uom.product_uom_kgm') uom_gram = self.env.ref('uom.product_uom_gram') + manufacturing_route_id = self.ref('mrp.route_warehouse0_manufacture') product_gram = self.env['product.product'].create({ 'name': 'Product sold in grams', 'type': 'product', 'uom_id': uom_gram.id, 'uom_po_id': uom_gram.id, + 'route_ids': [(4, manufacturing_route_id)], }) # We create a BoM that manufactures 2kg of product self.env['mrp.bom'].create({ @@ -1178,7 +1180,6 @@ class TestBoM(TestMrpCommon): self.env.flush_all() self.env['stock.warehouse.orderpoint']._get_orderpoint_action() orderpoint = self.env['stock.warehouse.orderpoint'].search([('product_id', '=', product_gram.id)]) - manufacturing_route_id = self.ref('mrp.route_warehouse0_manufacture') self.assertEqual(orderpoint.route_id.id, manufacturing_route_id) self.assertEqual(orderpoint.qty_multiple, 2000.0) self.assertEqual(orderpoint.qty_to_order, 4000.0) diff --git a/addons/purchase_stock/models/stock.py b/addons/purchase_stock/models/stock.py index 02e93e30dc2..c055acb3192 100644 --- a/addons/purchase_stock/models/stock.py +++ b/addons/purchase_stock/models/stock.py @@ -194,12 +194,16 @@ class Orderpoint(models.Model): return res def _set_default_route_id(self): - route_id = self.env['stock.rule'].search([ + route_ids = self.env['stock.rule'].search([ ('action', '=', 'buy') - ], limit=1).route_id - orderpoint_wh_supplier = self.filtered(lambda o: o.product_id.seller_ids) - if route_id and orderpoint_wh_supplier and (not self.product_id.route_ids or route_id in self.product_id.route_ids): - orderpoint_wh_supplier.route_id = route_id[0].id + ]).route_id + for orderpoint in self: + route_id = orderpoint.rule_ids.route_id & route_ids + if not orderpoint.product_id.seller_ids: + continue + if not route_id: + continue + orderpoint.route_id = route_id[0].id return super()._set_default_route_id()