Selaa lähdekoodia

report add handler filter and bracket negative value

reset-do-picking-order
Tommy\2Fi-Staff 2 viikkoa sitten
vanhempi
commit
d12c5077cd
5 muutettua tiedostoa jossa 134 lisäystä ja 115 poistoa
  1. +66
    -40
      src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt
  2. +15
    -23
      src/main/java/com/ffii/fpsms/modules/report/service/StockLedgerReportService.kt
  3. +23
    -22
      src/main/java/com/ffii/fpsms/modules/report/service/StockTakeVarianceReportService.kt
  4. +16
    -4
      src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt
  5. +14
    -26
      src/main/resources/jasper/StockLedgarReport.jrxml

+ 66
- 40
src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt Näytä tiedosto

@@ -266,13 +266,45 @@ return result
}

fun getDistinctHandlersForFGStockOutTraceability(): List<String> {
val sql = """
SELECT DISTINCT COALESCE(picker_user.name, modified_user.name, '') AS handler
FROM stock_out_line sol
INNER JOIN stock_out so ON sol.stockOutId = so.id AND so.deleted = 0 AND so.type = 'do'
LEFT JOIN user picker_user ON sol.handled_by = picker_user.id AND picker_user.deleted = 0
LEFT JOIN user modified_user ON sol.modifiedBy = modified_user.staffNo AND modified_user.deleted = 0 AND sol.handled_by IS NULL
WHERE sol.deleted = 0
ORDER BY handler
""".trimIndent()
return jdbcDao.queryForList(sql, emptyMap<String, Any>()).map { row -> (row["handler"]?.toString() ?: "").trim() }.filter { it.isNotBlank() }
}

fun getDistinctHandlersForMaterialStockOutTraceability(): List<String> {
val sql = """
SELECT DISTINCT COALESCE(picker_user.name, jpo_handler_user.name, created_user.name, modified_user.name, '') AS handler
FROM stock_out_line sol
INNER JOIN stock_out so ON sol.stockOutId = so.id AND so.deleted = 0 AND so.type = 'job'
INNER JOIN pick_order_line pol ON sol.pickOrderLineId = pol.id AND pol.deleted = 0
INNER JOIN pick_order po ON pol.poId = po.id AND po.deleted = 0 AND po.type IN ('jo', 'JOB_ORDER') AND po.joId IS NOT NULL
LEFT JOIN user picker_user ON sol.handled_by = picker_user.id AND picker_user.deleted = 0
LEFT JOIN jo_pick_order jpo ON po.id = jpo.pick_order_id AND pol.itemId = jpo.item_id AND jpo.deleted = 0
LEFT JOIN user jpo_handler_user ON jpo.handled_by = jpo_handler_user.id AND jpo_handler_user.deleted = 0
LEFT JOIN user created_user ON sol.createdBy = created_user.username AND created_user.deleted = 0
LEFT JOIN user modified_user ON sol.modifiedBy = modified_user.staffNo AND modified_user.deleted = 0 AND sol.handled_by IS NULL
WHERE sol.deleted = 0
ORDER BY handler
""".trimIndent()
return jdbcDao.queryForList(sql, emptyMap<String, Any>()).map { row -> (row["handler"]?.toString() ?: "").trim() }.filter { it.isNotBlank() }
}

fun searchFGStockOutTraceabilityReport(
stockCategory: String?,
stockSubCategory: String?,
itemCode: String?,
year: String?,
lastOutDateStart: String?,
lastOutDateEnd: String?
lastOutDateEnd: String?,
handler: String?
): List<Map<String, Any>> {
val args = mutableMapOf<String, Any>()
@@ -316,6 +348,13 @@ return result
"AND DATE(IFNULL(dpor.RequiredDeliveryDate, do.estimatedArrivalDate)) <= DATE(:lastOutDateEnd)"
} else ""

val handlerSql = buildMultiValueExactClause(
handler,
"COALESCE(picker_user.name, modified_user.name, '')",
"handler",
args
)

