From 14836d40841d1a2bc57cc1d39ab61f4f892f875b Mon Sep 17 00:00:00 2001 From: Djamel Touati Date: Wed, 24 Apr 2024 11:59:02 +0200 Subject: [PATCH] [FIX] mrp: create a stock move without `price_unit` in MO Steps to reproduce the bug: - Create a storable product C1: - standard_price: $10 - Update the quantity to 2 units - Create a storable product P1 with BoM: - Component: 1 unit of C1 - Create a MO to produce 1 unit of P1: - Confirm it - Update the price of C1 to $20 - Go back to the MO and set the quantity consumed of C1 to 2 - Mark the MO as done - Confirm the difference in consumption Problem: Another move is created with 1 unit of C1 consumed but is not merged with the first move because the two moves were created with different prices, making them incompatible for merging. Solution: There's no need to create the moves with `price_unit`. OPW-3791816 closes odoo/odoo#163175 Signed-off-by: William Henrotin (whe) --- addons/mrp/models/mrp_production.py | 1 - addons/mrp/models/stock_move.py | 1 - addons/mrp/tests/test_manual_consumption.py | 34 +++++++++++++++++++ .../models/stock_move.py | 2 +- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 8949fdc7268..ad07bfb53ef 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -1192,7 +1192,6 @@ class MrpProduction(models.Model): 'raw_material_production_id': self.id, 'company_id': self.company_id.id, 'operation_id': operation_id, - 'price_unit': product_id.standard_price, 'procure_method': 'make_to_stock', 'origin': self._get_origin(), 'state': 'draft', diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index 0fb50d8d362..70d9a035293 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -309,7 +309,6 @@ class StockMove(models.Model): product = product.browse(values['product_id']) product_id_to_product[values['product_id']] = product values['location_dest_id'] = mo.production_location_id.id - values['price_unit'] = product.standard_price if not values.get('location_id'): values['location_id'] = mo.location_src_id.id continue diff --git a/addons/mrp/tests/test_manual_consumption.py b/addons/mrp/tests/test_manual_consumption.py index f91cf38fa95..2f87fe9c964 100644 --- a/addons/mrp/tests/test_manual_consumption.py +++ b/addons/mrp/tests/test_manual_consumption.py @@ -237,3 +237,37 @@ class TestManualConsumption(TestMrpCommon): mo = self.env[action['res_model']].browse(action['res_id']) self.assertTrue(mo.move_raw_ids.filtered(lambda m: m.product_id == p1).manual_consumption) self.assertFalse(mo.move_raw_ids.filtered(lambda m: m.product_id == p2).manual_consumption) + + def test_manual_consumption_with_different_component_price(self): + """ + Test that the moves are merged correctly, even if the products have been used with different prices: + - Create a product with a price of $10 and use it in a BoM with 1 unit. + - Create a MO with this BoM and confirm it. + - Update the price of the component to $20 and adjust the consumed quantity to 2. + - Mark the MO as done. + - Another move should be created and merged with the first move. + + """ + self.bom_4.consumption = 'warning' + component = self.bom_4.bom_line_ids.product_id + component.write({ + 'type': 'product', + 'standard_price': 10, + }) + self.env['stock.quant']._update_available_quantity(component, self.stock_location, 2) + mo = self.env['mrp.production'].create({ + 'product_qty': 1, + 'bom_id': self.bom_4.id, + }) + mo.action_confirm() + self.assertEqual(mo.state, 'confirmed') + component.standard_price = 20 + mo.move_raw_ids.quantity = 2.0 + mo.move_raw_ids.picked = True + mo.move_raw_ids.manual_consumption = True + self.assertEqual(mo.state, 'progress') + action = mo.button_mark_done() + consumption_warning = Form(self.env['mrp.consumption.warning'].with_context(**action['context'])) + action = consumption_warning.save().action_confirm() + self.assertEqual(len(mo.move_raw_ids), 1) + self.assertEqual(mo.move_raw_ids.quantity, 2) diff --git a/addons/mrp_subcontracting_account/models/stock_move.py b/addons/mrp_subcontracting_account/models/stock_move.py index 2b92ecc7fce..2ae1f13ce70 100644 --- a/addons/mrp_subcontracting_account/models/stock_move.py +++ b/addons/mrp_subcontracting_account/models/stock_move.py @@ -23,7 +23,7 @@ class StockMove(models.Model): # In case of standard price, the component cost is the cost of the product # the subcontracting service cost may not represent the real cost of the subcontracting service # the difference should be posted in price difference account in the end - component_cost = currency.round(sum(m.price_unit * m.product_uom_qty for m in subcontract_production.move_raw_ids)) + component_cost = abs(currency.round(sum(subcontract_production.move_raw_ids.stock_valuation_layer_ids.mapped('value')))) subcontract_service_cost = credit_value - component_cost else: subcontract_service_cost = currency.round(subcontract_production.extra_cost * qty)