diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index f6968a1c3b5..01853a7246c 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -104,7 +104,7 @@ def get_label(periodicity, from_date, to_date): return label -def get_data(company, root_type, balance_must_be, period_list, +def get_data(company, root_type, balance_must_be, period_list, filters=None, accumulated_values=1, only_current_fiscal_year=True, ignore_closing_entries=False, ignore_accumulated_values_for_fy=False): accounts = get_accounts(company, root_type) @@ -122,7 +122,7 @@ def get_data(company, root_type, balance_must_be, period_list, set_gl_entries_by_account(company, period_list[0]["year_start_date"] if only_current_fiscal_year else None, period_list[-1]["to_date"], - root.lft, root.rgt, + root.lft, root.rgt, filters, gl_entries_by_account, ignore_closing_entries=ignore_closing_entries) calculate_values(accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy) @@ -288,16 +288,11 @@ def sort_root_accounts(roots): roots.sort(compare_roots) -def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, gl_entries_by_account, +def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, filters, gl_entries_by_account, ignore_closing_entries=False): """Returns a dict like { "account": [gl entries], ... }""" - additional_conditions = [] - 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") + additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters) gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening from `tabGL Entry` where company=%(company)s @@ -305,7 +300,7 @@ def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, g and posting_date <= %(to_date)s and account in (select name from `tabAccount` where lft >= %(lft)s and rgt <= %(rgt)s) - order by account, posting_date""".format(additional_conditions="\n".join(additional_conditions)), + order by account, posting_date""".format(additional_conditions=additional_conditions), { "company": company, "from_date": from_date, @@ -320,6 +315,22 @@ def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, g return gl_entries_by_account +def get_additional_conditions(from_date, ignore_closing_entries, filters): + additional_conditions = [] + + if ignore_closing_entries: + additional_conditions.append("ifnull(voucher_type, '')!='Period Closing Voucher'") + + if from_date: + additional_conditions.append("posting_date >= %(from_date)s") + + if filters: + for key in filters: + if filters.get(key) and key in ['cost_center', 'project']: + additional_conditions.append("%s = '%s'"%(key, filters.get(key))) + + return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else "" + def get_columns(periodicity, period_list, accumulated_values=1, company=None): columns = [{ "fieldname": "account", diff --git a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js index 0f7a6b6ef34..bcac2dffa43 100644 --- a/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js +++ b/erpnext/accounts/report/profit_and_loss_statement/profit_and_loss_statement.js @@ -5,9 +5,23 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { frappe.query_reports["Profit and Loss Statement"] = $.extend({}, erpnext.financial_statements); - frappe.query_reports["Profit and Loss Statement"]["filters"].push({ - "fieldname": "accumulated_values", - "label": __("Accumulated Values"), - "fieldtype": "Check" - }); + frappe.query_reports["Profit and Loss Statement"]["filters"].push( + { + "fieldname":"cost_center", + "label": __("Cost Center"), + "fieldtype": "Link", + "options": "Cost Center" + }, + { + "fieldname":"project", + "label": __("Project"), + "fieldtype": "Link", + "options": "Project" + }, + { + "fieldname": "accumulated_values", + "label": __("Accumulated Values"), + "fieldtype": "Check" + } + ); }); \ No newline at end of file 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 3629d4de76c..6b7f49041a6 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 @@ -10,9 +10,9 @@ from erpnext.accounts.report.financial_statements import (get_period_list, get_c def execute(filters=None): period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year, filters.periodicity) - income = get_data(filters.company, "Income", "Credit", period_list, + income = get_data(filters.company, "Income", "Credit", period_list, filters = filters, accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True) - expense = get_data(filters.company, "Expense", "Debit", period_list, + expense = get_data(filters.company, "Expense", "Debit", period_list, filters=filters, accumulated_values=filters.accumulated_values, ignore_closing_entries=True, ignore_accumulated_values_for_fy= True) net_profit_loss = get_net_profit_loss(income, expense, period_list, filters.company) diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js index 9c698f38d24..48924b5d916 100644 --- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.js +++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.js @@ -58,7 +58,45 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() { "fieldtype": "Check" } ], - "formatter": erpnext.financial_statements.formatter, + "formatter": function(row, cell, value, columnDef, dataContext, default_formatter) { + if (columnDef.df.fieldname=="account") { + value = dataContext.account_name; + + columnDef.df.link_onclick = + "frappe.query_reports['Profitability Analysis'].open_profit_and_loss_statement(" + JSON.stringify(dataContext) + ")"; + columnDef.df.is_tree = true; + } + + value = default_formatter(row, cell, value, columnDef, dataContext); + + if (!dataContext.parent_account && dataContext.based_on != 'project') { + var $value = $(value).css("font-weight", "bold"); + if (dataContext.warn_if_negative && dataContext[columnDef.df.fieldname] < 0) { + $value.addClass("text-danger"); + } + + value = $value.wrap("
").parent().html(); + } + + return value; + }, + "open_profit_and_loss_statement": function(data) { + if (!data.account) return; + + frappe.route_options = { + "company": frappe.query_report.filters_by_name.company.get_value(), + "from_fiscal_year": data.fiscal_year, + "to_fiscal_year": data.fiscal_year + }; + + if(data.based_on == 'cost_center'){ + frappe.route_options["cost_center"] = data.account + } else { + frappe.route_options["project"] = data.account + } + + frappe.set_route("query-report", "Profit and Loss Statement"); + }, "tree": true, "name_field": "account", "parent_field": "parent_account", diff --git a/erpnext/accounts/report/profitability_analysis/profitability_analysis.py b/erpnext/accounts/report/profitability_analysis/profitability_analysis.py index c81b4f264eb..7277dc2461d 100644 --- a/erpnext/accounts/report/profitability_analysis/profitability_analysis.py +++ b/erpnext/accounts/report/profitability_analysis/profitability_analysis.py @@ -39,7 +39,7 @@ def get_data(accounts, filters, based_on): total_row = calculate_values(accounts, gl_entries_by_account, filters) accumulate_values_into_parents(accounts, accounts_by_name) - data = prepare_data(accounts, filters, total_row, parent_children_map) + data = prepare_data(accounts, filters, total_row, parent_children_map, based_on) data = filter_out_zero_value_rows(data, parent_children_map, show_zero_values=filters.get("show_zero_values")) @@ -88,7 +88,7 @@ def accumulate_values_into_parents(accounts, accounts_by_name): for key in value_fields: accounts_by_name[d.parent_account][key] += d[key] -def prepare_data(accounts, filters, total_row, parent_children_map): +def prepare_data(accounts, filters, total_row, parent_children_map, based_on): data = [] company_currency = frappe.db.get_value("Company", filters.company, "default_currency") @@ -99,10 +99,9 @@ def prepare_data(accounts, filters, total_row, parent_children_map): "account": d.name, "parent_account": d.parent_account, "indent": d.indent, - "from_date": filters.from_date, - "to_date": filters.to_date, + "fiscal_year": filters.fiscal_year, "currency": company_currency, - "based_on": filters.based_on + "based_on": based_on } for key in value_fields: diff --git a/erpnext/accounts/report/trial_balance/trial_balance.py b/erpnext/accounts/report/trial_balance/trial_balance.py index a51e9b02eb5..5401902443c 100644 --- a/erpnext/accounts/report/trial_balance/trial_balance.py +++ b/erpnext/accounts/report/trial_balance/trial_balance.py @@ -65,7 +65,7 @@ def get_data(filters): gl_entries_by_account = {} set_gl_entries_by_account(filters.company, filters.from_date, - filters.to_date, min_lft, max_rgt, gl_entries_by_account, ignore_closing_entries=not flt(filters.with_period_closing_entry)) + filters.to_date, min_lft, max_rgt, filters, gl_entries_by_account, ignore_closing_entries=not flt(filters.with_period_closing_entry)) opening_balances = get_opening_balances(filters)