fix UPDATE_INVENTORY_QTY_SQL unavavable qty don't use onhold qtyfix負數倉
| @@ -217,7 +217,7 @@ internal object StockLedgerFixInventorySql { | |||||
| SUM( | SUM( | ||||
| CASE | CASE | ||||
| WHEN LOWER(ill.status) = 'unavailable' | WHEN LOWER(ill.status) = 'unavailable' | ||||
| THEN COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) - COALESCE(ill.holdQty, 0) | |||||
| THEN COALESCE(ill.inQty, 0) - COALESCE(ill.outQty, 0) | |||||
| ELSE 0 | ELSE 0 | ||||
| END | END | ||||
| ) AS unavailable | ) AS unavailable | ||||
| @@ -105,7 +105,7 @@ class FGStockOutTraceabilityReportService( | |||||
| CAST(IFNULL(sp.id, 0) AS CHAR) AS customerId, | CAST(IFNULL(sp.id, 0) AS CHAR) AS customerId, | ||||
| IFNULL(sp.name, '') AS customerName, | IFNULL(sp.name, '') AS customerName, | ||||
| FORMAT( | FORMAT( | ||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code), 0), 0 | |||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code, uc.udfudesc), 0), 0 | |||||
| ) AS qtyNumeric, | ) AS qtyNumeric, | ||||
| FORMAT(ROUND(IFNULL(sol.qty, 0), 0), 0) AS qty, | FORMAT(ROUND(IFNULL(sol.qty, 0), 0), 0) AS qty, | ||||
| '' AS truckNo, | '' AS truckNo, | ||||
| @@ -131,7 +131,7 @@ class FGStockOutTraceabilityReportService( | |||||
| GROUP_CONCAT(DISTINCT wh.code ORDER BY wh.code SEPARATOR ', ') AS storeLocation, | GROUP_CONCAT(DISTINCT wh.code ORDER BY wh.code SEPARATOR ', ') AS storeLocation, | ||||
| '' AS pickRemark, | '' AS pickRemark, | ||||
| FORMAT( | FORMAT( | ||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code), 0), 0 | |||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code, uc.udfudesc), 0), 0 | |||||
| ) AS totalStockOutQty, | ) AS totalStockOutQty, | ||||
| 0 AS stockSubCategory | 0 AS stockSubCategory | ||||
| FROM delivery_order_pick_order dopo | FROM delivery_order_pick_order dopo | ||||
| @@ -154,11 +154,6 @@ class FGStockOutTraceabilityReportService( | |||||
| ON dol.deliveryOrderId = do.id | ON dol.deliveryOrderId = do.id | ||||
| AND dol.itemId = pol.itemId | AND dol.itemId = pol.itemId | ||||
| AND dol.deleted = 0 | AND dol.deleted = 0 | ||||
| LEFT JOIN item_uom iu | |||||
| ON it.id = iu.itemId | |||||
| AND iu.stockUnit = 1 | |||||
| LEFT JOIN uom_conversion uc | |||||
| ON iu.uomId = uc.id | |||||
| LEFT JOIN stock_out_line sol | LEFT JOIN stock_out_line sol | ||||
| ON pol.id = sol.pickOrderLineId | ON pol.id = sol.pickOrderLineId | ||||
| AND sol.itemId = it.id | AND sol.itemId = it.id | ||||
| @@ -170,6 +165,20 @@ class FGStockOutTraceabilityReportService( | |||||
| LEFT JOIN inventory_lot_line ill | LEFT JOIN inventory_lot_line ill | ||||
| ON sol.inventoryLotLineId = ill.id | ON sol.inventoryLotLineId = ill.id | ||||
| AND ill.deleted = 0 | AND ill.deleted = 0 | ||||
| LEFT JOIN item_uom iu | |||||
| ON iu.deleted = 0 | |||||
| AND iu.id = COALESCE( | |||||
| ill.stockItemUomId, | |||||
| ( | |||||
| SELECT MIN(iu2.id) | |||||
| FROM item_uom iu2 | |||||
| WHERE iu2.itemId = it.id | |||||
| AND iu2.deleted = 0 | |||||
| AND iu2.stockUnit = 1 | |||||
| ) | |||||
| ) | |||||
| LEFT JOIN uom_conversion uc | |||||
| ON uc.id = iu.uomId | |||||
| LEFT JOIN inventory_lot il | LEFT JOIN inventory_lot il | ||||
| ON ill.inventoryLotId = il.id | ON ill.inventoryLotId = il.id | ||||
| AND il.deleted = 0 | AND il.deleted = 0 | ||||
| @@ -213,6 +222,7 @@ class FGStockOutTraceabilityReportService( | |||||
| il.expiryDate | il.expiryDate | ||||
| ORDER BY | ORDER BY | ||||
| it.code, | it.code, | ||||
| uc.udfudesc, | |||||
| deliveryDate, | deliveryDate, | ||||
| il.lotNo | il.lotNo | ||||
| """.trimIndent() | """.trimIndent() | ||||
| @@ -109,12 +109,23 @@ open class ItemQcFailReportService( | |||||
| LEFT JOIN qc_result_measurement qrm | LEFT JOIN qc_result_measurement qrm | ||||
| ON qrm.qcResultId = qr.id | ON qrm.qcResultId = qr.id | ||||
| AND qrm.deleted = 0 | AND qrm.deleted = 0 | ||||
| LEFT JOIN inventory_lot_line ill_uom | |||||
| ON ill_uom.deleted = 0 | |||||
| AND ill_uom.id = COALESCE( | |||||
| sil.inventoryLotLineId, | |||||
| ( | |||||
| SELECT MIN(illx.id) | |||||
| FROM inventory_lot_line illx | |||||
| WHERE illx.inventoryLotId = sil.inventoryLotId | |||||
| AND illx.deleted = 0 | |||||
| AND illx.stockItemUomId IS NOT NULL | |||||
| ) | |||||
| ) | |||||
| LEFT JOIN item_uom iu | LEFT JOIN item_uom iu | ||||
| ON it.id = iu.itemId | |||||
| AND iu.stockUnit = 1 | |||||
| ON iu.id = ill_uom.stockItemUomId | |||||
| AND iu.deleted = 0 | AND iu.deleted = 0 | ||||
| LEFT JOIN uom_conversion uc | LEFT JOIN uom_conversion uc | ||||
| ON iu.uomId = uc.id | |||||
| ON uc.id = iu.uomId | |||||
| LEFT JOIN item_uom iu_purchase | LEFT JOIN item_uom iu_purchase | ||||
| ON it.id = iu_purchase.itemId | ON it.id = iu_purchase.itemId | ||||
| AND iu_purchase.purchaseUnit = 1 | AND iu_purchase.purchaseUnit = 1 | ||||
| @@ -164,6 +175,7 @@ open class ItemQcFailReportService( | |||||
| qr.qcPassed DESC, | qr.qcPassed DESC, | ||||
| it.type, | it.type, | ||||
| it.code, | it.code, | ||||
| COALESCE(uc.udfudesc, uc.code, ''), | |||||
| COALESCE(sil.lotNo, il.lotNo, ''), | COALESCE(sil.lotNo, il.lotNo, ''), | ||||
| CASE WHEN sil.jobOrderId IS NOT NULL THEN 'EPQC' ELSE 'IQC' END, | CASE WHEN sil.jobOrderId IS NOT NULL THEN 'EPQC' ELSE 'IQC' END, | ||||
| COALESCE(qic.`order`, 9999), | COALESCE(qic.`order`, 9999), | ||||
| @@ -105,7 +105,7 @@ class MaterialStockOutTraceabilityReportService( | |||||
| COALESCE(wh.code, '') AS storeLocation, | COALESCE(wh.code, '') AS storeLocation, | ||||
| '' AS pickRemark, | '' AS pickRemark, | ||||
| FORMAT( | FORMAT( | ||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code), 0), 0 | |||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code, uc.udfudesc), 0), 0 | |||||
| ) AS totalStockOutQty | ) AS totalStockOutQty | ||||
| FROM stock_out_line sol | FROM stock_out_line sol | ||||
| INNER JOIN stock_out so | INNER JOIN stock_out so | ||||
| @@ -126,14 +126,23 @@ class MaterialStockOutTraceabilityReportService( | |||||
| INNER JOIN items it | INNER JOIN items it | ||||
| ON sol.itemId = it.id | ON sol.itemId = it.id | ||||
| AND it.deleted = 0 | AND it.deleted = 0 | ||||
| LEFT JOIN item_uom iu | |||||
| ON it.id = iu.itemId | |||||
| AND iu.stockUnit = 1 | |||||
| LEFT JOIN uom_conversion uc | |||||
| ON iu.uomId = uc.id | |||||
| LEFT JOIN inventory_lot_line ill | LEFT JOIN inventory_lot_line ill | ||||
| ON sol.inventoryLotLineId = ill.id | ON sol.inventoryLotLineId = ill.id | ||||
| AND ill.deleted = 0 | AND ill.deleted = 0 | ||||
| LEFT JOIN item_uom iu | |||||
| ON iu.deleted = 0 | |||||
| AND iu.id = COALESCE( | |||||
| ill.stockItemUomId, | |||||
| ( | |||||
| SELECT MIN(iu2.id) | |||||
| FROM item_uom iu2 | |||||
| WHERE iu2.itemId = it.id | |||||
| AND iu2.deleted = 0 | |||||
| AND iu2.stockUnit = 1 | |||||
| ) | |||||
| ) | |||||
| LEFT JOIN uom_conversion uc | |||||
| ON iu.uomId = uc.id | |||||
| LEFT JOIN inventory_lot il | LEFT JOIN inventory_lot il | ||||
| ON ill.inventoryLotId = il.id | ON ill.inventoryLotId = il.id | ||||
| AND il.deleted = 0 | AND il.deleted = 0 | ||||
| @@ -169,6 +178,7 @@ class MaterialStockOutTraceabilityReportService( | |||||
| $handlerSql | $handlerSql | ||||
| ORDER BY | ORDER BY | ||||
| it.code, | it.code, | ||||
| uc.udfudesc, | |||||
| il.lotNo, | il.lotNo, | ||||
| sol.endTime | sol.endTime | ||||
| """.trimIndent() | """.trimIndent() | ||||
| @@ -372,7 +372,7 @@ return result | |||||
| CAST(IFNULL(sp.id, 0) AS CHAR) AS customerId, | CAST(IFNULL(sp.id, 0) AS CHAR) AS customerId, | ||||
| IFNULL(sp.name, '') AS customerName, | IFNULL(sp.name, '') AS customerName, | ||||
| FORMAT( | FORMAT( | ||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code), 0), 0 | |||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code, uc.udfudesc), 0), 0 | |||||
| ) AS qtyNumeric, | ) AS qtyNumeric, | ||||
| FORMAT(ROUND(IFNULL(sol.qty, 0), 0), 0) AS qty, | FORMAT(ROUND(IFNULL(sol.qty, 0), 0), 0) AS qty, | ||||
| '' AS truckNo, | '' AS truckNo, | ||||
| @@ -396,7 +396,7 @@ return result | |||||
| GROUP_CONCAT(DISTINCT wh.code ORDER BY wh.code SEPARATOR ', ') AS storeLocation, | GROUP_CONCAT(DISTINCT wh.code ORDER BY wh.code SEPARATOR ', ') AS storeLocation, | ||||
| '' AS pickRemark, | '' AS pickRemark, | ||||
| FORMAT( | FORMAT( | ||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code), 0), 0 | |||||
| ROUND(SUM(IFNULL(sol.qty, 0)) OVER (PARTITION BY it.code, uc.udfudesc), 0), 0 | |||||
| ) AS totalStockOutQty, | ) AS totalStockOutQty, | ||||
| 0 AS stockSubCategory | 0 AS stockSubCategory | ||||
| FROM do_pick_order_line_record dpolr | FROM do_pick_order_line_record dpolr | ||||
| @@ -416,11 +416,6 @@ return result | |||||
| LEFT JOIN items it | LEFT JOIN items it | ||||
| ON dol.itemId = it.id | ON dol.itemId = it.id | ||||
| AND it.deleted = 0 | AND it.deleted = 0 | ||||
| LEFT JOIN item_uom iu | |||||
| ON it.id = iu.itemId | |||||
| AND iu.stockUnit = 1 | |||||
| LEFT JOIN uom_conversion uc | |||||
| ON iu.uomId = uc.id | |||||
| LEFT JOIN pick_order_line pol | LEFT JOIN pick_order_line pol | ||||
| ON dpolr.pick_order_id = pol.poId | ON dpolr.pick_order_id = pol.poId | ||||
| AND pol.itemId = it.id | AND pol.itemId = it.id | ||||
| @@ -439,6 +434,20 @@ return result | |||||
| LEFT JOIN inventory_lot_line ill | LEFT JOIN inventory_lot_line ill | ||||
| ON sol.inventoryLotLineId = ill.id | ON sol.inventoryLotLineId = ill.id | ||||
| AND ill.deleted = 0 | AND ill.deleted = 0 | ||||
| LEFT JOIN item_uom iu | |||||
| ON iu.deleted = 0 | |||||
| AND iu.id = COALESCE( | |||||
| ill.stockItemUomId, | |||||
| ( | |||||
| SELECT MIN(iu2.id) | |||||
| FROM item_uom iu2 | |||||
| WHERE iu2.itemId = it.id | |||||
| AND iu2.deleted = 0 | |||||
| AND iu2.stockUnit = 1 | |||||
| ) | |||||
| ) | |||||
| LEFT JOIN uom_conversion uc | |||||
| ON uc.id = iu.uomId | |||||
| LEFT JOIN inventory_lot il | LEFT JOIN inventory_lot il | ||||
| ON ill.inventoryLotId = il.id | ON ill.inventoryLotId = il.id | ||||
| AND il.deleted = 0 | AND il.deleted = 0 | ||||
| @@ -479,6 +488,7 @@ return result | |||||
| il.expiryDate | il.expiryDate | ||||
| ORDER BY | ORDER BY | ||||
| it.code, | it.code, | ||||
| uc.udfudesc, | |||||
| deliveryDate, | deliveryDate, | ||||
| il.lotNo | il.lotNo | ||||
| """.trimIndent() | """.trimIndent() | ||||
| @@ -730,19 +740,33 @@ return result | |||||
| END, 2))) as iqcDefectPercentage, | END, 2))) as iqcDefectPercentage, | ||||
| CASE WHEN COALESCE(qr_agg.qcFailed, 0) = 1 THEN '不合格' ELSE '已接受' END as iqcResult, | CASE WHEN COALESCE(qr_agg.qcFailed, 0) = 1 THEN '不合格' ELSE '已接受' END as iqcResult, | ||||
| COALESCE(qr_agg.remarksConcat, '') as iqcRemarks, | COALESCE(qr_agg.remarksConcat, '') as iqcRemarks, | ||||
| TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(qr_agg.failQtySum, 0)) OVER (PARTITION BY it.id), 2))) as totalIqcDefectQty, | |||||
| TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(qr_agg.failQtySum, 0)) OVER (PARTITION BY it.id, iu.id), 2))) as totalIqcDefectQty, | |||||
| COALESCE(wh.code, '') as storeLocation, | COALESCE(wh.code, '') as storeLocation, | ||||
| COALESCE(sp_si.code, sp_po.code, '') as supplierID, | COALESCE(sp_si.code, sp_po.code, '') as supplierID, | ||||
| COALESCE(sp_si.name, sp_po.name, '') as supplierName, | COALESCE(sp_si.name, sp_po.name, '') as supplierName, | ||||
| TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(pa_sil.putAwayQtySum, 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 | |||||
| TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(pa_sil.putAwayQtySum, 0)) OVER (PARTITION BY it.id, iu.id), 2))) as totalStockInQty, | |||||
| TRIM(TRAILING '.' FROM TRIM(TRAILING '0' FROM FORMAT(SUM(COALESCE(sil.acceptedQty, 0)) OVER (PARTITION BY it.id, iu.id), 2))) as totalIqcSampleQty | |||||
| FROM stock_in_line sil | FROM stock_in_line sil | ||||
| LEFT JOIN stock_in si ON sil.stockInId = si.id | LEFT JOIN stock_in si ON sil.stockInId = si.id | ||||
| LEFT JOIN purchase_order po ON sil.purchaseOrderId = po.id | LEFT JOIN purchase_order po ON sil.purchaseOrderId = po.id | ||||
| LEFT JOIN items it ON sil.itemId = it.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 inventory_lot il ON sil.inventoryLotId = il.id | LEFT JOIN inventory_lot il ON sil.inventoryLotId = il.id | ||||
| LEFT JOIN inventory_lot_line ill_uom | |||||
| ON ill_uom.deleted = 0 | |||||
| AND ill_uom.id = COALESCE( | |||||
| sil.inventoryLotLineId, | |||||
| ( | |||||
| SELECT MIN(illx.id) | |||||
| FROM inventory_lot_line illx | |||||
| WHERE illx.inventoryLotId = il.id | |||||
| AND illx.deleted = 0 | |||||
| AND illx.stockItemUomId IS NOT NULL | |||||
| ) | |||||
| ) | |||||
| LEFT JOIN item_uom iu | |||||
| ON iu.id = ill_uom.stockItemUomId | |||||
| AND iu.deleted = 0 | |||||
| LEFT JOIN uom_conversion uc ON uc.id = iu.uomId | |||||
| LEFT JOIN ( | LEFT JOIN ( | ||||
| SELECT inventoryLotId, SUM(COALESCE(inQty, 0)) AS putAwayQtySum | SELECT inventoryLotId, SUM(COALESCE(inQty, 0)) AS putAwayQtySum | ||||
| FROM inventory_lot_line | FROM inventory_lot_line | ||||
| @@ -778,7 +802,7 @@ return result | |||||
| $slotSql | $slotSql | ||||
| $lotNoSql | $lotNoSql | ||||
| $poPrefixSql | $poPrefixSql | ||||
| ORDER BY it.code, sil.lotNo | |||||
| ORDER BY it.code, uc.udfudesc, sil.lotNo | |||||
| """.trimIndent() | """.trimIndent() | ||||
| return jdbcDao.queryForList(sql, args) | return jdbcDao.queryForList(sql, args) | ||||
| @@ -89,6 +89,7 @@ open class StockLedgerReportService( | |||||
| COALESCE(sl.inQty, 0) AS inQty, | COALESCE(sl.inQty, 0) AS inQty, | ||||
| COALESCE(sl.outQty, 0) AS outQty, | COALESCE(sl.outQty, 0) AS outQty, | ||||
| COALESCE(sl.balance, 0) AS bal, | COALESCE(sl.balance, 0) AS bal, | ||||
| sl.uomId AS ledgerUomId, | |||||
| sl.inventoryLotLineId AS inventoryLotLineId, | sl.inventoryLotLineId AS inventoryLotLineId, | ||||
| sl.stockInLineId AS stockInLineId, | sl.stockInLineId AS stockInLineId, | ||||
| sl.stockOutLineId AS stockOutLineId | sl.stockOutLineId AS stockOutLineId | ||||
| @@ -112,6 +113,7 @@ open class StockLedgerReportService( | |||||
| inQty = toDouble(r["inQty"]), | inQty = toDouble(r["inQty"]), | ||||
| outQty = toDouble(r["outQty"]), | outQty = toDouble(r["outQty"]), | ||||
| bal = toDouble(r["bal"]), | bal = toDouble(r["bal"]), | ||||
| ledgerUomId = toLong(r["ledgerUomId"]), | |||||
| lotLineId = toLong(r["inventoryLotLineId"]), | lotLineId = toLong(r["inventoryLotLineId"]), | ||||
| stockInLineId = toLong(r["stockInLineId"]), | stockInLineId = toLong(r["stockInLineId"]), | ||||
| stockOutLineId = toLong(r["stockOutLineId"]), | stockOutLineId = toLong(r["stockOutLineId"]), | ||||
| @@ -183,12 +185,17 @@ open class StockLedgerReportService( | |||||
| ill.id AS lineId, | ill.id AS lineId, | ||||
| COALESCE(il.lotNo, '') AS lotNo, | COALESCE(il.lotNo, '') AS lotNo, | ||||
| COALESCE(DATE_FORMAT(il.expiryDate, '%Y-%m-%d'), '') AS expiryDate, | COALESCE(DATE_FORMAT(il.expiryDate, '%Y-%m-%d'), '') AS expiryDate, | ||||
| COALESCE(wh.code, '') AS storeLocation | |||||
| COALESCE(wh.code, '') AS storeLocation, | |||||
| COALESCE(uc.udfudesc, uc.code, '') AS unitOfMeasure | |||||
| FROM inventory_lot_line ill | FROM inventory_lot_line ill | ||||
| INNER JOIN inventory_lot il | INNER JOIN inventory_lot il | ||||
| ON il.id = ill.inventoryLotId AND il.deleted = 0 | ON il.id = ill.inventoryLotId AND il.deleted = 0 | ||||
| LEFT JOIN warehouse wh | LEFT JOIN warehouse wh | ||||
| ON wh.id = ill.warehouseId AND wh.deleted = 0 | ON wh.id = ill.warehouseId AND wh.deleted = 0 | ||||
| LEFT JOIN item_uom iu | |||||
| ON iu.id = ill.stockItemUomId AND iu.deleted = 0 | |||||
| LEFT JOIN uom_conversion uc | |||||
| ON uc.id = iu.uomId | |||||
| WHERE ill.deleted = 0 | WHERE ill.deleted = 0 | ||||
| AND ill.id IN (:ids) | AND ill.id IN (:ids) | ||||
| """.trimIndent(), | """.trimIndent(), | ||||
| @@ -197,6 +204,7 @@ open class StockLedgerReportService( | |||||
| lotNo = r["lotNo"]?.toString().orEmpty(), | lotNo = r["lotNo"]?.toString().orEmpty(), | ||||
| expiryDate = r["expiryDate"]?.toString().orEmpty(), | expiryDate = r["expiryDate"]?.toString().orEmpty(), | ||||
| storeLocation = r["storeLocation"]?.toString().orEmpty(), | storeLocation = r["storeLocation"]?.toString().orEmpty(), | ||||
| unitOfMeasure = r["unitOfMeasure"]?.toString().orEmpty(), | |||||
| ) | ) | ||||
| } | } | ||||
| val headerIds = lotKeyBySl.values | val headerIds = lotKeyBySl.values | ||||
| @@ -209,12 +217,17 @@ open class StockLedgerReportService( | |||||
| il.id AS lotId, | il.id AS lotId, | ||||
| COALESCE(il.lotNo, '') AS lotNo, | COALESCE(il.lotNo, '') AS lotNo, | ||||
| COALESCE(DATE_FORMAT(il.expiryDate, '%Y-%m-%d'), '') AS expiryDate, | COALESCE(DATE_FORMAT(il.expiryDate, '%Y-%m-%d'), '') AS expiryDate, | ||||
| COALESCE(MAX(wh.code), '') AS storeLocation | |||||
| COALESCE(MAX(wh.code), '') AS storeLocation, | |||||
| COALESCE(MAX(uc.udfudesc), MAX(uc.code), '') AS unitOfMeasure | |||||
| FROM inventory_lot il | FROM inventory_lot il | ||||
| LEFT JOIN inventory_lot_line ill | LEFT JOIN inventory_lot_line ill | ||||
| ON ill.inventoryLotId = il.id AND ill.deleted = 0 | ON ill.inventoryLotId = il.id AND ill.deleted = 0 | ||||
| LEFT JOIN warehouse wh | LEFT JOIN warehouse wh | ||||
| ON wh.id = ill.warehouseId AND wh.deleted = 0 | ON wh.id = ill.warehouseId AND wh.deleted = 0 | ||||
| LEFT JOIN item_uom iu | |||||
| ON iu.id = ill.stockItemUomId AND iu.deleted = 0 | |||||
| LEFT JOIN uom_conversion uc | |||||
| ON uc.id = iu.uomId | |||||
| WHERE il.deleted = 0 | WHERE il.deleted = 0 | ||||
| AND il.id IN (:ids) | AND il.id IN (:ids) | ||||
| GROUP BY il.id, il.lotNo, il.expiryDate | GROUP BY il.id, il.lotNo, il.expiryDate | ||||
| @@ -224,10 +237,31 @@ open class StockLedgerReportService( | |||||
| lotNo = r["lotNo"]?.toString().orEmpty(), | lotNo = r["lotNo"]?.toString().orEmpty(), | ||||
| expiryDate = r["expiryDate"]?.toString().orEmpty(), | expiryDate = r["expiryDate"]?.toString().orEmpty(), | ||||
| storeLocation = r["storeLocation"]?.toString().orEmpty(), | storeLocation = r["storeLocation"]?.toString().orEmpty(), | ||||
| unitOfMeasure = r["unitOfMeasure"]?.toString().orEmpty(), | |||||
| ) | ) | ||||
| } | } | ||||
| } | } | ||||
| val uomDescById = HashMap<Long, String>() | |||||
| val missingUomIds = ArrayList<Long>() | |||||
| for (m in moves) { | |||||
| val key = lotKeyBySl[m.slId] ?: continue | |||||
| val lot = if (key.lineId > 0) lotByLine[key.lineId] else lotByHeader[key.lotId] | |||||
| if (lot != null && lot.unitOfMeasure.isBlank() && m.ledgerUomId > 0) { | |||||
| missingUomIds.add(m.ledgerUomId) | |||||
| } | |||||
| } | |||||
| for (r in queryChunks( | |||||
| missingUomIds, | |||||
| """ | |||||
| SELECT id AS uomId, COALESCE(udfudesc, code, '') AS unitOfMeasure | |||||
| FROM uom_conversion | |||||
| WHERE id IN (:ids) | |||||
| """.trimIndent(), | |||||
| )) { | |||||
| uomDescById[toLong(r["uomId"])] = r["unitOfMeasure"]?.toString().orEmpty() | |||||
| } | |||||
| val locationFilter = storeLocation?.trim().orEmpty() | val locationFilter = storeLocation?.trim().orEmpty() | ||||
| val withLot = ArrayList<MoveWithLot>(moves.size) | val withLot = ArrayList<MoveWithLot>(moves.size) | ||||
| for (m in moves) { | for (m in moves) { | ||||
| @@ -239,7 +273,8 @@ open class StockLedgerReportService( | |||||
| ) { | ) { | ||||
| continue | continue | ||||
| } | } | ||||
| withLot.add(MoveWithLot(m, lot)) | |||||
| val uom = lot.unitOfMeasure.ifBlank { uomDescById[m.ledgerUomId].orEmpty() } | |||||
| withLot.add(MoveWithLot(m, lot, uom)) | |||||
| } | } | ||||
| timings.add("4.filter rows=${withLot.size}") | timings.add("4.filter rows=${withLot.size}") | ||||
| if (withLot.isEmpty()) { | if (withLot.isEmpty()) { | ||||
| @@ -251,7 +286,6 @@ open class StockLedgerReportService( | |||||
| val type: String, | val type: String, | ||||
| val code: String, | val code: String, | ||||
| val name: String, | val name: String, | ||||
| val uom: String, | |||||
| ) | ) | ||||
| val items = HashMap<Long, ItemInfo>() | val items = HashMap<Long, ItemInfo>() | ||||
| timed("5.items", { _: Unit -> "items=${items.size}" }) { | timed("5.items", { _: Unit -> "items=${items.size}" }) { | ||||
| @@ -262,19 +296,8 @@ open class StockLedgerReportService( | |||||
| it.id AS itemId, | it.id AS itemId, | ||||
| COALESCE(it.type, '') AS stockSubCategory, | COALESCE(it.type, '') AS stockSubCategory, | ||||
| COALESCE(it.code, '') AS itemNo, | COALESCE(it.code, '') AS itemNo, | ||||
| COALESCE(it.name, '') AS itemName, | |||||
| COALESCE(uc.udfudesc, '') AS unitOfMeasure | |||||
| COALESCE(it.name, '') AS itemName | |||||
| FROM items it | FROM items it | ||||
| LEFT JOIN ( | |||||
| SELECT itemId, MIN(id) AS id | |||||
| FROM item_uom | |||||
| WHERE deleted = 0 AND stockUnit = 1 AND itemId IN (:ids) | |||||
| GROUP BY itemId | |||||
| ) one_uom ON one_uom.itemId = it.id | |||||
| LEFT JOIN item_uom iu | |||||
| ON iu.id = one_uom.id | |||||
| LEFT JOIN uom_conversion uc | |||||
| ON uc.id = iu.uomId | |||||
| WHERE it.deleted = 0 | WHERE it.deleted = 0 | ||||
| AND it.id IN (:ids) | AND it.id IN (:ids) | ||||
| """.trimIndent(), | """.trimIndent(), | ||||
| @@ -283,7 +306,6 @@ open class StockLedgerReportService( | |||||
| type = r["stockSubCategory"]?.toString().orEmpty(), | type = r["stockSubCategory"]?.toString().orEmpty(), | ||||
| code = r["itemNo"]?.toString().orEmpty(), | code = r["itemNo"]?.toString().orEmpty(), | ||||
| name = r["itemName"]?.toString().orEmpty(), | name = r["itemName"]?.toString().orEmpty(), | ||||
| uom = r["unitOfMeasure"]?.toString().orEmpty(), | |||||
| ) | ) | ||||
| } | } | ||||
| } | } | ||||
| @@ -353,7 +375,7 @@ open class StockLedgerReportService( | |||||
| val totals = HashMap<String, ItemTotal>() | val totals = HashMap<String, ItemTotal>() | ||||
| for (row in withLot) { | for (row in withLot) { | ||||
| val m = row.move | val m = row.move | ||||
| val total = totals.getOrPut(m.itemCode) { ItemTotal() } | |||||
| val total = totals.getOrPut("${m.itemCode}|${row.unitOfMeasure}") { ItemTotal() } | |||||
| total.inSum += m.inQty | total.inSum += m.inQty | ||||
| total.outSum += m.outQty | total.outSum += m.outQty | ||||
| val opening = m.bal - m.inQty + m.outQty | val opening = m.bal - m.inQty + m.outQty | ||||
| @@ -372,6 +394,7 @@ open class StockLedgerReportService( | |||||
| val rows = timed("7.assemble", { list: List<Map<String, Any>> -> "rows=${list.size}" }) { | val rows = timed("7.assemble", { list: List<Map<String, Any>> -> "rows=${list.size}" }) { | ||||
| val sorted = withLot.sortedWith( | val sorted = withLot.sortedWith( | ||||
| compareBy<MoveWithLot> { items[it.move.itemId]?.code.orEmpty() } | compareBy<MoveWithLot> { items[it.move.itemId]?.code.orEmpty() } | ||||
| .thenBy { it.unitOfMeasure } | |||||
| .thenBy { it.move.trnDate } | .thenBy { it.move.trnDate } | ||||
| .thenBy { it.move.slId } | .thenBy { it.move.slId } | ||||
| .thenBy { it.lot.lotNo }, | .thenBy { it.lot.lotNo }, | ||||
| @@ -387,12 +410,12 @@ open class StockLedgerReportService( | |||||
| norm == "ADJ" && (outRef?.stockTake == true || inRef?.stockTake == true) -> "TKE" | norm == "ADJ" && (outRef?.stockTake == true || inRef?.stockTake == true) -> "TKE" | ||||
| else -> m.rawType | else -> m.rawType | ||||
| } | } | ||||
| val total = totals[m.itemCode] | |||||
| val total = totals["${m.itemCode}|${row.unitOfMeasure}"] | |||||
| reportRow( | reportRow( | ||||
| stockSubCategory = item?.type.orEmpty(), | stockSubCategory = item?.type.orEmpty(), | ||||
| itemNo = item?.code.orEmpty(), | itemNo = item?.code.orEmpty(), | ||||
| itemName = item?.name.orEmpty(), | itemName = item?.name.orEmpty(), | ||||
| unitOfMeasure = item?.uom.orEmpty(), | |||||
| unitOfMeasure = row.unitOfMeasure, | |||||
| lotNo = row.lot.lotNo, | lotNo = row.lot.lotNo, | ||||
| expiryDate = row.lot.expiryDate, | expiryDate = row.lot.expiryDate, | ||||
| trnDate = m.trnDate, | trnDate = m.trnDate, | ||||
| @@ -558,6 +581,7 @@ open class StockLedgerReportService( | |||||
| val inQty: Double, | val inQty: Double, | ||||
| val outQty: Double, | val outQty: Double, | ||||
| val bal: Double, | val bal: Double, | ||||
| val ledgerUomId: Long, | |||||
| val lotLineId: Long, | val lotLineId: Long, | ||||
| val stockInLineId: Long, | val stockInLineId: Long, | ||||
| val stockOutLineId: Long, | val stockOutLineId: Long, | ||||
| @@ -566,12 +590,14 @@ open class StockLedgerReportService( | |||||
| private data class MoveWithLot( | private data class MoveWithLot( | ||||
| val move: LedgerMove, | val move: LedgerMove, | ||||
| val lot: LotInfo, | val lot: LotInfo, | ||||
| val unitOfMeasure: String, | |||||
| ) | ) | ||||
| private data class LotInfo( | private data class LotInfo( | ||||
| val lotNo: String, | val lotNo: String, | ||||
| val expiryDate: String, | val expiryDate: String, | ||||
| val storeLocation: String, | val storeLocation: String, | ||||
| val unitOfMeasure: String, | |||||
| ) | ) | ||||
| private class ItemTotal { | private class ItemTotal { | ||||
| @@ -245,8 +245,7 @@ in_agg AS ( | |||||
| AND iu_purchase.purchaseUnit = 1 | AND iu_purchase.purchaseUnit = 1 | ||||
| AND iu_purchase.deleted = 0 | AND iu_purchase.deleted = 0 | ||||
| LEFT JOIN item_uom iu_stock | LEFT JOIN item_uom iu_stock | ||||
| ON it.id = iu_stock.itemId | |||||
| AND iu_stock.stockUnit = 1 | |||||
| ON iu_stock.id = ill.stockItemUomId | |||||
| AND iu_stock.deleted = 0 | AND iu_stock.deleted = 0 | ||||
| WHERE ill.deleted = 0 | WHERE ill.deleted = 0 | ||||
| GROUP BY ill.id | GROUP BY ill.id | ||||
| @@ -316,8 +315,7 @@ data AS ( | |||||
| $ROOT_STOCK_IN_JOIN_SQL | $ROOT_STOCK_IN_JOIN_SQL | ||||
| LEFT JOIN item_uom iu | LEFT JOIN item_uom iu | ||||
| ON it.id = iu.itemId | |||||
| AND iu.stockUnit = 1 | |||||
| ON iu.id = ill.stockItemUomId | |||||
| AND iu.deleted = 0 | AND iu.deleted = 0 | ||||
| LEFT JOIN uom_conversion uc | LEFT JOIN uom_conversion uc | ||||
| ON iu.uomId = uc.id | ON iu.uomId = uc.id | ||||
| @@ -377,16 +375,17 @@ SELECT | |||||
| END AS variancePercentage, | END AS variancePercentage, | ||||
| /* item totals(footer 用);負數括號顯示,無小數 */ | /* 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, | |||||
| CASE WHEN SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo), 0), ')') ELSE FORMAT(SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo), 0) END AS totalStockTakeQty, | |||||
| CASE WHEN SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalOpeningBalance, | |||||
| CASE WHEN SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalCumStockIn, | |||||
| CASE WHEN SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalCumStockOut, | |||||
| CASE WHEN SUM(COALESCE(currentQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(currentQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(currentQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalCurrentBalance, | |||||
| CASE WHEN SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalStockTakeQty, | |||||
| lotTypeRaw AS type | lotTypeRaw AS type | ||||
| FROM data | FROM data | ||||
| ORDER BY | ORDER BY | ||||
| itemNo, | itemNo, | ||||
| unitOfMeasure, | |||||
| lotNo, | lotNo, | ||||
| storeLocation | storeLocation | ||||
| """.trimIndent() | """.trimIndent() | ||||
| @@ -521,8 +520,7 @@ in_agg AS ( | |||||
| AND iu_purchase.purchaseUnit = 1 | AND iu_purchase.purchaseUnit = 1 | ||||
| AND iu_purchase.deleted = 0 | AND iu_purchase.deleted = 0 | ||||
| LEFT JOIN item_uom iu_stock | LEFT JOIN item_uom iu_stock | ||||
| ON it.id = iu_stock.itemId | |||||
| AND iu_stock.stockUnit = 1 | |||||
| ON iu_stock.id = ill.stockItemUomId | |||||
| AND iu_stock.deleted = 0 | AND iu_stock.deleted = 0 | ||||
| WHERE ill.deleted = 0 | WHERE ill.deleted = 0 | ||||
| GROUP BY ill.id | GROUP BY ill.id | ||||
| @@ -598,8 +596,7 @@ data AS ( | |||||
| $ROOT_STOCK_IN_JOIN_SQL | $ROOT_STOCK_IN_JOIN_SQL | ||||
| LEFT JOIN item_uom iu | LEFT JOIN item_uom iu | ||||
| ON it.id = iu.itemId | |||||
| AND iu.stockUnit = 1 | |||||
| ON iu.id = ill.stockItemUomId | |||||
| AND iu.deleted = 0 | AND iu.deleted = 0 | ||||
| LEFT JOIN uom_conversion uc | LEFT JOIN uom_conversion uc | ||||
| ON iu.uomId = uc.id | ON iu.uomId = uc.id | ||||
| @@ -655,16 +652,17 @@ SELECT | |||||
| ELSE CONCAT(FORMAT((COALESCE(stkVarianceQty, 0) / stkBookQty) * 100, 0), '%') | ELSE CONCAT(FORMAT((COALESCE(stkVarianceQty, 0) / stkBookQty) * 100, 0), '%') | ||||
| END AS variancePercentage, | END AS variancePercentage, | ||||
| 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(stkBookQty, 0)) OVER (PARTITION BY itemNo) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo), 0), ')') ELSE FORMAT(SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo), 0) END AS totalCurrentBalance, | |||||
| CASE WHEN SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo), 0), ')') ELSE FORMAT(SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo), 0) END AS totalStockTakeQty, | |||||
| CASE WHEN SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalOpeningBalance, | |||||
| CASE WHEN SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalCumStockIn, | |||||
| CASE WHEN SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalCumStockOut, | |||||
| CASE WHEN SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalCurrentBalance, | |||||
| CASE WHEN SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalStockTakeQty, | |||||
| lotTypeRaw AS type | lotTypeRaw AS type | ||||
| FROM data | FROM data | ||||
| ORDER BY | ORDER BY | ||||
| itemNo, | itemNo, | ||||
| unitOfMeasure, | |||||
| lotNo, | lotNo, | ||||
| storeLocation | storeLocation | ||||
| """.trimIndent() | """.trimIndent() | ||||
| @@ -820,8 +818,7 @@ in_agg AS ( | |||||
| AND iu_purchase.purchaseUnit = 1 | AND iu_purchase.purchaseUnit = 1 | ||||
| AND iu_purchase.deleted = 0 | AND iu_purchase.deleted = 0 | ||||
| LEFT JOIN item_uom iu_stock | LEFT JOIN item_uom iu_stock | ||||
| ON it.id = iu_stock.itemId | |||||
| AND iu_stock.stockUnit = 1 | |||||
| ON iu_stock.id = ill.stockItemUomId | |||||
| AND iu_stock.deleted = 0 | AND iu_stock.deleted = 0 | ||||
| WHERE ill.deleted = 0 | WHERE ill.deleted = 0 | ||||
| GROUP BY lb.inventoryLotLineId | GROUP BY lb.inventoryLotLineId | ||||
| @@ -888,8 +885,7 @@ data AS ( | |||||
| $ROOT_STOCK_IN_JOIN_SQL | $ROOT_STOCK_IN_JOIN_SQL | ||||
| LEFT JOIN item_uom iu | LEFT JOIN item_uom iu | ||||
| ON it.id = iu.itemId | |||||
| AND iu.stockUnit = 1 | |||||
| ON iu.id = ill.stockItemUomId | |||||
| AND iu.deleted = 0 | AND iu.deleted = 0 | ||||
| LEFT JOIN uom_conversion uc | LEFT JOIN uom_conversion uc | ||||
| ON iu.uomId = uc.id | ON iu.uomId = uc.id | ||||
| @@ -945,16 +941,17 @@ SELECT | |||||
| ELSE CONCAT(FORMAT((COALESCE(stkVarianceQty, 0) / stkBookQty) * 100, 0), '%') | ELSE CONCAT(FORMAT((COALESCE(stkVarianceQty, 0) / stkBookQty) * 100, 0), '%') | ||||
| END AS variancePercentage, | END AS variancePercentage, | ||||
| 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(stkBookQty, 0)) OVER (PARTITION BY itemNo) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo), 0), ')') ELSE FORMAT(SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo), 0) END AS totalCurrentBalance, | |||||
| CASE WHEN SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo), 0), ')') ELSE FORMAT(SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo), 0) END AS totalStockTakeQty, | |||||
| CASE WHEN SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(openingQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalOpeningBalance, | |||||
| CASE WHEN SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(inQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalCumStockIn, | |||||
| CASE WHEN SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(outQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalCumStockOut, | |||||
| CASE WHEN SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(stkBookQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalCurrentBalance, | |||||
| CASE WHEN SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure) < 0 THEN CONCAT('(', FORMAT(-SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0), ')') ELSE FORMAT(SUM(COALESCE(stkApproverQty, 0)) OVER (PARTITION BY itemNo, unitOfMeasure), 0) END AS totalStockTakeQty, | |||||
| lotTypeRaw AS type | lotTypeRaw AS type | ||||
| FROM data | FROM data | ||||
| ORDER BY | ORDER BY | ||||
| itemNo, | itemNo, | ||||
| unitOfMeasure, | |||||
| lotNo, | lotNo, | ||||
| storeLocation | storeLocation | ||||
| """.trimIndent() | """.trimIndent() | ||||
| @@ -306,11 +306,13 @@ class FGStockOutTraceabilityReportController( | |||||
| } else { | } else { | ||||
| var currentItemNo: String? = null | var currentItemNo: String? = null | ||||
| var currentItemName = "" | var currentItemName = "" | ||||
| var currentUom = "" | |||||
| var currentItemTotalQty = 0.0 | var currentItemTotalQty = 0.0 | ||||
| dbData.forEach { rowMap -> | dbData.forEach { rowMap -> | ||||
| val itemNo = rowMap["itemNo"]?.toString() ?: "" | val itemNo = rowMap["itemNo"]?.toString() ?: "" | ||||
| if (currentItemNo != null && itemNo != currentItemNo) { | |||||
| val uom = rowMap["unitOfMeasure"]?.toString().orEmpty() | |||||
| if (currentItemNo != null && (itemNo != currentItemNo || uom != currentUom)) { | |||||
| addItemSummaryRow(currentItemTotalQty, currentItemNo!!, currentItemName) | addItemSummaryRow(currentItemTotalQty, currentItemNo!!, currentItemName) | ||||
| addBlankSeparatorRow() | addBlankSeparatorRow() | ||||
| currentItemTotalQty = 0.0 | currentItemTotalQty = 0.0 | ||||
| @@ -331,6 +333,7 @@ class FGStockOutTraceabilityReportController( | |||||
| currentItemNo = itemNo | currentItemNo = itemNo | ||||
| currentItemName = rowMap["itemName"]?.toString() ?: "" | currentItemName = rowMap["itemName"]?.toString() ?: "" | ||||
| currentUom = uom | |||||
| currentItemTotalQty += parseNullableNumber(rowMap["stockOutQty"]) ?: 0.0 | currentItemTotalQty += parseNullableNumber(rowMap["stockOutQty"]) ?: 0.0 | ||||
| } | } | ||||
| @@ -298,11 +298,13 @@ class MaterialStockOutTraceabilityReportController( | |||||
| } else { | } else { | ||||
| var currentItemNo: String? = null | var currentItemNo: String? = null | ||||
| var currentItemName: String = "" | var currentItemName: String = "" | ||||
| var currentUom = "" | |||||
| var currentItemTotalQty: Double = 0.0 | var currentItemTotalQty: Double = 0.0 | ||||
| dbData.forEach { rowMap -> | dbData.forEach { rowMap -> | ||||
| val itemNo = rowMap["itemNo"]?.toString() ?: "" | val itemNo = rowMap["itemNo"]?.toString() ?: "" | ||||
| if (currentItemNo != null && itemNo != currentItemNo) { | |||||
| val uom = rowMap["unitOfMeasure"]?.toString().orEmpty() | |||||
| if (currentItemNo != null && (itemNo != currentItemNo || uom != currentUom)) { | |||||
| addItemSummaryRow(currentItemTotalQty, currentItemNo!!, currentItemName) | addItemSummaryRow(currentItemTotalQty, currentItemNo!!, currentItemName) | ||||
| addBlankSeparatorRow() | addBlankSeparatorRow() | ||||
| currentItemTotalQty = 0.0 | currentItemTotalQty = 0.0 | ||||
| @@ -323,6 +325,7 @@ class MaterialStockOutTraceabilityReportController( | |||||
| currentItemNo = itemNo | currentItemNo = itemNo | ||||
| currentItemName = rowMap["itemName"]?.toString() ?: "" | currentItemName = rowMap["itemName"]?.toString() ?: "" | ||||
| currentUom = uom | |||||
| currentItemTotalQty += parseNullableNumber(rowMap["stockOutQty"]) ?: 0.0 | currentItemTotalQty += parseNullableNumber(rowMap["stockOutQty"]) ?: 0.0 | ||||
| } | } | ||||
| @@ -704,7 +704,7 @@ class ReportController( | |||||
| val itemName = m["itemName"]?.toString().orEmpty() | val itemName = m["itemName"]?.toString().orEmpty() | ||||
| val uom = m["unitOfMeasure"]?.toString().orEmpty() | val uom = m["unitOfMeasure"]?.toString().orEmpty() | ||||
| if (currentItemNo != null && itemNo != currentItemNo) { | |||||
| if (currentItemNo != null && (itemNo != currentItemNo || uom != currentUom)) { | |||||
| addItemSummaryRow( | addItemSummaryRow( | ||||
| currentItemNo!!, | currentItemNo!!, | ||||
| currentItemName, | currentItemName, | ||||
| @@ -394,7 +394,7 @@ class StockLedgerReportController( | |||||
| val itemName = m["itemName"]?.toString().orEmpty() | val itemName = m["itemName"]?.toString().orEmpty() | ||||
| val uom = m["unitOfMeasure"]?.toString().orEmpty() | val uom = m["unitOfMeasure"]?.toString().orEmpty() | ||||
| if (currentItemNo != null && itemNo != currentItemNo) { | |||||
| if (currentItemNo != null && (itemNo != currentItemNo || uom != currentUom)) { | |||||
| addItemSummaryRow( | addItemSummaryRow( | ||||
| currentItemNo!!, | currentItemNo!!, | ||||
| currentItemName, | currentItemName, | ||||
| @@ -490,7 +490,7 @@ class StockTakeVarianceReportController( | |||||
| val itemName = rowMap["itemName"]?.toString().orEmpty() | val itemName = rowMap["itemName"]?.toString().orEmpty() | ||||
| val uom = rowMap["unitOfMeasure"]?.toString().orEmpty() | val uom = rowMap["unitOfMeasure"]?.toString().orEmpty() | ||||
| if (currentItemNo != null && itemNo != currentItemNo) { | |||||
| if (currentItemNo != null && (itemNo != currentItemNo || uom != currentUom)) { | |||||
| addItemSummaryRow(currentItemTotalQty, currentItemTotalStockTakeQty, currentItemNo!!, currentItemName) | addItemSummaryRow(currentItemTotalQty, currentItemTotalStockTakeQty, currentItemNo!!, currentItemName) | ||||
| addBlankSeparatorRow() | addBlankSeparatorRow() | ||||
| currentItemTotalQty = 0.0 | currentItemTotalQty = 0.0 | ||||
| @@ -59,7 +59,7 @@ | |||||
| <field name="deliveryDate" class="java.lang.String"/> | <field name="deliveryDate" class="java.lang.String"/> | ||||
| <field name="totalStockOutQty" class="java.lang.String"/> | <field name="totalStockOutQty" class="java.lang.String"/> | ||||
| <group name="Group1" keepTogether="true"> | <group name="Group1" keepTogether="true"> | ||||
| <groupExpression><![CDATA[$F{itemNo}]]></groupExpression> | |||||
| <groupExpression><![CDATA[$F{itemNo}+"|"+$F{unitOfMeasure}]]></groupExpression> | |||||
| <groupHeader> | <groupHeader> | ||||
| <band height="18"> | <band height="18"> | ||||
| <textField textAdjust="StretchHeight"> | <textField textAdjust="StretchHeight"> | ||||
| @@ -59,7 +59,7 @@ | |||||
| <field name="orderRefNo" class="java.lang.String"/> | <field name="orderRefNo" class="java.lang.String"/> | ||||
| <field name="stockSubCategory" class="java.lang.String"/> | <field name="stockSubCategory" class="java.lang.String"/> | ||||
| <group name="Group1" keepTogether="true"> | <group name="Group1" keepTogether="true"> | ||||
| <groupExpression><![CDATA[$F{itemNo}]]></groupExpression> | |||||
| <groupExpression><![CDATA[$F{itemNo}+"|"+$F{unitOfMeasure}]]></groupExpression> | |||||
| <groupHeader> | <groupHeader> | ||||
| <band height="18"> | <band height="18"> | ||||
| <property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.FreeLayout"/> | <property name="com.jaspersoft.studio.layout" value="com.jaspersoft.studio.editor.layout.FreeLayout"/> | ||||
| @@ -54,7 +54,7 @@ | |||||
| <field name="jobOrderNo" class="java.lang.String"/> | <field name="jobOrderNo" class="java.lang.String"/> | ||||
| <field name="totalStockOutQty" class="java.lang.String"/> | <field name="totalStockOutQty" class="java.lang.String"/> | ||||
| <group name="Group1" keepTogether="true"> | <group name="Group1" keepTogether="true"> | ||||
| <groupExpression><![CDATA[$F{itemNo}]]></groupExpression> | |||||
| <groupExpression><![CDATA[$F{itemNo}+"|"+$F{unitOfMeasure}]]></groupExpression> | |||||
| <groupHeader> | <groupHeader> | ||||
| <band height="18"> | <band height="18"> | ||||
| <textField textAdjust="StretchHeight"> | <textField textAdjust="StretchHeight"> | ||||
| @@ -62,7 +62,7 @@ | |||||
| <field name="totalIqcDefectQty" class="java.lang.String"/> | <field name="totalIqcDefectQty" class="java.lang.String"/> | ||||
| <field name="stockInQty" class="java.lang.String"/> | <field name="stockInQty" class="java.lang.String"/> | ||||
| <group name="Group1" keepTogether="true"> | <group name="Group1" keepTogether="true"> | ||||
| <groupExpression><![CDATA[$F{itemNo}]]></groupExpression> | |||||
| <groupExpression><![CDATA[$F{itemNo}+"|"+$F{unitOfMeasure}]]></groupExpression> | |||||
| <groupHeader> | <groupHeader> | ||||
| <band height="18"> | <band height="18"> | ||||
| <property name="com.jaspersoft.studio.unit.height" value="px"/> | <property name="com.jaspersoft.studio.unit.height" value="px"/> | ||||
| @@ -74,7 +74,7 @@ | |||||
| <field name="jobOrderNo" class="java.lang.String"/> | <field name="jobOrderNo" class="java.lang.String"/> | ||||
| <field name="orderRefNo" class="java.lang.String"/> | <field name="orderRefNo" class="java.lang.String"/> | ||||
| <group name="Group1" keepTogether="false"> | <group name="Group1" keepTogether="false"> | ||||
| <groupExpression><![CDATA[$F{itemNo}]]></groupExpression> | |||||
| <groupExpression><![CDATA[$F{itemNo}+"|"+$F{unitOfMeasure}]]></groupExpression> | |||||
| <groupHeader> | <groupHeader> | ||||
| <band height="18"> | <band height="18"> | ||||
| <textField textAdjust="StretchHeight"> | <textField textAdjust="StretchHeight"> | ||||
| @@ -67,7 +67,7 @@ | |||||
| <field name="totalStockTakeQty" class="java.lang.String"/> | <field name="totalStockTakeQty" class="java.lang.String"/> | ||||
| <field name="type" class="java.lang.String"/> | <field name="type" class="java.lang.String"/> | ||||
| <group name="Group1" keepTogether="true" preventOrphanFooter="true"> | <group name="Group1" keepTogether="true" preventOrphanFooter="true"> | ||||
| <groupExpression><![CDATA[$F{itemNo}]]></groupExpression> | |||||
| <groupExpression><![CDATA[$F{itemNo}+"|"+$F{unitOfMeasure}]]></groupExpression> | |||||
| <groupHeader> | <groupHeader> | ||||
| <band height="18"> | <band height="18"> | ||||
| <textField textAdjust="StretchHeight"> | <textField textAdjust="StretchHeight"> | ||||