fix(buying): make Purchase Order Analysis GROUP BY Postgres-valid

get_data() grouped only by Purchase Order Item while selecting Purchase
Order parent columns. MariaDB allows this loose GROUP BY; Postgres rejects
it with "column ... must appear in the GROUP BY clause".

Add the Purchase Order PK (po.name) to the GROUP BY. po.name is 1:1 with
the already-grouped po_item.name, so groups are unchanged and the result
is identical on MariaDB.

Adds a test (no test file existed) that runs the report and asserts the PO
is listed, exercising the GROUP BY on both engines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mihir Kandoi
2026-06-21 04:40:35 +05:30
parent 8b4845d272
commit 0b4e52e8d7
2 changed files with 31 additions and 1 deletions

View File

@@ -71,7 +71,9 @@ def get_data(filters):
po_item.name,
)
.where((po_item.parent == po.name) & (po.status.notin(("Stopped", "On Hold"))) & (po.docstatus == 1))
.groupby(po_item.name)
# the selected po.* columns need the Purchase Order PK grouped on postgres; po.name is 1:1
# with the grouped po_item.name, so groups are unchanged.
.groupby(po_item.name, po.name)
.orderby(po.transaction_date)
)

View File

@@ -0,0 +1,28 @@
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
from frappe.utils import add_days, nowdate
from erpnext.tests.utils import ERPNextTestSuite
class TestPurchaseOrderAnalysis(ERPNextTestSuite):
def test_report_executes_and_lists_po(self):
# get_data groups by (Purchase Order Item, Purchase Order) while selecting other parent
# columns; this exercises that GROUP BY so the report stays valid on Postgres (which rejects
# selecting non-grouped columns).
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
from erpnext.buying.report.purchase_order_analysis.purchase_order_analysis import execute
po = create_purchase_order(company="_Test Company")
filters = {
"company": "_Test Company",
"from_date": add_days(nowdate(), -1),
"to_date": add_days(nowdate(), 1),
}
result = execute(filters)
columns, data = result[0], result[1]
self.assertTrue(columns)
self.assertIn(po.name, {row.get("purchase_order") for row in data})