From 60fafa9fd2c0803c3b6343303209c9278acd6a82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Voet=20=28ryv=29?= Date: Thu, 31 Dec 2020 08:33:31 +0000 Subject: [PATCH] [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 --- addons/stock/models/stock_orderpoint.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/addons/stock/models/stock_orderpoint.py b/addons/stock/models/stock_orderpoint.py index 3a322c8aef2..df28cb0d0a8 100644 --- a/addons/stock/models/stock_orderpoint.py +++ b/addons/stock/models/stock_orderpoint.py @@ -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]