From 1c501e26844e5dde31ae954b56ada9186128715d Mon Sep 17 00:00:00 2001 From: "CANCERYS\\kw093" Date: Thu, 18 Sep 2025 17:17:56 +0800 Subject: [PATCH] update --- .../pickOrder/service/PickOrderService.kt | 151 ++++++++++++++++++ .../pickOrder/web/PickOrderController.kt | 8 +- 2 files changed, 158 insertions(+), 1 deletion(-) 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 c4f1d1b..40b07bc 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 @@ -2086,6 +2086,157 @@ logger.info("Precreated $precreated stock out lines for suggested lots on releas ) } } + @Transactional(rollbackFor = [java.lang.Exception::class]) +open fun autoAssignAndReleasePickOrderByStore(userId: Long, storeId: String): MessageResponse { + try { + println("=== DEBUG: autoAssignAndReleasePickOrderByStore ===") + println("userId: $userId, storeId: $storeId") + + 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 + ) + } + + // 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 + WHERE dpo.deleted = false + AND dpo.ticket_status = 'pending' + AND dpo.store_id = :storeId + AND dpo.pick_order_id IS NOT NULL + """.trimIndent() + val idRows = jdbcDao.queryForList(sql, mapOf("storeId" to storeId)) + val pickOrderIdsByStore = idRows.mapNotNull { row -> + when (val id = row["pickOrderId"]) { + is Number -> id.toLong() + is String -> id.toLongOrNull() + else -> null + } + }.toSet() + 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 + ) + } + + // 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!!) } + .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 + ) + } + + val newConsoCode = assignConsoCode() + 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) + + // 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 suggestions = suggestedPickLotService.suggestionForPickOrders( + SuggestedPickLotForPoRequest(pickOrders = listOf(selected)) + ) + val saveSuggestedPickLots = suggestedPickLotService.saveAll(suggestions.suggestedList) + pickOrderRepository.saveAndFlush(selected) + + // 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) + } + } + } + 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 + } + stockOutLIneRepository.save(line) + precreated++ + } + } + } + } + println("Precreated $precreated stock out lines for store $storeId") + + return MessageResponse( + id = null, + name = "Pick order assigned and released", + 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 + ) + ) + } catch (e: Exception) { + e.printStackTrace() + return MessageResponse( + id = null, name = "Failed to auto-assign by store", code = "ERROR", type = "pickorder", + message = "Failed to auto-assign by store: ${e.message}", errorPosition = null + ) + } +} open fun getAllPickOrderLotsWithDetailsWithAutoAssign(userId: Long): List> { println("=== Debug: getAllPickOrderLotsWithDetailsWithAutoAssign ===") println("today: ${LocalDate.now()}") diff --git a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt index 304dcfa..706f3e6 100644 --- a/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt +++ b/src/main/java/com/ffii/fpsms/modules/pickOrder/web/PickOrderController.kt @@ -230,7 +230,13 @@ class PickOrderController( fun autoAssignAndReleasePickOrder(@PathVariable userId: Long): MessageResponse { return pickOrderService.autoAssignAndReleasePickOrder(userId) } - + @PostMapping("/auto-assign-release-by-store") + fun autoAssignReleaseByStore( + @RequestParam userId: Long, + @RequestParam storeId: String + ): MessageResponse { + return pickOrderService.autoAssignAndReleasePickOrderByStore(userId, storeId) + } @GetMapping("/check-pick-completion/{userId}") fun checkPickOrderCompletion(@PathVariable userId: Long): MessageResponse { return pickOrderService.checkPickOrderCompletion(userId)