diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index a6faf782f70..8949fdc7268 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -889,12 +889,13 @@ class MrpProduction(models.Model): if production in production_to_replan: production._plan_workorders() if production.state == 'done' and ('lot_producing_id' in vals or 'qty_producing' in vals): - finished_move_lines = production.move_finished_ids.filtered( - lambda move: move.product_id == production.product_id and move.state == 'done').mapped('move_line_ids') + finished_move = production.move_finished_ids.filtered( + lambda move: move.product_id == production.product_id and move.state == 'done') + finished_move_lines = finished_move.move_line_ids if 'lot_producing_id' in vals: finished_move_lines.write({'lot_id': vals.get('lot_producing_id')}) if 'qty_producing' in vals: - finished_move_lines.write({'quantity': vals.get('qty_producing')}) + finished_move.quantity = vals.get('qty_producing') if self._has_workorders() and not production.workorder_ids.operation_id and vals.get('date_start') and not vals.get('date_finished'): new_date_start = fields.Datetime.to_datetime(vals.get('date_start')) if not production.date_finished or new_date_start >= production.date_finished: diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index 9f1712d816d..d4c0a0e9c25 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -805,6 +805,37 @@ class TestMrpOrder(TestMrpCommon): mo.button_mark_done() self.assertTrue(all(s in ['done', 'cancel'] for s in mo.move_raw_ids.mapped('state'))) + def test_product_produce_7(self): + """ Plan 2 finished products, reserve and produce 3. Post the current production. + Simulate an unlock and edit and, on the opened moves, set the consumed quantity + to 5, and to 4. Check the component quantity removed from inventory is correct.""" + self.stock_location = self.env.ref('stock.stock_location_stock') + mo, _, _, p1, p2 = self.generate_mo(qty_final=1) + self.assertEqual(len(mo), 1, 'MO should have been created') + + self.env['stock.quant']._update_available_quantity(p1, self.stock_location, 20) + self.env['stock.quant']._update_available_quantity(p2, self.stock_location, 5) + mo.action_assign() + + mo_form = Form(mo) + mo_form.qty_producing = 2 + mo = mo_form.save() + mo.button_mark_done() + self.assertEqual(sum(mo.move_finished_ids.move_line_ids.mapped('quantity')), 2) + self.assertTrue(mo.is_locked) + + mo.action_toggle_is_locked() + self.assertFalse(mo.is_locked) + mo_form = Form(mo) + mo_form.qty_producing = 5 + mo = mo_form.save() + self.assertAlmostEqual(sum(mo.move_finished_ids.move_line_ids.mapped('quantity')), 5) + + mo_form = Form(mo) + mo_form.qty_producing = 4 + mo = mo_form.save() + self.assertAlmostEqual(sum(mo.move_finished_ids.move_line_ids.mapped('quantity')), 4) + def test_consumption_strict_1(self): """ Checks the constraints of a strict BOM without tracking when playing around quantities to consume."""