revert changes 2324
[odoo/odoo.git] / addons / product / pricelist.py
index 837ea3e..a1bec9c 100644 (file)
@@ -1,28 +1,22 @@
 # -*- encoding: utf-8 -*-
 ##############################################################################
 #
-# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
+#    OpenERP, Open Source Management Solution  
+#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
+#    $Id$
 #
-# WARNING: This program as such is intended to be used by professional
-# programmers who take the whole responsability of assessing all potential
-# consequences resulting from its eventual inadequacies and bugs
-# End users who are looking for a ready-to-use solution with commercial
-# garantees and support are strongly adviced to contract a Free Software
-# Service Company
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
 #
-# This program is Free Software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
 #
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 #
 ##############################################################################
 
@@ -32,36 +26,43 @@ from osv import fields, osv
 from _common import rounding
 import time
 from tools import config
+from tools.misc import ustr
+from tools.translate import _
 
 class price_type(osv.osv):
-       """
-               The price type is used to points which field in the product form
-               is a price and in which currency is this price expressed.
-               When a field is a price, you can use it in pricelists to base
-               sale and purchase prices based on some fields of the product.
-       """
-       def _price_field_get(self, cr, uid, context={}):
-               cr.execute('select name, field_description from ir_model_fields where model in (%s,%s) and ttype=%s order by name', ('product.product', 'product.template', 'float'))
-               return cr.fetchall()
-       def _get_currency(self, cr, uid, ctx):
-               comp = self.pool.get('res.users').browse(cr,uid,uid).company_id
-               if not comp:
-                       comp_id = self.pool.get('res.company').search(cr, uid, [])[0]
-                       comp = self.pool.get('res.company').browse(cr, uid, comp_id)
-               return comp.currency_id.id
-
-       _name = "product.price.type"
-       _description = "Price type"
-       _columns = {
-               "name" : fields.char("Price Name", size=32, required=True, translate=True) ,
-               "active" : fields.boolean("Active"),
-               "field" : fields.selection(_price_field_get, "Product Field", required=True),
-               "currency_id" : fields.many2one('res.currency', "Currency", required=True),
-       }
-       _defaults = {
-               "active": lambda *args: True,
-               "currency_id": _get_currency
-       }
+    """
+        The price type is used to points which field in the product form
+        is a price and in which currency is this price expressed.
+        When a field is a price, you can use it in pricelists to base
+        sale and purchase prices based on some fields of the product.
+    """
+    def _price_field_get(self, cr, uid, context={}):
+        mf = self.pool.get('ir.model.fields')
+        ids = mf.search(cr, uid, [('model','in', (('product.product'),('product.template'))), ('ttype','=','float')], context=context)
+        res = []
+        for field in mf.browse(cr, uid, ids, context=context):
+            res.append((field.name, field.field_description))
+        return res
+
+    def _get_currency(self, cr, uid, ctx):
+        comp = self.pool.get('res.users').browse(cr,uid,uid).company_id
+        if not comp:
+            comp_id = self.pool.get('res.company').search(cr, uid, [])[0]
+            comp = self.pool.get('res.company').browse(cr, uid, comp_id)
+        return comp.currency_id.id
+
+    _name = "product.price.type"
+    _description = "Price type"
+    _columns = {
+        "name" : fields.char("Price Name", size=32, required=True, translate=True, help="Name of this kind of price."),
+        "active" : fields.boolean("Active"),
+        "field" : fields.selection(_price_field_get, "Product Field", size=32, required=True, help="Associated field in the product form."),
+        "currency_id" : fields.many2one('res.currency', "Currency", required=True, help="The currency the field is expressed in."),
+    }
+    _defaults = {
+        "active": lambda *args: True,
+        "currency_id": _get_currency
+    }
 price_type()
 
 #----------------------------------------------------------
@@ -69,277 +70,294 @@ price_type()
 #----------------------------------------------------------
 
 class product_pricelist_type(osv.osv):
