@@ -7,6 +7,7 @@ import com.ffii.fpsms.modules.common.SecurityUtils | |||
import com.ffii.fpsms.modules.jobOrder.entity.JobOrderRepository | |||
import com.ffii.fpsms.modules.master.entity.ItemsRepository | |||
import com.ffii.fpsms.modules.master.entity.UomConversionRepository | |||
import com.ffii.fpsms.modules.master.service.ItemUomService | |||
import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||
import com.ffii.fpsms.modules.pickOrder.entity.PickOrder | |||
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLine | |||
@@ -55,7 +56,8 @@ open class PickOrderService( | |||
private val stockOutRepository: StockOutRepository, | |||
private val itemsRepository: ItemsRepository, | |||
private val uomConversionRepository: UomConversionRepository, | |||
private val jobOrderRepository: JobOrderRepository | |||
private val jobOrderRepository: JobOrderRepository, | |||
private val itemUomService: ItemUomService, | |||
): AbstractBaseEntityService<PickOrder, Long, PickOrderRepository>(jdbcDao, pickOrderRepository) { | |||
open fun create(request: SavePickOrderRequest): MessageResponse { | |||
val code = assignPickCode() | |||
@@ -246,6 +248,7 @@ open class PickOrderService( | |||
// TODO: Add actual pick lots | |||
open fun consoPickOrderDetail(consoCode: String): ConsoPickOrderResponse { | |||
val zero = BigDecimal.ZERO | |||
val one = BigDecimal.ONE | |||
// pick orders | |||
val pos = pickOrderRepository.findAllByConsoCode(consoCode) | |||
@@ -276,6 +279,9 @@ open class PickOrderService( | |||
// Mapping: SuggestedPickLot -> SuggestPickLotInConso | |||
val finalSuggestedPickLots = suggestedPickLots.map { | |||
val inventoryLotLine = it.suggestedLotLine | |||
val salesUnit = inventoryLotLine?.inventoryLot?.item?.id?.let {_itemId -> itemUomService.findSalesUnitByItemId(_itemId) } | |||
val ratio = (salesUnit?.ratioN ?: zero).divide(salesUnit?.ratioD ?: one) | |||
val remainingQty = (inventoryLotLine?.inQty ?: zero) | |||
.minus(inventoryLotLine?.outQty ?: zero) | |||
.minus(inventoryLotLine?.holdQty ?: zero) | |||
@@ -285,10 +291,10 @@ open class PickOrderService( | |||
val finalInventoryLotLine = InventoryLotLineInConso( | |||
id = inventoryLotLine?.id, | |||
lotNo = inventoryLotLine?.inventoryLot?.lotNo, | |||
inQty = inventoryLotLine?.inQty, | |||
outQty = inventoryLotLine?.outQty, | |||
holdQty = inventoryLotLine?.holdQty, | |||
remainingQty = remainingQty, | |||
inQty = (inventoryLotLine?.inQty ?: zero).multiply(ratio), | |||
outQty = (inventoryLotLine?.outQty ?: zero).multiply(ratio), | |||
holdQty = (inventoryLotLine?.holdQty ?: zero).multiply(ratio), | |||
remainingQty = remainingQty.multiply(ratio), | |||
stockUom = IdCodeDesc(stockUom?.id, stockUom?.code, stockUom?.udfudesc), | |||
status = inventoryLotLine?.status?.value, | |||
remarks = inventoryLotLine?.remarks | |||
@@ -14,10 +14,13 @@ interface InventoryInfo{ | |||
@get:Value("#{target.item.type}") | |||
val itemType: String? | |||
// @get:Value("#{target.qty / (target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[stockUnit == true && deleted == false]?.ratioD)}") | |||
@get:Value("#{target.onHandQty / (target.item.itemUoms.^[salesUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[salesUnit == true && deleted == false]?.ratioD)}") | |||
val onHandQty: BigDecimal? | |||
@get:Value("#{target.onHoldQty / (target.item.itemUoms.^[salesUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[salesUnit == true && deleted == false]?.ratioD)}") | |||
val onHoldQty: BigDecimal? | |||
@get:Value("#{target.unavailableQty / (target.item.itemUoms.^[salesUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[salesUnit == true && deleted == false]?.ratioD)}") | |||
val unavailableQty: BigDecimal? | |||
@get:Value("#{target.onHandQty - target.onHoldQty - target.unavailableQty}") | |||
@get:Value("#{(target.onHandQty - target.onHoldQty - target.unavailableQty) / (target.item.itemUoms.^[salesUnit == true && deleted == false]?.ratioN / target.item.itemUoms.^[salesUnit == true && deleted == false]?.ratioD)}") | |||
val availableQty: BigDecimal? | |||
@get:Value("#{target.item.itemUoms.^[purchaseUnit == true && deleted == false]?.uom.code}") | |||
val uomCode: String? | |||
@@ -1,5 +1,6 @@ | |||
package com.ffii.fpsms.modules.stock.service | |||
import com.ffii.fpsms.modules.master.service.ItemUomService | |||
import com.ffii.fpsms.modules.pickOrder.entity.PickOrder | |||
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLine | |||
import com.ffii.fpsms.modules.pickOrder.entity.PickOrderLineRepository | |||
@@ -13,6 +14,7 @@ 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 java.time.LocalDate | |||
import kotlin.jvm.optionals.getOrDefault | |||
import kotlin.jvm.optionals.getOrNull | |||
@@ -23,6 +25,7 @@ open class SuggestedPickLotService( | |||
val inventoryLotLineRepository: InventoryLotLineRepository, | |||
val pickOrderLineRepository: PickOrderLineRepository, | |||
val inventoryLotLineService: InventoryLotLineService, | |||
val itemUomService: ItemUomService, | |||
) { | |||
// Calculation Available Qty / Remaining Qty | |||
open fun calculateRemainingQtyForInfo(inventoryLotLine: InventoryLotLineInfo?): BigDecimal { | |||
@@ -62,6 +65,8 @@ open class SuggestedPickLotService( | |||
val pols = request.pickOrderLines | |||
val itemIds = pols.mapNotNull { it.item?.id } | |||
val zero = BigDecimal.ZERO | |||
val one = BigDecimal.ONE | |||
val today = LocalDate.now() | |||
val suggestedList: MutableList<SuggestedPickLot> = mutableListOf() | |||
val holdQtyMap: MutableMap<Long?, BigDecimal?> = request.holdQtyMap | |||
@@ -71,13 +76,15 @@ open class SuggestedPickLotService( | |||
.allInventoryLotLinesByItemIdIn(itemIds) | |||
.filter { it.status == InventoryLotLineStatus.AVAILABLE.value } | |||
.filter { (it.inQty ?: zero).minus(it.outQty ?: zero).minus(it.holdQty ?: zero) > zero } | |||
.filter { it.expiryDate.isAfter(today) || it.expiryDate.isEqual(today)} | |||
.sortedBy { it.expiryDate } | |||
.groupBy { it.item?.id } | |||
// loop for suggest pick lot line | |||
pols.forEach { line -> | |||
val salesUnit = line.item?.id?.let { itemUomService.findSalesUnitByItemId(it) } | |||
val lotLines = availableInventoryLotLines[line.item?.id].orEmpty() | |||
var remainingQty = line.qty ?: zero | |||
var remainingQty = (line.qty ?: zero).multiply((salesUnit?.ratioN ?: zero).divide(salesUnit?.ratioD ?: one)) | |||
val updatedLotLines = mutableListOf<InventoryLotLineInfo>() | |||
lotLines.forEachIndexed { index, lotLine -> | |||