Browse Source

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>
develop
Deepesh Garg 5 years ago
committed by GitHub
parent
commit
433e58d131
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 55
      erpnext/accounts/report/balance_sheet/balance_sheet.py
  2. 5
      erpnext/accounts/report/cash_flow/cash_flow.js
  3. 30
      erpnext/accounts/report/cash_flow/cash_flow.py
  4. 14
      erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
  5. 32
      erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py
  6. 4
      erpnext/accounts/report/financial_statements.py
  7. 5
      erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js
  8. 30
      erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py

55
erpnext/accounts/report/balance_sheet/balance_sheet.py

@ -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:]]

5
erpnext/accounts/report/cash_flow/cash_flow.js

@ -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"),

30
erpnext/accounts/report/cash_flow/cash_flow.py

@ -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')]

14
erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js

@ -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;
}
}

32
erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.py

@ -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 = {}

4
erpnext/accounts/report/financial_statements.py

@ -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:

5
erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js

@ -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"),

30
erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py

@ -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…
Cancel
Save