-       _name = "product.pricelist.type"
-       _description = "Pricelist Type"
-       _columns = {
-               'name': fields.char('Name',size=64, required=True),
-               'key': fields.char('Key', size=64, required=True),
-       }
+    _name = "product.pricelist.type"
+    _description = "Pricelist Type"
+    _columns = {
+        'name': fields.char('Name',size=64, required=True, translate=True),
+        'key': fields.char('Key', size=64, required=True, help="Used in the code to select specific prices based on the context. Keep unchanged."),
+    }
 product_pricelist_type()
 
 
 class product_pricelist(osv.osv):
-       def _pricelist_type_get(self, cr, uid, context={}):
-               cr.execute('select key,name from product_pricelist_type order by name')
-               return cr.fetchall()
-       _name = "product.pricelist"
-       _description = "Pricelist"
-       _columns = {
-               'name': fields.char('Name',size=64, required=True),
-               'active': fields.boolean('Active'),
-               'type': fields.selection(_pricelist_type_get, 'Pricelist Type', required=True),
-               'version_id': fields.one2many('product.pricelist.version', 'pricelist_id', 'Pricelist Versions'),
-               'currency_id': fields.many2one('res.currency', 'Currency', required=True),
-       }
-       def _get_currency(self, cr, uid, ctx):
-               comp = self.pool.get('res.users').browse(cr,uid,uid).company_id
-               if not comp:
-                       comp_id = self.pool.get('res.company').search(cr, uid, [])[0]
-                       comp = self.pool.get('res.company').browse(cr, uid, comp_id)
-               return comp.currency_id.id
-
-       _defaults = {
-               'active': lambda *a: 1,
-               "currency_id": _get_currency
-       }
-
-       def price_get(self, cr, uid, ids, prod_id, qty, partner=None, context=None):
-               '''
-               context = {
-                       'uom': Unit of Measure (int),
-                       'partner': Partner ID (int),
-                       'date': Date of the pricelist (%Y-%m-%d),
-               }
-               '''
-               currency_obj = self.pool.get('res.currency')
-               product_obj = self.pool.get('product.product')
-               supplierinfo_obj = self.pool.get('product.supplierinfo')
-               price_type_obj = self.pool.get('product.price.type')
-
-               if context and ('partner_id' in context):
-                       partner = context['partner_id']
-               date = time.strftime('%Y-%m-%d')
-               if context and ('date' in context):
-                       date = context['date']
-               result = {}
-               for id in ids:
-                       cr.execute('SELECT * ' \
-                                       'FROM product_pricelist_version ' \
-                                       'WHERE pricelist_id = %d AND active=True ' \
-                                               'AND (date_start IS NULL OR date_start <= %s) ' \
-                                               'AND (date_end IS NULL OR date_end >= %s) ' \
-                                       'ORDER BY id LIMIT 1', (id, date, date))
-                       plversion = cr.dictfetchone()
-
-                       if not plversion:
-                               raise osv.except_osv('Warning !',
-                                               'No active version for the selected pricelist !\n' \
-                                                               'Please create or activate one.')
-
-                       cr.execute('SELECT id, categ_id ' \
-                                       'FROM product_template ' \
-                                       'WHERE id = (SELECT product_tmpl_id ' \
-                                               'FROM product_product ' \
-                                               'WHERE id = %d)', (prod_id,))
-                       tmpl_id, categ = cr.fetchone()
-                       categ_ids = []
-                       while categ:
-                               categ_ids.append(str(categ))
-                               cr.execute('SELECT parent_id ' \
-                                               'FROM product_category ' \
-                                               'WHERE id = %d', (categ,))
-                               categ = cr.fetchone()[0]
-                               if str(categ) in categ_ids:
-                                       raise osv.except_osv('Warning !',
-                                                       'Could not resolve product category, ' \
-                                                                       'you have defined cyclic categories ' \
-                                                                       'of products!')
-                       if categ_ids:
-                               categ_where = '(categ_id IN (' + ','.join(categ_ids) + '))'
-                       else:
-                               categ_where = '(categ_id IS NULL)'
-
-                       cr.execute(
-                               'SELECT i.*, pl.currency_id '
-                               'FROM product_pricelist_item AS i, '
-                                       'product_pricelist_version AS v, product_pricelist AS pl '
-                               'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %d) '
-                                       'AND (product_id IS NULL OR product_id = %d) '
-                                       'AND (' + categ_where + ' OR (categ_id IS NULL)) '
-                                       'AND price_version_id = %d '
-                                       'AND (min_quantity IS NULL OR min_quantity <= %f) '
-                                       'AND i.price_version_id = v.id AND v.pricelist_id = pl.id '
-                               'ORDER BY sequence LIMIT 1',
-                               (tmpl_id, prod_id, plversion['id'], qty))
-                       res = cr.dictfetchone()
-                       if res:
-                               if res['base'] == -1:
-                                       if not res['base_pricelist_id']:
-                                               price = 0.0
-                                       else:
-                                               price_tmp = self.price_get(cr, uid,
-                                                               [res['base_pricelist_id']], prod_id,
-                                                               qty)[res['base_pricelist_id']]
-                                               ptype_src = self.browse(cr, uid,
-                                                               res['base_pricelist_id']).currency_id.id
-                                               price = currency_obj.compute(cr, uid, ptype_src,
-                                                               res['currency_id'], price_tmp, round=False)
-                               elif res['base'] == -2:
-                                       where = []
-                                       if partner:
-                                               where = [('name', '=', partner) ] 
-                                       sinfo = supplierinfo_obj.search(cr, uid,
-                                                       [('product_id', '=', tmpl_id)] + where)
-                                       price = 0.0
-                                       if sinfo:
-                                               cr.execute('SELECT * ' \
-                                                               'FROM pricelist_partnerinfo ' \
-                                                               'WHERE suppinfo_id IN (' + \
-                                                                       ','.join(map(str, sinfo)) + ') ' \
-                                                                       'AND min_quantity <= %f ' \
-                                                               'ORDER BY min_quantity DESC LIMIT 1', (qty,))
-                                               res2 = cr.dictfetchone()
-                                               if res2:
-                                                       price = res2['price']
-                               else:
-                                       price_type = price_type_obj.browse(cr, uid, res['base'])
-                                       price = currency_obj.compute(cr, uid,
-                                                       price_type.currency_id.id, res['currency_id'],
-                                                       product_obj.price_get(cr, uid, [prod_id],
-                                                               price_type.field, context)[prod_id], round=False)
-
-                               price_limit = price
-
-                               price = price * (1.0-(res['price_discount'] or 0.0))
-                               price = rounding(price, res['price_round'])
-                               price += (res['price_surcharge'] or 0.0)
-                               if res['price_min_margin']:
-                                       price = max(price, price_limit+res['price_min_margin'])
-                               if res['price_max_margin']:
-                                       price = min(price, price_limit+res['price_max_margin'])
-                       else:
-                               # False means no valid line found ! But we may not raise an
-                               # exception here because it breaks the search
-                               price = False
-                       result[id] = price
-                       if context and ('uom' in context):
-                               product = product_obj.browse(cr, uid, prod_id)
-                               uom = product.uos_id or product.uom_id
-                               result[id] = self.pool.get('product.uom')._compute_price(cr,
-                                               uid, uom.id, result[id], context['uom'])
-               return result
+    def _pricelist_type_get(self, cr, uid, context={}):
+        cr.execute('select key,name from product_pricelist_type order by name')
+        return cr.fetchall()
+    _name = "product.pricelist"
+    _description = "Pricelist"
+    _columns = {
+        'name': fields.char('Pricelist Name',size=64, required=True, translate=True),
+        'active': fields.boolean('Active'),
+        'type': fields.selection(_pricelist_type_get, 'Pricelist Type', required=True),
+        'version_id': fields.one2many('product.pricelist.version', 'pricelist_id', 'Pricelist Versions'),
+        'currency_id': fields.many2one('res.currency', 'Currency', required=True),
+    }
+    
+    def name_get(self, cr, uid, ids, context={}):
+        result= []
+        if not all(ids):
+            return result
+        for pl in self.browse(cr, uid, ids, context):
+            name = pl.name + ' ('+ pl.currency_id.name + ')'
+            result.append((pl.id,name))
+        return result
+    
+
+    def _get_currency(self, cr, uid, ctx):
+        comp = self.pool.get('res.users').browse(cr, uid, uid).company_id
+        if not comp:
+            comp_id = self.pool.get('res.company').search(cr, uid, [])[0]
+            comp = self.pool.get('res.company').browse(cr, uid, comp_id)
+        return comp.currency_id.id
+
+    _defaults = {
+        'active': lambda *a: 1,
+        "currency_id": _get_currency
+    }
+
+    def price_get(self, cr, uid, ids, prod_id, qty, partner=None, context=None):
+        '''
+        context = {
+            'uom': Unit of Measure (int),
+            'partner': Partner ID (int),
+            'date': Date of the pricelist (%Y-%m-%d),
+        }
+        '''
+        context = context or {}
+        currency_obj = self.pool.get('res.currency')
+        product_obj = self.pool.get('product.product')
+        supplierinfo_obj = self.pool.get('product.supplierinfo')
+        price_type_obj = self.pool.get('product.price.type')
+
+        if context and ('partner_id' in context):
+            partner = context['partner_id']
+        context['partner_id'] = partner
+        date = time.strftime('%Y-%m-%d')
+        if context and ('date' in context):
+            date = context['date']
+        result = {}
+        for id in ids:
+            cr.execute('SELECT * ' \
+                    'FROM product_pricelist_version ' \
+                    'WHERE pricelist_id = %s AND active=True ' \
+                        'AND (date_start IS NULL OR date_start <= %s) ' \
+                        'AND (date_end IS NULL OR date_end >= %s) ' \
+                    'ORDER BY id LIMIT 1', (id, date, date))
+            plversion = cr.dictfetchone()
+
+            if not plversion:
+                raise osv.except_osv(_('Warning !'),
+                        _('No active version for the selected pricelist !\n' \
+                                'Please create or activate one.'))
+
+            cr.execute('SELECT id, categ_id ' \
+                    'FROM product_template ' \
+                    'WHERE id = (SELECT product_tmpl_id ' \
+                        'FROM product_product ' \
+                        'WHERE id = %s)', (prod_id,))
+            tmpl_id, categ = cr.fetchone()
+            categ_ids = []
+            while categ:
+                categ_ids.append(str(categ))
+                cr.execute('SELECT parent_id ' \
+                        'FROM product_category ' \
+                        'WHERE id = %s', (categ,))
+                categ = cr.fetchone()[0]
+                if str(categ) in categ_ids:
+                    raise osv.except_osv(_('Warning !'),
+                            _('Could not resolve product category, ' \
+                                    'you have defined cyclic categories ' \
+                                    'of products!'))
+            if categ_ids:
+                categ_where = '(categ_id IN (' + ','.join(categ_ids) + '))'
+            else:
+                categ_where = '(categ_id IS NULL)'
+
+            cr.execute(
+                'SELECT i.*, pl.currency_id '
+                'FROM product_pricelist_item AS i, '
+                    'product_pricelist_version AS v, product_pricelist AS pl '
+                'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) '
+                    'AND (product_id IS NULL OR product_id = %s) '
+                    'AND (' + categ_where + ' OR (categ_id IS NULL)) '
+                    'AND price_version_id = %s '
+                    'AND (min_quantity IS NULL OR min_quantity <= %s) '
+                    'AND i.price_version_id = v.id AND v.pricelist_id = pl.id '
+                'ORDER BY sequence LIMIT 1',
+                (tmpl_id, prod_id, plversion['id'], qty))
+            res = cr.dictfetchone()
+            if res:
+                if res['base'] == -1:
+                    if not res['base_pricelist_id']:
+                        price = 0.0
+                    else:
+                        price_tmp = self.price_get(cr, uid,
+                                [res['base_pricelist_id']], prod_id,
+                                qty)[res['base_pricelist_id']]
+                        ptype_src = self.browse(cr, uid,
+                                res['base_pricelist_id']).currency_id.id
+                        price = currency_obj.compute(cr, uid, ptype_src,
+                                res['currency_id'], price_tmp, round=False)
+                elif res['base'] == -2:
+                    where = []
+                    if partner:
+                        where = [('name', '=', partner) ] 
+                    sinfo = supplierinfo_obj.search(cr, uid,
+                            [('product_id', '=', tmpl_id)] + where)
+                    price = 0.0
+                    if sinfo:
+                        cr.execute('SELECT * ' \
+                                'FROM pricelist_partnerinfo ' \
+                                'WHERE suppinfo_id IN (' + \
+                                    ','.join(map(str, sinfo)) + ') ' \
+                                    'AND min_quantity <= %s ' \
+                                'ORDER BY min_quantity DESC LIMIT 1', (qty,))
+                        res2 = cr.dictfetchone()
+                        if res2:
+                            price = res2['price']
+                else:
+                    price_type = price_type_obj.browse(cr, uid, int(res['base']))
+                    price = currency_obj.compute(cr, uid,
+                            price_type.currency_id.id, res['currency_id'],
+                            product_obj.price_get(cr, uid, [prod_id],
+                                price_type.field)[prod_id], round=False)
+
+                price_limit = price
+
+                price = price * (1.0+(res['price_discount'] or 0.0))
+                price = rounding(price, res['price_round'])
+                price += (res['price_surcharge'] or 0.0)
+                if res['price_min_margin']:
+                    price = max(price, price_limit+res['price_min_margin'])
+                if res['price_max_margin']:
+                    price = min(price, price_limit+res['price_max_margin'])
+            else:
+                # False means no valid line found ! But we may not raise an
+                # exception here because it breaks the search
+                price = False
+            result[id] = price            
+            if context and ('uom' in context):
+                product = product_obj.browse(cr, uid, prod_id)
+                uom = product.uos_id or product.uom_id
+                result[id] = self.pool.get('product.uom')._compute_price(cr,
+                        uid, uom.id, result[id], context['uom'])                
+        return result
 
 product_pricelist()
 
 
 class product_pricelist_version(osv.osv):
