1
0
forked from test/crm

fix: removed currency exchange rate settings and moved it to crm settings

(cherry picked from commit 5bee7022b22395b1da2e0de90746cff12e298748)
This commit is contained in:
Shariq Ansari 2025-07-28 17:40:22 +05:30 committed by Mergify
parent 53781cbf1e
commit c4df4d3253
9 changed files with 113 additions and 175 deletions

View File

@ -1,8 +0,0 @@
// Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
// frappe.ui.form.on("CRM Currency Exchange Settings", {
// refresh(frm) {
// },
// });

View File

@ -1,54 +0,0 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2025-07-28 12:29:02.935286",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"service_provider",
"access_key"
],
"fields": [
{
"default": "frankfurter.app",
"fieldname": "service_provider",
"fieldtype": "Select",
"in_list_view": 1,
"label": "Service Provider",
"options": "frankfurter.app\nexchangerate.host",
"reqd": 1
},
{
"depends_on": "eval:doc.service_provider == 'exchangerate.host';",
"fieldname": "access_key",
"fieldtype": "Data",
"label": "Access Key",
"mandatory_depends_on": "eval:doc.service_provider == 'exchangerate.host';"
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2025-07-28 12:30:08.080590",
"modified_by": "Administrator",
"module": "FCRM",
"name": "CRM Currency Exchange Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@ -1,84 +0,0 @@
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import frappe
import requests
from frappe import _
from frappe.model.document import Document
class CRMCurrencyExchangeSettings(Document):
pass
def get_exchange_rate(from_currency, to_currency, date=None):
if not date:
date = "latest"
api_used = "frankfurter"
api_endpoint = f"https://api.frankfurter.app/{date}?from={from_currency}&to={to_currency}"
res = requests.get(api_endpoint, timeout=5)
if res.ok:
data = res.json()
return data["rates"][to_currency]
# Fallback to exchangerate.host if Frankfurter API fails
ces = frappe.get_single("CRM Currency Exchange Settings")
if ces and ces.service_provider == "exchangerate.host":
api_used = "exchangerate.host"
if not ces.access_key:
frappe.throw(
_("Access Key is required for Service Provider: {0}").format(
frappe.bold(ces.service_provider)
)
)
params = {
"access_key": ces.access_key,
"from": from_currency,
"to": to_currency,
"amount": 1,
}
if date != "latest":
params["date"] = date
api_endpoint = "https://api.exchangerate.host/convert"
res = requests.get(api_endpoint, params=params, timeout=5)
if res.ok:
data = res.json()
return data["result"]
frappe.log_error(
title="Exchange Rate Fetch Error",
message=f"Failed to fetch exchange rate from {from_currency} to {to_currency} using {api_used} API.",
)
if api_used == "frankfurter":
user = frappe.session.user
is_manager = (
"System Manager" in frappe.get_roles(user)
or "Sales Manager" in frappe.get_roles(user)
or user == "Administrator"
)
if not is_manager:
frappe.throw(
_(
"Ask your manager to set up the Currency Exchange Provider, as default provider does not support currency conversion for {0} to {1}."
).format(from_currency, to_currency)
)
else:
frappe.throw(
_(
"Setup the Currency Exchange Provider as 'exchangerate.host' in settings, as default provider does not support currency conversion for {0} to {1}."
).format(from_currency, to_currency)
)
frappe.throw(
_(
"Failed to fetch exchange rate from {0} to {1} on {2}. Please check your internet connection or try again later."
).format(from_currency, to_currency, date)
)

View File

@ -1,22 +0,0 @@
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
from frappe.tests import IntegrationTestCase
# On IntegrationTestCase, the doctype test records and all
# link-field test record dependencies are recursively loaded
# Use these module variables to add/remove to/from that list
EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
class IntegrationTestCRMCurrencyExchangeSettings(IntegrationTestCase):
"""
Integration tests for CRMCurrencyExchangeSettings.
Use this class for testing interactions between multiple components.
"""
pass

View File

@ -6,11 +6,9 @@ from frappe import _
from frappe.desk.form.assign_to import add as assign
from frappe.model.document import Document
from crm.fcrm.doctype.crm_currency_exchange_settings.crm_currency_exchange_settings import get_exchange_rate
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.fcrm.doctype.crm_status_change_log.crm_status_change_log import add_status_change_log
from crm.fcrm.doctype.fcrm_settings.fcrm_settings import get_exchange_rate
class CRMDeal(Document):

View File

@ -4,7 +4,7 @@
import frappe
from frappe.model.document import Document
from crm.fcrm.doctype.crm_currency_exchange_settings.crm_currency_exchange_settings import get_exchange_rate
from crm.fcrm.doctype.fcrm_settings.fcrm_settings import get_exchange_rate
class CRMOrganization(Document):

View File

@ -8,7 +8,12 @@
"defaults_tab",
"restore_defaults",
"enable_forecasting",
"currency_tab",
"currency",
"exchange_rate_provider_section",
"service_provider",
"column_break_vqck",
"access_key",
"branding_tab",
"brand_name",
"brand_logo",
@ -72,13 +77,42 @@
"in_list_view": 1,
"label": "Currency",
"options": "Currency"
},
{
"fieldname": "currency_tab",
"fieldtype": "Tab Break",
"label": "Currency"
},
{
"fieldname": "exchange_rate_provider_section",
"fieldtype": "Section Break",
"label": "Exchange Rate Provider"
},
{
"default": "frankfurter.app",
"fieldname": "service_provider",
"fieldtype": "Select",
"label": "Service Provider",
"options": "frankfurter.app\nexchangerate.host",
"reqd": 1
},
{
"depends_on": "eval:doc.service_provider == 'exchangerate.host';",
"fieldname": "access_key",
"fieldtype": "Data",
"label": "Access Key",
"mandatory_depends_on": "eval:doc.service_provider == 'exchangerate.host';"
},
{
"fieldname": "column_break_vqck",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2025-07-13 11:58:34.857638",
"modified_by": "Administrator",
"modified": "2025-07-28 17:04:24.585768",
"modified_by": "shariq@frappe.io",
"module": "FCRM",
"name": "FCRM Settings",
"owner": "Administrator",

View File

@ -2,6 +2,7 @@
# For license information, please see license.txt
import frappe
import requests
from frappe import _
from frappe.custom.doctype.property_setter.property_setter import delete_property_setter, make_property_setter
from frappe.model.document import Document
@ -132,3 +133,76 @@ def get_forecasting_script():
this.doc.probability = status.probability
}
}"""
def get_exchange_rate(from_currency, to_currency, date=None):
if not date:
date = "latest"
api_used = "frankfurter"
api_endpoint = f"https://api.frankfurter.app/{date}?from={from_currency}&to={to_currency}"
res = requests.get(api_endpoint, timeout=5)
if res.ok:
data = res.json()
return data["rates"][to_currency]
# Fallback to exchangerate.host if Frankfurter API fails
settings = FCRMSettings("FCRM Settings")
if settings and settings.service_provider == "exchangerate.host":
api_used = "exchangerate.host"
if not settings.access_key:
frappe.throw(
_("Access Key is required for Service Provider: {0}").format(
frappe.bold(settings.service_provider)
)
)
params = {
"access_key": settings.access_key,
"from": from_currency,
"to": to_currency,
"amount": 1,
}
if date != "latest":
params["date"] = date
api_endpoint = "https://api.exchangerate.host/convert"
res = requests.get(api_endpoint, params=params, timeout=5)
if res.ok:
data = res.json()
return data["result"]
frappe.log_error(
title="Exchange Rate Fetch Error",
message=f"Failed to fetch exchange rate from {from_currency} to {to_currency} using {api_used} API.",
)
if api_used == "frankfurter":
user = frappe.session.user
is_manager = (
"System Manager" in frappe.get_roles(user)
or "Sales Manager" in frappe.get_roles(user)
or user == "Administrator"
)
if not is_manager:
frappe.throw(
_(
"Ask your manager to set up the Exchange Rate Provider, as default provider does not support currency conversion for {0} to {1}."
).format(from_currency, to_currency)
)
else:
frappe.throw(
_(
"Setup the Exchange Rate Provider as 'Exchangerate Host' in settings, as default provider does not support currency conversion for {0} to {1}."
).format(from_currency, to_currency)
)
frappe.throw(
_(
"Failed to fetch exchange rate from {0} to {1} on {2}. Please check your internet connection or try again later."
).format(from_currency, to_currency, date)
)