fix(postgres): satisfy strict GROUP BY in production plan sub-assembly queries

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Mihir Kandoi
2026-06-17 14:05:54 +05:30
parent 85191d1cac
commit 725fd8ca97

View File

@@ -4,7 +4,7 @@
"""Sub-assembly resolution helpers for Production Plan."""
import frappe
from frappe.query_builder.functions import IfNull, Sum
from frappe.query_builder.functions import IfNull, Max, Sum
from frappe.utils import flt
from erpnext.manufacturing.doctype.bom.bom import get_children as get_bom_children
@@ -184,24 +184,27 @@ def _sub_assembly_rm_query(company, bom_no, include_non_stock_items, planned_qty
def _sub_assembly_rm_columns(bei, bom, item, item_default, item_uom, planned_qty):
# only item_code/stock_uom are grouped; every other column is functionally dependent on the
# grouped item (item attributes) or arbitrary per BOM Item on MySQL -> Max() keeps the GROUP BY
# valid on postgres while returning the same value MySQL picked.
return [
(IfNull(Sum(bei.stock_qty / IfNull(bom.quantity, 1)), 0) * planned_qty).as_("qty"),
item.item_name,
item.name.as_("item_code"),
bei.description,
Max(item.item_name).as_("item_name"),
Max(item.name).as_("item_code"),
Max(bei.description).as_("description"),
bei.stock_uom,
bei.is_phantom_item,
bei.bom_no,
item.min_order_qty,
bei.source_warehouse,
item.default_material_request_type,
item.min_order_qty,
item_default.default_warehouse,
item.purchase_uom,
item_uom.conversion_factor,
item.safety_stock,
bom.item.as_("main_bom_item"),
bom.name.as_("main_bom"),
Max(bei.is_phantom_item).as_("is_phantom_item"),
Max(bei.bom_no).as_("bom_no"),
Max(item.min_order_qty).as_("min_order_qty"),
Max(bei.source_warehouse).as_("source_warehouse"),
Max(item.default_material_request_type).as_("default_material_request_type"),
Max(item.min_order_qty).as_("min_order_qty"),
Max(item_default.default_warehouse).as_("default_warehouse"),
Max(item.purchase_uom).as_("purchase_uom"),
Max(item_uom.conversion_factor).as_("conversion_factor"),
Max(item.safety_stock).as_("safety_stock"),
Max(bom.item).as_("main_bom_item"),
Max(bom.name).as_("main_bom"),
]