From e2c89ff16dff6a2ba7314e9ab95eea13d69f749c Mon Sep 17 00:00:00 2001 From: Kavin <78342682+kavin0411@users.noreply.github.com> Date: Fri, 10 Jan 2025 18:20:47 +0530 Subject: [PATCH 1/3] fix: calculate AED exchange rate based on pegged value with USD --- erpnext/setup/utils.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index bebc5d9efb..13bfdb552e 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -51,6 +51,12 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No return if from_currency == to_currency: return 1 + # as AED is pegged to USD at the exchange rate of 3.6725 AED + # handling the exchange rate manually without API call + if from_currency == "USD" and to_currency == "AED": + return 3.6725 + if from_currency == "AED" and to_currency == "USD": + return 1 / 3.6725 if not transaction_date: transaction_date = nowdate() @@ -96,8 +102,8 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No settings = frappe.get_cached_doc("Currency Exchange Settings") req_params = { "transaction_date": transaction_date, - "from_currency": from_currency, - "to_currency": to_currency, + "from_currency": from_currency if from_currency != "AED" else "USD", + "to_currency": to_currency if to_currency != "AED" else "USD", } params = {} for row in settings.req_params: @@ -109,6 +115,12 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No for res_key in settings.result_key: value = value[format_ces_api(str(res_key.key), req_params)] cache.setex(name=key, time=21600, value=flt(value)) + + if to_currency == "AED": + value *= 3.6725 + if from_currency == "AED": + value /= 3.6725 + return flt(value) except Exception: frappe.log_error(title=_("Get Exchange Rate")) -- GitLab From a319b70d2124fe0ef87b0e69da97379d1a6f8f7d Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Tue, 21 Jan 2025 12:15:08 +0530 Subject: [PATCH 2/3] refactor: fix type error --- erpnext/setup/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index 13bfdb552e..40caebf935 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -116,6 +116,8 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No value = value[format_ces_api(str(res_key.key), req_params)] cache.setex(name=key, time=21600, value=flt(value)) + # Support AED conversion through pegged USD + value = flt(value) if to_currency == "AED": value *= 3.6725 if from_currency == "AED": -- GitLab From 00f909a29f4bb213aeb48c0959d59a72dec1a036 Mon Sep 17 00:00:00 2001 From: ruthra kumar Date: Mon, 20 Jan 2025 17:28:47 +0530 Subject: [PATCH 3/3] refactor: use dictionary for better expandability --- erpnext/setup/utils.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/erpnext/setup/utils.py b/erpnext/setup/utils.py index 40caebf935..99b6c07494 100644 --- a/erpnext/setup/utils.py +++ b/erpnext/setup/utils.py @@ -5,11 +5,15 @@ import frappe from frappe import _ from frappe.utils import add_days, flt, get_datetime_str, nowdate -from frappe.utils.data import now_datetime -from frappe.utils.nestedset import get_ancestors_of, get_root_of # noqa +from frappe.utils.data import getdate, now_datetime +from frappe.utils.nestedset import get_root_of from erpnext import get_default_company +PEGGED_CURRENCIES = { + "USD": {"AED": 3.6725}, # AED is pegged to USD at a rate of 3.6725 since 1997 +} + def before_tests(): frappe.clear_cache() @@ -44,6 +48,14 @@ def before_tests(): frappe.db.commit() +def get_pegged_rate(from_currency: str, to_currency: str, transaction_date) -> float | None: + if rate := PEGGED_CURRENCIES.get(from_currency, {}).get(to_currency): + return rate + elif rate := PEGGED_CURRENCIES.get(to_currency, {}).get(from_currency): + return 1 / rate + return None + + @frappe.whitelist() def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=None): if not (from_currency and to_currency): @@ -51,15 +63,13 @@ def get_exchange_rate(from_currency, to_currency, transaction_date=None, args=No return if from_currency == to_currency: return 1 - # as AED is pegged to USD at the exchange rate of 3.6725 AED - # handling the exchange rate manually without API call - if from_currency == "USD" and to_currency == "AED": - return 3.6725 - if from_currency == "AED" and to_currency == "USD": - return 1 / 3.6725 if not transaction_date: transaction_date = nowdate() + + if rate := get_pegged_rate(from_currency, to_currency, transaction_date): + return rate + currency_settings = frappe.get_doc("Accounts Settings").as_dict() allow_stale_rates = currency_settings.get("allow_stale") -- GitLab