diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index 72f1c0eb342..aaf68e3fe43 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -289,7 +289,12 @@ class product_pricelist(osv.osv): price = price * (1.0+(rule.price_discount or 0.0)) if rule.price_round: price = tools.float_round(price, precision_rounding=rule.price_round) - price += (rule.price_surcharge or 0.0) + if context.get('uom'): + # compute price_surcharge based on reference uom + factor = product_uom_obj.browse(cr, uid, context.get('uom'), context=context).factor + else: + factor = 1.0 + price += (rule.price_surcharge or 0.0) / factor if rule.price_min_margin: price = max(price, price_limit+rule.price_min_margin) if rule.price_max_margin: diff --git a/addons/product/tests/__init__.py b/addons/product/tests/__init__.py index 850189ac0f4..4a1ce43351b 100644 --- a/addons/product/tests/__init__.py +++ b/addons/product/tests/__init__.py @@ -1,5 +1,6 @@ -from . import test_uom +from . import test_uom, test_pricelist fast_suite = [ test_uom, + test_pricelist ] diff --git a/addons/product/tests/test_pricelist.py b/addons/product/tests/test_pricelist.py new file mode 100644 index 00000000000..dd9130e1be5 --- /dev/null +++ b/addons/product/tests/test_pricelist.py @@ -0,0 +1,70 @@ +from openerp.tests.common import TransactionCase + +class TestPricelist(TransactionCase): + """Tests for unit of measure conversion""" + + def setUp(self): + super(TestPricelist, self).setUp() + cr, uid, context = self.cr, self.uid, {} + self.ir_model_data = self.registry('ir.model.data') + self.product_product = self.registry('product.product') + self.product_pricelist = self.registry('product.pricelist') + self.uom = self.registry('product.uom') + + self.usb_adapter_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_product_48')[1] + self.datacard_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_template_46')[1] + self.unit_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_uom_unit')[1] + self.dozen_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'product_uom_dozen')[1] + + self.public_pricelist_id = self.ir_model_data.get_object_reference(cr, uid, 'product', 'list0')[1] + self.sale_pricelist_id = self.product_pricelist.create(cr, uid, { + 'name': 'Sale pricelist', + 'type': 'sale', + 'version_id': [(0, 0, { + 'name': 'v1.0', + 'items_id': [(0, 0, { + 'name': 'Discount 10%', + 'base': 1, # based on public price + 'price_discount': -0.1, + 'product_id': self.usb_adapter_id + }), (0, 0, { + 'name': 'Discount -0.5', + 'base': 1, # based on public price + 'price_surcharge': -0.5, + 'product_id': self.datacard_id + })] + })] + }, context=context) + + def test_10_discount(self): + # Make sure the price using a pricelist is the same than without after + # applying the computation manually + cr, uid, context = self.cr, self.uid, {} + + public_context = dict(context, pricelist=self.public_pricelist_id) + pricelist_context = dict(context, pricelist=self.sale_pricelist_id) + + usb_adapter_without_pricelist = self.product_product.browse(cr, uid, self.usb_adapter_id, context=public_context) + usb_adapter_with_pricelist = self.product_product.browse(cr, uid, self.usb_adapter_id, context=pricelist_context) + self.assertEqual(usb_adapter_with_pricelist.price, usb_adapter_without_pricelist.price*0.9) + + datacard_without_pricelist = self.product_product.browse(cr, uid, self.datacard_id, context=public_context) + datacard_with_pricelist = self.product_product.browse(cr, uid, self.datacard_id, context=pricelist_context) + self.assertEqual(datacard_with_pricelist.price, datacard_without_pricelist.price-0.5) + + # Make sure that changing the unit of measure does not break the unit + # price (after converting) + unit_context = dict(context, + pricelist=self.sale_pricelist_id, + uom=self.unit_id) + dozen_context = dict(context, + pricelist=self.sale_pricelist_id, + uom=self.dozen_id) + + usb_adapter_unit = self.product_product.browse(cr, uid, self.usb_adapter_id, context=unit_context) + usb_adapter_dozen = self.product_product.browse(cr, uid, self.usb_adapter_id, context=dozen_context) + self.assertAlmostEqual(usb_adapter_unit.price*12, usb_adapter_dozen.price) + + datacard_unit = self.product_product.browse(cr, uid, self.datacard_id, context=unit_context) + datacard_dozen = self.product_product.browse(cr, uid, self.datacard_id, context=dozen_context) + self.assertAlmostEqual(datacard_unit.price*12, datacard_dozen.price) diff --git a/addons/product_visible_discount/product_visible_discount.py b/addons/product_visible_discount/product_visible_discount.py index f4982bf2692..e32b039d293 100644 --- a/addons/product_visible_discount/product_visible_discount.py +++ b/addons/product_visible_discount/product_visible_discount.py @@ -43,6 +43,7 @@ class sale_order_line(osv.osv): fiscal_position=False, flag=False, context=None): def get_real_price(res_dict, product_id, qty, uom, pricelist): + """Retrieve the price before applying the pricelist""" item_obj = self.pool.get('product.pricelist.item') price_type_obj = self.pool.get('product.price.type') product_obj = self.pool.get('product.product') @@ -53,9 +54,8 @@ class sale_order_line(osv.osv): factor = 1.0 if uom and uom != product.uom_id.id: - product_uom_obj = self.pool.get('product.uom') - uom_data = product_uom_obj.browse(cr, uid, product.uom_id.id) - factor = uom_data.factor + # the unit price is in a different uom + factor = self.pool['product.uom']._compute_qty(cr, uid, uom, 1.0, product.uom_id.id) return product_read[field_name] * factor