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()