| @@ -482,7 +482,7 @@ open class DeliveryOrderService( | |||
| // ✅ Create stock out record and pre-create stock out lines | |||
| val stockOut = StockOut().apply { | |||
| this.type = "job" | |||
| this.type = "do" | |||
| this.consoPickOrderCode = consoCode | |||
| this.status = StockOutStatus.PENDING.status | |||
| this.handler = request.userId | |||
| @@ -930,7 +930,7 @@ open fun releaseDeliveryOrderWithoutTicket(request: ReleaseDoRequest): ReleaseDo | |||
| // 创建 stock out | |||
| val stockOut = StockOut().apply { | |||
| this.type = "job" | |||
| this.type = "do" | |||
| this.consoPickOrderCode = consoCode | |||
| this.status = StockOutStatus.PENDING.status | |||
| this.handler = request.userId | |||
| @@ -940,24 +940,25 @@ open fun releaseDeliveryOrderWithoutTicket(request: ReleaseDoRequest): ReleaseDo | |||
| 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 = StockOutLine().apply { | |||
| this.stockOut = savedStockOut | |||
| this.pickOrderLine = pickOrderLine | |||
| this.inventoryLotLine = inventoryLotLine | |||
| this.item = pickOrderLine.item | |||
| this.status = StockOutLineStatus.PENDING.status | |||
| this.qty = 0.0 | |||
| if (polId != null) { | |||
| val pickOrderLine = pickOrderLineRepository.findById(polId).orElse(null) | |||
| val inventoryLotLine = illId?.let { inventoryLotLineRepository.findById(it).orElse(null) } | |||
| if (pickOrderLine != null) { | |||
| val line = StockOutLine().apply { | |||
| this.stockOut = savedStockOut | |||
| this.pickOrderLine = pickOrderLine | |||
| this.inventoryLotLine = inventoryLotLine // 可能为 null | |||
| this.item = pickOrderLine.item | |||
| // ✅ 修复:根据是否有 inventoryLotLine 设置状态 | |||
| this.status = if (inventoryLotLine == null) { | |||
| StockOutLineStatus.PARTIALLY_COMPLETE.status // 没有库存批次时使用 PARTIALLY_COMPLETE | |||
| } else { | |||
| StockOutLineStatus.PENDING.status // 有正常库存批次时使用 PENDING | |||
| } | |||
| stockOutLineRepository.save(line) | |||
| this.qty = 0.0 | |||
| } | |||
| stockOutLineRepository.save(line) | |||
| } | |||
| } | |||
| } | |||
| @@ -12,7 +12,7 @@ import com.ffii.fpsms.modules.pickOrder.enums.PickOrderStatus | |||
| import com.ffii.fpsms.modules.user.entity.UserRepository | |||
| import org.springframework.stereotype.Service | |||
| import java.time.LocalDateTime | |||
| import java.time.LocalDate | |||
| @Service | |||
| class DoPickOrderAssignmentService( | |||
| private val doPickOrderRepository: DoPickOrderRepository, | |||
| @@ -38,13 +38,27 @@ class DoPickOrderAssignmentService( | |||
| } | |||
| println("🔍 DEBUG: assignByLane - Converting storeId from '${request.storeId}' to '$actualStoreId'") | |||
| // ✅ 获取所有候选记录 | |||
| val allCandidates = doPickOrderRepository | |||
| .findByStoreIdAndTicketStatusOrderByTruckDepartureTimeAsc( | |||
| // ✅ 获取日期(如果提供) | |||
| val requiredDate = request.requiredDate | |||
| println("🔍 DEBUG: assignByLane - Requested date: $requiredDate") | |||
| // ✅ 根据是否有日期参数选择不同的查询方法 | |||
| val allCandidates = if (requiredDate != null) { | |||
| println("🔍 DEBUG: Filtering by date: $requiredDate") | |||
| doPickOrderRepository.findByStoreIdAndRequiredDeliveryDateAndTicketStatusIn( | |||
| actualStoreId, | |||
| requiredDate, | |||
| listOf(DoPickOrderStatus.pending) | |||
| ) | |||
| } else { | |||
| println("🔍 DEBUG: No date filter applied") | |||
| doPickOrderRepository.findByStoreIdAndTicketStatusOrderByTruckDepartureTimeAsc( | |||
| actualStoreId, | |||
| DoPickOrderStatus.pending | |||
| ) | |||
| } | |||
| .filter { it.truckLanceCode == request.truckLanceCode } | |||
| .sortedBy { it.truckDepartureTime } | |||
| println("🔍 DEBUG: Found ${allCandidates.size} candidate do_pick_orders for lane ${request.truckLanceCode}") | |||
| @@ -1,6 +1,7 @@ | |||
| package com.ffii.fpsms.modules.deliveryOrder.web.models | |||
| import java.time.LocalDateTime | |||
| import java.time.LocalDate | |||
| import com.fasterxml.jackson.annotation.JsonFormat | |||
| data class DoDetailResponse( | |||
| val id: Long, | |||
| @@ -49,5 +50,6 @@ data class AssignByLaneRequest( | |||
| val userId: Long, | |||
| val storeId: String, | |||
| val truckDepartureTime: String?, // 可选:限定出车时间 | |||
| val truckLanceCode: String // 必填:车道编号 | |||
| val truckLanceCode: String , | |||
| val requiredDate: LocalDate? // 必填:车道编号 | |||
| ) | |||
| @@ -137,8 +137,8 @@ val existingStockOutLine = stockOutLineRepository.findByPickOrderLineIdAndInvent | |||
| // println("triggering") | |||
| return MessageResponse( | |||
| id = savedStockOutLine.id, | |||
| name = savedStockOutLine.inventoryLotLine!!.inventoryLot!!.lotNo, | |||
| code = savedStockOutLine.stockOut!!.consoPickOrderCode, | |||
| name = savedStockOutLine.inventoryLotLine?.inventoryLot?.lotNo?: "", | |||
| code = savedStockOutLine.stockOut?.consoPickOrderCode?: "", | |||
| type = savedStockOutLine.status, | |||
| message = "success", | |||
| errorPosition = null, | |||
| @@ -239,8 +239,8 @@ open fun createWithoutConso(request: CreateStockOutLineWithoutConsoRequest): Mes | |||
| return MessageResponse( | |||
| id = savedStockOutLine.id, | |||
| name = savedStockOutLine.inventoryLotLine!!.inventoryLot!!.lotNo, | |||
| code = savedStockOutLine.stockOut!!.consoPickOrderCode, | |||
| name = savedStockOutLine.inventoryLotLine?.inventoryLot?.lotNo?: "", | |||
| code = savedStockOutLine.stockOut?.consoPickOrderCode, | |||
| type = savedStockOutLine.status, | |||
| message = "success", | |||
| errorPosition = null, | |||
| @@ -552,8 +552,8 @@ private fun getStockOutIdFromPickOrderLine(pickOrderLineId: Long): Long { | |||
| val mappedSavedStockOutLine = stockOutLineRepository.findStockOutLineInfoById(savedStockOutLine.id!!) | |||
| return MessageResponse( | |||
| id = savedStockOutLine.id, | |||
| name = savedStockOutLine.inventoryLotLine!!.inventoryLot!!.lotNo, | |||
| code = savedStockOutLine.stockOut!!.consoPickOrderCode, | |||
| name = savedStockOutLine.inventoryLotLine?.inventoryLot?.lotNo?: "", | |||
| code = savedStockOutLine.stockOut?.consoPickOrderCode?: "", | |||
| type = savedStockOutLine.status, | |||
| message = "Stock out line status updated successfully", | |||
| errorPosition = null, | |||
| @@ -36,7 +36,8 @@ import com.ffii.fpsms.modules.stock.entity.FailInventoryLotLineRepository | |||
| import com.ffii.fpsms.modules.stock.entity.StockOutRepository | |||
| import com.ffii.fpsms.modules.master.entity.ItemsRepository | |||
| import com.ffii.fpsms.modules.pickOrder.enums.PickOrderLineStatus | |||
| import com.ffii.fpsms.modules.stock.entity.projection.StockOutLineInfo // ✅ 添加这行 | |||
| import com.ffii.fpsms.modules.stock.entity.projection.StockOutLineInfo | |||
| import com.ffii.fpsms.modules.stock.entity.StockOutLIneRepository | |||
| @Service | |||
| open class SuggestedPickLotService( | |||
| val suggestedPickLotRepository: SuggestPickLotRepository, | |||
| @@ -50,7 +51,8 @@ open class SuggestedPickLotService( | |||
| val inventoryRepository: InventoryRepository, | |||
| val failInventoryLotLineRepository: FailInventoryLotLineRepository, | |||
| val stockOutRepository: StockOutRepository, | |||
| val itemRepository: ItemsRepository | |||
| val itemRepository: ItemsRepository, | |||
| val stockOutLineRepository: StockOutLIneRepository | |||
| ) { | |||
| // Calculation Available Qty / Remaining Qty | |||
| @@ -177,7 +179,7 @@ open class SuggestedPickLotService( | |||
| // 查询现有的 suggestions 用于这个 pick order line | |||
| val existingSuggestions = suggestedPickLotRepository.findAllByPickOrderLineId(line.id!!) | |||
| existingSuggestions.forEach { existingSugg -> | |||
| existingSuggestions.forEach { existingSugg -> | |||
| if (existingSugg.suggestedLotLine?.id != null) { | |||
| val stockOutLines = stockOutLIneRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse( | |||
| line.id!!, existingSugg.suggestedLotLine?.id!! | |||
| @@ -632,15 +634,19 @@ println("Keeping all suggestions (including rejected ones for display)") | |||
| val rejectedStockOutLines = stockOutLIneRepository | |||
| .findAllByPickOrderLineIdAndDeletedFalse(pickOrderLine.id!!) | |||
| .filter { it.status == "rejected" } | |||
| println("Rejected stock out lines: ${rejectedStockOutLines.size}") | |||
| // ✅ 修复:只创建一个 resuggest_issue(如果有 rejected lines) | |||
| if (rejectedStockOutLines.isNotEmpty()) { | |||
| println("Creating resuggest failure issue") | |||
| createResuggestFailureIssue( | |||
| pickOrder = pickOrderToResuggest, | |||
| pickOrderLine = pickOrderLine, | |||
| rejectedStockOutLine = rejectedStockOutLines.first() | |||
| rejectedStockOutLine = rejectedStockOutLines.first() | |||
| ) | |||
| } | |||
| println("Creating stock out line for suggestion") | |||
| createStockOutLineForSuggestion(suggestion, pickOrderToResuggest) | |||
| println("Stock out line created") | |||
| } | |||
| } | |||
| } | |||
| @@ -679,6 +685,8 @@ println("Keeping all suggestions (including rejected ones for display)") | |||
| ) | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||