feat: Add report summary in financial statements (#20876)
* feat: Add report summary API for Balance Sheet and PL report * fix: Add summary cards in Cash flow report * feat: Add report summary in consolidated financial statements * fix: Remove accumulated values filter from P&L and cashflow report * fix: set company default currency in profit and loss statement if no data Co-authored-by: Prssanna Desai <prssud@gmail.com>
This commit is contained in:
parent
c01ec7606d
commit
433e58d131
@ -58,7 +58,10 @@ def execute(filters=None):
|
||||
|
||||
chart = get_chart_data(filters, columns, asset, liability, equity)
|
||||
|
||||
return columns, data, message, chart
|
||||
report_summary = get_report_summary(period_list, asset, liability, equity, provisional_profit_loss,
|
||||
total_credit, currency, filters)
|
||||
|
||||
return columns, data, message, chart, report_summary
|
||||
|
||||
def get_provisional_profit_loss(asset, liability, equity, period_list, company, currency=None, consolidated=False):
|
||||
provisional_profit_loss = {}
|
||||
@ -120,6 +123,56 @@ def check_opening_balance(asset, liability, equity):
|
||||
return _("Previous Financial Year is not closed"),opening_balance
|
||||
return None,None
|
||||
|
||||
def get_report_summary(period_list, asset, liability, equity, provisional_profit_loss, total_credit, currency,
|
||||
filters, consolidated=False):
|
||||
|
||||
net_asset, net_liability, net_equity, net_provisional_profit_loss = 0.0, 0.0, 0.0, 0.0
|
||||
|
||||
if filters.get('accumulated_values'):
|
||||
period_list = [period_list[-1]]
|
||||
|
||||
for period in period_list:
|
||||
key = period if consolidated else period.key
|
||||
if asset:
|
||||
net_asset += asset[-2].get(key)
|
||||
if liability:
|
||||
net_liability += liability[-2].get(key)
|
||||
if equity:
|
||||
net_equity += equity[-2].get(key)
|
||||
if provisional_profit_loss:
|
||||
net_provisional_profit_loss += provisional_profit_loss.get(key)
|
||||
|
||||
return [
|
||||
{
|
||||
"value": net_asset,
|
||||
"label": "Total Asset",
|
||||
"indicator": "Green",
|
||||
"datatype": "Currency",
|
||||
"currency": currency
|
||||
},
|
||||
{
|
||||
"value": net_liability,
|
||||
"label": "Total Liability",
|
||||
"datatype": "Currency",
|
||||
"indicator": "Red",
|
||||
"currency": currency
|
||||
},
|
||||
{
|
||||
"value": net_equity,
|
||||
"label": "Total Equity",
|
||||
"datatype": "Currency",
|
||||
"indicator": "Blue",
|
||||
"currency": currency
|
||||
},
|
||||
{
|
||||
"value": net_provisional_profit_loss,
|
||||
"label": "Provisional Profit / Loss (Credit)",
|
||||
"indicator": "Green" if net_provisional_profit_loss > 0 else "Red",
|
||||
"datatype": "Currency",
|
||||
"currency": currency
|
||||
}
|
||||
]
|
||||
|
||||
def get_chart_data(filters, columns, asset, liability, equity):
|
||||
labels = [d.get("label") for d in columns[2:]]
|
||||
|
||||
|
@ -12,11 +12,6 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||
frappe.query_reports["Cash Flow"]["filters"].splice(5, 1);
|
||||
|
||||
frappe.query_reports["Cash Flow"]["filters"].push(
|
||||
{
|
||||
"fieldname": "accumulated_values",
|
||||
"label": __("Accumulated Values"),
|
||||
"fieldtype": "Check"
|
||||
},
|
||||
{
|
||||
"fieldname": "include_default_book_entries",
|
||||
"label": __("Include Default Book Entries"),
|
||||
|
@ -8,6 +8,7 @@ from frappe.utils import cint, cstr
|
||||
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
||||
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import get_net_profit_loss
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from six import iteritems
|
||||
|
||||
|
||||
def execute(filters=None):
|
||||
@ -29,6 +30,7 @@ def execute(filters=None):
|
||||
net_profit_loss = get_net_profit_loss(income, expense, period_list, filters.company)
|
||||
|
||||
data = []
|
||||
summary_data = {}
|
||||
company_currency = frappe.get_cached_value('Company', filters.company, "default_currency")
|
||||
|
||||
for cash_flow_account in cash_flow_accounts:
|
||||
@ -64,14 +66,16 @@ def execute(filters=None):
|
||||
section_data.append(account_data)
|
||||
|
||||
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
|
||||
period_list, company_currency)
|
||||
period_list, company_currency, summary_data)
|
||||
|
||||
add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency)
|
||||
add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency, summary_data)
|
||||
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company)
|
||||
|
||||
chart = get_chart_data(columns, data)
|
||||
|
||||
return columns, data, None, chart
|
||||
report_summary = get_report_summary(summary_data, company_currency)
|
||||
|
||||
return columns, data, None, chart, report_summary
|
||||
|
||||
def get_cash_flow_accounts():
|
||||
operation_accounts = {
|
||||
@ -157,7 +161,7 @@ def get_start_date(period, accumulated_values, company):
|
||||
|
||||
return start_date
|
||||
|
||||
def add_total_row_account(out, data, label, period_list, currency, consolidated = False):
|
||||
def add_total_row_account(out, data, label, period_list, currency, summary_data, consolidated = False):
|
||||
total_row = {
|
||||
"account_name": "'" + _("{0}").format(label) + "'",
|
||||
"account": "'" + _("{0}").format(label) + "'",
|
||||
@ -176,6 +180,24 @@ def add_total_row_account(out, data, label, period_list, currency, consolidated
|
||||
out.append(total_row)
|
||||
out.append({})
|
||||
|
||||
summary_data[label] = total_row["total"]
|
||||
|
||||
def get_report_summary(summary_data, currency):
|
||||
report_summary = []
|
||||
|
||||
for label, value in iteritems(summary_data):
|
||||
report_summary.append(
|
||||
{
|
||||
"value": value,
|
||||
"label": label,
|
||||
"datatype": "Currency",
|
||||
"currency": currency
|
||||
}
|
||||
)
|
||||
|
||||
return report_summary
|
||||
|
||||
|
||||
def get_chart_data(columns, data):
|
||||
labels = [d.get("label") for d in columns[2:]]
|
||||
datasets = [{'name':account.get('account').replace("'", ""), 'values': [account.get('total')]} for account in data if account.get('parent_account') == None and account.get('currency')]
|
||||
|
@ -61,5 +61,17 @@ frappe.query_reports["Consolidated Financial Statement"] = {
|
||||
"fieldtype": "Check",
|
||||
"default": 1
|
||||
}
|
||||
]
|
||||
],
|
||||
"formatter": function(value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
|
||||
if (!data.parent_account) {
|
||||
value = $(`<span>${value}</span>`);
|
||||
|
||||
var $value = $(value).css("font-weight", "bold");
|
||||
|
||||
value = $value.wrap("<p></p>").parent().html();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
@ -8,11 +8,11 @@ from frappe.utils import flt, cint
|
||||
from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency
|
||||
from erpnext.accounts.report.financial_statements import get_fiscal_year_data, sort_accounts
|
||||
from erpnext.accounts.report.balance_sheet.balance_sheet import (get_provisional_profit_loss,
|
||||
check_opening_balance, get_chart_data)
|
||||
check_opening_balance, get_chart_data, get_report_summary as get_bs_summary)
|
||||
from erpnext.accounts.report.profit_and_loss_statement.profit_and_loss_statement import (get_net_profit_loss,
|
||||
get_chart_data as get_pl_chart_data)
|
||||
get_chart_data as get_pl_chart_data, get_report_summary as get_pl_summary)
|
||||
from erpnext.accounts.report.cash_flow.cash_flow import (get_cash_flow_accounts, get_account_type_based_gl_data,
|
||||
add_total_row_account)
|
||||
add_total_row_account, get_report_summary as get_cash_flow_summary)
|
||||
|
||||
def execute(filters=None):
|
||||
columns, data, message, chart = [], [], [], []
|
||||
@ -25,17 +25,17 @@ def execute(filters=None):
|
||||
columns = get_columns(companies_column)
|
||||
|
||||
if filters.get('report') == "Balance Sheet":
|
||||
data, message, chart = get_balance_sheet_data(fiscal_year, companies, columns, filters)
|
||||
data, message, chart, report_summary = get_balance_sheet_data(fiscal_year, companies, columns, filters)
|
||||
elif filters.get('report') == "Profit and Loss Statement":
|
||||
data, message, chart = get_profit_loss_data(fiscal_year, companies, columns, filters)
|
||||
data, message, chart, report_summary = get_profit_loss_data(fiscal_year, companies, columns, filters)
|
||||
else:
|
||||
if cint(frappe.db.get_single_value('Accounts Settings', 'use_custom_cash_flow')):
|
||||
from erpnext.accounts.report.cash_flow.custom_cash_flow import execute as execute_custom
|
||||
return execute_custom(filters=filters)
|
||||
|
||||
data = get_cash_flow_data(fiscal_year, companies, filters)
|
||||
data, report_summary = get_cash_flow_data(fiscal_year, companies, filters)
|
||||
|
||||
return columns, data, message, chart
|
||||
return columns, data, message, chart, report_summary
|
||||
|
||||
def get_balance_sheet_data(fiscal_year, companies, columns, filters):
|
||||
asset = get_data(companies, "Asset", "Debit", fiscal_year, filters=filters)
|
||||
@ -75,9 +75,12 @@ def get_balance_sheet_data(fiscal_year, companies, columns, filters):
|
||||
if total_credit:
|
||||
data.append(total_credit)
|
||||
|
||||
report_summary = get_bs_summary(companies, asset, liability, equity, provisional_profit_loss, total_credit,
|
||||
company_currency, filters, True)
|
||||
|
||||
chart = get_chart_data(filters, columns, asset, liability, equity)
|
||||
|
||||
return data, message, chart
|
||||
return data, message, chart, report_summary
|
||||
|
||||
def get_profit_loss_data(fiscal_year, companies, columns, filters):
|
||||
income, expense, net_profit_loss = get_income_expense_data(companies, fiscal_year, filters)
|
||||
@ -90,7 +93,9 @@ def get_profit_loss_data(fiscal_year, companies, columns, filters):
|
||||
|
||||
chart = get_pl_chart_data(filters, columns, income, expense, net_profit_loss)
|
||||
|
||||
return data, None, chart
|
||||
report_summary = get_pl_summary(companies, '', income, expense, net_profit_loss, True)
|
||||
|
||||
return data, None, chart, report_summary
|
||||
|
||||
def get_income_expense_data(companies, fiscal_year, filters):
|
||||
company_currency = get_company_currency(filters)
|
||||
@ -108,6 +113,7 @@ def get_cash_flow_data(fiscal_year, companies, filters):
|
||||
income, expense, net_profit_loss = get_income_expense_data(companies, fiscal_year, filters)
|
||||
|
||||
data = []
|
||||
summary_data = {}
|
||||
company_currency = get_company_currency(filters)
|
||||
|
||||
for cash_flow_account in cash_flow_accounts:
|
||||
@ -142,11 +148,13 @@ def get_cash_flow_data(fiscal_year, companies, filters):
|
||||
section_data.append(account_data)
|
||||
|
||||
add_total_row_account(data, section_data, cash_flow_account['section_footer'],
|
||||
companies, company_currency, True)
|
||||
companies, company_currency, summary_data, True)
|
||||
|
||||
add_total_row_account(data, data, _("Net Change in Cash"), companies, company_currency, True)
|
||||
add_total_row_account(data, data, _("Net Change in Cash"), companies, company_currency, summary_data, True)
|
||||
|
||||
return data
|
||||
report_summary = get_cash_flow_summary(summary_data, company_currency)
|
||||
|
||||
return data, report_summary
|
||||
|
||||
def get_account_type_based_data(account_type, companies, fiscal_year, filters):
|
||||
data = {}
|
||||
|
@ -151,7 +151,7 @@ def get_data(
|
||||
|
||||
calculate_values(
|
||||
accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy)
|
||||
accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values)
|
||||
accumulate_values_into_parents(accounts, accounts_by_name, period_list)
|
||||
out = prepare_data(accounts, balance_must_be, period_list, company_currency)
|
||||
out = filter_out_zero_value_rows(out, parent_children_map)
|
||||
|
||||
@ -191,7 +191,7 @@ def calculate_values(
|
||||
d["opening_balance"] = d.get("opening_balance", 0.0) + flt(entry.debit) - flt(entry.credit)
|
||||
|
||||
|
||||
def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accumulated_values):
|
||||
def accumulate_values_into_parents(accounts, accounts_by_name, period_list):
|
||||
"""accumulate children's values in parent accounts"""
|
||||
for d in reversed(accounts):
|
||||
if d.parent_account:
|
||||
|
@ -15,11 +15,6 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
|
||||
return frappe.db.get_link_options('Project', txt);
|
||||
}
|
||||
},
|
||||
{
|
||||
"fieldname": "accumulated_values",
|
||||
"label": __("Accumulated Values"),
|
||||
"fieldtype": "Check"
|
||||
},
|
||||
{
|
||||
"fieldname": "include_default_book_entries",
|
||||
"label": __("Include Default Book Entries"),
|
||||
|
@ -31,20 +31,22 @@ def execute(filters=None):
|
||||
|
||||
chart = get_chart_data(filters, columns, income, expense, net_profit_loss)
|
||||
|
||||
report_summary = get_report_summary(columns, income, expense, net_profit_loss, filters.periodicity, period_list)
|
||||
default_currency = frappe.get_cached_value('Company', filters.company, "default_currency")
|
||||
report_summary = get_report_summary(period_list, filters.periodicity, income, expense, net_profit_loss, default_currency)
|
||||
|
||||
return columns, data, None, chart, report_summary
|
||||
|
||||
def get_report_summary(columns, income, expense, net_profit_loss, period_list, periodicity):
|
||||
income_data, expense_data, net_profit = [], [], []
|
||||
def get_report_summary(period_list, periodicity, income, expense, net_profit_loss, default_currency, consolidated=False):
|
||||
net_income, net_expense, net_profit = 0.0, 0.0, 0.0
|
||||
|
||||
for p in columns[2:]:
|
||||
for period in period_list:
|
||||
key = period if consolidated else period.key
|
||||
if income:
|
||||
income_data.append(income[-2].get(p.get("fieldname")))
|
||||
net_income += income[-2].get(key)
|
||||
if expense:
|
||||
expense_data.append(expense[-2].get(p.get("fieldname")))
|
||||
net_expense += expense[-2].get(key)
|
||||
if net_profit_loss:
|
||||
net_profit.append(net_profit_loss.get(p.get("fieldname")))
|
||||
net_profit += net_profit_loss.get(key)
|
||||
|
||||
if (len(period_list) == 1 and periodicity== 'Yearly'):
|
||||
profit_label = _("Profit This Year")
|
||||
@ -57,23 +59,23 @@ def get_report_summary(columns, income, expense, net_profit_loss, period_list, p
|
||||
|
||||
return [
|
||||
{
|
||||
"value": net_profit[-1],
|
||||
"indicator": "Green" if net_profit[-1] > 0 else "Red",
|
||||
"value": net_profit,
|
||||
"indicator": "Green" if net_profit > 0 else "Red",
|
||||
"label": profit_label,
|
||||
"datatype": "Currency",
|
||||
"currency": net_profit_loss.get("currency")
|
||||
"currency": net_profit_loss.get("currency") if net_profit_loss else default_currency
|
||||
},
|
||||
{
|
||||
"value": income_data[-1],
|
||||
"value": net_income,
|
||||
"label": income_label,
|
||||
"datatype": "Currency",
|
||||
"currency": income[-1].get('currency')
|
||||
"currency": income[-1].get('currency') if income else default_currency
|
||||
},
|
||||
{
|
||||
"value": expense_data[-1],
|
||||
"value": net_expense,
|
||||
"label": expense_label,
|
||||
"datatype": "Currency",
|
||||
"currency": expense[-1].get('currency')
|
||||
"currency": expense[-1].get('currency') if expense else default_currency
|
||||
}
|
||||
]
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user