From 6de0051315daaeb6e49a9caa151bce338738187b Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Fri, 6 Sep 2013 17:50:47 +0200 Subject: [PATCH] [FIX] product: support string values for context `pricelist` key when computing prices As of v7 search views will replace the value of any `self` literal in a @context attribute by the name of the record, whereas it used to be its ID. This means that the `Pricelist` filter used to display the product list with a specific pricelist would not work anymore. The fix requires a rather hackish name_search() override for product.pricelist because the display name of pricelists includes their currency, while that could be a valid name for a pricelist too. To avoid side-effects the name_search() override only picks up the special case used by the product.product._product_price() method when it tries to apply the context pricelist, that is with operator explicitly set to `=` and no extra domain `args`. lp bug: https://launchpad.net/bugs/1178835 fixed bzr revid: odo@openerp.com-20130906155047-7dmozy2jpe1ca1p2 --- addons/product/pricelist.py | 22 ++++++++++++++++++++++ addons/product/product.py | 5 +++++ 2 files changed, 27 insertions(+) diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index 4b59856b6d8..331fb957e8e 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -95,6 +95,7 @@ class product_pricelist(osv.osv): _name = "product.pricelist" _description = "Pricelist" + _order = 'name' _columns = { 'name': fields.char('Pricelist Name',size=64, required=True, translate=True), 'active': fields.boolean('Active', help="If unchecked, it will allow you to hide the pricelist without removing it."), @@ -113,6 +114,27 @@ class product_pricelist(osv.osv): result.append((pl.id,name)) return result + def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): + if name and operator == '=' and not args: + # search on the name of the pricelist and its currency, opposite of name_get(), + # Used by the magic context filter in the product search view. + query_args = {'name': name, 'limit': limit} + query = """SELECT p.id + FROM product_pricelist p JOIN + res_currency c ON (p.currency_id = c.id) + WHERE p.name || ' (' || c.name || ')' = %(name)s + ORDER BY p.name""" + if limit: + query += " LIMIT %(limit)s" + cr.execute(query, query_args) + ids = [r[0] for r in cr.fetchall()] + # regular search() to apply ACLs - may limit results below limit in some cases + ids = self.search(cr, uid, [('id', 'in', ids)], limit=limit, context=context) + if ids: + return self.name_get(cr, uid, ids, context) + return super(product_pricelist, self).name_search( + cr, uid, name, args, operator=operator, context=context, limit=limit) + def _get_currency(self, cr, uid, ctx): comp = self.pool.get('res.users').browse(cr, uid, uid).company_id diff --git a/addons/product/product.py b/addons/product/product.py index 82b37f7b9e8..cc60dddd6e4 100644 --- a/addons/product/product.py +++ b/addons/product/product.py @@ -420,6 +420,11 @@ class product_product(osv.osv): pricelist = context.get('pricelist', False) partner = context.get('partner', False) if pricelist: + # Support context pricelists specified as display_name or ID for compatibility + if isinstance(pricelist, basestring): + pricelist_ids = self.pool.get('product.pricelist').name_search( + cr, uid, pricelist, operator='=', context=context, limit=1) + pricelist = pricelist_ids[0][0] if pricelist_ids else pricelist for id in ids: try: price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], id, quantity, partner=partner, context=context)[pricelist]