feat: release empty outbound pallet locations

This commit is contained in:
2026-09-24 16:47:50 +08:00
parent f7b009bcdf
commit 0e62b2f45b
@@ -26,10 +26,13 @@ import com.baiyue.lastleg.entity.LastlegOrder;
import com.baiyue.lastleg.entity.LastlegOrderStatusHistory;
import com.baiyue.lastleg.entity.LastlegOrderDetail;
import com.baiyue.lastleg.inboundplan.entity.InboundPlanLine;
import com.baiyue.lastleg.inboundplan.entity.InboundPlanPallet;
import com.baiyue.lastleg.inboundplan.entity.InboundPlanPalletAllocation;
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanLineMapper;
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanCartonMapper;
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanPalletAllocationMapper;
import com.baiyue.lastleg.inboundplan.mapper.InboundPlanPalletMapper;
import com.baiyue.lastleg.inboundplan.pda.gateway.WarehouseResourceGateway;
import com.baiyue.lastleg.delivery.entity.OutboundPdaTask;
import com.baiyue.lastleg.delivery.entity.OutboundPdaPick;
import com.baiyue.lastleg.delivery.mapper.OutboundPdaTaskMapper;
@@ -107,6 +110,8 @@ public class DeliveryTransferService {
@Resource private DropshipSkuInventoryMapper dropshipSkuInventory;
@Resource private ReturnInventoryCartonMapper returnCartons;
@Resource private InboundPlanPalletAllocationMapper planAllocations;
@Resource private InboundPlanPalletMapper inboundPlanPallets;
@Resource private WarehouseResourceGateway warehouseResources;
@Resource private InboundPlanLineMapper planLines;
@Resource private InboundPlanCartonMapper inboundCartons;
@Resource private LastlegOrderMapper tailOrders;
@@ -930,9 +935,41 @@ public class DeliveryTransferService {
}
}
}
releaseEmptyOutboundPalletLocations(customerId, outbound.getOverseasWarehouseId(), items);
return taskResult(outbound, task);
}
/** Release the physical location only after the whole pallet has left inventory. */
private void releaseEmptyOutboundPalletLocations(String customerId, String warehouseId,
List<OutboundPalletItem> items) {
if (!StringUtils.hasText(warehouseId)) return;
Set<Long> palletIds = items.stream().map(OutboundPalletItem::getWarehousePalletId)
.filter(Objects::nonNull).collect(Collectors.toCollection(LinkedHashSet::new));
for (Long palletId : palletIds) {
long remaining = inventoryPositions.listPallet(customerId, palletId).stream()
.filter(position -> warehouseId.equals(position.getOverseasWarehouseId()))
.mapToLong(position -> value(position.getAvailablePackages())
+ value(position.getHoldPackages()) + value(position.getAllocatedPackages())
+ value(position.getPickedPackages()) + value(position.getReceivingPackages()))
.sum();
if (remaining != 0) continue;
Long lockId = null;
WarehouseTransferPallet transferPallet = warehouseTransferPallets.selectOne(new LambdaQueryWrapper<WarehouseTransferPallet>()
.eq(WarehouseTransferPallet::getCustomerId, customerId)
.eq(WarehouseTransferPallet::getWarehousePalletId, palletId)
.last("LIMIT 1"));
if (transferPallet != null) lockId = transferPallet.getWarehouseResourceLockId();
if (lockId == null && inboundPlanPallets != null) {
InboundPlanPallet planPallet = inboundPlanPallets.selectOne(new LambdaQueryWrapper<InboundPlanPallet>()
.eq(InboundPlanPallet::getCustomerId, customerId)
.eq(InboundPlanPallet::getWarehousePalletId, palletId)
.last("LIMIT 1"));
if (planPallet != null) lockId = planPallet.getWarehouseResourceLockId();
}
if (lockId != null) warehouseResources.release(customerId, lockId);
}
}
@Transactional
public void cancelOutbound(String outboundNo, DeliveryRequests.Cancel request) {
OutboundOrder outbound = outboundOrders.lockGlobalByNo(trim(outboundNo));