diff --git a/erpnext/accounts/doctype/account/account.json b/erpnext/accounts/doctype/account/account.json index 66e710876a..ce038772c1 100644 --- a/erpnext/accounts/doctype/account/account.json +++ b/erpnext/accounts/doctype/account/account.json @@ -25,6 +25,7 @@ "oldfieldtype": "Section Break", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -46,6 +47,7 @@ "no_copy": 0, "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -71,6 +73,7 @@ "oldfieldtype": "Data", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, "reqd": 1, @@ -95,6 +98,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -120,6 +124,7 @@ "options": "Company", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, "reqd": 1, @@ -143,6 +148,7 @@ "options": "\nAsset\nLiability\nIncome\nExpense\nEquity", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, "reqd": 0, @@ -166,6 +172,7 @@ "options": "\nBalance Sheet\nProfit and Loss", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, "reqd": 0, @@ -191,6 +198,7 @@ "permlevel": 0, "precision": "", "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -212,6 +220,7 @@ "no_copy": 0, "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -238,6 +247,7 @@ "options": "Account", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 1, @@ -261,9 +271,10 @@ "no_copy": 0, "oldfieldname": "account_type", "oldfieldtype": "Select", - "options": "\nBank\nCash\nTax\nChargeable\nWarehouse\nReceivable\nPayable\nEquity\nFixed Asset\nCost of Goods Sold\nExpense Account\nRound Off\nIncome Account\nStock Received But Not Billed\nExpenses Included In Valuation\nStock Adjustment\nStock\nTemporary", + "options": "\nBank\nCash\nDepreciation\nTax\nChargeable\nWarehouse\nReceivable\nPayable\nEquity\nFixed Asset\nCost of Goods Sold\nExpense Account\nRound Off\nIncome Account\nStock Received But Not Billed\nExpenses Included In Valuation\nStock Adjustment\nStock\nTemporary", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -289,6 +300,7 @@ "oldfieldtype": "Currency", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -315,6 +327,7 @@ "options": "No\nYes", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -338,6 +351,7 @@ "options": "Warehouse", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -361,6 +375,7 @@ "options": "\nDebit\nCredit", "permlevel": 0, "print_hide": 0, + "print_hide_if_no_value": 0, "read_only": 0, "report_hide": 0, "reqd": 0, @@ -383,6 +398,7 @@ "no_copy": 0, "permlevel": 0, "print_hide": 1, + "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, "reqd": 0, @@ -405,6 +421,7 @@ "no_copy": 0, "permlevel": 0, "print_hide": 1, + "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, "reqd": 0, @@ -427,6 +444,7 @@ "no_copy": 0, "permlevel": 0, "print_hide": 1, + "print_hide_if_no_value": 0, "read_only": 1, "report_hide": 0, "reqd": 0, @@ -445,7 +463,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2015-11-16 06:29:41.535663", + "modified": "2015-12-12 10:19:54.365839", "modified_by": "Administrator", "module": "Accounts", "name": "Account", diff --git a/erpnext/accounts/report/cash_flow/__init__.py b/erpnext/accounts/report/cash_flow/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/accounts/report/cash_flow/cash_flow.js b/erpnext/accounts/report/cash_flow/cash_flow.js new file mode 100644 index 0000000000..c8fb04cb9d --- /dev/null +++ b/erpnext/accounts/report/cash_flow/cash_flow.js @@ -0,0 +1,6 @@ +// Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.require("assets/erpnext/js/financial_statements.js"); + +frappe.query_reports["Cash Flow"] = erpnext.financial_statements; diff --git a/erpnext/accounts/report/cash_flow/cash_flow.json b/erpnext/accounts/report/cash_flow/cash_flow.json new file mode 100644 index 0000000000..d0f2e048b2 --- /dev/null +++ b/erpnext/accounts/report/cash_flow/cash_flow.json @@ -0,0 +1,18 @@ +{ + "add_total_row": 0, + "apply_user_permissions": 1, + "creation": "2015-12-12 10:22:45.383203", + "disabled": 0, + "docstatus": 0, + "doctype": "Report", + "idx": 0, + "is_standard": "Yes", + "modified": "2015-12-12 10:22:45.383203", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Cash Flow", + "owner": "Administrator", + "ref_doctype": "GL Entry", + "report_name": "Cash Flow", + "report_type": "Script Report" +} \ No newline at end of file diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py new file mode 100644 index 0000000000..f6bf370df8 --- /dev/null +++ b/erpnext/accounts/report/cash_flow/cash_flow.py @@ -0,0 +1,134 @@ +# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +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 + + +def execute(filters=None): + period_list = get_period_list(filters.fiscal_year, filters.periodicity) + + operation_accounts = { + "section_name": "Operations", + "section_footer": _("Net Cash from Operations"), + "section_header": _("Cash Flow from Operations"), + "account_types": [ + {"account_type": "Depreciation", "label": _("Depreciation")}, + {"account_type": "Receivable", "label": _("Net Change in Accounts Receivable")}, + {"account_type": "Payable", "label": _("Net Change in Accounts Payable")}, + {"account_type": "Warehouse", "label": _("Net Change in Inventory")} + ] + } + + investing_accounts = { + "section_name": "Investing", + "section_footer": _("Net Cash from Investing"), + "section_header": _("Cash Flow from Investing"), + "account_types": [ + {"account_type": "Fixed Asset", "label": _("Net Change in Fixed Asset")} + ] + } + + financing_accounts = { + "section_name": "Financing", + "section_footer": _("Net Cash from Financing"), + "section_header": _("Cash Flow from Financing"), + "account_types": [ + {"account_type": "Equity", "label": _("Net Change in Equity")} + ] + } + + # combine all cash flow accounts for iteration + cash_flow_accounts = [] + cash_flow_accounts.append(operation_accounts) + cash_flow_accounts.append(investing_accounts) + cash_flow_accounts.append(financing_accounts) + + # compute net profit / loss + income = get_data(filters.company, "Income", "Credit", period_list, ignore_closing_entries=True) + expense = get_data(filters.company, "Expense", "Debit", period_list, ignore_closing_entries=True) + net_profit_loss = get_net_profit_loss(income, expense, period_list) + + data = [] + + for cash_flow_account in cash_flow_accounts: + + section_data = [] + data.append({ + "account_name": cash_flow_account['section_header'], + "parent_account": None, + "indent": 0.0, + "account": cash_flow_account['section_header'] + }) + + if len(data) == 1: + # add first net income in operations section + if net_profit_loss: + net_profit_loss.update({ + "indent": 1, + "parent_account": operation_accounts['section_header'] + }) + data.append(net_profit_loss) + section_data.append(net_profit_loss) + + for account in cash_flow_account['account_types']: + account_data = get_account_type_based_data(filters.company, account['account_type'], period_list) + account_data.update({ + "account_name": account['label'], + "indent": 1, + "parent_account": cash_flow_account['section_header'] + }) + data.append(account_data) + section_data.append(account_data) + + add_total_row_account(data, section_data, cash_flow_account['section_footer'], period_list) + + add_total_row_account(data, data, _("Net Change in Cash"), period_list) + columns = get_columns(period_list) + + return columns, data + + +def get_account_type_based_data(company, account_type, period_list): + data = {} + for period in period_list: + gl_sum = frappe.db.sql_list(""" + select sum(credit) - sum(debit) + from `tabGL Entry` + where company=%s and posting_date >= %s and posting_date <= %s + and voucher_type != 'Period Closing Voucher' + and account in ( SELECT name FROM tabAccount WHERE account_type = %s) + """, (company, period['from_date'], period['to_date'], account_type)) + + if gl_sum and gl_sum[0]: + amount = gl_sum[0] + if account_type == "Depreciation": + amount *= -1 + else: + amount = 0 + + data.update({ + "from_date": period['from_date'], + "to_date": period['to_date'], + period["key"]: amount + }) + return data + + +def add_total_row_account(out, data, label, period_list): + total_row = { + "account_name": "'" + _("{0}").format(label) + "'", + "account": None + } + + for row in data: + if row.get("parent_account"): + for period in period_list: + total_row.setdefault(period.key, 0.0) + total_row[period.key] += row.get(period.key, 0.0) + + out.append(total_row) + out.append({}) \ No newline at end of file diff --git a/erpnext/accounts/report/financial_statements.py b/erpnext/accounts/report/financial_statements.py index 5cdf553de1..5e3184d408 100644 --- a/erpnext/accounts/report/financial_statements.py +++ b/erpnext/accounts/report/financial_statements.py @@ -257,4 +257,4 @@ def get_columns(period_list): "width": 150 }) - return columns + return columns \ No newline at end of file diff --git a/erpnext/config/accounts.py b/erpnext/config/accounts.py index 7fca256c1a..8a27394509 100644 --- a/erpnext/config/accounts.py +++ b/erpnext/config/accounts.py @@ -229,6 +229,12 @@ def get_data(): "doctype": "GL Entry", "is_query_report": True }, + { + "type": "report", + "name": "Cash Flow", + "doctype": "GL Entry", + "is_query_report": True + }, { "type": "report", "name": "Profit and Loss Statement",