From 23451b645a9417aa037276c778c507f39d87f433 Mon Sep 17 00:00:00 2001 From: Arnold Moyaux Date: Tue, 18 Jan 2022 14:42:18 +0000 Subject: [PATCH] [FIX] mrp: mass produce should fill qty_done Usecase: - Create a BoM with a product tracked by SN - Create a MO with qty 5 - Mass produce - Generate -> All the `stock.move.line` in the move_raw_ids don't have the qty done prefilled. The purpose of the feature is to create and validate a lot of MO at once. Which is impossible if you have to fill all the quantity manualy. The choice of a new kwargs that directly set the qty_done is justified by the performance. -> For On a BoM with 10 components for a final product. For 1000 finished product with SN - If we do a loop on each `stock.move.line` to set qty_done as the reserved quantity. It goes from 40s to 135s - With the kwargs. It remaines 40s closes odoo/odoo#83123 X-original-commit: 8ce5926b5a337dc97237f39492e094288b453743 Signed-off-by: William Henrotin (whe) Signed-off-by: Arnold Moyaux --- addons/mrp/models/mrp_production.py | 11 ++++++++--- addons/mrp/tests/test_backorder.py | 1 - addons/mrp/wizard/stock_assign_serial_numbers.py | 6 +++++- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/addons/mrp/models/mrp_production.py b/addons/mrp/models/mrp_production.py index 2f8243b74bc..637b7387472 100644 --- a/addons/mrp/models/mrp_production.py +++ b/addons/mrp/models/mrp_production.py @@ -1493,7 +1493,7 @@ class MrpProduction(models.Model): 'orderpoint_id': self.orderpoint_id.id, } - def _split_productions(self, amounts=False, cancel_remaning_qty=False): + def _split_productions(self, amounts=False, cancel_remaning_qty=False, set_consumed_qty=False): """ Splits productions into productions smaller quantities to produce, i.e. creates its backorders. @@ -1620,12 +1620,17 @@ class MrpProduction(models.Model): taken_qty_uom = product_uom._compute_quantity(taken_qty, move_line.product_uom_id) if move == initial_move: move_line.with_context(bypass_reservation_update=True).reserved_uom_qty = taken_qty_uom + if set_consumed_qty: + move_line.qty_done = taken_qty_uom elif not float_is_zero(taken_qty_uom, precision_rounding=move_line.product_uom_id.rounding): - move_lines_vals.append(dict( + new_ml_vals = dict( ml_vals, reserved_uom_qty=taken_qty_uom, move_id=move.id - )) + ) + if set_consumed_qty: + new_ml_vals['qty_done'] = taken_qty_uom + move_lines_vals.append(new_ml_vals) quantity -= taken_qty move_qty_to_reserve -= taken_qty diff --git a/addons/mrp/tests/test_backorder.py b/addons/mrp/tests/test_backorder.py index 12756ea6cff..4bd524c0a4a 100644 --- a/addons/mrp/tests/test_backorder.py +++ b/addons/mrp/tests/test_backorder.py @@ -266,7 +266,6 @@ class TestMrpProductionBackorder(TestMrpCommon): production_form.qty_producing = 1 production_form.lot_producing_id = serials_final[i] active_production = production_form.save() - active_production.button_mark_done() if i + 1 != nb_product_todo: # If last MO, don't make a backorder action = active_production.button_mark_done() diff --git a/addons/mrp/wizard/stock_assign_serial_numbers.py b/addons/mrp/wizard/stock_assign_serial_numbers.py index 67443ad8845..d2c7407f8e1 100644 --- a/addons/mrp/wizard/stock_assign_serial_numbers.py +++ b/addons/mrp/wizard/stock_assign_serial_numbers.py @@ -62,7 +62,7 @@ class StockAssignSerialNumbers(models.TransientModel): def _assign_serial_numbers(self, cancel_remaining_quantity=False): serial_numbers = self._get_serial_numbers() productions = self.production_id._split_productions( - {self.production_id: [1] * len(serial_numbers)}, cancel_remaining_quantity) + {self.production_id: [1] * len(serial_numbers)}, cancel_remaining_quantity, set_consumed_qty=True) production_lots_vals = [] for serial_name in serial_numbers: production_lots_vals.append({ @@ -77,6 +77,10 @@ class StockAssignSerialNumbers(models.TransientModel): for workorder in production.workorder_ids: workorder.qty_produced = workorder.qty_producing + if productions and len(production_lots) < len(productions): + productions[-1].move_raw_ids.move_line_ids.write({'qty_done': 0}) + productions[-1].state = "confirmed" + def apply(self): self._assign_serial_numbers()