From a3ec98a57c971ae210f6e72723ae7669c84393d8 Mon Sep 17 00:00:00 2001 From: Mihir Kandoi Date: Wed, 17 Jun 2026 13:19:02 +0530 Subject: [PATCH] fix(postgres): satisfy strict GROUP BY in Process Loss Report 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) --- .../process_loss_report/process_loss_report.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/erpnext/manufacturing/report/process_loss_report/process_loss_report.py b/erpnext/manufacturing/report/process_loss_report/process_loss_report.py index 73560dd939b..2ba9f4742fd 100644 --- a/erpnext/manufacturing/report/process_loss_report/process_loss_report.py +++ b/erpnext/manufacturing/report/process_loss_report/process_loss_report.py @@ -4,7 +4,7 @@ import frappe from frappe import _ -from frappe.query_builder.functions import Sum +from frappe.query_builder.functions import Max, Sum Filters = frappe._dict Row = frappe._dict @@ -29,12 +29,14 @@ def get_data(filters: Filters) -> Data: .inner_join(se) .on(wo.name == se.work_order) .select( - wo.name, - wo.status, - wo.production_item, - wo.produced_qty, - wo.process_loss_qty, - wo.qty.as_("qty_to_manufacture"), + # grouped by se.work_order (== wo.name); the work-order columns are constant per group -> + # Max() keeps the GROUP BY valid on postgres with the same value. + Max(wo.name).as_("name"), + Max(wo.status).as_("status"), + Max(wo.production_item).as_("production_item"), + Max(wo.produced_qty).as_("produced_qty"), + Max(wo.process_loss_qty).as_("process_loss_qty"), + Max(wo.qty).as_("qty_to_manufacture"), Sum(se.total_incoming_value).as_("total_fg_value"), Sum(se.total_outgoing_value).as_("total_rm_value"), )