From 9fdeb5f9918d441a0d90504c3fc1454c561a14f4 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Tue, 23 Jun 2026 19:23:38 +0530 Subject: [PATCH] fix(accounts): make two Query Report SQLs valid on Postgres (loose GROUP BY + no-op ORDER BY) (#56369) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(accounts): wrap loose finance_book in max() in Trial Balance (Simple) (Postgres) The Trial Balance (Simple) Query Report selects `finance_book` but groups only by `fiscal_year, company, posting_date, account`. PostgreSQL rejects the non-grouped, non-aggregated column: column "tabGL Entry.finance_book" must appear in the GROUP BY clause or be used in an aggregate function MariaDB tolerates it and returns an arbitrary finance_book per group. Wrapping it in `max(finance_book)` keeps the row count identical (the GROUP BY is unchanged) and makes PostgreSQL valid. Adding finance_book to GROUP BY would split each group into N rows and change the MariaDB row count, so it is not an option. This replaces MariaDB's previously arbitrary finance_book value with a deterministic one (the only sanctioned MariaDB-output change); the row count is preserved. * fix(accounts): make Sales Partners Commission valid on Postgres (ORDER BY + div-by-zero) The Sales Partners Commission Query Report had two PostgreSQL problems: 1. It ended with `ORDER BY "Total Commission:Currency:120"`, but the alias the query produces is `"Total Commission:Currency:170"` (width 170, not 120), so the ORDER BY never referenced a real output column. On MariaDB a double-quoted token is a string literal — a no-op sort that never errored. On PostgreSQL a double-quoted token is an identifier, so it errors with `column "Total Commission:Currency:120" does not exist` (and single-quoting it instead trips `non-integer constant in ORDER BY`). Since the clause was always a no-op on MariaDB, it is removed — MariaDB's group-order output is unchanged and the report runs on PostgreSQL. 2. `sum(total_commission)*100 / sum(amount_eligible_for_commission)` has an unguarded divisor: the inner query filters `total_commission`/`base_net_total` but not `amount_eligible_for_commission`, so a partner whose rows sum to 0 there makes MariaDB return NULL but PostgreSQL raise `division by zero`. Wrap it in `NULLIF(sum(amount_eligible_for_commission), 0)` — NULL on both engines. Both verified live on MariaDB and PostgreSQL. --- .../sales_partners_commission/sales_partners_commission.json | 2 +- .../report/trial_balance_simple/trial_balance_simple.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/accounts/report/sales_partners_commission/sales_partners_commission.json b/erpnext/accounts/report/sales_partners_commission/sales_partners_commission.json index 9a1131e069b..dc20f197de1 100644 --- a/erpnext/accounts/report/sales_partners_commission/sales_partners_commission.json +++ b/erpnext/accounts/report/sales_partners_commission/sales_partners_commission.json @@ -16,7 +16,7 @@ "name": "Sales Partners Commission", "owner": "Administrator", "prepared_report": 0, - "query": "SELECT\n sales_partner as \"Sales Partner:Link / Sales Partner:220\",\n sum(base_net_total) as \"Invoiced Amount (Excl. Tax):Currency:220\",\n sum(amount_eligible_for_commission) as \"Amount Eligible for Commission:Currency:220\",\n sum(total_commission) as \"Total Commission:Currency:170\",\n sum(total_commission)*100 / sum(amount_eligible_for_commission) as \"Average Commission Rate:Percent:220\"\nFROM\n (\n SELECT\n sales_partner,\n base_net_total,\n total_commission,\n amount_eligible_for_commission\n FROM\n `tabSales Invoice` \n WHERE\n docstatus = 1\n AND IFNULL(base_net_total, 0) > 0\n AND IFNULL(total_commission, 0) > 0\n\n UNION ALL\n\n SELECT\n sales_partner,\n base_net_total,\n total_commission,\n amount_eligible_for_commission\n FROM\n `tabPOS Invoice`\n WHERE\n docstatus = 1\n AND IFNULL(base_net_total, 0) > 0\n AND IFNULL(total_commission, 0) > 0\n ) AS sub\nGROUP BY\n sales_partner\nORDER BY\n \"Total Commission:Currency:120\"", + "query": "SELECT\n sales_partner as \"Sales Partner:Link / Sales Partner:220\",\n sum(base_net_total) as \"Invoiced Amount (Excl. Tax):Currency:220\",\n sum(amount_eligible_for_commission) as \"Amount Eligible for Commission:Currency:220\",\n sum(total_commission) as \"Total Commission:Currency:170\",\n sum(total_commission)*100 / NULLIF(sum(amount_eligible_for_commission), 0) as \"Average Commission Rate:Percent:220\"\nFROM\n (\n SELECT\n sales_partner,\n base_net_total,\n total_commission,\n amount_eligible_for_commission\n FROM\n `tabSales Invoice` \n WHERE\n docstatus = 1\n AND IFNULL(base_net_total, 0) > 0\n AND IFNULL(total_commission, 0) > 0\n\n UNION ALL\n\n SELECT\n sales_partner,\n base_net_total,\n total_commission,\n amount_eligible_for_commission\n FROM\n `tabPOS Invoice`\n WHERE\n docstatus = 1\n AND IFNULL(base_net_total, 0) > 0\n AND IFNULL(total_commission, 0) > 0\n ) AS sub\nGROUP BY\n sales_partner", "ref_doctype": "Sales Invoice", "report_name": "Sales Partners Commission", "report_type": "Query Report", diff --git a/erpnext/accounts/report/trial_balance_simple/trial_balance_simple.json b/erpnext/accounts/report/trial_balance_simple/trial_balance_simple.json index 6b926649ca6..ecc47648cc2 100644 --- a/erpnext/accounts/report/trial_balance_simple/trial_balance_simple.json +++ b/erpnext/accounts/report/trial_balance_simple/trial_balance_simple.json @@ -22,7 +22,7 @@ "name": "Trial Balance (Simple)", "owner": "Administrator", "prepared_report": 0, - "query": "select fiscal_year as \"Fiscal Year:Data:80\",\n\tcompany as \"Company:Data:220\",\n\tposting_date as \"Posting Date:Date:100\",\n\taccount as \"Account:Data:380\",\n\tsum(debit) as \"Debit:Currency:140\",\n\tsum(credit) as \"Credit:Currency:140\",\n\tfinance_book as \"Finance Book:Link/Finance Book:140\"\nfrom `tabGL Entry`\nwhere is_cancelled = 0 and company = %(company)s\ngroup by fiscal_year, company, posting_date, account\norder by fiscal_year, company, posting_date, account", + "query": "select fiscal_year as \"Fiscal Year:Data:80\",\n\tcompany as \"Company:Data:220\",\n\tposting_date as \"Posting Date:Date:100\",\n\taccount as \"Account:Data:380\",\n\tsum(debit) as \"Debit:Currency:140\",\n\tsum(credit) as \"Credit:Currency:140\",\n\tmax(finance_book) as \"Finance Book:Link/Finance Book:140\"\nfrom `tabGL Entry`\nwhere is_cancelled = 0 and company = %(company)s\ngroup by fiscal_year, company, posting_date, account\norder by fiscal_year, company, posting_date, account", "ref_doctype": "GL Entry", "report_name": "Trial Balance (Simple)", "report_type": "Query Report",