fix: carry package count into inbound snapshot

This commit is contained in:
2026-08-08 10:16:33 +08:00
parent 71fde99ceb
commit dd8147c535
9 changed files with 68 additions and 11 deletions
@@ -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);