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 40b07bc..6dae3c6 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 @@ -2095,15 +2095,11 @@ open fun autoAssignAndReleasePickOrderByStore(userId: Long, storeId: String): Me val zero = BigDecimal.ZERO val releasedBy = SecurityUtils.getUser().getOrNull() val user = userService.find(userId).orElse(null) - if (user == null) { - return MessageResponse( - id = null, name = "User not found", code = "ERROR", type = "pickorder", - message = "User with ID $userId not found", errorPosition = null - ) + return MessageResponse(id = null, name = "User not found", code = "ERROR", type = "pickorder", + message = "User with ID $userId not found", errorPosition = null) } - // Get candidate pick order IDs by store from do_pick_order val sql = """ SELECT DISTINCT dpo.pick_order_id AS pickOrderId FROM do_pick_order dpo @@ -2123,111 +2119,106 @@ open fun autoAssignAndReleasePickOrderByStore(userId: Long, storeId: String): Me println("Candidate pickOrderIds by store $storeId: $pickOrderIdsByStore") if (pickOrderIdsByStore.isEmpty()) { - return MessageResponse( - id = null, name = "No pick orders", code = "NO_ORDERS", type = "pickorder", - message = "No pending pick orders found for store $storeId", errorPosition = null - ) + return MessageResponse(id = null, name = "No pick orders", code = "NO_ORDERS", type = "pickorder", + message = "No pending pick orders found for store $storeId", errorPosition = null) } - // Filter to available pending DO pick orders by ID and earliest target date val availablePickOrders = pickOrderRepository .findAll() - .filter { it.status == PickOrderStatus.PENDING } - .filter { it.deliveryOrder != null } .filter { it.id != null && pickOrderIdsByStore.contains(it.id!!) } + .filter { it.deliveryOrder != null } + .filter { it.assignTo == null } + .filter { it.status == PickOrderStatus.PENDING || it.status == PickOrderStatus.RELEASED } .sortedBy { it.targetDate } .take(1) if (availablePickOrders.isEmpty()) { - return MessageResponse( - id = null, name = "No available pick orders", code = "NO_ORDERS", type = "pickorder", - message = "No pending pick orders available for store $storeId", errorPosition = null - ) + return MessageResponse(id = null, name = "No available pick orders", code = "NO_ORDERS", type = "pickorder", + message = "No unassigned pick orders available for store $storeId", errorPosition = null) } - val newConsoCode = assignConsoCode() + val selected = availablePickOrders.first() val currUser = SecurityUtils.getUser().orElseThrow() - // Create stock out early - val stockOut = StockOut().apply { - this.type = "job" - this.consoPickOrderCode = newConsoCode - this.status = StockOutStatus.PENDING.status - this.handler = currUser.id - } - val savedStockOut = stockOutRepository.saveAndFlush(stockOut) + // If still PENDING, perform full release flow; if already RELEASED, skip creation duplication + if (selected.status == PickOrderStatus.PENDING) { + val newConsoCode = assignConsoCode() - // Assign and release selected pick order - val selected = availablePickOrders.first() - selected.apply { - this.releasedBy = releasedBy - status = PickOrderStatus.RELEASED - this.assignTo = user - this.consoCode = newConsoCode - } + val stockOut = StockOut().apply { + this.type = "job" + this.consoPickOrderCode = newConsoCode + this.status = StockOutStatus.PENDING.status + this.handler = currUser.id + } + val savedStockOut = stockOutRepository.saveAndFlush(stockOut) - val suggestions = suggestedPickLotService.suggestionForPickOrders( - SuggestedPickLotForPoRequest(pickOrders = listOf(selected)) - ) - val saveSuggestedPickLots = suggestedPickLotService.saveAll(suggestions.suggestedList) - pickOrderRepository.saveAndFlush(selected) + selected.apply { + this.releasedBy = releasedBy + status = PickOrderStatus.RELEASED + this.consoCode = newConsoCode + } - // Hold inventory - val inventoryLotLines = inventoryLotLineRepository.findAllByIdIn( - saveSuggestedPickLots.mapNotNull { it.suggestedLotLine?.id } - ) - saveSuggestedPickLots.forEach { lot -> - val lotLineId = lot.suggestedLotLine?.id - if (lotLineId != null) { - val idx = inventoryLotLines.indexOf(lot.suggestedLotLine) - if (idx >= 0) { - val currentHold = inventoryLotLines[idx].holdQty ?: zero - val addHold = lot.qty ?: zero - inventoryLotLines[idx].holdQty = currentHold.plus(addHold) + val suggestions = suggestedPickLotService.suggestionForPickOrders( + SuggestedPickLotForPoRequest(pickOrders = listOf(selected)) + ) + val saveSuggestedPickLots = suggestedPickLotService.saveAll(suggestions.suggestedList) + pickOrderRepository.saveAndFlush(selected) + + val inventoryLotLines = inventoryLotLineRepository.findAllByIdIn( + saveSuggestedPickLots.mapNotNull { it.suggestedLotLine?.id } + ) + saveSuggestedPickLots.forEach { lot -> + val lotLineId = lot.suggestedLotLine?.id + if (lotLineId != null) { + val idx = inventoryLotLines.indexOf(lot.suggestedLotLine) + if (idx >= 0) { + val currentHold = inventoryLotLines[idx].holdQty ?: zero + val addHold = lot.qty ?: zero + inventoryLotLines[idx].holdQty = currentHold.plus(addHold) + } } } - } - inventoryLotLineRepository.saveAll(inventoryLotLines) + inventoryLotLineRepository.saveAll(inventoryLotLines) - // Pre-create stock out lines - var precreated = 0 - saveSuggestedPickLots.forEach { lot -> - val polId = lot.pickOrderLine?.id - val illId = lot.suggestedLotLine?.id - if (polId != null && illId != null) { - val existingLines = stockOutLIneRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse(polId, illId) - if (existingLines.isEmpty()) { - val pickOrderLine = pickOrderLineRepository.findById(polId).orElse(null) - val inventoryLotLine = inventoryLotLineRepository.findById(illId).orElse(null) - if (pickOrderLine != null && inventoryLotLine != null) { - val line = com.ffii.fpsms.modules.stock.entity.StockOutLine().apply { - this.stockOut = savedStockOut - this.pickOrderLine = pickOrderLine - this.inventoryLotLine = inventoryLotLine - this.item = pickOrderLine.item - this.status = com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus.PENDING.status - this.qty = 0.0 + var precreated = 0 + saveSuggestedPickLots.forEach { lot -> + val polId = lot.pickOrderLine?.id + val illId = lot.suggestedLotLine?.id + if (polId != null && illId != null) { + val existing = stockOutLIneRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse(polId, illId) + if (existing.isEmpty()) { + val pol = pickOrderLineRepository.findById(polId).orElse(null) + val ill = inventoryLotLineRepository.findById(illId).orElse(null) + if (pol != null && ill != null) { + val line = com.ffii.fpsms.modules.stock.entity.StockOutLine().apply { + this.stockOut = savedStockOut + this.pickOrderLine = pol + this.inventoryLotLine = ill + this.item = pol.item + this.status = com.ffii.fpsms.modules.stock.web.model.StockOutLineStatus.PENDING.status + this.qty = 0.0 + } + stockOutLIneRepository.save(line) + precreated++ } - stockOutLIneRepository.save(line) - precreated++ } } } + println("Precreated $precreated stock out lines for store $storeId") } - println("Precreated $precreated stock out lines for store $storeId") + + // Assign user (both pending->released and already released) + selected.assignTo = user + pickOrderRepository.saveAndFlush(selected) return MessageResponse( id = null, - name = "Pick order assigned and released", + name = "Pick order assigned", code = "SUCCESS", type = "pickorder", message = "Assigned to user $userId for store $storeId", errorPosition = null, - entity = mapOf( - "consoCode" to newConsoCode, - "pickOrderIds" to listOf(selected.id!!), - "storeId" to storeId - ) + entity = mapOf("pickOrderIds" to listOf(selected.id!!), "storeId" to storeId, "status" to selected.status?.value) ) } catch (e: Exception) { e.printStackTrace()