| @@ -494,7 +494,8 @@ open class JoPickOrderService( | |||||
| uomShortDesc = uom?.udfShortDesc, | uomShortDesc = uom?.udfShortDesc, | ||||
| matchStatus = jpo?.matchStatus?.value, | matchStatus = jpo?.matchStatus?.value, | ||||
| matchBy = jpo?.matchBy, | matchBy = jpo?.matchBy, | ||||
| matchQty = jpo?.matchQty?.toDouble() | |||||
| matchQty = jpo?.matchQty?.toDouble(), | |||||
| stockInLineId = null, | |||||
| ) | ) | ||||
| } | } | ||||
| @@ -1914,6 +1915,15 @@ open fun getJobOrderLotsHierarchicalByPickOrderId(pickOrderId: Long): JobOrderLo | |||||
| stockOutLineRepository.findAllByPickOrderLineIdAndDeletedFalse(polId) | stockOutLineRepository.findAllByPickOrderLineIdAndDeletedFalse(polId) | ||||
| } | } | ||||
| // 获取 stock in lines 通过 inventoryLotLineId(用于填充 stockInLineId) | |||||
| val stockInLinesByInventoryLotLineId = if (inventoryLotLineIds.isNotEmpty()) { | |||||
| inventoryLotLineIds.associateWith { illId -> | |||||
| stockInLineRepository.findStockInLineInfoByInventoryLotLineId(illId).orElse(null)?.id | |||||
| }.filterValues { it != null } | |||||
| } else { | |||||
| emptyMap() | |||||
| } | |||||
| // 获取 jo_pick_order 记录 | // 获取 jo_pick_order 记录 | ||||
| val joPickOrders = joPickOrderRepository.findByPickOrderId(pickOrder.id!!) | val joPickOrders = joPickOrderRepository.findByPickOrderId(pickOrder.id!!) | ||||
| @@ -1983,6 +1993,11 @@ open fun getJobOrderLotsHierarchicalByPickOrderId(pickOrderId: Long): JobOrderLo | |||||
| else -> "pending" | else -> "pending" | ||||
| } | } | ||||
| // 获取 stockInLineId | |||||
| val stockInLineId = ill.id?.let { illId -> | |||||
| stockInLinesByInventoryLotLineId[illId] | |||||
| } | |||||
| LotDetailResponse( | LotDetailResponse( | ||||
| lotId = ill.id, | lotId = ill.id, | ||||
| lotNo = il.lotNo, | lotNo = il.lotNo, | ||||
| @@ -2000,6 +2015,7 @@ open fun getJobOrderLotsHierarchicalByPickOrderId(pickOrderId: Long): JobOrderLo | |||||
| pickOrderConsoCode = pickOrder.consoCode, | pickOrderConsoCode = pickOrder.consoCode, | ||||
| pickOrderLineId = pol.id, | pickOrderLineId = pol.id, | ||||
| stockOutLineId = sol?.id, | stockOutLineId = sol?.id, | ||||
| stockInLineId = stockInLineId, | |||||
| suggestedPickLotId = spl.id, | suggestedPickLotId = spl.id, | ||||
| stockOutLineQty = sol?.qty ?: 0.0, | stockOutLineQty = sol?.qty ?: 0.0, | ||||
| stockOutLineStatus = sol?.status, | stockOutLineStatus = sol?.status, | ||||
| @@ -109,6 +109,7 @@ data class LotDetailResponse( | |||||
| val pickOrderConsoCode: String?, | val pickOrderConsoCode: String?, | ||||
| val pickOrderLineId: Long?, | val pickOrderLineId: Long?, | ||||
| val stockOutLineId: Long?, | val stockOutLineId: Long?, | ||||
| val stockInLineId: Long?, | |||||
| val suggestedPickLotId: Long?, | val suggestedPickLotId: Long?, | ||||
| val stockOutLineQty: Double?, | val stockOutLineQty: Double?, | ||||
| val stockOutLineStatus: String?, | val stockOutLineStatus: String?, | ||||
| @@ -590,7 +590,7 @@ private fun handleMissItemOnly(request: PickExecutionIssueRequest, missQty: BigD | |||||
| val newStatus = if (actualPickQtyDouble >= requiredQty) { | val newStatus = if (actualPickQtyDouble >= requiredQty) { | ||||
| "completed" | "completed" | ||||
| } else { | } else { | ||||
| "partially_completed" | |||||
| "completed" | |||||
| } | } | ||||
| stockOutLine.status = newStatus | stockOutLine.status = newStatus | ||||
| @@ -606,6 +606,42 @@ private fun handleMissItemOnly(request: PickExecutionIssueRequest, missQty: BigD | |||||
| createStockLedgerForStockOut(savedStockOutLine, "Nor") | createStockLedgerForStockOut(savedStockOutLine, "Nor") | ||||
| } | } | ||||
| } | } | ||||
| // ✅ NEW: If all stock_out_line under this pick order line are finished (completed/rejected), | |||||
| // mark pick_order_line as COMPLETED. This is required for "miss all required qty" flows | |||||
| // where qty can be 0 but picking decision is finalized via issue form. | |||||
| try { | |||||
| stockOutLineRepository.flush() | |||||
| val allStockOutLines = stockOutLineRepository.findAllByPickOrderLineIdAndDeletedFalse(request.pickOrderLineId) | |||||
| val unfinishedLines = allStockOutLines.filter { | |||||
| it.status != StockOutLineStatus.COMPLETE.status && | |||||
| it.status != StockOutLineStatus.REJECTED.status | |||||
| } | |||||
| println("Miss item: Checking pick order line ${request.pickOrderLineId}") | |||||
| println(" Total stock out lines: ${allStockOutLines.size}") | |||||
| println(" Unfinished lines: ${unfinishedLines.size}") | |||||
| unfinishedLines.forEach { line -> | |||||
| println(" - Line ${line.id}: status=${line.status}") | |||||
| } | |||||
| if (unfinishedLines.isEmpty() && allStockOutLines.isNotEmpty()) { | |||||
| val pickOrderLine = pickOrderLineRepository.findById(request.pickOrderLineId).orElse(null) | |||||
| if (pickOrderLine != null) { | |||||
| pickOrderLine.status = PickOrderLineStatus.COMPLETED | |||||
| pickOrderLineRepository.saveAndFlush(pickOrderLine) | |||||
| println("✅ Miss item: Updated pick order line ${request.pickOrderLineId} status to COMPLETED") | |||||
| } else { | |||||
| println("⚠️ Miss item: Pick order line ${request.pickOrderLineId} not found") | |||||
| } | |||||
| } else { | |||||
| println("⚠️ Miss item: Pick order line ${request.pickOrderLineId} still has ${unfinishedLines.size} unfinished lines") | |||||
| } | |||||
| } catch (e: Exception) { | |||||
| println("⚠️ Miss item: Error checking pick order line completion: ${e.message}") | |||||
| e.printStackTrace() | |||||
| } | |||||
| // ✅ 修改:不重新建议拣货批次(因为 lot 仍然可用) | // ✅ 修改:不重新建议拣货批次(因为 lot 仍然可用) | ||||
| // resuggestPickOrder(request.pickOrderId) // 删除这行 | // resuggestPickOrder(request.pickOrderId) // 删除这行 | ||||
| @@ -51,6 +51,8 @@ import com.ffii.fpsms.modules.deliveryOrder.web.models.PrintQrCodeForDoRequest | |||||
| import com.ffii.fpsms.modules.stock.service.InventoryLotLineService | import com.ffii.fpsms.modules.stock.service.InventoryLotLineService | ||||
| import com.ffii.fpsms.modules.stock.entity.StockLedgerRepository | import com.ffii.fpsms.modules.stock.entity.StockLedgerRepository | ||||
| import com.ffii.fpsms.modules.stock.entity.InventoryRepository | import com.ffii.fpsms.modules.stock.entity.InventoryRepository | ||||
| import org.springframework.http.HttpStatus | |||||
| import org.springframework.web.server.ResponseStatusException | |||||
| @Serializable | @Serializable | ||||
| data class QrContent(val itemId: Long, val stockInLineId: Long) | data class QrContent(val itemId: Long, val stockInLineId: Long) | ||||
| @@ -81,7 +83,10 @@ open class StockInLineService( | |||||
| ): AbstractBaseEntityService<StockInLine, Long, StockInLineRepository>(jdbcDao, stockInLineRepository) { | ): AbstractBaseEntityService<StockInLine, Long, StockInLineRepository>(jdbcDao, stockInLineRepository) { | ||||
| open fun getStockInLineInfo(stockInLineId: Long): StockInLineInfo { | open fun getStockInLineInfo(stockInLineId: Long): StockInLineInfo { | ||||
| return stockInLineRepository.findStockInLineInfoByIdAndDeletedFalse(stockInLineId) | |||||
| // Use Optional-returning repository method to avoid EmptyResultDataAccessException | |||||
| return stockInLineRepository.findStockInLineInfoById(stockInLineId).orElseThrow { | |||||
| ResponseStatusException(HttpStatus.NOT_FOUND, "stockInLineId $stockInLineId not found") | |||||
| } | |||||
| } | } | ||||
| open fun getReceivedStockInLineInfo(stockInLineId: Long): StockInLineInfo { | open fun getReceivedStockInLineInfo(stockInLineId: Long): StockInLineInfo { | ||||
| return stockInLineRepository.findStockInLineInfoByIdAndStatusAndDeletedFalse(id = stockInLineId, status = StockInLineStatus.RECEIVED.status).orElseThrow() | return stockInLineRepository.findStockInLineInfoByIdAndStatusAndDeletedFalse(id = stockInLineId, status = StockInLineStatus.RECEIVED.status).orElseThrow() | ||||
| @@ -855,9 +855,11 @@ open fun batchSubmit(request: QrPickBatchSubmitRequest): MessageResponse { | |||||
| @Transactional | @Transactional | ||||
| open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineStatusByQRCodeAndLotNoRequest): MessageResponse { | open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineStatusByQRCodeAndLotNoRequest): MessageResponse { | ||||
| val totalStartTime = System.currentTimeMillis() | |||||
| val startTime = System.currentTimeMillis() | val startTime = System.currentTimeMillis() | ||||
| try { | try { | ||||
| println("=== QR SCAN REQUEST RECEIVED ===") | println("=== QR SCAN REQUEST RECEIVED ===") | ||||
| println("⏰ Request received at: ${java.time.LocalDateTime.now()}") | |||||
| println(" Request details:") | println(" Request details:") | ||||
| println(" - stockOutLineId: ${request.stockOutLineId}") | println(" - stockOutLineId: ${request.stockOutLineId}") | ||||
| println(" - pickOrderLineId: ${request.pickOrderLineId}") | println(" - pickOrderLineId: ${request.pickOrderLineId}") | ||||
| @@ -865,10 +867,14 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta | |||||
| println(" - itemId: ${request.itemId}") | println(" - itemId: ${request.itemId}") | ||||
| println(" - status: ${request.status}") | println(" - status: ${request.status}") | ||||
| // Step 1: Find StockOutLine | |||||
| val findStockOutLineStart = System.currentTimeMillis() | |||||
| val stockOutLine = stockOutLineRepository.findById(request.stockOutLineId).orElseThrow { | val stockOutLine = stockOutLineRepository.findById(request.stockOutLineId).orElseThrow { | ||||
| println(" StockOutLine not found with ID: ${request.stockOutLineId}") | println(" StockOutLine not found with ID: ${request.stockOutLineId}") | ||||
| IllegalArgumentException("StockOutLine not found with ID: ${request.stockOutLineId}") | IllegalArgumentException("StockOutLine not found with ID: ${request.stockOutLineId}") | ||||
| } | } | ||||
| val findStockOutLineTime = System.currentTimeMillis() - findStockOutLineStart | |||||
| println("⏱️ [STEP 1] Find StockOutLine: ${findStockOutLineTime}ms") | |||||
| println(" Found StockOutLine:") | println(" Found StockOutLine:") | ||||
| println(" - ID: ${stockOutLine.id}") | println(" - ID: ${stockOutLine.id}") | ||||
| @@ -878,8 +884,13 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta | |||||
| println(" - Item ID: ${stockOutLine.item?.id}") | println(" - Item ID: ${stockOutLine.item?.id}") | ||||
| println(" - InventoryLotLine ID: ${stockOutLine.inventoryLotLine?.id}") | println(" - InventoryLotLine ID: ${stockOutLine.inventoryLotLine?.id}") | ||||
| // Step 2: Get InventoryLotLine | |||||
| val getInventoryLotLineStart = System.currentTimeMillis() | |||||
| // 修复:从 stockOutLine.inventoryLotLine 获取 inventoryLot,而不是使用错误的参数 | // 修复:从 stockOutLine.inventoryLotLine 获取 inventoryLot,而不是使用错误的参数 | ||||
| val inventoryLotLine = stockOutLine.inventoryLotLine | val inventoryLotLine = stockOutLine.inventoryLotLine | ||||
| val getInventoryLotLineTime = System.currentTimeMillis() - getInventoryLotLineStart | |||||
| println("⏱️ [STEP 2] Get InventoryLotLine: ${getInventoryLotLineTime}ms") | |||||
| if (inventoryLotLine == null) { | if (inventoryLotLine == null) { | ||||
| println(" StockOutLine has no associated InventoryLotLine") | println(" StockOutLine has no associated InventoryLotLine") | ||||
| return MessageResponse( | return MessageResponse( | ||||
| @@ -892,7 +903,12 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta | |||||
| ) | ) | ||||
| } | } | ||||
| // Step 3: Get InventoryLot | |||||
| val getInventoryLotStart = System.currentTimeMillis() | |||||
| val inventoryLot = inventoryLotLine.inventoryLot | val inventoryLot = inventoryLotLine.inventoryLot | ||||
| val getInventoryLotTime = System.currentTimeMillis() - getInventoryLotStart | |||||
| println("⏱️ [STEP 3] Get InventoryLot: ${getInventoryLotTime}ms") | |||||
| if (inventoryLot == null) { | if (inventoryLot == null) { | ||||
| println(" InventoryLotLine has no associated InventoryLot") | println(" InventoryLotLine has no associated InventoryLot") | ||||
| return MessageResponse( | return MessageResponse( | ||||
| @@ -911,9 +927,13 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta | |||||
| println(" - Item ID: ${inventoryLot.item?.id}") | println(" - Item ID: ${inventoryLot.item?.id}") | ||||
| println(" - InventoryLot ID: ${inventoryLot.id}") | println(" - InventoryLot ID: ${inventoryLot.id}") | ||||
| // Step 4: Validation | |||||
| val validationStart = System.currentTimeMillis() | |||||
| // 修复:比较逻辑 | // 修复:比较逻辑 | ||||
| val lotNoMatch = inventoryLot.lotNo == request.inventoryLotNo | val lotNoMatch = inventoryLot.lotNo == request.inventoryLotNo | ||||
| val itemIdMatch = inventoryLot.item?.id == request.itemId | val itemIdMatch = inventoryLot.item?.id == request.itemId | ||||
| val validationTime = System.currentTimeMillis() - validationStart | |||||
| println("⏱️ [STEP 4] Validation: ${validationTime}ms") | |||||
| println(" Matching results:") | println(" Matching results:") | ||||
| println(" - Lot No match: $lotNoMatch (Expected: ${inventoryLot.lotNo}, Got: ${request.inventoryLotNo})") | println(" - Lot No match: $lotNoMatch (Expected: ${inventoryLot.lotNo}, Got: ${request.inventoryLotNo})") | ||||
| @@ -923,6 +943,8 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta | |||||
| println(" MATCH SUCCESS: Lot and Item both match!") | println(" MATCH SUCCESS: Lot and Item both match!") | ||||
| // Step 5: Update StockOutLine | |||||
| val updateStart = System.currentTimeMillis() | |||||
| stockOutLine.status = request.status | stockOutLine.status = request.status | ||||
| if (request.status == "checked") { | if (request.status == "checked") { | ||||
| stockOutLine.startTime = LocalDateTime.now() | stockOutLine.startTime = LocalDateTime.now() | ||||
| @@ -930,15 +952,30 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta | |||||
| if (request.status == "completed") { | if (request.status == "completed") { | ||||
| stockOutLine.endTime = LocalDateTime.now() | stockOutLine.endTime = LocalDateTime.now() | ||||
| } | } | ||||
| val updateTime = System.currentTimeMillis() - updateStart | |||||
| println("⏱️ [STEP 5] Update entity: ${updateTime}ms") | |||||
| // Step 6: Save to database | |||||
| val saveStart = System.currentTimeMillis() | |||||
| val savedStockOutLine = stockOutLineRepository.saveAndFlush(stockOutLine) | val savedStockOutLine = stockOutLineRepository.saveAndFlush(stockOutLine) | ||||
| val saveTime = System.currentTimeMillis() - saveStart | |||||
| println("⏱️ [STEP 6] Save to DB: ${saveTime}ms") | |||||
| println(" Status updated successfully:") | println(" Status updated successfully:") | ||||
| println(" - New status: ${savedStockOutLine.status}") | println(" - New status: ${savedStockOutLine.status}") | ||||
| println(" - StockOutLine ID: ${savedStockOutLine.id}") | println(" - StockOutLine ID: ${savedStockOutLine.id}") | ||||
| // Step 7: Fetch mapped info | |||||
| val fetchMappedStart = System.currentTimeMillis() | |||||
| val mappedStockOutLine = stockOutLineRepository.findStockOutLineInfoById(savedStockOutLine.id!!) | val mappedStockOutLine = stockOutLineRepository.findStockOutLineInfoById(savedStockOutLine.id!!) | ||||
| val fetchMappedTime = System.currentTimeMillis() - fetchMappedStart | |||||
| println("⏱️ [STEP 7] Fetch mapped info: ${fetchMappedTime}ms") | |||||
| val totalTime = System.currentTimeMillis() - totalStartTime | |||||
| println("=== QR SCAN COMPLETED SUCCESSFULLY ===") | println("=== QR SCAN COMPLETED SUCCESSFULLY ===") | ||||
| println("⏱️ [TOTAL BACKEND TIME] ${totalTime}ms (${totalTime / 1000.0}s)") | |||||
| println("📊 Breakdown: findStockOutLine=${findStockOutLineTime}ms, getInventoryLotLine=${getInventoryLotLineTime}ms, getInventoryLot=${getInventoryLotTime}ms, validation=${validationTime}ms, update=${updateTime}ms, save=${saveTime}ms, fetchMapped=${fetchMappedTime}ms") | |||||
| println("⏰ Completed at: ${java.time.LocalDateTime.now()}") | |||||
| return MessageResponse( | return MessageResponse( | ||||
| id = savedStockOutLine.id, | id = savedStockOutLine.id, | ||||
| @@ -951,6 +988,8 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta | |||||
| ) | ) | ||||
| } else if (!lotNoMatch && itemIdMatch) { | } else if (!lotNoMatch && itemIdMatch) { | ||||
| // Item 匹配但 lotNo 不匹配 | // Item 匹配但 lotNo 不匹配 | ||||
| val totalTime = System.currentTimeMillis() - totalStartTime | |||||
| println("⏱️ [TOTAL BACKEND TIME] ${totalTime}ms (LOT MISMATCH)") | |||||
| println(" LOT NUMBER MISMATCH:") | println(" LOT NUMBER MISMATCH:") | ||||
| println(" - Expected lotNo: ${inventoryLot.lotNo}, Got: ${request.inventoryLotNo}") | println(" - Expected lotNo: ${inventoryLot.lotNo}, Got: ${request.inventoryLotNo}") | ||||
| println(" - Item ID matches: ${inventoryLot.item?.id} == ${request.itemId}") | println(" - Item ID matches: ${inventoryLot.item?.id} == ${request.itemId}") | ||||
| @@ -965,6 +1004,8 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta | |||||
| ) | ) | ||||
| } else { | } else { | ||||
| // Item 不匹配 | // Item 不匹配 | ||||
| val totalTime = System.currentTimeMillis() - totalStartTime | |||||
| println("⏱️ [TOTAL BACKEND TIME] ${totalTime}ms (ITEM MISMATCH)") | |||||
| println(" ITEM MISMATCH:") | println(" ITEM MISMATCH:") | ||||
| println(" - Expected itemId: ${inventoryLot.item?.id}, Got: ${request.itemId}") | println(" - Expected itemId: ${inventoryLot.item?.id}, Got: ${request.itemId}") | ||||
| println(" - Expected lotNo: ${inventoryLot.lotNo}, Got: ${request.inventoryLotNo}") | println(" - Expected lotNo: ${inventoryLot.lotNo}, Got: ${request.inventoryLotNo}") | ||||
| @@ -980,6 +1021,8 @@ open fun updateStockOutLineStatusByQRCodeAndLotNo(request: UpdateStockOutLineSta | |||||
| } | } | ||||
| } catch (e: Exception) { | } catch (e: Exception) { | ||||
| val totalTime = System.currentTimeMillis() - totalStartTime | |||||
| println("⏱️ [TOTAL BACKEND TIME] ${totalTime}ms (ERROR)") | |||||
| println(" ERROR updating stock out line status by QR: ${e.message}") | println(" ERROR updating stock out line status by QR: ${e.message}") | ||||
| println(" Exception type: ${e.javaClass.simpleName}") | println(" Exception type: ${e.javaClass.simpleName}") | ||||
| println(" Stack trace:") | println(" Stack trace:") | ||||
| @@ -26,6 +26,8 @@ import com.ffii.fpsms.modules.master.web.models.MessageResponse | |||||
| import com.ffii.fpsms.modules.stock.web.model.UpdateInventoryLotLineStatusRequest | import com.ffii.fpsms.modules.stock.web.model.UpdateInventoryLotLineStatusRequest | ||||
| import com.ffii.fpsms.modules.stock.web.model.QrCodeAnalysisRequest | import com.ffii.fpsms.modules.stock.web.model.QrCodeAnalysisRequest | ||||
| import com.ffii.fpsms.modules.stock.web.model.QrCodeAnalysisResponse | import com.ffii.fpsms.modules.stock.web.model.QrCodeAnalysisResponse | ||||
| import org.springframework.http.HttpStatus | |||||
| import org.springframework.web.server.ResponseStatusException | |||||
| @RequestMapping("/inventoryLotLine") | @RequestMapping("/inventoryLotLine") | ||||
| @RestController | @RestController | ||||
| @@ -53,7 +55,9 @@ class InventoryLotLineController ( | |||||
| @GetMapping("/lot-detail/{stockInLineId}") | @GetMapping("/lot-detail/{stockInLineId}") | ||||
| fun getLotDetail(@Valid @PathVariable stockInLineId: Long): LotLineInfo { | fun getLotDetail(@Valid @PathVariable stockInLineId: Long): LotLineInfo { | ||||
| val stockInLine = stockInLineRepository.findById(stockInLineId).orElseThrow() | |||||
| val stockInLine = stockInLineRepository.findById(stockInLineId).orElseThrow { | |||||
| ResponseStatusException(HttpStatus.NOT_FOUND, "stockInLineId $stockInLineId not found") | |||||
| } | |||||
| val inventoryLotLine = stockInLine.inventoryLotLine!! | val inventoryLotLine = stockInLine.inventoryLotLine!! | ||||
| val zero = BigDecimal.ZERO | val zero = BigDecimal.ZERO | ||||
| return LotLineInfo( | return LotLineInfo( | ||||
| @@ -52,8 +52,10 @@ class StockOutLineController( | |||||
| } | } | ||||
| @PostMapping("/updateStatusByQRCodeAndLotNo") | @PostMapping("/updateStatusByQRCodeAndLotNo") | ||||
| fun updateStatusByQRCodeAndLotNo(@Valid @RequestBody request: UpdateStockOutLineStatusByQRCodeAndLotNoRequest): MessageResponse { | fun updateStatusByQRCodeAndLotNo(@Valid @RequestBody request: UpdateStockOutLineStatusByQRCodeAndLotNoRequest): MessageResponse { | ||||
| val controllerStartTime = System.currentTimeMillis() | |||||
| try { | try { | ||||
| println("=== CONTROLLER: updateStatusByQRCodeAndLotNo called ===") | println("=== CONTROLLER: updateStatusByQRCodeAndLotNo called ===") | ||||
| println("⏰ Controller start time: ${java.time.LocalDateTime.now()}") | |||||
| println(" Request received:") | println(" Request received:") | ||||
| println(" - stockOutLineId: ${request.stockOutLineId}") | println(" - stockOutLineId: ${request.stockOutLineId}") | ||||
| println(" - pickOrderLineId: ${request.pickOrderLineId}") | println(" - pickOrderLineId: ${request.pickOrderLineId}") | ||||
| @@ -61,11 +63,21 @@ class StockOutLineController( | |||||
| println(" - itemId: ${request.itemId}") | println(" - itemId: ${request.itemId}") | ||||
| println(" - status: ${request.status}") | println(" - status: ${request.status}") | ||||
| // Measure service call time | |||||
| val serviceCallStart = System.currentTimeMillis() | |||||
| val result = stockOutLineService.updateStockOutLineStatusByQRCodeAndLotNo(request) | val result = stockOutLineService.updateStockOutLineStatusByQRCodeAndLotNo(request) | ||||
| val serviceCallTime = System.currentTimeMillis() - serviceCallStart | |||||
| println("⏱️ [CONTROLLER] Service call time: ${serviceCallTime}ms (${serviceCallTime / 1000.0}s)") | |||||
| val controllerTotalTime = System.currentTimeMillis() - controllerStartTime | |||||
| println("⏱️ [CONTROLLER] Total controller time: ${controllerTotalTime}ms (${controllerTotalTime / 1000.0}s)") | |||||
| println("📊 Controller breakdown: serviceCall=${serviceCallTime}ms, overhead=${controllerTotalTime - serviceCallTime}ms") | |||||
| println(" CONTROLLER: Service call completed, returning result") | println(" CONTROLLER: Service call completed, returning result") | ||||
| println("⏰ Controller end time: ${java.time.LocalDateTime.now()}") | |||||
| return result | return result | ||||
| } catch (e: Exception) { | } catch (e: Exception) { | ||||
| val controllerTotalTime = System.currentTimeMillis() - controllerStartTime | |||||
| println("⏱️ [CONTROLLER] Total time before error: ${controllerTotalTime}ms") | |||||
| println(" CONTROLLER ERROR: ${e.message}") | println(" CONTROLLER ERROR: ${e.message}") | ||||
| println(" Exception type: ${e.javaClass.simpleName}") | println(" Exception type: ${e.javaClass.simpleName}") | ||||
| e.printStackTrace() | e.printStackTrace() | ||||