From 1594b40ac0e5300be8b8874a672af5af4eb894e1 Mon Sep 17 00:00:00 2001 From: "Adrien Widart (awt)" Date: Wed, 2 Nov 2022 14:43:19 +0000 Subject: [PATCH] [FIX] mrp: round the consumed quantity To reproduce the issue: 1. In Settings, enable UoM 2. Edit the UoM 'Dozens': - Rounding: 1.0 3. Create two products P_finished, P_compo: - P_finished: - UoM: Dozens 4. Create a BoM: - Product: P_finished - Qty: 1 x Dozens - Compo: 1 x P_compo 5. Create and confirm a MO for 1 x P_finished 6. Edit the MO: - Set the producing qty to 1 - Set the 'to consume' quantity of P_compo to 1.23 Error: the consumed quantity of P_compo is still 1.0 (it should be 1.23). If the user tries to set the quantity to 1.56, the consumed quantity will become 2 (also incorrect, should be 1.56) The UoM used to round the new consumed quantity of the component is incorrect. Considering its definition: https://github.com/odoo/odoo/blob/0fdd35cfb5c7145b3a7a855956004e38de7c6e2a/addons/mrp/models/stock_move.py#L164-L170 the UoM of `unit_factor` is `UoM_sm / UoM_mo`. Therefore, in `_update_quantity_done` (see diff), when we compute `new_qty`, we have (in terms of UoM) `(UoM_mo - UoM_mo) * UoM_sm / UoM_mo`. So, the value is already in the correct UoM (`UoM_sm`) and we just have to round it based on that UoM OPW-3016837 closes odoo/odoo#105059 X-original-commit: 90c245a3785a22c9fcbe7dcc2d06ae4205b4fdc9 Signed-off-by: William Henrotin (whe) Signed-off-by: Adrien Widart --- addons/mrp/models/stock_move.py | 2 +- addons/mrp/tests/test_order.py | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/addons/mrp/models/stock_move.py b/addons/mrp/models/stock_move.py index 4312d66bf14..35920f7a88e 100644 --- a/addons/mrp/models/stock_move.py +++ b/addons/mrp/models/stock_move.py @@ -520,7 +520,7 @@ class StockMove(models.Model): def _update_quantity_done(self, mo): self.ensure_one() - new_qty = mo.product_uom_id._compute_quantity((mo.qty_producing - mo.qty_produced) * self.unit_factor, mo.product_uom_id, rounding_method='HALF-UP') + new_qty = float_round((mo.qty_producing - mo.qty_produced) * self.unit_factor, precision_rounding=self.product_uom.rounding) if not self.is_quantity_done_editable: self.move_line_ids.filtered(lambda ml: ml.state not in ('done', 'cancel')).qty_done = 0 self.move_line_ids = self._set_quantity_done_prepare_vals(new_qty) diff --git a/addons/mrp/tests/test_order.py b/addons/mrp/tests/test_order.py index 43b8cad332d..c7dbb524793 100644 --- a/addons/mrp/tests/test_order.py +++ b/addons/mrp/tests/test_order.py @@ -3078,3 +3078,28 @@ class TestMrpOrder(TestMrpCommon): update_quantity_wizard.change_prod_qty() self.assertEqual(mo.move_raw_ids[0].product_uom_qty, 2) + + def test_update_qty_to_consume_of_component(self): + """ + The UoM of the finished product has a rounding precision equal to 1.0 + and the UoM of the component has a decimal one. When the producing qty + is set, an onchange autocomplete the consumed quantity of the component. + Then, when updating the 'to consume' quantity of the components, their + consumed quantity is updated again. The test ensures that this update + respects the rounding precisions + """ + self.uom_dozen.rounding = 1 + self.bom_4.product_uom_id = self.uom_dozen + + mo_form = Form(self.env['mrp.production']) + mo_form.bom_id = self.bom_4 + mo = mo_form.save() + mo.action_confirm() + + mo.action_toggle_is_locked() + with Form(mo) as mo_form: + mo_form.qty_producing = 1 + with mo_form.move_raw_ids.edit(0) as raw: + raw.product_uom_qty = 1.25 + + self.assertEqual(mo.move_raw_ids.quantity_done, 1.25)