瀏覽代碼

update

master
CANCERYS\kw093 1 月之前
父節點
當前提交
f94b79be8d
共有 4 個檔案被更改,包括 336 行新增5 行删除
  1. +246
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt
  2. +2
    -2
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt
  3. +85
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SearchPickOrderRequest.kt
  4. +3
    -3
      src/main/java/com/ffii/fpsms/modules/productProcess/service/ProductProcessService.kt

+ 246
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt 查看文件

@@ -5019,6 +5019,252 @@ open fun getLotDetailsByDoPickOrderRecordId(doPickOrderRecordId: Long): Map<Stri
"pickOrders" to pickOrderDtos
)
}
open fun getLotDetailsByDoPickOrderRecordId3(doPickOrderRecordId: Long): LotDetailsByDoPickOrderRecordResponse {
println("=== Debug: getLotDetailsByDoPickOrderRecordId3 (Repository-based) ===")
println("doPickOrderRecordId: $doPickOrderRecordId")
val zero = BigDecimal.ZERO
val today = LocalDate.now()
// 1) 获取 DoPickOrderRecord
val dpor = doPickOrderRecordRepository.findById(doPickOrderRecordId).orElse(null)
?: return LotDetailsByDoPickOrderRecordResponse(
fgInfo = null,
pickOrders = emptyList()
)
println("🔍 Found DoPickOrderRecord: id=${dpor.id}, ticketNo=${dpor.ticketNo}")
// 2) 构建 fgInfo
val fgInfo = FgInfoResponse(
doPickOrderId = dpor.id,
ticketNo = dpor.ticketNo,
storeId = dpor.storeId,
shopCode = dpor.shopCode,
shopName = dpor.shopName,
truckLanceCode = dpor.truckLanceCode,
departureTime = dpor.truckDepartureTime
)
// 3) 通过 DoPickOrderLineRecord 获取 pickOrderIds
val lineRecords = doPickOrderLineRecordRepository.findByDoPickOrderIdAndDeletedFalse(dpor.recordId!!)
println("🔍 Found ${lineRecords.size} DoPickOrderLineRecord records")
var pickOrderIds = lineRecords.mapNotNull { it.pickOrderId }.distinct()
// 备用方案:如果 lineRecords 中没有 pickOrderId,尝试使用 DoPickOrderRecord.pickOrderId
if (pickOrderIds.isEmpty() && dpor.pickOrderId != null) {
println("⚠️ WARNING: No pickOrderIds in lineRecords, using DoPickOrderRecord.pickOrderId=${dpor.pickOrderId}")
pickOrderIds = listOf(dpor.pickOrderId!!)
}
if (pickOrderIds.isEmpty()) {
println("❌ ERROR: No pickOrderIds found for doPickOrderRecordId=$doPickOrderRecordId")
return LotDetailsByDoPickOrderRecordResponse(
fgInfo = fgInfo,
pickOrders = emptyList()
)
}
println("🔍 Using pickOrderIds: $pickOrderIds")
// 4) 批量加载所有相关数据
val pickOrders = pickOrderRepository.findAllById(pickOrderIds)
.filter { !it.deleted }
if (pickOrders.isEmpty()) {
println("❌ ERROR: No pick orders found for ids: $pickOrderIds")
return LotDetailsByDoPickOrderRecordResponse(
fgInfo = fgInfo,
pickOrders = emptyList()
)
}
println("🔍 Found ${pickOrders.size} pick orders")
// 5) 收集所有 pickOrderLineIds
val allPickOrderLineIds = pickOrders
.flatMap { it.pickOrderLines }
.filter { !it.deleted }
.mapNotNull { it.id }
println("🔍 Found ${allPickOrderLineIds.size} pick order lines")
// 6) 批量加载 suggestions 和 stock out lines
val allSuggestions = if (allPickOrderLineIds.isNotEmpty()) {
suggestPickLotRepository.findAllByPickOrderLineIdIn(allPickOrderLineIds)
} else {
emptyList()
}
val allStockOutLines = if (allPickOrderLineIds.isNotEmpty()) {
allPickOrderLineIds.flatMap { lineId ->
stockOutLIneRepository.findAllByPickOrderLineIdAndDeletedFalse(lineId)
}
} else {
emptyList()
}
// 7) 按 pickOrderLineId 分组
val suggestionsByLineId = allSuggestions.groupBy { it.pickOrderLine?.id }
val stockOutLinesByLineId = allStockOutLines.groupBy { it.pickOrderLineId }
// 8) 批量加载所有 inventoryLotLineIds
val allInventoryLotLineIds = allSuggestions
.mapNotNull { it.suggestedLotLine?.id }
.distinct()
val inventoryLotLinesMap = if (allInventoryLotLineIds.isNotEmpty()) {
inventoryLotLineRepository.findAllById(allInventoryLotLineIds)
.associateBy { it.id!! }
} else {
emptyMap()
}
// 9) 构建响应
val pickOrderDtos = pickOrders.map { po ->
val lineDtos = po.pickOrderLines
.filter { !it.deleted }
.map { pol ->
val lineId = pol.id
val item = pol.item
val uom = pol.uom
// 获取该 line 的 suggestions 和 stock out lines
val suggestions = lineId?.let { suggestionsByLineId[it] } ?: emptyList()
val stockOutLines = lineId?.let { stockOutLinesByLineId[it] } ?: emptyList()
// 构建 lots(合并相同 lot 的多个 suggestions)
val lotMap = mutableMapOf<Long?, LotDetailResponse>()
suggestions.forEach { spl ->
val ill = spl.suggestedLotLine
if (ill != null && ill.id != null) {
val illId = ill.id!!
val illEntity = inventoryLotLinesMap[illId] ?: ill
val il = illEntity.inventoryLot
val w = illEntity.warehouse
val isExpired = il?.expiryDate?.let { exp -> exp.isBefore(today) } == true
val availableQty = (illEntity.inQty ?: zero)
.minus(illEntity.outQty ?: zero)
.minus(illEntity.holdQty ?: zero)
// 查找对应的 stock out line
val stockOutLine = stockOutLines.find { sol ->
sol.inventoryLotLineId == illId
}
// 计算 actualPickQty
val actualPickQty = stockOutLine?.qty?.let { numToBigDecimal(it as? Number) }
if (lotMap.containsKey(illId)) {
// 合并 requiredQty
val existing = lotMap[illId]!!
val newRequiredQty = (existing.requiredQty ?: zero).plus(spl.qty ?: zero)
lotMap[illId] = existing.copy(requiredQty = newRequiredQty)
} else {
lotMap[illId] = LotDetailResponse(
id = illId,
lotNo = il?.lotNo,
expiryDate = il?.expiryDate,
location = w?.name,
stockUnit = illEntity.stockUom?.uom?.udfudesc ?: uom?.udfudesc ?: "N/A",
availableQty = availableQty,
requiredQty = spl.qty,
actualPickQty = actualPickQty,
inQty = illEntity.inQty,
outQty = illEntity.outQty,
holdQty = illEntity.holdQty,
lotStatus = illEntity.status?.value,
lotAvailability = when {
isExpired -> "expired"
stockOutLine?.status == "rejected" -> "rejected"
availableQty <= zero -> "insufficient_stock"
illEntity.status?.value == "unavailable" -> "status_unavailable"
else -> "available"
},
processingStatus = when {
stockOutLine?.status == "completed" -> "completed"
stockOutLine?.status == "rejected" -> "rejected"
else -> "pending"
},
suggestedPickLotId = spl.id,
stockOutLineId = stockOutLine?.id,
stockOutLineStatus = stockOutLine?.status,
stockOutLineQty = stockOutLine?.qty?.let { numToBigDecimal(it as? Number) },
router = RouterInfoResponse(
id = null,
index = w?.order,
route = w?.code,
area = w?.code
)
)
}
}
}
val lots = lotMap.values.toList()
// 构建 stockouts(包括没有 lot 的)
val stockouts = stockOutLines.map { sol ->
val illId = sol.inventoryLotLineId
val ill = illId?.let { inventoryLotLinesMap[it] }
val il = ill?.inventoryLot
val w = ill?.warehouse
val available = if (ill == null) null else
(ill.inQty ?: zero)
.minus(ill.outQty ?: zero)
.minus(ill.holdQty ?: zero)
StockOutDetailResponse(
id = sol.id,
status = sol.status,
qty = sol.qty?.let { numToBigDecimal(it as? Number) },
lotId = ill?.id,
lotNo = il?.lotNo ?: "",
location = w?.name ?: "",
availableQty = available,
noLot = (ill == null)
)
}
PickOrderLineDetailResponse(
id = lineId,
requiredQty = pol.qty,
status = pol.status?.value,
item = ItemInfoResponse(
id = item?.id,
code = item?.code,
name = item?.name,
uomCode = uom?.code,
uomDesc = uom?.udfudesc,
uomShortDesc = uom?.udfShortDesc
),
lots = lots,
stockouts = stockouts
)
}
PickOrderDetailResponse(
pickOrderId = po.id,
pickOrderCode = po.code,
doOrderId = po.deliveryOrder?.id,
deliveryOrderCode = po.deliveryOrder?.code,
consoCode = po.consoCode,
status = po.status?.value,
targetDate = po.targetDate?.toLocalDate(),
pickOrderLines = lineDtos
)
}
println("✅ Successfully built response with ${pickOrderDtos.size} pick orders")
return LotDetailsByDoPickOrderRecordResponse(
fgInfo = fgInfo,
pickOrders = pickOrderDtos
)
}
// 新增:从 do_pick_order_record 表查询(用于已完成的 pick orders)
open fun getFgPickOrdersFromRecordByPickOrderId(pickOrderId: Long): List<Map<String, Any?>> {
try {


+ 2
- 2
src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt 查看文件

@@ -162,8 +162,8 @@ class PickOrderController(
return pickOrderService.getPickOrderLineLotDetails(pickOrderLineId);
}
@GetMapping("/lot-details-by-do-pick-order-record/{doPickOrderRecordId}")
fun getLotDetailsByDoPickOrderRecordId(@PathVariable doPickOrderRecordId: Long): Map<String, Any?> {
return pickOrderService.getLotDetailsByDoPickOrderRecordId2(doPickOrderRecordId)
fun getLotDetailsByDoPickOrderRecordId(@PathVariable doPickOrderRecordId: Long): LotDetailsByDoPickOrderRecordResponse {
return pickOrderService.getLotDetailsByDoPickOrderRecordId3(doPickOrderRecordId)
}

@PostMapping("/groups")


+ 85
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SearchPickOrderRequest.kt 查看文件

@@ -3,6 +3,8 @@ package com.ffii.fpsms.modules.pickOrder.web.models
import org.springframework.web.bind.annotation.RequestParam
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.LocalDate
import java.math.BigDecimal
data class SearchPickOrderRequest (
val code: String?,
val targetDateFrom: String?,
@@ -47,4 +49,87 @@ data class CompletedDoPickOrderResponse(
data class FgPickOrderSummary(
val pickOrderId: Long,
val deliveryOrderId: Long?
)
data class LotDetailsByDoPickOrderRecordResponse(
val fgInfo: FgInfoResponse?,
val pickOrders: List<PickOrderDetailResponse>
)

data class FgInfoResponse(
val doPickOrderId: Long?,
val ticketNo: String?,
val storeId: String?,
val shopCode: String?,
val shopName: String?,
val truckLanceCode: String?,
val departureTime: LocalTime?
)

data class PickOrderDetailResponse(
val pickOrderId: Long?,
val pickOrderCode: String?,
val doOrderId: Long?,
val deliveryOrderCode: String?,
val consoCode: String?,
val status: String?,
val targetDate: LocalDate?,
val pickOrderLines: List<PickOrderLineDetailResponse>
)

data class PickOrderLineDetailResponse(
val id: Long?,
val requiredQty: BigDecimal?,
val status: String?,
val item: ItemInfoResponse,
val lots: List<LotDetailResponse>,
val stockouts: List<StockOutDetailResponse>
)

data class ItemInfoResponse(
val id: Long?,
val code: String?,
val name: String?,
val uomCode: String?,
val uomDesc: String?,
val uomShortDesc: String?
)

data class LotDetailResponse(
val id: Long?,
val lotNo: String?,
val expiryDate: LocalDate?,
val location: String?,
val stockUnit: String?,
val availableQty: BigDecimal?,
val requiredQty: BigDecimal?,
val actualPickQty: BigDecimal?,
val inQty: BigDecimal?,
val outQty: BigDecimal?,
val holdQty: BigDecimal?,
val lotStatus: String?,
val lotAvailability: String?,
val processingStatus: String?,
val suggestedPickLotId: Long?,
val stockOutLineId: Long?,
val stockOutLineStatus: String?,
val stockOutLineQty: BigDecimal?,
val router: RouterInfoResponse
)

data class RouterInfoResponse(
val id: Long?,
val index: String?,
val route: String?,
val area: String?
)

data class StockOutDetailResponse(
val id: Long?,
val status: String?,
val qty: BigDecimal?,
val lotId: Long?,
val lotNo: String?,
val location: String?,
val availableQty: BigDecimal?,
val noLot: Boolean
)

+ 3
- 3
src/main/java/com/ffii/fpsms/modules/productProcess/service/ProductProcessService.kt 查看文件

@@ -476,7 +476,7 @@ open class ProductProcessService(
seqNo = line.seqNo?:0,
name = line.name?:"",
description = line.description?:"",
equipment_name = line.equipment?.name?:"",
equipment_name = line.equipmentType?:"",
status = line.status?:"",
byproductId = line.byproduct?.id?:0,
byproductName = line.byproduct?.name?:"",
@@ -487,8 +487,8 @@ open class ProductProcessService(
defectUom = line.defectUom?:"",
outputFromProcessQty = line.outputFromProcessQty?:0,
outputFromProcessUom = line.outputFromProcessUom?:"",
startTime = line.startTime?:LocalDateTime.now(),
endTime = line.endTime?:LocalDateTime.now()
startTime = line.startTime,
endTime = line.endTime
)
}
)


Loading…
取消
儲存