From ea28b69ed44c07406197f0bd7364d521749bfcd6 Mon Sep 17 00:00:00 2001 From: "B.E.N.S.O.N" Date: Mon, 23 Mar 2026 17:00:21 +0800 Subject: [PATCH] FG/Semi-FG Production Report Update --- .../SemiFGProductionAnalysisReportService.kt | 109 ++++++++++++------ 1 file changed, 73 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/ffii/fpsms/modules/report/service/SemiFGProductionAnalysisReportService.kt b/src/main/java/com/ffii/fpsms/modules/report/service/SemiFGProductionAnalysisReportService.kt index 1c45389..3861af1 100644 --- a/src/main/java/com/ffii/fpsms/modules/report/service/SemiFGProductionAnalysisReportService.kt +++ b/src/main/java/com/ffii/fpsms/modules/report/service/SemiFGProductionAnalysisReportService.kt @@ -119,42 +119,79 @@ class SemiFGProductionAnalysisReportService( } else "" val sql = """ - SELECT - COALESCE(ic.sub, '') as stockSubCategory, - COALESCE(sl.itemCode, '') as itemNo, - COALESCE(b.name, '') as itemName, - COALESCE(uc.udfudesc, '') as unitOfMeasure, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 1 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyJan, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 2 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyFeb, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 3 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyMar, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 4 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyApr, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 5 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyMay, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 6 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyJun, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 7 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyJul, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 8 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyAug, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 9 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtySep, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 10 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyOct, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 11 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyNov, - CAST(COALESCE(SUM(CASE WHEN MONTH(si.productionDate) = 12 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyDec, - CAST(COALESCE(SUM(sl.inQty), 0) AS CHAR) as totalProductionQty - FROM stock_ledger sl - INNER JOIN bom b ON sl.itemCode = b.code AND b.deleted = false - INNER JOIN stock_in_line si ON si.id = sl.stockInLineId AND si.deleted = false AND si.productionDate IS NOT NULL - LEFT JOIN items it ON sl.itemId = it.id - LEFT JOIN item_category ic ON it.categoryId = ic.id - LEFT JOIN item_uom iu ON it.id = iu.itemId AND iu.stockUnit = true - LEFT JOIN uom_conversion uc ON iu.uomId = uc.id - WHERE sl.deleted = false - AND sl.inQty IS NOT NULL - AND sl.inQty > 0 - $stockCategorySql - $stockSubCategorySql - $itemCodeSql - $yearSql - $lastOutDateStartSql - $lastOutDateEndSql - GROUP BY sl.itemCode, ic.sub, it.id, b.name, uc.udfudesc, b.description - ORDER BY ic.sub, sl.itemCode + WITH base AS ( + SELECT + COALESCE(sl.itemCode, '') as itemNo, + COALESCE(b.name, '') as itemName, + COALESCE(ic.sub, '') as stockSubCategory, + COALESCE(uc.udfudesc, '') as unitOfMeasure, + MONTH(si.productionDate) as mon, + si.id as stockInLineId, + si.acceptedQty as acceptedQty, + si.jobOrderId as jobOrderId + FROM stock_ledger sl + INNER JOIN bom b + ON sl.itemCode = b.code AND b.deleted = false + INNER JOIN stock_in_line si + ON si.id = sl.stockInLineId + AND si.deleted = false + AND si.productionDate IS NOT NULL + LEFT JOIN items it + ON sl.itemId = it.id + LEFT JOIN item_category ic + ON it.categoryId = ic.id + LEFT JOIN item_uom iu + ON it.id = iu.itemId + AND iu.stockUnit = true + LEFT JOIN uom_conversion uc + ON iu.uomId = uc.id + WHERE sl.deleted = false + AND sl.inQty IS NOT NULL + AND sl.inQty > 0 + $stockCategorySql + $stockSubCategorySql + $itemCodeSql + $yearSql + $lastOutDateStartSql + $lastOutDateEndSql + ), + -- Deduplicate: stock_in_line can join to multiple stock_ledger rows; acceptedQty must be counted once per stockInLineId. + dedup AS ( + SELECT + itemNo, + itemName, + stockSubCategory, + unitOfMeasure, + mon, + stockInLineId, + MAX(COALESCE(acceptedQty, 0)) as acceptedQty, + MAX(jobOrderId) as jobOrderId + FROM base + GROUP BY itemNo, itemName, stockSubCategory, unitOfMeasure, mon, stockInLineId + ) + SELECT + MAX(d.stockSubCategory) as stockSubCategory, + d.itemNo as itemNo, + MAX(d.itemName) as itemName, + MAX(d.unitOfMeasure) as unitOfMeasure, + CAST(COALESCE(SUM(CASE WHEN d.mon = 1 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyJan, + CAST(COALESCE(SUM(CASE WHEN d.mon = 2 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyFeb, + CAST(COALESCE(SUM(CASE WHEN d.mon = 3 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyMar, + CAST(COALESCE(SUM(CASE WHEN d.mon = 4 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyApr, + CAST(COALESCE(SUM(CASE WHEN d.mon = 5 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyMay, + CAST(COALESCE(SUM(CASE WHEN d.mon = 6 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyJun, + CAST(COALESCE(SUM(CASE WHEN d.mon = 7 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyJul, + CAST(COALESCE(SUM(CASE WHEN d.mon = 8 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyAug, + CAST(COALESCE(SUM(CASE WHEN d.mon = 9 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtySep, + CAST(COALESCE(SUM(CASE WHEN d.mon = 10 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyOct, + CAST(COALESCE(SUM(CASE WHEN d.mon = 11 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyNov, + CAST(COALESCE(SUM(CASE WHEN d.mon = 12 AND d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyDec, + -- Keep as CHAR for Jasper compatibility (previous template expects String). + CAST(COALESCE(SUM(CASE WHEN d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) AS CHAR) as totalProductionQty + FROM dedup d + GROUP BY d.itemNo + HAVING COALESCE(SUM(CASE WHEN d.jobOrderId IS NOT NULL AND TRIM(CAST(d.jobOrderId AS CHAR)) <> '' THEN d.acceptedQty ELSE 0 END), 0) > 0 + ORDER BY d.itemNo """.trimIndent() return jdbcDao.queryForList(sql, args)