diff --git a/modules/stock/move.py b/modules/stock/move.py index 4e33df0141..3780071931 100644 --- a/modules/stock/move.py +++ b/modules/stock/move.py @@ -151,6 +151,12 @@ class StockMixin(object): pbl = Product.products_by_location( location_ids, with_childs=with_childs, grouping=grouping) + quantities = defaultdict(float) + for key, quantity in pbl.items(): + # pbl could return None in some keys + if key[position] is not None: + quantities[key[position]] += quantity + operator_ = { '=': operator.eq, '>=': operator.ge, @@ -161,15 +167,8 @@ class StockMixin(object): 'in': lambda v, l: v in l, 'not in': lambda v, l: v not in l, }.get(operator_, lambda v, l: False) - record_ids = [] - for key, quantity in pbl.items(): - if (quantity is not None and operand is not None - and operator_(quantity, operand)): - # pbl could return None in some keys - if key[position] is not None: - record_ids.append(key[position]) - - return [('id', 'in', record_ids)] + return [('id', 'in', + [k for k, v in quantities.items() if operator_(v, operand)])] class Move(Workflow, ModelSQL, ModelView): diff --git a/modules/stock/tests/test_module.py b/modules/stock/tests/test_module.py index 42fe6ab160..c7cd620f46 100644 --- a/modules/stock/tests/test_module.py +++ b/modules/stock/tests/test_module.py @@ -335,6 +335,25 @@ class StockTestCase( test_products_by_location() + with transaction.set_context( + locations=[supplier.id, customer.id, storage.id]): + for domain, found in [ + ([('quantity', '=', 0)], True), + ([('quantity', '>=', 0)], True), + ([('quantity', '>', 0)], False), + ([('quantity', '<=', 0)], True), + ([('quantity', '<', 0)], False), + ([('quantity', '!=', 0)], False), + ([('quantity', 'in', [0])], True), + ([('quantity', 'in', [1])], False), + ([('quantity', 'not in', [0])], False), + ([('quantity', 'not in', [1])], True), + ]: + with self.subTest(domain=domain): + self.assertEqual( + Product.search(domain), + [product] if found else []) + periods = [ today + relativedelta(days=-6), today + relativedelta(days=-5),