mirror of
https://github.com/frappe/erpnext.git
synced 2026-03-23 13:12:22 +01:00
perf: optimize account balance data fetching for Chart Of Accounts
This commit is contained in:
@@ -52,60 +52,55 @@ 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;
|
||||
on_node_render: function (node, deep) {
|
||||
const render_balances = () => {
|
||||
for (let account of cur_tree.account_balance_data) {
|
||||
const node = cur_tree.nodes && cur_tree.nodes[account.value];
|
||||
if (!node || node.is_root) continue;
|
||||
|
||||
let accounts = [];
|
||||
if (deep) {
|
||||
// in case of `get_all_nodes`
|
||||
accounts = nodes.reduce((acc, node) => [...acc, ...node.data], []);
|
||||
} else {
|
||||
accounts = nodes;
|
||||
}
|
||||
// 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);
|
||||
|
||||
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
|
||||
if (value) {
|
||||
const get_balances = frappe.call({
|
||||
method: "erpnext.accounts.utils.get_account_balances",
|
||||
args: {
|
||||
accounts: accounts,
|
||||
company: cur_tree.args.company,
|
||||
include_default_fb_balances: true,
|
||||
},
|
||||
});
|
||||
|
||||
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) {
|
||||
node.parent && node.parent.find(".balance-area").remove();
|
||||
$(
|
||||
'<span class="balance-area pull-right">' +
|
||||
(account.balance_in_account_currency
|
||||
? format(
|
||||
account.balance_in_account_currency,
|
||||
account.account_currency
|
||||
) + " / "
|
||||
: "") +
|
||||
format(account.balance, account.company_currency) +
|
||||
" " +
|
||||
dr_or_cr +
|
||||
"</span>"
|
||||
).insertBefore(node.$ul);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (account.balance !== undefined) {
|
||||
node.parent && node.parent.find(".balance-area").remove();
|
||||
$(
|
||||
'<span class="balance-area pull-right">' +
|
||||
(account.account_currency != account.company_currency
|
||||
? format(account.balance_in_account_currency, account.account_currency) +
|
||||
" / "
|
||||
: "") +
|
||||
format(account.balance, account.company_currency) +
|
||||
" " +
|
||||
dr_or_cr +
|
||||
"</span>"
|
||||
).insertBefore(node.$ul);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
|
||||
if (!cur_tree.account_balance_data) {
|
||||
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
|
||||
if (value) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.utils.get_account_balances_coa",
|
||||
args: {
|
||||
company: cur_tree.args.company,
|
||||
include_default_fb_balances: true,
|
||||
},
|
||||
callback: function (r) {
|
||||
if (!r.message || r.message.length === 0) return;
|
||||
cur_tree.account_balance_data = r.message || [];
|
||||
render_balances();
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
render_balances();
|
||||
}
|
||||
},
|
||||
add_tree_node: "erpnext.accounts.utils.add_ac",
|
||||
menu_items: [
|
||||
|
||||
@@ -1414,6 +1414,78 @@ def get_account_balances(
|
||||
return accounts
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_account_balances_coa(company: str, include_default_fb_balances: bool = False):
|
||||
company_currency = frappe.get_cached_value("Company", company, "default_currency")
|
||||
|
||||
Account = DocType("Account")
|
||||
account_list = (
|
||||
frappe.qb.from_(Account)
|
||||
.select(Account.name, Account.parent_account, Account.account_currency)
|
||||
.where(Account.company == company)
|
||||
.orderby(Account.lft)
|
||||
.run(as_dict=True)
|
||||
)
|
||||
|
||||
account_balances_cc = {account.get("name"): 0 for account in account_list}
|
||||
|
||||
account_balances_ac = {account.get("name"): 0 for account in account_list}
|
||||
|
||||
GLEntry = DocType("GL Entry")
|
||||
precision = get_currency_precision()
|
||||
get_ledger_balances_query = (
|
||||
frappe.qb.from_(GLEntry)
|
||||
.select(
|
||||
GLEntry.account,
|
||||
(Sum(Round(GLEntry.debit, precision)) - Sum(Round(GLEntry.credit, precision))).as_("balance"),
|
||||
(
|
||||
Sum(Round(GLEntry.debit_in_account_currency, precision))
|
||||
- Sum(Round(GLEntry.credit_in_account_currency, precision))
|
||||
).as_("balance_in_account_currency"),
|
||||
)
|
||||
.groupby(GLEntry.account)
|
||||
)
|
||||
|
||||
condition_list = [GLEntry.company == company, GLEntry.is_cancelled == 0]
|
||||
|
||||
default_finance_book = None
|
||||
|
||||
if include_default_fb_balances:
|
||||
default_finance_book = frappe.get_cached_value("Company", company, "default_finance_book")
|
||||
|
||||
if default_finance_book:
|
||||
condition_list.append(
|
||||
(GLEntry.finance_book == default_finance_book) | (GLEntry.finance_book.isnull())
|
||||
)
|
||||
|
||||
for condition in condition_list:
|
||||
get_ledger_balances_query = get_ledger_balances_query.where(condition)
|
||||
|
||||
ledger_balances = get_ledger_balances_query.run(as_dict=True)
|
||||
|
||||
for ledger_entry in ledger_balances:
|
||||
account_balances_cc[ledger_entry.get("account")] = ledger_entry.get("balance")
|
||||
account_balances_ac[ledger_entry.get("account")] = ledger_entry.get("balance_in_account_currency")
|
||||
|
||||
for account in reversed(account_list):
|
||||
parent = account.get("parent_account")
|
||||
if parent:
|
||||
account_balances_cc[parent] += account_balances_cc.get(account.get("name"))
|
||||
|
||||
accounts_data = [
|
||||
{
|
||||
"value": account.get("name"),
|
||||
"company_currency": company_currency,
|
||||
"balance": account_balances_cc.get(account.get("name")),
|
||||
"account_currency": account.get("account_currency"),
|
||||
"balance_in_account_currency": account_balances_ac.get(account.get("name")),
|
||||
}
|
||||
for account in account_list
|
||||
]
|
||||
|
||||
return accounts_data
|
||||
|
||||
|
||||
def create_payment_gateway_account(gateway, payment_channel="Email", company=None):
|
||||
from erpnext.setup.setup_wizard.operations.install_fixtures import create_bank_account
|
||||
|
||||
|
||||
Reference in New Issue
Block a user