[FIX] stock: improve perf of replenishement report

Avoid to filter in a loop and use a read_group instead to group by
product-warehouse outside.
Also remove costly useless code.

Performance gain
----------------
On a large database (120K stock move, 5k product) where
+- 700 manual orderpoints will be create during the open of the
replenishement report:
Before:
16.14 +- 0.16 sec of python. (SQL time is +- 14 sec)
After:
1.33 +- 0.91 sec of python. (SQL time ==)

task-2390516

X-original-commit: 569b45d5cb139825690a90189b7a360f3fa89815
This commit is contained in:
Rémy Voet (ryv)
2021-01-22 15:49:11 +00:00
parent 805502c3a9
commit 60fafa9fd2
+11 -11
View File
@@ -313,16 +313,22 @@ class StockWarehouseOrderpoint(models.Model):
if not to_refill:
return action
# Remove incoming quantity from other otigin than moves (e.g RFQ)
# Remove incoming quantity from other origin than moves (e.g RFQ)
product_ids, warehouse_ids = zip(*to_refill)
# lot_stock_ids = [lot_stock_id_by_warehouse[w] for w in warehouse_ids]
dummy, qty_by_product_wh = self.env['product.product'].browse(product_ids)._get_quantity_in_progress(warehouse_ids=warehouse_ids)
rounding = self.env['decimal.precision'].precision_get('Product Unit of Measure')
# Group orderpoint by product-warehouse
grouped_orderpoint_data = self.env['stock.warehouse.orderpoint'].read_group(
[('id', 'in', orderpoints.ids)],
['product_id', 'warehouse_id', 'qty_to_order:sum'],
['product_id', 'warehouse_id'], lazy=False)
orderpoint_by_product_warehouse = {
(record.get('product_id')[0], record.get('warehouse_id')[0]): record.get('qty_to_order')
for record in grouped_orderpoint_data
}
for (product, warehouse), product_qty in to_refill.items():
qty_in_progress = qty_by_product_wh.get((product, warehouse)) or 0.0
qty_in_progress += sum(orderpoints.filtered(
lambda o: o.product_id.id == product and o.warehouse_id.id == warehouse
).mapped('qty_to_order'))
qty_in_progress += orderpoint_by_product_warehouse.get((product, warehouse), 0.0)
# Add qty to order for other orderpoint under this warehouse.
if not qty_in_progress:
continue
@@ -335,12 +341,6 @@ class StockWarehouseOrderpoint(models.Model):
], ['lot_stock_id'])
lot_stock_id_by_warehouse = {w['id']: w['lot_stock_id'][0] for w in lot_stock_id_by_warehouse}
product_qty_available = {}
for warehouse, group in groupby(sorted(to_refill, key=lambda p_w: p_w[1]), key=lambda p_w: p_w[1]):
products = self.env['product.product'].browse([p for p, w in group])
products_qty_available_list = products.with_context(location=lot_stock_id_by_warehouse[warehouse]).mapped('qty_available')
product_qty_available.update({(p.id, warehouse): q for p, q in zip(products, products_qty_available_list)})
orderpoint_values_list = []
for (product, warehouse), product_qty in to_refill.items():
lot_stock_id = lot_stock_id_by_warehouse[warehouse]