-       _name = "product.pricelist.version"
-       _description = "Pricelist Version"
-       _columns = {
-               'pricelist_id': fields.many2one('product.pricelist', 'Price List',
-                       required=True, select=True),
-               'name': fields.char('Name', size=64, required=True),
-               'active': fields.boolean('Active'),
-               'items_id': fields.one2many('product.pricelist.item',
-                       'price_version_id', 'Price List Items', required=True),
-               'date_start': fields.date('Start Date'),
-               'date_end': fields.date('End Date'),
-       }
-       _defaults = {
-               'active': lambda *a: 1,
-       }
-
-       def _check_date(self, cursor, user, ids):
-               for pricelist_version in self.browse(cursor, user, ids):
-                       if not pricelist_version.active:
-                               continue
-                       cursor.execute('SELECT id ' \
-                                       'FROM product_pricelist_version ' \
-                                       'WHERE ((date_start <= %s AND %s <= date_end ' \
-                                                       'AND date_end IS NOT NULL) ' \
-                                               'OR (date_end IS NULL AND date_start IS NOT NULL ' \
-                                                       'AND date_start <= %s) ' \
-                                               'OR (date_start IS NULL AND date_end IS NOT NULL ' \
-                                                       'AND %s <= date_end) ' \
-                                               'OR (date_start IS NULL AND date_end IS NULL) ' \
-                                               'OR (%s = \'0000-01-01\' AND date_start IS NULL) ' \
-                                               'OR (%s = \'0000-01-01\' AND date_end IS NULL) ' \
-                                               'OR (%s = \'0000-01-01\' AND %s = \'0000-01-01\') ' \
-                                               'OR (%s = \'0000-01-01\' AND date_start <= %s) ' \
-                                               'OR (%s = \'0000-01-01\' AND %s <= date_end)) ' \
-                                               'AND pricelist_id = %d ' \
-                                               'AND active ' \
-                                               'AND id <> %d', (pricelist_version.date_end or '0000-01-01',
-                                                       pricelist_version.date_start or '0000-01-01',
-                                                       pricelist_version.date_end or '0000-01-01',
-                                                       pricelist_version.date_start or '0000-01-01',
-                                                       pricelist_version.date_start or '0000-01-01',
-                                                       pricelist_version.date_end or '0000-01-01',
-                                                       pricelist_version.date_start or '0000-01-01',
-                                                       pricelist_version.date_end or '0000-01-01',
-                                                       pricelist_version.date_start or '0000-01-01',
-                                                       pricelist_version.date_end or '0000-01-01',
-                                                       pricelist_version.date_end or '0000-01-01',
-                                                       pricelist_version.date_start or '0000-01-01',
-                                                       pricelist_version.pricelist_id.id,
-                                                       pricelist_version.id))
-                       if cursor.fetchall():
-                               return False
-               return True
-
-       _constraints = [
-               (_check_date, 'You can not have 2 pricelist version that overlaps!',
-                       ['date_start', 'date_end'])
-       ]
+    _name = "product.pricelist.version"
+    _description = "Pricelist Version"
+    _columns = {
+        'pricelist_id': fields.many2one('product.pricelist', 'Price List',
+            required=True, select=True),
+        'name': fields.char('Name', size=64, required=True, translate=True),
+        'active': fields.boolean('Active',
+            help="When a version is duplicated it is set to non active, so that the " \
+            "dates do not overlaps with original version. You should change the dates " \
+            "and reactivate the pricelist"),
+        'items_id': fields.one2many('product.pricelist.item',
+            'price_version_id', 'Price List Items', required=True),
+        'date_start': fields.date('Start Date', help="Starting date for this pricelist version to be valid."),
+        'date_end': fields.date('End Date', help="Ending date for this pricelist version to be valid."),
+    }
+    _defaults = {
+        'active': lambda *a: 1,
+    }
+
+    # We desactivate duplicated pricelists, so that dates do not overlap
+    def copy(self, cr, uid, id, default=None,context={}):
+        if not default: default= {}
+        default['active'] = False
+        return super(product_pricelist_version, self).copy(cr, uid, id, default, context)
+
+    def _check_date(self, cursor, user, ids):
+        for pricelist_version in self.browse(cursor, user, ids):
+            if not pricelist_version.active:
+                continue
+            where = []
+            if pricelist_version.date_start:
+                where.append("((date_end>='%s') or (date_end is null))" % (pricelist_version.date_start,))
+            if pricelist_version.date_end:
+                where.append("((date_start<='%s') or (date_start is null))" % (pricelist_version.date_end,))
+
+            cursor.execute('SELECT id ' \
+                    'FROM product_pricelist_version ' \
+                    'WHERE '+' and '.join(where) + (where and ' and ' or '')+
+                        'pricelist_id = %s ' \
+                        'AND active ' \
+                        'AND id <> %s', (
+                            pricelist_version.pricelist_id.id,
+                            pricelist_version.id))
+            if cursor.fetchall():
+                return False
+        return True
+
+    _constraints = [
+        (_check_date, 'You cannot have 2 pricelist versions that overlap!',
+            ['date_start', 'date_end'])
+    ]
 
 product_pricelist_version()
 
 class product_pricelist_item(osv.osv):
