From a8053c760b60d660531d7fe1dc3d9348fc8cb1a1 Mon Sep 17 00:00:00 2001 From: "cyril.tsui" Date: Mon, 23 Jun 2025 17:17:17 +0800 Subject: [PATCH] Update for suggested pick lot --- .../pickOrder/service/PickOrderService.kt | 31 ++++---- .../web/models/ConsoPickOrderRequest.kt | 9 +++ .../stock/service/SuggestedPickLotService.kt | 78 ++++++++++++------- .../stock/web/SuggestedPickLotController.kt | 1 + .../model/SuggestInventoryLotLineResponse.kt | 13 ---- .../web/model/SuggestedPickLotRequest.kt | 17 ++++ .../web/model/SuggestedPickLotResponse.kt | 16 ++++ 7 files changed, 109 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestInventoryLotLineResponse.kt create mode 100644 src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestedPickLotRequest.kt create mode 100644 src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestedPickLotResponse.kt diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt index 950be8f..17fd78a 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt @@ -9,7 +9,7 @@ import com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus import com.ffii.fpsms.modules.pickOrder.web.models.* import com.ffii.fpsms.modules.stock.service.StockOutLineService import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService -import com.ffii.fpsms.modules.stock.web.model.SuggestInventoryLotLineResponse +import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotForPoRequest import org.springframework.context.annotation.Lazy import org.springframework.data.domain.PageRequest import org.springframework.stereotype.Service @@ -25,7 +25,7 @@ open class PickOrderService( val stockOutLineService: StockOutLineService, val suggestedPickLotService: SuggestedPickLotService, ) { - open fun LocalDateTimeParse(dateTime: String?, pattern: String? = "YYYY-MM-DD hh:mm:ss"): LocalDateTime? { + open fun localDateTimeParse(dateTime: String?, pattern: String? = "YYYY-MM-DD hh:mm:ss"): LocalDateTime? { try { val formatter = DateTimeFormatter.ofPattern(pattern!!) return LocalDateTime.parse(dateTime, formatter) @@ -43,8 +43,8 @@ open class PickOrderService( val response = pickOrderRepository.findPickOrderInfoByConditionsAndPageable( code = request.code ?: "all", - targetDateFrom = LocalDateTimeParse(request.targetDateFrom), - targetDateTo = LocalDateTimeParse(request.targetDateTo), + targetDateFrom = localDateTimeParse(request.targetDateFrom), + targetDateTo = localDateTimeParse(request.targetDateTo), type = request.type ?: "all", status = request.status ?: "all", itemName = request.itemName ?: "all", @@ -106,21 +106,23 @@ open class PickOrderService( return updatedPickOrderInfos } + // TODO: Add actual pick lots open fun consoPickOrderDetail(consoCode: String): ConsoPickOrderResponse { - // Conso code - // Pick orders with items - // Items - val zero = BigDecimal.ZERO // pick orders - // Mapping: PickOrder -> PickOrderInConso val pos = pickOrderRepository.findAllByConsoCode(consoCode) + + // Suggestions for Pick Order + val suggestions = suggestedPickLotService.suggestionForPickOrders(SuggestedPickLotForPoRequest(pickOrders = pos)) + val suggestedList = suggestions.suggestedList + + // Mapping: PickOrder -> PickOrderInConso val finalPos = pos.map { po -> val pols = po.pickOrderLines // Suggestions for Pick Order Line - val suggestions = suggestedPickLotService.suggestionForPickOrderLines(pols) + // val suggestions = suggestedPickLotService.suggestionForPickOrderLines(pols) // Pick Order Lines // Mapping: PickOrderLine -> PickOrderLineInConso @@ -131,7 +133,7 @@ open class PickOrderService( // Check If already have suggestion var suggestion = pol.suggestedPickLots if (suggestion.isEmpty()) { - suggestion = suggestions.filter { it.pickOrderLine?.id == pol.id }.toMutableList() + suggestion = suggestedList.filter { it.pickOrderLine?.id == pol.id }.toMutableList() } // Mapping: SuggestedPickLot -> SuggestPickLotInConso @@ -217,8 +219,7 @@ open class PickOrderService( code = _line.first().item.code, name = _line.first().item.name, qty = _line.fold(zero) { sum, item -> sum + (item.qty ?: zero)}, - suggestPickLots = _line - .flatMap { it.suggestPickLots }, + suggestPickLots = itemSuggestions, actualPickLots = mutableListOf() ) } @@ -231,4 +232,8 @@ open class PickOrderService( return response } + + open fun releaseConsoPickOrder(request: ReleaseConsoPickOrderRequest) { + val pos = pickOrderRepository.findAllByConsoCode(request.consoCode) + } } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderRequest.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderRequest.kt index 41d6a7c..91d7fd7 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderRequest.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderRequest.kt @@ -1,5 +1,14 @@ package com.ffii.fpsms.modules.pickOrder.web.models +import com.ffii.fpsms.modules.stock.web.model.SaveSuggestedPickLotRequest + +// Consolidated / De-consolidated data class ConsoPickOrderRequest ( val ids: List +) + +// Release Consolidated Pick Order +data class ReleaseConsoPickOrderRequest ( + val consoCode: String, + val suggestedPickLots: List ) \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt b/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt index ba22505..f40e39d 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt @@ -1,5 +1,6 @@ package com.ffii.fpsms.modules.stock.service +import com.ffii.fpsms.modules.pickOrder.entity.PickOrder import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLine import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository @@ -10,7 +11,9 @@ import com.ffii.fpsms.modules.stock.entity.enum.InventoryLotLineStatus import com.ffii.fpsms.modules.stock.entity.projection.InventoryLotLineInfo import com.ffii.fpsms.modules.stock.enums.SuggestedPickLotType import com.ffii.fpsms.modules.stock.web.model.SaveSuggestedPickLotRequest -import com.ffii.fpsms.modules.stock.web.model.SuggestInventoryLotLineResponse +import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotForPoRequest +import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotForPolRequest +import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotResponse import org.springframework.stereotype.Service import java.math.BigDecimal import kotlin.jvm.optionals.getOrDefault @@ -24,12 +27,31 @@ open class SuggestedPickLotService( val pickOrderLineRepository: PickOrderLineRepository, val inventoryLotLineService: InventoryLotLineService, ) { + open fun suggestionForPickOrders(request: SuggestedPickLotForPoRequest): SuggestedPickLotResponse { + val pos = request.pickOrders + val suggestedList = mutableListOf() + var holdQtyMap = request.holdQtyMap - open fun suggestionForPickOrderLines(pickOrderlines: List): List { - val itemIds = pickOrderlines.mapNotNull { it.item?.id } + pos.forEach { + val response = suggestionForPickOrderLines(SuggestedPickLotForPolRequest( + holdQtyMap = holdQtyMap, + pickOrderLines = it.pickOrderLines + )) + + holdQtyMap = response.holdQtyMap + suggestedList += response.suggestedList + } + + return SuggestedPickLotResponse(holdQtyMap = holdQtyMap, suggestedList = suggestedList) + } + + open fun suggestionForPickOrderLines(request: SuggestedPickLotForPolRequest): SuggestedPickLotResponse { + val pols = request.pickOrderLines + val itemIds = pols.mapNotNull { it.item?.id } val zero = BigDecimal.ZERO - val suggestionList: MutableList = mutableListOf() + val suggestedList: MutableList = mutableListOf() + val holdQtyMap: MutableMap = request.holdQtyMap // get current inventory lot line qty & grouped by item Id val availableInventoryLotLines = inventoryLotLineService @@ -40,7 +62,7 @@ open class SuggestedPickLotService( .groupBy { it.item?.id } // loop for suggest pick lot line - pickOrderlines.forEach { line -> + pols.forEach { line -> val lotLines = availableInventoryLotLines[line.item?.id].orEmpty() var remainingQty = line.qty ?: zero val updatedLotLines = mutableListOf() @@ -50,58 +72,44 @@ open class SuggestedPickLotService( val availableQty = (lotLine.inQty ?: zero) .minus(lotLine.outQty ?: zero) - .minus(lotLine.holdQty ?: zero) + .minus((lotLine.holdQty ?: zero) + .plus(holdQtyMap[lotLine.id] ?: zero) + ) if (availableQty <= zero) { updatedLotLines += lotLine return@forEachIndexed } val inventoryLotLine = lotLine.id?.let { inventoryLotLineService.findById(it).getOrNull() } -// println("1:${inventoryLotLine?.id}: ${inventoryLotLine?.holdQty}") val originalHoldQty = inventoryLotLine?.holdQty // Update Qty val assignQty = minOf(availableQty, remainingQty) remainingQty = remainingQty.minus(assignQty) - lotLine.holdQty = lotLine.holdQty?.plus(assignQty) -// println("2:${inventoryLotLine?.id}: ${inventoryLotLine?.holdQty}") -// println("3:${inventoryLotLine?.id}: ${originalHoldQty}") - suggestionList += SuggestedPickLot().apply { + holdQtyMap[lotLine.id] = (holdQtyMap[lotLine.id] ?: zero).plus(assignQty) +// lotLine.holdQty = lotLine.holdQty?.plus(assignQty) + suggestedList += SuggestedPickLot().apply { type = SuggestedPickLotType.PICK_ORDER - suggestedLotLine = inventoryLotLine?.apply { - holdQty = originalHoldQty - } + suggestedLotLine = inventoryLotLine pickOrderLine = line qty = assignQty } -// suggestionList += SuggestInventoryLotLineResponse( -// type = SuggestedPickLotType.PICK_ORDER.value, -// suggestedLotLine = inventoryLotLine, -// pickOrderLine = line, -// qty = assignQty -// ) } // if still have remainingQty if (remainingQty > zero) { - suggestionList += SuggestedPickLot().apply { + suggestedList += SuggestedPickLot().apply { type = SuggestedPickLotType.PICK_ORDER suggestedLotLine = null pickOrderLine = line - qty = null + qty = remainingQty } -// suggestionList += SuggestInventoryLotLineResponse( -// type = SuggestedPickLotType.PICK_ORDER.value, -// suggestedLotLine = null, -// pickOrderLine = line, -// qty = null -// ) } } - return suggestionList + return SuggestedPickLotResponse(holdQtyMap = holdQtyMap, suggestedList = suggestedList) } - open fun saveSuggestedPickLot(request: SaveSuggestedPickLotRequest): SuggestedPickLot { + open fun convertRequestToEntity(request: SaveSuggestedPickLotRequest): SuggestedPickLot{ val suggestedPickLot = request.id?.let { id -> suggestedPickLotRepository.findById(id).getOrDefault(SuggestedPickLot()) } ?: SuggestedPickLot() @@ -119,6 +127,16 @@ open class SuggestedPickLotService( qty = request.qty } + return suggestedPickLot + } + + open fun saveSuggestedPickLot(request: SaveSuggestedPickLotRequest): SuggestedPickLot { + val suggestedPickLot = convertRequestToEntity(request) + return suggestedPickLotRepository.save(suggestedPickLot) } + + open fun saveAll(request: List): List { + return suggestedPickLotRepository.saveAll(request) + } } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/SuggestedPickLotController.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/SuggestedPickLotController.kt index 14f2b13..68a129d 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/web/SuggestedPickLotController.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/SuggestedPickLotController.kt @@ -7,6 +7,7 @@ import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderLineService import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestInventoryLotLineResponse.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestInventoryLotLineResponse.kt deleted file mode 100644 index 61dedbe..0000000 --- a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestInventoryLotLineResponse.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.ffii.fpsms.modules.stock.web.model - -import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLine -import com.ffii.fpsms.modules.stock.entity.InventoryLotLine -import com.ffii.fpsms.modules.stock.enums.SuggestedPickLotType -import java.math.BigDecimal - -data class SuggestInventoryLotLineResponse( - val type: String?, - val suggestedLotLine: InventoryLotLine?, - val pickOrderLine: PickOrderLine?, - val qty: BigDecimal? -) diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestedPickLotRequest.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestedPickLotRequest.kt new file mode 100644 index 0000000..361fe42 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestedPickLotRequest.kt @@ -0,0 +1,17 @@ +package com.ffii.fpsms.modules.stock.web.model + +import com.ffii.fpsms.modules.pickOrder.entity.PickOrder +import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLine +import java.math.BigDecimal + +data class SuggestedPickLotForPoRequest( + val holdQtyMap: MutableMap = mutableMapOf(), + val pickOrders: List +) + +data class SuggestedPickLotForPolRequest( + val holdQtyMap: MutableMap = mutableMapOf(), + val pickOrderLines: List +) + + diff --git a/src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestedPickLotResponse.kt b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestedPickLotResponse.kt new file mode 100644 index 0000000..3cad900 --- /dev/null +++ b/src/main/java/com/ffii/fpsms/modules/stock/web/model/SuggestedPickLotResponse.kt @@ -0,0 +1,16 @@ +package com.ffii.fpsms.modules.stock.web.model + +import com.ffii.fpsms.modules.stock.entity.SuggestedPickLot +import java.math.BigDecimal + +//data class SuggestInventoryLotLine( +// val type: String?, +// val suggestedLotLine: InventoryLotLine?, +// val pickOrderLine: PickOrderLine?, +// val qty: BigDecimal? +//) + +data class SuggestedPickLotResponse( + val holdQtyMap: MutableMap, + val suggestedList: List +)