Skip to content

Commit aaea4df

Browse files
authored
Merge pull request #54100 from frappe/version-16-hotfix
2 parents ddef35c + 7b91566 commit aaea4df

136 files changed

Lines changed: 4541 additions & 1959 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

erpnext/accounts/doctype/account/account_tree.js

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -52,60 +52,55 @@ frappe.treeview_settings["Account"] = {
5252
],
5353
root_label: "Accounts",
5454
get_tree_nodes: "erpnext.accounts.utils.get_children",
55-
on_get_node: function (nodes, deep = false) {
56-
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
57-
58-
let accounts = [];
59-
if (deep) {
60-
// in case of `get_all_nodes`
61-
accounts = nodes.reduce((acc, node) => [...acc, ...node.data], []);
62-
} else {
63-
accounts = nodes;
64-
}
65-
66-
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
67-
if (value) {
68-
const get_balances = frappe.call({
69-
method: "erpnext.accounts.utils.get_account_balances",
70-
args: {
71-
accounts: accounts,
72-
company: cur_tree.args.company,
73-
include_default_fb_balances: true,
74-
},
75-
});
76-
77-
get_balances.then((r) => {
78-
if (!r.message || r.message.length == 0) return;
79-
80-
for (let account of r.message) {
81-
const node = cur_tree.nodes && cur_tree.nodes[account.value];
82-
if (!node || node.is_root) continue;
55+
on_node_render: function (node, deep) {
56+
const render_balances = () => {
57+
for (let account of cur_tree.account_balance_data) {
58+
const node = cur_tree.nodes && cur_tree.nodes[account.value];
59+
if (!node || node.is_root) continue;
8360

84-
// show Dr if positive since balance is calculated as debit - credit else show Cr
85-
const balance = account.balance_in_account_currency || account.balance;
86-
const dr_or_cr = balance > 0 ? __("Dr") : __("Cr");
87-
const format = (value, currency) => format_currency(Math.abs(value), currency);
61+
// show Dr if positive since balance is calculated as debit - credit else show Cr
62+
const balance = account.balance_in_account_currency || account.balance;
63+
const dr_or_cr = balance > 0 ? __("Dr") : __("Cr");
64+
const format = (value, currency) => format_currency(Math.abs(value), currency);
8865

89-
if (account.balance !== undefined) {
90-
node.parent && node.parent.find(".balance-area").remove();
91-
$(
92-
'<span class="balance-area pull-right">' +
93-
(account.balance_in_account_currency
94-
? format(
95-
account.balance_in_account_currency,
96-
account.account_currency
97-
) + " / "
98-
: "") +
99-
format(account.balance, account.company_currency) +
100-
" " +
101-
dr_or_cr +
102-
"</span>"
103-
).insertBefore(node.$ul);
104-
}
105-
}
106-
});
66+
if (account.balance !== undefined) {
67+
node.parent && node.parent.find(".balance-area").remove();
68+
$(
69+
'<span class="balance-area pull-right">' +
70+
(account.account_currency != account.company_currency
71+
? format(account.balance_in_account_currency, account.account_currency) +
72+
" / "
73+
: "") +
74+
format(account.balance, account.company_currency) +
75+
" " +
76+
dr_or_cr +
77+
"</span>"
78+
).insertBefore(node.$ul);
79+
}
10780
}
108-
});
81+
};
82+
83+
if (frappe.boot.user.can_read.indexOf("GL Entry") == -1) return;
84+
if (!cur_tree.account_balance_data) {
85+
frappe.db.get_single_value("Accounts Settings", "show_balance_in_coa").then((value) => {
86+
if (value) {
87+
frappe.call({
88+
method: "erpnext.accounts.utils.get_account_balances_coa",
89+
args: {
90+
company: cur_tree.args.company,
91+
include_default_fb_balances: true,
92+
},
93+
callback: function (r) {
94+
if (!r.message || r.message.length === 0) return;
95+
cur_tree.account_balance_data = r.message || [];
96+
render_balances();
97+
},
98+
});
99+
}
100+
});
101+
} else {
102+
render_balances();
103+
}
109104
},
110105
add_tree_node: "erpnext.accounts.utils.add_ac",
111106
menu_items: [

erpnext/accounts/doctype/account_category/account_category.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,13 @@
2626
],
2727
"grid_page_length": 50,
2828
"index_web_pages_for_search": 1,
29-
"links": [],
30-
"modified": "2025-10-15 03:19:47.171349",
29+
"links": [
30+
{
31+
"link_doctype": "Account",
32+
"link_fieldname": "account_category"
33+
}
34+
],
35+
"modified": "2026-02-23 01:19:49.589393",
3136
"modified_by": "Administrator",
3237
"module": "Accounts",
3338
"name": "Account Category",

