[IMP] stock: small improve performance of forecasted availability

Avoid some useless read_group on stock move (fetch too much qty fields
in product.product) and use a query object to avoid fetching data.

To compute 11K of forecasted information of stock move (multi-warehouse
):
- Before: 1.704 ± 0.046 sec and 174 SQL request
- After:  1.554 ± 0.012 sec and 134 SQL request

X-original-commit: 338edd616c2afe1d7a08a06a0b0278c3d7083c05
Part-of: odoo/odoo#77402
This commit is contained in:
Rémy Voet (ryv)
2021-09-29 13:39:56 +00:00
parent 22117b2311
commit 5ea9dfee32
3 changed files with 17 additions and 4 deletions
+12
View File
@@ -602,6 +602,18 @@ class Product(models.Model):
else:
return self._get_rules_from_location(rule.location_src_id, seen_rules=seen_rules | rule)
def _get_only_qty_available(self):
""" Get only quantities available, it is equivalent to read qty_available
but avoid fetching other qty fields (avoid costly read group on moves)
:rtype: defaultdict(float)
"""
domain_quant = expression.AND([self._get_domain_locations()[0], [('product_id', 'in', self.ids)]])
quants_groupby = self.env['stock.quant'].read_group(domain_quant, ['product_id', 'quantity'], ['product_id'], orderby='id')
currents = defaultdict(float)
for c in quants_groupby:
currents[c['product_id'][0]] = c['quantity']
return currents
def _filter_to_unlink(self):
domain = [('product_id', 'in', self.ids)]
+4 -3
View File
@@ -1931,10 +1931,10 @@ class StockMove(models.Model):
ids_in_self = set(self.ids)
product_ids = self.product_id
wh_location_ids = self.env['stock.location'].search([('id', 'child_of', warehouse.view_location_id.id)]).ids
wh_location_query = self.env['stock.location']._search([('id', 'child_of', warehouse.view_location_id.id)])
in_domain, out_domain = self.env['report.stock.report_product_product_replenishment']._move_confirmed_domain(
None, product_ids.ids, wh_location_ids
None, product_ids.ids, wh_location_query
)
outs = self.env['stock.move'].search(out_domain, order='reservation_date, priority desc, date, id')
reserved_outs = self.env['stock.move'].search(
@@ -1944,7 +1944,8 @@ class StockMove(models.Model):
# Prefetch data to avoid future request
(outs - self).read(['product_id', 'product_uom', 'product_qty', 'state'], load=False) # remove self because data is already fetch
ins.read(['product_id', 'product_qty', 'date', 'move_dest_ids'], load=False)
currents = {c['id']: c['qty_available'] for c in product_ids.with_context(warehouse=warehouse.id).read(['qty_available'])}
currents = product_ids.with_context(warehouse=warehouse.id)._get_only_qty_available()
outs_per_product = defaultdict(list)
reserved_outs_per_product = defaultdict(list)
@@ -176,7 +176,7 @@ class ReplenishmentReport(models.AbstractModel):
'move': in_,
'move_dests': in_._rollup_move_dests(set())
})
currents = {c['id']: c['qty_available'] for c in outs.product_id.read(['qty_available'])}
currents = outs.product_id._get_only_qty_available()
lines = []
for product in (ins | outs).product_id: