From 23ffff7a6f7ce066034cf78c228febf7f2e4fd38 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Wed, 25 Feb 2015 16:02:45 +0100 Subject: [PATCH] [FIX] product: recursive category name search Before this rev., if you had two child categories with the same name, e.g.: - Chocolates / Orange - Fruits / Orange In the product list, searching for category "Fruits / Orange" also returned the products from category "Chocolates / Orange", because it fetched all products which had "Orange" in the category. This rev. corrects this (in the above example, it returns only products from category "Fruits / Orange". The code is particularly complex. A proper solution would be to store the complete name field (but this cannot be done in stable releases, such as 8.0). Besides, it handles the fact a product category child can have ' / ' directly in its name (it's not only the category tree separator). e.g., you could have a category name called 'Fruits / Orange' directly not only in the complete name. opw-628793 --- addons/product/product.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/addons/product/product.py b/addons/product/product.py index e7f9903f79b..c599ce77b7d 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -256,8 +256,25 @@ class product_category(osv.osv): context = {} if name: # Be sure name_search is symetric to name_get - name = name.split(' / ')[-1] - ids = self.search(cr, uid, [('name', operator, name)] + args, limit=limit, context=context) + categories = name.split(' / ') + parents = list(categories) + child = parents.pop() + domain = [('name', operator, child)] + if parents: + names_ids = self.name_search(cr, uid, ' / '.join(parents), args=args, operator='ilike', context=context, limit=limit) + category_ids = [name_id[0] for name_id in names_ids] + if operator in expression.NEGATIVE_TERM_OPERATORS: + category_ids = self.search(cr, uid, [('id', 'not in', category_ids)]) + domain = expression.OR([[('parent_id', 'in', category_ids)], domain]) + else: + domain = expression.AND([[('parent_id', 'in', category_ids)], domain]) + for i in range(1, len(categories)): + domain = [[('name', operator, ' / '.join(categories[-1 - i:]))], domain] + if operator in expression.NEGATIVE_TERM_OPERATORS: + domain = expression.AND(domain) + else: + domain = expression.OR(domain) + ids = self.search(cr, uid, expression.AND([domain, args]), limit=limit, context=context) else: ids = self.search(cr, uid, args, limit=limit, context=context) return self.name_get(cr, uid, ids, context)