| @@ -63,6 +63,7 @@ open class StockLedgerFixAdjService( | |||
| val (adjDate, asOfExclusive) = resolveAdjWindow(adjDateRaw) | |||
| val t0 = System.nanoTime() | |||
| try { | |||
| support.stampFixActor() | |||
| val plans = planLotAdjs(asOfExclusive) | |||
| var insertedIn = 0 | |||
| var insertedOut = 0 | |||
| @@ -111,7 +112,7 @@ open class StockLedgerFixAdjService( | |||
| WHERE deleted = 0 | |||
| AND date >= :adjDate AND date < :asOf | |||
| AND type = 'ADJ' | |||
| AND createdBy = 'stock-ledger-fix' | |||
| AND createdBy IN ('DNP', 'stock-ledger-fix') | |||
| """.trimIndent(), | |||
| mapOf("adjDate" to adjDate, "asOf" to asOfExclusive), | |||
| ).forEach { addLot(support.toLong(it["lotId"]), support.toLongOrNull(it["invId"])) } | |||
| @@ -165,6 +166,7 @@ open class StockLedgerFixAdjService( | |||
| val (adjDate, asOfExclusive) = resolveAdjWindow(adjDateRaw) | |||
| val t0 = System.nanoTime() | |||
| try { | |||
| support.stampFixActor() | |||
| val gaps = loadLotLineInGaps() | |||
| var insertedIn = 0 | |||
| val lotIds = linkedSetOf<Long>() | |||
| @@ -181,7 +183,7 @@ open class StockLedgerFixAdjService( | |||
| UPDATE inventory_lot_line | |||
| SET inQty = outQty, | |||
| modified = NOW(), | |||
| modifiedBy = 'stock-ledger-fix' | |||
| modifiedBy = 'DNP' | |||
| WHERE id = :id | |||
| AND IFNULL(deleted, 0) = 0 | |||
| AND COALESCE(outQty, 0) > COALESCE(inQty, 0) | |||
| @@ -414,7 +416,7 @@ open class StockLedgerFixAdjService( | |||
| itemId, itemCode, inQty, outQty, balance, lotQtyBefore, lotQtyAfter, | |||
| uomId, type | |||
| ) VALUES ( | |||
| NOW(), 'stock-ledger-fix', 0, NOW(), 'stock-ledger-fix', 0, | |||
| NOW(), 'DNP', 0, NOW(), 'DNP', 0, | |||
| :adjDate, :silId, :solId, :lotLineId, :inventoryId, | |||
| :itemId, :itemCode, :inQty, :outQty, NULL, NULL, NULL, | |||
| :uomId, 'ADJ' | |||
| @@ -448,7 +450,7 @@ open class StockLedgerFixAdjService( | |||
| created, createdBy, version, modified, modifiedBy, deleted, | |||
| code, status, orderDate, completeDate | |||
| ) VALUES ( | |||
| NOW(), 'stock-ledger-fix', 0, NOW(), 'stock-ledger-fix', 0, | |||
| NOW(), 'DNP', 0, NOW(), 'DNP', 0, | |||
| :code, 'completed', :at, :at | |||
| ) | |||
| """.trimIndent(), | |||
| @@ -462,7 +464,7 @@ open class StockLedgerFixAdjService( | |||
| val existing = support.jdbcDao.queryForMap( | |||
| """ | |||
| SELECT id FROM stock_out | |||
| WHERE createdBy = 'stock-ledger-fix' | |||
| WHERE createdBy IN ('DNP', 'stock-ledger-fix') | |||
| AND type = 'ADJ' | |||
| AND remarks = :remarks | |||
| AND IFNULL(deleted, 0) = 0 | |||
| @@ -481,7 +483,7 @@ open class StockLedgerFixAdjService( | |||
| created, createdBy, version, modified, modifiedBy, deleted, | |||
| type, completeDate, status, remarks, handlerId | |||
| ) VALUES ( | |||
| NOW(), 'stock-ledger-fix', 0, NOW(), 'stock-ledger-fix', 0, | |||
| NOW(), 'DNP', 0, NOW(), 'DNP', 0, | |||
| 'ADJ', :at, 'completed', :remarks, :handlerId | |||
| ) | |||
| """.trimIndent(), | |||
| @@ -499,14 +501,14 @@ open class StockLedgerFixAdjService( | |||
| stockInLineId, stockOutLineId | |||
| ) | |||
| SELECT | |||
| NOW(), 'stock-ledger-fix', 0, NOW(), 'stock-ledger-fix', 0, | |||
| NOW(), 'DNP', 0, NOW(), 'DNP', 0, | |||
| sl.itemId, | |||
| LEFT(COALESCE(sl.itemCode, it.code), 50), | |||
| LEFT(it.name, 200), | |||
| LEFT(il.lotNo, 512), | |||
| CASE WHEN sl.stockInLineId IS NOT NULL THEN sl.inQty ELSE NULL END, | |||
| CASE WHEN sl.stockOutLineId IS NOT NULL THEN sl.outQty ELSE NULL END, | |||
| LEFT(COALESCE(sil.remarks, so.remarks, 'stock-ledger-fix 2.7 ADJ'), 500), | |||
| 'DNP', | |||
| sl.stockInLineId, | |||
| sl.stockOutLineId | |||
| FROM stock_ledger sl | |||
| @@ -518,7 +520,7 @@ open class StockLedgerFixAdjService( | |||
| LEFT JOIN stock_out so ON so.id = sol.stockOutId | |||
| WHERE sl.deleted = 0 | |||
| AND sl.type = 'ADJ' | |||
| AND sl.createdBy = 'stock-ledger-fix' | |||
| AND sl.createdBy IN ('DNP', 'stock-ledger-fix') | |||
| AND (sl.stockInLineId IS NOT NULL OR sl.stockOutLineId IS NOT NULL) | |||
| AND NOT EXISTS ( | |||
| SELECT 1 | |||
| @@ -555,7 +557,7 @@ open class StockLedgerFixAdjService( | |||
| itemId, itemNo, stockInId, acceptedQty, receiptDate, status, | |||
| inventoryLotId, inventoryLotLineId, lotNo, remarks, type | |||
| ) VALUES ( | |||
| NOW(), 'stock-ledger-fix', 0, NOW(), 'stock-ledger-fix', 0, | |||
| NOW(), 'DNP', 0, NOW(), 'DNP', 0, | |||
| :itemId, :itemNo, :stockInId, :qty, :at, 'completed', | |||
| :inventoryLotId, :lotLineId, :lotNo, :remarks, 'ADJ' | |||
| ) | |||
| @@ -595,7 +597,7 @@ open class StockLedgerFixAdjService( | |||
| created, createdBy, version, modified, modifiedBy, deleted, | |||
| itemId, qty, stockOutId, inventoryLotLineId, status, pickTime, type | |||
| ) VALUES ( | |||
| NOW(), 'stock-ledger-fix', 0, NOW(), 'stock-ledger-fix', 0, | |||
| NOW(), 'DNP', 0, NOW(), 'DNP', 0, | |||
| :itemId, :qty, :stockOutId, :lotLineId, 'completed', :at, 'ADJ' | |||
| ) | |||
| """.trimIndent(), | |||
| @@ -23,6 +23,7 @@ open class StockLedgerFixBackfillService( | |||
| throw IllegalStateException("inventory 1.0 already running") | |||
| } | |||
| try { | |||
| support.stampFixActor() | |||
| val patchedFromUom = support.jdbcDao.executeUpdate(StockLedgerFixInventorySql.BACKFILL_STOCK_UOM_WHEN_UOM_MATCHES_LOT_SQL) | |||
| val patchedSingleLot = support.jdbcDao.executeUpdate(StockLedgerFixInventorySql.BACKFILL_STOCK_UOM_SINGLE_LOT_SQL) | |||
| val patchedStockUomId = patchedFromUom + patchedSingleLot | |||
| @@ -426,7 +427,7 @@ open class StockLedgerFixBackfillService( | |||
| SET | |||
| sl.deleted = 1, | |||
| sl.modified = NOW(), | |||
| sl.modifiedBy = 'stock-ledger-fix' | |||
| sl.modifiedBy = 'DNP' | |||
| WHERE sl.deleted = 0 | |||
| AND ($dateWhere) | |||
| AND sl.inventoryLotLineId IS NULL | |||
| @@ -510,7 +511,7 @@ open class StockLedgerFixBackfillService( | |||
| SET | |||
| sol.inventoryLotLineId = src.lotLineId, | |||
| sol.modified = NOW(), | |||
| sol.modifiedBy = 'stock-ledger-fix' | |||
| sol.modifiedBy = 'DNP' | |||
| WHERE IFNULL(sol.deleted, 0) = 0 | |||
| AND sol.inventoryLotLineId IS NOT NULL | |||
| AND sol.inventoryLotLineId <> src.lotLineId | |||
| @@ -526,7 +527,7 @@ open class StockLedgerFixBackfillService( | |||
| sl.inventoryLotLineId = NULL, | |||
| sl.deleted = 1, | |||
| sl.modified = NOW(), | |||
| sl.modifiedBy = 'stock-ledger-fix' | |||
| sl.modifiedBy = 'DNP' | |||
| WHERE sl.deleted = 0 | |||
| AND ($dateWhere) | |||
| AND sl.inventoryLotLineId IS NOT NULL | |||
| @@ -1136,7 +1137,7 @@ open class StockLedgerFixBackfillService( | |||
| SET | |||
| sl.deleted = 1, | |||
| sl.modified = NOW(), | |||
| sl.modifiedBy = 'stock-ledger-fix' | |||
| sl.modifiedBy = 'DNP' | |||
| WHERE sl.deleted = 0 | |||
| AND sl.inventoryLotLineId IS NULL | |||
| """.trimIndent(), | |||
| @@ -1399,7 +1400,7 @@ open class StockLedgerFixBackfillService( | |||
| opening, inQty, outQty, closing | |||
| ) | |||
| SELECT | |||
| NOW(), 'ledger-fix-api', 0, NOW(), 'ledger-fix-api', 0, | |||
| NOW(), 'DNP', 0, NOW(), 'DNP', 0, | |||
| x.inventoryLotLineId, | |||
| x.itemId, | |||
| x.itemCode, | |||
| @@ -1442,7 +1443,7 @@ open class StockLedgerFixBackfillService( | |||
| outQty = VALUES(outQty), | |||
| closing = VALUES(closing), | |||
| modified = NOW(), | |||
| modifiedBy = 'ledger-fix-api', | |||
| modifiedBy = 'DNP', | |||
| version = stock_lot_day.version + 1, | |||
| deleted = 0 | |||
| """.trimIndent(), | |||
| @@ -1605,7 +1606,7 @@ open class StockLedgerFixBackfillService( | |||
| WHERE deleted = 0 | |||
| AND date >= :adjDate AND date < :today | |||
| AND type = 'ADJ' | |||
| AND createdBy = 'stock-ledger-fix' | |||
| AND createdBy IN ('DNP', 'stock-ledger-fix') | |||
| AND inventoryId IS NOT NULL | |||
| ORDER BY id | |||
| """.trimIndent(), | |||
| @@ -43,6 +43,7 @@ open class StockLedgerFixExportService( | |||
| if (!from.isBefore(toExclusive)) { | |||
| throw IllegalArgumentException("from must be before toExclusive") | |||
| } | |||
| support.stampFixActor() | |||
| val parts = parseExportParts(partsRaw) | |||
| val want10 = "1.0" in parts | |||
| val want21 = "2.1" in parts | |||
| @@ -88,7 +89,7 @@ open class StockLedgerFixExportService( | |||
| WHERE deleted = 0 | |||
| AND date >= :from AND date < :toExclusive | |||
| AND type = 'ADJ' | |||
| AND createdBy = 'stock-ledger-fix' | |||
| AND createdBy IN ('DNP', 'stock-ledger-fix') | |||
| """.trimIndent(), | |||
| args, | |||
| ).firstOrNull()?.get("c"), | |||
| @@ -223,7 +224,7 @@ open class StockLedgerFixExportService( | |||
| SELECT id, modified, modifiedBy | |||
| FROM inventory | |||
| WHERE deleted = 1 | |||
| AND modifiedBy = 'stock-ledger-fix' | |||
| AND modifiedBy IN ('DNP', 'stock-ledger-fix') | |||
| ORDER BY id | |||
| """.trimIndent(), | |||
| tempName = "tmp_sl_fix_inv_del", | |||
| @@ -260,7 +261,7 @@ open class StockLedgerFixExportService( | |||
| SELECT id, inventoryLotLineId, modified, modifiedBy | |||
| FROM stock_ledger | |||
| WHERE deleted = 1 | |||
| AND modifiedBy = 'stock-ledger-fix' | |||
| AND modifiedBy IN ('DNP', 'stock-ledger-fix') | |||
| AND date >= :from AND date < :toExclusive | |||
| ORDER BY id | |||
| """.trimIndent(), | |||
| @@ -286,8 +287,8 @@ open class StockLedgerFixExportService( | |||
| selectSql = """ | |||
| SELECT sol.id, sol.inventoryLotLineId, sol.modified, sol.modifiedBy | |||
| FROM stock_out_line sol | |||
| WHERE sol.modifiedBy = 'stock-ledger-fix' | |||
| AND IFNULL(sol.createdBy, '') <> 'stock-ledger-fix' | |||
| WHERE sol.modifiedBy IN ('DNP', 'stock-ledger-fix') | |||
| AND IFNULL(sol.createdBy, '') NOT IN ('DNP', 'stock-ledger-fix') | |||
| AND EXISTS ( | |||
| SELECT 1 | |||
| FROM stock_ledger sl | |||
| @@ -444,7 +445,7 @@ open class StockLedgerFixExportService( | |||
| selectSql = """ | |||
| SELECT ill.id, ill.inQty, ill.modified, ill.modifiedBy | |||
| FROM inventory_lot_line ill | |||
| WHERE ill.modifiedBy = 'stock-ledger-fix' | |||
| WHERE ill.modifiedBy IN ('DNP', 'stock-ledger-fix') | |||
| AND IFNULL(ill.deleted, 0) = 0 | |||
| AND EXISTS ( | |||
| SELECT 1 | |||
| @@ -453,7 +454,7 @@ open class StockLedgerFixExportService( | |||
| WHERE sl.inventoryLotLineId = ill.id | |||
| AND sl.deleted = 0 | |||
| AND sl.type = 'ADJ' | |||
| AND sl.createdBy = 'stock-ledger-fix' | |||
| AND sl.createdBy IN ('DNP', 'stock-ledger-fix') | |||
| AND sl.date >= :from AND sl.date < :toExclusive | |||
| AND sil.remarks = 'stock-ledger-fix 2.7a ADJ' | |||
| ) | |||
| @@ -484,7 +485,7 @@ open class StockLedgerFixExportService( | |||
| WHERE sl.deleted = 0 | |||
| AND sl.date >= :from AND sl.date < :toExclusive | |||
| AND sl.type = 'ADJ' | |||
| AND sl.createdBy = 'stock-ledger-fix' | |||
| AND sl.createdBy IN ('DNP', 'stock-ledger-fix') | |||
| ORDER BY si.id | |||
| """.trimIndent(), | |||
| args, | |||
| @@ -510,7 +511,7 @@ open class StockLedgerFixExportService( | |||
| WHERE sl.deleted = 0 | |||
| AND sl.date >= :from AND sl.date < :toExclusive | |||
| AND sl.type = 'ADJ' | |||
| AND sl.createdBy = 'stock-ledger-fix' | |||
| AND sl.createdBy IN ('DNP', 'stock-ledger-fix') | |||
| ORDER BY sil.id | |||
| """.trimIndent(), | |||
| args, | |||
| @@ -538,7 +539,7 @@ open class StockLedgerFixExportService( | |||
| WHERE sl.deleted = 0 | |||
| AND sl.date >= :from AND sl.date < :toExclusive | |||
| AND sl.type = 'ADJ' | |||
| AND sl.createdBy = 'stock-ledger-fix' | |||
| AND sl.createdBy IN ('DNP', 'stock-ledger-fix') | |||
| ORDER BY so.id | |||
| """.trimIndent(), | |||
| args, | |||
| @@ -563,7 +564,7 @@ open class StockLedgerFixExportService( | |||
| WHERE sl.deleted = 0 | |||
| AND sl.date >= :from AND sl.date < :toExclusive | |||
| AND sl.type = 'ADJ' | |||
| AND sl.createdBy = 'stock-ledger-fix' | |||
| AND sl.createdBy IN ('DNP', 'stock-ledger-fix') | |||
| ORDER BY sol.id | |||
| """.trimIndent(), | |||
| args, | |||
| @@ -592,11 +593,11 @@ open class StockLedgerFixExportService( | |||
| OR (r.stockOutLineId IS NOT NULL AND sl.stockOutLineId = r.stockOutLineId) | |||
| ) | |||
| WHERE IFNULL(r.deleted, 0) = 0 | |||
| AND r.createdBy = 'stock-ledger-fix' | |||
| AND r.createdBy IN ('DNP', 'stock-ledger-fix') | |||
| AND sl.deleted = 0 | |||
| AND sl.date >= :from AND sl.date < :toExclusive | |||
| AND sl.type = 'ADJ' | |||
| AND sl.createdBy = 'stock-ledger-fix' | |||
| AND sl.createdBy IN ('DNP', 'stock-ledger-fix') | |||
| ORDER BY r.id | |||
| """.trimIndent(), | |||
| args, | |||
| @@ -632,7 +633,7 @@ open class StockLedgerFixExportService( | |||
| WHERE deleted = 0 | |||
| AND date >= :from AND date < :toExclusive | |||
| AND type = 'ADJ' | |||
| AND createdBy = 'stock-ledger-fix' | |||
| AND createdBy IN ('DNP', 'stock-ledger-fix') | |||
| ORDER BY id | |||
| """.trimIndent(), | |||
| args, | |||
| @@ -81,7 +81,7 @@ internal object StockLedgerFixInventorySql { | |||
| i.stockUomId = b.stockUomId, | |||
| i.uomId = COALESCE(baseIu.uomId, i.uomId), | |||
| i.modified = NOW(), | |||
| i.modifiedBy = 'stock-ledger-fix' | |||
| i.modifiedBy = 'DNP' | |||
| WHERE IFNULL(i.deleted, 0) = 0 | |||
| AND i.stockUomId IS NULL | |||
| AND taken.id IS NULL | |||
| @@ -125,7 +125,7 @@ internal object StockLedgerFixInventorySql { | |||
| i.stockUomId = b.stockUomId, | |||
| i.uomId = COALESCE(baseIu.uomId, i.uomId), | |||
| i.modified = NOW(), | |||
| i.modifiedBy = 'stock-ledger-fix' | |||
| i.modifiedBy = 'DNP' | |||
| WHERE IFNULL(i.deleted, 0) = 0 | |||
| AND i.stockUomId IS NULL | |||
| AND taken.id IS NULL | |||
| @@ -149,7 +149,7 @@ internal object StockLedgerFixInventorySql { | |||
| COALESCE(tpl.cpm, 0), | |||
| COALESCE(tpl.cpmUnit, 'HKD'), | |||
| 'unavailable', | |||
| NOW(), 'stock-ledger-fix', NOW(), 'stock-ledger-fix', 0, 0 | |||
| NOW(), 'DNP', NOW(), 'DNP', 0, 0 | |||
| FROM ( | |||
| SELECT il.itemId, iu.uomId | |||
| FROM inventory_lot_line ill | |||
| @@ -202,7 +202,7 @@ internal object StockLedgerFixInventorySql { | |||
| SET | |||
| i.deleted = 1, | |||
| i.modified = NOW(), | |||
| i.modifiedBy = 'stock-ledger-fix' | |||
| i.modifiedBy = 'DNP' | |||
| WHERE IFNULL(i.deleted, 0) = 0 | |||
| AND i.stockUomId IS NULL | |||
| """ | |||
| @@ -240,7 +240,7 @@ internal object StockLedgerFixInventorySql { | |||
| 'unavailable' | |||
| ), | |||
| i.modified = NOW(), | |||
| i.modifiedBy = 'stock-ledger-fix' | |||
| i.modifiedBy = 'DNP' | |||
| WHERE IFNULL(i.deleted, 0) = 0 | |||
| """ | |||
| } | |||
| @@ -109,6 +109,36 @@ open class StockLedgerFixSupport( | |||
| return out | |||
| } | |||
| /** | |||
| * Rename rows already stamped by this fix to [FIX_ACTOR]. | |||
| * Adjustment-record remarks written by the fix become [FIX_ACTOR] as well. | |||
| */ | |||
| fun stampFixActor() { | |||
| jdbcDao.executeUpdate( | |||
| """ | |||
| UPDATE stock_adjustment_record | |||
| SET remarks = '$FIX_ACTOR', | |||
| modified = NOW(), | |||
| modifiedBy = '$FIX_ACTOR' | |||
| WHERE IFNULL(remarks, '') LIKE 'stock-ledger-fix%' | |||
| """.trimIndent(), | |||
| ) | |||
| FIX_ACTOR_TABLES.forEach { table -> | |||
| jdbcDao.executeUpdate( | |||
| "UPDATE $table SET createdBy = '$FIX_ACTOR' WHERE createdBy = 'stock-ledger-fix'", | |||
| ) | |||
| jdbcDao.executeUpdate( | |||
| "UPDATE $table SET modifiedBy = '$FIX_ACTOR' WHERE modifiedBy = 'stock-ledger-fix'", | |||
| ) | |||
| } | |||
| jdbcDao.executeUpdate( | |||
| "UPDATE stock_lot_day SET createdBy = '$FIX_ACTOR' WHERE createdBy = 'ledger-fix-api'", | |||
| ) | |||
| jdbcDao.executeUpdate( | |||
| "UPDATE stock_lot_day SET modifiedBy = '$FIX_ACTOR' WHERE modifiedBy = 'ledger-fix-api'", | |||
| ) | |||
| } | |||
| fun toInt(value: Any?): Int = when (value) { | |||
| null -> 0 | |||
| is Number -> value.toInt() | |||
| @@ -144,6 +174,17 @@ open class StockLedgerFixSupport( | |||
| companion object { | |||
| const val INVENTORY_LOCK = "inventory-1.0" | |||
| const val RUN_LOCK = "ledger-fix-run" | |||
| const val FIX_ACTOR = "DNP" | |||
| private val DAY_STEPS = linkedSetOf("2.1", "2.2", "2.3", "2.4", "2.5", "2.6") | |||
| private val FIX_ACTOR_TABLES = listOf( | |||
| "stock_ledger", | |||
| "inventory", | |||
| "inventory_lot_line", | |||
| "stock_in", | |||
| "stock_in_line", | |||
| "stock_out", | |||
| "stock_out_line", | |||
| "stock_adjustment_record", | |||
| ) | |||
| } | |||
| } | |||