优化
This commit is contained in:
@@ -202,7 +202,7 @@ public class FbaPricingRepository {
|
|||||||
LambdaUpdateWrapper<InboundPricingEntity> update = new LambdaUpdateWrapper<InboundPricingEntity>()
|
LambdaUpdateWrapper<InboundPricingEntity> update = new LambdaUpdateWrapper<InboundPricingEntity>()
|
||||||
.eq(InboundPricingEntity::getTenantId, inbound.getTenantId())
|
.eq(InboundPricingEntity::getTenantId, inbound.getTenantId())
|
||||||
.eq(InboundPricingEntity::getId, inbound.getId())
|
.eq(InboundPricingEntity::getId, inbound.getId())
|
||||||
.in(InboundPricingEntity::getFeeStatus, List.of("UNPRICED", "CALCULATED"))
|
.in(InboundPricingEntity::getFeeStatus, List.of("UNPRICED", "CALCULATED", "VOIDED"))
|
||||||
.set(InboundPricingEntity::getChannelCode, channelCode)
|
.set(InboundPricingEntity::getChannelCode, channelCode)
|
||||||
.set(InboundPricingEntity::getChannelName, channelName)
|
.set(InboundPricingEntity::getChannelName, channelName)
|
||||||
.set(InboundPricingEntity::getFeeStatus, "UNPRICED")
|
.set(InboundPricingEntity::getFeeStatus, "UNPRICED")
|
||||||
|
|||||||
+2
-1
@@ -129,7 +129,8 @@ public class OrderChannelChangePricingService {
|
|||||||
|| feeItems.findPublishedFreight(inbound.getTenantId(), inbound.getId()) != null) {
|
|| feeItems.findPublishedFreight(inbound.getTenantId(), inbound.getId()) != null) {
|
||||||
throw conflict("费用已确认或已发布,渠道不可变更;请先按费用作废流程处理");
|
throw conflict("费用已确认或已发布,渠道不可变更;请先按费用作废流程处理");
|
||||||
}
|
}
|
||||||
if (!"UNPRICED".equals(inbound.getFeeStatus()) && !"CALCULATED".equals(inbound.getFeeStatus())) {
|
if (!"UNPRICED".equals(inbound.getFeeStatus()) && !"CALCULATED".equals(inbound.getFeeStatus())
|
||||||
|
&& !"VOIDED".equals(inbound.getFeeStatus())) {
|
||||||
throw conflict("当前费用状态不可逆,渠道不可变更");
|
throw conflict("当前费用状态不可逆,渠道不可变更");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ paths:
|
|||||||
仅供 Order 在渠道变更成功后调用。tenantId + orderId + orderVersion 构成幂等边界;
|
仅供 Order 在渠道变更成功后调用。tenantId + orderId + orderVersion 构成幂等边界;
|
||||||
旧版本重放不会覆盖新版本。只将 CALCULATED 费用及草稿运费标记为 SUPERSEDED,
|
旧版本重放不会覆盖新版本。只将 CALCULATED 费用及草稿运费标记为 SUPERSEDED,
|
||||||
入库单恢复 UNPRICED 并可重新计价;实际净重、实际体积和测量审核事实保持不变。
|
入库单恢复 UNPRICED 并可重新计价;实际净重、实际体积和测量审核事实保持不变。
|
||||||
已确认、已发送或已发布费用一律拒绝,不能由本命令覆盖。
|
已确认、已发送或已发布费用一律拒绝,不能由本命令覆盖;费用正式作废为 VOIDED 后可重新计价。
|
||||||
security:
|
security:
|
||||||
- internalServiceToken: []
|
- internalServiceToken: []
|
||||||
requestBody:
|
requestBody:
|
||||||
@@ -1066,7 +1066,7 @@ components:
|
|||||||
orderVersion: {type: integer, format: int64}
|
orderVersion: {type: integer, format: int64}
|
||||||
channelCode: {type: string}
|
channelCode: {type: string}
|
||||||
priceBookVersionId: {type: integer, format: int64, nullable: true}
|
priceBookVersionId: {type: integer, format: int64, nullable: true}
|
||||||
feeStatus: {type: string, enum: [UNPRICED, CALCULATED]}
|
feeStatus: {type: string, enum: [UNPRICED, CALCULATED, VOIDED]}
|
||||||
calculatedFeeWillBeInvalidated: {type: boolean}
|
calculatedFeeWillBeInvalidated: {type: boolean}
|
||||||
invalidatedFeeId: {type: integer, format: int64, nullable: true}
|
invalidatedFeeId: {type: integer, format: int64, nullable: true}
|
||||||
UnifiedMainStatus:
|
UnifiedMainStatus:
|
||||||
|
|||||||
@@ -218,6 +218,8 @@ paths:
|
|||||||
/internal/firstleg/v1/pricing/order-channel-changes/validate,两个服务均失败关闭。
|
/internal/firstleg/v1/pricing/order-channel-changes/validate,两个服务均失败关闭。
|
||||||
国内收货仓或中转仓如需变化必须重新下单。成功后通过 ORDER_DECLARATION_UPDATED_V1 Outbox
|
国内收货仓或中转仓如需变化必须重新下单。成功后通过 ORDER_DECLARATION_UPDATED_V1 Outbox
|
||||||
同步 Firstleg;消费者按 eventId 幂等、version 顺序刷新申报快照,不覆盖实测、箱码或已确认费用。
|
同步 Firstleg;消费者按 eventId 幂等、version 顺序刷新申报快照,不覆盖实测、箱码或已确认费用。
|
||||||
|
本次 changes 含渠道字段时,同版本 Outbox 还必须调用
|
||||||
|
/internal/firstleg/v1/pricing/order-channel-changes/apply,使未确认价格预估显式失效;普通申报更新不得调用。
|
||||||
parameters:
|
parameters:
|
||||||
- $ref: '#/components/parameters/UnifiedOrderId'
|
- $ref: '#/components/parameters/UnifiedOrderId'
|
||||||
- $ref: '#/components/parameters/UnifiedTenantId'
|
- $ref: '#/components/parameters/UnifiedTenantId'
|
||||||
|
|||||||
+6
-1
@@ -51,7 +51,8 @@ class OrderDeclarationUpdateContractTest {
|
|||||||
assertThat(map(row.get("actualVolumeCbm")).get("description").toString()).contains("仅 Firstleg 实测");
|
assertThat(map(row.get("actualVolumeCbm")).get("description").toString()).contains("仅 Firstleg 实测");
|
||||||
assertThat(source).contains("ORDER_DECLARATION_UPDATED_V1", "platform:order:declaration:edit", "A0409",
|
assertThat(source).contains("ORDER_DECLARATION_UPDATED_V1", "platform:order:declaration:edit", "A0409",
|
||||||
"/internal/firstleg/v1/inbounds/order-channel-changes/validate",
|
"/internal/firstleg/v1/inbounds/order-channel-changes/validate",
|
||||||
"/internal/firstleg/v1/pricing/order-channel-changes/validate");
|
"/internal/firstleg/v1/pricing/order-channel-changes/validate",
|
||||||
|
"/internal/firstleg/v1/pricing/order-channel-changes/apply");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -60,10 +61,14 @@ class OrderDeclarationUpdateContractTest {
|
|||||||
String.class, FirstlegInboundClient.OrderChannelChangeValidationRequest.class);
|
String.class, FirstlegInboundClient.OrderChannelChangeValidationRequest.class);
|
||||||
var pricing = FirstlegPricingClient.class.getDeclaredMethod("validateOrderChannelChange",
|
var pricing = FirstlegPricingClient.class.getDeclaredMethod("validateOrderChannelChange",
|
||||||
String.class, FirstlegPricingClient.OrderChannelChangeRequest.class);
|
String.class, FirstlegPricingClient.OrderChannelChangeRequest.class);
|
||||||
|
var applyPricing = FirstlegPricingClient.class.getDeclaredMethod("applyOrderChannelChange",
|
||||||
|
String.class, FirstlegPricingClient.OrderChannelChangeRequest.class);
|
||||||
assertThat(fulfillment.getAnnotation(PostMapping.class).value())
|
assertThat(fulfillment.getAnnotation(PostMapping.class).value())
|
||||||
.containsExactly("/order-channel-changes/validate");
|
.containsExactly("/order-channel-changes/validate");
|
||||||
assertThat(pricing.getAnnotation(PostMapping.class).value())
|
assertThat(pricing.getAnnotation(PostMapping.class).value())
|
||||||
.containsExactly("/order-channel-changes/validate");
|
.containsExactly("/order-channel-changes/validate");
|
||||||
|
assertThat(applyPricing.getAnnotation(PostMapping.class).value())
|
||||||
|
.containsExactly("/order-channel-changes/apply");
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|||||||
@@ -171,6 +171,25 @@ class OrderInboundOutboxPublisherTest {
|
|||||||
verify(fixture.repository).markOutboxPublished(eq(11L), eq(41L), any(LocalDateTime.class));
|
verify(fixture.repository).markOutboxPublished(eq(11L), eq(41L), any(LocalDateTime.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void channelPricingApplyFailureKeepsOutboxPendingAndDoesNotAdvanceFulfillmentSnapshot() {
|
||||||
|
String payload = "{\"schemaVersion\":1,\"eventId\":\"evt-3\",\"tenantId\":11,"
|
||||||
|
+ "\"orderId\":21,\"orderNo\":\"ORD-21\",\"inboundCode\":\"RK-21\","
|
||||||
|
+ "\"version\":4,\"operatorId\":7,\"channelCode\":\"SEA\","
|
||||||
|
+ "\"channelName\":\"海运\",\"channelChanged\":true,\"cargoes\":[],"
|
||||||
|
+ "\"changes\":[{\"field\":\"channelName\",\"beforeValue\":\"旧渠道\",\"afterValue\":\"海运\"}]}";
|
||||||
|
Fixture fixture = fixture(event("ORDER_DECLARATION_UPDATED_V1", 11L, 21L, payload));
|
||||||
|
when(fixture.pricingClient.applyOrderChannelChange(eq("internal-token"), any())).thenReturn(
|
||||||
|
ApiResponse.failure(com.baiyue.common.core.api.ResultCode.CONFLICT,
|
||||||
|
"费用已确认或已发布,渠道不可变更", null, null));
|
||||||
|
|
||||||
|
fixture.publisher.publishApprovedOrders();
|
||||||
|
|
||||||
|
verify(fixture.repository).markOutboxRetry(eq(11L), eq(41L), any(LocalDateTime.class));
|
||||||
|
verify(fixture.client, never()).updateDeclaration(any(), any());
|
||||||
|
verify(fixture.repository, never()).markOutboxPublished(anyLong(), anyLong(), any());
|
||||||
|
}
|
||||||
|
|
||||||
private Fixture fixture(OutboxEventEntity event) {
|
private Fixture fixture(OutboxEventEntity event) {
|
||||||
return fixture(event, "BUY_DECLARATION");
|
return fixture(event, "BUY_DECLARATION");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user