Procházet zdrojové kódy

update do ticket ui

master
CANCERYS\kw093 před 8 hodinami
rodič
revize
4ee5babc8d
4 změnil soubory, kde provedl 76 přidání a 22 odebrání
  1. +31
    -12
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt
  2. +20
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderAssignmentService.kt
  3. +22
    -10
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderQueryService.kt
  4. +3
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/DoDetailResponse.kt

+ 31
- 12
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt Zobrazit soubor

@@ -1806,16 +1806,33 @@ val inventoryLotLine = illId?.let { inventoryLotLineMap[it] }
}

/**
* Workbench NO-HOLD release:
* - Create pick_order + stock_out
* Workbench NO-HOLD release (V1):
* - Create pick_order + stock_out header
* - Do NOT create suggested_pick_lot / stock_out_line
* - Do NOT update inventory_lot_line.holdQty
*
* Downstream should be handled by workbench services (no-hold suggestion + stock_out_line creation).
* Downstream should be handled by workbench batch release (no-hold suggestion + stock_out_line creation),
* or on ticket assign when using [releaseDeliveryOrderWithoutTicketNoHoldV2].
*/
@Transactional(rollbackFor = [Exception::class])
open fun releaseDeliveryOrderWithoutTicketNoHold(request: ReleaseDoRequest): ReleaseDoResult {
println(" DEBUG: Starting releaseDeliveryOrderWithoutTicketNoHold for DO ID: ${request.id}")
open fun releaseDeliveryOrderWithoutTicketNoHold(request: ReleaseDoRequest): ReleaseDoResult =
releaseDeliveryOrderWithoutTicketNoHoldInternal(request, createStockOutHeader = true)

/**
* Workbench NO-HOLD release (V2): same as [releaseDeliveryOrderWithoutTicketNoHold] but **does not** create a
* [StockOut] row. Suggested pick lots, stock out header, and stock out lines are created when the workbench
* assigns the [delivery_order_pick_order] ([com.ffii.fpsms.modules.deliveryOrder.service.DoWorkbenchDopoAssignmentService]).
*/
@Transactional(rollbackFor = [Exception::class])
open fun releaseDeliveryOrderWithoutTicketNoHoldV2(request: ReleaseDoRequest): ReleaseDoResult =
releaseDeliveryOrderWithoutTicketNoHoldInternal(request, createStockOutHeader = false)

private fun releaseDeliveryOrderWithoutTicketNoHoldInternal(
request: ReleaseDoRequest,
createStockOutHeader: Boolean,
): ReleaseDoResult {
val tag = if (createStockOutHeader) "V1" else "V2"
println(" DEBUG: Starting releaseDeliveryOrderWithoutTicketNoHold ($tag) for DO ID: ${request.id}")

val deliveryOrder = deliveryOrderRepository.findByIdAndDeletedIsFalse(request.id)
?: throw NoSuchElementException("Delivery Order not found")
@@ -1854,14 +1871,16 @@ val inventoryLotLine = illId?.let { inventoryLotLineMap[it] }
pickOrderEntity.status = com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus.RELEASED
pickOrderRepository.saveAndFlush(pickOrderEntity)

// Create stock out header only; stock_out_line is created by workbench service
val stockOut = StockOut().apply {
this.type = "do"
this.consoPickOrderCode = consoCode
this.status = StockOutStatus.PENDING.status
this.handler = request.userId
if (createStockOutHeader) {
// Create stock out header only; stock_out_line is created by workbench service (V1 batch) or on assign (V2)
val stockOut = StockOut().apply {
this.type = "do"
this.consoPickOrderCode = consoCode
this.status = StockOutStatus.PENDING.status
this.handler = request.userId
}
stockOutRepository.saveAndFlush(stockOut)
}
stockOutRepository.saveAndFlush(stockOut)
}

// Truck selection (reuse normal logic)


+ 20
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderAssignmentService.kt Zobrazit soubor

@@ -13,6 +13,7 @@ import com.ffii.fpsms.modules.user.entity.UserRepository
import org.springframework.stereotype.Service
import java.time.LocalDateTime
import java.time.LocalDate
import java.time.LocalTime
@Service
class DoPickOrderAssignmentService(
private val doPickOrderRepository: DoPickOrderRepository,
@@ -41,6 +42,15 @@ class DoPickOrderAssignmentService(
// 获取日期(如果提供)
val requiredDate = request.requiredDate
println(" DEBUG: assignByLane - Requested date: $requiredDate")
val requestedDepartureTime: LocalTime? = request.truckDepartureTime
?.takeIf { it.isNotBlank() }
?.let {
try {
LocalTime.parse(it)
} catch (e: Exception) {
null
}
}
// 根据是否有日期参数选择不同的查询方法
val allCandidates = if (requiredDate != null) {
@@ -58,6 +68,16 @@ class DoPickOrderAssignmentService(
)
}
.filter { it.truckLanceCode == request.truckLanceCode }
.let { candidates ->
requestedDepartureTime?.let { dep ->
candidates.filter { it.truckDepartureTime == dep }
} ?: candidates
}
.let { candidates ->
request.loadingSequence?.let { seq ->
candidates.filter { it.loadingSequence == seq }
} ?: candidates
}
.sortedBy { it.truckDepartureTime }
println(" DEBUG: Found ${allCandidates.size} candidate do_pick_orders for lane ${request.truckLanceCode}")


+ 22
- 10
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderQueryService.kt Zobrazit soubor

@@ -86,12 +86,15 @@ class DoPickOrderQueryService(
DoPickOrderSummaryItem(
truckDepartureTime = it.truckDepartureTime,
truckLanceCode = it.truckLanceCode,
// 只對 4/F 顯示/分組 loadingSequence;2/F 維持舊邏輯避免同車線被拆成多序
loadingSequence = if (actualStoreId == "4/F") it.loadingSequence else null,
handledBy = it.handledBy
)
} + filteredCompletedRecords.map {
DoPickOrderSummaryItem(
truckDepartureTime = it.truckDepartureTime,
truckLanceCode = it.truckLanceCode,
loadingSequence = if (actualStoreId == "4/F") it.loadingSequence else null,
handledBy = it.handledBy
)
}
@@ -100,24 +103,33 @@ class DoPickOrderQueryService(
val defaultTruckLaneCode = defaultTruck?.truckLanceCode ?: ""
//println(" DEBUG: After filtering, ${allRecords.size} records remain (${filteredActiveRecords.size} active + ${filteredCompletedRecords.size} completed)")
val grouped = allRecords.groupBy { it.truckDepartureTime to it.truckLanceCode }
.mapValues { (_, list) ->
LaneBtn(
truckLanceCode = list.first().truckLanceCode ?: "",
unassigned = list.count { it.handledBy == null },
total = list.size
)
}
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) ->
LaneBtn(
truckLanceCode = list.first().truckLanceCode ?: "",
loadingSequence = if (actualStoreId == "4/F") list.first().loadingSequence else null,
unassigned = list.count { it.handledBy == null },
total = list.size
)
}
val filteredGrouped = grouped
.filter { (_, laneBtn) ->
laneBtn.truckLanceCode != defaultTruckLaneCode
}
val timeGroups = filteredGrouped.entries
.groupBy { it.key.first }
.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
.sortedByDescending { it.unassigned }
.sortedWith(
compareByDescending<LaneBtn> { it.unassigned }
.thenBy { it.truckLanceCode }
.thenBy { it.loadingSequence ?: 999 }
)
}
.filterValues { lanes -> lanes.isNotEmpty() }
.toSortedMap(compareBy { it })


+ 3
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/DoDetailResponse.kt Zobrazit soubor

@@ -45,6 +45,7 @@ data class LaneRow(

data class LaneBtn(
val truckLanceCode: String,
val loadingSequence: Int? = null,
val unassigned: Int,
val total: Int
)
@@ -53,11 +54,13 @@ data class AssignByLaneRequest(
val storeId: String,
val truckDepartureTime: String?, // 可选:限定出车时间
val truckLanceCode: String ,
val loadingSequence: Int? = null,
val requiredDate: LocalDate? // 必填:车道编号
)
data class DoPickOrderSummaryItem(
val truckDepartureTime: java.time.LocalTime?,
val truckLanceCode: String?,
val loadingSequence: Int?,
val handledBy: Long?
)
data class DoSearchRow(


Načítá se…
Zrušit
Uložit