fix: validate overseas handover before settlement

This commit is contained in:
2026-09-01 23:20:34 +08:00
parent e19224c4b7
commit f4a3b58959
9 changed files with 89 additions and 24 deletions
@@ -234,7 +234,7 @@ class LoadingCompletedOutboxServiceTest {
assertThat(firstMarks).doesNotContainAnyElementsOf(secondMarks);
}
@Test void snapshotOnlyPublishesFinalizedLoadedInbounds() throws Exception {
@Test void snapshotSupportsReadOnlyPreflightBeforeFinalStatusMutation() throws Exception {
String rowsSql = String.join(" ", LoadingCompletedEventMapper.class.getMethod("rows", long.class)
.getAnnotation(Select.class).value()).replaceAll("\\s+", " ");
String palletsSql = String.join(" ", LoadingCompletedEventMapper.class.getMethod("palletRows", long.class)
@@ -243,8 +243,8 @@ class LoadingCompletedOutboxServiceTest {
.getMethod("actualPalletRows", long.class).getAnnotation(Select.class).value())
.replaceAll("\\s+", " ");
assertThat(rowsSql).contains("p.plan_status = 'COMPLETED'")
.contains("o.process_status = 'LOADED'")
assertThat(rowsSql).doesNotContain("p.plan_status = 'COMPLETED'")
.doesNotContain("o.process_status = 'LOADED'")
.contains("i.customer_name")
.doesNotContain("b.customer_id AS booking_customer_id")
.doesNotContain("b.customer_name")
@@ -966,6 +966,33 @@ class LoadingPickServiceTest {
verify(loadingListService, never()).publishCompletedEvent(anyLong());
}
@Test
void unpublishableCrossRegionSnapshotFailsBeforeAnyOwnerSettlement() {
LoadingPickTaskEntity completing = task();
completing.setTaskStatus("COMPLETING");
when(repository.task(20L)).thenReturn(completing);
when(repository.inboundOwners(20L)).thenReturn(List.of(
new LoadingPickItemMapper.InboundOwner(101L, 50L),
new LoadingPickItemMapper.InboundOwner(101L, 60L)));
doThrow(new BizException(com.baiyue.common.core.api.ResultCode.CONFLICT,
"一件代发现场托盘箱唛数与实装箱数不一致"))
.when(loadingListService).requireCompletedEventReady(10L);
assertThatThrownBy(() -> service.processCompletion(
completionCommand(905L, "async-unpublishable"), "worker-unpublishable"))
.isInstanceOf(LoadingPickService.CompletionProcessingException.class)
.satisfies(error -> assertThat(((LoadingPickService.CompletionProcessingException) error).stage())
.isEqualTo("COMPLETED_EVENT_READY"));
verify(settlementService, never()).settleOwner(anyLong(), anyLong(), anyLong(), anyString());
verify(loadingDeliveryService, never()).completeAfterPdaSettlement(anyLong(), anyLong(), anyLong(),
anyString(), anyString(), anyString());
verify(completionCommands, never()).checkpoint(anyLong(), anyLong(), anyLong(), anyInt(), anyString());
verify(repository, never()).insert(any(LoadingPickOperationEntity.class));
verify(loadingListService, never()).finishFromPda(anyLong(), anyLong(), anyLong(), anyString());
verify(loadingListService, never()).publishCompletedEvent(anyLong());
}
@Test
void workerRestartResumesFromOwnerCheckpointsWithoutRepeatingSettlements() {
assertNoTruckCoupling();