[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
This commit is contained in:
Denis Ledoux 2015-02-25 16:02:45 +01:00
parent eb0a309522
commit 23ffff7a6f
1 changed files with 19 additions and 2 deletions

View File

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