This commit is contained in:
2026-08-15 09:57:46 +08:00
parent e7c0788a0b
commit bafabf7217
10 changed files with 140 additions and 16 deletions
@@ -30,6 +30,9 @@ class PdaConvergenceOpenApiContractTest {
.contains("InventorySnapshot")
.contains("changing it never resynchronizes the task or item versions")
.contains("expectedTaskVersion")
.contains("advances every associated inbound from WAIT_SPLIT to LOADING with optimistic locking")
.contains("workflowStatus may later become AWAITING_REVIEW")
.contains("without using containerNo as an association key")
.contains("CompleteLoadingRequest");
String taskLookup = yaml.substring(
@@ -25,6 +25,8 @@ class LoadingDeliveryOpenApiContractTest {
.contains("同类型可多次追加")
.contains("Required when evidenceType is SEAL")
.contains("compatibility projection")
.contains("associated inbound process status to be LOADING")
.contains("workflowStatus AWAITING_REVIEW does not bypass this gate")
.contains("must exactly match the server-derived container-task aggregate")
.contains("cannot complete canonical picking");
assertThat(yaml).doesNotContain("/delivery/complete").doesNotContain("DELIVERED");
@@ -17,6 +17,10 @@ import com.baiyue.firstleg.entity.LoadingPickItemEntity;
import com.baiyue.firstleg.entity.LoadingPickOperationEntity;
import com.baiyue.firstleg.entity.LoadingPickTaskEntity;
import com.baiyue.firstleg.entity.LoadingPlanItemEntity;
import com.baiyue.firstleg.entity.InboundStatusHistoryEntity;
import com.baiyue.firstleg.loading.mapper.LoadingInboundMapper;
import com.baiyue.firstleg.mapper.InboundStatusHistoryMapper;
import com.baiyue.firstleg.mapper.LoadingPickItemMapper;
import com.baiyue.firstleg.repository.LoadingPickRepository;
import com.baiyue.firstleg.repository.SmartLoadingRepository;
import com.baiyue.firstleg.oceanbooking.repository.OceanBookingRepository;
@@ -53,6 +57,8 @@ class LoadingPickServiceTest {
@MockBean
private LoadingListService loadingListService;
@MockBean
private InboundStatusHistoryMapper inboundHistories;
@MockBean
private PdaPickSettlementService settlementService;
@MockBean
private WarehousePalletLocationClient warehouse;
@@ -178,6 +184,51 @@ class LoadingPickServiceTest {
verify(smartLoadingRepository).insert(any(com.baiyue.firstleg.entity.LoadingPlanHistoryEntity.class));
}
@Test
void startsInboundLoadingEvenWhenPlanWasAlreadyStarted() {
LoadingPickTaskEntity task = task();
LoadingPickItemEntity item = item();
preparePick(task, item, "pick-start-inbound");
when(smartLoadingRepository.startPicking(10L, 9L, "operator")).thenReturn(0);
when(repository.inboundOwners(20L)).thenReturn(List.of(
new LoadingPickItemMapper.InboundOwner(101L, 50L)));
when(repository.inbound(101L, 50L)).thenReturn(
new LoadingInboundMapper.Snapshot(50L, 101L, "WAIT_SPLIT", 4));
when(repository.beginInboundLoading(101L, 50L, 9L, 4)).thenReturn(1);
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-start-inbound"),
9L, "operator");
verify(repository).beginInboundLoading(101L, 50L, 9L, 4);
verify(inboundHistories).insert(argThat((InboundStatusHistoryEntity history) ->
Long.valueOf(101L).equals(history.getTenantId())
&& Long.valueOf(50L).equals(history.getInboundId())
&& "WAIT_SPLIT".equals(history.getFromStatus())
&& "LOADING".equals(history.getToStatus())
&& "PDA_START_LOADING".equals(history.getAction())));
verify(smartLoadingRepository, never()).insert(any(
com.baiyue.firstleg.entity.LoadingPlanHistoryEntity.class));
}
@Test
void acceptsConcurrentInboundTransitionWithoutDuplicateHistory() {
LoadingPickTaskEntity task = task();
LoadingPickItemEntity item = item();
preparePick(task, item, "pick-concurrent-inbound");
when(repository.inboundOwners(20L)).thenReturn(List.of(
new LoadingPickItemMapper.InboundOwner(101L, 50L)));
when(repository.inbound(101L, 50L)).thenReturn(
new LoadingInboundMapper.Snapshot(50L, 101L, "WAIT_SPLIT", 4),
new LoadingInboundMapper.Snapshot(50L, 101L, "LOADING", 5));
when(repository.beginInboundLoading(101L, 50L, 9L, 4)).thenReturn(0);
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-concurrent-inbound"),
9L, "operator");
verify(repository).beginInboundLoading(101L, 50L, 9L, 4);
verify(inboundHistories, never()).insert(any(InboundStatusHistoryEntity.class));
}
@Test
void claimStartsLoadingAndSameOperatorReentryDoesNotDuplicateStartHistory() {
LoadingPickTaskEntity task = task();