Merge pull request #56277 from mihir-kandoi/pg-sales-register-colorder

fix(accounts): keep Sales Register account-column order MariaDB-faithful on both engines
This commit is contained in:
Mihir Kandoi
2026-06-22 07:49:49 +05:30
committed by GitHub
2 changed files with 40 additions and 3 deletions

View File

@@ -347,14 +347,17 @@ def get_account_columns(invoice_list, include_payments):
if invoice_list:
# frappe drops ORDER BY for distinct queries on postgres (db_query), so sort in python to keep
# the generated account-column order deterministic and identical on both backends.
# the generated account-column order deterministic and identical on both backends. casefold
# reproduces MariaDB's case-insensitive collation order (the original raw SQL ORDER BY); plain
# sorted() would be case-sensitive and reorder columns vs the pre-effort MariaDB output.
income_accounts = sorted(
frappe.get_all(
"Sales Invoice Item",
filters={"docstatus": 1, "parent": ["in", [inv.name for inv in invoice_list]]},
pluck="income_account",
distinct=True,
)
),
key=str.casefold,
)
sales_taxes_query = get_taxes_query(invoice_list, "Sales Taxes and Charges", "Sales Invoice")
@@ -377,7 +380,8 @@ def get_account_columns(invoice_list, include_payments):
},
pluck="unrealized_profit_loss_account",
distinct=True,
)
),
key=str.casefold,
)
for account in income_accounts:

View File

@@ -55,6 +55,39 @@ class TestItemWiseSalesRegister(ERPNextTestSuite, AccountsTestMixin):
si = si.submit()
return si
def _ensure_income_account(self, account_name):
name = f"{account_name} - _TC"
if not frappe.db.exists("Account", name):
frappe.get_doc(
{
"doctype": "Account",
"account_name": account_name,
"parent_account": "Income - _TC",
"company": self.company,
"root_type": "Income",
"report_type": "Profit and Loss",
"account_type": "Income Account",
}
).insert()
return name
def test_income_account_columns_sorted_case_insensitively(self):
# The dynamic income-account columns must follow MariaDB's case-insensitive collation order and
# be identical on both engines. Plain python sorted() is case-sensitive (ASCII), so "ZZZ" would
# sort before "aaa"; casefold restores the pre-effort MariaDB order on both backends.
lower = self._ensure_income_account("aaa Test Income")
upper = self._ensure_income_account("ZZZ Test Income")
for account in (upper, lower): # submit in non-casefold order
si = self.create_sales_invoice(do_not_submit=True)
si.items[0].income_account = account
si.submit()
filters = frappe._dict({"from_date": today(), "to_date": today(), "company": self.company})
columns = execute(filters)[0]
labels = [col["label"] for col in columns if col.get("label") in (lower, upper)]
self.assertEqual(labels, sorted([lower, upper], key=str.casefold))
def test_basic_report_output(self):
si = self.create_sales_invoice(rate=98)