diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 1734418e4d1..043f700a886 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -2,14 +2,14 @@ # License: GNU General Public License v3. See license.txt from __future__ import unicode_literals -import frappe + import re +import frappe from erpnext.accounts.report.utils import get_currency, convert_to_presentation_currency -from frappe import _ -from frappe.utils import (flt, getdate, get_first_day, get_last_day, date_diff, - add_months, add_days, formatdate, cint) from erpnext.accounts.utils import get_fiscal_year +from frappe import _ +from frappe.utils import (flt, getdate, get_first_day, add_months, add_days, formatdate) def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_values=False, @@ -86,6 +86,7 @@ def get_period_list(from_fiscal_year, to_fiscal_year, periodicity, accumulated_v return period_list + def get_fiscal_year_data(from_fiscal_year, to_fiscal_year): fiscal_year = frappe.db.sql("""select min(year_start_date) as year_start_date, max(year_end_date) as year_end_date from `tabFiscal Year` where @@ -94,16 +95,19 @@ def get_fiscal_year_data(from_fiscal_year, to_fiscal_year): return fiscal_year[0] if fiscal_year else {} + def validate_fiscal_year(fiscal_year, from_fiscal_year, to_fiscal_year): if not fiscal_year.get('year_start_date') and not fiscal_year.get('year_end_date'): frappe.throw(_("End Year cannot be before Start Year")) + def get_months(start_date, end_date): diff = (12 * end_date.year + end_date.month) - (12 * start_date.year + start_date.month) return diff + 1 + def get_label(periodicity, from_date, to_date): - if periodicity=="Yearly": + if periodicity == "Yearly": if formatdate(from_date, "YYYY") == formatdate(to_date, "YYYY"): label = formatdate(from_date, "YYYY") else: @@ -113,9 +117,12 @@ def get_label(periodicity, from_date, to_date): return label -def get_data(company, root_type, balance_must_be, period_list, filters=None, + +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) if not accounts: return None @@ -128,13 +135,16 @@ def get_data(company, root_type, balance_must_be, period_list, filters=None, for root in frappe.db.sql("""select lft, rgt from tabAccount where root_type=%s and ifnull(parent_account, '') = ''""", root_type, as_dict=1): - set_gl_entries_by_account(company, + 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, filters, - gl_entries_by_account, ignore_closing_entries=ignore_closing_entries) + 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) + 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) out = prepare_data(accounts, balance_must_be, period_list, company_currency) out = filter_out_zero_value_rows(out, parent_children_map) @@ -145,7 +155,8 @@ def get_data(company, root_type, balance_must_be, period_list, filters=None, return out -def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy): +def calculate_values( + accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy): for entries in gl_entries_by_account.values(): for entry in entries: d = accounts_by_name.get(entry.account) @@ -166,6 +177,7 @@ def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accum if entry.posting_date < period_list[0].year_start_date: 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): """accumulate children's values in parent accounts""" for d in reversed(accounts): @@ -177,6 +189,7 @@ def accumulate_values_into_parents(accounts, accounts_by_name, period_list, accu accounts_by_name[d.parent_account]["opening_balance"] = \ accounts_by_name[d.parent_account].get("opening_balance", 0.0) + d.get("opening_balance", 0.0) + def prepare_data(accounts, balance_must_be, period_list, company_currency): data = [] year_start_date = period_list[0]["year_start_date"].strftime("%Y-%m-%d") @@ -194,10 +207,10 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency): "year_start_date": year_start_date, "year_end_date": year_end_date, "currency": company_currency, - "opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be=="Debit" else -1) + "opening_balance": d.get("opening_balance", 0.0) * (1 if balance_must_be == "Debit" else -1) }) for period in period_list: - if d.get(period.key) and balance_must_be=="Credit": + if d.get(period.key) and balance_must_be == "Credit": # change sign based on Debit or Credit, since calculation is done using (debit - credit) d[period.key] *= -1 @@ -214,6 +227,7 @@ def prepare_data(accounts, balance_must_be, period_list, company_currency): return data + def filter_out_zero_value_rows(data, parent_children_map, show_zero_values=False): data_with_value = [] for d in data: @@ -230,6 +244,7 @@ def filter_out_zero_value_rows(data, parent_children_map, show_zero_values=False return data_with_value + def add_total_row(out, root_type, balance_must_be, period_list, company_currency): total_row = { "account_name": "'" + _("Total {0} ({1})").format(_(root_type), _(balance_must_be)) + "'", @@ -248,16 +263,19 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency total_row["total"] += flt(row["total"]) row["total"] = "" - if total_row.has_key("total"): + if "total" in total_row: out.append(total_row) # blank row after Total out.append({}) + def get_accounts(company, root_type): - return frappe.db.sql("""select name, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount` + return frappe.db.sql( + """select name, parent_account, lft, rgt, root_type, report_type, account_name from `tabAccount` where company=%s and root_type=%s order by lft""", (company, root_type), as_dict=True) + def filter_accounts(accounts, depth=10): parent_children_map = {} accounts_by_name = {} @@ -282,6 +300,7 @@ def filter_accounts(accounts, depth=10): return filtered_accounts, accounts_by_name, parent_children_map + def sort_root_accounts(roots): """Sort root types as Asset, Liability, Equity, Income, Expense""" @@ -301,8 +320,9 @@ def sort_root_accounts(roots): roots.sort(compare_roots) -def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, filters, gl_entries_by_account, - ignore_closing_entries=False): + +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 = get_additional_conditions(from_date, ignore_closing_entries, filters) @@ -331,6 +351,7 @@ def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, f return gl_entries_by_account + def get_additional_conditions(from_date, ignore_closing_entries, filters): additional_conditions = [] @@ -342,15 +363,17 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters): if filters: if filters.get("project"): - additional_conditions.append("project = '%s'"%(frappe.db.escape(filters.get("project")))) + additional_conditions.append("project = '%s'" % (frappe.db.escape(filters.get("project")))) if filters.get("cost_center"): additional_conditions.append(get_cost_center_cond(filters.get("cost_center"))) return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else "" + def get_cost_center_cond(cost_center): lft, rgt = frappe.db.get_value("Cost Center", cost_center, ["lft", "rgt"]) - return (""" cost_center in (select name from `tabCost Center` where lft >=%s and rgt <=%s)"""%(lft, rgt)) + return """ cost_center in (select name from `tabCost Center` where lft >=%s and rgt <=%s)""" % (lft, rgt) + def get_columns(periodicity, period_list, accumulated_values=1, company=None): columns = [{ diff --git a/erpnext/accounts/report/general_ledger/general_ledger.py b/erpnext/accounts/report/general_ledger/general_ledger.py index 4d41b23985d..532ed244dbc 100644 --- a/erpnext/accounts/report/general_ledger/general_ledger.py +++ b/erpnext/accounts/report/general_ledger/general_ledger.py @@ -36,6 +36,7 @@ def execute(filters=None): return columns, res + def validate_filters(filters, account_details): if not filters.get('company'): frappe.throw(_('{0} is mandatory').format(_('Company'))) @@ -44,7 +45,7 @@ def validate_filters(filters, account_details): frappe.throw(_("Account {0} does not exists").format(filters.account)) if filters.get("account") and filters.get("group_by_account") \ - and account_details[filters.account].is_group == 0: + and account_details[filters.account].is_group == 0: frappe.throw(_("Can not filter based on Account, if grouped by Account")) if filters.get("voucher_no") and filters.get("group_by_voucher"): @@ -63,6 +64,7 @@ def validate_party(filters): elif not frappe.db.exists(party_type, party): frappe.throw(_("Invalid {0}: {1}").format(party_type, party)) + def set_account_currency(filters): if not (filters.get("account") or filters.get("party")): return filters @@ -73,8 +75,13 @@ def set_account_currency(filters): if filters.get("account"): account_currency = get_account_currency(filters.account) elif filters.get("party"): - gle_currency = frappe.db.get_value("GL Entry", {"party_type": filters.party_type, - "party": filters.party, "company": filters.company}, "account_currency") + gle_currency = frappe.db.get_value( + "GL Entry", { + "party_type": filters.party_type, "party": filters.party, "company": filters.company + }, + "account_currency" + ) + if gle_currency: account_currency = gle_currency else: @@ -88,6 +95,7 @@ def set_account_currency(filters): return filters + def get_columns(filters): if filters.get("presentation_currency"): currency = filters["presentation_currency"] @@ -120,6 +128,7 @@ def get_columns(filters): return columns + def get_result(filters, account_details): gl_entries = get_gl_entries(filters) @@ -139,7 +148,8 @@ def get_gl_entries(filters): group_by_condition = "group by voucher_type, voucher_no, account, cost_center" \ if filters.get("group_by_voucher") else "group by name" - gl_entries = frappe.db.sql(""" + gl_entries = frappe.db.sql( + """ select posting_date, account, party_type, party, sum(debit) as debit, sum(credit) as credit, @@ -149,9 +159,12 @@ def get_gl_entries(filters): from `tabGL Entry` where company=%(company)s {conditions} {group_by_condition} - order by posting_date, account"""\ - .format(select_fields=select_fields, conditions=get_conditions(filters), - group_by_condition=group_by_condition), filters, as_dict=1) + order by posting_date, account + """.format( + select_fields=select_fields, conditions=get_conditions(filters), + group_by_condition=group_by_condition + ), + filters, as_dict=1) if filters.get('presentation_currency'): return convert_to_presentation_currency(gl_entries, currency_map) @@ -184,10 +197,13 @@ def get_conditions(filters): from frappe.desk.reportview import build_match_conditions match_conditions = build_match_conditions("GL Entry") - if match_conditions: conditions.append(match_conditions) + + if match_conditions: + conditions.append(match_conditions) return "and {}".format(" and ".join(conditions)) if conditions else "" + def get_data_with_opening_closing(filters, account_details, gl_entries): data = [] gle_map = initialize_gle_map(gl_entries) @@ -222,7 +238,7 @@ def get_data_with_opening_closing(filters, account_details, gl_entries): # closing data.append(totals.closing) - #total closing + # total closing total_closing = totals.total_closing total_debit = totals.closing.get('debit', 0) total_credit = totals.closing.get('credit', 0) @@ -242,28 +258,31 @@ def get_data_with_opening_closing(filters, account_details, gl_entries): return data + def get_totals_dict(): def _get_debit_credit_dict(label): return _dict( - account = "'{0}'".format(label), - debit = 0.0, - credit = 0.0, - debit_in_account_currency = 0.0, - credit_in_account_currency = 0.0 + account="'{0}'".format(label), + debit=0.0, + credit=0.0, + debit_in_account_currency=0.0, + credit_in_account_currency=0.0 ) return _dict( - opening = _get_debit_credit_dict(_('Opening')), - total = _get_debit_credit_dict(_('Total')), - closing = _get_debit_credit_dict(_('Closing (Opening + Total)')), - total_closing = _get_debit_credit_dict(_('Closing Balance (Dr - Cr)')) + opening=_get_debit_credit_dict(_('Opening')), + total=_get_debit_credit_dict(_('Total')), + closing=_get_debit_credit_dict(_('Closing (Opening + Total)')), + total_closing=_get_debit_credit_dict(_('Closing Balance (Dr - Cr)')) ) + def initialize_gle_map(gl_entries): gle_map = frappe._dict() for gle in gl_entries: - gle_map.setdefault(gle.account, _dict(totals = get_totals_dict(), entries = [])) + gle_map.setdefault(gle.account, _dict(totals=get_totals_dict(), entries=[])) return gle_map + def get_accountwise_gle(filters, gl_entries, gle_map): totals = get_totals_dict() entries = [] @@ -275,13 +294,12 @@ def get_accountwise_gle(filters, gl_entries, gle_map): data[key].debit_in_account_currency += flt(gle.debit_in_account_currency) data[key].credit_in_account_currency += flt(gle.credit_in_account_currency) - from_date, to_date = getdate(filters.from_date), getdate(filters.to_date) for gle in gl_entries: if gle.posting_date < from_date or cstr(gle.is_opening) == "Yes": update_value_in_dict(gle_map[gle.account].totals, 'opening', gle) update_value_in_dict(totals, 'opening', gle) - + update_value_in_dict(gle_map[gle.account].totals, 'closing', gle) update_value_in_dict(totals, 'closing', gle) @@ -298,6 +316,7 @@ def get_accountwise_gle(filters, gl_entries, gle_map): return totals, entries + def get_result_as_list(data, filters): result = [] for d in data: @@ -306,8 +325,10 @@ def get_result_as_list(data, filters): if filters.get("show_in_account_currency"): row += [d.get("debit_in_account_currency"), d.get("credit_in_account_currency")] - row += [d.get("voucher_type"), d.get("voucher_no"), d.get("against"), - d.get("party_type"), d.get("party"), d.get("project"), d.get("cost_center"), d.get("against_voucher_type"), d.get("against_voucher"), d.get("remarks") + row += [ + d.get("voucher_type"), d.get("voucher_no"), d.get("against"), d.get("party_type"), + d.get("party"), d.get("project"), d.get("cost_center"), d.get("against_voucher_type"), + d.get("against_voucher"), d.get("remarks") ] result.append(row)