diff --git a/erpnext/accounts/report/balance_sheet/balance_sheet.py b/erpnext/accounts/report/balance_sheet/balance_sheet.py index 425257ffb5..4edc9b9515 100644 --- a/erpnext/accounts/report/balance_sheet/balance_sheet.py +++ b/erpnext/accounts/report/balance_sheet/balance_sheet.py @@ -3,19 +3,51 @@ from __future__ import unicode_literals import frappe +from frappe import _ +from frappe.utils import flt from erpnext.accounts.report.financial_statements import (process_filters, get_period_list, get_columns, get_data) def execute(filters=None): process_filters(filters) period_list = get_period_list(filters.fiscal_year, filters.periodicity, from_beginning=True) + asset = get_data(filters.company, "Asset", "Debit", period_list, filters.depth) + liability = get_data(filters.company, "Liability", "Credit", period_list, filters.depth) + equity = get_data(filters.company, "Equity", "Credit", period_list, filters.depth) + provisional_profit_loss = get_provisional_profit_loss(asset, liability, equity, period_list) + data = [] - for (root_type, balance_must_be) in (("Asset", "Debit"), ("Liability", "Credit"), ("Equity", "Credit")): - result = get_data(filters.company, root_type, balance_must_be, period_list, filters.depth) - data.extend(result or []) + data.extend(asset or []) + data.extend(liability or []) + data.extend(equity or []) + if provisional_profit_loss: + data.append(provisional_profit_loss) columns = get_columns(period_list) return columns, data +def get_provisional_profit_loss(asset, liability, equity, period_list): + if asset and (liability or equity): + provisional_profit_loss = { + "account_name": _("Provisional Profit / Loss (Credit)"), + "account": None, + "is_profit_loss": True + } + has_value = False + + for period in period_list: + effective_liability = 0.0 + if liability: + effective_liability += flt(liability[-2][period.key]) + if equity: + effective_liability += flt(equity[-2][period.key]) + + provisional_profit_loss[period.key] = flt(asset[-2][period.key]) - effective_liability + + if provisional_profit_loss[period.key]: + has_value = True + + if has_value: + return provisional_profit_loss diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 30650fff7d..45d5b3a737 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -5,7 +5,7 @@ from __future__ import unicode_literals import frappe from frappe import _, _dict from frappe.utils import (flt, cint, getdate, get_first_day, get_last_day, - add_months, add_days, now_datetime, formatdate) + add_months, add_days, formatdate) def process_filters(filters): filters.depth = cint(filters.depth) or 3 @@ -19,7 +19,6 @@ def get_period_list(fiscal_year, periodicity, from_beginning=False): start_date, end_date = frappe.db.get_value("Fiscal Year", fiscal_year, ["year_start_date", "year_end_date"]) start_date = getdate(start_date) end_date = getdate(end_date) - today = now_datetime().date() if periodicity == "Yearly": period_list = [_dict({"to_date": end_date, "key": fiscal_year, "label": fiscal_year})] @@ -45,18 +44,9 @@ def get_period_list(fiscal_year, periodicity, from_beginning=False): # to_date should be the last day of the new to_date's month to_date = get_last_day(to_date) - if to_date > today: - # checking in the middle of the currenct fiscal year? don't show future periods - key = today.strftime("%b_%Y").lower() - label = formatdate(today, "MMM YYYY") - period_list.append(_dict({"to_date": today, "key": key, "label": label})) - break - - elif to_date <= end_date: + if to_date <= end_date: # the normal case - key = to_date.strftime("%b_%Y").lower() - label = formatdate(to_date, "MMM YYYY") - period_list.append(_dict({"to_date": to_date, "key": key, "label": label})) + period_list.append(_dict({ "to_date": to_date })) # if it ends before a full year if to_date == end_date: @@ -64,14 +54,19 @@ def get_period_list(fiscal_year, periodicity, from_beginning=False): else: # if a fiscal year ends before a 12 month period - key = end_date.strftime("%b_%Y").lower() - label = formatdate(end_date, "MMM YYYY") - period_list.append(_dict({"to_date": end_date, "key": key, "label": label})) + period_list.append(_dict({ "to_date": end_date })) break # common processing for opts in period_list: - opts["key"] = opts["key"].replace(" ", "_").replace("-", "_") + key = opts["to_date"].strftime("%b_%Y").lower() + label = formatdate(opts["to_date"], "MMM YYYY") + opts.update({ + "key": key.replace(" ", "_").replace("-", "_"), + "label": label, + "year_start_date": start_date, + "year_end_date": end_date + }) if from_beginning: # set start date as None for all fiscal periods, used in case of Balance Sheet @@ -81,14 +76,14 @@ def get_period_list(fiscal_year, periodicity, from_beginning=False): return period_list -def get_data(company, root_type, balance_must_be, period_list, depth, ignore_opening_and_closing_entries=False): +def get_data(company, root_type, balance_must_be, period_list, depth, ignore_closing_entries=False): accounts = get_accounts(company, root_type) if not accounts: return None accounts, accounts_by_name = filter_accounts(accounts, depth) gl_entries_by_account = get_gl_entries(company, root_type, period_list[0]["from_date"], period_list[-1]["to_date"], - accounts[0].lft, accounts[0].rgt, ignore_opening_and_closing_entries=ignore_opening_and_closing_entries) + accounts[0].lft, accounts[0].rgt, ignore_closing_entries=ignore_closing_entries) calculate_values(accounts, gl_entries_by_account, period_list) accumulate_values_into_parents(accounts, accounts_by_name, period_list) @@ -121,6 +116,9 @@ def accumulate_values_into_parents(accounts, accounts_by_name, period_list): def prepare_data(accounts, balance_must_be, period_list): out = [] + year_start_date = period_list[0]["year_start_date"].strftime("%Y-%m-%d") + year_end_date = period_list[-1]["year_end_date"].strftime("%Y-%m-%d") + for d in accounts: # add to output has_value = False @@ -128,7 +126,9 @@ def prepare_data(accounts, balance_must_be, period_list): "account_name": d.account_name, "account": d.name, "parent_account": d.parent_account, - "indent": flt(d.indent) + "indent": flt(d.indent), + "year_start_date": year_start_date, + "year_end_date": year_end_date } for period in period_list: if d.get(period.key): @@ -204,12 +204,12 @@ def filter_accounts(accounts, depth): return filtered_accounts, accounts_by_name -def get_gl_entries(company, root_type, from_date, to_date, root_lft, root_rgt, ignore_opening_and_closing_entries=False): +def get_gl_entries(company, root_type, from_date, to_date, root_lft, root_rgt, ignore_closing_entries=False): """Returns a dict like { "account": [gl entries], ... }""" additional_conditions = [] - if ignore_opening_and_closing_entries: - additional_conditions.append("and ifnull(is_opening, 'No')='No' and ifnull(voucher_type, '')!='Period Closing Voucher'") + if ignore_closing_entries: + additional_conditions.append("and ifnull(voucher_type, '')!='Period Closing Voucher'") if from_date: additional_conditions.append("and posting_date >= %(from_date)s") diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py index 9886f2f497..3a3123fc36 100644 --- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py +++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.py @@ -11,30 +11,29 @@ def execute(filters=None): process_filters(filters) period_list = get_period_list(filters.fiscal_year, filters.periodicity) - data = [] - income = get_data(filters.company, "Income", "Credit", period_list, filters.depth, - ignore_opening_and_closing_entries=True) - expense = get_data(filters.company, "Expense", "Debit", period_list, filters.depth, - ignore_opening_and_closing_entries=True) - net_total = get_net_total(income, expense, period_list) + income = get_data(filters.company, "Income", "Credit", period_list, filters.depth, ignore_closing_entries=True) + expense = get_data(filters.company, "Expense", "Debit", period_list, filters.depth, ignore_closing_entries=True) + net_profit_loss = get_net_profit_loss(income, expense, period_list) + data = [] data.extend(income or []) data.extend(expense or []) - if net_total: - data.append(net_total) + if net_profit_loss: + data.append(net_profit_loss) columns = get_columns(period_list) return columns, data -def get_net_total(income, expense, period_list): +def get_net_profit_loss(income, expense, period_list): if income and expense: - net_total = { + net_profit_loss = { "account_name": _("Net Profit / Loss"), - "account": None + "account": None, + "is_profit_loss": True } for period in period_list: - net_total[period.key] = flt(income[-2][period.key] - expense[-2][period.key], 3) + net_profit_loss[period.key] = flt(income[-2][period.key] - expense[-2][period.key], 3) - return net_total + return net_profit_loss diff --git a/erpnext/public/js/financial_statements.js b/erpnext/public/js/financial_statements.js index dbe41ff345..5e3ba0e116 100644 --- a/erpnext/public/js/financial_statements.js +++ b/erpnext/public/js/financial_statements.js @@ -38,7 +38,7 @@ erpnext.financial_statements = { if (columnDef.df.fieldname=="account") { var link = $("") .text(dataContext.account_name) - .attr("onclick", 'erpnext.financial_statements.open_general_ledger("' + dataContext.account + '")'); + .attr("onclick", "erpnext.financial_statements.open_general_ledger(" + JSON.stringify(dataContext) + ")"); var span = $("") .css("padding-left", (cint(dataContext.indent) * 21) + "px") @@ -51,17 +51,24 @@ erpnext.financial_statements = { } if (!dataContext.parent_account) { - value = $(value).css("font-weight", "bold").wrap("

").parent().html(); + var $value = $(value).css("font-weight", "bold"); + if (dataContext.is_profit_loss && dataContext[columnDef.df.fieldname] < 0) { + $value.addClass("text-danger"); + } + + value = $value.wrap("

").parent().html(); } return value; }, - "open_general_ledger": function(account) { - if (!account) return; + "open_general_ledger": function(data) { + if (!data.account) return; frappe.route_options = { - "account": account, - "company": frappe.query_report.filters_by_name.company.get_value() + "account": data.account, + "company": frappe.query_report.filters_by_name.company.get_value(), + "from_date": data.year_start_date, + "to_date": data.year_end_date }; frappe.set_route("query-report", "General Ledger"); }