优化
This commit is contained in:
@@ -70,7 +70,7 @@ public class OrderApplicationService {
|
||||
long orderId = IdWorker.getId();
|
||||
order.setId(orderId); order.setTenantId(tenantId); order.setOrderNo(nextNo(orderId));
|
||||
order.setStatus(OrderStatus.DRAFT);
|
||||
apply(order, request, snapshots);
|
||||
apply(order, tenantId, request, snapshots);
|
||||
order.setInboundCode(nextInboundCode(inboundCodePrefix));
|
||||
order.setCreatedBy(userId); order.setUpdatedBy(userId);
|
||||
repository.insertOrder(order);
|
||||
@@ -108,7 +108,7 @@ public class OrderApplicationService {
|
||||
}
|
||||
pricingChannelGuard.requireAvailable(tenantId, request.receivingWarehouseId(), request.channelCode(),
|
||||
request.destinationType());
|
||||
apply(order, request, snapshots); order.setStatus(OrderStatus.DRAFT); order.setUpdatedBy(userId);
|
||||
apply(order, tenantId, request, snapshots); order.setStatus(OrderStatus.DRAFT); order.setUpdatedBy(userId);
|
||||
if (before == OrderStatus.SUBMITTED) {
|
||||
order.setStatus(OrderStatus.SUBMITTED);
|
||||
}
|
||||
@@ -411,9 +411,9 @@ public class OrderApplicationService {
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
private void apply(OrderEntity order, OrderRequests.SaveRequest request, OrderMasterDataGuard.Snapshots snapshots) {
|
||||
order.setCustomerId(snapshots.partner() == null ? null : snapshots.partner().id());
|
||||
order.setCustomerName(snapshots.partner() == null ? request.customerName() : snapshots.partner().partnerName());
|
||||
private void apply(OrderEntity order, long tenantId, OrderRequests.SaveRequest request, OrderMasterDataGuard.Snapshots snapshots) {
|
||||
order.setCustomerId(tenantId);
|
||||
order.setCustomerName(request.customerName().trim());
|
||||
order.setTransportMode(request.transportMode()); order.setTradeTerm(request.tradeTerm());
|
||||
order.setDestinationCountryCode(snapshots.destination() == null ? request.destinationCountryCode()
|
||||
: snapshots.destination().warehouse().countryCode());
|
||||
|
||||
@@ -5,7 +5,6 @@ import jakarta.annotation.Resource;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.order.client.PartnerClient;
|
||||
import com.baiyue.order.client.WarehouseClient;
|
||||
import com.baiyue.order.dto.OrderRequests;
|
||||
import feign.FeignException;
|
||||
@@ -21,13 +20,11 @@ import org.slf4j.LoggerFactory;
|
||||
public class OrderMasterDataGuard {
|
||||
private static final Logger log = LoggerFactory.getLogger(OrderMasterDataGuard.class);
|
||||
@Resource private WarehouseClient warehouses;
|
||||
@Resource private PartnerClient partners;
|
||||
@Value("${baiyue.security.internal-service-token}") private String token;
|
||||
@Value("${baiyue.warehouse.public-tenant-id:0}")
|
||||
private long publicTenantId = 0L;
|
||||
public Snapshots validate(long tenantId, OrderRequests.SaveRequest request) {
|
||||
try {
|
||||
PartnerClient.Partner partner=request.customerId()==null ? null : loadPartner(request.customerId());
|
||||
var receiving=loadWarehouse(request.receivingWarehouseId(),"收货仓库");
|
||||
requireWarehouseType(receiving, "DOMESTIC", "收货仓库");
|
||||
if (receiving.addresses()==null || receiving.addresses().stream().noneMatch(Objects::nonNull))
|
||||
@@ -47,7 +44,7 @@ public class OrderMasterDataGuard {
|
||||
destination=loadWarehouse(request.destinationWarehouseId(),"目的仓库");
|
||||
requireWarehouseType(destination, request.destinationType(), "目的仓库");
|
||||
}
|
||||
return new Snapshots(partner,receiving,destination);
|
||||
return new Snapshots(receiving,destination);
|
||||
} catch (FeignException exception) {
|
||||
throw downstreamFailure(exception);
|
||||
} catch (BizException exception) {
|
||||
@@ -56,10 +53,12 @@ public class OrderMasterDataGuard {
|
||||
throw downstreamFailure(exception);
|
||||
}
|
||||
}
|
||||
public void validatePersisted(long tenantId, Long partnerId, Long receivingWarehouseId,
|
||||
public void validatePersisted(long tenantId, Long customerId, Long receivingWarehouseId,
|
||||
Long destinationWarehouseId, String destinationType) {
|
||||
try {
|
||||
if (partnerId!=null) loadPartner(partnerId);
|
||||
if (customerId != null && customerId != tenantId) {
|
||||
throw new BizException(ResultCode.FORBIDDEN,"订单客户必须是当前登录企业");
|
||||
}
|
||||
if (receivingWarehouseId==null) throw new BizException(ResultCode.NOT_FOUND,"收货仓库已停用或不可用");
|
||||
WarehouseClient.Detail receiving=loadWarehouse(receivingWarehouseId,"收货仓库");
|
||||
requireWarehouseType(receiving,"DOMESTIC","收货仓库");
|
||||
@@ -78,25 +77,6 @@ public class OrderMasterDataGuard {
|
||||
throw downstreamFailure(exception);
|
||||
}
|
||||
}
|
||||
private PartnerClient.Partner loadPartner(long id) {
|
||||
ApiResponse<PartnerClient.Partner> response;
|
||||
try {
|
||||
response=partners.active(token,publicTenantId,id);
|
||||
} catch (FeignException.NotFound exception) {
|
||||
throw new BizException(ResultCode.NOT_FOUND,"平台往来单位不存在或不可用");
|
||||
}
|
||||
requireSuccessful(response,"往来单位");
|
||||
if (response.data()==null) throw unavailable("往来单位");
|
||||
var value=response.data();
|
||||
if (!Long.valueOf(publicTenantId).equals(value.tenantId()))
|
||||
throw new BizException(ResultCode.FORBIDDEN,"往来单位不属于平台公共主数据");
|
||||
if (!"ACTIVE".equals(value.status()))
|
||||
throw new BizException(ResultCode.CONFLICT,"往来单位已停用");
|
||||
if (value.types() == null || !value.types().contains("SHIPPER"))
|
||||
throw new BizException(ResultCode.VALIDATION_FAILED,"所选往来单位不具备发货单位类型");
|
||||
if (!StringUtils.hasText(value.partnerName())) throw unavailable("往来单位");
|
||||
return value;
|
||||
}
|
||||
private WarehouseClient.Detail loadWarehouse(long id,String name) {
|
||||
ApiResponse<WarehouseClient.Detail> response;
|
||||
try {
|
||||
@@ -139,6 +119,5 @@ public class OrderMasterDataGuard {
|
||||
throw new BizException(code, message);
|
||||
}
|
||||
}
|
||||
public record Snapshots(PartnerClient.Partner partner, WarehouseClient.Detail receiving,
|
||||
WarehouseClient.Detail destination) { }
|
||||
public record Snapshots(WarehouseClient.Detail receiving, WarehouseClient.Detail destination) { }
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.baiyue.order.service;
|
||||
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.order.client.PartnerClient;
|
||||
import com.baiyue.order.client.WarehouseClient;
|
||||
import com.baiyue.order.dto.OrderRequests;
|
||||
import com.baiyue.order.entity.OrderEntity;
|
||||
@@ -558,15 +557,15 @@ class OrderApplicationServiceStateTest {
|
||||
}
|
||||
|
||||
private OrderMasterDataGuard.Snapshots snapshots() {
|
||||
return snapshots(new PartnerClient.Partner(7L, 0L, "客户", "ACTIVE", "SHIPPER", List.of("SHIPPER")));
|
||||
return snapshots(null);
|
||||
}
|
||||
|
||||
private OrderMasterDataGuard.Snapshots snapshots(PartnerClient.Partner partner) {
|
||||
private OrderMasterDataGuard.Snapshots snapshots(Object ignored) {
|
||||
var warehouse = new WarehouseClient.Warehouse(8L, 0L, "CN-SZX-01", "收货仓", "DOMESTIC", "CN", "ACTIVE");
|
||||
var address = new WarehouseClient.Address("CN", "广东", "深圳", "南山", "518000", "测试路1号", null);
|
||||
var capability = new WarehouseClient.Capability("RECEIVING", true, LocalTime.of(16, 0));
|
||||
var receiving = new WarehouseClient.Detail(warehouse, List.of(address), List.of(capability));
|
||||
return new OrderMasterDataGuard.Snapshots(partner, receiving, null);
|
||||
return new OrderMasterDataGuard.Snapshots(receiving, null);
|
||||
}
|
||||
|
||||
private OrderEntity persistedDraft(String pickupMethod, String destinationType) {
|
||||
|
||||
@@ -3,241 +3,92 @@ package com.baiyue.order.service;
|
||||
import com.baiyue.common.core.api.ApiResponse;
|
||||
import com.baiyue.common.core.api.ResultCode;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.order.client.PartnerClient;
|
||||
import com.baiyue.order.client.WarehouseClient;
|
||||
import com.baiyue.order.dto.OrderRequests;
|
||||
import feign.FeignException;
|
||||
import feign.Request;
|
||||
import feign.Response;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@DisplayName("订单主数据校验")
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SpringJUnitConfig(OrderMasterDataGuard.class)
|
||||
@TestPropertySource(properties = "baiyue.security.internal-service-token=token")
|
||||
class OrderMasterDataGuardTest {
|
||||
@MockBean private WarehouseClient warehouses;
|
||||
@MockBean private PartnerClient partners;
|
||||
@Resource private OrderMasterDataGuard guard;
|
||||
private static final long PUBLIC_TENANT_ID = 0L;
|
||||
|
||||
@Test
|
||||
void validMasterDataReturnsTrustedServerSnapshot() {
|
||||
var partner=new PartnerClient.Partner(7L,PUBLIC_TENANT_ID,"服务端客户名","ACTIVE","SHIPPER",List.of("SHIPPER"));
|
||||
var address=new WarehouseClient.Address("CN","广东省","深圳市","宝安区","518000","示例路1号",null);
|
||||
var capability=new WarehouseClient.Capability("RECEIVING",true,java.time.LocalTime.of(16,0));
|
||||
var wh=new WarehouseClient.Detail(new WarehouseClient.Warehouse(8L,PUBLIC_TENANT_ID,"CN-SZX-01","深圳仓","DOMESTIC","CN","ACTIVE"),List.of(address),List.of(capability));
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(ApiResponse.success(partner));
|
||||
when(warehouses.active("token",PUBLIC_TENANT_ID,8)).thenReturn(ApiResponse.success(wh));
|
||||
var result=guard.validate(10001,request(7L,8L));
|
||||
assertThat(result.partner().partnerName()).isEqualTo("服务端客户名");
|
||||
assertThat(result.receiving().warehouse().warehouseName()).isEqualTo("深圳仓");
|
||||
}
|
||||
@Test
|
||||
void inactiveOrCrossTenantMasterDataIsRejected() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(ApiResponse.success(null));
|
||||
assertThatThrownBy(() -> guard.validate(10002,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("服务暂时不可用");
|
||||
}
|
||||
@Test
|
||||
void downstreamHttp200BusinessFailureKeepsBusinessCodeAndMessage() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(
|
||||
ApiResponse.<PartnerClient.Partner>failure(ResultCode.NOT_FOUND,"往来单位不存在",null,null));
|
||||
@MockBean private WarehouseClient warehouses;
|
||||
@Resource private OrderMasterDataGuard guard;
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
@Test
|
||||
void validatesWarehousesWithoutTreatingCustomerAsWarehousePartner() {
|
||||
when(warehouses.active("token", PUBLIC_TENANT_ID, 8L))
|
||||
.thenReturn(ApiResponse.success(warehouse(8L, "DOMESTIC", true)));
|
||||
|
||||
var result = guard.validate(20002L, request(8L, "PRIVATE", null));
|
||||
|
||||
assertThat(result.receiving().warehouse().warehouseName()).isEqualTo("仓库8");
|
||||
verify(warehouses).active("token", PUBLIC_TENANT_ID, 8L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void persistedCustomerMustMatchAuthenticatedEnterprise() {
|
||||
assertThatThrownBy(() -> guard.validatePersisted(20002L, 30003L, 8L, null, "PRIVATE"))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessage("往来单位不存在")
|
||||
.hasMessage("订单客户必须是当前登录企业")
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.NOT_FOUND);
|
||||
verifyNoInteractions(warehouses);
|
||||
.isEqualTo(ResultCode.FORBIDDEN);
|
||||
}
|
||||
@Test
|
||||
void masterDataResponseWithNullElementReturnsControlledBusinessError() {
|
||||
var partner=new PartnerClient.Partner(7L,PUBLIC_TENANT_ID,"服务端客户名","ACTIVE","SHIPPER",List.of("SHIPPER"));
|
||||
var wh=new WarehouseClient.Detail(new WarehouseClient.Warehouse(8L,PUBLIC_TENANT_ID,"CN-SZX-01","深圳仓","DOMESTIC","CN","ACTIVE"),
|
||||
Collections.singletonList(null), Collections.singletonList(null));
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(ApiResponse.success(partner));
|
||||
when(warehouses.active("token",PUBLIC_TENANT_ID,8)).thenReturn(ApiResponse.success(wh));
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.VALIDATION_FAILED);
|
||||
@Test
|
||||
void customerTenantCanUsePublicDomesticReceivingWarehouse() {
|
||||
when(warehouses.active("token", PUBLIC_TENANT_ID, 8L))
|
||||
.thenReturn(ApiResponse.success(warehouse(8L, "DOMESTIC", true)));
|
||||
|
||||
guard.validate(20002L, request(8L, "PRIVATE", null));
|
||||
|
||||
verify(warehouses).active("token", PUBLIC_TENANT_ID, 8L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void masterDataResponseMissingSnapshotNameIsServiceUnavailable() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(ApiResponse.success(new PartnerClient.Partner(7L,PUBLIC_TENANT_ID,null,"ACTIVE","SHIPPER",List.of("SHIPPER"))));
|
||||
void destinationWarehouseTypeMustMatchDestinationType() {
|
||||
when(warehouses.active("token", PUBLIC_TENANT_ID, 8L))
|
||||
.thenReturn(ApiResponse.success(warehouse(8L, "DOMESTIC", true)));
|
||||
when(warehouses.active("token", PUBLIC_TENANT_ID, 9L))
|
||||
.thenReturn(ApiResponse.success(warehouse(9L, "OVERSEAS", false)));
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.SERVICE_UNAVAILABLE);
|
||||
verifyNoInteractions(warehouses);
|
||||
}
|
||||
@Test
|
||||
void downstreamNonFeignRuntimeExceptionMapsToServiceUnavailable() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenThrow(new IllegalStateException("解码失败"));
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.SERVICE_UNAVAILABLE);
|
||||
}
|
||||
@Test
|
||||
void downstreamForbiddenMapsToServiceUnavailable() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenThrow(feign(403));
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.SERVICE_UNAVAILABLE);
|
||||
}
|
||||
@Test
|
||||
void downstreamHttpNotFoundReturnsPlatformPartnerUnavailableMessage() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenThrow(feign(404));
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessage("平台往来单位不存在或不可用")
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.NOT_FOUND);
|
||||
}
|
||||
@Test
|
||||
void wrappedDownstreamHttpConflictMapsToServiceUnavailable() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenThrow(new IllegalStateException("wrapped", feign(409)));
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.SERVICE_UNAVAILABLE);
|
||||
}
|
||||
@Test
|
||||
void downstreamServerErrorMapsToServiceUnavailable() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenThrow(feign(500));
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.SERVICE_UNAVAILABLE);
|
||||
}
|
||||
@Test
|
||||
void inactiveMasterDataInSuccessfulResponseMapsToConflict() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7))
|
||||
.thenReturn(ApiResponse.success(new PartnerClient.Partner(7L,PUBLIC_TENANT_ID,"客户","INACTIVE","SHIPPER",List.of("SHIPPER"))));
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.CONFLICT);
|
||||
}
|
||||
@Test
|
||||
void partnerWithoutShipperTypeIsRejected() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(ApiResponse.success(
|
||||
new PartnerClient.Partner(7L,PUBLIC_TENANT_ID,"收货单位","ACTIVE","CONSIGNEE",List.of("CONSIGNEE"))));
|
||||
|
||||
assertThatThrownBy(() -> guard.validate(10001,request(7L,8L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(exception -> ((BizException) exception).getResultCode())
|
||||
.isEqualTo(ResultCode.VALIDATION_FAILED);
|
||||
verifyNoInteractions(warehouses);
|
||||
}
|
||||
@Test
|
||||
void customerTenantCanUseDomesticWarehouseFromPublicTenant() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(ApiResponse.success(
|
||||
new PartnerClient.Partner(7L,PUBLIC_TENANT_ID,"客户","ACTIVE","SHIPPER",List.of("SHIPPER"))));
|
||||
when(warehouses.active("token",PUBLIC_TENANT_ID,8)).thenReturn(ApiResponse.success(
|
||||
warehouse(8L,"DOMESTIC",true)));
|
||||
|
||||
guard.validate(20002,request(7L,8L));
|
||||
|
||||
verify(warehouses).active("token",PUBLIC_TENANT_ID,8);
|
||||
}
|
||||
@Test
|
||||
void customersAAndBUseTheSamePlatformWarehouseAndPartner() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(ApiResponse.success(
|
||||
new PartnerClient.Partner(7L,PUBLIC_TENANT_ID,"平台共享单位","ACTIVE","SHIPPER",List.of("SHIPPER"))));
|
||||
when(warehouses.active("token",PUBLIC_TENANT_ID,8)).thenReturn(ApiResponse.success(
|
||||
warehouse(8L,"DOMESTIC",true)));
|
||||
|
||||
guard.validate(20002,request(7L,8L));
|
||||
guard.validate(30003,request(7L,8L));
|
||||
|
||||
verify(partners,times(2)).active("token",PUBLIC_TENANT_ID,7);
|
||||
verify(warehouses,times(2)).active("token",PUBLIC_TENANT_ID,8);
|
||||
}
|
||||
@Test
|
||||
void orderWithoutPartnerUsesPublicWarehouseWithoutPartnerLookup() {
|
||||
when(warehouses.active("token",PUBLIC_TENANT_ID,8)).thenReturn(ApiResponse.success(
|
||||
warehouse(8L,"DOMESTIC",true)));
|
||||
|
||||
var result=guard
|
||||
.validate(20002,request(null,8L));
|
||||
|
||||
assertThat(result.partner()).isNull();
|
||||
verifyNoInteractions(partners);
|
||||
verify(warehouses).active("token",PUBLIC_TENANT_ID,8);
|
||||
}
|
||||
@Test
|
||||
void fbaDestinationMustReferenceMatchingPublicWarehouse() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(ApiResponse.success(
|
||||
new PartnerClient.Partner(7L,PUBLIC_TENANT_ID,"客户","ACTIVE","SHIPPER",List.of("SHIPPER"))));
|
||||
when(warehouses.active("token",PUBLIC_TENANT_ID,8)).thenReturn(ApiResponse.success(
|
||||
warehouse(8L,"DOMESTIC",true)));
|
||||
when(warehouses.active("token",PUBLIC_TENANT_ID,9)).thenReturn(ApiResponse.success(
|
||||
warehouse(9L,"OVERSEAS",false)));
|
||||
|
||||
assertThatThrownBy(() -> guard
|
||||
.validate(20002,request(7L,8L,"FBA",9L)))
|
||||
assertThatThrownBy(() -> guard.validate(20002L, request(8L, "FBA", 9L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("目的仓库类型必须为 FBA");
|
||||
}
|
||||
@Test
|
||||
void privateDestinationCannotReferencePublicWarehouse() {
|
||||
when(partners.active("token",PUBLIC_TENANT_ID,7)).thenReturn(ApiResponse.success(
|
||||
new PartnerClient.Partner(7L,PUBLIC_TENANT_ID,"客户","ACTIVE","SHIPPER",List.of("SHIPPER"))));
|
||||
when(warehouses.active("token",PUBLIC_TENANT_ID,8)).thenReturn(ApiResponse.success(
|
||||
warehouse(8L,"DOMESTIC",true)));
|
||||
|
||||
assertThatThrownBy(() -> guard
|
||||
.validate(20002,request(7L,8L,"PRIVATE",9L)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("私人地址不能引用公共仓库");
|
||||
verify(warehouses,never()).active("token",PUBLIC_TENANT_ID,9);
|
||||
private OrderRequests.SaveRequest request(long receivingWarehouseId, String destinationType,
|
||||
Long destinationWarehouseId) {
|
||||
var party = new OrderRequests.Party("公司", "联系人", "13800138000", null,
|
||||
"CN", null, "深圳", null, "地址", null);
|
||||
var cargo = new OrderRequests.Cargo("货物", null, "CARTON", 1, BigDecimal.ONE, BigDecimal.ONE,
|
||||
null, null, null, null, null, false, null, null, null, null, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null, null);
|
||||
return new OrderRequests.SaveRequest(null, "当前企业", "SEA", null, "CN", destinationWarehouseId,
|
||||
"目的仓", null, null, party, party, List.of(cargo), "PICKUP", receivingWarehouseId,
|
||||
"收货仓", "CH", "渠道", null, null, "BUY_DECLARATION", null, "LCL", false,
|
||||
destinationType, null, null, null);
|
||||
}
|
||||
private FeignException feign(int status) {
|
||||
Request request = Request.create(Request.HttpMethod.GET, "http://warehouse-service/internal/test",
|
||||
Map.of(), null, StandardCharsets.UTF_8, null);
|
||||
Response response = Response.builder().status(status).reason("test").request(request)
|
||||
.headers(Map.of()).build();
|
||||
return FeignException.errorStatus("masterData", response);
|
||||
}
|
||||
private OrderRequests.SaveRequest request(Long partner,Long warehouse) {
|
||||
return request(partner,warehouse,"PRIVATE",null);
|
||||
}
|
||||
private OrderRequests.SaveRequest request(Long partner,Long warehouse,String destinationType,Long destinationWarehouseId) {
|
||||
var party=new OrderRequests.Party("公司","联系人","13800138000",null,"CN",null,"深圳",null,"地址",null);
|
||||
var cargo=new OrderRequests.Cargo("货物",null,"CARTON",1,BigDecimal.ONE,BigDecimal.ONE,
|
||||
null,null,null,null,null,false,null,null,null,null,null,null,null,null,null,null,null,null,null,
|
||||
null,null,null,null,null,null);
|
||||
return new OrderRequests.SaveRequest(partner,"不可信客户名","SEA",null,"CN",destinationWarehouseId,"私人地址",null,null,party,party,List.of(cargo),"PICKUP",warehouse,"不可信收货仓","CH","渠道",null,null,"BUY_DECLARATION",null,"LCL",false,destinationType,null,null,null);
|
||||
}
|
||||
private WarehouseClient.Detail warehouse(long id,String type,boolean receiving) {
|
||||
var value=new WarehouseClient.Warehouse(id,PUBLIC_TENANT_ID,"WH-"+id,"仓库"+id,type,"CN","ACTIVE");
|
||||
var address=new WarehouseClient.Address("CN","广东省","深圳市",null,null,"示例地址",null);
|
||||
var capabilities=receiving
|
||||
? List.of(new WarehouseClient.Capability("RECEIVING",true,null))
|
||||
|
||||
private WarehouseClient.Detail warehouse(long id, String type, boolean receiving) {
|
||||
var value = new WarehouseClient.Warehouse(id, PUBLIC_TENANT_ID, "WH-" + id, "仓库" + id,
|
||||
type, "CN", "ACTIVE");
|
||||
var address = new WarehouseClient.Address("CN", "广东省", "深圳市", null, null, "示例地址", null);
|
||||
var capabilities = receiving
|
||||
? List.of(new WarehouseClient.Capability("RECEIVING", true, null))
|
||||
: List.<WarehouseClient.Capability>of();
|
||||
return new WarehouseClient.Detail(value,List.of(address),capabilities);
|
||||
return new WarehouseClient.Detail(value, List.of(address), capabilities);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user