From cfbeed761a3f9877f01e7200fee91af76b072761 Mon Sep 17 00:00:00 2001 From: fw-bot Date: Thu, 21 Nov 2019 11:10:50 +0000 Subject: [PATCH] [FIX] mrp: unit_factor computation Updating the quantity to produce in a production order will recompute each raw move's unit factor. The issue was this computation did not take care of the previously product quantity. The unit factor was wrong and so the next created workorder lines get the wrong quantity. Example: - 1 components for 1 finished product (unit_factor = 1) - Create a production for 2 finished product -> quantity to consume = 2 - Produce 1 then change quantity to produce to 3 -> quantity to consume = 3 and quantity done = 1 but unit factor became 1.5 closes odoo/odoo#40990 X-original-commit: 79976600df45afc6150150734eef405fd41a70a3 Signed-off-by: William Henrotin --- addons/mrp/models/mrp_production.py | 2 +- addons/mrp/tests/test_order.py | 36 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index e7547f22e34..1e29203d220 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -625,7 +625,7 @@ class MrpProduction(models.Model): move[0].with_context(do_not_unreserve=True).write({'product_uom_qty': quantity}) move[0]._recompute_state() move[0]._action_assign() - move[0].unit_factor = remaining_qty and quantity / remaining_qty or 1.0 + move[0].unit_factor = remaining_qty and (quantity - move[0].quantity_done) / remaining_qty or 1.0 return move[0], old_qty, quantity else: if move[0].quantity_done > 0: diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index a6bc2d47566..f13f41d44ae 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -363,6 +363,42 @@ class TestMrpOrder(TestMrpCommon): self.assertEqual(sum(mo.move_raw_ids.filtered(lambda m: m.product_id == p1).mapped('quantity_done')), 20) self.assertEqual(sum(mo.move_finished_ids.mapped('quantity_done')), 5) + def test_update_quantity_3(self): + """ Build 1 final products then update the Manufacturing + order quantity. Check the remaining quantity to produce + take care of the first quantity produced.""" + self.stock_location = self.env.ref('stock.stock_location_stock') + mo, bom, p_final, p1, p2 = self.generate_mo(qty_final=2) + 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() + + produce_form = Form(self.env['mrp.product.produce'].with_context({ + 'active_id': mo.id, + 'active_ids': [mo.id], + })) + produce_form.qty_producing = 1 + produce_wizard = produce_form.save() + produce_wizard.do_produce() + + update_quantity_wizard = self.env['change.production.qty'].create({ + 'mo_id': mo.id, + 'product_qty': 3, + }) + update_quantity_wizard.change_prod_qty() + + produce_form = Form(self.env['mrp.product.produce'].with_context({ + 'active_id': mo.id, + 'active_ids': [mo.id], + })) + produce_wizard = produce_form.save() + produce_wizard.do_produce() + mo.button_mark_done() + self.assertEqual(sum(mo.move_raw_ids.filtered(lambda m: m.product_id == p1).mapped('quantity_done')), 12) + self.assertEqual(sum(mo.move_finished_ids.mapped('quantity_done')), 3) + def test_rounding(self): """ Checks we round up when bringing goods to produce and round half-up when producing. This implementation allows to implement an efficiency notion (see rev 347f140fe63612ee05e).