From 812a06cf44139da98b296d281aff9c315c5a3191 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Wed, 17 Jun 2026 13:18:59 +0530 Subject: [PATCH] fix(postgres): satisfy strict GROUP BY in Requested Items To Order And Receive report Wrap the non-aggregated, functionally-dependent column(s) in Max()/Min() (or add them to GROUP BY) so the report's grouped query is valid under PostgreSQL's strict GROUP BY. No behaviour change on MariaDB. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../requested_items_to_order_and_receive.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py b/erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py index 55189a722a3..b6f9bb13795 100644 --- a/erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py +++ b/erpnext/buying/report/requested_items_to_order_and_receive/requested_items_to_order_and_receive.py @@ -6,7 +6,7 @@ import copy import frappe from frappe import _ -from frappe.query_builder.functions import Coalesce, Sum +from frappe.query_builder.functions import Coalesce, Max, Sum from frappe.utils import cint, date_diff, flt, getdate @@ -44,13 +44,15 @@ def get_data(filters): .on(mr_item.parent == mr.name) .select( mr.name.as_("material_request"), - mr.transaction_date.as_("date"), - mr_item.schedule_date.as_("required_date"), + # non-grouped columns are constant per grouped mr.name / item_code -> Max() keeps the + # GROUP BY valid on postgres while returning the same value MySQL picked. + Max(mr.transaction_date).as_("date"), + Max(mr_item.schedule_date).as_("required_date"), mr_item.item_code.as_("item_code"), Sum(Coalesce(mr_item.qty, 0)).as_("qty"), Sum(Coalesce(mr_item.stock_qty, 0)).as_("stock_qty"), - Coalesce(mr_item.uom, "").as_("uom"), - Coalesce(mr_item.stock_uom, "").as_("stock_uom"), + Max(Coalesce(mr_item.uom, "")).as_("uom"), + Max(Coalesce(mr_item.stock_uom, "")).as_("stock_uom"), Sum(Coalesce(mr_item.ordered_qty, 0)).as_("ordered_qty"), Sum(Coalesce(mr_item.received_qty, 0)).as_("received_qty"), (Sum(Coalesce(mr_item.stock_qty, 0)) - Sum(Coalesce(mr_item.received_qty, 0))).as_( @@ -58,9 +60,9 @@ def get_data(filters): ), Sum(Coalesce(mr_item.received_qty, 0)).as_("received_qty"), (Sum(Coalesce(mr_item.stock_qty, 0)) - Sum(Coalesce(mr_item.ordered_qty, 0))).as_("qty_to_order"), - mr_item.item_name, - mr_item.description, - mr.company, + Max(mr_item.item_name).as_("item_name"), + Max(mr_item.description).as_("description"), + Max(mr.company).as_("company"), ) .where( (mr.material_request_type == "Purchase") @@ -72,7 +74,7 @@ def get_data(filters): query = get_conditions(filters, query, mr, mr_item) # add conditional conditions - query = query.groupby(mr.name, mr_item.item_code).orderby(mr.transaction_date, mr.schedule_date) + query = query.groupby(mr.name, mr_item.item_code).orderby(Max(mr.transaction_date), Max(mr.schedule_date)) data = query.run(as_dict=True) return data