fix: 支持多SKU共箱整托装柜

This commit is contained in:
2026-09-16 21:22:18 +08:00
parent 1cd10a9d3b
commit 9ab1c328ba
9 changed files with 125 additions and 24 deletions
@@ -1068,19 +1068,48 @@ public class LoadingPickService {
}
Map<Long, LoadingPickItemEntity> itemsById = taskItems.stream().collect(Collectors.toMap(
LoadingPickItemEntity::getId, item -> item));
Set<Long> unresolvedIds = allItems.stream().filter(item -> !isResolved(item))
.map(LoadingPickItemEntity::getId).collect(Collectors.toSet());
Set<Long> requestIds = request.items().stream().map(BatchItemRequest::itemId)
.collect(Collectors.toSet());
if (requestIds.size() != request.items().size()) {
throw new BizException(ResultCode.BAD_REQUEST, "整批明细不能包含重复itemId");
}
if (!requestIds.equals(unresolvedIds)) {
Set<String> unresolvedUnits = allItems.stream().filter(item -> !isResolved(item))
.map(LoadingPickService::batchUnitKey).collect(Collectors.toSet());
Set<String> requestUnits = request.items().stream().map(requestItem -> {
LoadingPickItemEntity item = itemsById.get(requestItem.itemId());
if (item == null || isResolved(item)) throw conflict("PDA明细不属于当前任务或已完成");
return batchUnitKey(item);
}).collect(Collectors.toSet());
if (requestUnits.size() != request.items().size()) {
throw new BizException(ResultCode.BAD_REQUEST, "同一整托只能提交一次");
}
if (!requestUnits.equals(unresolvedUnits)) {
throw conflict("整批提交必须且只能包含当前任务全部待拣明细");
}
Map<Long, Boolean> inboundHasWork = new HashMap<>();
List<BatchItemRequest> expandedRequests = new ArrayList<>();
for (BatchItemRequest requestItem : request.items()) {
LoadingPickItemEntity representative = itemsById.get(requestItem.itemId());
if (representative.getPalletId() == null) {
expandedRequests.add(requestItem);
continue;
}
List<LoadingPickItemEntity> members = allItems.stream().filter(item -> !isResolved(item)
&& representative.getPalletId().equals(item.getPalletId())).toList();
int aggregateVersion = members.stream().map(LoadingPickItemEntity::getVersion)
.filter(Objects::nonNull).max(Integer::compareTo).orElse(0);
if (!Objects.equals(requestItem.version(), aggregateVersion)) {
throw conflict("PDA明细版本已变化,请刷新后重试");
}
for (LoadingPickItemEntity member : members) {
expandedRequests.add(new BatchItemRequest(member.getId(), requestItem.action(),
requestItem.pickedPackageCount(), requestItem.finalPickedPackageCount(),
member.getVersion(), requestItem.reason(), requestItem.palletNo()));
}
}
Map<Long, Boolean> inboundHasWork = new HashMap<>();
for (BatchItemRequest requestItem : expandedRequests) {
LoadingPickItemEntity item = itemsById.get(requestItem.itemId());
if (item == null || item.getInboundId() == null || item.getLoadingPlanItemId() == null
|| item.getInboundDetailId() == null) {
@@ -1092,7 +1121,7 @@ public class LoadingPickService {
}
List<BatchLine> result = new ArrayList<>();
for (BatchItemRequest requestItem : request.items()) {
for (BatchItemRequest requestItem : expandedRequests) {
LoadingPickItemEntity item = itemsById.get(requestItem.itemId());
if (!Objects.equals(requestItem.version(), item.getVersion())) {
throw conflict("PDA明细版本已变化,请刷新后重试");
@@ -1152,6 +1181,10 @@ public class LoadingPickService {
return result;
}
private static String batchUnitKey(LoadingPickItemEntity item) {
return item.getPalletId() == null ? "ITEM:" + item.getId() : "PALLET:" + item.getPalletId();
}
private void validateWholePallets(List<BatchLine> lines, List<LoadingPickItemEntity> allItems, long warehouseId) {
Map<Long, List<BatchLine>> groups = lines.stream().filter(line -> "PICK_PALLET".equals(line.action()))
.collect(Collectors.groupingBy(line -> line.item().getPalletId()));
@@ -1281,6 +1314,7 @@ public class LoadingPickService {
Map<Long, Integer> requestedByInbound = new HashMap<>();
Map<Long, BatchLine> lineByItem = lines.stream().collect(Collectors.toMap(
line -> line.item().getId(), line -> line));
Set<String> countedPalletInbounds = new HashSet<>();
for (LoadingPickItemEntity item : allItems) {
BatchLine line = lineByItem.get(item.getId());
int picked = line == null ? count(item.getPickedPackageCount())
@@ -1288,6 +1322,10 @@ public class LoadingPickService {
? count(item.getPickedPackageCount()) + line.request().pickedPackageCount()
: "PICK_PALLET".equals(line.action()) ? count(item.getPlannedPackageCount())
: "PARTIAL".equals(line.action()) ? line.request().finalPickedPackageCount() : 0;
if (line != null && "PICK_PALLET".equals(line.action())) {
String physicalUnit = item.getPalletId() + ":" + item.getInboundId();
if (!countedPalletInbounds.add(physicalUnit)) continue;
}
requestedByInbound.merge(item.getInboundId(), picked, Integer::sum);
}
requestedByInbound.forEach((inboundId, requested) -> {