[MERGE] 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`.

      Also avoid useless warning in log by disabling the actual
      filtering for the dummy pricelist_id field, whose
      only purpose is to alter the context.

      Finally, add a default _order for pricelists that is
      a bit more intuitive than the default sort by `id`.
      An explicit _order was required for the application of
      the `limit` in pure SQL, and using `name` seems slightly
      better than `id`.

lp bug: https://launchpad.net/bugs/1178835 fixed

bzr revid: odo@openerp.com-20130906161422-0huf2uwjg42shdqp
This commit is contained in:
Olivier Dony 2013-09-06 18:14:22 +02:00
commit 54a8cbb7cd
3 changed files with 28 additions and 1 deletions

View File

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

View File

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

View File

@ -15,7 +15,7 @@
<filter string="Can be Sold" name="filter_to_sell" icon="terp-accessories-archiver-minus" domain="[('sale_ok','=',1)]"/>
<field name="categ_id"/>
<group expand="0" string="Context...">
<field name="pricelist_id" context="{'pricelist': self}" groups="product.group_sale_pricelist"/>
<field name="pricelist_id" context="{'pricelist': self}" filter_domain="[]" groups="product.group_sale_pricelist"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group expand='0' string='Group by...'>