Skip to content

Commit

Permalink
[FIX] stock: create orderpoints faster
Browse files Browse the repository at this point in the history
This commit changes the computation of product having a negative forecasted
quantity to create manual orderpoints. The issue was that each replenish
location needed multiple `_read_group` on `stock.quant` and `stock.move`
on all storable product.

This commit makes only 3 `_read_group`s for all products x locations and
post process the group and quantity sum by location in Python.

This method gives some performance gain in time as well as in memory
consumption

closes #149966

Task: 3653272
Signed-off-by: Arnold Moyaux (arm) <arm@odoo.com>
  • Loading branch information
Whenrow committed Feb 19, 2024
1 parent 46fc328 commit 13ea202
Showing 1 changed file with 36 additions and 8 deletions.
44 changes: 36 additions & 8 deletions addons/stock/models/stock_orderpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,15 +343,43 @@ def _get_orderpoint_action(self):
all_replenish_location_ids = self._get_orderpoint_locations()
ploc_per_day = defaultdict(set)
# For each replenish location get products with negative virtual_available aka forecast


Move = self.env['stock.move'].with_context(active_test=False)
Quant = self.env['stock.quant'].with_context(active_test=False)
domain_quant, domain_move_in_loc, domain_move_out_loc = all_product_ids._get_domain_locations_new(all_replenish_location_ids.ids)
domain_state = [('state', 'in', ('waiting', 'confirmed', 'assigned', 'partially_available'))]
domain_product = [['product_id', 'in', all_product_ids.ids]]

domain_quant = expression.AND([domain_product, domain_quant])
domain_move_in = expression.AND([domain_product, domain_state, domain_move_in_loc])
domain_move_out = expression.AND([domain_product, domain_state, domain_move_out_loc])

moves_in = defaultdict(list)
for item in Move._read_group(domain_move_in, ['product_qty'], ['product_id', 'location_dest_id'], lazy=False):
moves_in[item['product_id'][0]].append((item['location_dest_id'][0], item['product_qty']))

moves_out = defaultdict(list)
for item in Move._read_group(domain_move_out, ['product_qty'], ['product_id', 'location_id'], lazy=False):
moves_out[item['product_id'][0]].append((item['location_id'][0], item['product_qty']))

quants = defaultdict(list)
for item in Quant._read_group(domain_quant, ['quantity'], ['product_id', 'location_id'], lazy=False):
quants[item['product_id'][0]].append((item['location_id'][0], item['quantity']))

rounding = {product.id: product.uom_id.rounding for product in all_product_ids}
path = {loc.id: loc.parent_path for loc in self.env['stock.location'].search([('id', 'child_of', all_replenish_location_ids.ids)])}
for loc in all_replenish_location_ids:
for product in all_product_ids.with_context(location=loc.id):
if float_compare(product.virtual_available, 0, precision_rounding=product.uom_id.rounding) >= 0:
continue
# group product by lead_days and location in order to read virtual_available
# in batch
rules = product._get_rules_from_location(loc)
lead_days = rules.with_context(bypass_delay_description=True)._get_lead_days(product)[0]
ploc_per_day[(lead_days, loc)].add(product.id)
for product in all_product_ids:
qty_available = sum(q[1] for q in quants.get(product.id, [(0, 0)]) if q[0] and path[q[0]] in loc.parent_path)
incoming_qty = sum(m[1] for m in moves_in.get(product.id, [(0, 0)]) if m[0] and path[m[0]] in loc.parent_path)
outgoing_qty = sum(m[1] for m in moves_out.get(product.id, [(0, 0)]) if m[0] and path[m[0]] in loc.parent_path)
if float_compare(qty_available + incoming_qty - outgoing_qty, 0, precision_rounding=rounding[product.id]) < 0:
# group product by lead_days and location in order to read virtual_available
# in batch
rules = product._get_rules_from_location(loc)
lead_days = rules.with_context(bypass_delay_description=True)._get_lead_days(product)[0]
ploc_per_day[(lead_days, loc)].add(product.id)

# recompute virtual_available with lead days
today = fields.datetime.now().replace(hour=23, minute=59, second=59)
Expand Down

0 comments on commit 13ea202

Please sign in to comment.