[IMP] stock: improve scalability of _action_assign
Replace union of RecordSet by union of OrderedSet to reduce the complexity and improve the scalability. It can be a bottleneck to huge number of move to assign. task-2390516 X-original-commit: e89105144a34ee73981db383ac0625dcaf63b27b
This commit is contained in:
@@ -1272,8 +1272,9 @@ class StockMove(models.Model):
|
||||
equal to its `product_qty`. If it is less, the stock move is considered
|
||||
partially available.
|
||||
"""
|
||||
assigned_moves = self.env['stock.move']
|
||||
partially_available_moves = self.env['stock.move']
|
||||
StockMove = self.env['stock.move']
|
||||
assigned_moves_ids = OrderedSet()
|
||||
partially_available_moves_ids = OrderedSet()
|
||||
# Read the `reserved_availability` field of the moves out of the loop to prevent unwanted
|
||||
# cache invalidation when actually reserving the move.
|
||||
reserved_availability = {move: move.reserved_availability for move in self}
|
||||
@@ -1300,17 +1301,17 @@ class StockMove(models.Model):
|
||||
to_update[0].product_uom_qty += missing_reserved_uom_quantity
|
||||
else:
|
||||
move_line_vals_list.append(move._prepare_move_line_vals(quantity=missing_reserved_quantity))
|
||||
assigned_moves |= move
|
||||
assigned_moves_ids.add(move.id)
|
||||
else:
|
||||
if float_is_zero(move.product_uom_qty, precision_rounding=move.product_uom.rounding):
|
||||
assigned_moves |= move
|
||||
assigned_moves_ids.add(move.id)
|
||||
elif not move.move_orig_ids:
|
||||
if move.procure_method == 'make_to_order':
|
||||
continue
|
||||
# If we don't need any quantity, consider the move assigned.
|
||||
need = missing_reserved_quantity
|
||||
if float_is_zero(need, precision_rounding=rounding):
|
||||
assigned_moves |= move
|
||||
assigned_moves_ids.add(move.id)
|
||||
continue
|
||||
# Reserve new quants and create move lines accordingly.
|
||||
forced_package_id = move.package_level_id.package_id or None
|
||||
@@ -1321,9 +1322,9 @@ class StockMove(models.Model):
|
||||
if float_is_zero(taken_quantity, precision_rounding=rounding):
|
||||
continue
|
||||
if float_compare(need, taken_quantity, precision_rounding=rounding) == 0:
|
||||
assigned_moves |= move
|
||||
assigned_moves_ids.add(move.id)
|
||||
else:
|
||||
partially_available_moves |= move
|
||||
partially_available_moves_ids.add(move.id)
|
||||
else:
|
||||
# Check what our parents brought and what our siblings took in order to
|
||||
# determine what we can distribute.
|
||||
@@ -1348,7 +1349,7 @@ class StockMove(models.Model):
|
||||
# As we defer the write on the stock.move's state at the end of the loop, there
|
||||
# could be moves to consider in what our siblings already took.
|
||||
moves_out_siblings = move.move_orig_ids.mapped('move_dest_ids') - move
|
||||
moves_out_siblings_to_consider = moves_out_siblings & (assigned_moves + partially_available_moves)
|
||||
moves_out_siblings_to_consider = moves_out_siblings & (StockMove.browse(assigned_moves_ids) + StockMove.browse(partially_available_moves_ids))
|
||||
reserved_moves_out_siblings = moves_out_siblings.filtered(lambda m: m.state in ['partially_available', 'assigned'])
|
||||
move_lines_out_reserved = (reserved_moves_out_siblings | moves_out_siblings_to_consider).mapped('move_line_ids')
|
||||
keys_out_groupby = ['location_id', 'lot_id', 'package_id', 'owner_id']
|
||||
@@ -1388,15 +1389,15 @@ class StockMove(models.Model):
|
||||
if float_is_zero(taken_quantity, precision_rounding=rounding):
|
||||
continue
|
||||
if float_is_zero(need - taken_quantity, precision_rounding=rounding):
|
||||
assigned_moves |= move
|
||||
assigned_moves_ids.add(move.id)
|
||||
break
|
||||
partially_available_moves |= move
|
||||
partially_available_moves_ids.add(move.id)
|
||||
if move.product_id.tracking == 'serial':
|
||||
move.next_serial_count = move.product_uom_qty
|
||||
|
||||
self.env['stock.move.line'].create(move_line_vals_list)
|
||||
partially_available_moves.write({'state': 'partially_available'})
|
||||
assigned_moves.write({'state': 'assigned'})
|
||||
StockMove.browse(partially_available_moves_ids).write({'state': 'partially_available'})
|
||||
StockMove.browse(assigned_moves_ids).write({'state': 'assigned'})
|
||||
if self.env.context.get('bypass_entire_pack'):
|
||||
return
|
||||
self.mapped('picking_id')._check_entire_pack()
|
||||
|
||||
Reference in New Issue
Block a user