1
0
forked from test/crm

fix: store current day exchange rate when currency is updated in deal & organization

(cherry picked from commit d7ba5a5f629d5fe7cf3a00fddd8df7818e7b874d)

# Conflicts:
#	crm/fcrm/doctype/crm_deal/crm_deal.json
This commit is contained in:
Shariq Ansari 2025-07-09 18:22:13 +05:30 committed by Mergify
parent 910c1e0c78
commit 6e3737403d
4 changed files with 58 additions and 45 deletions

View File

@ -38,7 +38,7 @@
"column_break_xbyf",
"territory",
"currency",
"currency_exchange",
"exchange_rate",
"annual_revenue",
"industry",
"person_section",
@ -418,16 +418,18 @@
"label": "Closed On"
},
{
"fieldname": "currency_exchange",
"fieldtype": "Link",
"label": "Currency Exchange",
"options": "CRM Currency Exchange"
"default": "1",
"description": "The rate used to convert the deal\u2019s currency to your crm's base currency (set in CRM Settings). It is set once when the currency is first added and doesn't change automatically.",
"fieldname": "exchange_rate",
"fieldtype": "Float",
"label": "Exchange Rate"
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
<<<<<<< HEAD
<<<<<<< HEAD
<<<<<<< HEAD
"modified": "2025-07-05 12:25:05.927806",
=======
@ -436,6 +438,9 @@
=======
"modified": "2025-07-09 14:26:53.986118",
>>>>>>> 0be73791 (fix: store currency exchange in deal & organization)
=======
"modified": "2025-07-09 17:58:55.956639",
>>>>>>> d7ba5a5f (fix: store current day exchange rate when currency is updated in deal & organization)
"modified_by": "Administrator",
"module": "FCRM",
"name": "CRM Deal",

View File

@ -10,6 +10,7 @@ from crm.fcrm.doctype.crm_service_level_agreement.utils import get_sla
from crm.fcrm.doctype.crm_status_change_log.crm_status_change_log import (
add_status_change_log,
)
from crm.utils import get_historical_exchange_rate
class CRMDeal(Document):
@ -28,7 +29,7 @@ class CRMDeal(Document):
self.closed_on = frappe.utils.now_datetime()
self.validate_forcasting_fields()
self.validate_lost_reason()
self.update_currency_exchange()
self.update_exchange_rate()
def after_insert(self):
if self.deal_owner:
@ -171,27 +172,16 @@ class CRMDeal(Document):
elif self.lost_reason == "Other" and not self.lost_notes:
frappe.throw(_("Please specify the reason for losing the deal."), frappe.ValidationError)
def update_currency_exchange(self):
if self.has_value_changed("currency") or not self.currency_exchange:
system_currency = frappe.db.get_single_value("System Settings", "currency")
currency_exchange = None
def update_exchange_rate(self):
if self.has_value_changed("currency") or not self.exchange_rate:
system_currency = frappe.db.get_single_value("FCRM Settings", "currency") or "USD"
exchange_rate = 1
if self.currency and self.currency != system_currency:
if not frappe.db.exists(
"CRM Currency Exchange", {"from_currency": self.currency, "to_currency": system_currency}
):
new_er = frappe.new_doc("CRM Currency Exchange")
new_er.from_currency = self.currency
new_er.to_currency = system_currency
new_er.insert(ignore_permissions=True)
currency_exchange = new_er.name
else:
currency_exchange = frappe.db.get_value(
"CRM Currency Exchange",
{"from_currency": self.currency, "to_currency": system_currency},
"name",
)
exchange_rate = get_historical_exchange_rate(
frappe.utils.nowdate(), self.currency, system_currency
)
currency_exchange and self.db_set("currency_exchange", currency_exchange)
self.db_set("exchange_rate", exchange_rate)
@staticmethod
def default_list_data():

View File

@ -4,32 +4,23 @@
import frappe
from frappe.model.document import Document
from crm.utils import get_historical_exchange_rate
class CRMOrganization(Document):
def validate(self):
self.update_currency_exchange()
self.update_exchange_rate()
def update_currency_exchange(self):
if self.has_value_changed("currency") or not self.currency_exchange:
system_currency = frappe.db.get_single_value("System Settings", "currency")
currency_exchange = None
def update_exchange_rate(self):
if self.has_value_changed("currency") or not self.exchange_rate:
system_currency = frappe.db.get_single_value("FCRM Settings", "currency") or "USD"
exchange_rate = 1
if self.currency and self.currency != system_currency:
if not frappe.db.exists(
"CRM Currency Exchange", {"from_currency": self.currency, "to_currency": system_currency}
):
new_er = frappe.new_doc("CRM Currency Exchange")
new_er.from_currency = self.currency
new_er.to_currency = system_currency
new_er.insert(ignore_permissions=True)
currency_exchange = new_er.name
else:
currency_exchange = frappe.db.get_value(
"CRM Currency Exchange",
{"from_currency": self.currency, "to_currency": system_currency},
"name",
)
exchange_rate = get_historical_exchange_rate(
frappe.utils.nowdate(), self.currency, system_currency
)
currency_exchange and self.db_set("currency_exchange", currency_exchange)
self.db_set("exchange_rate", exchange_rate)
@staticmethod
def default_list_data():

View File

@ -2,6 +2,7 @@ import functools
import frappe
import phonenumbers
import requests
from frappe import _
from frappe.model.docstatus import DocStatus
from frappe.model.dynamic_links import get_dynamic_link_map
@ -266,3 +267,29 @@ def sales_user_only(fn):
return fn(*args, **kwargs)
return wrapper
def get_exchange_rate(from_currency, to_currency):
url = f"https://api.frankfurter.app/latest?from={from_currency}&to={to_currency}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
rate = data["rates"].get(to_currency)
return rate
else:
frappe.throw(_("Failed to fetch exchange rate from external API. Please try again later."))
return None
def get_historical_exchange_rate(date, from_currency, to_currency):
url = f"https://api.frankfurter.app/{date}?from={from_currency}&to={to_currency}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
rate = data["rates"].get(to_currency)
return rate
else:
frappe.throw(_("Failed to fetch historical exchange rate from external API. Please try again later."))
return None