Browse Source

update 4F handler name

stable1
CANCERYS\kw093 2 weeks ago
parent
commit
2c17ee7ab1
2 changed files with 89 additions and 77 deletions
  1. +79
    -71
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderQueryService.kt
  2. +10
    -6
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/DoDetailResponse.kt

+ 79
- 71
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderQueryService.kt View File

@@ -9,6 +9,7 @@ import com.ffii.fpsms.modules.deliveryOrder.web.models.StoreLaneSummary
import com.ffii.fpsms.modules.deliveryOrder.web.models.DoPickOrderSummaryItem
import org.springframework.stereotype.Service
import java.time.LocalDate
import java.time.LocalTime
import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRecordRepository
import com.ffii.fpsms.modules.pickOrder.entity.TruckRepository
@Service
@@ -21,48 +22,40 @@ class DoPickOrderQueryService(
fun getSummaryByStore(storeId: String, requiredDate: LocalDate?, releaseType: String): StoreLaneSummary {
val targetDate = requiredDate ?: LocalDate.now()
//println(" DEBUG: Getting summary for store=$storeId, date=$targetDate, releaseType=$releaseType")
val actualStoreId = when (storeId) {
"2/F" -> "2/F"
"4/F" -> "4/F"
else -> storeId
}
// Query active do_pick_order records (pending, released, completed that haven't been moved yet)
// Active: do_pick_order
val activeRecords = doPickOrderRepository.findByStoreIdAndRequiredDeliveryDateAndTicketStatusIn(
actualStoreId,
targetDate,
listOf(DoPickOrderStatus.pending, DoPickOrderStatus.released, DoPickOrderStatus.completed)
)
// 根据 releaseType 过滤 activeRecords
val filteredActiveRecordsByReleaseType = when (releaseType.lowercase()) {
"batch" -> activeRecords.filter { it.releaseType == "batch" }
"single" -> activeRecords.filter { it.releaseType == "single" }
else -> activeRecords // "all" 或其他值,不过滤
else -> activeRecords
}
// Query completed records from do_pick_order_record table
// Completed archive: do_pick_order_record
val completedRecords = doPickOrderRecordRepository.findByStoreIdAndRequiredDeliveryDateAndTicketStatusIn(
actualStoreId,
targetDate,
listOf(DoPickOrderStatus.completed)
)
// 根据 releaseType 过滤 completedRecords
val filteredCompletedRecordsByReleaseType = when (releaseType.lowercase()) {
"batch" -> completedRecords.filter { it.releaseType == "batch" }
"single" -> completedRecords.filter { it.releaseType == "single" }
else -> completedRecords // "all" 或其他值,不过滤
else -> completedRecords
}
//println(" DEBUG: Found ${activeRecords.size} active records for date $targetDate")
// println(" DEBUG: After releaseType filter: ${filteredActiveRecordsByReleaseType.size} active records")
//println(" DEBUG: Found ${completedRecords.size} completed records for date $targetDate")
//println(" DEBUG: After releaseType filter: ${filteredCompletedRecordsByReleaseType.size} completed records")
// Filter active records (check for non-issue lines)
// non-issue filter
val filteredActiveRecords = filteredActiveRecordsByReleaseType.filter { doPickOrder ->
val hasNonIssueLines = checkDoPickOrderHasNonIssueLines(doPickOrder.id!!)
if (!hasNonIssueLines) {
@@ -70,8 +63,7 @@ class DoPickOrderQueryService(
}
hasNonIssueLines
}
// For completed records, check if they have non-issue lines in the record table
val filteredCompletedRecords = filteredCompletedRecordsByReleaseType.filter { record ->
val hasNonIssueLines = checkDoPickOrderRecordHasNonIssueLines(record.id!!)
if (!hasNonIssueLines) {
@@ -79,84 +71,100 @@ class DoPickOrderQueryService(
}
hasNonIssueLines
}
// Combine both lists - need to create a common interface or convert to a common type
// Since both have the same fields we need, we can create a wrapper or use a data class
val allRecords = filteredActiveRecords.map {
// 合并为 summary item
// 你的要求是 handler 来源用 delivery_order_pick_order.handlerName
// 所以 active records 用 it.handlerName;completed records 这里给 null,避免混入 archive 来源
val allRecords = filteredActiveRecords.map {
DoPickOrderSummaryItem(
truckDepartureTime = it.truckDepartureTime,
truckLanceCode = it.truckLanceCode,
// 只對 4/F 顯示/分組 loadingSequence;2/F 維持舊邏輯避免同車線被拆成多序
loadingSequence = if (actualStoreId == "4/F") it.loadingSequence else null,
handledBy = it.handledBy
handledBy = it.handledBy,
handlerName = it.handlerName
)
} + filteredCompletedRecords.map {
DoPickOrderSummaryItem(
truckDepartureTime = it.truckDepartureTime,
truckLanceCode = it.truckLanceCode,
loadingSequence = if (actualStoreId == "4/F") it.loadingSequence else null,
handledBy = it.handledBy
handledBy = it.handledBy,
handlerName = null
)
}
val defaultTruckId = 5577L
val defaultTruck = truckRepository.findById(defaultTruckId).orElse(null)
val defaultTruckLaneCode = defaultTruck?.truckLanceCode ?: ""
//println(" DEBUG: After filtering, ${allRecords.size} records remain (${filteredActiveRecords.size} active + ${filteredCompletedRecords.size} completed)")
val grouped = if (actualStoreId == "4/F") {
allRecords.groupBy { Triple(it.truckDepartureTime, it.truckLanceCode, it.loadingSequence) }
} else {
// 2/F:回到舊分組(truckDepartureTime + truckLanceCode)
allRecords.groupBy { Pair(it.truckDepartureTime, it.truckLanceCode) }
}.mapValues { (_, list) ->
val mergedHandlerNames = list
.mapNotNull { it.handlerName?.trim()?.takeIf { n -> n.isNotEmpty() } }
.distinct()
.sorted()
.joinToString(",")
LaneBtn(
truckLanceCode = list.first().truckLanceCode ?: "",
loadingSequence = if (actualStoreId == "4/F") list.first().loadingSequence else null,
unassigned = list.count { it.handledBy == null },
total = list.size
total = list.size,
handlerName = mergedHandlerNames.ifBlank { null }
)
}
val filteredGrouped = grouped
.filter { (_, laneBtn) ->
laneBtn.truckLanceCode != defaultTruckLaneCode
}
val timeGroups = filteredGrouped.entries
.groupBy { (it.key as? Triple<*, *, *>)?.first as? java.time.LocalTime ?: (it.key as Pair<*, *>).first as java.time.LocalTime? }
.mapValues { (_, entries) ->
entries.map { it.value }
.filter { it.unassigned > 0 } // filter out lanes with no unassigned orders
.sortedWith(
compareByDescending<LaneBtn> { it.unassigned }
.thenBy { it.truckLanceCode }
.thenBy { it.loadingSequence ?: 999 }
)
}
.filterValues { lanes -> lanes.isNotEmpty() }
.toSortedMap(compareBy { it })
.entries.take(4)
.map { (time, lanes) ->
LaneRow(
truckDepartureTime = time?.toString() ?: "",
lanes = lanes
)
}
val defaultTruckCandidates = doPickOrderRepository.findByRequiredDeliveryDateAndTicketStatusIn(
targetDate,
listOf(DoPickOrderStatus.pending, DoPickOrderStatus.released)
)
// 只算:storeId = null 且 truckLanceCode = '車線-X'
val defaultTruckCount = defaultTruckCandidates.count {
it.storeId == null && it.truckLanceCode == "車線-X"
}
// 9) 回傳 summary,附帶 defaultTruckCount
return StoreLaneSummary(
storeId = storeId,
rows = timeGroups,
defaultTruckCount = defaultTruckCount
val filteredGrouped = grouped.filter { (_, laneBtn) ->
laneBtn.truckLanceCode != defaultTruckLaneCode
}
val groupedByTime: Map<LocalTime?, List<Map.Entry<Any, LaneBtn>>> =
filteredGrouped.entries.groupBy { entry: Map.Entry<Any, LaneBtn> ->
when (val key = entry.key) {
is Triple<*, *, *> -> key.first as? LocalTime
is Pair<*, *> -> key.first as? LocalTime
else -> null
}
}

val timeGroups = groupedByTime
.mapValues { (_, entries: List<Map.Entry<Any, LaneBtn>>) ->
entries.map { it.value }
.sortedWith(
compareByDescending<LaneBtn> { it.unassigned }
.thenBy { it.truckLanceCode }
.thenBy { it.loadingSequence ?: 999 }
)
}
.filterValues { lanes -> lanes.isNotEmpty() }
.toSortedMap(compareBy { it })
.entries
.take(4)
.map { (time, lanes) ->
LaneRow(
truckDepartureTime = time?.toString() ?: "",
lanes = lanes
)
}
val defaultTruckCandidates = doPickOrderRepository.findByRequiredDeliveryDateAndTicketStatusIn(
targetDate,
listOf(DoPickOrderStatus.pending, DoPickOrderStatus.released)
)
val defaultTruckCount = defaultTruckCandidates.count {
it.storeId == null && it.truckLanceCode == "車線-X"
}
return StoreLaneSummary(
storeId = storeId,
rows = timeGroups,
defaultTruckCount = defaultTruckCount
)
}
private fun checkDoPickOrderHasNonIssueLines(doPickOrderId: Long): Boolean {


+ 10
- 6
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/DoDetailResponse.kt View File

@@ -47,7 +47,9 @@ data class LaneBtn(
val truckLanceCode: String,
val loadingSequence: Int? = null,
val unassigned: Int,
val total: Int
val total: Int,
// 同一 truckLanceCode + loadingSequence 的 handler 去重后逗号拼接
val handlerName: String? = null
)
data class AssignByLaneRequest(
val userId: Long,
@@ -58,11 +60,13 @@ data class AssignByLaneRequest(
val requiredDate: LocalDate? // 必填:车道编号
)
data class DoPickOrderSummaryItem(
val truckDepartureTime: java.time.LocalTime?,
val truckLanceCode: String?,
val loadingSequence: Int?,
val handledBy: Long?
)
val truckDepartureTime: java.time.LocalTime?,
val truckLanceCode: String?,
val loadingSequence: Int?,
val handledBy: Long?,
// 来源:delivery_order_pick_order.handlerName
val handlerName: String? = null
)
data class DoSearchRow(
val id: Long,
val code: String?,


Loading…
Cancel
Save