From f9c66ff20f2e7d8d35b9bc775486bb62abd4c367 Mon Sep 17 00:00:00 2001 From: "Hamza (hisl)" <hisl@odoo.com> Date: Thu, 24 Aug 2023 14:11:15 +0300 Subject: [PATCH] [FIX] purchase: correct currency for purchase_order_line If the currency_id and cost_currency_id is different for a product, the cost in the purchase order is wrong. The purchase order should use cost_currency_id instead of currency_id. Steps to reproduce on runbot: -Set the currency of main company as Dollars (USD). -Choose in runbot the company "My Belgian Company" as its currency is Euro. - Add the currency rate of today between EUR and USD - Take a product and edit the cost to 100 EUR - as the cost field is linked with the currency of the company make sure on the tab purchase there is no information - so the vendor pricelist is not present. - Go inside the purchase module and start a request for a quotation leave the currency as EUR - Select the product to purchase Current Behavior: The unit price will be (100*currency rate). If you do the same but take the currency as USD the product unit price on the purchase order line will be 100 Expected Behavior: The unit price should have been 100 Euros. And when dollar is chosen as currency, the exchange should have been applied. OPW-3460551 closes odoo/odoo#133024 Signed-off-by: Tiffany Chang (tic) <tic@odoo.com> --- addons/purchase/models/purchase.py | 2 +- addons/purchase/tests/test_purchase.py | 48 +++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/addons/purchase/models/purchase.py b/addons/purchase/models/purchase.py index 2237a985de3e..482d177b19c6 100644 --- a/addons/purchase/models/purchase.py +++ b/addons/purchase/models/purchase.py @@ -1246,7 +1246,7 @@ class PurchaseOrderLine(models.Model): line.taxes_id, line.company_id, ) - price_unit = line.product_id.currency_id._convert( + price_unit = line.product_id.cost_currency_id._convert( price_unit, line.currency_id, line.company_id, diff --git a/addons/purchase/tests/test_purchase.py b/addons/purchase/tests/test_purchase.py index 1977e2423bf8..5215dc9bfbcc 100644 --- a/addons/purchase/tests/test_purchase.py +++ b/addons/purchase/tests/test_purchase.py @@ -291,9 +291,12 @@ class TestPurchase(AccountTestInvoicingCommon): pol.product_qty += 1 self.assertEqual(pol.name, "New custom description") - def test_unit_price_precision_multicurrency(self): + def test_purchase_multicurrency(self): """ Purchase order lines should keep unit price precision of products + Also the products having prices in different currencies should be + correctly handled when creating a purchase order i-e product having a price of 100 usd + and when purchasing in EUR company the correct conversion should be applied """ self.env['decimal.precision'].search([ ('name', '=', 'Product Price'), @@ -334,6 +337,49 @@ class TestPurchase(AccountTestInvoicingCommon): purchase_order_coco = po_form.save() self.assertEqual(purchase_order_coco.order_line.price_unit, currency_rate.rate * product.standard_price, "Value shouldn't be rounded ðŸ«") + #check if the correct currency is set on the purchase order by comparing the expected price and actual price + + company_a = self.company_data['company'] + company_b = self.company_data_2['company'] + + company_b.currency_id = currency + + self.env['res.currency.rate'].create({ + 'name': '2023-01-01', + 'rate': 2, + 'currency_id': currency.id, + 'company_id': company_b.id, + }) + + product_b = self.env['product.product'].with_company(company_a).create({ + 'name': 'product_2', + 'uom_id': self.env.ref('uom.product_uom_unit').id, + 'standard_price': 0.0, + }) + + self.assertEqual(product_b.cost_currency_id, company_a.currency_id, 'The cost currency should be the one set on' + ' the company') + + product_b = product_b.with_company(company_b) + + self.assertEqual(product_b.cost_currency_id, currency, 'The cost currency should be the one set on the company,' + ' as the product is now opened in another company') + + product_b.supplier_taxes_id = False + product_b.update({'standard_price': 10.0}) + + #create a purchase order with the product from company B + order_b = self.env['purchase.order'].with_company(company_b).create({ + 'partner_id': self.partner_a.id, + 'order_line': [(0, 0, { + 'product_id': product_b.id, + 'product_qty': 1, + 'product_uom': self.env.ref('uom.product_uom_unit').id, + })], + }) + + self.assertEqual(order_b.order_line.price_unit, 10.0, 'The price unit should be 10.0') + def test_purchase_not_creating_useless_product_vendor(self): """ This test ensures that the product vendor is not created when the product is not set on the purchase order line. -- GitLab