提交
This commit is contained in:
+7
@@ -30,6 +30,7 @@ class MerchantWorkbenchFilterMapperTest {
|
||||
jdbc.execute("ALTER TABLE fl_loading_plan_item ADD id BIGINT GENERATED BY DEFAULT AS IDENTITY");
|
||||
jdbc.execute("CREATE TABLE fl_loading_pick_task(id BIGINT,loading_plan_id BIGINT,task_status VARCHAR(32))");
|
||||
jdbc.execute("CREATE TABLE fl_loading_pick_item(pick_task_id BIGINT,loading_plan_item_id BIGINT,item_status VARCHAR(32),picked_package_count INT)");
|
||||
jdbc.execute("CREATE TABLE fl_container_document(container_booking_id BIGINT,document_type VARCHAR(40),file_id BIGINT)");
|
||||
jdbc.execute("CREATE TABLE fl_carrier_schedule_node_fact(container_booking_id BIGINT,standard_node VARCHAR(64),actual_at TIMESTAMP)");
|
||||
var config=new MybatisConfiguration();config.setMapUnderscoreToCamelCase(true);config.addMapper(MerchantWorkbenchFilterMapper.class);
|
||||
var factory=new MybatisSqlSessionFactoryBean();factory.setDataSource(ds);factory.setConfiguration(config);
|
||||
@@ -95,6 +96,12 @@ class MerchantWorkbenchFilterMapperTest {
|
||||
jdbc.update("INSERT INTO fl_carrier_schedule_node_fact VALUES(100,'PICKUP_READY',NULL)");
|
||||
assertThat(mapper.progressFragments(11, null)).allMatch(f->f.stage()==2);
|
||||
jdbc.update("UPDATE fl_carrier_schedule_node_fact SET actual_at=CURRENT_TIMESTAMP");
|
||||
assertThat(mapper.progressFragments(11, null)).allMatch(f->f.stage()==2);
|
||||
// 其他柜、其他资料类型或未绑定文件不能视为清关资料提交成功。
|
||||
jdbc.update("INSERT INTO fl_container_document VALUES(999,'DESTINATION_CLEARANCE',1),(100,'DELIVERY_ORDER',2),(100,'DESTINATION_CLEARANCE',NULL)");
|
||||
assertThat(mapper.progressFragments(11, null)).allMatch(f->f.stage()==2);
|
||||
jdbc.update("UPDATE fl_carrier_schedule_node_fact SET actual_at=NULL");
|
||||
jdbc.update("UPDATE fl_container_document SET file_id=3 WHERE document_type='DESTINATION_CLEARANCE' AND container_booking_id=100");
|
||||
assertThat(mapper.progressFragments(11, null)).allMatch(f->f.stage()==3);
|
||||
assertThat(mapper.progressFragments(11,List.of(101L))).singleElement().satisfies(f->{assertThat(f.orderId()).isEqualTo(101);assertThat(f.stage()).isEqualTo(3);});
|
||||
jdbc.update("UPDATE fl_container_booking SET record_status='CANCELLED'");
|
||||
|
||||
@@ -13,7 +13,7 @@ import static org.mockito.Mockito.*;
|
||||
class WorkflowBoundaryTest {
|
||||
/** 真实开船来源的测试事实。 */
|
||||
private WorkflowFacts.Fact fact() {
|
||||
return new WorkflowFacts.Fact(11,1,101,"APPROVED",true,false,false,false);
|
||||
return new WorkflowFacts.Fact(11,1,101,"APPROVED",true,false,false,false,false);
|
||||
}
|
||||
|
||||
/** 下游漏来源或返回其他客户均整体失败。 */
|
||||
@@ -33,4 +33,23 @@ class WorkflowBoundaryTest {
|
||||
assertThatThrownBy(()->service.rows(List.of(inbound))).isInstanceOf(BizException.class);
|
||||
}
|
||||
|
||||
/** 未记录离港时,报关完成即可待清关;上传清关资料后也必须查询精确海外来源。 */
|
||||
@Test void completedCustomsAndClearanceUploadDoNotWaitForDeparture() {
|
||||
var repository=mock(WorkflowFactRepository.class);
|
||||
var downstream=mock(LastlegWorkflowClient.class);
|
||||
var service=new WorkflowTabService(repository,downstream);
|
||||
var inbound=new InboundOrderEntity();inbound.setId(1L);inbound.setTenantId(11L);
|
||||
inbound.setOrderId(101L);inbound.setProcessStatus("LOADED");
|
||||
when(repository.facts(List.of(1L))).thenReturn(List.of(
|
||||
new WorkflowFacts.Fact(11,1,101,"APPROVED",false,false,false,true,true)));
|
||||
assertThat(service.rows(List.of(inbound))).extracting(r->r.mainStatus()).containsExactly("SAILING_CLEARANCE");
|
||||
verifyNoInteractions(downstream);
|
||||
when(repository.facts(List.of(1L))).thenReturn(List.of(
|
||||
new WorkflowFacts.Fact(11,1,101,"APPROVED",false,true,false,true,true)));
|
||||
when(downstream.read(any(),any())).thenReturn(ApiResponse.success(List.of(
|
||||
new WorkflowFacts.Overseas(11,1,false,false,false,false))));
|
||||
assertThat(service.rows(List.of(inbound))).extracting(r->r.mainStatus()).containsExactly("WAIT_UNLOAD","WAIT_DISPATCH");
|
||||
verify(downstream).read(any(),eq(new WorkflowFacts.Request(List.of(new WorkflowFacts.Source(11,1)))));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,33 +3,46 @@ import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
/** 取消回显、分柜隔离和资料页签回归。 */
|
||||
class WorkflowBusinessTest {
|
||||
/** 报关资料齐备进入汇总,实际开船及清关资料分别驱动后续页签。 */
|
||||
/** 报关完成进入待清关,清关资料保存后才进入拆柜与排车待办。 */
|
||||
@Test void customsDocumentsDepartureAndClearanceDriveTabs() {
|
||||
var missing=new WorkflowFacts.Fact(11,1,101,"APPROVED",false,false,true,false);
|
||||
var uploaded=new WorkflowFacts.Fact(11,1,101,"APPROVED",false,false,false,true);
|
||||
var departed=new WorkflowFacts.Fact(11,1,101,"APPROVED",true,false,false,true);
|
||||
var cleared=new WorkflowFacts.Fact(11,1,101,"APPROVED",true,true,false,true);
|
||||
var uploadedBeforeDeparture=new WorkflowFacts.Fact(11,1,101,"APPROVED",false,true,false,true);
|
||||
var missing=new WorkflowFacts.Fact(11,1,101,"APPROVED",false,false,true,false,false);
|
||||
var uploaded=new WorkflowFacts.Fact(11,1,101,"APPROVED",false,false,false,true,false);
|
||||
var departed=new WorkflowFacts.Fact(11,1,101,"APPROVED",true,false,false,true,false);
|
||||
var cleared=new WorkflowFacts.Fact(11,1,101,"APPROVED",true,true,false,true,false);
|
||||
var completed=new WorkflowFacts.Fact(11,1,101,"APPROVED",false,false,false,true,true);
|
||||
var uploadedBeforeDeparture=new WorkflowFacts.Fact(11,1,101,"APPROVED",false,true,false,true,false);
|
||||
var pendingUnload=new WorkflowFacts.Overseas(11,1,false,false,false,false);
|
||||
var unloaded=new WorkflowFacts.Overseas(11,1,false,false,false,true);
|
||||
assertThat(WorkflowTabService.classify(missing,"LOADED",null))
|
||||
.contains("WAIT_CUSTOMS_DOCS").doesNotContain("EXPORT_CUSTOMS","SAILING_CLEARANCE","WAIT_UNLOAD");
|
||||
assertThat(WorkflowTabService.classify(uploaded,"LOADED",null))
|
||||
.contains("EXPORT_CUSTOMS").doesNotContain("WAIT_CUSTOMS_DOCS","SAILING_CLEARANCE","WAIT_UNLOAD");
|
||||
assertThat(WorkflowTabService.classify(completed,"LOADED",null))
|
||||
.containsExactly("SAILING_CLEARANCE");
|
||||
assertThat(WorkflowTabService.classify(uploadedBeforeDeparture,"LOADED",pendingUnload))
|
||||
.contains("EXPORT_CUSTOMS").doesNotContain("SAILING_CLEARANCE","WAIT_UNLOAD");
|
||||
.containsExactly("WAIT_UNLOAD","WAIT_DISPATCH");
|
||||
assertThat(WorkflowTabService.classify(departed,"LOADED",pendingUnload))
|
||||
.contains("SAILING_CLEARANCE").doesNotContain("WAIT_CUSTOMS_DOCS","EXPORT_CUSTOMS","WAIT_UNLOAD");
|
||||
.containsExactly("SAILING_CLEARANCE");
|
||||
assertThat(WorkflowTabService.classify(cleared,"LOADED",pendingUnload))
|
||||
.contains("WAIT_UNLOAD").doesNotContain("WAIT_CUSTOMS_DOCS","EXPORT_CUSTOMS","SAILING_CLEARANCE");
|
||||
.containsExactly("WAIT_UNLOAD","WAIT_DISPATCH");
|
||||
assertThat(WorkflowTabService.classify(cleared,"LOADED",unloaded))
|
||||
.doesNotContain("WAIT_UNLOAD","SAILING_CLEARANCE","EXPORT_CUSTOMS");
|
||||
assertThat(WorkflowTabService.classify(uploaded,"DELIVERED",unloaded))
|
||||
.contains("SIGNED").doesNotContain("EXPORT_CUSTOMS","WAIT_CUSTOMS_DOCS");
|
||||
}
|
||||
/** 清关前不能被海外建单事实提前推进,清关后出库与派送依次替换待办。 */
|
||||
@Test void downstreamFactsCannotBypassClearanceAndOutboundReplacesQueues() {
|
||||
var pending=new WorkflowFacts.Overseas(11,1,true,true,false,false);
|
||||
var shipped=new WorkflowFacts.Overseas(11,1,true,false,true,false);
|
||||
assertThat(WorkflowTabService.classify(fact(1,false),"LOADED",pending)).containsExactly("SAILING_CLEARANCE");
|
||||
assertThat(WorkflowTabService.classify(fact(1,false),"LOADED",shipped)).containsExactly("SAILING_CLEARANCE");
|
||||
assertThat(WorkflowTabService.classify(fact(1,true),"LOADED",pending)).containsExactly("OUTBOUND_DOCUMENT");
|
||||
assertThat(WorkflowTabService.classify(fact(1,true),"LOADED",shipped)).containsExactly("DELIVERING");
|
||||
assertThat(WorkflowTabService.classify(fact(1,true),"DELIVERED",shipped)).containsExactly("SIGNED");
|
||||
}
|
||||
/** 构造独立分柜来源。 */
|
||||
private WorkflowFacts.Fact fact(long id,boolean uploaded) {
|
||||
return new WorkflowFacts.Fact(11,id,100+id,"APPROVED",true,uploaded,false,false);
|
||||
return new WorkflowFacts.Fact(11,id,100+id,"APPROVED",true,uploaded,false,false,false);
|
||||
}
|
||||
/** 有效建单移出待排车,取消后恢复;实际出库不计未出库单。 */
|
||||
@Test void cancellationRestoresDispatchQueue() {
|
||||
@@ -45,9 +58,9 @@ class WorkflowBusinessTest {
|
||||
/** 一柜资料上传不覆盖另一柜;签收不再进入待排。 */
|
||||
@Test void independentSlicesAndUploadedClearance() {
|
||||
assertThat(WorkflowTabService.classify(fact(1,false),"LOADED",new WorkflowFacts.Overseas(11,1,false,false,false,false)))
|
||||
.contains("SAILING_CLEARANCE","WAIT_DISPATCH").doesNotContain("WAIT_UNLOAD");
|
||||
.containsExactly("SAILING_CLEARANCE");
|
||||
assertThat(WorkflowTabService.classify(fact(2,true),"LOADED",new WorkflowFacts.Overseas(11,2,true,true,false,false)))
|
||||
.contains("WAIT_UNLOAD","OUTBOUND_DOCUMENT").doesNotContain("SAILING_CLEARANCE","WAIT_DISPATCH");
|
||||
.containsExactly("OUTBOUND_DOCUMENT");
|
||||
assertThat(WorkflowTabService.classify(fact(1,false),"DELIVERED",null)).contains("SIGNED").doesNotContain("WAIT_DISPATCH");
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -60,10 +60,11 @@ class WorkflowFactPersistenceTest {
|
||||
db.update("INSERT INTO fl_customs_customer_document VALUES(10,11,'ACTIVE',8)");
|
||||
db.update("INSERT INTO fl_customs_customer_document_inbound VALUES(1,11,10)");
|
||||
assertThat(mapper.facts(List.of(1L))).singleElement().satisfies(f->{assertThat(f.missingCustoms()).isFalse();assertThat(f.exportCustomsReady()).isTrue();});
|
||||
// 本票上传后即可汇总,不必等同柜其他票或点击开始报关;完成报关后仍等待实际开船。
|
||||
// 本票资料上传后进入出口报关汇总,报关完成事实独立驱动待清关。
|
||||
for (String status : List.of("READY_TO_START", "DECLARING", "COMPLETED")) {
|
||||
db.update("UPDATE fl_customs_container SET status=? WHERE id=8", status);
|
||||
assertThat(mapper.facts(List.of(1L)).get(0).exportCustomsReady()).isTrue();
|
||||
assertThat(mapper.facts(List.of(1L)).get(0).customsCompleted()).isEqualTo("COMPLETED".equals(status));
|
||||
}
|
||||
db.update("UPDATE fl_customs_customer_document SET status='DELETED' WHERE id=10");
|
||||
assertThat(mapper.facts(List.of(1L))).singleElement().satisfies(f->{
|
||||
|
||||
Reference in New Issue
Block a user