@@ -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.pickOrder.web.models.* | ||||
import com.ffii.fpsms.modules.stock.service.StockOutLineService | import com.ffii.fpsms.modules.stock.service.StockOutLineService | ||||
import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService | 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.context.annotation.Lazy | ||||
import org.springframework.data.domain.PageRequest | import org.springframework.data.domain.PageRequest | ||||
import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
@@ -25,7 +25,7 @@ open class PickOrderService( | |||||
val stockOutLineService: StockOutLineService, | val stockOutLineService: StockOutLineService, | ||||
val suggestedPickLotService: SuggestedPickLotService, | 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 { | try { | ||||
val formatter = DateTimeFormatter.ofPattern(pattern!!) | val formatter = DateTimeFormatter.ofPattern(pattern!!) | ||||
return LocalDateTime.parse(dateTime, formatter) | return LocalDateTime.parse(dateTime, formatter) | ||||
@@ -43,8 +43,8 @@ open class PickOrderService( | |||||
val response = pickOrderRepository.findPickOrderInfoByConditionsAndPageable( | val response = pickOrderRepository.findPickOrderInfoByConditionsAndPageable( | ||||
code = request.code ?: "all", | code = request.code ?: "all", | ||||
targetDateFrom = LocalDateTimeParse(request.targetDateFrom), | |||||
targetDateTo = LocalDateTimeParse(request.targetDateTo), | |||||
targetDateFrom = localDateTimeParse(request.targetDateFrom), | |||||
targetDateTo = localDateTimeParse(request.targetDateTo), | |||||
type = request.type ?: "all", | type = request.type ?: "all", | ||||
status = request.status ?: "all", | status = request.status ?: "all", | ||||
itemName = request.itemName ?: "all", | itemName = request.itemName ?: "all", | ||||
@@ -106,21 +106,23 @@ open class PickOrderService( | |||||
return updatedPickOrderInfos | return updatedPickOrderInfos | ||||
} | } | ||||
// TODO: Add actual pick lots | |||||
open fun consoPickOrderDetail(consoCode: String): ConsoPickOrderResponse { | open fun consoPickOrderDetail(consoCode: String): ConsoPickOrderResponse { | ||||
// Conso code | |||||
// Pick orders with items | |||||
// Items | |||||
val zero = BigDecimal.ZERO | val zero = BigDecimal.ZERO | ||||
// pick orders | // pick orders | ||||
// Mapping: PickOrder -> PickOrderInConso | |||||
val pos = pickOrderRepository.findAllByConsoCode(consoCode) | 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 finalPos = pos.map { po -> | ||||
val pols = po.pickOrderLines | val pols = po.pickOrderLines | ||||
// Suggestions for Pick Order Line | // Suggestions for Pick Order Line | ||||
val suggestions = suggestedPickLotService.suggestionForPickOrderLines(pols) | |||||
// val suggestions = suggestedPickLotService.suggestionForPickOrderLines(pols) | |||||
// Pick Order Lines | // Pick Order Lines | ||||
// Mapping: PickOrderLine -> PickOrderLineInConso | // Mapping: PickOrderLine -> PickOrderLineInConso | ||||
@@ -131,7 +133,7 @@ open class PickOrderService( | |||||
// Check If already have suggestion | // Check If already have suggestion | ||||
var suggestion = pol.suggestedPickLots | var suggestion = pol.suggestedPickLots | ||||
if (suggestion.isEmpty()) { | if (suggestion.isEmpty()) { | ||||
suggestion = suggestions.filter { it.pickOrderLine?.id == pol.id }.toMutableList() | |||||
suggestion = suggestedList.filter { it.pickOrderLine?.id == pol.id }.toMutableList() | |||||
} | } | ||||
// Mapping: SuggestedPickLot -> SuggestPickLotInConso | // Mapping: SuggestedPickLot -> SuggestPickLotInConso | ||||
@@ -217,8 +219,7 @@ open class PickOrderService( | |||||
code = _line.first().item.code, | code = _line.first().item.code, | ||||
name = _line.first().item.name, | name = _line.first().item.name, | ||||
qty = _line.fold(zero) { sum, item -> sum + (item.qty ?: zero)}, | qty = _line.fold(zero) { sum, item -> sum + (item.qty ?: zero)}, | ||||
suggestPickLots = _line | |||||
.flatMap { it.suggestPickLots }, | |||||
suggestPickLots = itemSuggestions, | |||||
actualPickLots = mutableListOf() | actualPickLots = mutableListOf() | ||||
) | ) | ||||
} | } | ||||
@@ -231,4 +232,8 @@ open class PickOrderService( | |||||
return response | return response | ||||
} | } | ||||
open fun releaseConsoPickOrder(request: ReleaseConsoPickOrderRequest) { | |||||
val pos = pickOrderRepository.findAllByConsoCode(request.consoCode) | |||||
} | |||||
} | } |
@@ -1,5 +1,14 @@ | |||||
package com.ffii.fpsms.modules.pickOrder.web.models | package com.ffii.fpsms.modules.pickOrder.web.models | ||||
import com.ffii.fpsms.modules.stock.web.model.SaveSuggestedPickLotRequest | |||||
// Consolidated / De-consolidated | |||||
data class ConsoPickOrderRequest ( | data class ConsoPickOrderRequest ( | ||||
val ids: List<Long> | val ids: List<Long> | ||||
) | |||||
// Release Consolidated Pick Order | |||||
data class ReleaseConsoPickOrderRequest ( | |||||
val consoCode: String, | |||||
val suggestedPickLots: List<SaveSuggestedPickLotRequest> | |||||
) | ) |
@@ -1,5 +1,6 @@ | |||||
package com.ffii.fpsms.modules.stock.service | 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.PickOrderLine | ||||
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository | import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository | ||||
import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository | 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.entity.projection.InventoryLotLineInfo | ||||
import com.ffii.fpsms.modules.stock.enums.SuggestedPickLotType | 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.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 org.springframework.stereotype.Service | ||||
import java.math.BigDecimal | import java.math.BigDecimal | ||||
import kotlin.jvm.optionals.getOrDefault | import kotlin.jvm.optionals.getOrDefault | ||||
@@ -24,12 +27,31 @@ open class SuggestedPickLotService( | |||||
val pickOrderLineRepository: PickOrderLineRepository, | val pickOrderLineRepository: PickOrderLineRepository, | ||||
val inventoryLotLineService: InventoryLotLineService, | val inventoryLotLineService: InventoryLotLineService, | ||||
) { | ) { | ||||
open fun suggestionForPickOrders(request: SuggestedPickLotForPoRequest): SuggestedPickLotResponse { | |||||
val pos = request.pickOrders | |||||
val suggestedList = mutableListOf<SuggestedPickLot>() | |||||
var holdQtyMap = request.holdQtyMap | |||||
open fun suggestionForPickOrderLines(pickOrderlines: List<PickOrderLine>): List<SuggestedPickLot> { | |||||
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 zero = BigDecimal.ZERO | ||||
val suggestionList: MutableList<SuggestedPickLot> = mutableListOf() | |||||
val suggestedList: MutableList<SuggestedPickLot> = mutableListOf() | |||||
val holdQtyMap: MutableMap<Long?, BigDecimal?> = request.holdQtyMap | |||||
// get current inventory lot line qty & grouped by item Id | // get current inventory lot line qty & grouped by item Id | ||||
val availableInventoryLotLines = inventoryLotLineService | val availableInventoryLotLines = inventoryLotLineService | ||||
@@ -40,7 +62,7 @@ open class SuggestedPickLotService( | |||||
.groupBy { it.item?.id } | .groupBy { it.item?.id } | ||||
// loop for suggest pick lot line | // loop for suggest pick lot line | ||||
pickOrderlines.forEach { line -> | |||||
pols.forEach { line -> | |||||
val lotLines = availableInventoryLotLines[line.item?.id].orEmpty() | val lotLines = availableInventoryLotLines[line.item?.id].orEmpty() | ||||
var remainingQty = line.qty ?: zero | var remainingQty = line.qty ?: zero | ||||
val updatedLotLines = mutableListOf<InventoryLotLineInfo>() | val updatedLotLines = mutableListOf<InventoryLotLineInfo>() | ||||
@@ -50,58 +72,44 @@ open class SuggestedPickLotService( | |||||
val availableQty = (lotLine.inQty ?: zero) | val availableQty = (lotLine.inQty ?: zero) | ||||
.minus(lotLine.outQty ?: zero) | .minus(lotLine.outQty ?: zero) | ||||
.minus(lotLine.holdQty ?: zero) | |||||
.minus((lotLine.holdQty ?: zero) | |||||
.plus(holdQtyMap[lotLine.id] ?: zero) | |||||
) | |||||
if (availableQty <= zero) { | if (availableQty <= zero) { | ||||
updatedLotLines += lotLine | updatedLotLines += lotLine | ||||
return@forEachIndexed | return@forEachIndexed | ||||
} | } | ||||
val inventoryLotLine = lotLine.id?.let { inventoryLotLineService.findById(it).getOrNull() } | val inventoryLotLine = lotLine.id?.let { inventoryLotLineService.findById(it).getOrNull() } | ||||
// println("1:${inventoryLotLine?.id}: ${inventoryLotLine?.holdQty}") | |||||
val originalHoldQty = inventoryLotLine?.holdQty | val originalHoldQty = inventoryLotLine?.holdQty | ||||
// Update Qty | // Update Qty | ||||
val assignQty = minOf(availableQty, remainingQty) | val assignQty = minOf(availableQty, remainingQty) | ||||
remainingQty = remainingQty.minus(assignQty) | 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 | type = SuggestedPickLotType.PICK_ORDER | ||||
suggestedLotLine = inventoryLotLine?.apply { | |||||
holdQty = originalHoldQty | |||||
} | |||||
suggestedLotLine = inventoryLotLine | |||||
pickOrderLine = line | pickOrderLine = line | ||||
qty = assignQty | qty = assignQty | ||||
} | } | ||||
// suggestionList += SuggestInventoryLotLineResponse( | |||||
// type = SuggestedPickLotType.PICK_ORDER.value, | |||||
// suggestedLotLine = inventoryLotLine, | |||||
// pickOrderLine = line, | |||||
// qty = assignQty | |||||
// ) | |||||
} | } | ||||
// if still have remainingQty | // if still have remainingQty | ||||
if (remainingQty > zero) { | if (remainingQty > zero) { | ||||
suggestionList += SuggestedPickLot().apply { | |||||
suggestedList += SuggestedPickLot().apply { | |||||
type = SuggestedPickLotType.PICK_ORDER | type = SuggestedPickLotType.PICK_ORDER | ||||
suggestedLotLine = null | suggestedLotLine = null | ||||
pickOrderLine = line | 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 = | val suggestedPickLot = | ||||
request.id?.let { id -> suggestedPickLotRepository.findById(id).getOrDefault(SuggestedPickLot()) } | request.id?.let { id -> suggestedPickLotRepository.findById(id).getOrDefault(SuggestedPickLot()) } | ||||
?: SuggestedPickLot() | ?: SuggestedPickLot() | ||||
@@ -119,6 +127,16 @@ open class SuggestedPickLotService( | |||||
qty = request.qty | qty = request.qty | ||||
} | } | ||||
return suggestedPickLot | |||||
} | |||||
open fun saveSuggestedPickLot(request: SaveSuggestedPickLotRequest): SuggestedPickLot { | |||||
val suggestedPickLot = convertRequestToEntity(request) | |||||
return suggestedPickLotRepository.save(suggestedPickLot) | return suggestedPickLotRepository.save(suggestedPickLot) | ||||
} | } | ||||
open fun saveAll(request: List<SuggestedPickLot>): List<SuggestedPickLot> { | |||||
return suggestedPickLotRepository.saveAll(request) | |||||
} | |||||
} | } |
@@ -7,6 +7,7 @@ import com.ffii.fpsms.modules.purchaseOrder.service.PurchaseOrderLineService | |||||
import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService | import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService | ||||
import org.springframework.web.bind.annotation.GetMapping | import org.springframework.web.bind.annotation.GetMapping | ||||
import org.springframework.web.bind.annotation.PathVariable | 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.RequestMapping | ||||
import org.springframework.web.bind.annotation.RestController | import org.springframework.web.bind.annotation.RestController | ||||
@@ -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? | |||||
) |
@@ -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<Long?, BigDecimal?> = mutableMapOf(), | |||||
val pickOrders: List<PickOrder> | |||||
) | |||||
data class SuggestedPickLotForPolRequest( | |||||
val holdQtyMap: MutableMap<Long?, BigDecimal?> = mutableMapOf(), | |||||
val pickOrderLines: List<PickOrderLine> | |||||
) | |||||
@@ -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<Long?, BigDecimal?>, | |||||
val suggestedList: List<SuggestedPickLot> | |||||
) |