CANCERYS\kw093 vor 2 Monaten
Ursprung
Commit
7517d99499
8 geänderte Dateien mit 283 neuen und 11 gelöschten Zeilen
  1. +20
    -1
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrder.kt
  2. +20
    -4
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRecord.kt
  3. +3
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRepository.kt
  4. +6
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt
  5. +131
    -5
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderService.kt
  6. +10
    -1
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DoPickOrderController.kt
  7. +21
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/DoDetailResponse.kt
  8. +72
    -0
      src/main/resources/db/changelog/changes/20251014_01_enson/02_altertable_enson.sql

+ 20
- 1
src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrder.kt Datei anzeigen

@@ -81,6 +81,17 @@ class DoPickOrder {
@Column(name = "deleted")
var deleted: Boolean = false
@Column(name = "pick_order_code", length = 50)
var pickOrderCode: String? = null

@Column(name = "delivery_order_code", length = 50)
var deliveryOrderCode: String? = null

@Column(name = "loading_sequence")
var loadingSequence: Int? = null

@Column(name = "handler_name", length = 100)
var handlerName: String? = null
// Default constructor for Hibernate
constructor()
@@ -96,6 +107,7 @@ class DoPickOrder {
doOrderId: Long? = null,
ticketReleaseTime: LocalDateTime? = null,
shopId: Long? = null,
handlerName: String? = null,
handledBy: Long? = null,
ticketCompleteDateTime: LocalDateTime? = null,
truckLanceCode: String? = null,
@@ -103,7 +115,10 @@ class DoPickOrder {
shopName: String? = null,
requiredDeliveryDate: LocalDate? = null,
createdBy: String? = null,
modifiedBy: String? = null
modifiedBy: String? = null,
pickOrderCode: String? = null,
deliveryOrderCode: String? = null,
loadingSequence: Int? = null,
) {
this.storeId = storeId
this.ticketNo = ticketNo
@@ -113,6 +128,7 @@ class DoPickOrder {
this.ticketStatus = ticketStatus
this.truckId = truckId
this.truckDepartureTime = truckDepartureTime
this.handlerName = handlerName
this.shopId = shopId
this.handledBy = handledBy
this.ticketCompleteDateTime = ticketCompleteDateTime
@@ -122,5 +138,8 @@ class DoPickOrder {
this.requiredDeliveryDate = requiredDeliveryDate
this.createdBy = createdBy
this.modifiedBy = modifiedBy
this.pickOrderCode = pickOrderCode
this.deliveryOrderCode = deliveryOrderCode
this.loadingSequence = loadingSequence
}
}

+ 20
- 4
src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRecord.kt Datei anzeigen

@@ -26,7 +26,14 @@ class DoPickOrderRecord {
@Column(name = "do_order_id")
var doOrderId: Long? = null
@Column(name = "pick_order_code", length = 50)
var pickOrderCode: String? = null

@Column(name = "delivery_order_code", length = 50)
var deliveryOrderCode: String? = null

@Column(name = "loading_sequence")
var loadingSequence: Int? = null
@Enumerated(EnumType.STRING)
@Column(name = "ticket_status")
var ticketStatus: DoPickOrderStatus? = null
@@ -81,7 +88,8 @@ class DoPickOrderRecord {
@Column(name = "deleted")
var deleted: Boolean = false
@Column(name = "handler_name", length = 100)
var handlerName: String? = null
// Default constructor for Hibernate
constructor()
@@ -94,8 +102,9 @@ class DoPickOrderRecord {
truckDepartureTime: LocalTime? = null,
pickOrderId: Long? = null,
doOrderId: Long? = null,
shopId: Long? = null,
ticketReleaseTime: LocalDateTime? = null,
shopId: Long? = null,
handlerName: String? = null,
handledBy: Long? = null,
ticketCompleteDateTime: LocalDateTime? = null,
truckLanceCode: String? = null,
@@ -103,7 +112,10 @@ class DoPickOrderRecord {
shopName: String? = null,
requiredDeliveryDate: LocalDate? = null,
createdBy: String? = null,
modifiedBy: String? = null
modifiedBy: String? = null,
pickOrderCode: String? = null,
deliveryOrderCode: String? = null,
loadingSequence: Int? = null,
) {
this.storeId = storeId
this.ticketNo = ticketNo
@@ -116,11 +128,15 @@ class DoPickOrderRecord {
this.shopId = shopId
this.handledBy = handledBy
this.ticketCompleteDateTime = ticketCompleteDateTime
this.handlerName = handlerName
this.truckLanceCode = truckLanceCode
this.shopCode = shopCode
this.shopName = shopName
this.requiredDeliveryDate = requiredDeliveryDate
this.createdBy = createdBy
this.modifiedBy = modifiedBy
this.pickOrderCode = pickOrderCode
this.deliveryOrderCode = deliveryOrderCode
this.loadingSequence = loadingSequence
}
}

+ 3
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/entity/DoPickOrderRepository.kt Datei anzeigen

@@ -21,4 +21,7 @@ interface DoPickOrderRepository : JpaRepository<DoPickOrder, Long> {
fun findByPickOrderId(pickOrderId: Long): List<DoPickOrder>

fun findByTicketStatusIn(statuses: List<DoPickOrderStatus>): List<DoPickOrder>
// 在 DoPickOrderRepository 中添加这个方法
fun findByHandledByAndTicketStatusIn(handledBy: Long, status: List<DoPickOrderStatus>): List<DoPickOrder>
fun findByStoreIdAndTicketStatusIn(storeId: String, status: List<DoPickOrderStatus>): List<DoPickOrder>
}

+ 6
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DeliveryOrderService.kt Datei anzeigen

@@ -563,6 +563,9 @@ val doPickOrderRecord = DoPickOrderRecord(
shopId = deliveryOrder.shop?.id,
handledBy = null,
doOrderId = deliveryOrder.id,
pickOrderCode = createdPickOrder.code,
deliveryOrderCode = deliveryOrder.code,
loadingSequence = deliveryOrder.deliveryOrderLines.size,
// ✅ 填充新增字段
truckLanceCode = truck?.truckLanceCode,
shopCode = deliveryOrder.shop?.code,
@@ -585,6 +588,9 @@ val doPickOrder = DoPickOrder(
truckDepartureTime = truck?.departureTime,
shopId = deliveryOrder.shop?.id,
handledBy = null,
pickOrderCode = createdPickOrder.code,
deliveryOrderCode = deliveryOrder.code,
loadingSequence = deliveryOrder.deliveryOrderLines.size,
ticketReleaseTime = null,
// ✅ 填充新增字段
truckLanceCode = truck?.truckLanceCode,


+ 131
- 5
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoPickOrderService.kt Datei anzeigen

@@ -35,10 +35,15 @@ import java.time.LocalDateTime
import com.ffii.fpsms.modules.deliveryOrder.web.models.AssignByStoreRequest
import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRecord
import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRecordRepository
import com.ffii.fpsms.modules.deliveryOrder.web.models.* // ✅ 导入
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository
import com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus
@Service
class DoPickOrderService(
private val doPickOrderRepository: DoPickOrderRepository,
private val doPickOrderRecordRepository: DoPickOrderRecordRepository
private val doPickOrderRecordRepository: DoPickOrderRecordRepository,
private val userRepository: UserRepository,
private val pickOrderRepository: PickOrderRepository
) {
fun findReleasedDoPickOrders(): List<DoPickOrder> {
return doPickOrderRepository.findByTicketStatusIn(
@@ -107,10 +112,13 @@ class DoPickOrderService(
// ✅ Updated method to set ticketReleaseTime when assigning order to user
fun updateHandledByForPickOrder(pickOrderId: Long, userId: Long): List<DoPickOrder> {
val doPickOrders = doPickOrderRepository.findByPickOrderId(pickOrderId)
val user = userRepository.findById(userId).orElse(null) // ✅ 改用 orElse(null)
val handlerName = user?.name ?: "Unknown"
doPickOrders.forEach {
it.handledBy = userId
it.handlerName = handlerName
it.ticketStatus = DoPickOrderStatus.released
it.ticketReleaseTime = LocalDateTime.now() // ✅ 设置 release time
it.ticketReleaseTime = LocalDateTime.now()
}
return doPickOrderRepository.saveAll(doPickOrders)
}
@@ -142,10 +150,13 @@ class DoPickOrderService(
// ✅ Add method to update DoPickOrderRecord status
fun updateRecordHandledByForPickOrder(pickOrderId: Long, userId: Long): List<DoPickOrderRecord> {
val doPickOrderRecords = doPickOrderRecordRepository.findByPickOrderId(pickOrderId)
val user = userRepository.findById(userId).orElse(null) // ✅ 改用 orElse(null)
val handlerName = user?.name ?: "Unknown"
doPickOrderRecords.forEach {
it.handledBy = userId
it.handlerName = handlerName
it.ticketStatus = DoPickOrderStatus.released
it.ticketReleaseTime = LocalDateTime.now() // ✅ 设置 release time
it.ticketReleaseTime = LocalDateTime.now()
}
return doPickOrderRecordRepository.saveAll(doPickOrderRecords)
}
@@ -171,6 +182,121 @@ class DoPickOrderService(
}
return doPickOrderRepository.saveAll(doPickOrders)
}
fun getSummaryByStore(storeId: String): StoreLaneSummary {
// ✅ 修改:查询所有状态的订单,不只是 pending
val allRecords = doPickOrderRepository.findByStoreIdAndTicketStatusIn(
storeId,
listOf(DoPickOrderStatus.pending, DoPickOrderStatus.released, DoPickOrderStatus.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 timeGroups = grouped.entries
.groupBy { it.key.first }
.mapValues { (_, entries) ->
entries.map { it.value }
.sortedByDescending { it.unassigned }
.take(3)
}
.filterValues { lanes -> lanes.any { it.unassigned > 0 } }
.toSortedMap(compareBy { it })
.entries.take(4)
.map { (time, lanes) ->
LaneRow(
truckDepartureTime = time?.toString() ?: "",
lanes = lanes
)
}
return StoreLaneSummary(storeId = storeId, rows = timeGroups)
}

}
// ✅ 修复:把 assignByLane 移到类里面
fun assignByLane(request: AssignByLaneRequest): MessageResponse {
val existingOrders = doPickOrderRepository.findByHandledByAndTicketStatusIn(
request.userId,
listOf(DoPickOrderStatus.released, DoPickOrderStatus.pending)
)
if (existingOrders.isNotEmpty()) {
return MessageResponse(
id = null, code = "USER_BUSY", name = null, type = null,
message = "User already has an active pick order. Please complete it first.",
errorPosition = null, entity = null
)
}
val candidates = doPickOrderRepository
.findByStoreIdAndTicketStatusOrderByTruckDepartureTimeAsc(
request.storeId,
DoPickOrderStatus.pending
)
.filter {
it.handledBy == null &&
it.truckLanceCode == request.truckLanceCode &&
(request.truckDepartureTime == null ||
it.truckDepartureTime?.toString() == request.truckDepartureTime)
}
if (candidates.isEmpty()) {
return MessageResponse(
id = null, code = "NO_ORDERS", name = null, type = null,
message = "No available orders for lane ${request.truckLanceCode}",
errorPosition = null, entity = null
)
}
val firstOrder = candidates.first()
val user = userRepository.findById(request.userId).orElse(null)
val handlerName = user?.name ?: "Unknown"
// ✅ 更新 do_pick_order
firstOrder.handledBy = request.userId
firstOrder.handlerName = handlerName
firstOrder.ticketStatus = DoPickOrderStatus.released
firstOrder.ticketReleaseTime = LocalDateTime.now()
doPickOrderRepository.save(firstOrder)
// ✅ 同步更新 pick_order 表
if (firstOrder.pickOrderId != null) {
val pickOrder = pickOrderRepository.findById(firstOrder.pickOrderId!!).orElse(null)
if (pickOrder != null) {
// ✅ 修复:assignTo 需要 User 对象,不是 Long
val user = userRepository.findById(request.userId).orElse(null)
pickOrder.assignTo = user
pickOrder.status = PickOrderStatus.RELEASED
pickOrderRepository.save(pickOrder)
}
}
// 同步更新 record
val records = doPickOrderRecordRepository.findByPickOrderId(firstOrder.pickOrderId!!)
records.forEach {
it.handledBy = request.userId
it.handlerName = handlerName
it.ticketStatus = DoPickOrderStatus.released
it.ticketReleaseTime = LocalDateTime.now()
}
doPickOrderRecordRepository.saveAll(records)
return MessageResponse(
id = firstOrder.pickOrderId,
code = "SUCCESS",
name = null,
type = null,
message = "Assigned pick order from lane ${request.truckLanceCode}",
errorPosition = null,
entity = mapOf(
"pickOrderId" to firstOrder.pickOrderId,
"ticketNo" to firstOrder.ticketNo
)
)
}
} // ✅ 类结束

+ 10
- 1
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/DoPickOrderController.kt Datei anzeigen

@@ -13,6 +13,7 @@ import com.ffii.fpsms.modules.pickOrder.web.models.ConsoPickOrderRequest
import com.ffii.fpsms.modules.pickOrder.web.models.ConsoPickOrderResponse
import com.ffii.fpsms.modules.pickOrder.web.models.ReleaseConsoPickOrderRequest
import com.ffii.fpsms.modules.pickOrder.web.models.SearchPickOrderRequest
import com.ffii.fpsms.modules.deliveryOrder.web.models.DoDetailResponse
import com.ffii.fpsms.modules.pickOrder.web.models.SavePickOrderGroupRequest
import jakarta.servlet.http.HttpServletRequest
import jakarta.validation.Valid
@@ -35,7 +36,7 @@ import java.time.LocalDate
import com.ffii.fpsms.modules.deliveryOrder.service.DoPickOrderService
import com.ffii.fpsms.modules.deliveryOrder.entity.DoPickOrderRepository
import com.ffii.fpsms.modules.deliveryOrder.web.models.AssignByStoreRequest
import com.ffii.fpsms.modules.deliveryOrder.web.models.*
@RestController
@RequestMapping("/doPickOrder")
class DoPickOrderController(
@@ -56,4 +57,12 @@ class DoPickOrderController(
fun getReleasedDoPickOrders(): List<DoPickOrder> {
return doPickOrderService.findReleasedDoPickOrders()
}
@GetMapping("/summary-by-store")
fun getSummaryByStore(@RequestParam storeId: String): StoreLaneSummary {
return doPickOrderService.getSummaryByStore(storeId)
}
@PostMapping("/assign-by-lane")
fun assignByLane(@RequestBody request: AssignByLaneRequest): MessageResponse {
return doPickOrderService.assignByLane(request)
}
}

+ 21
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/web/models/DoDetailResponse.kt Datei anzeigen

@@ -29,4 +29,25 @@ data class DoDetailLineResponse(
val uom: String?,
val uomCode: String?,
val shortUom: String?,
)
data class StoreLaneSummary(
val storeId: String,
val rows: List<LaneRow>
)

data class LaneRow(
val truckDepartureTime: String,
val lanes: List<LaneBtn>
)

data class LaneBtn(
val truckLanceCode: String,
val unassigned: Int,
val total: Int
)
data class AssignByLaneRequest(
val userId: Long,
val storeId: String,
val truckDepartureTime: String?, // 可选:限定出车时间
val truckLanceCode: String // 必填:车道编号
)

+ 72
- 0
src/main/resources/db/changelog/changes/20251014_01_enson/02_altertable_enson.sql Datei anzeigen

@@ -0,0 +1,72 @@
-- liquibase formatted sql
-- changeset enson:altertable_warehouse


ALTER TABLE do_pick_order_record
ADD COLUMN pick_order_code VARCHAR(50) NULL AFTER pick_order_id,
ADD COLUMN delivery_order_code VARCHAR(50) NULL AFTER do_order_id,
ADD COLUMN handler_name VARCHAR(100) NULL AFTER handled_by,
ADD COLUMN loading_sequence INT NULL AFTER ShopName;


ALTER TABLE do_pick_order
ADD COLUMN pick_order_code VARCHAR(50) NULL AFTER pick_order_id,
ADD COLUMN delivery_order_code VARCHAR(50) NULL AFTER do_order_id,
ADD COLUMN handler_name VARCHAR(100) NULL AFTER handled_by,
ADD COLUMN loading_sequence INT NULL AFTER ShopName;

ALTER TABLE do_pick_order_record
MODIFY COLUMN id INT NOT NULL AUTO_INCREMENT FIRST,
MODIFY COLUMN pick_order_id INT NULL AFTER id,
MODIFY COLUMN do_order_id INT NULL AFTER pick_order_id,
MODIFY COLUMN truck_id INT NULL AFTER do_order_id,
MODIFY COLUMN shop_id INT NULL AFTER truck_id,
MODIFY COLUMN store_id VARCHAR(10) NULL AFTER shop_id,
MODIFY COLUMN RequiredDeliveryDate DATE NULL AFTER store_id,
MODIFY COLUMN truck_departure_time TIME NULL AFTER RequiredDeliveryDate,
MODIFY COLUMN TruckLanceCode VARCHAR(50) NULL AFTER truck_departure_time,
MODIFY COLUMN ShopCode VARCHAR(50) NULL AFTER TruckLanceCode,
MODIFY COLUMN ShopName VARCHAR(255) NULL AFTER ShopCode,
MODIFY COLUMN loading_sequence INT NULL AFTER ShopName,
MODIFY COLUMN delivery_order_code VARCHAR(50) NULL AFTER loading_sequence,
MODIFY COLUMN pick_order_code VARCHAR(50) NULL AFTER delivery_order_code,
MODIFY COLUMN ticket_no VARCHAR(50) NULL AFTER pick_order_code,
MODIFY COLUMN ticket_release_time DATETIME NULL AFTER ticket_no,
MODIFY COLUMN ticketCompleteDateTime DATETIME NULL AFTER ticket_release_time,
MODIFY COLUMN ticket_status ENUM('pending','released','completed') NULL AFTER ticketCompleteDateTime,
MODIFY COLUMN handled_by INT NULL AFTER ticket_status,
MODIFY COLUMN handler_name VARCHAR(100) NULL AFTER handled_by,
MODIFY COLUMN created DATETIME NULL AFTER handler_name,
MODIFY COLUMN createdBy VARCHAR(30) NULL AFTER created,
MODIFY COLUMN version INT NULL AFTER createdBy,
MODIFY COLUMN modified DATETIME NULL AFTER version,
MODIFY COLUMN modifiedBy VARCHAR(30) NULL AFTER modified,
MODIFY COLUMN deleted TINYINT(1) NULL AFTER modifiedBy;

ALTER TABLE do_pick_order
MODIFY COLUMN id INT NOT NULL AUTO_INCREMENT FIRST,
MODIFY COLUMN pick_order_id INT NULL AFTER id,
MODIFY COLUMN do_order_id INT NULL AFTER pick_order_id,
MODIFY COLUMN truck_id INT NULL AFTER do_order_id,
MODIFY COLUMN shop_id INT NULL AFTER truck_id,
MODIFY COLUMN store_id VARCHAR(10) NULL AFTER shop_id,
MODIFY COLUMN RequiredDeliveryDate DATE NULL AFTER store_id,
MODIFY COLUMN truck_departure_time TIME NULL AFTER RequiredDeliveryDate,
MODIFY COLUMN TruckLanceCode VARCHAR(50) NULL AFTER truck_departure_time,
MODIFY COLUMN ShopCode VARCHAR(50) NULL AFTER TruckLanceCode,
MODIFY COLUMN ShopName VARCHAR(255) NULL AFTER ShopCode,
MODIFY COLUMN loading_sequence INT NULL AFTER ShopName,
MODIFY COLUMN delivery_order_code VARCHAR(50) NULL AFTER loading_sequence,
MODIFY COLUMN pick_order_code VARCHAR(50) NULL AFTER delivery_order_code,
MODIFY COLUMN ticket_no VARCHAR(50) NULL AFTER pick_order_code,
MODIFY COLUMN ticket_release_time DATETIME NULL AFTER ticket_no,
MODIFY COLUMN ticketCompleteDateTime DATETIME NULL AFTER ticket_release_time,
MODIFY COLUMN ticket_status ENUM('pending','released','completed') NULL AFTER ticketCompleteDateTime,
MODIFY COLUMN handled_by INT NULL AFTER ticket_status,
MODIFY COLUMN handler_name VARCHAR(100) NULL AFTER handled_by,
MODIFY COLUMN created DATETIME NULL AFTER handler_name,
MODIFY COLUMN createdBy VARCHAR(30) NULL AFTER created,
MODIFY COLUMN version INT NULL AFTER createdBy,
MODIFY COLUMN modified DATETIME NULL AFTER version,
MODIFY COLUMN modifiedBy VARCHAR(30) NULL AFTER modified,
MODIFY COLUMN deleted TINYINT(1) NULL AFTER modifiedBy;

Laden…
Abbrechen
Speichern