mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-19 04:59:18 +00:00
refactor: optimize budget variance report queries
This commit is contained in:
@@ -191,12 +191,10 @@ def build_report_data(budget_map, filters):
|
|||||||
data = []
|
data = []
|
||||||
|
|
||||||
show_cumulative = filters.get("show_cumulative") and filters.get("period") != "Yearly"
|
show_cumulative = filters.get("show_cumulative") and filters.get("period") != "Yearly"
|
||||||
|
periods = get_periods(filters)
|
||||||
fiscal_years = get_fiscal_years(filters)
|
|
||||||
group_months = filters["period"] != "Monthly"
|
|
||||||
|
|
||||||
for dimension, accounts in budget_map.items():
|
for dimension, accounts in budget_map.items():
|
||||||
for account in accounts:
|
for account, fiscal_year_map in accounts.items():
|
||||||
row = {
|
row = {
|
||||||
"budget_against": dimension,
|
"budget_against": dimension,
|
||||||
"account": account,
|
"account": account,
|
||||||
@@ -204,52 +202,48 @@ def build_report_data(budget_map, filters):
|
|||||||
|
|
||||||
running_budget = 0
|
running_budget = 0
|
||||||
running_actual = 0
|
running_actual = 0
|
||||||
|
|
||||||
total_budget = 0
|
total_budget = 0
|
||||||
total_actual = 0
|
total_actual = 0
|
||||||
|
|
||||||
for fy in fiscal_years:
|
for period in periods:
|
||||||
fiscal_year = fy[0]
|
fiscal_year = period["fiscal_year"]
|
||||||
|
months = get_months_between(period["from_date"], period["to_date"])
|
||||||
|
|
||||||
for from_date, to_date in get_period_date_ranges(filters["period"], fiscal_year):
|
period_budget = 0
|
||||||
months = get_months_between(from_date, to_date)
|
period_actual = 0
|
||||||
|
|
||||||
period_budget = 0
|
month_map = fiscal_year_map.get(fiscal_year, {})
|
||||||
period_actual = 0
|
|
||||||
|
|
||||||
for month in months:
|
for month in months:
|
||||||
budget_amount, actual_amount = get_budget_and_actual_values(
|
values = month_map.get(month)
|
||||||
budget_map, dimension, account, fiscal_year, month
|
if values:
|
||||||
)
|
period_budget += values.get("budget", 0)
|
||||||
period_budget += budget_amount
|
period_actual += values.get("actual", 0)
|
||||||
period_actual += actual_amount
|
|
||||||
|
|
||||||
if filters["period"] == "Yearly":
|
if show_cumulative:
|
||||||
budget_label = _("Budget") + " " + fiscal_year
|
running_budget += period_budget
|
||||||
actual_label = _("Actual") + " " + fiscal_year
|
running_actual += period_actual
|
||||||
variance_label = _("Variance") + " " + fiscal_year
|
display_budget = running_budget
|
||||||
else:
|
display_actual = running_actual
|
||||||
if group_months:
|
else:
|
||||||
label_suffix = formatdate(from_date, "MMM") + "-" + formatdate(to_date, "MMM")
|
display_budget = period_budget
|
||||||
else:
|
display_actual = period_actual
|
||||||
label_suffix = formatdate(from_date, "MMM")
|
|
||||||
|
|
||||||
budget_label = _("Budget") + f" ({label_suffix}) {fiscal_year}"
|
total_budget += period_budget
|
||||||
actual_label = _("Actual") + f" ({label_suffix}) {fiscal_year}"
|
total_actual += period_actual
|
||||||
variance_label = _("Variance") + f" ({label_suffix}) {fiscal_year}"
|
|
||||||
|
|
||||||
total_budget += period_budget
|
if filters["period"] == "Yearly":
|
||||||
total_actual += period_actual
|
budget_label = _("Budget") + " " + fiscal_year
|
||||||
|
actual_label = _("Actual") + " " + fiscal_year
|
||||||
|
variance_label = _("Variance") + " " + fiscal_year
|
||||||
|
else:
|
||||||
|
budget_label = _("Budget") + f" ({period['label_suffix']}) {fiscal_year}"
|
||||||
|
actual_label = _("Actual") + f" ({period['label_suffix']}) {fiscal_year}"
|
||||||
|
variance_label = _("Variance") + f" ({period['label_suffix']}) {fiscal_year}"
|
||||||
|
|
||||||
if show_cumulative:
|
row[frappe.scrub(budget_label)] = display_budget
|
||||||
running_budget += period_budget
|
row[frappe.scrub(actual_label)] = display_actual
|
||||||
running_actual += period_actual
|
row[frappe.scrub(variance_label)] = display_budget - display_actual
|
||||||
period_budget = running_budget
|
|
||||||
period_actual = running_actual
|
|
||||||
|
|
||||||
row[frappe.scrub(budget_label)] = period_budget
|
|
||||||
row[frappe.scrub(actual_label)] = period_actual
|
|
||||||
row[frappe.scrub(variance_label)] = period_budget - period_actual
|
|
||||||
|
|
||||||
if filters["period"] != "Yearly":
|
if filters["period"] != "Yearly":
|
||||||
row["total_budget"] = total_budget
|
row["total_budget"] = total_budget
|
||||||
@@ -261,6 +255,33 @@ def build_report_data(budget_map, filters):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def get_periods(filters):
|
||||||
|
periods = []
|
||||||
|
|
||||||
|
group_months = filters["period"] != "Monthly"
|
||||||
|
|
||||||
|
for (fiscal_year,) in get_fiscal_years(filters):
|
||||||
|
for from_date, to_date in get_period_date_ranges(filters["period"], fiscal_year):
|
||||||
|
if filters["period"] == "Yearly":
|
||||||
|
label_suffix = fiscal_year
|
||||||
|
else:
|
||||||
|
if group_months:
|
||||||
|
label_suffix = formatdate(from_date, "MMM") + "-" + formatdate(to_date, "MMM")
|
||||||
|
else:
|
||||||
|
label_suffix = formatdate(from_date, "MMM")
|
||||||
|
|
||||||
|
periods.append(
|
||||||
|
{
|
||||||
|
"fiscal_year": fiscal_year,
|
||||||
|
"from_date": from_date,
|
||||||
|
"to_date": to_date,
|
||||||
|
"label_suffix": label_suffix,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return periods
|
||||||
|
|
||||||
|
|
||||||
def get_months_between(from_date, to_date):
|
def get_months_between(from_date, to_date):
|
||||||
months = []
|
months = []
|
||||||
current = from_date
|
current = from_date
|
||||||
@@ -272,16 +293,6 @@ def get_months_between(from_date, to_date):
|
|||||||
return months
|
return months
|
||||||
|
|
||||||
|
|
||||||
def get_budget_and_actual_values(budget_map, dimension, account, fiscal_year, month):
|
|
||||||
try:
|
|
||||||
data = budget_map[dimension][account][fiscal_year].get(month)
|
|
||||||
if not data:
|
|
||||||
return 0, 0
|
|
||||||
return data.get("budget", 0), data.get("actual", 0)
|
|
||||||
except KeyError:
|
|
||||||
return 0, 0
|
|
||||||
|
|
||||||
|
|
||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
columns = [
|
columns = [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user