| @@ -482,7 +482,7 @@ open class DeliveryOrderService( | |||||
| // ✅ Create stock out record and pre-create stock out lines | // ✅ Create stock out record and pre-create stock out lines | ||||
| val stockOut = StockOut().apply { | val stockOut = StockOut().apply { | ||||
| this.type = "job" | |||||
| this.type = "do" | |||||
| this.consoPickOrderCode = consoCode | this.consoPickOrderCode = consoCode | ||||
| this.status = StockOutStatus.PENDING.status | this.status = StockOutStatus.PENDING.status | ||||
| this.handler = request.userId | this.handler = request.userId | ||||
| @@ -930,7 +930,7 @@ open fun releaseDeliveryOrderWithoutTicket(request: ReleaseDoRequest): ReleaseDo | |||||
| // 创建 stock out | // 创建 stock out | ||||
| val stockOut = StockOut().apply { | val stockOut = StockOut().apply { | ||||
| this.type = "job" | |||||
| this.type = "do" | |||||
| this.consoPickOrderCode = consoCode | this.consoPickOrderCode = consoCode | ||||
| this.status = StockOutStatus.PENDING.status | this.status = StockOutStatus.PENDING.status | ||||
| this.handler = request.userId | this.handler = request.userId | ||||
| @@ -940,24 +940,25 @@ open fun releaseDeliveryOrderWithoutTicket(request: ReleaseDoRequest): ReleaseDo | |||||
| saveSuggestedPickLots.forEach { lot -> | saveSuggestedPickLots.forEach { lot -> | ||||
| val polId = lot.pickOrderLine?.id | val polId = lot.pickOrderLine?.id | ||||
| val illId = lot.suggestedLotLine?.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 com.ffii.fpsms.modules.user.entity.UserRepository | ||||
| import org.springframework.stereotype.Service | import org.springframework.stereotype.Service | ||||
| import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
| import java.time.LocalDate | |||||
| @Service | @Service | ||||
| class DoPickOrderAssignmentService( | class DoPickOrderAssignmentService( | ||||
| private val doPickOrderRepository: DoPickOrderRepository, | private val doPickOrderRepository: DoPickOrderRepository, | ||||
| @@ -38,13 +38,27 @@ class DoPickOrderAssignmentService( | |||||
| } | } | ||||
| println("🔍 DEBUG: assignByLane - Converting storeId from '${request.storeId}' to '$actualStoreId'") | 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, | actualStoreId, | ||||
| DoPickOrderStatus.pending | DoPickOrderStatus.pending | ||||
| ) | ) | ||||
| } | |||||
| .filter { it.truckLanceCode == request.truckLanceCode } | .filter { it.truckLanceCode == request.truckLanceCode } | ||||
| .sortedBy { it.truckDepartureTime } | |||||
| println("🔍 DEBUG: Found ${allCandidates.size} candidate do_pick_orders for lane ${request.truckLanceCode}") | 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 | package com.ffii.fpsms.modules.deliveryOrder.web.models | ||||
| import java.time.LocalDateTime | import java.time.LocalDateTime | ||||
| import java.time.LocalDate | |||||
| import com.fasterxml.jackson.annotation.JsonFormat | import com.fasterxml.jackson.annotation.JsonFormat | ||||
| data class DoDetailResponse( | data class DoDetailResponse( | ||||
| val id: Long, | val id: Long, | ||||
| @@ -49,5 +50,6 @@ data class AssignByLaneRequest( | |||||
| val userId: Long, | val userId: Long, | ||||
| val storeId: String, | val storeId: String, | ||||
| val truckDepartureTime: String?, // 可选:限定出车时间 | val truckDepartureTime: String?, // 可选:限定出车时间 | ||||
| val truckLanceCode: String // 必填:车道编号 | |||||
| val truckLanceCode: String , | |||||
| val requiredDate: LocalDate? // 必填:车道编号 | |||||
| ) | ) | ||||
| @@ -137,8 +137,8 @@ val existingStockOutLine = stockOutLineRepository.findByPickOrderLineIdAndInvent | |||||
| // println("triggering") | // println("triggering") | ||||
| return MessageResponse( | return MessageResponse( | ||||
| id = savedStockOutLine.id, | id = savedStockOutLine.id, | ||||
| name = savedStockOutLine.inventoryLotLine!!.inventoryLot!!.lotNo, | |||||
| code = savedStockOutLine.stockOut!!.consoPickOrderCode, | |||||
| name = savedStockOutLine.inventoryLotLine?.inventoryLot?.lotNo?: "", | |||||
| code = savedStockOutLine.stockOut?.consoPickOrderCode?: "", | |||||
| type = savedStockOutLine.status, | type = savedStockOutLine.status, | ||||
| message = "success", | message = "success", | ||||
| errorPosition = null, | errorPosition = null, | ||||
| @@ -239,8 +239,8 @@ open fun createWithoutConso(request: CreateStockOutLineWithoutConsoRequest): Mes | |||||
| return MessageResponse( | return MessageResponse( | ||||
| id = savedStockOutLine.id, | id = savedStockOutLine.id, | ||||
| name = savedStockOutLine.inventoryLotLine!!.inventoryLot!!.lotNo, | |||||
| code = savedStockOutLine.stockOut!!.consoPickOrderCode, | |||||
| name = savedStockOutLine.inventoryLotLine?.inventoryLot?.lotNo?: "", | |||||
| code = savedStockOutLine.stockOut?.consoPickOrderCode, | |||||
| type = savedStockOutLine.status, | type = savedStockOutLine.status, | ||||
| message = "success", | message = "success", | ||||
| errorPosition = null, | errorPosition = null, | ||||
| @@ -552,8 +552,8 @@ private fun getStockOutIdFromPickOrderLine(pickOrderLineId: Long): Long { | |||||
| val mappedSavedStockOutLine = stockOutLineRepository.findStockOutLineInfoById(savedStockOutLine.id!!) | val mappedSavedStockOutLine = stockOutLineRepository.findStockOutLineInfoById(savedStockOutLine.id!!) | ||||
| return MessageResponse( | return MessageResponse( | ||||
| id = savedStockOutLine.id, | id = savedStockOutLine.id, | ||||
| name = savedStockOutLine.inventoryLotLine!!.inventoryLot!!.lotNo, | |||||
| code = savedStockOutLine.stockOut!!.consoPickOrderCode, | |||||
| name = savedStockOutLine.inventoryLotLine?.inventoryLot?.lotNo?: "", | |||||
| code = savedStockOutLine.stockOut?.consoPickOrderCode?: "", | |||||
| type = savedStockOutLine.status, | type = savedStockOutLine.status, | ||||
| message = "Stock out line status updated successfully", | message = "Stock out line status updated successfully", | ||||
| errorPosition = null, | 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.stock.entity.StockOutRepository | ||||
| import com.ffii.fpsms.modules.master.entity.ItemsRepository | import com.ffii.fpsms.modules.master.entity.ItemsRepository | ||||
| import com.ffii.fpsms.modules.pickOrder.enums.PickOrderLineStatus | 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 | @Service | ||||
| open class SuggestedPickLotService( | open class SuggestedPickLotService( | ||||
| val suggestedPickLotRepository: SuggestPickLotRepository, | val suggestedPickLotRepository: SuggestPickLotRepository, | ||||
| @@ -50,7 +51,8 @@ open class SuggestedPickLotService( | |||||
| val inventoryRepository: InventoryRepository, | val inventoryRepository: InventoryRepository, | ||||
| val failInventoryLotLineRepository: FailInventoryLotLineRepository, | val failInventoryLotLineRepository: FailInventoryLotLineRepository, | ||||
| val stockOutRepository: StockOutRepository, | val stockOutRepository: StockOutRepository, | ||||
| val itemRepository: ItemsRepository | |||||
| val itemRepository: ItemsRepository, | |||||
| val stockOutLineRepository: StockOutLIneRepository | |||||
| ) { | ) { | ||||
| // Calculation Available Qty / Remaining Qty | // Calculation Available Qty / Remaining Qty | ||||
| @@ -177,7 +179,7 @@ open class SuggestedPickLotService( | |||||
| // 查询现有的 suggestions 用于这个 pick order line | // 查询现有的 suggestions 用于这个 pick order line | ||||
| val existingSuggestions = suggestedPickLotRepository.findAllByPickOrderLineId(line.id!!) | val existingSuggestions = suggestedPickLotRepository.findAllByPickOrderLineId(line.id!!) | ||||
| existingSuggestions.forEach { existingSugg -> | |||||
| existingSuggestions.forEach { existingSugg -> | |||||
| if (existingSugg.suggestedLotLine?.id != null) { | if (existingSugg.suggestedLotLine?.id != null) { | ||||
| val stockOutLines = stockOutLIneRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse( | val stockOutLines = stockOutLIneRepository.findByPickOrderLineIdAndInventoryLotLineIdAndDeletedFalse( | ||||
| line.id!!, existingSugg.suggestedLotLine?.id!! | line.id!!, existingSugg.suggestedLotLine?.id!! | ||||
| @@ -632,15 +634,19 @@ println("Keeping all suggestions (including rejected ones for display)") | |||||
| val rejectedStockOutLines = stockOutLIneRepository | val rejectedStockOutLines = stockOutLIneRepository | ||||
| .findAllByPickOrderLineIdAndDeletedFalse(pickOrderLine.id!!) | .findAllByPickOrderLineIdAndDeletedFalse(pickOrderLine.id!!) | ||||
| .filter { it.status == "rejected" } | .filter { it.status == "rejected" } | ||||
| println("Rejected stock out lines: ${rejectedStockOutLines.size}") | |||||
| // ✅ 修复:只创建一个 resuggest_issue(如果有 rejected lines) | // ✅ 修复:只创建一个 resuggest_issue(如果有 rejected lines) | ||||
| if (rejectedStockOutLines.isNotEmpty()) { | if (rejectedStockOutLines.isNotEmpty()) { | ||||
| println("Creating resuggest failure issue") | |||||
| createResuggestFailureIssue( | createResuggestFailureIssue( | ||||
| pickOrder = pickOrderToResuggest, | pickOrder = pickOrderToResuggest, | ||||
| pickOrderLine = pickOrderLine, | 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)") | |||||
| ) | ) | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||