|
|
|
@@ -230,19 +230,25 @@ class StockTakeRecordService( |
|
|
|
println("getApproverInventoryLotDetailsAll called with stockTakeId: $stockTakeId, pageNum: $pageNum, pageSize: $pageSize") |
|
|
|
|
|
|
|
// 3. 如果传了 stockTakeId,就把「同一轮」的所有 stockTake 找出来(stockTakeRoundId,舊資料則 planStart) |
|
|
|
val roundStockTakeIds: Set<Long> = if (stockTakeId != null) { |
|
|
|
// stockTakeId != null 时,优先用 stocktakerecord.stockTakeRoundId 取整轮记录(更快) |
|
|
|
// 如果该轮因为旧数据尚未写入 roundId 导致取不到,再 fallback 到旧逻辑(根据 stock_take 的 planStart / stockTakeRoundId 求 stockTakeId 列表) |
|
|
|
val (roundStockTakeIds, roundStockTakeRecords) = if (stockTakeId != null) { |
|
|
|
val baseStockTake = stockTakeRepository.findByIdAndDeletedIsFalse(stockTakeId) |
|
|
|
?: throw IllegalArgumentException("Stock take not found: $stockTakeId") |
|
|
|
resolveRoundStockTakeIds(baseStockTake) |
|
|
|
} else { |
|
|
|
emptySet() |
|
|
|
} |
|
|
|
|
|
|
|
// 4. 如果有 stockTakeId,则预先把这一轮相关的 stockTakeRecord 查出来建 map(避免全表扫描 + N^2) |
|
|
|
val roundStockTakeRecords = if (stockTakeId != null && roundStockTakeIds.isNotEmpty()) { |
|
|
|
stockTakeRecordRepository.findAllByStockTakeIdInAndDeletedIsFalse(roundStockTakeIds) |
|
|
|
val roundId = baseStockTake.stockTakeRoundId ?: baseStockTake.id |
|
|
|
val recordsByRound = stockTakeRecordRepository.findAllByStockTakeRoundIdAndDeletedIsFalse(roundId) |
|
|
|
|
|
|
|
if (recordsByRound.isNotEmpty()) { |
|
|
|
val ids = recordsByRound.mapNotNull { it.stockTake?.id }.toSet() |
|
|
|
ids to recordsByRound |
|
|
|
} else { |
|
|
|
val ids = resolveRoundStockTakeIds(baseStockTake) |
|
|
|
val records = if (ids.isNotEmpty()) stockTakeRecordRepository.findAllByStockTakeIdInAndDeletedIsFalse(ids) else emptyList() |
|
|
|
ids to records |
|
|
|
} |
|
|
|
} else { |
|
|
|
emptyList() |
|
|
|
emptySet<Long>() to emptyList() |
|
|
|
} |
|
|
|
val stockTakeRecordsMap = roundStockTakeRecords |
|
|
|
.groupBy { Pair(it.lotId ?: 0L, it.warehouse?.id ?: 0L) } |
|
|
|
@@ -413,13 +419,19 @@ class StockTakeRecordService( |
|
|
|
.maxByOrNull { it.actualStart ?: it.planStart ?: LocalDateTime.MIN } |
|
|
|
?: return emptyList() |
|
|
|
|
|
|
|
val roundStockTakeIds = resolveRoundStockTakeIds(latestBaseStockTake) |
|
|
|
if (roundStockTakeIds.isEmpty()) return emptyList() |
|
|
|
|
|
|
|
// stockTakeRecord 存在性:用来对齐 details 接口的 `stockTakeRecordId != null` |
|
|
|
val roundStockTakeRecords = stockTakeRecordRepository.findAllByStockTakeIdInAndDeletedIsFalse(roundStockTakeIds) |
|
|
|
// 优先用 stocktakerecord.stockTakeRoundId 直接取该轮次记录(避免再算 stockTakeId 列表 + in 查询) |
|
|
|
val roundId = latestBaseStockTake.stockTakeRoundId ?: latestBaseStockTake.id |
|
|
|
var roundStockTakeRecords = stockTakeRecordRepository.findAllByStockTakeRoundIdAndDeletedIsFalse(roundId) |
|
|
|
.filter { it.warehouse?.id in warehouseIds } |
|
|
|
|
|
|
|
// 兼容旧数据:如果该轮次 roundId 为空/未补写,则 fallback 到旧逻辑 |
|
|
|
if (roundStockTakeRecords.isEmpty()) { |
|
|
|
val roundStockTakeIds = resolveRoundStockTakeIds(latestBaseStockTake) |
|
|
|
if (roundStockTakeIds.isEmpty()) return emptyList() |
|
|
|
roundStockTakeRecords = stockTakeRecordRepository.findAllByStockTakeIdInAndDeletedIsFalse(roundStockTakeIds) |
|
|
|
.filter { it.warehouse?.id in warehouseIds } |
|
|
|
} |
|
|
|
|
|
|
|
val recordKeySet = roundStockTakeRecords.mapNotNull { r -> |
|
|
|
val lotId = r.lotId |
|
|
|
val whId = r.warehouse?.id |
|
|
|
@@ -476,6 +488,40 @@ class StockTakeRecordService( |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 轻量版:只返回 Approver 最新一轮的基本信息,不做 totalItem/totalLot 重计算。 |
|
|
|
* 用于前端先拿 stockTakeId,再调用 pending/approved 明细接口。 |
|
|
|
*/ |
|
|
|
open fun getLatestApproverStockTakeHeader(): AllPickedStockTakeListReponse? { |
|
|
|
val latestBaseStockTake = stockTakeRepository.findAll() |
|
|
|
.filter { !it.deleted } |
|
|
|
.maxByOrNull { it.actualStart ?: it.planStart ?: LocalDateTime.MIN } |
|
|
|
?: return null |
|
|
|
|
|
|
|
val statusValue = latestBaseStockTake.status?.let { st -> |
|
|
|
if (st == StockTakeStatus.APPROVING || st == StockTakeStatus.COMPLETED) st.value else "" |
|
|
|
} ?: "" |
|
|
|
|
|
|
|
return AllPickedStockTakeListReponse( |
|
|
|
id = 1L, |
|
|
|
stockTakeSession = "", |
|
|
|
lastStockTakeDate = latestBaseStockTake.actualStart?.toLocalDate(), |
|
|
|
status = statusValue, |
|
|
|
currentStockTakeItemNumber = 0, |
|
|
|
totalInventoryLotNumber = 0, |
|
|
|
stockTakeId = latestBaseStockTake.id ?: 0, |
|
|
|
stockTakeRoundId = latestBaseStockTake.stockTakeRoundId ?: latestBaseStockTake.id, |
|
|
|
stockTakerName = null, |
|
|
|
approverName = null, |
|
|
|
TotalItemNumber = 0, |
|
|
|
startTime = latestBaseStockTake.actualStart, |
|
|
|
endTime = latestBaseStockTake.actualEnd, |
|
|
|
ReStockTakeTrueFalse = false, |
|
|
|
planStartDate = latestBaseStockTake.planStart?.toLocalDate(), |
|
|
|
stockTakeSectionDescription = null |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
open fun getInventoryLotDetailsByWarehouseCode(warehouseCode: String): List<InventoryLotDetailResponse> { |
|
|
|
println("getInventoryLotDetailsByWarehouseCode called with code: $warehouseCode") |
|
|
|
|
|
|
|
@@ -690,6 +736,8 @@ return RecordsRes(paginatedResult, filteredResults.size) |
|
|
|
val varianceQty = availableQty - request.qty - request.badQty |
|
|
|
// 更新字段(第二次盘点) |
|
|
|
existingRecord.apply { |
|
|
|
// 兼容旧数据:如果之前没写 round id,则补写 |
|
|
|
this.stockTakeRoundId = this.stockTakeRoundId ?: (stockTake.stockTakeRoundId ?: stockTake.id) |
|
|
|
this.pickerSecondStockTakeQty = request.qty |
|
|
|
this.pickerSecondBadQty = request.badQty // 更新 badQty |
|
|
|
this.status = "pass" |
|
|
|
@@ -711,6 +759,7 @@ return RecordsRes(paginatedResult, filteredResults.size) |
|
|
|
this.lotId = inventoryLot.id |
|
|
|
this.warehouse = warehouse |
|
|
|
this.stockTake = stockTake |
|
|
|
this.stockTakeRoundId = stockTake.stockTakeRoundId ?: stockTake.id |
|
|
|
this.stockTakeSection = warehouse.stockTakeSection |
|
|
|
this.inventoryLotId = inventoryLot.id |
|
|
|
this.stockTakerId = stockTakerId |
|
|
|
@@ -853,6 +902,7 @@ return RecordsRes(paginatedResult, filteredResults.size) |
|
|
|
this.lotId = inventoryLot.id |
|
|
|
this.warehouse = warehouse |
|
|
|
this.stockTake = stockTake |
|
|
|
this.stockTakeRoundId = stockTake.stockTakeRoundId ?: stockTake.id |
|
|
|
this.stockTakeSection = request.stockTakeSection |
|
|
|
this.inventoryLotId = inventoryLot.id |
|
|
|
this.stockTakerId = request.stockTakerId |
|
|
|
|