fix: ignore empty loading links during completion

This commit is contained in:
2026-09-16 11:33:16 +08:00
parent a975b07968
commit 011aa80870
3 changed files with 63 additions and 9 deletions
@@ -193,24 +193,24 @@ public class LoadingModelBridgeService {
}
public void requireStarted(long tenantId, long inboundId) {
List<Link> links = requireLinks(tenantId, inboundId);
if (links.stream().anyMatch(link -> link.allocatedPackageCount() == null || link.allocatedPackageCount() <= 0
|| !Set.of("LOADING", "COMPLETED").contains(link.loadingPlanStatus()))) {
List<Link> links = requireAllocatedLinks(tenantId, inboundId);
if (links.stream().anyMatch(link -> !Set.of("LOADING", "COMPLETED").contains(link.loadingPlanStatus()))) {
throw conflict("关联柜次尚未全部开始装柜");
}
}
public void requireCompleted(long tenantId, long inboundId) {
List<Link> links = requireLinks(tenantId, inboundId);
if (links.stream().anyMatch(link -> link.allocatedPackageCount() == null || link.allocatedPackageCount() <= 0
|| !"COMPLETED".equals(link.loadingPlanStatus()))) {
List<Link> links = requireAllocatedLinks(tenantId, inboundId);
if (links.stream().anyMatch(link -> !"COMPLETED".equals(link.loadingPlanStatus()))) {
throw conflict("关联柜次尚未全部完成装柜");
}
}
private List<Link> requireLinks(long tenantId, long inboundId) {
List<Link> links = repository.byInbound(tenantId, inboundId);
if (links.isEmpty()) throw conflict("入库单尚未关联柜次装柜计划");
private List<Link> requireAllocatedLinks(long tenantId, long inboundId) {
List<Link> links = repository.byInbound(tenantId, inboundId).stream()
.filter(link -> link.allocatedPackageCount() != null && link.allocatedPackageCount() > 0)
.toList();
if (links.isEmpty()) throw conflict("入库单尚未关联有效柜次装柜计划");
return links;
}
@@ -0,0 +1,18 @@
package com.baiyue.firstleg.loading.bridge.mapper;
import org.apache.ibatis.annotations.Select;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class LoadingModelBridgeMapperContractTest {
@Test
void allocatedPackagesCountsOnlyActiveLoadingPlanItems() throws Exception {
String sql = String.join(" ", LoadingModelBridgeMapper.class
.getMethod("allocatedPackages", long.class, long.class, long.class)
.getAnnotation(Select.class).value()).replaceAll("\\s+", " ");
assertThat(sql).contains("inbound_id=#{inboundId} AND deleted=0");
}
}
@@ -264,6 +264,42 @@ class LoadingModelBridgeServiceTest {
.hasMessageContaining("尚未全部完成装柜");
}
@Test
void completionGatesIgnoreHistoricalLinksWithoutActiveAllocatedPackages() {
Link removedEditingLink = new Link(2L, 10L, 20L, 30L, "CONFIRMED", 4,
41L, 51L, null, "EDITING", 6, 0, LocalDateTime.now());
when(repository.byInbound(10, 20)).thenReturn(List.of(
removedEditingLink, link("CONFIRMED", 4, "LOADING", 7, 5)));
service.requireStarted(10, 20);
when(repository.byInbound(10, 20)).thenReturn(List.of(
removedEditingLink, link("CONFIRMED", 4, "COMPLETED", 8, 5)));
service.requireCompleted(10, 20);
}
@Test
void completionGateStillRejectsAnActivelyAllocatedContainerThatHasNotStarted() {
when(repository.byInbound(10, 20)).thenReturn(List.of(
link("CONFIRMED", 4, "LOADING", 7, 5),
new Link(2L, 10L, 20L, 30L, "CONFIRMED", 4, 41L, 51L, null,
"EDITING", 6, 3, LocalDateTime.now())));
assertThatThrownBy(() -> service.requireStarted(10, 20))
.hasMessageContaining("尚未全部开始装柜");
}
@Test
void completionGateRejectsAnInboundWithOnlyHistoricalZeroAllocationLinks() {
when(repository.byInbound(10, 20)).thenReturn(List.of(
new Link(2L, 10L, 20L, 30L, "CONFIRMED", 4, 41L, 51L, null,
"EDITING", 6, 0, LocalDateTime.now())));
assertThatThrownBy(() -> service.requireStarted(10, 20))
.hasMessageContaining("尚未关联有效柜次装柜计划");
}
@Test
void bindsConfirmingPreloadToRunningPlanAndConfirmsIt() {
when(repository.byPair(10, 20, 40)).thenReturn(null);