[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) <whe@odoo.com>
This commit is contained in:
Aurelien van Delft (avd)
2023-02-01 17:49:10 +01:00
parent 032c5e1d9d
commit b7d66bec16
+4 -1
View File
@@ -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):