diff --git a/addons/product/models/product_pricelist.py b/addons/product/models/product_pricelist.py index 50d4961ef687276624a3d9fa0ac4665bf4127d1e..413888f717e883a7c3679274c7b241e2872c5bb6 100644 --- a/addons/product/models/product_pricelist.py +++ b/addons/product/models/product_pricelist.py @@ -221,7 +221,9 @@ class Pricelist(models.Model): price = product.price_compute(rule.base)[product.id] if price is not False: - price = rule._compute_price(price, price_uom, product, quantity=qty, partner=partner) + # pass the date through the context for further currency conversions + rule_with_date_context = rule.with_context(date=date) + price = rule_with_date_context._compute_price(price, price_uom, product, quantity=qty, partner=partner) suitable_rule = rule break # Final price conversion into pricelist currency @@ -583,6 +585,7 @@ class PricelistItem(models.Model): The unused parameters are there to make the full context available for overrides. """ self.ensure_one() + date = self.env.context.get('date') or fields.Date.today() convert_to_price_uom = (lambda price: product.uom_id._compute_price(price, price_uom)) if self.compute_price == 'fixed': price = convert_to_price_uom(self.fixed_price) @@ -592,18 +595,30 @@ class PricelistItem(models.Model): # complete formula price_limit = price price = (price - (price * (self.price_discount / 100))) or 0.0 + if self.base == 'standard_price': + price_currency = product.cost_currency_id + elif self.base == 'pricelist': + price_currency = self.currency_id # Already converted before to the pricelist currency + else: + price_currency = product.currency_id if self.price_round: price = tools.float_round(price, precision_rounding=self.price_round) + def convert_to_base_price_currency(amount): + return self.currency_id._convert(amount, price_currency, self.env.company, date, round=False) + if self.price_surcharge: - price_surcharge = convert_to_price_uom(self.price_surcharge) + price_surcharge = convert_to_base_price_currency(self.price_surcharge) + price_surcharge = convert_to_price_uom(price_surcharge) price += price_surcharge if self.price_min_margin: - price_min_margin = convert_to_price_uom(self.price_min_margin) + price_min_margin = convert_to_base_price_currency(self.price_min_margin) + price_min_margin = convert_to_price_uom(price_min_margin) price = max(price, price_limit + price_min_margin) if self.price_max_margin: - price_max_margin = convert_to_price_uom(self.price_max_margin) + price_max_margin = convert_to_base_price_currency(self.price_max_margin) + price_max_margin = convert_to_price_uom(price_max_margin) price = min(price, price_limit + price_max_margin) return price diff --git a/addons/product/tests/test_product_pricelist.py b/addons/product/tests/test_product_pricelist.py index 0269a570037a9451593f9a196b50790029c4618c..b3ec0955b6117c55259d0657e3f247922013e627 100644 --- a/addons/product/tests/test_product_pricelist.py +++ b/addons/product/tests/test_product_pricelist.py @@ -1,11 +1,14 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +import time + from odoo.tests.common import TransactionCase from odoo.tools import float_compare, test_reports class TestProductPricelist(TransactionCase): + # create context with pricelist and get price of it -> def setUp(self): super(TestProductPricelist, self).setUp() @@ -22,6 +25,12 @@ class TestProductPricelist(TransactionCase): self.uom_unit_id = self.ref('uom.product_uom_unit') self.list0 = self.ref('product.list0') + self.new_currency = self.env['res.currency'].create({ + 'name': 'Wonderful Currency', + 'symbol': ':)', + 'rate_ids': [(0, 0, {'rate': 10, 'name': time.strftime('%Y-%m-%d')})], + }) + self.ipad_retina_display.write({'uom_id': self.uom_unit_id, 'categ_id': self.category_5_id}) self.customer_pricelist = self.ProductPricelist.create({ 'name': 'Customer Pricelist', @@ -127,3 +136,53 @@ class TestProductPricelist(TransactionCase): self.env.company.external_report_layout_id = self.env.ref('web.external_layout_standard').id test_reports.try_report_action(self.cr, self.uid, 'action_product_price_list', wiz_data=data_dict, context=ctx, our_module='product') + + def test_20_price_different_currency_pricelist(self): + pricelist = self.ProductPricelist.create({ + 'name': 'Currency Pricelist', + 'currency_id': self.new_currency.id, + 'item_ids': [(0, 0, { + 'compute_price': 'formula', + 'base': 'list_price', + 'price_surcharge': 100 + })] + }) + product = self.computer_SC234.with_context({ + 'pricelist': pricelist.id, 'quantity': 1 + }) + # product price use the currency of the pricelist + self.assertEqual(product.price, 4600) + + def test_21_price_diff_cur_min_margin_pricelist(self): + pricelist = self.ProductPricelist.create({ + 'name': 'Currency with Margin Pricelist', + 'currency_id': self.new_currency.id, + 'item_ids': [(0, 0, { + 'compute_price': 'formula', + 'base': 'list_price', + 'price_min_margin': 10, + 'price_max_margin': 100, + })] + }) + product = self.computer_SC234.with_context({ + 'pricelist': pricelist.id, 'quantity': 1 + }) + # product price use the currency of the pricelist + self.assertEqual(product.price, 4510) + + def test_22_price_diff_cur_max_margin_pricelist(self): + pricelist = self.ProductPricelist.create({ + 'name': 'Currency with Margin Pricelist', + 'currency_id': self.new_currency.id, + 'item_ids': [(0, 0, { + 'compute_price': 'formula', + 'base': 'list_price', + 'price_surcharge': 100, + 'price_max_margin': 90 + })] + }) + product = self.computer_SC234.with_context({ + 'pricelist': pricelist.id, 'quantity': 1 + }) + # product price use the currency of the pricelist + self.assertEqual(product.price, 4590)