Selaa lähdekoodia

update do is extra same order

production
CANCERYS\kw093 1 viikko sitten
vanhempi
commit
9bbd43aade
6 muutettua tiedostoa jossa 325 lisäystä ja 115 poistoa
  1. +6
    -2
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchDopoAssignmentService.kt
  2. +10
    -12
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt
  3. +245
    -101
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchReleaseService.kt
  4. +61
    -0
      src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/WorkbenchReleaseTypeSupport.kt
  5. +1
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/service/HierarchicalFgPayloadAssembler.kt
  6. +2
    -0
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SearchPickOrderRequest.kt

+ 6
- 2
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchDopoAssignmentService.kt Näytä tiedosto

@@ -145,7 +145,9 @@ open class DoWorkbenchDopoAssignmentService(
params["loadingSequence"] = request.loadingSequence
}
if (isisExtraReleaseType(request.releaseType)) {
sql.append(" AND LOWER(COALESCE(dop.releaseType, '')) = 'isExtra' ")
sql.append(WorkbenchReleaseTypeSupport.legacyIsExtraSql())
} else {
sql.append(WorkbenchReleaseTypeSupport.assignFilterSql(request.releaseType))
}
// Fetch a batch of candidates and try atomic-assign sequentially.
// This avoids forcing the frontend to refresh when a single picked candidate is concurrently assigned.
@@ -251,7 +253,9 @@ open class DoWorkbenchDopoAssignmentService(
params["loadingSequence"] = request.loadingSequence
}
if (isisExtraReleaseType(request.releaseType)) {
sql.append(" AND LOWER(COALESCE(dop.releaseType, '')) = 'isExtra' ")
sql.append(WorkbenchReleaseTypeSupport.legacyIsExtraSql())
} else {
sql.append(WorkbenchReleaseTypeSupport.assignFilterSql(request.releaseType))
}
val shouldOrderBySequenceV1 = actualStoreId == "2/F" && request.loadingSequence == null
if (shouldOrderBySequenceV1) {


+ 10
- 12
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchMainService.kt Näytä tiedosto

@@ -668,13 +668,7 @@ return MessageResponse(
"4/F" -> "4/F"
else -> storeId
}
val rt = releaseType.lowercase()
val releaseFilterClause = when (rt) {
"batch" -> " AND LOWER(COALESCE(dop.releaseType, '')) = 'batch' "
"single" -> " AND LOWER(COALESCE(dop.releaseType, '')) = 'single' "
"isExtra" -> " AND LOWER(COALESCE(dop.releaseType, '')) = 'isExtra' "
else -> ""
}
val releaseFilterClause = WorkbenchReleaseTypeSupport.summaryFilterSql(releaseType)
val sql = """
SELECT
dop.truckDepartureTime AS truckDepartureTime,
@@ -1068,6 +1062,7 @@ return MessageResponse(
dop.deliveryNoteCode AS deliveryNoteCode,
dop.cartonQty AS cartonQty,
dop.handlerName AS handlerName,
dop.releaseType AS releaseType,
GROUP_CONCAT(DISTINCT po.id ORDER BY po.id SEPARATOR ',') AS pickOrderIdsStr,
GROUP_CONCAT(DISTINCT po.code ORDER BY po.code SEPARATOR ',') AS pickOrderCodesStr,
GROUP_CONCAT(DISTINCT d.id ORDER BY d.id SEPARATOR ',') AS deliveryOrderIdsStr,
@@ -1186,6 +1181,7 @@ return MessageResponse(
shopAddress = null,
fgPickOrders = emptyList<FgPickOrderSummary>(),
handlerName = str(row, "handlerName"),
releaseType = str(row, "releaseType"),
)
}
}
@@ -1219,6 +1215,7 @@ return MessageResponse(
dop.deliveryNoteCode AS deliveryNoteCode,
dop.cartonQty AS cartonQty,
dop.handlerName AS handlerName,
dop.releaseType AS releaseType,
GROUP_CONCAT(DISTINCT po.id ORDER BY po.id SEPARATOR ',') AS pickOrderIdsStr,
GROUP_CONCAT(DISTINCT po.code ORDER BY po.code SEPARATOR ',') AS pickOrderCodesStr,
GROUP_CONCAT(DISTINCT d.id ORDER BY d.id SEPARATOR ',') AS deliveryOrderIdsStr,
@@ -1336,6 +1333,7 @@ return MessageResponse(
shopAddress = null,
fgPickOrders = emptyList<FgPickOrderSummary>(),
handlerName = str(row, "handlerName"),
releaseType = str(row, "releaseType"),
)
}
}
@@ -1681,9 +1679,7 @@ return MessageResponse(
params["shopPat"] = "%${shopName.trim()}%"
}
val rtNorm = releaseTypeFilter?.trim()?.lowercase().orEmpty()
if (rtNorm == "isExtra") {
sqlBuilder.append(" AND LOWER(COALESCE(dop.releaseType, '')) = 'isExtra' ")
}
sqlBuilder.append(WorkbenchReleaseTypeSupport.summaryFilterSql(rtNorm))
sqlBuilder.append(" ORDER BY dop.requiredDeliveryDate, dop.truckDepartureTime, dop.truckLanceCode, dop.id ")
val rows: List<Map<String, Any?>> = try {
jdbcDao.queryForList(sqlBuilder.toString(), params)
@@ -1768,7 +1764,8 @@ return MessageResponse(
dop.shopCode as ShopCode,
dop.shopName as ShopName,
dop.ticketStatus as doTicketStatus,
dop.requiredDeliveryDate as required_delivery_date
dop.requiredDeliveryDate as required_delivery_date,
dop.releaseType as release_type
FROM fpsmsdb.delivery_order_pick_order dop
WHERE dop.handledBy = :userId

@@ -1897,7 +1894,8 @@ return MessageResponse(
dop.truckDepartureTime as truck_departure_time,
dop.shopCode as ShopCode,
dop.shopName as ShopName,
dop.ticketStatus as doTicketStatus
dop.ticketStatus as doTicketStatus,
dop.releaseType as release_type
FROM fpsmsdb.delivery_order_pick_order dop
WHERE dop.id = :dopoId
AND dop.deleted = 0


+ 245
- 101
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/DoWorkbenchReleaseService.kt Näytä tiedosto

@@ -359,7 +359,7 @@ open class DoWorkbenchReleaseService(
}

/**
* `TI-B-yyyyMMdd-2F-001` (batch), `TI-S-yyyyMMdd-2F-001` (single), or `TI-E-yyyyMMdd-2F-001` (Etra),
* `TI-B-yyyyMMdd-2F-001` (batch / isExtrabatch) or `TI-S-yyyyMMdd-2F-001` (single / isExtrasingle),
* same suffix rules as [DoReleaseCoordinatorService] / legacy `do_pick_order`.
*/
private fun nextDeliveryOrderPickOrderTicketNo(
@@ -367,8 +367,8 @@ open class DoWorkbenchReleaseService(
storeDisplay: String,
ticketLetter: String,
): String {
require(ticketLetter == "B" || ticketLetter == "S" || ticketLetter == "E") {
"ticketLetter must be B, S or E"
require(ticketLetter == "B" || ticketLetter == "S") {
"ticketLetter must be B or S"
}
val ymd = requiredDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"))
val floor = storeDisplay.replace("/", "").trim()
@@ -400,9 +400,6 @@ open class DoWorkbenchReleaseService(
private fun nextDeliveryOrderPickOrderSingleTicketNo(requiredDate: LocalDate, storeDisplay: String): String =
nextDeliveryOrderPickOrderTicketNo(requiredDate, storeDisplay, "S")

private fun nextDeliveryOrderPickOrderEtraTicketNo(requiredDate: LocalDate, storeDisplay: String): String =
nextDeliveryOrderPickOrderTicketNo(requiredDate, storeDisplay, "E")

private fun asyncJobType(useV2: Boolean, dopReleaseType: String): String {
val single = dopReleaseType.equals("single", ignoreCase = true)
return when {
@@ -440,120 +437,267 @@ open class DoWorkbenchReleaseService(
}
}

private fun laneGroupKey(result: ReleaseDoResult): String =
listOf(
result.shopId?.toString() ?: "",
result.estimatedArrivalDate?.toString() ?: "",
result.preferredFloor,
result.truckId?.toString() ?: "",
result.truckDepartureTime?.toString() ?: "",
result.truckLanceCode ?: "",
result.loadingSequence?.toString() ?: "",
).joinToString("|")

private fun resolveStoreId(first: ReleaseDoResult): String? {
val isDefaultTruckLane =
first.usedDefaultTruck == true ||
first.truckLanceCode?.trim() == WORKBENCH_DEFAULT_TRUCK_LANCE_CODE
if (isDefaultTruckLane) return null
return when (first.preferredFloor) {
"2F" -> "2/F"
"4F" -> "4/F"
else -> "2/F"
}
}

private fun resolveTicketFloorSegment(storeId: String?, isDefaultTruckLane: Boolean): String =
if (isDefaultTruckLane) {
WORKBENCH_TICKET_FLOOR_SEGMENT_DEFAULT_TRUCK
} else {
(storeId ?: "2/F").replace("/", "").trim()
}

private data class MergeableWorkbenchTicket(val id: Long, val releaseType: String?)

/**
* Active batch/single-family ticket for the same lane. Excludes completed tickets and legacy `isExtra`.
*/
private fun findMergeableWorkbenchTicket(
first: ReleaseDoResult,
storeId: String?,
isSingleRelease: Boolean,
): MergeableWorkbenchTicket? {
if (first.shopId == null || first.estimatedArrivalDate == null) return null

val familyTypes = if (isSingleRelease) {
WorkbenchReleaseTypeSupport.singleFamilyTypes()
} else {
WorkbenchReleaseTypeSupport.batchFamilyTypes()
}
val typePlaceholders = familyTypes.joinToString(",") { "'${it.lowercase()}'" }

val sql = StringBuilder(
"""
SELECT id, releaseType
FROM fpsmsdb.delivery_order_pick_order
WHERE deleted = 0
AND shopId = :shopId
AND requiredDeliveryDate = :requiredDate
AND ticketStatus IN ('pending', 'released')
AND LOWER(COALESCE(releaseType, '')) IN ($typePlaceholders)
""".trimIndent()
)
val params = mutableMapOf<String, Any>(
"shopId" to first.shopId!!,
"requiredDate" to first.estimatedArrivalDate!!,
)
if (storeId.isNullOrBlank()) {
sql.append(" AND (storeId IS NULL OR TRIM(COALESCE(storeId, '')) = '') ")
} else {
sql.append(" AND storeId = :storeId ")
params["storeId"] = storeId
}
if (first.truckId != null) {
sql.append(" AND truckId = :truckId ")
params["truckId"] = first.truckId!!
} else {
sql.append(" AND truckId IS NULL ")
}
if (first.truckDepartureTime != null) {
sql.append(" AND truckDepartureTime = :truckDepartureTime ")
params["truckDepartureTime"] = first.truckDepartureTime!!
} else {
sql.append(" AND truckDepartureTime IS NULL ")
}
if (!first.truckLanceCode.isNullOrBlank()) {
sql.append(" AND truckLanceCode = :truckLanceCode ")
params["truckLanceCode"] = first.truckLanceCode!!.trim()
} else {
sql.append(" AND (truckLanceCode IS NULL OR TRIM(truckLanceCode) = '') ")
}
if (first.loadingSequence != null) {
sql.append(" AND loadingSequence = :loadingSequence ")
params["loadingSequence"] = first.loadingSequence!!
}
sql.append(" ORDER BY id ASC ")

val rows = try {
jdbcDao.queryForList(sql.toString(), params)
} catch (_: Exception) {
emptyList()
}
if (rows.isEmpty()) return null

fun rowId(row: Map<String, Any?>): Long? {
val key = row.keys.find { it.equals("id", true) } ?: return null
return (row[key] as? Number)?.toLong()
}
fun rowReleaseType(row: Map<String, Any?>): String? {
val key = row.keys.find { it.equals("releaseType", true) } ?: return null
return row[key]?.toString()
}

val matched = rows.first()
val id = rowId(matched) ?: return null
return MergeableWorkbenchTicket(id = id, releaseType = rowReleaseType(matched))
}

private fun linkPickOrdersToHeader(headerId: Long, group: List<ReleaseDoResult>) {
group.forEach { r ->
jdbcDao.executeUpdate(
"""
UPDATE fpsmsdb.pick_order
SET deliveryOrderPickOrderId = :headerId
WHERE id = :pickOrderId
""".trimIndent(),
mapOf(
"headerId" to headerId,
"pickOrderId" to r.pickOrderId
)
)
}
}

private fun maybeUpgradeReleaseType(
headerId: Long,
currentReleaseType: String?,
isExtraRelease: Boolean,
isSingleRelease: Boolean,
) {
val upgraded = WorkbenchReleaseTypeSupport.upgradedReleaseTypeIfNeeded(
currentReleaseType,
isExtraRelease,
isSingleRelease,
) ?: return
jdbcDao.executeUpdate(
"""
UPDATE fpsmsdb.delivery_order_pick_order
SET releaseType = :releaseType,
modified = :modified,
modifiedBy = :modifiedBy
WHERE id = :id AND deleted = 0
""".trimIndent(),
mapOf(
"releaseType" to upgraded,
"modified" to LocalDateTime.now(),
"modifiedBy" to "system",
"id" to headerId,
)
)
}

private fun insertNewDeliveryOrderPickOrderHeader(
first: ReleaseDoResult,
storeId: String?,
releaseTypeCol: String,
ticketNo: String,
): Long? {
val now = LocalDateTime.now()
jdbcDao.executeUpdate(
"""
INSERT INTO fpsmsdb.delivery_order_pick_order (
truckId, shopId, storeId, requiredDeliveryDate, truckDepartureTime,
truckLanceCode, shopCode, shopName, loadingSequence, ticketNo,
ticketReleaseTime, ticketStatus, releaseType, handledBy, handlerName,
created, createdBy, version, modified, modifiedBy, deleted
) VALUES (
:truckId, :shopId, :storeId, :requiredDeliveryDate, :truckDepartureTime,
:truckLanceCode, :shopCode, :shopName, :loadingSequence, :ticketNo,
NULL, 'pending', :releaseType, NULL, NULL,
:created, :createdBy, 0, :modified, :modifiedBy, 0
)
""".trimIndent(),
mapOf(
"truckId" to first.truckId,
"shopId" to first.shopId,
"storeId" to storeId,
"requiredDeliveryDate" to (first.estimatedArrivalDate ?: LocalDate.now()),
"truckDepartureTime" to first.truckDepartureTime,
"truckLanceCode" to first.truckLanceCode,
"shopCode" to first.shopCode,
"shopName" to first.shopName,
"loadingSequence" to first.loadingSequence,
"ticketNo" to ticketNo,
"releaseType" to releaseTypeCol,
"created" to now,
"createdBy" to "system",
"modified" to now,
"modifiedBy" to "system",
)
)
return jdbcDao.queryForList(
"""
SELECT id
FROM fpsmsdb.delivery_order_pick_order
WHERE ticketNo = :ticketNo
ORDER BY id DESC
LIMIT 1
""".trimIndent(),
mapOf("ticketNo" to ticketNo)
).firstOrNull()?.get("id")?.let { (it as Number).toLong() }
}

/**
* Link released pick orders to [delivery_order_pick_order] headers.
* Normal DOs merge into batch/single-family tickets; isExtra DOs upgrade `batch`→`isExtrabatch` or `single`→`isExtrasingle`.
* Legacy `isExtra` tickets are never merge targets. Completed tickets are skipped (new header created instead).
*/
private fun createAndLinkDeliveryOrderPickOrders(
results: List<ReleaseDoResult>,
dopReleaseType: String = "batch",
): Int {
if (results.isEmpty()) return 0

val grouped = results.groupBy {
listOf(
it.shopId?.toString() ?: "",
it.estimatedArrivalDate?.toString() ?: "",
it.preferredFloor,
it.truckId?.toString() ?: "",
it.truckDepartureTime?.toString() ?: "",
it.truckLanceCode ?: "",
it.isExtra.toString(),
).joinToString("|")
}
val isSingleRelease = dopReleaseType.equals("single", ignoreCase = true)
val normalGroups = results.filter { !it.isExtra }.groupBy { laneGroupKey(it) }
val extraGroups = results.filter { it.isExtra }.groupBy { laneGroupKey(it) }

var createdHeaders = 0
grouped.values.forEach { group ->

fun processGroup(group: List<ReleaseDoResult>, isExtraRelease: Boolean): Int {
if (group.isEmpty()) return 0
val first = group.first()
val storeId = resolveStoreId(first)
val isDefaultTruckLane =
first.usedDefaultTruck == true ||
first.truckLanceCode?.trim() == WORKBENCH_DEFAULT_TRUCK_LANCE_CODE
val storeId: String? = if (isDefaultTruckLane) {
null
} else {
when (first.preferredFloor) {
"2F" -> "2/F"
"4F" -> "4/F"
else -> "2/F"
}
}
val ticketFloorSegment = if (isDefaultTruckLane) {
WORKBENCH_TICKET_FLOOR_SEGMENT_DEFAULT_TRUCK
} else {
(storeId ?: "2/F").replace("/", "").trim()
}
val ticketFloorSegment = resolveTicketFloorSegment(storeId, isDefaultTruckLane)
val requiredDate = first.estimatedArrivalDate ?: LocalDate.now()
val releaseTypeCol = if (first.isExtra) {
"isExtra"
} else if (dopReleaseType.equals("single", ignoreCase = true)) {
"single"
} else {
"batch"

val existing = findMergeableWorkbenchTicket(first, storeId, isSingleRelease)
if (existing != null) {
linkPickOrdersToHeader(existing.id, group)
maybeUpgradeReleaseType(existing.id, existing.releaseType, isExtraRelease, isSingleRelease)
return 0
}
val tempTicket = if (first.isExtra) {
nextDeliveryOrderPickOrderEtraTicketNo(requiredDate, ticketFloorSegment)
} else if (releaseTypeCol == "single") {

val releaseTypeCol = WorkbenchReleaseTypeSupport.newHeaderReleaseType(isExtraRelease, isSingleRelease)
val ticketNo = if (isSingleRelease) {
nextDeliveryOrderPickOrderSingleTicketNo(requiredDate, ticketFloorSegment)
} else {
nextDeliveryOrderPickOrderBatchTicketNo(requiredDate, ticketFloorSegment)
}
val now = LocalDateTime.now()

// Column names must match Liquibase `01_alter_stock_take.sql` (camelCase), not snake_case.
jdbcDao.executeUpdate(
"""
INSERT INTO fpsmsdb.delivery_order_pick_order (
truckId, shopId, storeId, requiredDeliveryDate, truckDepartureTime,
truckLanceCode, shopCode, shopName, loadingSequence, ticketNo,
ticketReleaseTime, ticketStatus, releaseType, handledBy, handlerName,
created, createdBy, version, modified, modifiedBy, deleted
) VALUES (
:truckId, :shopId, :storeId, :requiredDeliveryDate, :truckDepartureTime,
:truckLanceCode, :shopCode, :shopName, :loadingSequence, :ticketNo,
NULL, 'pending', :releaseType, NULL, NULL,
:created, :createdBy, 0, :modified, :modifiedBy, 0
)
""".trimIndent(),
mapOf(
"truckId" to first.truckId,
"shopId" to first.shopId,
"storeId" to storeId,
"requiredDeliveryDate" to (first.estimatedArrivalDate ?: LocalDate.now()),
"truckDepartureTime" to first.truckDepartureTime,
"truckLanceCode" to first.truckLanceCode,
"shopCode" to first.shopCode,
"shopName" to first.shopName,
"loadingSequence" to first.loadingSequence,
"ticketNo" to tempTicket,
"releaseType" to releaseTypeCol,
"created" to now,
"createdBy" to "system",
"modified" to now,
"modifiedBy" to "system",
)
)

val headerId = jdbcDao.queryForList(
"""
SELECT id
FROM fpsmsdb.delivery_order_pick_order
WHERE ticketNo = :ticketNo
ORDER BY id DESC
LIMIT 1
""".trimIndent(),
mapOf("ticketNo" to tempTicket)
).firstOrNull()?.get("id")?.let { (it as Number).toLong() } ?: return@forEach
val headerId = insertNewDeliveryOrderPickOrderHeader(first, storeId, releaseTypeCol, ticketNo)
?: return 0
linkPickOrdersToHeader(headerId, group)
return 1
}

group.forEach { r ->
jdbcDao.executeUpdate(
"""
UPDATE fpsmsdb.pick_order
SET deliveryOrderPickOrderId = :headerId
WHERE id = :pickOrderId
""".trimIndent(),
mapOf(
"headerId" to headerId,
"pickOrderId" to r.pickOrderId
)
)
}
createdHeaders++
normalGroups.values.forEach { group ->
createdHeaders += processGroup(group, isExtraRelease = false)
}
extraGroups.values.forEach { group ->
createdHeaders += processGroup(group, isExtraRelease = true)
}

return createdHeaders


+ 61
- 0
src/main/java/com/ffii/fpsms/modules/deliveryOrder/service/WorkbenchReleaseTypeSupport.kt Näytä tiedosto

@@ -0,0 +1,61 @@
package com.ffii.fpsms.modules.deliveryOrder.service

/**
* Workbench [delivery_order_pick_order.releaseType] values and SQL filters.
* Legacy `isExtra` tickets are excluded from merge; only used for legacy Etra views.
*/
object WorkbenchReleaseTypeSupport {
const val BATCH = "batch"
const val SINGLE = "single"
const val IS_EXTRA_BATCH = "isExtrabatch"
const val IS_EXTRA_SINGLE = "isExtrasingle"
const val LEGACY_IS_EXTRA = "isExtra"

fun batchFamilyTypes(): List<String> = listOf(BATCH, IS_EXTRA_BATCH)

fun singleFamilyTypes(): List<String> = listOf(SINGLE, IS_EXTRA_SINGLE)

fun summaryFilterSql(releaseType: String, column: String = "dop.releaseType"): String =
when (releaseType.trim().lowercase()) {
"batch" -> batchFamilySql(column)
"single" -> singleFamilySql(column)
"isextra" -> legacyIsExtraSql(column)
else -> ""
}

fun assignFilterSql(releaseType: String?, column: String = "dop.releaseType"): String {
val n = releaseType?.trim()?.lowercase().orEmpty()
return when (n) {
"batch" -> batchFamilySql(column)
"single" -> singleFamilySql(column)
"isextra" -> legacyIsExtraSql(column)
else -> ""
}
}

fun batchFamilySql(column: String = "dop.releaseType"): String =
" AND LOWER(COALESCE($column, '')) IN ('batch', 'isextrabatch') "

fun singleFamilySql(column: String = "dop.releaseType"): String =
" AND LOWER(COALESCE($column, '')) IN ('single', 'isextrasingle') "

fun legacyIsExtraSql(column: String = "dop.releaseType"): String =
" AND LOWER(COALESCE($column, '')) = 'isextra' "

fun newHeaderReleaseType(isExtraRelease: Boolean, isSingleRelease: Boolean): String = when {
isExtraRelease && isSingleRelease -> IS_EXTRA_SINGLE
isExtraRelease -> IS_EXTRA_BATCH
isSingleRelease -> SINGLE
else -> BATCH
}

fun upgradedReleaseTypeIfNeeded(currentType: String?, isExtraRelease: Boolean, isSingleRelease: Boolean): String? {
if (!isExtraRelease) return null
val cur = currentType?.trim()?.lowercase().orEmpty()
return when {
isSingleRelease && cur == SINGLE.lowercase() -> IS_EXTRA_SINGLE
!isSingleRelease && cur == BATCH.lowercase() -> IS_EXTRA_BATCH
else -> null
}
}
}

+ 1
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/service/HierarchicalFgPayloadAssembler.kt Näytä tiedosto

@@ -336,6 +336,7 @@ ORDER BY
"shopName" to doPickOrderInfo["ShopName"],
"truckLanceCode" to doPickOrderInfo["TruckLanceCode"],
"departureTime" to doPickOrderInfo["truck_departure_time"],
"releaseType" to doPickOrderInfo["release_type"],
)
val allConsoCodes = pickOrdersInfo.mapNotNull { it["consoCode"] as? String }.distinct()



+ 2
- 0
src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/SearchPickOrderRequest.kt Näytä tiedosto

@@ -53,6 +53,8 @@ data class CompletedDoPickOrderResponse(
val fgPickOrders: List<FgPickOrderSummary>,
/** Legacy: `do_pick_order_record.handler_name`; workbench: `delivery_order_pick_order.handlerName`. */
val handlerName: String? = null,
/** Workbench: `delivery_order_pick_order.releaseType` (e.g. isExtrabatch, batch). */
val releaseType: String? = null,
)

data class FgPickOrderSummary(


Ladataan…
Peruuta
Tallenna