diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 4e2e5f6608c..3e487e7636c 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -282,7 +282,12 @@ class MrpProduction(models.Model): ] picking_types = self.env['stock.picking.type'].search_read(domain, ['company_id'], load=False, limit=1) picking_type_by_company = {pt['company_id']: pt['id'] for pt in picking_types} + default_picking_type_id = self._context.get('default_picking_type_id') + default_picking_type = default_picking_type_id and self.env['stock.picking.type'].browse(default_picking_type_id) for mo in self: + if default_picking_type and default_picking_type.company_id == mo.company_id: + mo.picking_type_id = default_picking_type_id + continue if mo.bom_id and mo.bom_id.picking_type_id: mo.picking_type_id = mo.bom_id.picking_type_id continue @@ -345,21 +350,24 @@ class MrpProduction(models.Model): ): production.product_id = bom.product_id or bom.product_tmpl_id.product_variant_id - @api.depends('product_id', 'picking_type_id') + @api.depends('product_id') def _compute_bom_id(self): - mo_by_picking_type_and_company_id = defaultdict(lambda: self.env['mrp.production']) + mo_by_company_id = defaultdict(lambda: self.env['mrp.production']) for mo in self: if not mo.product_id and not mo.bom_id: mo.bom_id = False continue - mo_by_picking_type_and_company_id[(mo.picking_type_id, mo.company_id.id)] |= mo + mo_by_company_id[mo.company_id.id] |= mo - for (picking_type, company_id), productions in mo_by_picking_type_and_company_id.items(): + for company_id, productions in mo_by_company_id.items(): + picking_type_id = self._context.get('default_picking_type_id') + picking_type = picking_type_id and self.env['stock.picking.type'].browse(picking_type_id) boms_by_product = self.env['mrp.bom'].with_context(active_test=True)._bom_find(productions.product_id, picking_type=picking_type, company_id=company_id, bom_type='normal') for production in productions: if not production.bom_id or production.bom_id.product_tmpl_id != production.product_tmpl_id or (production.bom_id.product_id and production.bom_id.product_id != production.product_id): bom = boms_by_product[production.product_id] production.bom_id = bom.id or False + self.env.add_to_compute(production._fields['picking_type_id'], production) @api.depends('bom_id') def _compute_product_qty(self): diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index 80ec4aad926..3bb2b8c4e6c 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -3163,3 +3163,65 @@ class TestMrpOrder(TestMrpCommon): ('warehouse_id.company_id', 'in', mo_2.company_id.ids), ], ['company_id'], load=False, limit=1) self.assertEqual(mo_2.picking_type_id.id, picking_type_company[0]['id']) + + def test_onchange_bom_ids_and_picking_type(self): + warehouse01 = self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1) + warehouse02, warehouse03 = self.env['stock.warehouse'].create([ + {'name': 'Second Warehouse', 'code': 'WH02'}, + {'name': 'Third Warehouse', 'code': 'WH03'}, + ]) + + finished_product = self.env['product.product'].create({'name': 'finished product'}) + bom_wh01, bom_wh02 = self.env['mrp.bom'].create([{ + 'product_id': finished_product.id, + 'product_tmpl_id': finished_product.product_tmpl_id.id, + 'product_uom_id': self.uom_unit.id, + 'product_qty': 1.0, + 'bom_line_ids': [(0, 0, {'product_id': self.product.id, 'product_qty': 1})], + 'picking_type_id': wh.manu_type_id.id, + 'sequence': wh.id, + } for wh in [warehouse01, warehouse02]]) + + # Prioritize BoM of WH02 + bom_wh01.sequence = bom_wh02.sequence + 1 + + mo_form = Form(self.env['mrp.production']) + mo_form.product_id = finished_product + self.assertEqual(mo_form.bom_id, bom_wh02, 'Should select the first BoM in the list, whatever the picking type is') + self.assertEqual(mo_form.picking_type_id, warehouse02.manu_type_id) + + mo_form.bom_id = bom_wh01 + self.assertEqual(mo_form.picking_type_id, warehouse01.manu_type_id, 'Should be adapted because of the found BoM') + + mo_form.bom_id = bom_wh02 + self.assertEqual(mo_form.picking_type_id, warehouse02.manu_type_id, 'Should be adapted because of the found BoM') + + mo_form.picking_type_id = warehouse01.manu_type_id + self.assertEqual(mo_form.bom_id, bom_wh02, 'Should not change') + self.assertEqual(mo_form.picking_type_id, warehouse01.manu_type_id, 'Should not change') + + mo_form.picking_type_id = warehouse03.manu_type_id + mo_form.bom_id = bom_wh01 + self.assertEqual(mo_form.picking_type_id, warehouse01.manu_type_id, 'Should be adapted because of the found BoM ' + '(the selected picking type should be ignored)') + + mo_form = Form(self.env['mrp.production'].with_context(default_picking_type_id=warehouse03.manu_type_id.id)) + mo_form.product_id = finished_product + self.assertFalse(mo_form.bom_id, 'Should not find any BoM, because of the defined picking type') + self.assertEqual(mo_form.picking_type_id, warehouse03.manu_type_id) + + mo_form = Form(self.env['mrp.production'].with_context(default_picking_type_id=warehouse01.manu_type_id.id)) + mo_form.product_id = finished_product + self.assertEqual(mo_form.bom_id, bom_wh01, 'Should select the BoM that matches the default picking type') + self.assertEqual(mo_form.picking_type_id, warehouse01.manu_type_id, 'Should be the default one') + + mo_form.bom_id = bom_wh02 + self.assertEqual(mo_form.picking_type_id, warehouse01.manu_type_id, 'Should not change, because of default value') + + mo_form.picking_type_id = warehouse02.manu_type_id + self.assertEqual(mo_form.bom_id, bom_wh02, 'Should not change') + self.assertEqual(mo_form.picking_type_id, warehouse02.manu_type_id, 'Should not change') + + mo_form.picking_type_id = warehouse02.manu_type_id + mo_form.bom_id = bom_wh02 + self.assertEqual(mo_form.picking_type_id, warehouse01.manu_type_id, 'Should be adapted because of the default value')