From 3e51d875f7d8527622163bcb3f08ea0c1b341244 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 23 Jul 2025 13:12:12 +0530 Subject: [PATCH 1/3] refactor: cache assignees (cherry picked from commit cf8a1ce8a3e465c0762a8158c14d0ac8e7207663) --- frontend/src/data/document.js | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/frontend/src/data/document.js b/frontend/src/data/document.js index 4d073e3e..44af0a3d 100644 --- a/frontend/src/data/document.js +++ b/frontend/src/data/document.js @@ -5,6 +5,7 @@ import { reactive } from 'vue' const documentsCache = {} const controllersCache = {} +const assigneesCache = {} export function useDocument(doctype, docname) { const { setupScript } = getScript(doctype) @@ -46,16 +47,20 @@ export function useDocument(doctype, docname) { } } - const assignees = createResource({ - url: 'crm.api.doc.get_assigned_users', - cache: `assignees:${doctype}:${docname}`, - auto: docname ? true : false, - params: { - doctype: doctype, - name: docname, - }, - transform: (data) => parseAssignees(data), - }) + assigneesCache[doctype] = assigneesCache[doctype] || {} + + if (!assigneesCache[doctype][docname || '']) { + assigneesCache[doctype][docname || ''] = createResource({ + url: 'crm.api.doc.get_assigned_users', + cache: `assignees:${doctype}:${docname}`, + auto: docname ? true : false, + params: { + doctype: doctype, + name: docname, + }, + transform: (data) => parseAssignees(data), + }) + } async function setupFormScript() { if ( @@ -224,7 +229,7 @@ export function useDocument(doctype, docname) { return { document: documentsCache[doctype][docname || ''], - assignees, + assignees: assigneesCache[doctype][docname || ''], getControllers, triggerOnLoad, triggerOnBeforeCreate, From c345d5b5bd5f7fcc32dccfcb2789f4bc4a304ee6 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 23 Jul 2025 13:21:02 +0530 Subject: [PATCH 2/3] refactor: rename update_close_date to update_closed_date and adjust related logic (cherry picked from commit c84ac2933265889a599bd1cc8e57fb802fa2baea) --- crm/fcrm/doctype/crm_deal/crm_deal.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crm/fcrm/doctype/crm_deal/crm_deal.py b/crm/fcrm/doctype/crm_deal/crm_deal.py index f46f6475..bd4198a3 100644 --- a/crm/fcrm/doctype/crm_deal/crm_deal.py +++ b/crm/fcrm/doctype/crm_deal/crm_deal.py @@ -139,12 +139,12 @@ class CRMDeal(Document): if sla: sla.apply(self) - def update_close_date(self): + def update_closed_date(self): """ - Update the close date based on the "Won" status. + Update the closed date based on the "Won" status. """ - if self.status == "Won" and not self.close_date: - self.close_date = frappe.utils.nowdate() + if self.status == "Won" and not self.closed_date: + self.closed_date = frappe.utils.nowdate() def update_default_probability(self): """ @@ -154,13 +154,13 @@ class CRMDeal(Document): self.probability = frappe.db.get_value("CRM Deal Status", self.status, "probability") or 0 def validate_forcasting_fields(self): - self.update_close_date() + self.update_closed_date() self.update_default_probability() if frappe.db.get_single_value("FCRM Settings", "enable_forecasting"): - if not self.deal_value or self.deal_value == 0: - frappe.throw(_("Deal Value is required."), frappe.MandatoryError) - if not self.close_date: - frappe.throw(_("Close Date is required."), frappe.MandatoryError) + if not self.expected_deal_value or self.expected_deal_value == 0: + frappe.throw(_("Expected Deal Value is required."), frappe.MandatoryError) + if not self.expected_closure_date: + frappe.throw(_("Expected Closure Date is required."), frappe.MandatoryError) def validate_lost_reason(self): """ From bafe1c7e0a5e7bfa20896fffbbe5bf130fd2d730 Mon Sep 17 00:00:00 2001 From: Shariq Ansari Date: Wed, 23 Jul 2025 13:33:41 +0530 Subject: [PATCH 3/3] fix: improve exchange rate fetching with retry logic and default return value (cherry picked from commit 9761989ea49fee7dacb3dcf756887f05f5a2cc9c) --- crm/utils/__init__.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/crm/utils/__init__.py b/crm/utils/__init__.py index 6f7bbad0..eaf076d5 100644 --- a/crm/utils/__init__.py +++ b/crm/utils/__init__.py @@ -275,12 +275,16 @@ def get_exchange_rate(from_currency, to_currency, date=None): url = f"https://api.frankfurter.app/{date}?from={from_currency}&to={to_currency}" - response = requests.get(url) + for _i in range(3): + response = requests.get(url) + if response.status_code == 200: + data = response.json() + rate = data["rates"].get(to_currency) + if rate: + return rate - 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 + frappe.log_error( + f"Failed to fetch exchange rate from {from_currency} to {to_currency} on {date}", + title="Exchange Rate Fetch Error", + ) + return 1.0 # Default exchange rate if API call fails or no rate found