fix: convert to system currency and show deal value
This commit is contained in:
parent
f4b81b3761
commit
4f02f0a4d7
@ -223,19 +223,20 @@ def get_average_deal_value(from_date, to_date, user="", conds="", return_result=
|
|||||||
f"""
|
f"""
|
||||||
SELECT
|
SELECT
|
||||||
AVG(CASE
|
AVG(CASE
|
||||||
WHEN creation >= %(from_date)s AND creation < DATE_ADD(%(to_date)s, INTERVAL 1 DAY) AND status != 'Lost'
|
WHEN d.creation >= %(from_date)s AND d.creation < DATE_ADD(%(to_date)s, INTERVAL 1 DAY) AND d.status != 'Lost'
|
||||||
{conds}
|
{conds}
|
||||||
THEN deal_value
|
THEN d.deal_value * IFNULL(e.exchange_rate, 1)
|
||||||
ELSE NULL
|
ELSE NULL
|
||||||
END) as current_month_avg,
|
END) as current_month_avg,
|
||||||
|
|
||||||
AVG(CASE
|
AVG(CASE
|
||||||
WHEN creation >= %(prev_from_date)s AND creation < %(from_date)s AND status != 'Lost'
|
WHEN d.creation >= %(prev_from_date)s AND d.creation < %(from_date)s AND d.status != 'Lost'
|
||||||
{conds}
|
{conds}
|
||||||
THEN deal_value
|
THEN d.deal_value * IFNULL(e.exchange_rate, 1)
|
||||||
ELSE NULL
|
ELSE NULL
|
||||||
END) as prev_month_avg
|
END) as prev_month_avg
|
||||||
FROM `tabCRM Deal`
|
FROM `tabCRM Deal` d
|
||||||
|
LEFT JOIN `tabCRM Currency Exchange` e ON d.currency_exchange = e.name
|
||||||
""",
|
""",
|
||||||
{
|
{
|
||||||
"from_date": from_date,
|
"from_date": from_date,
|
||||||
@ -253,8 +254,8 @@ def get_average_deal_value(from_date, to_date, user="", conds="", return_result=
|
|||||||
return {
|
return {
|
||||||
"title": _("Avg Deal Value"),
|
"title": _("Avg Deal Value"),
|
||||||
"value": current_month_avg,
|
"value": current_month_avg,
|
||||||
"tooltip": _("Average value of deals created"),
|
"tooltip": _("Average value of deals created (converted to base currency)"),
|
||||||
# "prefix": "$",
|
"prefix": get_base_currency_symbol(),
|
||||||
# "suffix": "K",
|
# "suffix": "K",
|
||||||
"delta": delta,
|
"delta": delta,
|
||||||
"deltaSuffix": "%",
|
"deltaSuffix": "%",
|
||||||
@ -405,9 +406,10 @@ def get_deals_by_salesperson(from_date="", to_date="", user="", deal_conds=""):
|
|||||||
SELECT
|
SELECT
|
||||||
IFNULL(u.full_name, d.deal_owner) AS salesperson,
|
IFNULL(u.full_name, d.deal_owner) AS salesperson,
|
||||||
COUNT(*) AS deals,
|
COUNT(*) AS deals,
|
||||||
SUM(COALESCE(d.deal_value, 0)) AS value
|
SUM(COALESCE(d.deal_value, 0) * IFNULL(e.exchange_rate, 1)) AS value
|
||||||
FROM `tabCRM Deal` AS d
|
FROM `tabCRM Deal` AS d
|
||||||
LEFT JOIN `tabUser` AS u ON u.name = d.deal_owner
|
LEFT JOIN `tabUser` AS u ON u.name = d.deal_owner
|
||||||
|
LEFT JOIN `tabCRM Currency Exchange` AS e ON d.currency_exchange = e.name
|
||||||
WHERE DATE(d.creation) BETWEEN %(from)s AND %(to)s
|
WHERE DATE(d.creation) BETWEEN %(from)s AND %(to)s
|
||||||
{deal_conds}
|
{deal_conds}
|
||||||
GROUP BY d.deal_owner
|
GROUP BY d.deal_owner
|
||||||
@ -417,7 +419,10 @@ def get_deals_by_salesperson(from_date="", to_date="", user="", deal_conds=""):
|
|||||||
as_dict=True,
|
as_dict=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
return result or []
|
return {
|
||||||
|
"data": result or [],
|
||||||
|
"currency_symbol": get_base_currency_symbol(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -443,8 +448,9 @@ def get_deals_by_territory(from_date="", to_date="", user="", deal_conds=""):
|
|||||||
SELECT
|
SELECT
|
||||||
IFNULL(d.territory, 'Empty') AS territory,
|
IFNULL(d.territory, 'Empty') AS territory,
|
||||||
COUNT(*) AS deals,
|
COUNT(*) AS deals,
|
||||||
SUM(COALESCE(d.deal_value, 0)) AS value
|
SUM(COALESCE(d.deal_value, 0) * IFNULL(e.exchange_rate, 1)) AS value
|
||||||
FROM `tabCRM Deal` AS d
|
FROM `tabCRM Deal` AS d
|
||||||
|
LEFT JOIN `tabCRM Currency Exchange` AS e ON d.currency_exchange = e.name
|
||||||
WHERE DATE(d.creation) BETWEEN %(from)s AND %(to)s
|
WHERE DATE(d.creation) BETWEEN %(from)s AND %(to)s
|
||||||
{deal_conds}
|
{deal_conds}
|
||||||
GROUP BY d.territory
|
GROUP BY d.territory
|
||||||
@ -454,7 +460,10 @@ def get_deals_by_territory(from_date="", to_date="", user="", deal_conds=""):
|
|||||||
as_dict=True,
|
as_dict=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
return result or []
|
return {
|
||||||
|
"data": result or [],
|
||||||
|
"currency_symbol": get_base_currency_symbol(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -508,28 +517,29 @@ def get_forecasted_revenue(user="", deal_conds=""):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if user:
|
if user:
|
||||||
deal_conds += f" AND deal_owner = '{user}'"
|
deal_conds += f" AND d.deal_owner = '{user}'"
|
||||||
|
|
||||||
result = frappe.db.sql(
|
result = frappe.db.sql(
|
||||||
f"""
|
f"""
|
||||||
SELECT
|
SELECT
|
||||||
DATE_FORMAT(close_date, '%Y-%m') AS month,
|
DATE_FORMAT(d.close_date, '%Y-%m') AS month,
|
||||||
SUM(
|
SUM(
|
||||||
CASE
|
CASE
|
||||||
WHEN status = 'Lost' THEN deal_value
|
WHEN d.status = 'Lost' THEN d.deal_value * IFNULL(e.exchange_rate, 1)
|
||||||
ELSE deal_value * IFNULL(probability, 0) / 100 -- forecasted
|
ELSE d.deal_value * IFNULL(d.probability, 0) / 100 * IFNULL(e.exchange_rate, 1) -- forecasted
|
||||||
END
|
END
|
||||||
) AS forecasted,
|
) AS forecasted,
|
||||||
SUM(
|
SUM(
|
||||||
CASE
|
CASE
|
||||||
WHEN status = 'Won' THEN deal_value -- actual
|
WHEN d.status = 'Won' THEN d.deal_value * IFNULL(e.exchange_rate, 1) -- actual
|
||||||
ELSE 0
|
ELSE 0
|
||||||
END
|
END
|
||||||
) AS actual
|
) AS actual
|
||||||
FROM `tabCRM Deal`
|
FROM `tabCRM Deal` AS d
|
||||||
WHERE close_date >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
|
LEFT JOIN `tabCRM Currency Exchange` AS e ON d.currency_exchange = e.name
|
||||||
|
WHERE d.close_date >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH)
|
||||||
{deal_conds}
|
{deal_conds}
|
||||||
GROUP BY DATE_FORMAT(close_date, '%Y-%m')
|
GROUP BY DATE_FORMAT(d.close_date, '%Y-%m')
|
||||||
ORDER BY month
|
ORDER BY month
|
||||||
""",
|
""",
|
||||||
as_dict=True,
|
as_dict=True,
|
||||||
@ -541,7 +551,11 @@ def get_forecasted_revenue(user="", deal_conds=""):
|
|||||||
row["month"] = frappe.utils.get_datetime(row["month"]).strftime("%Y-%m-01")
|
row["month"] = frappe.utils.get_datetime(row["month"]).strftime("%Y-%m-01")
|
||||||
row["forecasted"] = row["forecasted"] or ""
|
row["forecasted"] = row["forecasted"] or ""
|
||||||
row["actual"] = row["actual"] or ""
|
row["actual"] = row["actual"] or ""
|
||||||
return result or []
|
|
||||||
|
return {
|
||||||
|
"data": result or [],
|
||||||
|
"currency_symbol": get_base_currency_symbol(),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
@ -675,3 +689,11 @@ def get_leads_by_source(from_date="", to_date="", user="", lead_conds=""):
|
|||||||
)
|
)
|
||||||
|
|
||||||
return result or []
|
return result or []
|
||||||
|
|
||||||
|
|
||||||
|
def get_base_currency_symbol():
|
||||||
|
"""
|
||||||
|
Get the base currency symbol from the system settings.
|
||||||
|
"""
|
||||||
|
base_currency = frappe.db.get_single_value("System Settings", "currency") or "USD"
|
||||||
|
return frappe.db.get_value("Currency", base_currency, "symbol") or ""
|
||||||
|
|||||||
@ -331,9 +331,9 @@ const dealsBySalesperson = createResource({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
auto: true,
|
auto: true,
|
||||||
transform(data = []) {
|
transform(r = { data: [], currency_symbol: '$' }) {
|
||||||
return {
|
return {
|
||||||
data: data,
|
data: r.data || [],
|
||||||
title: __('Deals by Salesperson'),
|
title: __('Deals by Salesperson'),
|
||||||
subtitle: 'Number of deals and total value per salesperson',
|
subtitle: 'Number of deals and total value per salesperson',
|
||||||
xAxis: {
|
xAxis: {
|
||||||
@ -345,7 +345,7 @@ const dealsBySalesperson = createResource({
|
|||||||
title: __('Number of Deals'),
|
title: __('Number of Deals'),
|
||||||
},
|
},
|
||||||
y2Axis: {
|
y2Axis: {
|
||||||
title: __('Deal Value ($)'),
|
title: __('Deal Value') + ` (${r.currency_symbol})`,
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{ name: 'deals', type: 'bar' as const },
|
{ name: 'deals', type: 'bar' as const },
|
||||||
@ -371,9 +371,9 @@ const dealsByTerritory = createResource({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
auto: true,
|
auto: true,
|
||||||
transform(data = []) {
|
transform(r = { data: [], currency_symbol: '$' }) {
|
||||||
return {
|
return {
|
||||||
data: data,
|
data: r.data || [],
|
||||||
title: __('Deals by Territory'),
|
title: __('Deals by Territory'),
|
||||||
subtitle: __('Geographic distribution of deals and revenue'),
|
subtitle: __('Geographic distribution of deals and revenue'),
|
||||||
xAxis: {
|
xAxis: {
|
||||||
@ -385,7 +385,7 @@ const dealsByTerritory = createResource({
|
|||||||
title: __('Number of Deals'),
|
title: __('Number of Deals'),
|
||||||
},
|
},
|
||||||
y2Axis: {
|
y2Axis: {
|
||||||
title: __('Deal Value ($)'),
|
title: __('Deal Value') + ` (${r.currency_symbol})`,
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{ name: 'deals', type: 'bar' as const },
|
{ name: 'deals', type: 'bar' as const },
|
||||||
@ -437,9 +437,9 @@ const forecastedRevenue = createResource({
|
|||||||
return { user: filters.user }
|
return { user: filters.user }
|
||||||
},
|
},
|
||||||
auto: true,
|
auto: true,
|
||||||
transform(data = []) {
|
transform(r = { data: [], currency_symbol: '$' }) {
|
||||||
return {
|
return {
|
||||||
data: data,
|
data: r.data || [],
|
||||||
title: __('Revenue Forecast'),
|
title: __('Revenue Forecast'),
|
||||||
subtitle: __('Projected vs actual revenue based on deal probability'),
|
subtitle: __('Projected vs actual revenue based on deal probability'),
|
||||||
xAxis: {
|
xAxis: {
|
||||||
@ -449,7 +449,7 @@ const forecastedRevenue = createResource({
|
|||||||
timeGrain: 'month' as const,
|
timeGrain: 'month' as const,
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
title: __('Revenue ($)'),
|
title: __('Revenue') + ` (${r.currency_symbol})`,
|
||||||
},
|
},
|
||||||
series: [
|
series: [
|
||||||
{ name: 'forecasted', type: 'line' as const, showDataPoints: true },
|
{ name: 'forecasted', type: 'line' as const, showDataPoints: true },
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user