| @@ -60,7 +60,7 @@ class SemiFGProductionAnalysisReportService( | |||||
| * Flow: | * Flow: | ||||
| * 1. Filter bom by description (FG/WIP) to get bom.code values | * 1. Filter bom by description (FG/WIP) to get bom.code values | ||||
| * 2. Match bom.code with stock_ledger.itemCode | * 2. Match bom.code with stock_ledger.itemCode | ||||
| * 3. Aggregate stock_ledger data by month for each item based on inQty | |||||
| * 3. Join stock_in_line; aggregate by calendar month of stock_in_line.productionDate (完成生產日期), not stock_ledger.modified | |||||
| * Supports comma-separated values for stockCategory, stockSubCategory, and itemCode. | * Supports comma-separated values for stockCategory, stockSubCategory, and itemCode. | ||||
| */ | */ | ||||
| fun searchSemiFGProductionAnalysisReport( | fun searchSemiFGProductionAnalysisReport( | ||||
| @@ -101,7 +101,7 @@ class SemiFGProductionAnalysisReportService( | |||||
| val yearSql = if (!year.isNullOrBlank() && year != "All") { | val yearSql = if (!year.isNullOrBlank() && year != "All") { | ||||
| args["year"] = year | args["year"] = year | ||||
| "AND YEAR(sl.modified) = :year" | |||||
| "AND YEAR(si.productionDate) = :year" | |||||
| } else { | } else { | ||||
| "" | "" | ||||
| } | } | ||||
| @@ -109,13 +109,13 @@ class SemiFGProductionAnalysisReportService( | |||||
| val lastOutDateStartSql = if (!lastOutDateStart.isNullOrBlank()) { | val lastOutDateStartSql = if (!lastOutDateStart.isNullOrBlank()) { | ||||
| val formattedDate = lastOutDateStart.replace("/", "-") | val formattedDate = lastOutDateStart.replace("/", "-") | ||||
| args["lastOutDateStart"] = formattedDate | args["lastOutDateStart"] = formattedDate | ||||
| "AND DATE(sl.modified) >= DATE(:lastOutDateStart)" | |||||
| "AND DATE(si.productionDate) >= DATE(:lastOutDateStart)" | |||||
| } else "" | } else "" | ||||
| val lastOutDateEndSql = if (!lastOutDateEnd.isNullOrBlank()) { | val lastOutDateEndSql = if (!lastOutDateEnd.isNullOrBlank()) { | ||||
| val formattedDate = lastOutDateEnd.replace("/", "-") | val formattedDate = lastOutDateEnd.replace("/", "-") | ||||
| args["lastOutDateEnd"] = formattedDate | args["lastOutDateEnd"] = formattedDate | ||||
| "AND DATE(sl.modified) <= DATE(:lastOutDateEnd)" | |||||
| "AND DATE(si.productionDate) <= DATE(:lastOutDateEnd)" | |||||
| } else "" | } else "" | ||||
| val sql = """ | val sql = """ | ||||
| @@ -124,21 +124,22 @@ class SemiFGProductionAnalysisReportService( | |||||
| COALESCE(sl.itemCode, '') as itemNo, | COALESCE(sl.itemCode, '') as itemNo, | ||||
| COALESCE(b.name, '') as itemName, | COALESCE(b.name, '') as itemName, | ||||
| COALESCE(uc.udfudesc, '') as unitOfMeasure, | COALESCE(uc.udfudesc, '') as unitOfMeasure, | ||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 1 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyJan, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 2 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyFeb, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 3 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyMar, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 4 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyApr, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 5 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyMay, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 6 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyJun, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 7 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyJul, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 8 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyAug, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 9 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtySep, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 10 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyOct, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 11 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyNov, | |||||
| CAST(COALESCE(SUM(CASE WHEN MONTH(sl.modified) = 12 THEN sl.inQty ELSE 0 END), 0) AS DECIMAL(18,2)) as qtyDec, | |||||
| 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 | CAST(COALESCE(SUM(sl.inQty), 0) AS CHAR) as totalProductionQty | ||||
| FROM stock_ledger sl | FROM stock_ledger sl | ||||
| INNER JOIN bom b ON sl.itemCode = b.code AND b.deleted = false | 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 items it ON sl.itemId = it.id | ||||
| LEFT JOIN item_category ic ON it.categoryId = ic.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 item_uom iu ON it.id = iu.itemId AND iu.stockUnit = true | ||||