erpnext/accounts/doctype/accounts_settings/accounts_settings.json

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
"payment_options_section",
6666
"enable_loyalty_point_program",
6767
"column_break_ctam",
68+
"fetch_payment_schedule_in_payment_request",
6869
"invoicing_settings_tab",
6970
"accounts_transactions_settings_section",
7071
"over_billing_allowance",
@@ -688,6 +689,19 @@
688689
"fieldname": "enable_accounting_dimensions",
689690
"fieldtype": "Check",
690691
"label": "Enable Accounting Dimensions"
692+
},
693+
{
694+
"default": "1",
695+
"description": "Enable Subscription tracking in invoice",
696+
"fieldname": "enable_subscription",
697+
"fieldtype": "Check",
698+
"label": "Enable Subscription"
699+
},
700+
{
701+
"default": "1",
702+
"fieldname": "fetch_payment_schedule_in_payment_request",
703+
"fieldtype": "Check",
704+
"label": "Fetch Payment Schedule In Payment Request"
691705
}
692706
],
693707
"grid_page_length": 50,
@@ -697,7 +711,7 @@
697711
"index_web_pages_for_search": 1,
698712
"issingle": 1,
699713
"links": [],
700-
"modified": "2026-02-27 01:04:09.415288",
714+
"modified": "2026-03-30 07:32:58.182018",
701715
"modified_by": "Administrator",
702716
"module": "Accounts",
703717
"name": "Accounts Settings",

erpnext/accounts/doctype/accounts_settings/accounts_settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ class AccountsSettings(Document):
7373
enable_loyalty_point_program: DF.Check
7474
enable_party_matching: DF.Check
7575
exchange_gain_loss_posting_date: DF.Literal["Invoice", "Payment", "Reconciliation Date"]
76+
fetch_payment_schedule_in_payment_request: DF.Check
7677
fetch_valuation_rate_for_internal_transaction: DF.Check
7778
general_ledger_remarks_length: DF.Int
7879
ignore_account_closing_balance: DF.Check

erpnext/accounts/doctype/advance_payment_ledger_entry/test_advance_payment_ledger_entry.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from erpnext.tests.utils import ERPNextTestSuite
1616

1717

