| @@ -21,7 +21,9 @@ import com.ffii.fpsms.modules.stock.entity.InventoryLotLineRepository | |||
| import com.ffii.fpsms.modules.stock.entity.StockOut | |||
| import com.ffii.fpsms.modules.stock.entity.StockOutLIneRepository | |||
| import com.ffii.fpsms.modules.stock.entity.StockOutRepository | |||
| import com.ffii.fpsms.modules.stock.entity.enum.InventoryLotLineStatus | |||
| import com.ffii.fpsms.modules.stock.entity.projection.CurrentInventoryItemInfo | |||
| import com.ffii.fpsms.modules.stock.service.InventoryLotLineService | |||
| import com.ffii.fpsms.modules.stock.service.InventoryService | |||
| import com.ffii.fpsms.modules.stock.service.StockOutLineService | |||
| import com.ffii.fpsms.modules.stock.service.SuggestedPickLotService | |||
| @@ -52,13 +54,14 @@ open class PickOrderService( | |||
| private val userService: UserService, | |||
| private val stockOutLIneRepository: StockOutLIneRepository, | |||
| private val inventoryLotLineRepository: InventoryLotLineRepository, | |||
| private val inventoryLotLineService: InventoryLotLineService, | |||
| private val inventoryService: InventoryService, | |||
| private val stockOutRepository: StockOutRepository, | |||
| private val itemsRepository: ItemsRepository, | |||
| private val uomConversionRepository: UomConversionRepository, | |||
| private val jobOrderRepository: JobOrderRepository, | |||
| private val itemUomService: ItemUomService, | |||
| ): AbstractBaseEntityService<PickOrder, Long, PickOrderRepository>(jdbcDao, pickOrderRepository) { | |||
| ) : AbstractBaseEntityService<PickOrder, Long, PickOrderRepository>(jdbcDao, pickOrderRepository) { | |||
| open fun create(request: SavePickOrderRequest): MessageResponse { | |||
| val code = assignPickCode() | |||
| val jo = request.joId?.let { jobOrderRepository.findById(it).getOrNull() } | |||
| @@ -86,13 +89,14 @@ open class PickOrderService( | |||
| pickOrderLineRepository.saveAll(polEntries) | |||
| return MessageResponse( | |||
| id = savedPickOrder.id, | |||
| name = savedPickOrder.code, | |||
| code = savedPickOrder.code, | |||
| type = savedPickOrder.type!!.value, | |||
| message = "success", | |||
| errorPosition = "", | |||
| name = savedPickOrder.code, | |||
| code = savedPickOrder.code, | |||
| type = savedPickOrder.type!!.value, | |||
| message = "success", | |||
| errorPosition = "", | |||
| ) | |||
| } | |||
| open fun localDateTimeParse(dateTime: String?, pattern: String? = "YYYY-MM-DD hh:mm:ss"): LocalDateTime? { | |||
| try { | |||
| val formatter = DateTimeFormatter.ofPattern(pattern!!) | |||
| @@ -125,24 +129,26 @@ open class PickOrderService( | |||
| } | |||
| open fun getConsoPickOrderList(args: MutableMap<String, Any>): List<Map<String, Any>> { | |||
| val sql = StringBuilder( "select" | |||
| + " po.consoCode, " | |||
| + " po.releasedDate, " | |||
| + " po.status, " | |||
| + " po.assignTo " | |||
| + " from pick_order po " | |||
| + " where po.deleted = false " | |||
| + " and po.consoCode is not null " | |||
| val sql = StringBuilder( | |||
| "select" | |||
| + " po.consoCode, " | |||
| + " po.releasedDate, " | |||
| + " po.status, " | |||
| + " po.assignTo " | |||
| + " from pick_order po " | |||
| + " where po.deleted = false " | |||
| + " and po.consoCode is not null " | |||
| ) | |||
| if (args.containsKey("consoCode")){ | |||
| if (args.containsKey("consoCode")) { | |||
| sql.append(" AND po.consoCode like :consoCode "); | |||
| } | |||
| if (args.containsKey("status")){ | |||
| if (args.containsKey("status")) { | |||
| sql.append(" AND po.status = :status "); | |||
| } | |||
| sql.append(" group by po.consoCode, po.releasedDate, po.status, po.assignTo ") | |||
| return jdbcDao.queryForList(sql.toString(), args); | |||
| } | |||
| open fun assignPickCode(): String { | |||
| val suffixFormat = "%03d" | |||
| val pattern = "yyyyMMdd" | |||
| @@ -163,6 +169,7 @@ open class PickOrderService( | |||
| return listOf<String>(prefix, midfix, suffix).joinToString("-") | |||
| } | |||
| // Consolidating Pick Orders | |||
| open fun assignConsoCode(): String { | |||
| val suffixFormat = "%03d" | |||
| @@ -220,27 +227,28 @@ open class PickOrderService( | |||
| if (!args.containsKey("consoCode") || args["consoCode"] == null) { | |||
| throw IllegalArgumentException("consoCode must not be null") | |||
| } | |||
| val sql = StringBuilder("select" | |||
| + " po.status as poStatus," | |||
| + " pol.id, " | |||
| + " i.name as itemName, " | |||
| + " pol.qty as qty, " | |||
| + " max(uc.code) as uom, " | |||
| + " group_concat(ill.id) as lotLineId, " | |||
| + " group_concat(w.name) as warehouse, " | |||
| + " group_concat(il.lotNo) as suggestedLotNo, " | |||
| + " pol.status " | |||
| + " from pick_order po " | |||
| + " left join pick_order_line pol on pol.poId = po.id " | |||
| + " left join items i on i.id = pol.itemId " | |||
| + " left join suggested_pick_lot spl on spl.pickOrderLineId = pol.id " | |||
| + " left join inventory_lot_line ill on ill.id = spl.suggestedLotLineId " | |||
| + " left join warehouse w on w.id = ill.warehouseId " | |||
| + " left join inventory_lot il on il.id = ill.inventoryLotId " | |||
| + " left join uom_conversion uc on uc.id = pol.uomId " | |||
| + " where po.deleted = false " | |||
| + " and po.consoCode = :consoCode " | |||
| + " group by po.status, pol.id, i.name, pol.qty, pol.status " | |||
| val sql = StringBuilder( | |||
| "select" | |||
| + " po.status as poStatus," | |||
| + " pol.id, " | |||
| + " i.name as itemName, " | |||
| + " pol.qty as qty, " | |||
| + " max(uc.code) as uom, " | |||
| + " group_concat(ill.id) as lotLineId, " | |||
| + " group_concat(w.name) as warehouse, " | |||
| + " group_concat(il.lotNo) as suggestedLotNo, " | |||
| + " pol.status " | |||
| + " from pick_order po " | |||
| + " left join pick_order_line pol on pol.poId = po.id " | |||
| + " left join items i on i.id = pol.itemId " | |||
| + " left join suggested_pick_lot spl on spl.pickOrderLineId = pol.id " | |||
| + " left join inventory_lot_line ill on ill.id = spl.suggestedLotLineId " | |||
| + " left join warehouse w on w.id = ill.warehouseId " | |||
| + " left join inventory_lot il on il.id = ill.inventoryLotId " | |||
| + " left join uom_conversion uc on uc.id = pol.uomId " | |||
| + " where po.deleted = false " | |||
| + " and po.consoCode = :consoCode " | |||
| + " group by po.status, pol.id, i.name, pol.qty, pol.status " | |||
| ) | |||
| return jdbcDao.queryForList(sql.toString(), args); | |||
| } | |||
| @@ -279,7 +287,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 salesUnit = inventoryLotLine?.inventoryLot?.item?.id?.let { _itemId -> | |||
| itemUomService.findSalesUnitByItemId(_itemId) | |||
| } | |||
| val ratio = (salesUnit?.ratioN ?: zero).divide(salesUnit?.ratioD ?: one) | |||
| val remainingQty = (inventoryLotLine?.inQty ?: zero) | |||
| @@ -386,6 +396,7 @@ open class PickOrderService( | |||
| } | |||
| open fun releaseConsoPickOrderInfo(consoCode: String): ReleasePickOrderInfoResponse { | |||
| val today = LocalDate.now() | |||
| val zero = BigDecimal.ZERO | |||
| val pos = pickOrderRepository.findAllByConsoCodeAndStatus(consoCode, PickOrderStatus.CONSOLIDATED) | |||
| println(pos) | |||
| @@ -407,13 +418,22 @@ open class PickOrderService( | |||
| val itemIds = requiredItems.mapNotNull { it.first } | |||
| // val inventories = inventoryLotLineRepository.findCurrentInventoryByItems(itemIds) | |||
| val inventories = inventoryService.allInventoriesByItemIds(itemIds) | |||
| // val inventories = inventoryService.allInventoriesByItemIds(itemIds) | |||
| val inventories = inventoryLotLineService | |||
| .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 } | |||
| // Pick Orders | |||
| val releasePickOrderInfos = pos | |||
| .map { po -> | |||
| val releasePickOrderLineInfos = po.pickOrderLines.map { pol -> | |||
| val inventory = inventories.find { it.itemId == pol.item?.id } | |||
| // if (pol.item?.id != null && pol.item!!.id!! > 0) { | |||
| val inventory = pol.item?.id.let { inventories[it] } | |||
| // val inventory = inventories.find { it.itemId == pol.item?.id } | |||
| // Return | |||
| ReleasePickOrderLineInfo( | |||
| @@ -421,11 +441,13 @@ open class PickOrderService( | |||
| itemId = pol.item?.id, | |||
| itemCode = pol.item?.code, | |||
| itemName = pol.item?.name, | |||
| availableQty = inventory?.availableQty, | |||
| // availableQty = inventory?.availableQty, | |||
| availableQty = inventory?.sumOf { i -> i.availableQty ?: zero }, | |||
| requiredQty = pol.qty, | |||
| uomCode = pol.uom?.code, | |||
| uomDesc = pol.uom?.udfudesc, | |||
| ) | |||
| // } | |||
| } | |||
| // Return | |||
| @@ -441,10 +463,13 @@ open class PickOrderService( | |||
| // Items | |||
| val currentInventoryInfos = requiredItems.map { item -> | |||
| val inventory = inventories.find { it.itemId == item.first } | |||
| // val inventory = inventories | |||
| // .find { it.itemId == item.first } | |||
| val inventory = item.first?.let { inventories[it] } | |||
| item.second.let { | |||
| it.availableQty = inventory?.availableQty | |||
| // it.availableQty = inventory?.availableQty | |||
| it.availableQty = inventory?.sumOf { i -> i.availableQty ?: zero } | |||
| // return | |||
| it | |||
| @@ -482,17 +507,26 @@ open class PickOrderService( | |||
| this.handler = currUser.id | |||
| } | |||
| stockOutRepository.save(stockOut) | |||
| suggestions.suggestedList.forEach { | |||
| println("suggest ${it.suggestedLotLine?.id}") | |||
| println("pick ${it.pickOrderLine?.id}") | |||
| } | |||
| suggestedPickLotService.saveAll(suggestions.suggestedList) | |||
| val saveSuggestedPickLots = suggestedPickLotService.saveAll(suggestions.suggestedList) | |||
| pickOrderRepository.saveAll(pos) | |||
| val inventoryLotLines = inventoryLotLineRepository.findAllByIdIn(saveSuggestedPickLots.mapNotNull { it.suggestedLotLine?.id }) | |||
| val inventoryLotLines = | |||
| inventoryLotLineRepository.findAllByIdIn(saveSuggestedPickLots.mapNotNull { it.suggestedLotLine?.id }) | |||
| logger.info(saveSuggestedPickLots) | |||
| saveSuggestedPickLots.forEach { lot -> | |||
| // val ratio = lot.suggestedLotLine!!.stockUom | |||
| val lineIndex = inventoryLotLines.indexOf(lot.suggestedLotLine) | |||
| inventoryLotLines[lineIndex].holdQty = (inventoryLotLines[lineIndex].holdQty ?: zero).plus(lot.qty ?: zero) | |||
| if (lot.suggestedLotLine != null && lot.suggestedLotLine?.id != null && lot.suggestedLotLine!!.id!! > 0) { | |||
| val lineIndex = inventoryLotLines.indexOf(lot.suggestedLotLine) | |||
| inventoryLotLines[lineIndex].holdQty = | |||
| (inventoryLotLines[lineIndex].holdQty ?: zero).plus(lot.qty ?: zero) | |||
| } | |||
| } | |||
| // inventoryLotLines.forEach { line -> | |||
| // line.holdQty = (line.holdQty ?: zero)?.plus(saveSuggestedPickLots.find { it.suggestedLotLine == line }?.qty ?: zero) | |||
| @@ -510,7 +544,7 @@ open class PickOrderService( | |||
| val stockOutLines = stockOutLIneRepository.findAllByStockOutId(stockOut.id!!) | |||
| val unfinishedLines = stockOutLines.filter { | |||
| it.status != StockOutLineStatus.COMPLETE.status | |||
| && it.status != StockOutLineStatus.REJECTED.status | |||
| && it.status != StockOutLineStatus.REJECTED.status | |||
| } | |||
| if (unfinishedLines.isEmpty()) { | |||
| stockOut.apply { | |||