fix(customs): add broker submission and receipt action history
This commit is contained in:
+4
-1
@@ -17,7 +17,9 @@ class ContainerCustomsControllerContractTest {
|
||||
.containsExactly("/api/platform/v1/customs/loading-plans");
|
||||
assertPermission(PlatformContainerCustomsController.class,"detail","platform:firstleg:customs:list");
|
||||
assertPermission(PlatformContainerCustomsController.class,"start","platform:firstleg:customs:manage");
|
||||
assertPermission(PlatformContainerCustomsController.class,"sendInitialToBroker","platform:firstleg:customs:manage");
|
||||
assertPermission(PlatformContainerCustomsController.class,"uploadCompletion","platform:firstleg:customs:manage");
|
||||
assertPermission(PlatformContainerCustomsController.class,"receiptActions","platform:firstleg:customs:list");
|
||||
assertPermission(PlatformContainerCustomsController.class,"completeAllBuy","platform:firstleg:customs:manage");
|
||||
assertPermission(PlatformContainerCustomsController.class,"declarationBatches","platform:firstleg:customs:list");
|
||||
assertPermission(PlatformContainerCustomsController.class,"createDeclarationBatch","platform:firstleg:customs:manage");
|
||||
@@ -34,12 +36,13 @@ class ContainerCustomsControllerContractTest {
|
||||
assertPermission(MerchantContainerCustomsController.class,"scope","merchant:order:edit");
|
||||
assertPermission(MerchantContainerCustomsController.class,"delete","merchant:order:edit");
|
||||
assertPermission(MerchantContainerCustomsController.class,"clearanceResults","merchant:order:view");
|
||||
assertPermission(MerchantContainerCustomsController.class,"receiptActions","merchant:order:view");
|
||||
}
|
||||
@Test void openApiPublishesEveryPathParameterAndGeneratableDtos()throws Exception{
|
||||
String yaml=new ClassPathResource("openapi/customs-v1.yaml").getContentAsString(java.nio.charset.StandardCharsets.UTF_8);
|
||||
new Yaml().load(yaml);
|
||||
assertThat(yaml).contains("ContainerView:","DocumentView:","FileView:","InboundView:","ActionRequest:","ScopeRequest:",
|
||||
"DeclarationBatch:","ClearanceResult:","declaration-batches","clearance-results")
|
||||
"DeclarationBatch:","BrokerSubmissionView:","ClearanceResult:","ReceiptActionView:","confirmationHistory","brokerSubmission","send-to-broker","declaration-batches","clearance-results")
|
||||
.contains("merchantStatus:","WAITING_UPLOAD","CUSTOMS_COMPLETED","loadingPlanId:","hasActualCargo:","nullable: true")
|
||||
.contains("LOADING_LIST_BUY_DECLARATION_ITEMS")
|
||||
.doesNotContain("/cases/","CUSTOMS_DECLARATION");
|
||||
|
||||
+6
@@ -46,6 +46,7 @@ class ContainerCustomsMapperContractTest {
|
||||
assertRecordProjection("completion", ContainerCustomsMapper.CompletionRow.class, long.class);
|
||||
assertRecordProjection("lockCompletion", ContainerCustomsMapper.CompletionRow.class, long.class);
|
||||
assertRecordProjectionWithoutVersion("completionVersions", ContainerCustomsMapper.CompletionVersionRow.class, long.class);
|
||||
assertRecordProjectionWithoutVersion("receiptActionHistory", ContainerCustomsMapper.ReceiptActionRow.class, long.class, Long.class);
|
||||
}
|
||||
|
||||
@Test void declarationAndClearanceQueriesMapExplicitHistoricalFacts() throws Exception {
|
||||
@@ -57,6 +58,11 @@ class ContainerCustomsMapperContractTest {
|
||||
assertRecordProjectionWithoutVersion("lockClearanceResult", ContainerCustomsMapper.ClearanceResultRow.class, long.class);
|
||||
}
|
||||
|
||||
@Test void brokerSubmissionQueriesMapIndependentFirstSendFact() throws Exception {
|
||||
assertRecordProjection("brokerSubmission", ContainerCustomsMapper.BrokerSubmissionRow.class, long.class);
|
||||
assertRecordProjection("lockBrokerSubmission", ContainerCustomsMapper.BrokerSubmissionRow.class, long.class);
|
||||
}
|
||||
|
||||
private static void assertRecordProjection(String method,Class<?> recordType,Class<?>... parameterTypes) throws Exception {
|
||||
assertProjection(method, recordType, true, parameterTypes);
|
||||
}
|
||||
|
||||
+58
@@ -150,6 +150,61 @@ class ContainerCustomsServiceTest {
|
||||
verify(mapper,never()).freezeScopes(anyLong());
|
||||
}
|
||||
|
||||
@Test void initialBrokerSendCreatesIndependentFrozenSnapshotBatch() throws Exception {
|
||||
var inbound=new ContainerCustomsMapper.InboundRow(9L,"LP9",8L,"COMPLETED","CAB","C",11L,21L,"O","I",7L,"客户","TAX_REFUND");
|
||||
var declaring=container(ContainerCustomsService.DECLARING,3);
|
||||
var source=new ContainerCustomsMapper.DocumentRow(31L,2L,7L,10L,"source.bin","a".repeat(64),
|
||||
"application/octet-stream",1L,"ACTIVE",5L,java.time.LocalDateTime.now(),1,java.time.LocalDateTime.now(),1);
|
||||
var submission=new ContainerCustomsMapper.BrokerSubmissionRow(41L,2L,9L,"BR-LP9-01","SENT",3,"admin",
|
||||
java.time.LocalDateTime.now(),1);
|
||||
when(mapper.claimCommand(anyLong(),eq(5L),eq("SEND_CUSTOMS_INITIAL_TO_BROKER_9"),eq("send-key"),anyString())).thenReturn(1);
|
||||
when(mapper.lockContainer(9L)).thenReturn(declaring);
|
||||
when(mapper.taxRefundCount(9L)).thenReturn(1);
|
||||
when(mapper.brokerSubmission(2L)).thenReturn(null,submission);
|
||||
when(mapper.documents(2L,null)).thenReturn(List.of(source));
|
||||
when(mapper.frozenScopes(31L)).thenReturn(List.of(new ContainerCustomsMapper.ScopeRow(31L,11L,21L,"I")));
|
||||
when(objectMapper.writeValueAsString(any())).thenReturn("[]");
|
||||
when(mapper.insertBrokerSubmission(anyLong(),eq(2L),eq(9L),eq("BR-LP9-01"),eq(3),eq("[]"),eq(5L),eq("admin"))).thenReturn(1);
|
||||
when(mapper.bumpVersionAfterBrokerSubmission(2L,3)).thenReturn(1);
|
||||
when(mapper.insertHistory(anyLong(),eq(2L),eq("SEND_CUSTOMS_INITIAL_TO_BROKER"),eq(ContainerCustomsService.DECLARING),eq(ContainerCustomsService.DECLARING),isNull(),eq(5L),eq("admin"))).thenReturn(1);
|
||||
when(mapper.completeCommand(eq(5L),eq("SEND_CUSTOMS_INITIAL_TO_BROKER_9"),eq("send-key"),anyLong())).thenReturn(1);
|
||||
when(mapper.planInbounds(9L)).thenReturn(List.of(inbound));
|
||||
when(mapper.plan(9L)).thenReturn(new ContainerCustomsMapper.PlanRow(9L,"LP9",8L,"COMPLETED","CAB","C"));
|
||||
when(mapper.container(9L)).thenReturn(declaring);
|
||||
when(mapper.actualBoxCount(9L,null,null)).thenReturn(0L);
|
||||
when(mapper.finalDocument(31L)).thenReturn(null);
|
||||
when(mapper.completion(31L)).thenReturn(null);
|
||||
|
||||
var result=service.sendInitialToBroker(9L,5L,"admin","send-key",new ActionRequest(3,true,null));
|
||||
|
||||
assertThat(result.brokerSubmission()).isNotNull();
|
||||
assertThat(result.brokerSubmission().batchNo()).isEqualTo("BR-LP9-01");
|
||||
assertThat(result.brokerSubmission().sourceVersion()).isEqualTo(3);
|
||||
verify(mapper).insertBrokerSubmission(anyLong(),eq(2L),eq(9L),eq("BR-LP9-01"),eq(3),eq("[]"),eq(5L),eq("admin"));
|
||||
}
|
||||
|
||||
@Test void initialBrokerSendRejectsStaleAggregateVersion(){
|
||||
var declaring=container(ContainerCustomsService.DECLARING,4);
|
||||
when(mapper.claimCommand(anyLong(),eq(5L),eq("SEND_CUSTOMS_INITIAL_TO_BROKER_9"),eq("stale-key"),anyString())).thenReturn(1);
|
||||
when(mapper.lockContainer(9L)).thenReturn(declaring);
|
||||
|
||||
assertThatThrownBy(()->service.sendInitialToBroker(9L,5L,"admin","stale-key",new ActionRequest(3,true,null)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("其他人修改");
|
||||
verify(mapper,never()).insertBrokerSubmission(anyLong(),anyLong(),anyLong(),anyString(),anyInt(),anyString(),anyLong(),anyString());
|
||||
}
|
||||
|
||||
@Test void receiptUploadRejectsWhenInitialBrokerSubmissionIsMissing(){
|
||||
var source=document(1L);var container=container(ContainerCustomsService.DECLARING,3);
|
||||
when(mapper.claimCommand(anyLong(),eq(5L),eq("UPLOAD_COMPLETION_1"),eq("before-send"),anyString())).thenReturn(1);
|
||||
when(mapper.document(1L)).thenReturn(source);when(mapper.lockContainerById(2L)).thenReturn(container);
|
||||
when(mapper.lockDocument(1L)).thenReturn(source);when(mapper.brokerSubmission(2L)).thenReturn(null);
|
||||
|
||||
assertThatThrownBy(()->service.uploadCompletion(1L,5L,"admin","before-send",0,
|
||||
new MockMultipartFile("file","receipt.pdf","application/pdf",new byte[]{1})))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("首次发送报关行资料");
|
||||
verifyNoInteractions(files);
|
||||
}
|
||||
|
||||
@Test void declaringContainerFreezesUploadReplacementScopeAndDeletionWithoutDrift(){
|
||||
var inbound=new ContainerCustomsMapper.InboundRow(9L,"LP9",8L,"COMPLETED","CAB","C",11L,21L,"O","I",7L,"客户","TAX_REFUND");
|
||||
var declaring=container(ContainerCustomsService.DECLARING,3);
|
||||
@@ -247,6 +302,7 @@ class ContainerCustomsServiceTest {
|
||||
var source=document(1L);var container=container(ContainerCustomsService.DECLARING,3);
|
||||
when(mapper.claimCommand(anyLong(),eq(5L),eq("UPLOAD_COMPLETION_1"),eq("k"),anyString())).thenReturn(1);
|
||||
when(mapper.document(1L)).thenReturn(source);when(mapper.lockContainerById(2L)).thenReturn(container);
|
||||
when(mapper.brokerSubmission(2L)).thenReturn(brokerSubmission());
|
||||
when(mapper.lockDocument(1L)).thenReturn(source);when(mapper.lockCompletion(1L)).thenReturn(null);
|
||||
when(files.upload(any(),eq(5L),eq(7L),eq("LOADING_LIST_CUSTOMS_RECEIPT"),eq("9"),any()))
|
||||
.thenReturn(com.baiyue.common.core.api.ApiResponse.success(new CustomsFileClient.Metadata(99L,7L,
|
||||
@@ -307,6 +363,7 @@ class ContainerCustomsServiceTest {
|
||||
when(mapper.command(5L,"UPLOAD_COMPLETION_1","completion-key")).thenAnswer(invocation->commandState.get());
|
||||
when(mapper.lockContainerById(2L)).thenAnswer(invocation->containerState.get());
|
||||
when(mapper.lockDocument(1L)).thenReturn(source);
|
||||
when(mapper.brokerSubmission(2L)).thenReturn(brokerSubmission());
|
||||
when(mapper.lockCompletion(1L)).thenAnswer(invocation->completionState.get());
|
||||
when(files.upload(any(),eq(5L),eq(7L),eq("LOADING_LIST_CUSTOMS_RECEIPT"),eq("9"),same(file)))
|
||||
.thenReturn(com.baiyue.common.core.api.ApiResponse.success(metadata));
|
||||
@@ -382,6 +439,7 @@ class ContainerCustomsServiceTest {
|
||||
}
|
||||
|
||||
private static ContainerCustomsMapper.DocumentRow document(long id){return new ContainerCustomsMapper.DocumentRow(id,2L,7L,10L,"source.bin","a".repeat(64),"application/octet-stream",1L,"ACTIVE",5L,java.time.LocalDateTime.now(),1,java.time.LocalDateTime.now(),1);}
|
||||
private static ContainerCustomsMapper.BrokerSubmissionRow brokerSubmission(){return new ContainerCustomsMapper.BrokerSubmissionRow(41L,2L,9L,"BR-LP9-01","SENT",3,"admin",java.time.LocalDateTime.now(),1);}
|
||||
private static ContainerCustomsMapper.ContainerRow container(String status,int version){return new ContainerCustomsMapper.ContainerRow(2L,9L,8L,status,null,null,null,null,null,null,null,null,version);}
|
||||
private void assertMerchantOrderNotFound(long tenantId,long orderId){
|
||||
assertThatThrownBy(()->service.merchantOrderView(tenantId,orderId))
|
||||
|
||||
Reference in New Issue
Block a user