fix(order): align FBA submit and fee confirmation
This commit is contained in:
@@ -38,7 +38,7 @@ public interface FirstlegUnifiedOrderClient {
|
||||
record BatchRequest(Long tenantId, List<Long> orderIds) {}
|
||||
record DetailRequest(long tenantId, long orderId) {}
|
||||
|
||||
record Summary(Inbound inbound, String mainStatus, String nextAction,
|
||||
record Summary(Inbound inbound, String mainStatus, String nextAction, Boolean customerFeeConfirmationRequired,
|
||||
Preload preload, Loading loading, Delivery delivery) {}
|
||||
record Detail(Summary summary, List<Timeline> timeline) {}
|
||||
record Inbound(Long id, Long tenantId, Long orderId, String orderNo, String inboundCode,
|
||||
|
||||
@@ -13,6 +13,7 @@ public final class UnifiedOrderResponse {
|
||||
|
||||
public record Row(
|
||||
Long orderId, Integer orderVersion, Long tenantId, String orderNo, String mainStatus, String nextAction,
|
||||
Boolean customerFeeConfirmationRequired,
|
||||
OrderRelationSummary relation,
|
||||
OrderStatus internalOrderStatus,
|
||||
Long customerId, String customerName, String channelCode, String channelName, Boolean channelChanged,
|
||||
|
||||
@@ -348,11 +348,11 @@ public class OrderApplicationService {
|
||||
"FBA orders require Amazon warehouse code, Shipment ID and Reference ID");
|
||||
}
|
||||
for (var cargo : cargoes) {
|
||||
if (!StringUtils.hasText(cargo.getSkuNo()) || !StringUtils.hasText(cargo.getUpcNo())
|
||||
if (!StringUtils.hasText(cargo.getSkuNo())
|
||||
|| !StringUtils.hasText(cargo.getShipmentId())
|
||||
|| !StringUtils.hasText(cargo.getReferenceId())) {
|
||||
throw new BizException(ResultCode.VALIDATION_FAILED,
|
||||
"FBA cargo requires SKU NO., UPC NO., Shipment ID and Reference ID.");
|
||||
"FBA cargo requires SKU NO., Shipment ID and Reference ID.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -387,10 +387,10 @@ public class OrderApplicationService {
|
||||
"FBA orders require Amazon warehouse code, Shipment ID and Reference ID");
|
||||
}
|
||||
for (var cargo : request.cargoes()) {
|
||||
if (!StringUtils.hasText(cargo.skuNo()) || !StringUtils.hasText(cargo.upcNo())
|
||||
if (!StringUtils.hasText(cargo.skuNo())
|
||||
|| !StringUtils.hasText(cargo.shipmentId()) || !StringUtils.hasText(cargo.referenceId())) {
|
||||
throw new BizException(ResultCode.VALIDATION_FAILED,
|
||||
"FBA cargo requires SKU NO., UPC NO., Shipment ID and Reference ID.");
|
||||
"FBA cargo requires SKU NO., Shipment ID and Reference ID.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,6 +316,7 @@ public class UnifiedOrderQueryService {
|
||||
String mainStatus = orderMainStatus(order.getStatus());
|
||||
return new UnifiedOrderResponse.Row(order.getId(), order.getVersion(), order.getTenantId(), order.getOrderNo(), mainStatus,
|
||||
order.getStatus() == OrderStatus.SUBMITTED ? "APPROVE_ORDER" : null,
|
||||
false,
|
||||
relation(order, childCounts),
|
||||
order.getStatus(), order.getCustomerId(), order.getCustomerName(),
|
||||
order.getChannelCode(), order.getChannelName(), Boolean.TRUE.equals(order.getChannelChanged()), order.getReceivingWarehouseId(), order.getReceivingWarehouseName(),
|
||||
@@ -337,7 +338,7 @@ public class UnifiedOrderQueryService {
|
||||
String mainStatus = pendingReview ? "PENDING_REVIEW" : summary.mainStatus();
|
||||
String nextAction = pendingReview ? "APPROVE_ORDER" : summary.nextAction();
|
||||
return new UnifiedOrderResponse.Row(order.getId(), order.getVersion(), order.getTenantId(), order.getOrderNo(),
|
||||
mainStatus, nextAction, relation(order, childCounts), order.getStatus(),
|
||||
mainStatus, nextAction, Boolean.TRUE.equals(summary.customerFeeConfirmationRequired()), relation(order, childCounts), order.getStatus(),
|
||||
order.getCustomerId(), order.getCustomerName(),
|
||||
order.getChannelCode(), order.getChannelName(), Boolean.TRUE.equals(order.getChannelChanged()), order.getReceivingWarehouseId(), order.getReceivingWarehouseName(),
|
||||
order.getDestinationWarehouseId(), order.getDestinationWarehouseName(), inbound.id(), inbound.version(), inbound.inboundCode(),
|
||||
@@ -366,7 +367,7 @@ public class UnifiedOrderQueryService {
|
||||
UnifiedOrderResponse.CoLoadGroupSummary coLoadGroup) {
|
||||
var inbound = summary.inbound();
|
||||
return new UnifiedOrderResponse.Row(inbound.orderId(), order == null ? null : order.getVersion(), inbound.tenantId(), inbound.orderNo(),
|
||||
summary.mainStatus(), summary.nextAction(), relation(order, childCounts),
|
||||
summary.mainStatus(), summary.nextAction(), Boolean.TRUE.equals(summary.customerFeeConfirmationRequired()), relation(order, childCounts),
|
||||
parseOrderStatus(inbound.orderStatusSnapshot()),
|
||||
inbound.customerId(), inbound.customerName(), inbound.channelCode(), inbound.channelName(),
|
||||
order != null && Boolean.TRUE.equals(order.getChannelChanged()), inbound.warehouseId(),
|
||||
|
||||
@@ -893,6 +893,7 @@ components:
|
||||
orderNo: {type: string}
|
||||
mainStatus: {$ref: '#/components/schemas/UnifiedMainStatus'}
|
||||
nextAction: {type: string, nullable: true}
|
||||
customerFeeConfirmationRequired: {type: boolean, description: Firstleg 已向客户发送最新费用且客户尚未确认时为 true}
|
||||
relation: {$ref: '#/components/schemas/UnifiedOrderRelation'}
|
||||
internalOrderStatus: {type: string, enum: [DRAFT, SUBMITTED, APPROVED, ACCEPTED, REJECTED, CANCELLED, PROCESSING, COMPLETED], nullable: true}
|
||||
customerId: {type: integer, format: int64, nullable: true}
|
||||
@@ -1289,7 +1290,7 @@ components:
|
||||
dangerousGoods: {type: boolean}
|
||||
woodenProduct: {type: boolean, description: 木制品权威判定快照;为 true 时订单 customsInspection 必须为 true}
|
||||
description: >-
|
||||
原型货物明细字段。FBA 货物的 skuNo、upcNo、shipmentId、referenceId 由服务端按每条货物校验;
|
||||
原型货物明细字段。FBA 货物的 skuNo、shipmentId、referenceId 由服务端按每条货物校验,upcNo 选填;
|
||||
productImageFileId 必须属于当前登录客户。一件代发中,相同 packingGroupNo 的多条 SKU 行属于同一批物理箱,物理箱数只计算一次。
|
||||
FirstLegOrderSummary:
|
||||
type: object
|
||||
|
||||
@@ -306,6 +306,30 @@ class OrderApplicationServiceStateTest {
|
||||
verify(repository).saveOrder(20002L, order);
|
||||
}
|
||||
|
||||
@Test
|
||||
void submittingFbaDraftKeepsUpcOptional() {
|
||||
OrderRepository repository = mock(OrderRepository.class);
|
||||
OrderEntity order = persistedDraft("SELF_EXPRESS", "FBA");
|
||||
order.setAmazonWarehouseCode("GEU2");
|
||||
order.setShipmentId("FBA19PS4C6SP");
|
||||
order.setReferenceId("2F6MA5QD");
|
||||
OrderCargoEntity cargo = completeCargo();
|
||||
cargo.setSkuNo("Shoes");
|
||||
cargo.setShipmentId("FBA19PS4C6SP");
|
||||
cargo.setReferenceId("2F6MA5QD");
|
||||
cargo.setUpcNo(null);
|
||||
when(repository.findOwned(20002L, 1L)).thenReturn(order);
|
||||
when(repository.findCargo(20002L, 1L)).thenReturn(List.of(cargo));
|
||||
when(repository.findParties(20002L, 1L)).thenReturn(List.of());
|
||||
when(repository.saveOrder(20002L, order)).thenReturn(1);
|
||||
|
||||
service(repository, mock(OrderEligibilityGuard.class), mock(OrderMasterDataGuard.class))
|
||||
.transit(20002L, 2L, "u", 1L, OrderStatus.SUBMITTED, null);
|
||||
|
||||
assertThat(order.getStatus()).isEqualTo(OrderStatus.SUBMITTED);
|
||||
verify(repository).saveOrder(20002L, order);
|
||||
}
|
||||
|
||||
@Test
|
||||
void submittingDraftPreparesInboundForWarehouseMeasurementBeforeReview() {
|
||||
OrderRepository repository = mock(OrderRepository.class);
|
||||
|
||||
@@ -683,6 +683,7 @@ class UnifiedOrderQueryServiceTest {
|
||||
assertThat(result.summary().mainStatus()).isEqualTo("LOADED");
|
||||
assertThat(result.summary().internalOrderStatus()).isEqualTo(OrderStatus.APPROVED);
|
||||
assertThat(result.summary().inboundId()).isEqualTo(88L);
|
||||
assertThat(result.summary().customerFeeConfirmationRequired()).isTrue();
|
||||
assertThat(result.summary().holdFlag()).isTrue();
|
||||
assertThat(result.summary().currentHoldReason()).isEqualTo("等待客户补充资料");
|
||||
ArgumentCaptor<FirstlegUnifiedOrderClient.DetailRequest> captor =
|
||||
@@ -934,7 +935,7 @@ class UnifiedOrderQueryServiceTest {
|
||||
when(inbound.chargeableWeightKg()).thenReturn(new BigDecimal("125.500"));
|
||||
when(inbound.createdAt()).thenReturn(LocalDateTime.of(2026, 8, 6, 10, 0));
|
||||
when(inbound.updatedAt()).thenReturn(LocalDateTime.of(2026, 8, 6, 11, 0));
|
||||
return new FirstlegUnifiedOrderClient.Summary(inbound, status, action,
|
||||
return new FirstlegUnifiedOrderClient.Summary(inbound, status, action, true,
|
||||
new FirstlegUnifiedOrderClient.Preload("PENDING", 1, 2, null),
|
||||
new FirstlegUnifiedOrderClient.Loading("IN_PROGRESS", 3, 3, 10, 5, 1, "SEAL-1", null), null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user