changeset 7e581e7b9674 in modules/stock:default
details: https://hg.tryton.org/modules/stock?cmd=changeset;node=7e581e7b9674
description:
        Use query clause when searching quantity for 1 location

        We can use the compute quantities query if the request is for a single 
location
        because all the locations are children and so we can do a SUM.

        issue9594
        review323991002
diffstat:

 move.py             |   19 ++++++-
 tests/test_stock.py |  151 +++++++++++++++++++++++++++------------------------
 2 files changed, 97 insertions(+), 73 deletions(-)

diffs (223 lines):

diff -r 823f65854065 -r 7e581e7b9674 move.py
--- a/move.py   Thu Sep 24 18:28:45 2020 +0200
+++ b/move.py   Sun Sep 27 18:20:34 2020 +0200
@@ -118,17 +118,34 @@
         """
         pool = Pool()
         Product = pool.get('product.product')
+        Move = pool.get('stock.move')
 
         if not location_ids or not domain:
             return []
         with_childs = Transaction().context.get(
             'with_childs', len(location_ids) == 1)
+        _, operator_, operand = domain
 
         with Transaction().set_context(cls._quantity_context(name)):
+            if (len(location_ids) == 1
+                    and not Transaction().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
+                # so we can do a SUM.
+                Operator = fields.SQL_OPERATORS[operator_]
+                query = Move.compute_quantities_query(
+                    location_ids, with_childs, grouping=grouping)
+                col_id = Column(query, grouping[position])
+                quantity = Sum(query.quantity)
+                group_by = [Column(query, key).as_(key) for key in grouping]
+                return [('id', 'in', query.select(
+                            col_id,
+                            group_by=group_by,
+                            having=Operator(quantity, operand)))]
+
             pbl = Product.products_by_location(
                 location_ids, with_childs=with_childs, grouping=grouping)
 
-        _, operator_, operand = domain
         operator_ = {
             '=': operator.eq,
             '>=': operator.ge,
diff -r 823f65854065 -r 7e581e7b9674 tests/test_stock.py
--- a/tests/test_stock.py       Thu Sep 24 18:28:45 2020 +0200
+++ b/tests/test_stock.py       Sun Sep 27 18:20:34 2020 +0200
@@ -104,6 +104,7 @@
         supplier, = Location.search([('code', '=', 'SUP')])
         customer, = Location.search([('code', '=', 'CUS')])
         storage, = Location.search([('code', '=', 'STO')])
+        storage_empty, = Location.copy([storage])
         company = create_company()
         currency = company.currency
         with set_company(company):
@@ -234,85 +235,83 @@
             today_quantity = 4
 
             def tests_product_quantity(context, quantity):
-                with transaction.set_context(locations=[storage.id]):
-                    product_reloaded = Product(product.id)
-                    if (not context.get('stock_date_end')
-                            or context['stock_date_end'] > today):
-                        self.assertEqual(
-                            product_reloaded.forecast_quantity, quantity,
-                            msg='context %r' % context)
-                        self.assertEqual(
-                            product_reloaded.quantity, today_quantity,
-                            msg='context %r' % context)
-                    elif context.get('forecast'):
-                        self.assertEqual(
-                            product_reloaded.forecast_quantity, quantity,
-                            msg='context %r' % context)
-                    elif context.get('stock_date_end') == today:
-                        self.assertEqual(product_reloaded.quantity, quantity,
-                            msg='context %r' % context)
-                    else:
-                        self.assertEqual(
-                            product_reloaded.forecast_quantity, quantity,
-                            msg='context %r' % context)
-                        self.assertEqual(product_reloaded.quantity, quantity,
-                            msg='context %r' % context)
+                product_reloaded = Product(product.id)
+                if (not context.get('stock_date_end')
+                        or context['stock_date_end'] > today):
+                    self.assertEqual(
+                        product_reloaded.forecast_quantity, quantity,
+                        msg='context %r' % context)
+                    self.assertEqual(
+                        product_reloaded.quantity, today_quantity,
+                        msg='context %r' % context)
+                elif context.get('forecast'):
+                    self.assertEqual(
+                        product_reloaded.forecast_quantity, quantity,
+                        msg='context %r' % context)
+                elif context.get('stock_date_end') == today:
+                    self.assertEqual(product_reloaded.quantity, quantity,
+                        msg='context %r' % context)
+                else:
+                    self.assertEqual(
+                        product_reloaded.forecast_quantity, quantity,
+                        msg='context %r' % context)
+                    self.assertEqual(product_reloaded.quantity, quantity,
+                        msg='context %r' % context)
 
             def tests_product_search_quantity(context, quantity):
-                with transaction.set_context(locations=[storage.id]):
-                    if (not context.get('stock_date_end')
-                            or context['stock_date_end'] > today
-                            or context.get('forecast')):
-                        fname = 'forecast_quantity'
-                    else:
-                        fname = 'quantity'
-                    found_products = Product.search([
-                            (fname, '=', quantity),
-                            ])
-                    self.assertIn(product, found_products)
+                if (not context.get('stock_date_end')
+                        or context['stock_date_end'] > today
+                        or context.get('forecast')):
+                    fname = 'forecast_quantity'
+                else:
+                    fname = 'quantity'
+                found_products = Product.search([
+                        (fname, '=', quantity),
+                        ])
+                self.assertIn(product, found_products)
 
-                    found_products = Product.search([
-                            (fname, '!=', quantity),
-                            ])
-                    self.assertNotIn(product, found_products)
+                found_products = Product.search([
+                        (fname, '!=', quantity),
+                        ])
+                self.assertNotIn(product, found_products)
 
-                    found_products = Product.search([
-                            (fname, 'in', (quantity, quantity + 1)),
-                            ])
-                    self.assertIn(product, found_products)
+                found_products = Product.search([
+                        (fname, 'in', (quantity, quantity + 1)),
+                        ])
+                self.assertIn(product, found_products)
 
-                    found_products = Product.search([
-                            (fname, 'not in', (quantity, quantity + 1)),
-                            ])
-                    self.assertNotIn(product, found_products)
+                found_products = Product.search([
+                        (fname, 'not in', (quantity, quantity + 1)),
+                        ])
+                self.assertNotIn(product, found_products)
 
-                    found_products = Product.search([
-                            (fname, '<', quantity),
-                            ])
-                    self.assertNotIn(product, found_products)
-                    found_products = Product.search([
-                            (fname, '<', quantity + 1),
-                            ])
-                    self.assertIn(product, found_products)
+                found_products = Product.search([
+                        (fname, '<', quantity),
+                        ])
+                self.assertNotIn(product, found_products)
+                found_products = Product.search([
+                        (fname, '<', quantity + 1),
+                        ])
+                self.assertIn(product, found_products)
 
-                    found_products = Product.search([
-                            (fname, '>', quantity),
-                            ])
-                    self.assertNotIn(product, found_products)
-                    found_products = Product.search([
-                            (fname, '>', quantity - 1),
-                            ])
-                    self.assertIn(product, found_products)
+                found_products = Product.search([
+                        (fname, '>', quantity),
+                        ])
+                self.assertNotIn(product, found_products)
+                found_products = Product.search([
+                        (fname, '>', quantity - 1),
+                        ])
+                self.assertIn(product, found_products)
 
-                    found_products = Product.search([
-                            (fname, '>=', quantity),
-                            ])
-                    self.assertIn(product, found_products)
+                found_products = Product.search([
+                        (fname, '>=', quantity),
+                        ])
+                self.assertIn(product, found_products)
 
-                    found_products = Product.search([
-                            (fname, '<=', quantity),
-                            ])
-                    self.assertIn(product, found_products)
+                found_products = Product.search([
+                        (fname, '<=', quantity),
+                        ])
+                self.assertIn(product, found_products)
 
             def test_products_by_location():
                 for context, quantity in tests:
@@ -322,8 +321,16 @@
                         else:
                             self.assertEqual(products_by_location(),
                                     {(storage.id, product.id): quantity})
-                            tests_product_quantity(context, quantity)
-                            tests_product_search_quantity(context, quantity)
+                            with transaction.set_context(
+                                    locations=[storage.id]):
+                                tests_product_quantity(context, quantity)
+                                tests_product_search_quantity(
+                                    context, quantity)
+                            with transaction.set_context(
+                                    locations=[storage.id, storage_empty.id]):
+                                tests_product_quantity(context, quantity)
+                                tests_product_search_quantity(
+                                    context, quantity)
 
             test_products_by_location()
 

Reply via email to