diff --git a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/service/RelabelApplicationService.java b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/service/RelabelApplicationService.java index f18fd781c..b0d516e32 100644 --- a/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/service/RelabelApplicationService.java +++ b/lastleg-service/src/main/java/com/baiyue/lastleg/relabel/service/RelabelApplicationService.java @@ -859,7 +859,8 @@ public class RelabelApplicationService implements WalletResultHandler { if ("COMPLETED".equals(application.getStatus())) return; if (!READY_FOR_OUTBOUND.equals(application.getStatus()) || !"OUTBOUNDED".equals(application.getFulfillmentStatus()) - || !Set.of("FROZEN", "NOT_REQUIRED").contains(application.getWalletStatus())) { + // PDA 完工已发起结算;转运收货只结束履约,不能拒绝已结算的原单或再次扣款。 + || !Set.of("FROZEN", "NOT_REQUIRED", "SETTLE_PENDING", "SETTLED").contains(application.getWalletStatus())) { throw conflict("本票换标尚未完成出库或资金冻结"); } List linkedOrders = tailOrders(application); diff --git a/lastleg-service/src/test/java/com/baiyue/lastleg/relabel/service/RelabelApplicationServiceTest.java b/lastleg-service/src/test/java/com/baiyue/lastleg/relabel/service/RelabelApplicationServiceTest.java index 72f93a84f..abcf3d3c0 100644 --- a/lastleg-service/src/test/java/com/baiyue/lastleg/relabel/service/RelabelApplicationServiceTest.java +++ b/lastleg-service/src/test/java/com/baiyue/lastleg/relabel/service/RelabelApplicationServiceTest.java @@ -1164,6 +1164,24 @@ class RelabelApplicationServiceTest { verify(inventoryCommands, never()).release(any(), any(), any()); } + @Test + void receivedTransferAfterPdaSettlementCompletesWithoutDuplicateFinancialCommands() { + RelabelApplication app = transferCompletionFixture(); + for (String walletStatus : List.of("SETTLE_PENDING", "SETTLED")) { + app.setStatus(RelabelApplicationService.READY_FOR_OUTBOUND); app.setFulfillmentStatus("OUTBOUNDED"); + app.setWalletStatus(walletStatus); + service.completeWarehouseTransferFulfillment("10001", app.getRelabelNo(), 91L, "operator-1"); + service.completeWarehouseTransferFulfillment("10001", app.getRelabelNo(), 91L, "operator-1"); + assertEquals("COMPLETED", app.getStatus()); assertEquals("COMPLETED", app.getFulfillmentStatus()); + assertEquals(walletStatus, app.getWalletStatus()); + } + verify(histories, times(2)).insert(any(RelabelStatusHistory.class)); + verify(feeSources, never()).publishApproved(any(), any(), any()); + verify(walletCommands, never()).publish(any(), anyLong(), any(), any(), any(), any(), anyLong()); + verify(inventoryCommands, never()).release(any(), any(), any()); + verify(inventoryCommands, never()).releaseTransferRelabel(any(), any(), any(), any(), any()); + } + @Test void transferCompletionRejectsWrongLinkUnreceivedStockMissingConfirmationOrFailedFreeze() { RelabelApplication app = transferCompletionFixture();