details:   https://code.tryton.org/tryton/commit/c62abebb2795
branch:    default
user:      Cédric Krier <[email protected]>
date:      Tue Jul 14 19:06:52 2026 +0200
description:
        Optimise stock quantity computations for warehouses only

        When the 'location_ids' are only comprise warehouses, we know that the 
children
        locations of each one cannot be shared.
        Therefore, we can use the 72fff0ca9da7 optimisation by calculating the
        quantities for each warehouse individually and then adding them 
together.

        Closes #14956
diffstat:

 modules/stock/move.py |  53 +++++++++++++++++++++++++++++++++-----------------
 1 files changed, 35 insertions(+), 18 deletions(-)

diffs (84 lines):

diff -r 91152da49e71 -r c62abebb2795 modules/stock/move.py
--- a/modules/stock/move.py     Mon Aug 17 23:31:29 2026 +0200
+++ b/modules/stock/move.py     Tue Jul 14 19:06:52 2026 +0200
@@ -80,25 +80,34 @@
         """
         pool = Pool()
         Product = pool.get('product.product')
+        Location = pool.get('stock.location')
 
         quantities = defaultdict(float)
         if not location_ids:
             return quantities
 
-        with_childs = Transaction().context.get(
-            'with_childs', len(location_ids) == 1)
+        warehouse_only = all(
+            l.type == 'warehouse' for l in Location.browse(location_ids))
+        if warehouse_only:
+            grouped_location_ids = ([l] for l in location_ids)
+        else:
+            grouped_location_ids = [location_ids]
+
+        for sub_location_ids in grouped_location_ids:
+            with_childs = Transaction().context.get(
+                'with_childs', len(sub_location_ids) == 1)
 
-        with Transaction().set_context(cls._quantity_context(name)):
-            pbl = Product.products_by_location(
-                location_ids,
-                with_childs=with_childs,
-                grouping=grouping,
-                grouping_filter=grouping_filter)
+            with Transaction().set_context(cls._quantity_context(name)):
+                pbl = Product.products_by_location(
+                    sub_location_ids,
+                    with_childs=with_childs,
+                    grouping=grouping,
+                    grouping_filter=grouping_filter)
 
-        for key, quantity in pbl.items():
-            # pbl could return None in some keys
-            if key[position] is not None:
-                quantities[key[position]] += quantity
+            for key, quantity in pbl.items():
+                # pbl could return None in some keys
+                if key[position] is not None:
+                    quantities[key[position]] += quantity
         return quantities
 
     @classmethod
@@ -118,19 +127,27 @@
         Product = pool.get('product.product')
         Move = pool.get('stock.move')
         Uom = pool.get('product.uom')
+        Location = pool.get('stock.location')
+        transaction = Transaction()
+        context = transaction.context
         uom = Uom.__table__()
 
         if not location_ids or not domain:
             return []
-        with_childs = Transaction().context.get(
-            'with_childs', len(location_ids) == 1)
+
+        warehouse_only = all(
+            l.type == 'warehouse' for l in Location.browse(location_ids))
+        with_childs = context.get(
+            'with_childs', len(location_ids) == 1 or warehouse_only)
         _, operator_, operand = domain
 
-        with Transaction().set_context(cls._quantity_context(name)):
-            if (len(location_ids) == 1
-                    and not Transaction().context.get('stock_skip_warehouse')):
+        with transaction.set_context(cls._quantity_context(name)):
+            if ((len(location_ids) == 1 or warehouse_only)
+                    and not context.get('stock_skip_warehouse')):
                 # We can use the compute quantities query if the request is for
-                # a single location because all the locations are children and
+                # a single location because all the locations are children or
+                # if the request is for only warehouses because all the
+                # children locations are under a single warehouse
                 # so we can do a SUM.
                 Operator = fields.SQL_OPERATORS[operator_]
                 query = Move.compute_quantities_query(

Reply via email to