fix: carry package count into inbound snapshot
This commit is contained in:
+2
-1
@@ -55,7 +55,8 @@ public class InternalInboundOrderController {
|
||||
if (command.tenantId() <= 0 || command.orderId() <= 0 || command.warehouseId() == null
|
||||
|| command.warehouseId() <= 0 || command.customerName() == null || command.customerName().isBlank()
|
||||
|| command.inboundCode() == null || command.inboundCode().isBlank()
|
||||
|| command.inboundCode().length() > 40) {
|
||||
|| command.inboundCode().length() > 40
|
||||
|| command.totalPackageCount() != null && command.totalPackageCount() < 1) {
|
||||
throw new BizException(ResultCode.BAD_REQUEST, "订单入库快照不完整");
|
||||
}
|
||||
return ApiResponse.success(service.createFromApprovedOrder(command));
|
||||
|
||||
@@ -30,8 +30,25 @@ public record OrderApprovedInboundCommand(
|
||||
String destinationName,
|
||||
String publicRemark,
|
||||
String expressCompanyName,
|
||||
String expressTrackingNo
|
||||
String expressTrackingNo,
|
||||
Integer totalPackageCount
|
||||
) {
|
||||
/** 兼容尚未携带订单总箱数的历史事件。 */
|
||||
public OrderApprovedInboundCommand(
|
||||
long tenantId, long orderId, String orderNo, String inboundCode, Long customerId, String customerName,
|
||||
Long warehouseId, String warehouseName, Long deliveryWarehouseId, String deliveryWarehouseName,
|
||||
LocalDateTime expectedArrivalAt, String businessType, String channelCode, String channelName,
|
||||
Long carrierId, String carrierName, String taxMode, String pricingTaxMode, String containerMode,
|
||||
Boolean customsInspection, String destinationType, Long destinationWarehouseId, String destinationCode,
|
||||
String destinationName, String publicRemark, String expressCompanyName, String expressTrackingNo
|
||||
) {
|
||||
this(tenantId, orderId, orderNo, inboundCode, customerId, customerName, warehouseId, warehouseName,
|
||||
deliveryWarehouseId, deliveryWarehouseName, expectedArrivalAt, businessType, channelCode, channelName,
|
||||
carrierId, carrierName, taxMode, pricingTaxMode, containerMode, customsInspection, destinationType,
|
||||
destinationWarehouseId, destinationCode, destinationName, publicRemark, expressCompanyName,
|
||||
expressTrackingNo, null);
|
||||
}
|
||||
|
||||
/** 兼容未携带报价包税维度的历史调用方。 */
|
||||
public OrderApprovedInboundCommand(
|
||||
long tenantId, long orderId, String orderNo, String inboundCode, Long customerId, String customerName,
|
||||
@@ -45,6 +62,6 @@ public record OrderApprovedInboundCommand(
|
||||
deliveryWarehouseId, deliveryWarehouseName, expectedArrivalAt, businessType, channelCode, channelName,
|
||||
carrierId, carrierName, taxMode, null, containerMode, customsInspection, destinationType,
|
||||
destinationWarehouseId, destinationCode, destinationName, publicRemark, expressCompanyName,
|
||||
expressTrackingNo);
|
||||
expressTrackingNo, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ public class InboundOrderCreationService {
|
||||
inbound.setDestinationName(command.destinationName());
|
||||
inbound.setExpressCompanyName(command.expressCompanyName());
|
||||
inbound.setExpressTrackingNo(command.expressTrackingNo());
|
||||
inbound.setTotalPackageCount(command.totalPackageCount());
|
||||
inbound.setPublicRemark(command.publicRemark());
|
||||
inbound.setCreatedBy(0L);
|
||||
inbound.setUpdatedBy(0L);
|
||||
|
||||
+2
-1
@@ -53,6 +53,7 @@ class InboundOrderCreationServiceTest {
|
||||
assertThat(inboundCaptor.getValue().getCarrierId()).isNull();
|
||||
assertThat(inboundCaptor.getValue().getTaxMode()).isEqualTo("BUY_DECLARATION");
|
||||
assertThat(inboundCaptor.getValue().getPricingTaxMode()).isEqualTo("TAX_EXCLUDED");
|
||||
assertThat(inboundCaptor.getValue().getTotalPackageCount()).isEqualTo(4);
|
||||
assertThat(createdId).isEqualTo(inboundCaptor.getValue().getId());
|
||||
assertThat(replayedId).isEqualTo(900L);
|
||||
}
|
||||
@@ -97,6 +98,6 @@ class InboundOrderCreationServiceTest {
|
||||
return new OrderApprovedInboundCommand(
|
||||
10001L, 77L, "FL-77", inboundCode, 7L, "测试客户", 9L, "义乌仓",
|
||||
null, null, null, "FBA", "AIR", "空运", null, null,
|
||||
"BUY_DECLARATION", "TAX_EXCLUDED", null, null, null, null, null, null, null, null, null);
|
||||
"BUY_DECLARATION", "TAX_EXCLUDED", null, null, null, null, null, null, null, null, null, 4);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ public interface FirstlegInboundClient {
|
||||
Long carrierId, String carrierName, String taxMode, String pricingTaxMode, String containerMode,
|
||||
Boolean customsInspection, String destinationType, Long destinationWarehouseId,
|
||||
String destinationCode, String destinationName, String publicRemark,
|
||||
String expressCompanyName, String expressTrackingNo
|
||||
String expressCompanyName, String expressTrackingNo, Integer totalPackageCount
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,7 +425,7 @@ public class OrderApplicationService {
|
||||
event.setEventType(target == OrderStatus.APPROVED ? "FIRST_LEG_ORDER_APPROVED" : "FIRST_LEG_ORDER_CANCELLED");
|
||||
try {
|
||||
event.setPayloadJson(target == OrderStatus.APPROVED
|
||||
? json.writeValueAsString(inboundCommand(order))
|
||||
? json.writeValueAsString(inboundCommand(order, totalPackageCount(order)))
|
||||
: json.writeValueAsString(Map.of("tenantId", order.getTenantId(), "orderId", order.getId(),
|
||||
"orderNo", order.getOrderNo(), "status", target.name())));
|
||||
} catch (JsonProcessingException exception) { throw new BizException("Cannot serialize order event"); }
|
||||
@@ -433,6 +433,10 @@ public class OrderApplicationService {
|
||||
repository.insertOutbox(event);
|
||||
}
|
||||
static FirstlegInboundClient.OrderApprovedInboundCommand inboundCommand(OrderEntity order) {
|
||||
return inboundCommand(order, null);
|
||||
}
|
||||
static FirstlegInboundClient.OrderApprovedInboundCommand inboundCommand(OrderEntity order,
|
||||
Integer totalPackageCount) {
|
||||
return new FirstlegInboundClient.OrderApprovedInboundCommand(
|
||||
order.getTenantId(), order.getId(), order.getOrderNo(), order.getInboundCode(),
|
||||
order.getCustomerId(), order.getCustomerName(),
|
||||
@@ -443,7 +447,18 @@ public class OrderApplicationService {
|
||||
order.getTaxMode(), order.getPricingTaxMode(),
|
||||
order.getContainerMode(), order.getCustomsInspection(), order.getDestinationType(),
|
||||
order.getDestinationWarehouseId(), order.getAmazonWarehouseCode(), order.getDestinationWarehouseName(),
|
||||
order.getCustomerRemark(), order.getExpressCompany(), order.getExpressTrackingNo());
|
||||
order.getCustomerRemark(), order.getExpressCompany(), order.getExpressTrackingNo(), totalPackageCount);
|
||||
}
|
||||
private int totalPackageCount(OrderEntity order) {
|
||||
long total = repository.findCargo(order.getTenantId(), order.getId()).stream()
|
||||
.map(com.baiyue.order.entity.OrderCargoEntity::getPackageCount)
|
||||
.filter(java.util.Objects::nonNull)
|
||||
.mapToLong(Integer::longValue)
|
||||
.sum();
|
||||
if (total < 1 || total > 1_000_000) {
|
||||
throw new BizException("订单货物总箱数必须为1至1000000箱");
|
||||
}
|
||||
return (int) total;
|
||||
}
|
||||
private String nextNo(long orderId) {
|
||||
return "FL" + orderId;
|
||||
|
||||
@@ -55,7 +55,7 @@ public class OrderInboundOutboxPublisher {
|
||||
failPermanently(event, "order snapshot is unavailable");
|
||||
continue;
|
||||
}
|
||||
command = OrderApplicationService.inboundCommand(order);
|
||||
command = OrderApplicationService.inboundCommand(order, totalPackageCount(order));
|
||||
if (incomplete(command)) {
|
||||
failPermanently(event, "rebuilt order snapshot is incomplete");
|
||||
continue;
|
||||
@@ -77,7 +77,17 @@ public class OrderInboundOutboxPublisher {
|
||||
return command.orderNo() == null || command.orderNo().isBlank()
|
||||
|| command.inboundCode() == null || command.inboundCode().isBlank()
|
||||
|| command.customerName() == null || command.customerName().isBlank()
|
||||
|| command.warehouseId() == null || command.warehouseId() <= 0;
|
||||
|| command.warehouseId() == null || command.warehouseId() <= 0
|
||||
|| command.totalPackageCount() == null || command.totalPackageCount() < 1;
|
||||
}
|
||||
|
||||
private int totalPackageCount(com.baiyue.order.entity.OrderEntity order) {
|
||||
long total = repository.findCargo(order.getTenantId(), order.getId()).stream()
|
||||
.map(com.baiyue.order.entity.OrderCargoEntity::getPackageCount)
|
||||
.filter(java.util.Objects::nonNull)
|
||||
.mapToLong(Integer::longValue)
|
||||
.sum();
|
||||
return total > 0 && total <= 1_000_000 ? (int) total : 0;
|
||||
}
|
||||
|
||||
private void failPermanently(OutboxEventEntity event, String reason) {
|
||||
|
||||
@@ -217,13 +217,17 @@ class OrderApplicationServiceStateTest {
|
||||
order.setInboundCode("RK-1");
|
||||
when(repository.findOwned(10001L, 1L)).thenReturn(order);
|
||||
when(repository.saveOrder(10001L, order)).thenReturn(1);
|
||||
OrderCargoEntity cargo = new OrderCargoEntity();
|
||||
cargo.setPackageCount(4);
|
||||
when(repository.findCargo(10001L, 1L)).thenReturn(List.of(cargo));
|
||||
|
||||
service(repository, mock(OrderEligibilityGuard.class), mock(OrderMasterDataGuard.class))
|
||||
.transit(10001L, 2L, "u", 1L, OrderStatus.APPROVED, null);
|
||||
|
||||
assertThat(order.getStatus()).isEqualTo(OrderStatus.APPROVED);
|
||||
verify(repository).insertOutbox(argThat(event -> event.getPayloadJson().contains("\"inboundCode\":\"RK-1\"")
|
||||
&& event.getPayloadJson().contains("\"carrierId\":null")));
|
||||
&& event.getPayloadJson().contains("\"carrierId\":null")
|
||||
&& event.getPayloadJson().contains("\"totalPackageCount\":4")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -290,10 +294,11 @@ class OrderApplicationServiceStateTest {
|
||||
order.setTaxMode("BUY_DECLARATION");
|
||||
order.setPricingTaxMode("TAX_EXCLUDED");
|
||||
|
||||
var command = OrderApplicationService.inboundCommand(order);
|
||||
var command = OrderApplicationService.inboundCommand(order, 4);
|
||||
|
||||
assertThat(command.taxMode()).isEqualTo("BUY_DECLARATION");
|
||||
assertThat(command.pricingTaxMode()).isEqualTo("TAX_EXCLUDED");
|
||||
assertThat(command.totalPackageCount()).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -36,6 +36,7 @@ class OrderInboundOutboxPublisherTest {
|
||||
org.assertj.core.api.Assertions.assertThat(command.getValue().warehouseId()).isEqualTo(31L);
|
||||
org.assertj.core.api.Assertions.assertThat(command.getValue().taxMode()).isEqualTo("BUY_DECLARATION");
|
||||
org.assertj.core.api.Assertions.assertThat(command.getValue().pricingTaxMode()).isEqualTo("TAX_EXCLUDED");
|
||||
org.assertj.core.api.Assertions.assertThat(command.getValue().totalPackageCount()).isEqualTo(4);
|
||||
verify(fixture.repository).markOutboxPublished(eq(11L), eq(41L), any(LocalDateTime.class));
|
||||
verify(fixture.repository, never()).markOutboxRetry(anyLong(), anyLong(), any());
|
||||
verify(fixture.repository, never()).markOutboxFailed(any(), anyLong());
|
||||
@@ -114,6 +115,12 @@ class OrderInboundOutboxPublisherTest {
|
||||
order.setTaxMode("BUY_DECLARATION");
|
||||
order.setPricingTaxMode("TAX_EXCLUDED");
|
||||
when(repository.findOwned(event.getTenantId(), event.getAggregateId())).thenReturn(order);
|
||||
var firstCargo = new com.baiyue.order.entity.OrderCargoEntity();
|
||||
firstCargo.setPackageCount(1);
|
||||
var secondCargo = new com.baiyue.order.entity.OrderCargoEntity();
|
||||
secondCargo.setPackageCount(3);
|
||||
when(repository.findCargo(event.getTenantId(), event.getAggregateId()))
|
||||
.thenReturn(List.of(firstCargo, secondCargo));
|
||||
}
|
||||
OrderInboundOutboxPublisher publisher = new OrderInboundOutboxPublisher();
|
||||
ReflectionTestUtils.setField(publisher, "repository", repository);
|
||||
|
||||
Reference in New Issue
Block a user