Merge pull request #56207 from mihir-kandoi/pg-buying-reports-groupby

fix(buying): make Procurement Tracker & PO Analysis reports Postgres-valid (GROUP BY)
This commit is contained in:
Mihir Kandoi
2026-06-21 07:32:58 +05:30
committed by GitHub
4 changed files with 47 additions and 3 deletions

View File

@@ -305,7 +305,9 @@ def get_po_entries(filters):
& (parent.name == child.parent)
& (parent.status.notin(("Closed", "Completed", "Cancelled")))
)
.groupby(parent.name, child.material_request_item)
# This is one row per PO item; the selected child.* columns are only functionally dependent
# on the child PK, which postgres requires in the GROUP BY (MariaDB allows omitting it).
.groupby(parent.name, child.material_request_item, child.name)
)
query = apply_filters_on_query(filters, parent, child, query)

View File

@@ -6,4 +6,16 @@ from erpnext.tests.utils import ERPNextTestSuite
class TestProcurementTracker(ERPNextTestSuite):
pass
def test_report_executes_and_lists_po(self):
# get_po_entries groups by (Purchase Order, material_request_item, Purchase Order Item)
# while selecting other child 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.procurement_tracker.procurement_tracker import execute
po = create_purchase_order(company="_Test Company")
columns, data = execute({"company": "_Test Company"})
self.assertTrue(columns)
self.assertIn(po.name, {row.get("purchase_order") for row in data})

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})