-       def _price_field_get(self, cr, uid, context={}):
-               cr.execute('select id,name from product_price_type where active')
-               result = cr.fetchall()
-               result.append((-1,'Other Pricelist'))
-               result.append((-2,'Partner section of the product form'))
-               return result
-
-       _name = "product.pricelist.item"
-       _description = "Pricelist item"
-       _order = "sequence, min_quantity desc"
-       _defaults = {
-               'base': lambda *a: -1,
-               'min_quantity': lambda *a: 0,
-               'sequence': lambda *a: 5,
-               'price_discount': lambda *a: 0,
-       }
-       _columns = {
-               'name': fields.char('Name', size=64),
-               'price_version_id': fields.many2one('product.pricelist.version', 'Price List Version', required=True, select=True),
-               'product_tmpl_id': fields.many2one('product.template', 'Product Template'),
-               'product_id': fields.many2one('product.product', 'Product'),
-               'categ_id': fields.many2one('product.category', 'Product Category'),
-
-               'min_quantity': fields.integer('Min. Quantity', required=True),
-               'sequence': fields.integer('Sequence', required=True),
-               'base': fields.selection(_price_field_get, 'Based on', required=True, size=-1),
-               'base_pricelist_id': fields.many2one('product.pricelist', 'If Other Pricelist'),
-
-               'price_surcharge': fields.float('Price Surcharge',
-                       digits=(16, int(config['price_accuracy']))),
-               'price_discount': fields.float('Price Discount', digits=(16,4)),
-               'price_round': fields.float('Price Rounding',
-                       digits=(16, int(config['price_accuracy']))),
-               'price_min_margin': fields.float('Price Min. Margin',
-                       digits=(16, int(config['price_accuracy']))),
-               'price_max_margin': fields.float('Price Max. Margin',
-                       digits=(16, int(config['price_accuracy']))),
-       }
-       def product_id_change(self, cr, uid, ids, product_id, context={}):
-               if not product_id:
-                       return {}
-               prod = self.pool.get('product.product').read(cr, uid, [product_id], ['code','name'])
-               if prod[0]['code']:
-                       return {'value': {'name': prod[0]['code']}}
-               return {}
+    def _price_field_get(self, cr, uid, context={}):
+        pt = self.pool.get('product.price.type')
+        ids = pt.search(cr, uid, [], context=context)
+        result = []
+        for line in pt.browse(cr, uid, ids, context=context):
+            result.append((line.id, line.name))
+
+        result.append((-1, _('Other Pricelist')))
+        result.append((-2, _('Partner section of the product form')))
+        return result
+
+    _name = "product.pricelist.item"
+    _description = "Pricelist item"
+    _order = "sequence, min_quantity desc"
+    _defaults = {
+        'base': lambda *a: -1,
+        'min_quantity': lambda *a: 0,
+        'sequence': lambda *a: 5,
+        'price_discount': lambda *a: 0,
+    }
+    _columns = {
+        'name': fields.char('Rule Name', size=64, help="Explicit rule name for this pricelist line."),
+        'price_version_id': fields.many2one('product.pricelist.version', 'Price List Version', required=True, select=True),
+        'product_tmpl_id': fields.many2one('product.template', 'Product Template', ondelete='cascade', help="Set a template if this rule only apply to a template of product. Keep empty for all products"),
+        'product_id': fields.many2one('product.product', 'Product', ondelete='cascade', help="Set a product if this rule only apply to one product. Keep empty for all products"),
+        'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade', help="Set a category of product if this rule only apply to products of a category and his childs. Keep empty for all products"),
+
+        'min_quantity': fields.integer('Min. Quantity', required=True, help="The rule only applies if the partner buys/sells more than this quantity."),
+        'sequence': fields.integer('Sequence', required=True),
+        'base': fields.selection(_price_field_get, 'Based on', required=True, size=-1, help="The mode for computing the price for this rule."),
+        'base_pricelist_id': fields.many2one('product.pricelist', 'If Other Pricelist'),
+
+        'price_surcharge': fields.float('Price Surcharge',
+            digits=(16, int(config['price_accuracy']))),
+        'price_discount': fields.float('Price Discount', digits=(16,4)),
+        'price_round': fields.float('Price Rounding',
+            digits=(16, int(config['price_accuracy'])),
+            help="Sets the price so that it is a multiple of this value.\n" \
+              "Rounding is applied after the discount and before the surcharge.\n" \
+              "To have prices that end in 9.99, set rounding 10, surcharge -0.01" \
+            ),
+        'price_min_margin': fields.float('Min. Price Margin',
+            digits=(16, int(config['price_accuracy']))),
+        'price_max_margin': fields.float('Max. Price Margin',
+            digits=(16, int(config['price_accuracy']))),
+    }
+    def product_id_change(self, cr, uid, ids, product_id, context={}):
+        if not product_id:
+            return {}
+        prod = self.pool.get('product.product').read(cr, uid, [product_id], ['code','name'])
+        if prod[0]['code']:
+            return {'value': {'name': prod[0]['code']}}
+        return {}
 product_pricelist_item()
 
 
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+