Procházet zdrojové kódy

update stockbalance and fix stockledger fiter problem

reset-do-picking-order
Tommy\2Fi-Staff před 1 týdnem
rodič
revize
3eeafd46ed
2 změnil soubory, kde provedl 19 přidání a 19 odebrání
  1. +17
    -17
      src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt
  2. +2
    -2
      src/main/java/com/ffii/fpsms/modules/report/web/StockLedgerReportController.kt

+ 17
- 17
src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt Zobrazit soubor

@@ -818,7 +818,9 @@ fun searchMaterialStockOutTraceabilityReport(
/**
* Queries the database for Stock Balance Report data (one summarized row per item).
* Uses stock_ledger with report period (fromDate/toDate): opening = before fromDate, cum in/out = in period, current = up to toDate.
* totalStockBalance = SUM(pol.qty * pol.up) per item via purchase_order_line; avgUnitPrice = totalStockBalance / totalCurrentBalance.
* Price per stock unit = (pol.qty * pol.up) / sil.acceptedQty (PO unit price is per purchase unit; acceptedQty is in stock unit).
* Total balance = sum over movements of (inQty * price_per_stock_in - outQty * price_per_stock_out) per item.
* 現存存貨 = totalCurrentBalance; avg unit price = total_balance / 現存存貨 (0 when current stock is 0).
*/
fun searchStockBalanceReport(
stockCategory: String?,
@@ -874,10 +876,10 @@ fun searchMaterialStockOutTraceabilityReport(
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,
FORMAT(ROUND(COALESCE(item_agg.total_in_value, 0) - COALESCE(item_agg.total_out_value, 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)
WHEN COALESCE(item_agg.totalCurrentBalance, 0) > 0
THEN FORMAT(ROUND((COALESCE(item_agg.total_in_value, 0) - COALESCE(item_agg.total_out_value, 0)) / item_agg.totalCurrentBalance, 2), 2)
ELSE '0.00'
END as avgUnitPrice
FROM (
@@ -895,7 +897,9 @@ fun searchMaterialStockOutTraceabilityReport(
SUM(agg.cumStockOutBad) AS totalDefectiveGoods,
MAX(agg.storeLocation) AS storeLocation,
MAX(agg.lastInDate) AS lastInDate,
MAX(agg.lastOutDate) AS lastOutDate
MAX(agg.lastOutDate) AS lastOutDate,
SUM(agg.total_in_value) AS total_in_value,
SUM(agg.total_out_value) AS total_out_value
FROM (
SELECT
sl.itemCode,
@@ -935,7 +939,9 @@ fun searchMaterialStockOutTraceabilityReport(
MAX(lot_wh.storeLocation) AS storeLocation,
SUM(CASE WHEN DATE(sl.date) BETWEEN :fromDate AND :toDate AND COALESCE(sl.inQty, 0) > 0 AND (LOWER(TRIM(COALESCE(sl.type, ''))) = 'miss' OR LOWER(TRIM(COALESCE(sol.type, ''))) = 'miss') THEN sl.outQty ELSE 0 END) AS cumStockOutMiss,
SUM(CASE WHEN DATE(sl.date) BETWEEN :fromDate AND :toDate AND COALESCE(sl.outQty, 0) > 0 AND (LOWER(TRIM(COALESCE(sl.type, ''))) = 'bad' OR LOWER(TRIM(COALESCE(sol.type, ''))) = 'bad') THEN sl.outQty ELSE 0 END) AS cumStockOutBad,
SUM(CASE WHEN DATE(sl.date) BETWEEN :fromDate AND :toDate AND COALESCE(sl.outQty, 0) > 0 AND LOWER(TRIM(COALESCE(sl.type, ''))) = 'adj' AND (sol.stockTransferId IS NULL OR sol.id IS NULL) THEN sl.outQty ELSE 0 END) AS cumStockOutAdjStockTake
SUM(CASE WHEN DATE(sl.date) BETWEEN :fromDate AND :toDate AND COALESCE(sl.outQty, 0) > 0 AND LOWER(TRIM(COALESCE(sl.type, ''))) = 'adj' AND (sol.stockTransferId IS NULL OR sol.id IS NULL) THEN sl.outQty ELSE 0 END) AS cumStockOutAdjStockTake,
SUM(COALESCE(sl.inQty, 0) * CASE WHEN pol_in.id IS NOT NULL AND iu_stock.id IS NOT NULL AND iu_purchase.id IS NOT NULL AND COALESCE(iu_purchase.ratioN, 0) > 0 THEN COALESCE(pol_in.up, 0) * (iu_stock.ratioN / NULLIF(iu_stock.ratioD, 0)) / (iu_purchase.ratioN / NULLIF(iu_purchase.ratioD, 0)) ELSE 0 END) AS total_in_value,
SUM(COALESCE(sl.outQty, 0) * CASE WHEN pol_out.id IS NOT NULL AND iu_stock.id IS NOT NULL AND iu_purchase.id IS NOT NULL AND COALESCE(iu_purchase.ratioN, 0) > 0 THEN COALESCE(pol_out.up, 0) * (iu_stock.ratioN / NULLIF(iu_stock.ratioD, 0)) / (iu_purchase.ratioN / NULLIF(iu_purchase.ratioD, 0)) ELSE 0 END) AS total_out_value
FROM stock_ledger sl
LEFT JOIN stock_in_line sil ON sl.stockInLineId = sil.id AND sil.deleted = 0
LEFT JOIN inventory_lot il_in ON sil.inventoryLotId = il_in.id AND il_in.deleted = 0
@@ -949,6 +955,11 @@ fun searchMaterialStockOutTraceabilityReport(
LEFT JOIN warehouse wh ON ill.warehouseId = wh.id AND wh.deleted = 0
GROUP BY il.id
) lot_wh ON lot_wh.lotId = COALESCE(il_in.id, il_out.id)
LEFT JOIN purchase_order_line pol_in ON sil.purchaseOrderLineId = pol_in.id AND pol_in.deleted = 0
LEFT JOIN stock_in_line sil_out ON il_out.stockInLineId = sil_out.id AND sil_out.deleted = 0
LEFT JOIN purchase_order_line pol_out ON sil_out.purchaseOrderLineId = pol_out.id AND pol_out.deleted = 0
LEFT JOIN item_uom iu_stock ON sl.itemId = iu_stock.itemId AND iu_stock.stockUnit = 1 AND iu_stock.deleted = 0
LEFT JOIN item_uom iu_purchase ON sl.itemId = iu_purchase.itemId AND iu_purchase.purchaseUnit = 1 AND iu_purchase.deleted = 0
WHERE sl.deleted = 0
AND sl.itemCode IS NOT NULL AND sl.itemCode <> ''
AND DATE(sl.date) <= :toDate
@@ -965,17 +976,6 @@ fun searchMaterialStockOutTraceabilityReport(
GROUP BY agg.itemCode, agg.itemId, it.id, it.code, it.name, uc.udfudesc, uc.code
HAVING 1=1
) item_agg
LEFT JOIN (
SELECT itemId, SUM(pol_qty_up) AS totalStockBalanceRaw
FROM (
SELECT sil.itemId, MAX(COALESCE(pol.qty, 0) * COALESCE(pol.up, 0)) AS pol_qty_up
FROM stock_in_line sil
LEFT JOIN purchase_order_line pol ON sil.purchaseOrderLineId = pol.id AND pol.deleted = 0
WHERE sil.deleted = 0
GROUP BY sil.itemId, pol.id
) t
GROUP BY itemId
) ipv ON item_agg.itemId = ipv.itemId
WHERE 1=1
""".trimIndent()



+ 2
- 2
src/main/java/com/ffii/fpsms/modules/report/web/StockLedgerReportController.kt Zobrazit soubor

@@ -20,8 +20,8 @@ fun generateStockLedgerReport(
@RequestParam(required = false) itemCode: String?,
@RequestParam(required = false) storeLocation: String?,
// URL 參數名仍然是 lastInDateStart / lastInDateEnd
@RequestParam(name = "startDateStart", required = false) reportPeriodStart: String?,
@RequestParam(name = "startDateEnd", required = false) reportPeriodEnd: String?,
@RequestParam(name = "lastInDateStart", required = false) reportPeriodStart: String?,
@RequestParam(name = "lastInDateEnd", required = false) reportPeriodEnd: String?,
): ResponseEntity<ByteArray> {
val parameters = mutableMapOf<String, Any>()



Načítá se…
Zrušit
Uložit