From 3c3c856c2bacb0eb4ec6635774c9babd46e3b85e Mon Sep 17 00:00:00 2001 From: "Touati Djamel (otd)" Date: Wed, 19 Apr 2023 12:17:35 +0000 Subject: [PATCH] [FIX] mrp, purchase{stock,mrp}: use route set on product in orderpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce the bug: - Install purchase, then mrp (in this order) - Create a storable product “P1” - route: buy - Add a supplier - Add a BoM - Create a delivery for the product “P1” - A need is created - Go to inventory > operation > replenishment Problem: An orderpoint is created with the preferred route: Manufacture instead of buy As the "Purchase" module was installed first, the override of the `_set_default_route_id` function will be triggered first, the 'buy' route will be set in the created order point because the product has a supplier. Then, the function in the MRP module will be triggered and since the product has a BoM, the 'buy' route will be replaced by "Manufacture". opw-3228971 closes odoo/odoo#119172 X-original-commit: 227d038efbadf25e3a7be7cceedd9159b71162a3 Signed-off-by: William Henrotin (whe) --- addons/mrp/models/stock_orderpoint.py | 4 +- .../tests/test_purchase_mrp_flow.py | 50 +++++++++++++++++++ addons/purchase_stock/models/stock.py | 4 +- 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/addons/mrp/models/stock_orderpoint.py b/addons/mrp/models/stock_orderpoint.py index fa1cb4a07c6..282210ab871 100644 --- a/addons/mrp/models/stock_orderpoint.py +++ b/addons/mrp/models/stock_orderpoint.py @@ -125,9 +125,9 @@ class StockWarehouseOrderpoint(models.Model): def _set_default_route_id(self): route_id = self.env['stock.rule'].search([ ('action', '=', 'manufacture') - ]).route_id + ], limit=1).route_id orderpoint_wh_bom = self.filtered(lambda o: o.product_id.bom_ids) - if route_id and orderpoint_wh_bom: + 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 return super()._set_default_route_id() diff --git a/addons/purchase_mrp/tests/test_purchase_mrp_flow.py b/addons/purchase_mrp/tests/test_purchase_mrp_flow.py index d24c96878e8..09759f194ad 100644 --- a/addons/purchase_mrp/tests/test_purchase_mrp_flow.py +++ b/addons/purchase_mrp/tests/test_purchase_mrp_flow.py @@ -564,3 +564,53 @@ class TestPurchaseMrpFlow(TransactionCase): po.button_confirm() move_in = po.picking_ids.move_ids self.assertEqual(move_in.move_dest_ids.ids, move_check.ids) + + def test_procurement_with_preferred_route_2(self): + """ + Check that the route set in the product is taken into account + when the product have a supplier and bom. + """ + manu_route = self.warehouse.manufacture_pull_id.route_id + buy_route = self.warehouse.buy_pull_id.route_id + + vendor = self.env['res.partner'].create({'name': 'super vendor'}) + + product = self.env['product.product'].create({ + 'name': 'super product', + 'type': 'product', + 'seller_ids': [(0, 0, {'partner_id': vendor.id})], + 'route_ids': buy_route, + }) + self.env['mrp.bom'].create({ + 'product_tmpl_id': product.product_tmpl_id.id, + 'product_qty': 1.0, + 'product_uom_id': product.uom_id.id, + }) + # create a need of the product with a picking + warehouse = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1) + picking = self.env['stock.picking'].create({ + 'location_id': warehouse.lot_stock_id.id, + 'location_dest_id': self.env.ref('stock.stock_location_customers').id, + 'picking_type_id': warehouse.out_type_id.id, + 'move_ids': [(0, 0, { + 'name': product.name, + 'product_id': product.id, + 'product_uom': product.uom_id.id, + 'product_uom_qty': 1, + 'location_id': warehouse.lot_stock_id.id, + 'location_dest_id': self.env.ref('stock.stock_location_customers').id, + })] + }) + picking.action_assign() + self.env['stock.warehouse.orderpoint']._get_orderpoint_action() + orderpoint_product = self.env['stock.warehouse.orderpoint'].search( + [('product_id', '=', product.id)]) + self.assertEqual(orderpoint_product.route_id, buy_route, "The route buy should be set on the orderpoint") + # Delete the orderpoint to generate a new one with the manufacture route + orderpoint_product.unlink() + # switch the product route to manufacture + product.write({'route_ids': [(3, buy_route.id), (4, manu_route.id)]}) + self.env['stock.warehouse.orderpoint']._get_orderpoint_action() + orderpoint_product = self.env['stock.warehouse.orderpoint'].search( + [('product_id', '=', product.id)]) + self.assertEqual(orderpoint_product.route_id, manu_route, "The route manufacture should be set on the orderpoint") diff --git a/addons/purchase_stock/models/stock.py b/addons/purchase_stock/models/stock.py index 2fc6bd58be4..84af9ffcf32 100644 --- a/addons/purchase_stock/models/stock.py +++ b/addons/purchase_stock/models/stock.py @@ -188,9 +188,9 @@ class Orderpoint(models.Model): def _set_default_route_id(self): route_id = self.env['stock.rule'].search([ ('action', '=', 'buy') - ]).route_id + ], limit=1).route_id orderpoint_wh_supplier = self.filtered(lambda o: o.product_id.seller_ids) - if route_id and orderpoint_wh_supplier: + 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 return super()._set_default_route_id()