Browse Source

Add Release Conso. Pick Order Page

master
cyril.tsui 2 months ago
parent
commit
bed2f86c00
6 changed files with 110 additions and 36 deletions
  1. +33
    -13
      src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt
  2. +7
    -5
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt
  3. +2
    -9
      src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderResponse.kt
  4. +16
    -0
      src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt
  5. +12
    -0
      src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt
  6. +40
    -9
      src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt

+ 33
- 13
src/main/java/com/ffii/fpsms/modules/pickOrder/service/PickOrderService.kt View File

@@ -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)
}
}

+ 7
- 5
src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt View File

@@ -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)
}
}

+ 2
- 9
src/main/java/com/ffii/fpsms/modules/pickOrder/web/models/ConsoPickOrderResponse.kt View File

@@ -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<ReleasePickOrderInfoInventory>
)

data class ReleasePickOrderInfoInventory(
val id: Long?,
val itemCode: String?,
val itemName: String?,
val availableQty: BigDecimal?,
val requiredQty: BigDecimal?,
val items: List<CurrentInventoryItemInfo>
)

// Final Response - Conso Pick Order Detail


+ 16
- 0
src/main/java/com/ffii/fpsms/modules/stock/entity/InventoryLotLineRepository.kt View File

@@ -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<InventoryLotLine, Long> {
fun findInventoryLotLineInfoByInventoryLotItemIdIn(ids: List<Serializable>): List<InventoryLotLineInfo>

@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<Serializable>): List<CurrentInventoryItemInfo>
}

+ 12
- 0
src/main/java/com/ffii/fpsms/modules/stock/entity/projection/InventoryLotLineInfo.kt View File

@@ -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?
}

+ 40
- 9
src/main/java/com/ffii/fpsms/modules/stock/service/SuggestedPickLotService.kt View File

@@ -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<SuggestedPickLot>()
@@ -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<SaveSuggestedPickLotRequest>): List<SuggestedPickLot> {
// val zero = BigDecimal.ZERO
// val entities = mutableListOf<SuggestedPickLot>()
// val holdQtyCount = mutableMapOf<Long?, BigDecimal?>()
// 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)



Loading…
Cancel
Save