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 ae06ff6..74edf4e 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 @@ -2,18 +2,16 @@ package com.ffii.fpsms.modules.pickOrder.service import com.ffii.core.response.RecordsRes import com.ffii.fpsms.modules.common.SecurityUtils -import com.ffii.fpsms.modules.master.web.models.MessageResponse -import com.ffii.fpsms.modules.pickOrder.entity.PickOrder import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderInfo -import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderLineInfo import com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus import com.ffii.fpsms.modules.pickOrder.web.models.* +import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository +import com.ffii.fpsms.modules.stock.entity.projection.CurrentInventoryItemInfo import com.ffii.fpsms.modules.stock.service.StockOutLineService import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService import com.ffii.fpsms.modules.stock.web.model.SuggestedPickLotForPoRequest import com.ffii.fpsms.modules.user.service.UserService -import org.springframework.context.annotation.Lazy import org.springframework.data.domain.PageRequest import org.springframework.stereotype.Service import java.io.Serializable @@ -28,7 +26,7 @@ open class PickOrderService( val pickOrderRepository: PickOrderRepository, val stockOutLineService: StockOutLineService, val suggestedPickLotService: SuggestedPickLotService, - val userService: UserService, + val userService: UserService, private val inventoryLotLineRepository: InventoryLotLineRepository, ) { open fun localDateTimeParse(dateTime: String?, pattern: String? = "YYYY-MM-DD hh:mm:ss"): LocalDateTime? { try { @@ -69,7 +67,6 @@ open class PickOrderService( val prefix = "PICK" val midfix = LocalDate.now().format(formatter) - println(midfix) val suffix = String.format(suffixFormat, 1) val latestConsoCode = pickOrderRepository.findLatestConsoCodeByPrefix("${prefix}-${midfix}") @@ -240,16 +237,43 @@ open class PickOrderService( return response } - open fun releaseConsoPickOrderInfo() { + open fun releaseConsoPickOrderInfo(request: ReleaseConsoPickOrderRequest): ReleasePickOrderInfoResponse { + val zero = BigDecimal.ZERO + val pos = pickOrderRepository.findAllByConsoCode(request.consoCode) + val requiredItems = pos + .flatMap { it.pickOrderLines } + .groupBy { it.item?.id } + .map { (key, value) -> key to object : CurrentInventoryItemInfo { + override val id: Long? = value[0].item?.id + override val code: String? = value[0].item?.code + override val name: String? = value[0].item?.name + override var availableQty: BigDecimal? = zero + override val requiredQty: BigDecimal = value.sumOf { it.qty ?: zero } + }} // itemId - requiredQty + + val itemIds = requiredItems.mapNotNull { it.first } + val inventories = inventoryLotLineRepository.findCurrentInventoryByItems(itemIds) + val currentInventoryInfos = requiredItems.map { item -> + val inventory = inventories.find { it.id == item.first } + + item.second.let { + it.availableQty = inventory?.availableQty + + // return + it + } + } + return ReleasePickOrderInfoResponse( + consoCode = request.consoCode, + items = currentInventoryInfos, + ) } open fun releaseConsoPickOrderAction(request: ReleaseConsoPickOrderRequest) { val releasedBy = SecurityUtils.getUser().getOrNull() val assignTo = request.assignTo?.let { userService.find(it) }?.getOrNull() - println("123") val pos = pickOrderRepository.findAllByConsoCode(request.consoCode) - println("456") pos.forEach { it.apply { this.releasedBy = releasedBy @@ -257,10 +281,6 @@ open class PickOrderService( status = PickOrderStatus.RELEASED } } - println(pos[0].releasedBy?.id) pickOrderRepository.saveAll(pos) -// val suggestedPickLots = suggestedPickLotService.convertRequestsToEntities(request.suggestedPickLots) -// -// suggestedPickLotService.saveAll(suggestedPickLots) } } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt index e404cc3..7cb56ea 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt @@ -4,10 +4,7 @@ import com.ffii.core.response.RecordsRes import com.ffii.fpsms.modules.pickOrder.entity.PickOrderRepository import com.ffii.fpsms.modules.pickOrder.entity.projection.PickOrderInfo import com.ffii.fpsms.modules.pickOrder.service.PickOrderService -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.pickOrder.web.models.* import jakarta.validation.Valid import org.springframework.data.domain.Page import org.springframework.data.domain.PageRequest @@ -56,8 +53,13 @@ class PickOrderController( return pickOrderService.consoPickOrderDetail(consoCode); } + @GetMapping("/releaseConso") + fun releaseConsoPickOrderInfo(@Valid @RequestBody request: ReleaseConsoPickOrderRequest): ReleasePickOrderInfoResponse { + return pickOrderService.releaseConsoPickOrderInfo(request); + } + @PostMapping("/releaseConso") - fun releaseConsoPickOrders(@Valid @RequestBody request: ReleaseConsoPickOrderRequest) { + fun releaseConsoPickOrderAction(@Valid @RequestBody request: ReleaseConsoPickOrderRequest) { pickOrderService.releaseConsoPickOrderAction(request) } } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderResponse.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderResponse.kt index 7dc8e02..4746cc4 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderResponse.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderResponse.kt @@ -1,20 +1,13 @@ package com.ffii.fpsms.modules.pickOrder.web.models +import com.ffii.fpsms.modules.stock.entity.projection.CurrentInventoryItemInfo import java.math.BigDecimal import java.time.LocalDateTime // Final Response - Release Conso Pick Order Page data class ReleasePickOrderInfoResponse( val consoCode: String, - val inventory: List -) - -data class ReleasePickOrderInfoInventory( - val id: Long?, - val itemCode: String?, - val itemName: String?, - val availableQty: BigDecimal?, - val requiredQty: BigDecimal?, + val items: List ) // Final Response - Conso Pick Order Detail diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt index a47532d..5ef3818 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt @@ -1,11 +1,27 @@ package com.ffii.fpsms.modules.stock.entity import com.ffii.core.support.AbstractRepository +import com.ffii.fpsms.modules.stock.entity.projection.CurrentInventoryItemInfo import com.ffii.fpsms.modules.stock.entity.projection.InventoryLotLineInfo +import org.springframework.data.jpa.repository.Query import org.springframework.stereotype.Repository import java.io.Serializable @Repository interface InventoryLotLineRepository : AbstractRepository { fun findInventoryLotLineInfoByInventoryLotItemIdIn(ids: List): List + + @Query(""" + select + i.id as id, + i.code as itemCode, + i.name as itemName, + sum(coalesce(ill.inQty, 0) - coalesce(ill.outQty, 0) - coalesce(ill.holdQty, 0)) as availableQty + from InventoryLotLine ill + left join InventoryLot il on ill.inventoryLot = il + left join Items i on il.item = i + where i.id in :items + group by i.id + """) + fun findCurrentInventoryByItems(items: List): List } \ No newline at end of file diff --git a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt index fbd4343..0ca9fc0 100644 --- a/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt +++ b/src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt @@ -20,17 +20,29 @@ interface InventoryLotLineWarehouseInfo { interface InventoryLotLineInfo { val id: Long? + @get:Value("#{target.inventoryLot.item}") val item: InventoryLotLineItemInfo? val warehouse: InventoryLotLineWarehouseInfo? var inQty: BigDecimal? var outQty: BigDecimal? var holdQty: BigDecimal? + @get:Value("#{target.status.value}") val status: String? val remarks: String? + @get:Value("#{target.stockUom.uom.udfudesc}") val uom: String? + @get:Value("#{target.inventoryLot.expiryDate}") val expiryDate: LocalDate +} + +interface CurrentInventoryItemInfo { + val id: Long? // item id + val code: String? + val name: String? + val availableQty: BigDecimal? + val requiredQty: BigDecimal? } \ 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 f40e39d..9298222 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 @@ -3,10 +3,7 @@ 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 -import com.ffii.fpsms.modules.stock.entity.StockOutLIneRepository -import com.ffii.fpsms.modules.stock.entity.SuggestPickLotRepository -import com.ffii.fpsms.modules.stock.entity.SuggestedPickLot +import com.ffii.fpsms.modules.stock.entity.* 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 @@ -27,6 +24,22 @@ open class SuggestedPickLotService( val pickOrderLineRepository: PickOrderLineRepository, val inventoryLotLineService: InventoryLotLineService, ) { + // Calculation Available Qty / Remaining Qty + open fun calculateRemainingQtyForInfo(inventoryLotLine: InventoryLotLineInfo?): BigDecimal { + val zero = BigDecimal.ZERO + return (inventoryLotLine?.inQty ?: zero) + .minus(inventoryLotLine?.outQty ?: zero) + .minus((inventoryLotLine?.holdQty ?: zero)) + } + + open fun calculateRemainingQty(inventoryLotLine: InventoryLotLine?): BigDecimal { + val zero = BigDecimal.ZERO + return (inventoryLotLine?.inQty ?: zero) + .minus(inventoryLotLine?.outQty ?: zero) + .minus((inventoryLotLine?.holdQty ?: zero)) + } + + // Suggestion open fun suggestionForPickOrders(request: SuggestedPickLotForPoRequest): SuggestedPickLotResponse { val pos = request.pickOrders val suggestedList = mutableListOf() @@ -70,11 +83,9 @@ open class SuggestedPickLotService( lotLines.forEachIndexed { index, lotLine -> if (remainingQty <= zero) return@forEachIndexed - val availableQty = (lotLine.inQty ?: zero) - .minus(lotLine.outQty ?: zero) - .minus((lotLine.holdQty ?: zero) - .plus(holdQtyMap[lotLine.id] ?: zero) - ) + val availableQty = calculateRemainingQtyForInfo(lotLine) + .minus(holdQtyMap[lotLine.id] ?: zero) + if (availableQty <= zero) { updatedLotLines += lotLine @@ -109,6 +120,25 @@ open class SuggestedPickLotService( return SuggestedPickLotResponse(holdQtyMap = holdQtyMap, suggestedList = suggestedList) } + // Convertion + open fun convertRequestsToEntities(request: List): List { +// val zero = BigDecimal.ZERO +// val entities = mutableListOf() +// val holdQtyCount = mutableMapOf() +// request.forEach { +// val entity = convertRequestToEntity(it) +// val suggestedLotLine = entity.suggestedLotLine +// val remainQty = calculateRemainingQty(suggestedLotLine) +// holdQtyCount[suggestedLotLine?.id] = (holdQtyCount[suggestedLotLine?.id] ?: zero).plus(suggestedLotLine?.holdQty ?: zero) +// if (remainQty.minus(holdQtyCount[suggestedLotLine?.id] ?: zero) < zero) { +// throw RuntimeException("The suggested pick qty is over. Please re-suggest the pick qty."); +// } +// entities += entity +// } +// return entities + return request.map { convertRequestToEntity(it) } + } + open fun convertRequestToEntity(request: SaveSuggestedPickLotRequest): SuggestedPickLot{ val suggestedPickLot = request.id?.let { id -> suggestedPickLotRepository.findById(id).getOrDefault(SuggestedPickLot()) } @@ -130,6 +160,7 @@ open class SuggestedPickLotService( return suggestedPickLot } + // Save open fun saveSuggestedPickLot(request: SaveSuggestedPickLotRequest): SuggestedPickLot { val suggestedPickLot = convertRequestToEntity(request)