From b7d66bec16aa50b41ea214bd3a57b1a9e18d79fd Mon Sep 17 00:00:00 2001 From: "Aurelien van Delft (avd)" Date: Tue, 24 Jan 2023 13:50:30 +0000 Subject: [PATCH] [FIX] stock: speed up MO confirmation When confirming a MO for a SN-tracked product with at least one SN-tracked component, most of the time is taken by _update_reserved_quantity and _apply_putaway_rule. Since a component is tracked by serial number, there will be one move_line with product_uom_qty = 1.0 and one reserved_quant with associated quant of 1.0 by serial number. When the mrp.production.product_qty gets bigger (> 1000) this becomes a performance bottleneck as it slows down the creation of smls and the search for candidate move_lines in _update_reserved_quantity. To fix that, this commit introduces a delay when creating move_lines with sn-tracked products. Because move_lines with sn-tracked product_id are not eligible as to-update candidates, we can create them at the end of the method. This speeds up the search for to-update candidates as these lines are not written to self.move_line_ids during the for loop. This also speeds up the creation of serial-tracked smls as it calls self.create only once at the end. opw-3125714 closes odoo/odoo#111608 X-original-commit: 57ac92fc4c14bf305ffd9ef98212cc80013345f5 Signed-off-by: William Henrotin (whe) --- addons/stock/models/stock_move.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/addons/stock/models/stock_move.py b/addons/stock/models/stock_move.py index 5e4fb1ff29c..dc40c2b9a68 100644 --- a/addons/stock/models/stock_move.py +++ b/addons/stock/models/stock_move.py @@ -1482,6 +1482,7 @@ Please change the quantity done or the rounding precision of your unit of measur taken_quantity = 0 # Find a candidate move line to update or create a new one. + serial_move_line_vals = [] for reserved_quant, quantity in quants: to_update = next((line for line in self.move_line_ids if line._reservation_is_updatable(quantity, reserved_quant)), False) if to_update: @@ -1492,9 +1493,11 @@ Please change the quantity done or the rounding precision of your unit of measur to_update.with_context(bypass_reservation_update=True).reserved_uom_qty += uom_quantity else: if self.product_id.tracking == 'serial': - self.env['stock.move.line'].create([self._prepare_move_line_vals(quantity=1, reserved_quant=reserved_quant) for i in range(int(quantity))]) + # Move lines with serial tracked product_id cannot be to-update candidates. Delay the creation to speed up candidates search + create. + serial_move_line_vals.extend([self._prepare_move_line_vals(quantity=1, reserved_quant=reserved_quant) for i in range(int(quantity))]) else: self.env['stock.move.line'].create(self._prepare_move_line_vals(quantity=quantity, reserved_quant=reserved_quant)) + self.env['stock.move.line'].create(serial_move_line_vals) return taken_quantity def _should_bypass_reservation(self, forced_location=False):