diff --git a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json index b19bb2bfeb6..e040b619d13 100644 --- a/erpnext/accounts/doctype/accounts_settings/accounts_settings.json +++ b/erpnext/accounts/doctype/accounts_settings/accounts_settings.json @@ -514,6 +514,68 @@ "set_only_once": 0, "translatable": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "report_settings_sb", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Report Settings", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "description": "Only select if you have setup Cash Flow Mapper documents", + "fieldname": "use_custom_cash_flow", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Use Custom Cash Flow Format", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } ], "has_web_view": 0, diff --git a/erpnext/accounts/doctype/cash_flow_mapper/__init__.py b/erpnext/accounts/doctype/cash_flow_mapper/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/cash_flow_mapper/cash_flow_mapper.js b/erpnext/accounts/doctype/cash_flow_mapper/cash_flow_mapper.js new file mode 100644 index 00000000000..13d223ad407 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapper/cash_flow_mapper.js @@ -0,0 +1,6 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Cash Flow Mapper', { + +}); diff --git a/erpnext/accounts/doctype/cash_flow_mapper/cash_flow_mapper.json b/erpnext/accounts/doctype/cash_flow_mapper/cash_flow_mapper.json new file mode 100644 index 00000000000..f0e984dc2a3 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapper/cash_flow_mapper.json @@ -0,0 +1,275 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 1, + "autoname": "field:section_name", + "beta": 0, + "creation": "2018-02-08 10:00:14.066519", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Section Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_header", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Section Header", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "e.g Adjustments for:", + "fieldname": "section_leader", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Section Leader", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_subtotal", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Section Subtotal", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_footer", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Section Footer", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "accounts", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Accounts", + "length": 0, + "no_copy": 0, + "options": "Cash Flow Mapping Template Details", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "position", + "fieldtype": "Int", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Position", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-02-15 18:28:55.034933", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Cash Flow Mapper", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "name", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/cash_flow_mapper/cash_flow_mapper.py b/erpnext/accounts/doctype/cash_flow_mapper/cash_flow_mapper.py new file mode 100644 index 00000000000..72515338378 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapper/cash_flow_mapper.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +from frappe.model.document import Document + + +class CashFlowMapper(Document): + pass diff --git a/erpnext/accounts/doctype/cash_flow_mapper/default_cash_flow_mapper.py b/erpnext/accounts/doctype/cash_flow_mapper/default_cash_flow_mapper.py new file mode 100644 index 00000000000..6e7b687c04d --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapper/default_cash_flow_mapper.py @@ -0,0 +1,25 @@ +DEFAULT_MAPPERS = [ + { + 'doctype': 'Cash Flow Mapper', + 'section_footer': 'Net cash generated by operating activities', + 'section_header': 'Cash flows from operating activities', + 'section_leader': 'Adjustments for', + 'section_name': 'Operating Activities', + 'position': 0, + 'section_subtotal': 'Cash generated from operations', + }, + { + 'doctype': 'Cash Flow Mapper', + 'position': 1, + 'section_footer': 'Net cash used in investing activities', + 'section_header': 'Cash flows from investing activities', + 'section_name': 'Investing Activities' + }, + { + 'doctype': 'Cash Flow Mapper', + 'position': 2, + 'section_footer': 'Net cash used in financing activites', + 'section_header': 'Cash flows from financing activities', + 'section_name': 'Financing Activities', + } +] diff --git a/erpnext/accounts/doctype/cash_flow_mapper/test_cash_flow_mapper.js b/erpnext/accounts/doctype/cash_flow_mapper/test_cash_flow_mapper.js new file mode 100644 index 00000000000..12ca254c5ae --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapper/test_cash_flow_mapper.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Cash Flow Mapper", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Cash Flow Mapper + () => frappe.tests.make('Cash Flow Mapper', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/accounts/doctype/cash_flow_mapper/test_cash_flow_mapper.py b/erpnext/accounts/doctype/cash_flow_mapper/test_cash_flow_mapper.py new file mode 100644 index 00000000000..f055e563adb --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapper/test_cash_flow_mapper.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import unittest + + +class TestCashFlowMapper(unittest.TestCase): + pass diff --git a/erpnext/accounts/doctype/cash_flow_mapping/__init__.py b/erpnext/accounts/doctype/cash_flow_mapping/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/cash_flow_mapping/cash_flow_mapping.js b/erpnext/accounts/doctype/cash_flow_mapping/cash_flow_mapping.js new file mode 100644 index 00000000000..00c71657c5c --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping/cash_flow_mapping.js @@ -0,0 +1,43 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Cash Flow Mapping', { + refresh: function(frm) { + frm.events.disable_unchecked_fields(frm); + }, + reset_check_fields: function(frm) { + frm.fields.filter(field => field.df.fieldtype === 'Check') + .map(field => frm.set_df_property(field.df.fieldname, 'read_only', 0)); + }, + has_checked_field(frm) { + const val = frm.fields.filter(field => field.value === 1); + return val.length ? 1 : 0; + }, + _disable_unchecked_fields: function(frm) { + // get value of clicked field + frm.fields.filter(field => field.value === 0) + .map(field => frm.set_df_property(field.df.fieldname, 'read_only', 1)); + }, + disable_unchecked_fields: function(frm) { + frm.events.reset_check_fields(frm); + const checked = frm.events.has_checked_field(frm); + if (checked) { + frm.events._disable_unchecked_fields(frm); + } + }, + is_working_capital: function(frm) { + frm.events.disable_unchecked_fields(frm); + }, + is_finance_cost: function(frm) { + frm.events.disable_unchecked_fields(frm); + }, + is_income_tax_liability: function(frm) { + frm.events.disable_unchecked_fields(frm); + }, + is_income_tax_expense: function(frm) { + frm.events.disable_unchecked_fields(frm); + }, + is_finance_cost_adjustment: function(frm) { + frm.events.disable_unchecked_fields(frm); + } +}); diff --git a/erpnext/accounts/doctype/cash_flow_mapping/cash_flow_mapping.json b/erpnext/accounts/doctype/cash_flow_mapping/cash_flow_mapping.json new file mode 100644 index 00000000000..bd7fd1c135e --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping/cash_flow_mapping.json @@ -0,0 +1,359 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 1, + "autoname": "field:mapping_name", + "beta": 0, + "creation": "2018-02-08 09:28:44.678364", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "mapping_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "label", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Label", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "accounts", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Accounts", + "length": 0, + "no_copy": 0, + "options": "Cash Flow Mapping Accounts", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "sb_1", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Select Maximum Of 1", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "is_finance_cost", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Is Finance Cost", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "is_working_capital", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Is Working Capital", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "is_finance_cost_adjustment", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Is Finance Cost Adjustment", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "is_income_tax_liability", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Is Income Tax Liability", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "is_income_tax_expense", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Is Income Tax Expense", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-02-15 08:25:18.693533", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Cash Flow Mapping", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + }, + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Administrator", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "name", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/cash_flow_mapping/cash_flow_mapping.py b/erpnext/accounts/doctype/cash_flow_mapping/cash_flow_mapping.py new file mode 100644 index 00000000000..28d84b4442f --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping/cash_flow_mapping.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + + +class CashFlowMapping(Document): + def validate(self): + self.validate_checked_options() + + def validate_checked_options(self): + checked_fields = [d for d in self.meta.fields if d.fieldtype == 'Check' and self.get(d.fieldname) == 1] + if len(checked_fields) > 1: + frappe.throw( + frappe._('You can only select a maximum of one option from the list of check boxes.'), + title='Error' + ) + + diff --git a/erpnext/accounts/doctype/cash_flow_mapping/test_cash_flow_mapping.js b/erpnext/accounts/doctype/cash_flow_mapping/test_cash_flow_mapping.js new file mode 100644 index 00000000000..1970ca806dc --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping/test_cash_flow_mapping.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Cash Flow Mapping", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Cash Flow Mapping + () => frappe.tests.make('Cash Flow Mapping', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/accounts/doctype/cash_flow_mapping/test_cash_flow_mapping.py b/erpnext/accounts/doctype/cash_flow_mapping/test_cash_flow_mapping.py new file mode 100644 index 00000000000..499c820479e --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping/test_cash_flow_mapping.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + + +class TestCashFlowMapping(unittest.TestCase): + def setUp(self): + if frappe.db.exists("Cash Flow Mapping", "Test Mapping"): + frappe.delete_doc('Cash Flow Mappping', 'Test Mapping') + + def tearDown(self): + frappe.delete_doc('Cash Flow Mapping', 'Test Mapping') + + def test_multiple_selections_not_allowed(self): + doc = frappe.new_doc('Cash Flow Mapping') + doc.mapping_name = 'Test Mapping' + doc.label = 'Test label' + doc.append( + 'accounts', + {'account': 'Accounts Receivable - _TC'} + ) + doc.is_working_capital = 1 + doc.is_finance_cost = 1 + + self.assertRaises(frappe.ValidationError, doc.insert) + + doc.is_finance_cost = 0 + doc.insert() diff --git a/erpnext/accounts/doctype/cash_flow_mapping_accounts/__init__.py b/erpnext/accounts/doctype/cash_flow_mapping_accounts/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/cash_flow_mapping_accounts/cash_flow_mapping_accounts.json b/erpnext/accounts/doctype/cash_flow_mapping_accounts/cash_flow_mapping_accounts.json new file mode 100644 index 00000000000..470c87c0b84 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_accounts/cash_flow_mapping_accounts.json @@ -0,0 +1,73 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "field:account", + "beta": 0, + "creation": "2018-02-08 09:25:34.353995", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "account", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "account", + "length": 0, + "no_copy": 0, + "options": "Account", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 1, + "max_attachments": 0, + "modified": "2018-02-08 09:25:34.353995", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Cash Flow Mapping Accounts", + "name_case": "", + "owner": "Administrator", + "permissions": [], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/cash_flow_mapping_accounts/cash_flow_mapping_accounts.py b/erpnext/accounts/doctype/cash_flow_mapping_accounts/cash_flow_mapping_accounts.py new file mode 100644 index 00000000000..fc63b8f9af6 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_accounts/cash_flow_mapping_accounts.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +from frappe.model.document import Document + + +class CashFlowMappingAccounts(Document): + pass diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template/__init__.py b/erpnext/accounts/doctype/cash_flow_mapping_template/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template/cash_flow_mapping_template.js b/erpnext/accounts/doctype/cash_flow_mapping_template/cash_flow_mapping_template.js new file mode 100644 index 00000000000..8611153cd8b --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template/cash_flow_mapping_template.js @@ -0,0 +1,6 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Cash Flow Mapping Template', { + +}); diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template/cash_flow_mapping_template.json b/erpnext/accounts/doctype/cash_flow_mapping_template/cash_flow_mapping_template.json new file mode 100644 index 00000000000..27e19dc7562 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template/cash_flow_mapping_template.json @@ -0,0 +1,123 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-02-08 10:20:18.316801", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "template_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Template Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "mapping", + "fieldtype": "Table", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Cash Flow Mapping", + "length": 0, + "no_copy": 0, + "options": "Cash Flow Mapping Template Details", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-02-08 10:20:18.316801", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Cash Flow Mapping Template", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template/cash_flow_mapping_template.py b/erpnext/accounts/doctype/cash_flow_mapping_template/cash_flow_mapping_template.py new file mode 100644 index 00000000000..6f77a39bab9 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template/cash_flow_mapping_template.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +from frappe.model.document import Document + + +class CashFlowMappingTemplate(Document): + pass diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template/test_cash_flow_mapping_template.js b/erpnext/accounts/doctype/cash_flow_mapping_template/test_cash_flow_mapping_template.js new file mode 100644 index 00000000000..12546ce2e3a --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template/test_cash_flow_mapping_template.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Cash Flow Mapping Template", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Cash Flow Mapping Template + () => frappe.tests.make('Cash Flow Mapping Template', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template/test_cash_flow_mapping_template.py b/erpnext/accounts/doctype/cash_flow_mapping_template/test_cash_flow_mapping_template.py new file mode 100644 index 00000000000..d6b964bb177 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template/test_cash_flow_mapping_template.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import unittest + + +class TestCashFlowMappingTemplate(unittest.TestCase): + pass diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template_details/__init__.py b/erpnext/accounts/doctype/cash_flow_mapping_template_details/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template_details/cash_flow_mapping_template_details.js b/erpnext/accounts/doctype/cash_flow_mapping_template_details/cash_flow_mapping_template_details.js new file mode 100644 index 00000000000..2e5dce4fb57 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template_details/cash_flow_mapping_template_details.js @@ -0,0 +1,6 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Cash Flow Mapping Template Details', { + +}); diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template_details/cash_flow_mapping_template_details.json b/erpnext/accounts/doctype/cash_flow_mapping_template_details/cash_flow_mapping_template_details.json new file mode 100644 index 00000000000..22cf797fc3f --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template_details/cash_flow_mapping_template_details.json @@ -0,0 +1,94 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "field:mapping", + "beta": 0, + "creation": "2018-02-08 10:18:48.513608", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "mapping", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Mapping", + "length": 0, + "no_copy": 0, + "options": "Cash Flow Mapping", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-02-08 10:33:39.413930", + "modified_by": "Administrator", + "module": "Accounts", + "name": "Cash Flow Mapping Template Details", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template_details/cash_flow_mapping_template_details.py b/erpnext/accounts/doctype/cash_flow_mapping_template_details/cash_flow_mapping_template_details.py new file mode 100644 index 00000000000..e10b63829fd --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template_details/cash_flow_mapping_template_details.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +from frappe.model.document import Document + + +class CashFlowMappingTemplateDetails(Document): + pass diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template_details/test_cash_flow_mapping_template_details.js b/erpnext/accounts/doctype/cash_flow_mapping_template_details/test_cash_flow_mapping_template_details.js new file mode 100644 index 00000000000..eecabda751b --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template_details/test_cash_flow_mapping_template_details.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Cash Flow Mapping Template Details", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Cash Flow Mapping Template Details + () => frappe.tests.make('Cash Flow Mapping Template Details', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/accounts/doctype/cash_flow_mapping_template_details/test_cash_flow_mapping_template_details.py b/erpnext/accounts/doctype/cash_flow_mapping_template_details/test_cash_flow_mapping_template_details.py new file mode 100644 index 00000000000..db5683a5a74 --- /dev/null +++ b/erpnext/accounts/doctype/cash_flow_mapping_template_details/test_cash_flow_mapping_template_details.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import unittest + + +class TestCashFlowMappingTemplateDetails(unittest.TestCase): + pass diff --git a/erpnext/accounts/report/cash_flow/cash_flow.py b/erpnext/accounts/report/cash_flow/cash_flow.py index f55d1927318..c81db38ebe4 100644 --- a/erpnext/accounts/report/cash_flow/cash_flow.py +++ b/erpnext/accounts/report/cash_flow/cash_flow.py @@ -4,12 +4,17 @@ from __future__ import unicode_literals import frappe from frappe import _ +from frappe.utils import cint 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 def execute(filters=None): + 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) + period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year, filters.periodicity, filters.accumulated_values, filters.company) @@ -44,10 +49,7 @@ def execute(filters=None): } # 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) + cash_flow_accounts = [operation_accounts, investing_accounts, financing_accounts] # compute net profit / loss income = get_data(filters.company, "Income", "Credit", period_list, @@ -100,6 +102,7 @@ def execute(filters=None): return columns, data + def get_account_type_based_data(company, account_type, period_list, accumulated_values): data = {} total = 0 @@ -127,6 +130,7 @@ def get_account_type_based_data(company, account_type, period_list, accumulated_ data["total"] = total return data + def get_start_date(period, accumulated_values, company): start_date = period["year_start_date"] if accumulated_values: @@ -134,6 +138,7 @@ def get_start_date(period, accumulated_values, company): return start_date + def add_total_row_account(out, data, label, period_list, currency): total_row = { "account_name": "'" + _("{0}").format(label) + "'", diff --git a/erpnext/accounts/report/cash_flow/custom_cash_flow.py b/erpnext/accounts/report/cash_flow/custom_cash_flow.py new file mode 100644 index 00000000000..160b200142c --- /dev/null +++ b/erpnext/accounts/report/cash_flow/custom_cash_flow.py @@ -0,0 +1,443 @@ +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe import _ +from frappe.utils import add_to_date +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 get_mapper_for(mappers, position): + mapper_list = filter(lambda x: x['position'] == position, mappers) + return mapper_list[0] if mapper_list else [] + + +def get_mappers_from_db(): + return frappe.get_all( + 'Cash Flow Mapper', + fields=[ + 'section_name', 'section_header', 'section_leader', 'section_subtotal', + 'section_footer', 'name', 'position'], + order_by='position' + ) + + +def get_accounts_in_mappers(mapping_names): + return frappe.db.sql( + 'select cfma.name, cfm.label, cfm.is_working_capital, cfm.is_income_tax_liability, ' + 'cfm.is_income_tax_expense, cfm.is_finance_cost, cfm.is_finance_cost_adjustment ' + 'from `tabCash Flow Mapping Accounts` cfma ' + 'join `tabCash Flow Mapping` cfm on cfma.parent=cfm.name ' + 'where cfma.parent in %s ' + 'order by cfm.is_working_capital', + (mapping_names,) + ) + + +def setup_mappers(mappers): + cash_flow_accounts = [] + + for mapping in mappers: + mapping['account_types'] = [] + mapping['tax_liabilities'] = [] + mapping['tax_expenses'] = [] + mapping['finance_costs'] = [] + mapping['finance_costs_adjustments'] = [] + doc = frappe.get_doc('Cash Flow Mapper', mapping['name']) + mapping_names = [item.name for item in doc.accounts] + + if not mapping_names: + continue + + accounts = get_accounts_in_mappers(mapping_names) + + account_types = [ + dict( + name=account[0], label=account[1], is_working_capital=account[2], + is_income_tax_liability=account[3], is_income_tax_expense=account[4] + ) for account in accounts if not account[3]] + + finance_costs_adjustments = [ + dict( + name=account[0], label=account[1], is_finance_cost=account[5], + is_finance_cost_adjustment=account[6] + ) for account in accounts if account[6]] + + tax_liabilities = [ + dict( + name=account[0], label=account[1], is_income_tax_liability=account[3], + is_income_tax_expense=account[4] + ) for account in accounts if account[3]] + + tax_expenses = [ + dict( + name=account[0], label=account[1], is_income_tax_liability=account[3], + is_income_tax_expense=account[4] + ) for account in accounts if account[4]] + + finance_costs = [ + dict( + name=account[0], label=account[1], is_finance_cost=account[5]) + for account in accounts if account[5]] + + account_types_labels = sorted( + set( + [(d['label'], d['is_working_capital'], d['is_income_tax_liability'], d['is_income_tax_expense']) + for d in account_types] + ), + key=lambda x: x[1] + ) + + fc_adjustment_labels = sorted( + set( + [(d['label'], d['is_finance_cost'], d['is_finance_cost_adjustment']) + for d in finance_costs_adjustments if d['is_finance_cost_adjustment']] + ), + key=lambda x: x[2] + ) + + unique_liability_labels = sorted( + set( + [(d['label'], d['is_income_tax_liability'], d['is_income_tax_expense']) + for d in tax_liabilities] + ), + key=lambda x: x[0] + ) + + unique_expense_labels = sorted( + set( + [(d['label'], d['is_income_tax_liability'], d['is_income_tax_expense']) + for d in tax_expenses] + ), + key=lambda x: x[0] + ) + + unique_finance_costs_labels = sorted( + set( + [(d['label'], d['is_finance_cost']) for d in finance_costs] + ), + key=lambda x: x[0] + ) + + for label in account_types_labels: + names = [d['name'] for d in account_types if d['label'] == label[0]] + m = dict(label=label[0], names=names, is_working_capital=label[1]) + mapping['account_types'].append(m) + + for label in fc_adjustment_labels: + names = [d['name'] for d in finance_costs_adjustments if d['label'] == label[0]] + m = dict(label=label[0], names=names) + mapping['finance_costs_adjustments'].append(m) + + for label in unique_liability_labels: + names = [d['name'] for d in tax_liabilities if d['label'] == label[0]] + m = dict(label=label[0], names=names, tax_liability=label[1], tax_expense=label[2]) + mapping['tax_liabilities'].append(m) + + for label in unique_expense_labels: + names = [d['name'] for d in tax_expenses if d['label'] == label[0]] + m = dict(label=label[0], names=names, tax_liability=label[1], tax_expense=label[2]) + mapping['tax_expenses'].append(m) + + for label in unique_finance_costs_labels: + names = [d['name'] for d in finance_costs if d['label'] == label[0]] + m = dict(label=label[0], names=names, is_finance_cost=label[1]) + mapping['finance_costs'].append(m) + + cash_flow_accounts.append(mapping) + + return cash_flow_accounts + + +def add_data_for_operating_activities( + filters, company_currency, profit_data, period_list, light_mappers, mapper, data): + has_added_working_capital_header = False + section_data = [] + + data.append({ + "account_name": mapper['section_header'], + "parent_account": None, + "indent": 0.0, + "account": mapper['section_header'] + }) + + if profit_data: + profit_data.update({ + "indent": 1, + "parent_account": get_mapper_for(light_mappers, position=0)['section_header'] + }) + data.append(profit_data) + section_data.append(profit_data) + + data.append({ + "account_name": mapper["section_leader"], + "parent_account": None, + "indent": 1.0, + "account": mapper["section_leader"] + }) + + for account in mapper['account_types']: + if account['is_working_capital'] and not has_added_working_capital_header: + data.append({ + "account_name": 'Movement in working capital', + "parent_account": None, + "indent": 1.0, + "account": "" + }) + has_added_working_capital_header = True + + account_data = _get_account_type_based_data( + filters, account['names'], period_list, filters.accumulated_values) + + if not account['is_working_capital']: + for key in account_data: + if key != 'total': + account_data[key] *= -1 + + if account_data['total'] != 0: + account_data.update({ + "account_name": account['label'], + "account": account['names'], + "indent": 1.0, + "parent_account": mapper['section_header'], + "currency": company_currency + }) + data.append(account_data) + section_data.append(account_data) + + _add_total_row_account( + data, section_data, mapper['section_subtotal'], period_list, company_currency, indent=1) + + # calculate adjustment for tax paid and add to data + if not mapper['tax_liabilities']: + mapper['tax_liabilities'] = [ + dict(label='Income tax paid', names=[''], tax_liability=1, tax_expense=0)] + + for account in mapper['tax_liabilities']: + tax_paid = calculate_adjustment( + filters, mapper['tax_liabilities'], mapper['tax_expenses'], + filters.accumulated_values, period_list) + + if tax_paid: + tax_paid.update({ + 'parent_account': mapper['section_header'], + 'currency': company_currency, + 'account_name': account['label'], + 'indent': 1.0 + }) + data.append(tax_paid) + section_data.append(tax_paid) + + if not mapper['finance_costs_adjustments']: + mapper['finance_costs_adjustments'] = [dict(label='Interest Paid', names=[''])] + + for account in mapper['finance_costs_adjustments']: + interest_paid = calculate_adjustment( + filters, mapper['finance_costs_adjustments'], mapper['finance_costs'], + filters.accumulated_values, period_list + ) + + if interest_paid: + interest_paid.update({ + 'parent_account': mapper['section_header'], + 'currency': company_currency, + 'account_name': account['label'], + 'indent': 1.0 + }) + data.append(interest_paid) + section_data.append(interest_paid) + + _add_total_row_account( + data, section_data, mapper['section_footer'], period_list, company_currency) + + +def calculate_adjustment(filters, non_expense_mapper, expense_mapper, use_accumulated_values, period_list): + liability_accounts = [d['names'] for d in non_expense_mapper] + expense_accounts = [d['names'] for d in expense_mapper] + + non_expense_closing = _get_account_type_based_data( + filters, liability_accounts, period_list, 0) + + non_expense_opening = _get_account_type_based_data( + filters, liability_accounts, period_list, use_accumulated_values, opening_balances=1) + + expense_data = _get_account_type_based_data( + filters, expense_accounts, period_list, use_accumulated_values) + + data = _calculate_adjustment(non_expense_closing, non_expense_opening, expense_data) + return data + + +def _calculate_adjustment(non_expense_closing, non_expense_opening, expense_data): + account_data = {} + for month in non_expense_opening.keys(): + if non_expense_opening[month] and non_expense_closing[month]: + account_data[month] = non_expense_opening[month] - expense_data[month] + non_expense_closing[month] + elif expense_data[month]: + account_data[month] = expense_data[month] + + return account_data + + +def add_data_for_other_activities( + filters, company_currency, profit_data, period_list, light_mappers, mapper_list, data): + for mapper in mapper_list: + section_data = [] + data.append({ + "account_name": mapper['section_header'], + "parent_account": None, + "indent": 0.0, + "account": mapper['section_header'] + }) + + for account in mapper['account_types']: + account_data = _get_account_type_based_data(filters, + account['names'], period_list, filters.accumulated_values) + if account_data['total'] != 0: + account_data.update({ + "account_name": account['label'], + "account": account['names'], + "indent": 1, + "parent_account": mapper['section_header'], + "currency": company_currency + }) + data.append(account_data) + section_data.append(account_data) + + _add_total_row_account(data, section_data, mapper['section_footer'], + period_list, company_currency) + + +def compute_data(filters, company_currency, profit_data, period_list, light_mappers, full_mapper): + data = [] + + operating_activities_mapper = get_mapper_for(light_mappers, position=0) + other_mappers = [ + get_mapper_for(light_mappers, position=1), + get_mapper_for(light_mappers, position=2) + ] + + if operating_activities_mapper: + add_data_for_operating_activities( + filters, company_currency, profit_data, period_list, light_mappers, + operating_activities_mapper, data + ) + + if all(other_mappers): + add_data_for_other_activities( + filters, company_currency, profit_data, period_list, light_mappers, other_mappers, data + ) + + return data + + +def execute(filters=None): + period_list = get_period_list( + filters.from_fiscal_year, filters.to_fiscal_year, filters.periodicity, + filters.accumulated_values, filters.company + ) + + mappers = get_mappers_from_db() + + cash_flow_accounts = setup_mappers(mappers) + + # compute net profit / loss + income = get_data( + filters.company, "Income", "Credit", period_list, + accumulated_values=filters.accumulated_values, ignore_closing_entries=True, + ignore_accumulated_values_for_fy=True + ) + + expense = get_data( + filters.company, "Expense", "Debit", period_list, + 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) + + company_currency = frappe.db.get_value("Company", filters.company, "default_currency") + + data = compute_data(filters, company_currency, net_profit_loss, period_list, mappers, cash_flow_accounts) + + _add_total_row_account(data, data, _("Net Change in Cash"), period_list, company_currency) + columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, filters.company) + + return columns, data + + +def _get_account_type_based_data(filters, account_names, period_list, accumulated_values, opening_balances=0): + from erpnext.accounts.report.cash_flow.cash_flow import get_start_date + + company = filters.company + data = {} + total = 0 + for period in period_list: + start_date = get_start_date(period, accumulated_values, company) + + if opening_balances: + date_info = dict(date=start_date) + months_map = {'Monthly': -1, 'Quarterly': -3, 'Half-Yearly': -6} + years_map = {'Yearly': -1} + + if months_map.get(filters.periodicity): + date_info.update(months=months_map[filters.periodicity]) + else: + date_info.update(years=years_map[filters.periodicity]) + + if accumulated_values: + start, end = add_to_date(start_date, years=-1), add_to_date(period['to_date'], years=-1) + else: + start, end = add_to_date(**date_info), add_to_date(**date_info) + + 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 name IN %s + OR parent_account IN %s) + """, (company, start, end, account_names, account_names)) + else: + 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 name IN %s + OR parent_account IN %s) + """, (company, start_date if accumulated_values else period['from_date'], + period['to_date'], account_names, account_names)) + + if gl_sum and gl_sum[0]: + amount = gl_sum[0] + else: + amount = 0 + + total += amount + data.setdefault(period["key"], amount) + + data["total"] = total + return data + + +def _add_total_row_account(out, data, label, period_list, currency, indent=0.0): + total_row = { + "indent": indent, + "account_name": "'" + _("{0}").format(label) + "'", + "account": "'" + _("{0}").format(label) + "'", + "currency": currency + } + 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) + + total_row.setdefault("total", 0.0) + total_row["total"] += row["total"] + + out.append(total_row) + out.append({}) 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 89ee63aa649..466562b8690 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 @@ -36,8 +36,8 @@ def execute(filters=None): def get_net_profit_loss(income, expense, period_list, company): total = 0 net_profit_loss = { - "account_name": "'" + _("Net Profit / Loss") + "'", - "account": "'" + _("Net Profit / Loss") + "'", + "account_name": "'" + _("Profit for the year") + "'", + "account": "'" + _("Profit for the year") + "'", "warn_if_negative": True, "currency": frappe.db.get_value("Company", company, "default_currency") } diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapper-1.png b/erpnext/docs/assets/img/articles/cash-flow-mapper-1.png new file mode 100644 index 00000000000..c6b37b175ad Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapper-1.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapper-2.png b/erpnext/docs/assets/img/articles/cash-flow-mapper-2.png new file mode 100644 index 00000000000..b3ba12d416d Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapper-2.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapper-3.png b/erpnext/docs/assets/img/articles/cash-flow-mapper-3.png new file mode 100644 index 00000000000..f494ecb7560 Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapper-3.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapper-4.png b/erpnext/docs/assets/img/articles/cash-flow-mapper-4.png new file mode 100644 index 00000000000..8f94b87d835 Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapper-4.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapper-5.png b/erpnext/docs/assets/img/articles/cash-flow-mapper-5.png new file mode 100644 index 00000000000..39371e670c5 Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapper-5.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapper-6.png b/erpnext/docs/assets/img/articles/cash-flow-mapper-6.png new file mode 100644 index 00000000000..08472cac41e Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapper-6.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapping-1.png b/erpnext/docs/assets/img/articles/cash-flow-mapping-1.png new file mode 100644 index 00000000000..e724b5b9bb0 Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapping-1.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapping-10.png b/erpnext/docs/assets/img/articles/cash-flow-mapping-10.png new file mode 100644 index 00000000000..b9ca66f255f Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapping-10.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapping-2.png b/erpnext/docs/assets/img/articles/cash-flow-mapping-2.png new file mode 100644 index 00000000000..89adfb9e4ab Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapping-2.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapping-3.png b/erpnext/docs/assets/img/articles/cash-flow-mapping-3.png new file mode 100644 index 00000000000..45595f0b494 Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapping-3.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapping-4.png b/erpnext/docs/assets/img/articles/cash-flow-mapping-4.png new file mode 100644 index 00000000000..0be7f2079d0 Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapping-4.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapping-5.png b/erpnext/docs/assets/img/articles/cash-flow-mapping-5.png new file mode 100644 index 00000000000..fc5173275eb Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapping-5.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapping-7.png b/erpnext/docs/assets/img/articles/cash-flow-mapping-7.png new file mode 100644 index 00000000000..6bf3043ab51 Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapping-7.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapping-8.png b/erpnext/docs/assets/img/articles/cash-flow-mapping-8.png new file mode 100644 index 00000000000..f945a7d215b Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapping-8.png differ diff --git a/erpnext/docs/assets/img/articles/cash-flow-mapping-9.png b/erpnext/docs/assets/img/articles/cash-flow-mapping-9.png new file mode 100644 index 00000000000..5928909bdd3 Binary files /dev/null and b/erpnext/docs/assets/img/articles/cash-flow-mapping-9.png differ diff --git a/erpnext/docs/assets/img/articles/default-cash-flow-report.png b/erpnext/docs/assets/img/articles/default-cash-flow-report.png new file mode 100644 index 00000000000..804178124bf Binary files /dev/null and b/erpnext/docs/assets/img/articles/default-cash-flow-report.png differ diff --git a/erpnext/docs/assets/img/articles/final-cash-flow.png b/erpnext/docs/assets/img/articles/final-cash-flow.png new file mode 100644 index 00000000000..88821c465bc Binary files /dev/null and b/erpnext/docs/assets/img/articles/final-cash-flow.png differ diff --git a/erpnext/docs/assets/img/articles/format-1.png b/erpnext/docs/assets/img/articles/format-1.png new file mode 100644 index 00000000000..e504455001c Binary files /dev/null and b/erpnext/docs/assets/img/articles/format-1.png differ diff --git a/erpnext/docs/assets/img/articles/format-2.png b/erpnext/docs/assets/img/articles/format-2.png new file mode 100644 index 00000000000..c997f99da3c Binary files /dev/null and b/erpnext/docs/assets/img/articles/format-2.png differ diff --git a/erpnext/docs/assets/img/articles/new-cash-flow-mapping.png b/erpnext/docs/assets/img/articles/new-cash-flow-mapping.png new file mode 100644 index 00000000000..df269bca032 Binary files /dev/null and b/erpnext/docs/assets/img/articles/new-cash-flow-mapping.png differ diff --git a/erpnext/docs/assets/img/articles/no-mappers.png b/erpnext/docs/assets/img/articles/no-mappers.png new file mode 100644 index 00000000000..4dd000f134f Binary files /dev/null and b/erpnext/docs/assets/img/articles/no-mappers.png differ diff --git a/erpnext/docs/user/manual/en/accounts/articles/how-to-customise-cash-flow-report.md b/erpnext/docs/user/manual/en/accounts/articles/how-to-customise-cash-flow-report.md new file mode 100644 index 00000000000..ed4262ae023 --- /dev/null +++ b/erpnext/docs/user/manual/en/accounts/articles/how-to-customise-cash-flow-report.md @@ -0,0 +1,156 @@ +# How To Customise Cash Flow Report + +As your chart of accounts begins to get more complex and reporting standards change and evolve, the default cash flow +report might no longer suffice. This is because ERPNext might not be able to accurately guess the classification and +purpose of all accounts in the charts of accounts. Another gripe you might have is the inability to adjust the report +format to fit your needs. + +This will no longer be a problem because ERPNext now allows users to customise the cash flow report. + + +## Technical Overview +Customisation is made possible by the introduction of two new doctypes - Cash Flow Mapper and Cash Flow Mapping. Both +doctypes contain the information required to generate a cash flow report. + +Cash Flow Mapping shows how accounts in your charts of accounts map to a line item in your cash flow report while +Cash Flow Mapper gets all the Cash Flow Mappings that relate to the three sections of a cash flow statement. + +With this, you generate detailed cash flow reports to your requirements. This might not make a lot of sense but it will +after we go through an example. + +## Example +### Background information +Let's assume we have a fictitious company for which we want to generate a cash flow report. +This is what the cash flow report looks like at the moment: +Default cash flow report + +We don't like the report for the following reasons: +- The reporting format is too scant. +- The 'Net Cash From Operations' figure is wrong + +### Customisation Process + +We wants the Cash Flow Report to look something similar to the format in the images below: +cash flow format 1 +cash flow format 1 + +#### Activate Customised Cash Flow Report +Do this in Accounts Settings by checking the 'Use Custom Cash Flow Format' checkbox. This will cause ERPNext to only +use your custom format for cash flow reports. + +After doing that, your cash flow report should look like this: +custom cash flow statement + +Move to the next section to build the report. + +#### Create Cash Flow Mappings +For each line, we need to create a Cash Flow Mapping document to represent it. + +new cash flow mapping form + +You can think of the Cash Flow Mapping as a representation of each line in the cash flow report. A Cash Flow Mapping +is a child of a Cash Flow Mapper which will be explained later. + +Let's start by creating Cash Flow Mappings that will represent the add back of non cash expenses already recodgnised in +the Profit or Loss statement. We want them to appear on the cash statement as: +- Income taxes recognised in profit or loss +- Finance costs recognised in profit or loss +- Depreciation of non-current assets + +Start by opening a new Cash Flow Mapping form. + +The fields in the Cash Flow Mapping doctype are: +- **Name**: This something to identify this document. Name it something related to the label +- **Label**: This is what will show in the cash flow statement +- **Accounts**: This table contains all the accounts which this line relates to. + +With this information, let's go ahead and create the Cash Flow Mapping Document for the line 'Income taxes recognised in profit or loss' + +custom cash flow statement + +I have named it 'Income Tax Charge' and given it a label 'Income taxes recognised in profit or loss'. We want this +line to reflect income tax charges from our profit or loss statement. The account where this happens in our chart +of account is named 'Income Taxes' (an expense) so I have added 'Income Taxes' into the accounts table. If you have +more accounts representing income tax expenses, you should add all of them here. + +Because Income Tax expense needs to be adjusted further in the cash flow statement, check the 'Is Income Tax Expense' +checkbox. This is what will help ERPNext properly calculate the adjustments to be made. + +*For best results, let parent accounts have child accounts that have the same treatment for cash flow reporting +purposes because ERPNext will calculate net change of all children accounts in a situation where the selected account +is a parent account.* + +In the same way, I have created for the remaining two mappings. + +custom cash flow statement + +Finance costs also need to be adjusted so make sure to check the 'Is Finance Cost' checkbox. + +custom cash flow statement + +Next let's add Cash Flow Mapping for items that show changes in working capital: +- Increase/(decrease) in other liabilities +- (Increase)/decrease in trade and other receivables +- Increase/(decrease) in trade and other payables +- VAT payable +- (Increase)/decrease in inventory + +custom cash flow statement + +custom cash flow statement + +custom cash flow statement + +custom cash flow statement + +custom cash flow statement + +Don't forget to tell ERPNext that these mappings represent changes in working capital by checking the 'Is Working +Capital' checkbox. + +At this point we have created all the mappings necessary for the Operating Activities section of our cash flow +statement. However, ERPNext doesn't know that yet until we create Cash Flow Mapper documents. We'll create Cash Flow +Mapper documents next. + + +#### Create Cash Flow Mappers +Cash Flow Mappers represents the sections of the cash flow statement. A standard cash flow statement has only three +sections so when you view the Cash Flow Mapper list, you will that three have been created for you named: +- Operating Activities +- Financing Activities +- Investing Activities + +You will not be able to add or remove any of them but they are editable and can be renamed. +cash flow mapper list + + +Open the Operating Activities Cash Flow Mapper so we can add the Cash Flow Mappings we have created. + + +- **Section Name**: This is the heading of the section. +- **Section Leader**: This is the first sub-header immediately after the profit figure. Relates only to Operating +Activities Cash Flow Mapper +- **Section Subtotal**: This is the label for subtotal in the cash flow statement section. Relates only to Operating +Activities Cash Flow Mapper +- **Section Footer**: This is the label for the total in the cash flow statement section. +- **Mapping**: This table contains all the Cash Flow Mappings related to the Cash Flow Mapper. + +Now add all the Cash Flow Mappings you have created and Save. You should have something like this: +cash flow mapper for operating activities + + Refresh the cash flow statement and view the changes. +updated cash flow report + +Looks close to our requirements but we are not done yet. Create new mappings for 'Investing Activities' and 'Financing +Activities' sections of the cash flow statement. + +cash flow mapping + +cash flow mapping + +cash flow mapper for operating activities + +cash flow mapper for operating activities + +Here's what our cash flow statement now looks like: +final cash flow statement diff --git a/erpnext/patches.txt b/erpnext/patches.txt index b365e961b46..c4e39496016 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -502,5 +502,6 @@ erpnext.patches.v10_0.update_translatable_fields erpnext.patches.v10_0.rename_offer_letter_to_job_offer execute:frappe.delete_doc('DocType', 'Production Planning Tool', ignore_missing=True) erpnext.patches.v10_0.migrate_daily_work_summary_settings_to_daily_work_summary_group +erpnext.patches.v10_0.add_default_cash_flow_mappers erpnext.patches.v11_0.make_quality_inspection_template erpnext.patches.v10_0.update_territory_and_customer_group diff --git a/erpnext/patches/v10_0/add_default_cash_flow_mappers.py b/erpnext/patches/v10_0/add_default_cash_flow_mappers.py new file mode 100644 index 00000000000..d607b2f745e --- /dev/null +++ b/erpnext/patches/v10_0/add_default_cash_flow_mappers.py @@ -0,0 +1,15 @@ +# Copyright (c) 2017, Frappe and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals + +import frappe +from erpnext.setup.install import create_default_cash_flow_mapper_templates + + +def execute(): + frappe.reload_doc('accounts', 'doctype', frappe.scrub('Cash Flow Mapping')) + frappe.reload_doc('accounts', 'doctype', frappe.scrub('Cash Flow Mapper')) + frappe.reload_doc('accounts', 'doctype', frappe.scrub('Cash Flow Mapping Template Details')) + + create_default_cash_flow_mapper_templates() diff --git a/erpnext/setup/install.py b/erpnext/setup/install.py index 0c93be99e79..8548f92dfa7 100644 --- a/erpnext/setup/install.py +++ b/erpnext/setup/install.py @@ -4,6 +4,7 @@ from __future__ import print_function, unicode_literals import frappe +from erpnext.accounts.doctype.cash_flow_mapper.default_cash_flow_mapper import DEFAULT_MAPPERS from frappe import _ from frappe.desk.page.setup_wizard.setup_wizard import add_all_roles_to from frappe.custom.doctype.custom_field.custom_field import create_custom_field @@ -11,14 +12,17 @@ from frappe.custom.doctype.custom_field.custom_field import create_custom_field default_mail_footer = """
Sent via ERPNext
""" + def after_install(): frappe.get_doc({'doctype': "Role", "role_name": "Analytics"}).insert() set_single_defaults() create_compact_item_print_custom_field() create_print_zero_amount_taxes_custom_field() add_all_roles_to("Administrator") + create_default_cash_flow_mapper_templates() frappe.db.commit() + def check_setup_wizard_not_completed(): if frappe.db.get_default('desktop:home_page') == 'desktop': print() @@ -27,6 +31,7 @@ def check_setup_wizard_not_completed(): print() return False + def set_single_defaults(): for dt in ('Accounts Settings', 'Print Settings', 'HR Settings', 'Buying Settings', 'Selling Settings', 'Stock Settings'): @@ -45,6 +50,7 @@ def set_single_defaults(): frappe.db.set_default("date_format", "dd-mm-yyyy") + def create_compact_item_print_custom_field(): create_custom_field('Print Settings', { 'label': _('Compact Item Print'), @@ -54,6 +60,7 @@ def create_compact_item_print_custom_field(): 'insert_after': 'with_letterhead' }) + def create_print_zero_amount_taxes_custom_field(): create_custom_field('Print Settings', { 'label': _('Print taxes with zero amount'), @@ -61,4 +68,13 @@ def create_print_zero_amount_taxes_custom_field(): 'fieldtype': 'Check', 'default': 0, 'insert_after': 'allow_print_for_cancelled' - }) \ No newline at end of file + }) + + +def create_default_cash_flow_mapper_templates(): + mappers = DEFAULT_MAPPERS + + for mapper in mappers: + if not frappe.db.exists('Cash Flow Mapper', mapper['section_name']): + doc = frappe.get_doc(mapper) + doc.insert(ignore_permissions=True)