This commit is contained in:
2026-08-14 12:50:37 +08:00
parent 91e781b3ff
commit ce6963a25e
46 changed files with 664 additions and 76 deletions
@@ -49,6 +49,8 @@ class FbaPricingContractTest {
.contains("/api/platform/v1/inbounds/{inboundId}/fees/published:")
.contains("Idempotency-Key")
.contains("主流程已到 WAIT_SPLIT,也可独立试算且不回退主流程状态")
.contains("区域阶梯渠道可按平台 FBA 仓或海外中转仓的邮编区域")
.contains("不再以 carrierId、业务 customerId 或客户计费规则作为前置")
.contains("该动作涉及后续仓储流程,本轮二期验收不调用")
.contains("不回退 WAIT_SPLIT 状态")
.doesNotContain("应收")
@@ -51,9 +51,9 @@ class LoadingListRepositoryTest {
confirmedPage.setTotal(1);
when(mapper.selectConfirmedPage(any(), any())).thenReturn(confirmedPage);
var preload = repository.preloadPage(new PreloadQuery(null, null, null, null, null, 1, 20))
var preload = repository.preloadPage(new PreloadQuery(null, null, null, null, null, null, 1, 20))
.records().get(0);
var confirmed = repository.confirmedPage(new ConfirmedQuery(null, null, null, null, 1, 20))
var confirmed = repository.confirmedPage(new ConfirmedQuery(null, null, null, null, null, 1, 20))
.records().get(0);
assertThat(preload.planId()).isEqualTo(41L);
@@ -42,6 +42,8 @@ class PriceBookSqlContractTest {
.contains("destination_name VARCHAR(128)")
.contains("parse_issues_json JSON NULL")
.contains("DEFAULT 'PENDING_CONFIRMATION'");
assertThat(schema)
.contains("customer_id BIGINT UNSIGNED NULL COMMENT '可选业务客户快照;平台公共渠道计费不依赖该字段'");
assertThat(schema)
.contains("'ORIGIN_CODE', 'CN-YIWU-01', 193000000000200001")
.contains("'ORIGIN_CODE', 'CN-DONGGUAN-01', 193000000000200002")
@@ -92,6 +92,24 @@ class FbaPricingServiceTest {
assertThat(fee.getValue().getCarrierId()).isNull();
}
@Test
@DisplayName("平台公共渠道计费允许业务客户快照为空")
void calculatesWithoutOptionalBusinessCustomerSnapshot() {
readyRepository();
InboundPricingEntity inbound = inbound("200.000", "0.2000");
inbound.setCustomerId(null);
when(repository.findInbound(TENANT, INBOUND)).thenReturn(inbound);
when(priceBookEstimator.estimate(any())).thenReturn(
estimate("KG", "200.000", "14.300000", "2860.00", "0.00"));
FeeSnapshotResponse response = service.calculate(TENANT, OPERATOR, INBOUND, NOW, "calc-no-customer");
assertThat(response.totalAmount()).isEqualByComparingTo("2860.00");
ArgumentCaptor<InboundFeeEntity> fee = ArgumentCaptor.forClass(InboundFeeEntity.class);
verify(repository).insertFee(fee.capture());
assertThat(fee.getValue().getCustomerId()).isNull();
}
@Test
@DisplayName("不包税CBM使用生效价格表返回的计费量")
void calculatesTaxExcludedCbmFromActivePriceBook() {
@@ -61,7 +61,7 @@ class LoadingListServiceTest {
@Test
void shouldAcceptEditingStatusFromPreloadList() {
PreloadQuery query = new PreloadQuery(null, "EDITING", 100L, null, null, 1, 20);
PreloadQuery query = new PreloadQuery(null, "EDITING", null, 100L, null, null, 1, 20);
service.preloadPage(query);
@@ -184,7 +184,7 @@ class LoadingListServiceTest {
@Test
void confirmedPageAlwaysUsesRepositoryConfirmedProjection() {
ConfirmedQuery query = new ConfirmedQuery(" plan ", 100L, null, null, 1, 20);
ConfirmedQuery query = new ConfirmedQuery(" plan ", null, 100L, null, null, 1, 20);
when(repository.confirmedPage(org.mockito.ArgumentMatchers.any())).thenReturn(
new PageResult<>(List.of(), 1, 20, 0, 0));
@@ -201,8 +201,8 @@ class LoadingListServiceTest {
when(repository.confirmedPage(org.mockito.ArgumentMatchers.any())).thenReturn(
new PageResult<>(List.of(), 1, 20, 0, 0));
service.preloadPage(new PreloadQuery(null, "LOADING", null, null, null, 1, 20));
service.confirmedPage(new ConfirmedQuery(null, null, null, null, 1, 20));
service.preloadPage(new PreloadQuery(null, "LOADING", null, null, null, null, 1, 20));
service.confirmedPage(new ConfirmedQuery(null, null, null, null, null, 1, 20));
verify(repository).preloadPage(org.mockito.ArgumentMatchers.argThat(value -> value.warehouseId() == null));
verify(repository).confirmedPage(org.mockito.ArgumentMatchers.argThat(value -> value.warehouseId() == null));
@@ -187,6 +187,26 @@ class MerchantPriceBookServiceTest {
verify(repository).regionTiers(8L, 10L, "MATSON_PARCEL", "EAST", "TAX_INCLUDED");
}
@Test
void shouldResolveTierRegionFromPlatformOverseasWarehousePostalCode() {
stubChannel(8L, "MATSON_MAX_PARCEL", PriceModel.REGION_WEIGHT_TIER);
when(repository.regionTiers(8L, 10L, "MATSON_MAX_PARCEL", "WEST", "TAX_INCLUDED"))
.thenReturn(tiers());
var warehouse = new PriceBookWarehouseClient.Warehouse(901L, 0L, "US-LAX-01", "洛杉矶仓",
"OVERSEAS", "US", "ACTIVE");
var address = new PriceBookWarehouseClient.Address("US", "CA", "Los Angeles", null,
"90001", "address", null);
when(warehouses.active("internal-token", 0L, 901L))
.thenReturn(ApiResponse.success(new PriceBookWarehouseClient.Detail(warehouse, List.of(address))));
var result = service.estimate(10001L,
request("MATSON_MAX_PARCEL", PricingDestinationType.OVERSEAS, null, 901L, null,
PricingTaxMode.TAX_INCLUDED, "51", null));
assertThat(result.unitPrice()).isEqualByComparingTo("13");
verify(repository).regionTiers(8L, 10L, "MATSON_MAX_PARCEL", "WEST", "TAX_INCLUDED");
}
@Test
void shouldRejectMissingRequiredEstimateFields() {
stubChannel(7L, "MATSON_TRUCK", PriceModel.FBA_WAREHOUSE_RATE);
@@ -206,7 +226,7 @@ class MerchantPriceBookServiceTest {
request("MATSON_PARCEL", PricingDestinationType.FBA, "ONT8", null, null,
PricingTaxMode.TAX_INCLUDED, "51", null)))
.isInstanceOf(BizException.class)
.hasMessageContaining("目的仓区域或平台FBA仓");
.hasMessageContaining("目的仓区域");
}
@Test