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