mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-16 16:08:39 +00:00
fix(manufacturing): make Work Order Stock report GROUP BY Postgres-valid
get_item_list() computes build_qty as IfNull(bin.actual_qty * bom.quantity / bom_item.stock_qty, 0) while grouping only by bom_item.item_code. The three operand columns are neither grouped nor aggregated, so MariaDB arbitrary-picks them but Postgres rejects the query with "column ... must appear in the GROUP BY clause". Add bom.quantity, bom_item.stock_qty and bin.actual_qty to the GROUP BY. The WHERE pins bom/item and the join pins warehouse to single rows (Bin is unique per item+warehouse), so the result stays one row per item and MariaDB behaviour is unchanged. Adds a test (no test file existed) that runs the report against a Work Order and asserts it is listed, exercising the query on both engines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# Copyright (c) 2017, Velometro Mobility Inc and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
import frappe
|
||||
|
||||
from erpnext.tests.utils import ERPNextTestSuite
|
||||
|
||||
|
||||
class TestWorkOrderStockReport(ERPNextTestSuite):
|
||||
def test_report_executes_and_lists_work_order(self):
|
||||
# get_item_list computes build_qty by multiplying bin/bom/bom_item columns that are not
|
||||
# functionally dependent on the grouped item_code; they must be in the GROUP BY for the
|
||||
# report to run on Postgres. This exercises that query on both engines.
|
||||
from erpnext.manufacturing.doctype.work_order.test_work_order import make_wo_order_test_record
|
||||
from erpnext.manufacturing.report.work_order_stock_report.work_order_stock_report import execute
|
||||
|
||||
wo = make_wo_order_test_record(
|
||||
production_item="_Test FG Item", qty=1, source_warehouse="_Test Warehouse - _TC"
|
||||
)
|
||||
|
||||
columns, data = execute(frappe._dict(warehouse="_Test Warehouse - _TC"))
|
||||
|
||||
self.assertTrue(columns)
|
||||
self.assertIn(wo.name, {row["work_order"] for row in data})
|
||||
@@ -47,7 +47,10 @@ def get_item_list(wo_list, filters):
|
||||
& (bom_item.item_code == wo_item_details.item_code)
|
||||
& (bom.name == wo_details.bom_no)
|
||||
)
|
||||
.groupby(bom_item.item_code)
|
||||
# build_qty multiplies columns from bin/bom/bom_item that aren't functionally
|
||||
# dependent on the grouped item_code, so postgres requires them in the GROUP BY.
|
||||
# The WHERE pins bom, item and warehouse to single rows, so this stays one row.
|
||||
.groupby(bom_item.item_code, bom.quantity, bom_item.stock_qty, bin.actual_qty)
|
||||
).run(as_dict=1)
|
||||
|
||||
stock_qty = 0
|
||||
|
||||
Reference in New Issue
Block a user