From e1e56b6920b6e9095e3a6c366870d305a6d440b3 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Sun, 12 Jul 2026 21:12:29 +0530 Subject: [PATCH] test: adjust currency tests for deterministic seeded exchange rate Seeding a current-dated USD->INR rate makes get_exchange_rate resolve 62.9 on today() instead of hitting the live API, which exposed three tests that implicitly relied on a different/undefined current rate: - customer: dropped its own colliding current-dated seed (ignored via ignore_if_duplicate, and its cleanup deleted the shared seed) and now asserts the quotation resolves the seeded rate via get_exchange_rate. - exchange_rate_revaluation: the revalued rate (62.9) is now below the booked 80, so the revaluation is a loss (debited) rather than a gain; derive the gain/loss column from the sign instead of assuming a gain. - purchase_invoice: the receipt rate was an accidental tuple (70,) that got discarded and recomputed to the seed; set explicit rates with the receipt above the invoice so the stock exchange difference is a credit, matching the asserted column. --- .../test_exchange_rate_revaluation.py | 7 ++++++- .../purchase_invoice/test_purchase_invoice.py | 4 ++-- .../selling/doctype/customer/test_customer.py | 20 +++++-------------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py b/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py index 5a37bccaafb..3e5b08d069d 100644 --- a/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py +++ b/erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py @@ -348,10 +348,15 @@ class TestExchangeRateRevaluation(ERPNextTestSuite, AccountsTestMixin): je.reload() self.assertEqual(je.voucher_type, "Exchange Rate Revaluation") self.assertEqual(len(je.accounts), 3) + # A gain is credited to the gain/loss account, a loss is debited. The current + # exchange rate (from master data) may sit either side of the booked rate, so + # derive the column from the sign instead of assuming a gain. + gain_loss_debit = abs(total_gain_loss) if total_gain_loss < 0 else 0.0 + gain_loss_credit = total_gain_loss if total_gain_loss > 0 else 0.0 expected = [ (usd_account, new_balance, 0.0, 100.0, 0.0), (usd_account, 0.0, old_balance, 0.0, 100.0), - (gain_loss_account, 0.0, total_gain_loss, 0.0, total_gain_loss), + (gain_loss_account, gain_loss_debit, gain_loss_credit, gain_loss_debit, gain_loss_credit), ] actual = [] for acc in je.accounts: diff --git a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py index 17afc03dde1..e60d3f4614c 100644 --- a/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py +++ b/erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py @@ -472,7 +472,7 @@ class TestPurchaseInvoice(ERPNextTestSuite, StockTestMixin): pr = frappe.new_doc("Purchase Receipt") pr.currency = "USD" pr.company = "_Test Company with perpetual inventory" - pr.conversion_rate = (70,) + pr.conversion_rate = 80 pr.supplier = "_Test Supplier USD" pr.append( "items", @@ -491,7 +491,7 @@ class TestPurchaseInvoice(ERPNextTestSuite, StockTestMixin): # Createing purchase invoice against Purchase Receipt pi = create_purchase_invoice(pr.name) - pi.conversion_rate = 80 + pi.conversion_rate = 70 pi.credit_to = "_Test Payable USD - TCP1" pi.insert() pi.submit() diff --git a/erpnext/selling/doctype/customer/test_customer.py b/erpnext/selling/doctype/customer/test_customer.py index a1b15a1e867..c1315fe518b 100644 --- a/erpnext/selling/doctype/customer/test_customer.py +++ b/erpnext/selling/doctype/customer/test_customer.py @@ -17,6 +17,7 @@ from erpnext.selling.doctype.customer.mapper import ( make_quotation, parse_full_name, ) +from erpnext.setup.utils import get_exchange_rate from erpnext.tests.utils import ERPNextTestSuite @@ -29,20 +30,9 @@ class TestCustomer(ERPNextTestSuite): frappe.defaults.set_user_default("company", company) self.addCleanup(frappe.defaults.clear_user_default, "company") - # Seed a deterministic rate so the test does not depend on the live exchange-rate API. - rate = 83.0 - exchange = frappe.get_doc( - { - "doctype": "Currency Exchange", - "date": nowdate(), - "from_currency": foreign_currency, - "to_currency": company_currency, - "exchange_rate": rate, - "for_selling": 1, - "for_buying": 1, - } - ).insert(ignore_if_duplicate=True) - self.addCleanup(frappe.delete_doc, "Currency Exchange", exchange.name, force=1) + # Master data seeds a current-dated exchange rate, so make_quotation should + # resolve that rate instead of falling back to the default conversion rate of 1.0. + expected_rate = get_exchange_rate(foreign_currency, company_currency, nowdate()) customer = frappe.get_doc( { @@ -59,7 +49,7 @@ class TestCustomer(ERPNextTestSuite): self.assertEqual(quotation.currency, foreign_currency) self.assertNotEqual(flt(quotation.conversion_rate), 1.0) self.assertNotEqual(flt(quotation.conversion_rate), 0.0) - self.assertEqual(flt(quotation.conversion_rate), rate) + self.assertEqual(flt(quotation.conversion_rate), flt(expected_rate)) def test_get_customer_name_dedupes_with_numeric_suffix(self): # When a customer name already exists, get_customer_name appends "- ". The