val sql = """
SELECT
IFNULL(DATE_FORMAT(
@@ -416,6 +455,7 @@ return result
$yearSql
$lastOutDateStartSql
$lastOutDateEndSql
$handlerSql
GROUP BY
sol.id,
dpor.RequiredDeliveryDate,
@@ -469,7 +509,8 @@ fun searchMaterialStockOutTraceabilityReport(
itemCode: String?,
year: String?,
lastOutDateStart: String?,
lastOutDateEnd: String?
lastOutDateEnd: String?,
handler: String?
): List<Map<String, Any>> {
val args = mutableMapOf<String, Any>()

@@ -514,6 +555,13 @@ fun searchMaterialStockOutTraceabilityReport(
""
}

val handlerSql = buildMultiValueExactClause(
handler,
"COALESCE(picker_user.name, jpo_handler_user.name, created_user.name, modified_user.name, '')",
"handler",
args
)

val sql = """
SELECT
IFNULL(it.code, '') AS itemNo,
@@ -597,6 +645,7 @@ fun searchMaterialStockOutTraceabilityReport(
$yearSql
$lastOutDateStartSql
$lastOutDateEndSql
$handlerSql
ORDER BY
it.code,
il.lotNo,
@@ -706,7 +755,6 @@ fun searchMaterialStockOutTraceabilityReport(
} else ""

val sql = """

SELECT
COALESCE(it.code, '') as itemNo,
COALESCE(it.name, '') as itemName,
@@ -715,25 +763,13 @@ fun searchMaterialStockOutTraceabilityReport(
COALESCE(sil.lotNo, il.lotNo, '') as lotNo,
COALESCE(DATE_FORMAT(COALESCE(sil.expiryDate, il.expiryDate), '%Y-%m-%d'), '') as expiryDate,
CASE WHEN COALESCE(qr_agg.qcFailed, 0) = 1 THEN '0'
ELSE TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(
CASE WHEN sil.purchaseOrderId IS NOT NULL AND iu_purchase.id IS NOT NULL AND iu.id IS NOT NULL
THEN sil.acceptedQty * (iu_purchase.ratioN / NULLIF(iu_purchase.ratioD, 0)) / (iu.ratioN / NULLIF(iu.ratioD, 0))
ELSE sil.acceptedQty END, 0), 2)))
END as stockInQty,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(
CASE WHEN sil.purchaseOrderId IS NOT NULL AND iu_purchase.id IS NOT NULL AND iu.id IS NOT NULL
THEN sil.acceptedQty * (iu_purchase.ratioN / NULLIF(iu_purchase.ratioD, 0)) / (iu.ratioN / NULLIF(iu.ratioD, 0))
ELSE sil.acceptedQty END, 0), 2))) as iqcSampleQty,
ELSE TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(sil.acceptedQty, 0), 2)))
END as stockInQty,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(sil.acceptedQty, 0), 2))) as iqcSampleQty,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(qr_agg.failQtySum, 0), 2))) as iqcDefectQty,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(
CASE WHEN COALESCE(
CASE WHEN sil.purchaseOrderId IS NOT NULL AND iu_purchase.id IS NOT NULL AND iu.id IS NOT NULL
THEN sil.acceptedQty * (iu_purchase.ratioN / NULLIF(iu_purchase.ratioD, 0)) / (iu.ratioN / NULLIF(iu.ratioD, 0))
ELSE sil.acceptedQty END, 0) > 0
THEN COALESCE(qr_agg.failQtySum, 0) /
(CASE WHEN sil.purchaseOrderId IS NOT NULL AND iu_purchase.id IS NOT NULL AND iu.id IS NOT NULL
THEN sil.acceptedQty * (iu_purchase.ratioN / NULLIF(iu_purchase.ratioD, 0)) / (iu.ratioN / NULLIF(iu.ratioD, 0))
ELSE sil.acceptedQty END) * 100
CASE WHEN COALESCE(sil.acceptedQty, 0) > 0
THEN COALESCE(qr_agg.failQtySum, 0) / sil.acceptedQty * 100
ELSE 0
END, 2))) as iqcDefectPercentage,
CASE WHEN COALESCE(qr_agg.qcFailed, 0) = 1 THEN '不合格' ELSE '已接受' END as iqcResult,
@@ -742,24 +778,14 @@ fun searchMaterialStockOutTraceabilityReport(
COALESCE(wh.code, '') as storeLocation,
COALESCE(sp_si.code, sp_po.code, '') as supplierID,
COALESCE(sp_si.name, sp_po.name, '') as supplierName,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(
CASE WHEN sil.purchaseOrderId IS NOT NULL AND iu_purchase.id IS NOT NULL AND iu.id IS NOT NULL
THEN sil.acceptedQty * (iu_purchase.ratioN / NULLIF(iu_purchase.ratioD, 0)) / (iu.ratioN / NULLIF(iu.ratioD, 0))
ELSE sil.acceptedQty END, 0)) OVER (PARTITION BY it.id), 2))) as totalStockInQty,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(
CASE WHEN sil.purchaseOrderId IS NOT NULL AND iu_purchase.id IS NOT NULL AND iu.id IS NOT NULL
THEN sil.acceptedQty * (iu_purchase.ratioN / NULLIF(iu_purchase.ratioD, 0)) / (iu.ratioN / NULLIF(iu.ratioD, 0))
ELSE sil.acceptedQty END, 0)) OVER (PARTITION BY it.id), 2))) as totalIqcSampleQty
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(sil.acceptedQty, 0)) OVER (PARTITION BY it.id), 2))) as totalStockInQty,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(sil.acceptedQty, 0)) OVER (PARTITION BY it.id), 2))) as totalIqcSampleQty
FROM stock_in_line sil
LEFT JOIN stock_in si ON sil.stockInId = si.id
LEFT JOIN purchase_order po ON sil.purchaseOrderId = po.id
LEFT JOIN items it ON sil.itemId = it.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
LEFT JOIN item_uom iu_purchase
ON it.id = iu_purchase.itemId
AND iu_purchase.purchaseUnit = 1
AND iu_purchase.deleted = 0
LEFT JOIN inventory_lot il ON sil.inventoryLotId = il.id
LEFT JOIN inventory_lot_line ill ON il.id = ill.inventoryLotId
LEFT JOIN warehouse wh ON ill.warehouseId = wh.id
@@ -838,17 +864,17 @@ fun searchMaterialStockOutTraceabilityReport(
COALESCE(item_agg.storeLocation, '') as storeLocation,
COALESCE(DATE_FORMAT(item_agg.lastInDate, '%Y-%m-%d'), '') as lastInDate,
COALESCE(DATE_FORMAT(item_agg.lastOutDate, '%Y-%m-%d'), '') as lastOutDate,
FORMAT(ROUND(COALESCE(item_agg.totalOpeningBalance, 0), 0), 0) as totalOpeningBalance,
FORMAT(ROUND(COALESCE(item_agg.totalCumStockIn, 0), 0), 0) as totalCumStockIn,
FORMAT(ROUND(COALESCE(item_agg.totalCumStockOut, 0), 0), 0) as totalCumStockOut,
FORMAT(ROUND(COALESCE(item_agg.totalCurrentBalance, 0), 0), 0) as totalCurrentBalance,
CASE WHEN COALESCE(item_agg.totalOpeningBalance, 0) < 0 THEN CONCAT('(', FORMAT(-item_agg.totalOpeningBalance, 0), ')') ELSE FORMAT(COALESCE(item_agg.totalOpeningBalance, 0), 0) END as totalOpeningBalance,
CASE WHEN COALESCE(item_agg.totalCumStockIn, 0) < 0 THEN CONCAT('(', FORMAT(-item_agg.totalCumStockIn, 0), ')') ELSE FORMAT(COALESCE(item_agg.totalCumStockIn, 0), 0) END as totalCumStockIn,
CASE WHEN COALESCE(item_agg.totalCumStockOut, 0) < 0 THEN CONCAT('(', FORMAT(-item_agg.totalCumStockOut, 0), ')') ELSE FORMAT(COALESCE(item_agg.totalCumStockOut, 0), 0) END as totalCumStockOut,
CASE WHEN COALESCE(item_agg.totalCurrentBalance, 0) < 0 THEN CONCAT('(', FORMAT(-item_agg.totalCurrentBalance, 0), ')') ELSE FORMAT(COALESCE(item_agg.totalCurrentBalance, 0), 0) END as totalCurrentBalance,
'' as misInputAndLost,
'' as defectiveGoods,
'' as variance,
FORMAT(ROUND(COALESCE(item_agg.totalMisInputAndLost, 0), 0), 0) as totalMisInputAndLost,
FORMAT(ROUND(COALESCE(item_agg.totalVariance, 0), 0), 0) as totalVariance,
FORMAT(ROUND(COALESCE(item_agg.totalDefectiveGoods, 0), 0), 0) as totalDefectiveGoods,
FORMAT(ROUND(COALESCE(ipv.totalStockBalanceRaw, 0), 2), 0) as totalStockBalance,
CASE WHEN COALESCE(item_agg.totalMisInputAndLost, 0) < 0 THEN CONCAT('(', FORMAT(-item_agg.totalMisInputAndLost, 0), ')') ELSE FORMAT(COALESCE(item_agg.totalMisInputAndLost, 0), 0) END as totalMisInputAndLost,
CASE WHEN COALESCE(item_agg.totalVariance, 0) < 0 THEN CONCAT('(', FORMAT(-item_agg.totalVariance, 0), ')') ELSE FORMAT(COALESCE(item_agg.totalVariance, 0), 0) END as totalVariance,
CASE WHEN COALESCE(item_agg.totalDefectiveGoods, 0) < 0 THEN CONCAT('(', FORMAT(-item_agg.totalDefectiveGoods, 0), ')') ELSE FORMAT(COALESCE(item_agg.totalDefectiveGoods, 0), 0) END as totalDefectiveGoods,
FORMAT(ROUND(COALESCE(ipv.totalStockBalanceRaw, 0), 2), 2) as totalStockBalance,
CASE
WHEN COALESCE(item_agg.totalCurrentBalance, 0) > 0 AND ipv.totalStockBalanceRaw IS NOT NULL AND ipv.totalStockBalanceRaw <> 0
THEN FORMAT(ROUND(ipv.totalStockBalanceRaw / item_agg.totalCurrentBalance, 2), 2)


+ 15
- 23
src/main/java/com/ffii/fpsms/modules/report/service/StockLedgerReportService.kt Näytä tiedosto

@@ -255,35 +255,27 @@ SELECT
reOrderLevel,
reOrderQty,

-- jrxml 需要 String,避免 BigDecimal cast/trim 爆炸
CAST(CAST(inQty AS DECIMAL(20,0)) AS CHAR) AS stockIn,
CAST(CAST(outQty AS DECIMAL(20,0)) AS CHAR) AS stockOut,
-- jrxml 需要 String;負數括號顯示,無小數
CASE WHEN COALESCE(inQty, 0) < 0 THEN CONCAT('(', FORMAT(-inQty, 0), ')') ELSE FORMAT(COALESCE(inQty, 0), 0) END AS stockIn,
CASE WHEN COALESCE(outQty, 0) < 0 THEN CONCAT('(', FORMAT(-outQty, 0), ')') ELSE FORMAT(COALESCE(outQty, 0), 0) END AS stockOut,

-- 累計存量(跨 lot:只用 itemCode 分區)
CAST(CAST(
(openingBeforeStart
+ SUM(delta) OVER (PARTITION BY itemCode ORDER BY trnDateRaw, slId)
) AS DECIMAL(20,0)
) AS CHAR) AS cumBalance,
CASE WHEN (openingBeforeStart + SUM(delta) OVER (PARTITION BY itemCode ORDER BY trnDateRaw, slId)) < 0
THEN CONCAT('(', FORMAT(-(openingBeforeStart + SUM(delta) OVER (PARTITION BY itemCode ORDER BY trnDateRaw, slId)), 0), ')')
ELSE FORMAT(openingBeforeStart + SUM(delta) OVER (PARTITION BY itemCode ORDER BY trnDateRaw, slId), 0) END AS cumBalance,

-- 累計期初存量 = 本行累計 - 本行異動
CAST(CAST(
(openingBeforeStart
+ SUM(delta) OVER (PARTITION BY itemCode ORDER BY trnDateRaw, slId)
- delta
) AS DECIMAL(20,0)
) AS CHAR) AS cumOpeningBal,
CASE WHEN (openingBeforeStart + SUM(delta) OVER (PARTITION BY itemCode ORDER BY trnDateRaw, slId) - delta) < 0
THEN CONCAT('(', FORMAT(-(openingBeforeStart + SUM(delta) OVER (PARTITION BY itemCode ORDER BY trnDateRaw, slId) - delta), 0), ')')
ELSE FORMAT(openingBeforeStart + SUM(delta) OVER (PARTITION BY itemCode ORDER BY trnDateRaw, slId) - delta, 0) END AS cumOpeningBal,

-- footer totals(同樣輸出 String)
CAST(openingBeforeStart AS DECIMAL(20,0)) AS totalCumOpeningBal,
CAST(SUM(inQty) OVER (PARTITION BY itemCode) AS DECIMAL(20,0)) AS totalStockIn,
CAST(SUM(outQty) OVER (PARTITION BY itemCode) AS DECIMAL(20,0)) AS totalStockOut,
CAST(
(openingBeforeStart
+ SUM(inQty) OVER (PARTITION BY itemCode)
- SUM(outQty) OVER (PARTITION BY itemCode)
) AS DECIMAL(20,0)
) AS totalCumBalance
CASE WHEN COALESCE(openingBeforeStart, 0) < 0 THEN CONCAT('(', FORMAT(-openingBeforeStart, 0), ')') ELSE FORMAT(COALESCE(openingBeforeStart, 0), 0) END AS totalCumOpeningBal,
CASE WHEN SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemCode) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemCode), 0), ')') ELSE FORMAT(SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemCode), 0) END AS totalStockIn,
CASE WHEN SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemCode) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemCode), 0), ')') ELSE FORMAT(SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemCode), 0) END AS totalStockOut,
CASE WHEN (openingBeforeStart + SUM(inQty) OVER (PARTITION BY itemCode) - SUM(outQty) OVER (PARTITION BY itemCode)) < 0
THEN CONCAT('(', FORMAT(-(openingBeforeStart + SUM(inQty) OVER (PARTITION BY itemCode) - SUM(outQty) OVER (PARTITION BY itemCode)), 0), ')')
ELSE FORMAT(openingBeforeStart + SUM(inQty) OVER (PARTITION BY itemCode) - SUM(outQty) OVER (PARTITION BY itemCode), 0) END AS totalCumBalance

FROM period
ORDER BY


+ 23
- 22
src/main/java/com/ffii/fpsms/modules/report/service/StockTakeVarianceReportService.kt Näytä tiedosto

@@ -248,41 +248,42 @@ SELECT
expiryDate,
storeLocation,

/* 期初/累計/現存:jrxml 欄位全是 String */
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(openingQty, 0), 2))) AS openingBalance,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(inQty, 0), 2))) AS cumStockIn,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(outQty, 0), 2))) AS cumStockOut,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(currentQty, 0), 2))) AS currentBookBalance,
/* 期初/累計/現存:jrxml 欄位全是 String;負數括號顯示,無小數 */
CASE WHEN COALESCE(openingQty, 0) < 0 THEN CONCAT('(', FORMAT(-openingQty, 0), ')') ELSE FORMAT(COALESCE(openingQty, 0), 0) END AS openingBalance,
CASE WHEN COALESCE(inQty, 0) < 0 THEN CONCAT('(', FORMAT(-inQty, 0), ')') ELSE FORMAT(COALESCE(inQty, 0), 0) END AS cumStockIn,
CASE WHEN COALESCE(outQty, 0) < 0 THEN CONCAT('(', FORMAT(-outQty, 0), ')') ELSE FORMAT(COALESCE(outQty, 0), 0) END AS cumStockOut,
CASE WHEN COALESCE(currentQty, 0) < 0 THEN CONCAT('(', FORMAT(-currentQty, 0), ')') ELSE FORMAT(COALESCE(currentQty, 0), 0) END AS currentBookBalance,

COALESCE(DATE_FORMAT(lastInDateRaw, '%Y-%m-%d'), '') AS lastInDate,
COALESCE(DATE_FORMAT(lastOutDateRaw, '%Y-%m-%d'), '') AS lastOutDate,
COALESCE(DATE_FORMAT(stockTakeDateRaw, '%Y-%m-%d'), '') AS stockTakeDate,
/* 取貨量 = approverStockTakeQty(無盤點紀錄就空白) */
/* 取貨量 = approverStockTakeQty(無盤點紀錄顯示 0) */
CASE
WHEN stkApproverQty IS NULL THEN ''
ELSE TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(stkApproverQty, 0), 2)))
WHEN stkApproverQty IS NULL THEN '0'
WHEN COALESCE(stkApproverQty, 0) < 0 THEN CONCAT('(', FORMAT(-stkApproverQty, 0), ')')
ELSE FORMAT(COALESCE(stkApproverQty, 0), 0)
END AS stockTakeQty,

/* 超撿量 = varianceQty(無盤點紀錄就空白) */
/* 超撿量 = varianceQty(無盤點紀錄顯示 0) */
CASE
WHEN stkVarianceQty IS NULL THEN ''
ELSE TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(COALESCE(stkVarianceQty, 0), 2)))
WHEN stkVarianceQty IS NULL THEN '0'
WHEN COALESCE(stkVarianceQty, 0) < 0 THEN CONCAT('(', FORMAT(-stkVarianceQty, 0), ')')
ELSE FORMAT(COALESCE(stkVarianceQty, 0), 0)
END AS variance,

/* 盤盈虧百分比(無盤點或 bookQty=0 顯示 0%) */
CASE
WHEN stkVarianceQty IS NULL THEN ''
WHEN COALESCE(stkBookQty, 0) = 0 THEN ''
ELSE CONCAT(
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT((COALESCE(stkVarianceQty, 0) / stkBookQty) * 100, 2))),
'%'
)
WHEN stkVarianceQty IS NULL THEN '0%'
WHEN COALESCE(stkBookQty, 0) = 0 THEN '0%'
WHEN (COALESCE(stkVarianceQty, 0) / stkBookQty) * 100 < 0 THEN CONCAT('(', FORMAT(-(COALESCE(stkVarianceQty, 0) / stkBookQty) * 100, 0), '%)')
ELSE CONCAT(FORMAT((COALESCE(stkVarianceQty, 0) / stkBookQty) * 100, 0), '%')
END AS variancePercentage,

/* item totals(footer 用) */
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo), 2))) AS totalOpeningBalance,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo), 2))) AS totalCumStockIn,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo), 2))) AS totalCumStockOut,
TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(currentQty, 0)) OVER (PARTITION BY itemNo), 2))) AS totalCurrentBalance
/* item totals(footer 用);負數括號顯示,無小數 */
CASE WHEN SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo), 0), ')') ELSE FORMAT(SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo), 0) END AS totalOpeningBalance,
CASE WHEN SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo), 0), ')') ELSE FORMAT(SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo), 0) END AS totalCumStockIn,
CASE WHEN SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo), 0), ')') ELSE FORMAT(SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo), 0) END AS totalCumStockOut,
CASE WHEN SUM(COALESCE(currentQty, 0)) OVER (PARTITION BY itemNo) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(currentQty, 0)) OVER (PARTITION BY itemNo), 0), ')') ELSE FORMAT(SUM(COALESCE(currentQty, 0)) OVER (PARTITION BY itemNo), 0) END AS totalCurrentBalance

FROM data
ORDER BY


+ 16
- 4
src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt Näytä tiedosto

@@ -164,6 +164,14 @@ class ReportController(
return ResponseEntity(pdfBytes, headers, HttpStatus.OK)
}
@GetMapping("/fg-stock-out-traceability-handlers")
fun getFGStockOutTraceabilityHandlers(): List<String> =
reportService.getDistinctHandlersForFGStockOutTraceability()

@GetMapping("/material-stock-out-traceability-handlers")
fun getMaterialStockOutTraceabilityHandlers(): List<String> =
reportService.getDistinctHandlersForMaterialStockOutTraceability()

@GetMapping("/print-fg-stock-out-traceability")
fun generateFGStockOutTraceabilityReport(
@RequestParam(required = false) stockCategory: String?,
@@ -171,7 +179,8 @@ class ReportController(
@RequestParam(required = false) itemCode: String?,
@RequestParam(required = false) year: String?,
@RequestParam(required = false) lastOutDateStart: String?,
@RequestParam(required = false) lastOutDateEnd: String?
@RequestParam(required = false) lastOutDateEnd: String?,
@RequestParam(required = false) handler: String?
): ResponseEntity<ByteArray> {
val parameters = mutableMapOf<String, Any>()
@@ -193,7 +202,8 @@ class ReportController(
itemCode,
year,
lastOutDateStart,
lastOutDateEnd
lastOutDateEnd,
handler
)
val pdfBytes = reportService.createPdfResponse(
@@ -217,7 +227,8 @@ class ReportController(
@RequestParam(required = false) itemCode: String?,
@RequestParam(required = false) year: String?,
@RequestParam(required = false) lastOutDateStart: String?,
@RequestParam(required = false) lastOutDateEnd: String?
@RequestParam(required = false) lastOutDateEnd: String?,
@RequestParam(required = false) handler: String?
): ResponseEntity<ByteArray> {
val parameters = mutableMapOf<String, Any>()
@@ -239,7 +250,8 @@ class ReportController(
itemCode,
year,
lastOutDateStart,
lastOutDateEnd
lastOutDateEnd,
handler
)
val pdfBytes = reportService.createPdfResponse(


+ 14
- 26
src/main/resources/jasper/StockLedgarReport.jrxml Näytä tiedosto

@@ -57,10 +57,10 @@
<field name="cumStockIn" class="java.lang.String"/>
<field name="cumStockOut" class="java.lang.String"/>
<field name="currentBalance" class="java.lang.String"/>
<field name="totalStockIn" class="java.math.BigDecimal"/>
<field name="totalCumOpeningBal" class="java.math.BigDecimal"/>
<field name="totalStockOut" class="java.math.BigDecimal"/>
<field name="totalCumBalance" class="java.math.BigDecimal"/>
<field name="totalStockIn" class="java.lang.String"/>
<field name="totalCumOpeningBal" class="java.lang.String"/>
<field name="totalStockOut" class="java.lang.String"/>
<field name="totalCumBalance" class="java.lang.String"/>
<field name="lastOutDate" class="java.lang.String"/>
<field name="lastInDate" class="java.lang.String"/>
<field name="reOrderLevel" class="java.lang.String"/>
@@ -100,32 +100,32 @@
</textElement>
<text><![CDATA[貨品總量:]]></text>
</staticText>
<textField pattern="#,##0">
<textField>
<reportElement x="416" y="0" width="50" height="18" uuid="6c141d7d-766e-49bf-b987-e790312573a5">
<property name="com.jaspersoft.studio.unit.width" value="px"/>
</reportElement>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="微軟正黑體"/>
</textElement>
<textFieldExpression><![CDATA[$F{totalStockIn}]]></textFieldExpression>
<textFieldExpression><![CDATA[$F{totalStockIn} != null ? $F{totalStockIn} : ""]]></textFieldExpression>
</textField>
<textField textAdjust="StretchHeight" pattern="#,##0">
<textField textAdjust="StretchHeight">
<reportElement x="466" y="0" width="50" height="18" uuid="f6be72ca-650f-4c37-a149-26d5502be17a">
<property name="com.jaspersoft.studio.unit.width" value="px"/>
</reportElement>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="微軟正黑體"/>
</textElement>
<textFieldExpression><![CDATA[$F{totalStockOut}]]></textFieldExpression>
<textFieldExpression><![CDATA[$F{totalStockOut} != null ? $F{totalStockOut} : ""]]></textFieldExpression>
</textField>
<textField pattern="#,##0">
<textField>
<reportElement x="524" y="0" width="66" height="18" uuid="636bf782-3020-4b49-837e-53ede91d1443">
<property name="com.jaspersoft.studio.unit.width" value="px"/>
</reportElement>
<textElement textAlignment="Right" verticalAlignment="Middle">
<font fontName="微軟正黑體"/>
</textElement>
<textFieldExpression><![CDATA[$F{totalCumBalance}]]></textFieldExpression>
<textFieldExpression><![CDATA[$F{totalCumBalance} != null ? $F{totalCumBalance} : ""]]></textFieldExpression>
</textField>
<line>
<reportElement x="2" y="18" width="799" height="1" uuid="c31c2ebe-c7c9-4ad1-abc2-fa0ba99dd77f">
@@ -381,20 +381,14 @@
<textElement textAlignment="Right" verticalAlignment="Top">
<font fontName="微軟正黑體" size="10"/>
</textElement>
<textFieldExpression><![CDATA[$F{cumOpeningBal} == null || $F{cumOpeningBal}.trim().length() == 0
? ""
: new java.text.DecimalFormat("#,##0")
.format(new java.math.BigDecimal($F{cumOpeningBal}))]]></textFieldExpression>
<textFieldExpression><![CDATA[$F{cumOpeningBal} == null || $F{cumOpeningBal}.trim().length() == 0 ? "" : $F{cumOpeningBal}]]></textFieldExpression>
</textField>
<textField textAdjust="StretchHeight">
<reportElement x="466" y="0" width="50" height="16" uuid="ca781a08-f648-41bc-a44f-b4d3fc05bf24"/>
<textElement textAlignment="Right" verticalAlignment="Top">
<font fontName="微軟正黑體" size="10"/>
</textElement>
<textFieldExpression><![CDATA[$F{stockOut} == null || $F{stockOut}.trim().length() == 0
? ""
: new java.text.DecimalFormat("#,##0")
.format(new java.math.BigDecimal($F{stockOut}))]]></textFieldExpression>
<textFieldExpression><![CDATA[$F{stockOut} == null || $F{stockOut}.trim().length() == 0 ? "" : $F{stockOut}]]></textFieldExpression>
</textField>
<textField textAdjust="StretchHeight">
<reportElement x="524" y="0" width="66" height="16" uuid="0011e1ab-a161-46d8-af84-629e955e5461">
@@ -403,10 +397,7 @@
<textElement textAlignment="Right" verticalAlignment="Top">
<font fontName="微軟正黑體" size="10"/>
</textElement>
<textFieldExpression><![CDATA[$F{cumBalance} == null || $F{cumBalance}.trim().length() == 0
? ""
: new java.text.DecimalFormat("#,##0")
.format(new java.math.BigDecimal($F{cumBalance}))]]></textFieldExpression>
<textFieldExpression><![CDATA[$F{cumBalance} == null || $F{cumBalance}.trim().length() == 0 ? "" : $F{cumBalance}]]></textFieldExpression>
</textField>
<textField textAdjust="StretchHeight">
<reportElement x="592" y="0" width="112" height="16" uuid="abcf9c0b-8e93-44b0-af99-8b7fe7812ff8">
@@ -452,10 +443,7 @@
<textElement textAlignment="Right" verticalAlignment="Top">
<font fontName="微軟正黑體" size="10"/>
</textElement>
<textFieldExpression><![CDATA[$F{stockIn} == null || $F{stockIn}.trim().length() == 0
? ""
: new java.text.DecimalFormat("#,##0")
.format(new java.math.BigDecimal($F{stockIn}))]]></textFieldExpression>
<textFieldExpression><![CDATA[$F{stockIn} == null || $F{stockIn}.trim().length() == 0 ? "" : $F{stockIn}]]></textFieldExpression>
</textField>
</band>
</detail>


Ladataan…
Peruuta
Tallenna