Parcourir la source

2.4,2.5 fix

fix負數倉
CANCERYS\kw093 il y a 14 heures
Parent
révision
90fd8b37ee
2 fichiers modifiés avec 36 ajouts et 15 suppressions
  1. +6
    -3
      src/main/java/com/ffii/fpsms/modules/master/service/ledgerfix/StockLedgerFixAdjService.kt
  2. +30
    -12
      src/main/java/com/ffii/fpsms/modules/master/service/ledgerfix/StockLedgerFixBackfillService.kt

+ 6
- 3
src/main/java/com/ffii/fpsms/modules/master/service/ledgerfix/StockLedgerFixAdjService.kt Voir le fichier

@@ -1,5 +1,6 @@
package com.ffii.fpsms.modules.master.service.ledgerfix

import com.ffii.fpsms.modules.common.SecurityUtils
import com.ffii.fpsms.modules.master.web.models.StockLedgerFixAdjPreview
import com.ffii.fpsms.modules.master.web.models.StockLedgerFixAdjResponse
import com.ffii.fpsms.modules.master.web.models.StockLedgerFixAdjRow
@@ -439,17 +440,19 @@ open class StockLedgerFixAdjService(
).orElse(null)
if (existing != null) return support.toLong(existing["id"])
val at = adjDate.atTime(12, 0)
val handlerId = SecurityUtils.getUser().orElse(null)?.id
?: throw IllegalStateException("stock-ledger-fix: login user required for stock_out.handlerId")
return insertReturningId(
"""
INSERT INTO stock_out (
created, createdBy, version, modified, modifiedBy, deleted,
type, completeDate, status, remarks
type, completeDate, status, remarks, handlerId
) VALUES (
NOW(), 'stock-ledger-fix', 0, NOW(), 'stock-ledger-fix', 0,
'ADJ', :at, 'completed', :remarks
'ADJ', :at, 'completed', :remarks, :handlerId
)
""".trimIndent(),
mapOf("at" to at, "remarks" to remarks),
mapOf("at" to at, "remarks" to remarks, "handlerId" to handlerId),
)
}



+ 30
- 12
src/main/java/com/ffii/fpsms/modules/master/service/ledgerfix/StockLedgerFixBackfillService.kt Voir le fichier

@@ -439,6 +439,8 @@ open class StockLedgerFixBackfillService(

/**
* 2.4 Opening = last lotQtyAfter before the window start (yesterday first, then lookback).
* Lookback: latest date before yesterday, then MAX(id) on that date. MAX(id) over all
* older rows picks a backdated insert (higher id, earlier date) and skips later receipts.
* Idle days must not reset to 0. Window is :day .. :dayNext (one day or a range).
*/
private fun fillLotQty(args: Map<String, Any>): Int {
@@ -529,12 +531,19 @@ open class StockLedgerFixBackfillService(
INNER JOIN (
SELECT sl.inventoryLotLineId, MAX(sl.id) AS maxId
FROM stock_ledger sl
INNER JOIN (
SELECT s.inventoryLotLineId, MAX(s.date) AS maxDate
FROM stock_ledger s
INNER JOIN tmp_sl_fix_lot_miss m
ON m.inventoryLotLineId = s.inventoryLotLineId
WHERE s.deleted = 0
AND s.date < :prevDay
AND s.lotQtyAfter IS NOT NULL
GROUP BY s.inventoryLotLineId
) d ON d.inventoryLotLineId = sl.inventoryLotLineId
AND d.maxDate = sl.date
WHERE sl.deleted = 0
AND sl.date < :prevDay
AND sl.lotQtyAfter IS NOT NULL
AND sl.inventoryLotLineId IN (
SELECT inventoryLotLineId FROM tmp_sl_fix_lot_miss
)
GROUP BY sl.inventoryLotLineId
) x ON x.maxId = slp.id
""".trimIndent(),
@@ -593,6 +602,8 @@ open class StockLedgerFixBackfillService(
* 2.5 Running balance per inventoryId.
* Opening = last balance before the window. Fast path: day before :day. Lookback only for
* inventoryIds that had no row that day (idle days must not reset to 0).
* Lookback: latest date before yesterday, then MAX(id) on that date. MAX(id) over all
* older rows picks a backdated insert and skips receipts dated after that row.
* Window is :day .. :dayNext (one day or a range).
*/
private fun fillBalance(args: Map<String, Any>): Int {
@@ -683,12 +694,19 @@ open class StockLedgerFixBackfillService(
INNER JOIN (
SELECT sl.inventoryId, MAX(sl.id) AS maxId
FROM stock_ledger sl
INNER JOIN (
SELECT s.inventoryId, MAX(s.date) AS maxDate
FROM stock_ledger s
INNER JOIN tmp_stock_ledger_fix_miss m
ON m.inventoryId = s.inventoryId
WHERE s.deleted = 0
AND s.date < :prevDay
AND s.balance IS NOT NULL
GROUP BY s.inventoryId
) d ON d.inventoryId = sl.inventoryId
AND d.maxDate = sl.date
WHERE sl.deleted = 0
AND sl.date < :prevDay
AND sl.balance IS NOT NULL
AND sl.inventoryId IN (
SELECT inventoryId FROM tmp_stock_ledger_fix_miss
)
GROUP BY sl.inventoryId
) x ON x.maxId = slp.id
""".trimIndent(),
@@ -1131,7 +1149,7 @@ open class StockLedgerFixBackfillService(
).map { support.toLong(it["id"]) }.filter { it > 0 }
}

internal fun dateRangeForFilter(filter: String, args: Map<String, Any>): Pair<LocalDate, LocalDate>? {
open internal fun dateRangeForFilter(filter: String, args: Map<String, Any>): Pair<LocalDate, LocalDate>? {
val row = support.jdbcDao.queryForList(
"""
SELECT MIN(date) AS firstDate, MAX(date) AS lastDate
@@ -1149,7 +1167,7 @@ open class StockLedgerFixBackfillService(
return first to toExclusive
}

internal fun upsertStockLotDayRange(lotIds: List<Long>, from: LocalDate, toExclusive: LocalDate): Int {
open internal fun upsertStockLotDayRange(lotIds: List<Long>, from: LocalDate, toExclusive: LocalDate): Int {
if (lotIds.isEmpty()) return 0
return support.jdbcDao.executeUpdate(
"""
@@ -1259,7 +1277,7 @@ open class StockLedgerFixBackfillService(
)
}

internal fun fillLotQtyForLotIds(lotIds: List<Long>, today: LocalDate): Int {
open internal fun fillLotQtyForLotIds(lotIds: List<Long>, today: LocalDate): Int {
if (lotIds.isEmpty()) return 0
return support.withTempTx {
support.jdbcDao.executeUpdate("DROP TEMPORARY TABLE IF EXISTS tmp_sl_fix_adj_lots")
@@ -1313,7 +1331,7 @@ open class StockLedgerFixBackfillService(
}

/** Chain balance on new ADJ rows only; older rows for the same SKU are unchanged. */
internal fun fillBalanceOnNewAdjRows(adjDate: LocalDate, today: LocalDate): Int {
open internal fun fillBalanceOnNewAdjRows(adjDate: LocalDate, today: LocalDate): Int {
val rows = support.jdbcDao.queryForList(
"""
SELECT id, inventoryId,


Chargement…
Annuler
Enregistrer