From 3111a66036fa8bc60a9c2f8557c9176bb217060b Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Mon, 27 Sep 2021 11:06:01 +0530 Subject: [PATCH 1/3] refactor: fetching of account balance in chart of accounts --- .../accounts/doctype/account/account_tree.js | 33 +++++++++++-------- erpnext/accounts/utils.py | 23 +++++++++---- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index 7516134baf54..0d6647a4e811 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -123,21 +123,28 @@ frappe.treeview_settings["Account"] = { }, "add"); }, onrender: function(node) { - if (frappe.boot.user.can_read.indexOf("GL Entry") !== -1) { + if (frappe.boot.user.can_read.indexOf("GL Entry") !== -1 && !node.is_root && node.data) { - // show Dr if positive since balance is calculated as debit - credit else show Cr - let balance = node.data.balance_in_account_currency || node.data.balance; - let dr_or_cr = balance > 0 ? "Dr": "Cr"; + frappe.call({ + method: 'erpnext.accounts.utils.get_account_balance', + args: {account: node.data, ...cur_tree.args}, + callback: function(r) { + let account = r.message; + // show Dr if positive since balance is calculated as debit - credit else show Cr + let balance = account.balance_in_account_currency || account.balance; + let dr_or_cr = balance > 0 ? "Dr": "Cr"; + let format = (value, currency) => format_currency(Math.abs(value), currency); - if (node.data && node.data.balance!==undefined) { - $('' - + (node.data.balance_in_account_currency ? - (format_currency(Math.abs(node.data.balance_in_account_currency), - node.data.account_currency) + " / ") : "") - + format_currency(Math.abs(node.data.balance), node.data.company_currency) - + " " + dr_or_cr - + '').insertBefore(node.$ul); - } + if (account.balance!==undefined) { + $('' + + (account.balance_in_account_currency ? + (format(account.balance_in_account_currency, account.account_currency) + " / ") : "") + + format(account.balance, account.company_currency) + + " " + dr_or_cr + + '').insertBefore(node.$ul); + } + } + }); } }, toolbar: [ diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index fbad171b7874..2226d35a6d9a 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -4,11 +4,14 @@ from __future__ import unicode_literals +from json import loads + import frappe import frappe.defaults from frappe import _, throw from frappe.model.meta import get_field_precision from frappe.utils import cint, cstr, flt, formatdate, get_number_format_info, getdate, now, nowdate +from six import string_types import erpnext @@ -787,16 +790,22 @@ def get_children(doctype, parent, company, is_root=False): if doctype == 'Account': sort_accounts(acc, is_root, key="value") - company_currency = frappe.get_cached_value('Company', company, "default_currency") - for each in acc: - each["company_currency"] = company_currency - each["balance"] = flt(get_balance_on(each.get("value"), in_account_currency=False, company=company)) - - if each.account_currency != company_currency: - each["balance_in_account_currency"] = flt(get_balance_on(each.get("value"), company=company)) return acc +@frappe.whitelist() +def get_account_balance(account, company): + if isinstance(account, string_types): + account = loads(account) + + company_currency = frappe.get_cached_value("Company", company, "default_currency") + account["company_currency"] = company_currency + account["balance"] = flt(get_balance_on(account["value"], in_account_currency=False, company=company)) + if account["account_currency"] and account["account_currency"] != company_currency: + account["balance_in_account_currency"] = flt(get_balance_on(account["value"], company=company)) + + return account + def create_payment_gateway_account(gateway, payment_channel="Email"): from erpnext.setup.setup_wizard.operations.install_fixtures import create_bank_account From 4519a85d05f88288851dbb6487975f415e045fb8 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 28 Sep 2021 18:01:32 +0530 Subject: [PATCH 2/3] refactor: fetching of account balances when node is expanded --- .../accounts/doctype/account/account_tree.js | 67 ++++++++++++------- erpnext/accounts/utils.py | 22 +++--- 2 files changed, 56 insertions(+), 33 deletions(-) diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index 0d6647a4e811..250907966060 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -45,6 +45,48 @@ frappe.treeview_settings["Account"] = { ], root_label: "Accounts", get_tree_nodes: 'erpnext.accounts.utils.get_children', + on_get_node: function(nodes, deep=false) { + if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return; + + if (deep) { + // in case of `get_all_nodes` + accounts = nodes.reduce((acc, node) => [...acc, ...node.data], []); + } else { + accounts = nodes; + } + + const get_balances = frappe.call({ + method: 'erpnext.accounts.utils.get_account_balances', + args: { + accounts: accounts, + company: cur_tree.args.company + }, + }); + + get_balances.then(r => { + if (!r.message || r.message.length == 0) return; + + for (let account of r.message) { + + const node = cur_tree.nodes && cur_tree.nodes[account.value]; + if (!node || node.is_root) continue; + + // show Dr if positive since balance is calculated as debit - credit else show Cr + const balance = account.balance_in_account_currency || account.balance; + const dr_or_cr = balance > 0 ? "Dr": "Cr"; + const format = (value, currency) => format_currency(Math.abs(value), currency); + + if (account.balance!==undefined) { + $('' + + (account.balance_in_account_currency ? + (format(account.balance_in_account_currency, account.account_currency) + " / ") : "") + + format(account.balance, account.company_currency) + + " " + dr_or_cr + + '').insertBefore(node.$ul); + } + } + }); + }, add_tree_node: 'erpnext.accounts.utils.add_ac', menu_items:[ { @@ -122,31 +164,6 @@ frappe.treeview_settings["Account"] = { } }, "add"); }, - onrender: function(node) { - if (frappe.boot.user.can_read.indexOf("GL Entry") !== -1 && !node.is_root && node.data) { - - frappe.call({ - method: 'erpnext.accounts.utils.get_account_balance', - args: {account: node.data, ...cur_tree.args}, - callback: function(r) { - let account = r.message; - // show Dr if positive since balance is calculated as debit - credit else show Cr - let balance = account.balance_in_account_currency || account.balance; - let dr_or_cr = balance > 0 ? "Dr": "Cr"; - let format = (value, currency) => format_currency(Math.abs(value), currency); - - if (account.balance!==undefined) { - $('' - + (account.balance_in_account_currency ? - (format(account.balance_in_account_currency, account.account_currency) + " / ") : "") - + format(account.balance, account.company_currency) - + " " + dr_or_cr - + '').insertBefore(node.$ul); - } - } - }); - } - }, toolbar: [ { label:__("Add Child"), diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 2226d35a6d9a..fdd8d092ebb5 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -794,17 +794,23 @@ def get_children(doctype, parent, company, is_root=False): return acc @frappe.whitelist() -def get_account_balance(account, company): - if isinstance(account, string_types): - account = loads(account) +def get_account_balances(accounts, company): + + if isinstance(accounts, string_types): + accounts = loads(accounts) + + if not accounts: + return [] company_currency = frappe.get_cached_value("Company", company, "default_currency") - account["company_currency"] = company_currency - account["balance"] = flt(get_balance_on(account["value"], in_account_currency=False, company=company)) - if account["account_currency"] and account["account_currency"] != company_currency: - account["balance_in_account_currency"] = flt(get_balance_on(account["value"], company=company)) - return account + for account in accounts: + account["company_currency"] = company_currency + account["balance"] = flt(get_balance_on(account["value"], in_account_currency=False, company=company)) + if account["account_currency"] and account["account_currency"] != company_currency: + account["balance_in_account_currency"] = flt(get_balance_on(account["value"], company=company)) + + return accounts def create_payment_gateway_account(gateway, payment_channel="Email"): from erpnext.setup.setup_wizard.operations.install_fixtures import create_bank_account From 68668e91a35ca37f4541ea97da19d8deac3a0284 Mon Sep 17 00:00:00 2001 From: Saqib Ansari Date: Tue, 28 Sep 2021 20:20:29 +0530 Subject: [PATCH 3/3] fix: sider --- erpnext/accounts/doctype/account/account_tree.js | 1 + 1 file changed, 1 insertion(+) diff --git a/erpnext/accounts/doctype/account/account_tree.js b/erpnext/accounts/doctype/account/account_tree.js index 250907966060..a4b6e0b45ae3 100644 --- a/erpnext/accounts/doctype/account/account_tree.js +++ b/erpnext/accounts/doctype/account/account_tree.js @@ -48,6 +48,7 @@ frappe.treeview_settings["Account"] = { on_get_node: function(nodes, deep=false) { if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return; + let accounts = []; if (deep) { // in case of `get_all_nodes` accounts = nodes.reduce((acc, node) => [...acc, ...node.data], []);