18-
class TestAdvancePaymentLedgerEntry(AccountsTestMixin, ERPNextTestSuite):
18+
class TestAdvancePaymentLedgerEntry(ERPNextTestSuite, AccountsTestMixin):
1919
"""
2020
Integration tests for AdvancePaymentLedgerEntry.
2121
Use this class for testing interactions between multiple components.

erpnext/accounts/doctype/bank_reconciliation_tool/test_bank_reconciliation_tool.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from erpnext.tests.utils import ERPNextTestSuite
1616

1717

18-
class TestBankReconciliationTool(AccountsTestMixin, ERPNextTestSuite):
18+
class TestBankReconciliationTool(ERPNextTestSuite, AccountsTestMixin):
1919
def setUp(self):
2020
self.create_company()
2121
self.create_customer()

erpnext/accounts/doctype/bank_transaction/test_bank_transaction.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ def add_vouchers(gl_account="_Test Bank - _TC"):
382382
frappe.get_doc(
383383
{
384384
"doctype": "Customer",
385-
"customer_group": "All Customer Groups",
385+
"customer_group": "Individual",
386386
"customer_type": "Company",
387387
"customer_name": "Poore Simon's",
388388
}
@@ -413,7 +413,7 @@ def add_vouchers(gl_account="_Test Bank - _TC"):
413413
frappe.get_doc(
414414
{
415415
"doctype": "Customer",
416-
"customer_group": "All Customer Groups",
416+
"customer_group": "Individual",
417417
"customer_type": "Company",
418418
"customer_name": "Fayva",
419419
}

erpnext/accounts/doctype/bank_transaction/test_bank_transaction_fees.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
# See license.txt
33

44
import frappe
5-
from frappe.tests import UnitTestCase
65

6+
from erpnext.tests.utils import ERPNextTestSuite
77

8-
class TestBankTransactionFees(UnitTestCase):
8+
9+
class TestBankTransactionFees(ERPNextTestSuite):
910
def test_included_fee_throws(self):
1011
"""A fee that's part of a withdrawal cannot be bigger than the
1112
withdrawal itself."""

erpnext/accounts/doctype/exchange_rate_revaluation/test_exchange_rate_revaluation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from erpnext.tests.utils import ERPNextTestSuite
1414

1515

16-
class TestExchangeRateRevaluation(AccountsTestMixin, ERPNextTestSuite):
16+
class TestExchangeRateRevaluation(ERPNextTestSuite, AccountsTestMixin):
1717
def setUp(self):
1818
self.create_company()
1919
self.create_usd_receivable_account()

erpnext/accounts/doctype/financial_report_template/financial_report_template.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
frappe.ui.form.on("Financial Report Template", {
55
refresh(frm) {
6+
if (frm.is_new() || frm.doc.rows.length === 0) return;
7+
68
// add custom button to view missed accounts
79
frm.add_custom_button(__("View Account Coverage"), function () {
810
let selected_rows = frm.get_field("rows").grid.get_selected_children();
@@ -20,7 +22,7 @@ frappe.ui.form.on("Financial Report Template", {
2022
});
2123
},
2224

23-
validate(frm) {
25+
after_save(frm) {
2426
if (!frm.doc.rows || frm.doc.rows.length === 0) {
2527
frappe.msgprint(__("At least one row is required for a financial report template"));
2628
}
@@ -34,14 +36,6 @@ frappe.ui.form.on("Financial Report Row", {
3436
update_formula_label(frm, row.data_source);
3537
update_formula_description(frm, row.data_source);
3638

37-
if (row.data_source !== "Account Data") {
38-
frappe.model.set_value(cdt, cdn, "balance_type", "");
39-
}
40-
41-
if (["Blank Line", "Column Break", "Section Break"].includes(row.data_source)) {
42-
frappe.model.set_value(cdt, cdn, "calculation_formula", "");
43-
}
44-
4539
set_up_filters_editor(frm, cdt, cdn);
4640
},
4741

@@ -322,6 +316,8 @@ function update_formula_description(frm, data_source) {
322316
const list_style = `style="margin-bottom: var(--margin-sm); color: var(--text-muted); font-size: 0.9em;"`;
323317
const note_style = `style="margin-bottom: 0; color: var(--text-muted); font-size: 0.9em;"`;
324318
const tip_style = `style="margin-bottom: 0; color: var(--text-color); font-size: 0.85em;"`;
319+
const code_style = `style="background: var(--bg-light-gray); padding: var(--padding-xs); border-radius: var(--border-radius); font-size: 0.85em; width: max-content; margin-bottom: var(--margin-sm);"`;
320+
const pre_style = `style="margin: 0; border-radius: var(--border-radius)"`;
325321

326322
let description_html = "";
327323

@@ -382,8 +378,13 @@ function update_formula_description(frm, data_source) {
382378
<li><code>my_app.financial_reports.get_kpi_data</code></li>
383379
</ul>
384380
381+
<h6 ${subtitle_style}>Method Signature:</h6>
382+
<div ${code_style}>
383+
<pre ${pre_style}>def get_custom_data(filters, periods, row): <br>&nbsp; # filters: dict — report filters (company, period, etc.) <br>&nbsp; # periods: list[dict] — period definitions <br>&nbsp; # row: dict — the current report row <br><br>&nbsp; return [1000.0, 1200.0, 1150.0] # one value per period</pre>
384+
</div>
385+
385386
<h6 ${subtitle_style}>Return Format:</h6>
386-
<p ${text_style}>Numbers for each period: <code>[1000.0, 1200.0, 1150.0]</code></p>
387+
<p ${text_style}>A list of numbers, one for each period: <code>[1000.0, 1200.0, 1150.0]</code></p>
387388
</div>`;
388389
} else if (data_source === "Blank Line") {
389390
description_html = `

0 commit comments

Comments
 (0)