fix: complete order measurement downstream flow
This commit is contained in:
@@ -5,6 +5,8 @@ import org.springframework.cloud.openfeign.FeignClient;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
@@ -36,10 +38,21 @@ public interface OrderCargoClient {
|
||||
@RequestHeader("X-Internal-Service-Token") String token,
|
||||
@PathVariable long tenantId, @PathVariable long orderId);
|
||||
|
||||
@PutMapping("/{tenantId}/{orderId}/remarks")
|
||||
ApiResponse<RemarksUpdateResponse> updateRemarks(
|
||||
@RequestHeader("X-Internal-Service-Token") String token,
|
||||
@PathVariable long tenantId, @PathVariable long orderId,
|
||||
@RequestBody RemarksUpdateRequest request);
|
||||
|
||||
record MeasurementDeclarationSnapshot(
|
||||
String referenceId, BigDecimal originalGrossWeightKg,
|
||||
BigDecimal originalVolumeCbm, String defaultActualGoodsName) {}
|
||||
|
||||
record RemarksUpdateRequest(String internalRemark, String warehouseRemark,
|
||||
String customerServiceRemark, long operatorId) {}
|
||||
record RemarksUpdateResponse(int version, String customerRemark, String internalRemark,
|
||||
String warehouseRemark, String customerServiceRemark) {}
|
||||
|
||||
record CargoBinding(Long cargoId, Long orderId, Integer itemNo, String cargoName,
|
||||
Integer originalPackageCount, BigDecimal originalGrossWeightKg,
|
||||
BigDecimal originalVolumeCbm, String skuNo, String cargoNameEn,
|
||||
|
||||
+12
@@ -12,7 +12,9 @@ import com.baiyue.firstleg.service.InboundOrderCreationService;
|
||||
import com.baiyue.firstleg.service.InboundCartonLabelService;
|
||||
import com.baiyue.firstleg.service.UnifiedInboundQueryService;
|
||||
import com.baiyue.firstleg.service.OrderDeclarationSyncService;
|
||||
import com.baiyue.firstleg.service.OrderRemarksSyncService;
|
||||
import com.baiyue.firstleg.dto.OrderDeclarationSync;
|
||||
import com.baiyue.firstleg.dto.OrderRemarksSync;
|
||||
import com.baiyue.firstleg.dto.UnifiedInboundDetail;
|
||||
import com.baiyue.firstleg.dto.UnifiedInboundQuery;
|
||||
import com.baiyue.firstleg.dto.UnifiedInboundRequest;
|
||||
@@ -43,6 +45,8 @@ public class InternalInboundOrderController {
|
||||
private UnifiedInboundQueryService unifiedQueryService;
|
||||
@Resource
|
||||
private OrderDeclarationSyncService declarationSync;
|
||||
@Resource
|
||||
private OrderRemarksSyncService remarksSync;
|
||||
@Value("${baiyue.security.internal-service-token}")
|
||||
private String internalToken;
|
||||
private byte[] expectedToken;
|
||||
@@ -127,6 +131,14 @@ public class InternalInboundOrderController {
|
||||
return ApiResponse.success(null);
|
||||
}
|
||||
|
||||
@PostMapping("/order-remarks-updated")
|
||||
public ApiResponse<Integer> updateOrderRemarks(
|
||||
@RequestHeader(value = "X-Internal-Service-Token", required = false) String token,
|
||||
@Valid @RequestBody OrderRemarksSync.Command command) {
|
||||
requireToken(token);
|
||||
return ApiResponse.success(remarksSync.sync(command));
|
||||
}
|
||||
|
||||
@PostMapping("/unified-orders/query")
|
||||
public ApiResponse<PageResult<UnifiedInboundSummary>> unifiedPage(
|
||||
@RequestHeader(value = "X-Internal-Service-Token", required = false) String token,
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.baiyue.firstleg.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Positive;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
public final class OrderRemarksSync {
|
||||
private OrderRemarksSync() {
|
||||
}
|
||||
|
||||
public record Command(
|
||||
@Positive long tenantId,
|
||||
@Positive long orderId,
|
||||
@Size(max = 1000) String customerRemark,
|
||||
@Size(max = 1000) String internalRemark,
|
||||
@Size(max = 1000) String warehouseRemark,
|
||||
@Size(max = 1000) String customerServiceRemark,
|
||||
@NotNull @Positive Long operatorId,
|
||||
@Size(max = 128) String operatorName
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
package com.baiyue.firstleg.mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baiyue.firstleg.entity.LoadingPlanItemEntity; import org.apache.ibatis.annotations.*;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baiyue.firstleg.entity.LoadingPlanItemEntity; import org.apache.ibatis.annotations.*; import java.util.List;
|
||||
@Mapper public interface LoadingPlanItemMapper extends BaseMapper<LoadingPlanItemEntity> {
|
||||
@Update("""
|
||||
UPDATE fl_loading_plan_item SET deleted=1,removed_by=#{operatorId},removed_by_name=#{operatorName},
|
||||
@@ -30,4 +30,69 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baiyue.firstl
|
||||
@Param("customerServiceRemark") String customerServiceRemark,
|
||||
@Param("operatorId") long operatorId,
|
||||
@Param("operatorName") String operatorName);
|
||||
|
||||
@Select("""
|
||||
SELECT DISTINCT i.loading_plan_id
|
||||
FROM fl_loading_plan_item i
|
||||
JOIN fl_loading_plan p ON p.id=i.loading_plan_id AND p.plan_status IN ('EDITING','LOADING')
|
||||
WHERE i.account_id=#{tenantId} AND i.order_id=#{orderId} AND i.deleted=0 AND i.frozen_at IS NULL
|
||||
AND (#{excludedItemId} IS NULL OR i.id<>#{excludedItemId})
|
||||
AND NOT (i.customer_remark <=> #{customerRemark}
|
||||
AND i.internal_remark <=> #{internalRemark}
|
||||
AND i.warehouse_remark <=> #{warehouseRemark}
|
||||
AND i.customer_service_remark <=> #{customerServiceRemark})
|
||||
""")
|
||||
List<Long> findMutablePlanIdsWithDifferentRemarks(@Param("tenantId") long tenantId,
|
||||
@Param("orderId") long orderId,
|
||||
@Param("customerRemark") String customerRemark,
|
||||
@Param("internalRemark") String internalRemark,
|
||||
@Param("warehouseRemark") String warehouseRemark,
|
||||
@Param("customerServiceRemark") String customerServiceRemark,
|
||||
@Param("excludedItemId") Long excludedItemId);
|
||||
|
||||
@Update("""
|
||||
UPDATE fl_loading_plan_item i
|
||||
JOIN fl_loading_plan p ON p.id=i.loading_plan_id AND p.plan_status IN ('EDITING','LOADING')
|
||||
SET i.customer_remark=#{customerRemark}, i.internal_remark=#{internalRemark}, i.warehouse_remark=#{warehouseRemark},
|
||||
i.customer_service_remark=#{customerServiceRemark}, i.updated_by=#{operatorId},
|
||||
i.updated_by_name=#{operatorName}, i.updated_at=CURRENT_TIMESTAMP(3), i.version=i.version+1
|
||||
WHERE i.account_id=#{tenantId} AND i.order_id=#{orderId} AND i.deleted=0 AND i.frozen_at IS NULL
|
||||
AND (#{excludedItemId} IS NULL OR i.id<>#{excludedItemId})
|
||||
AND NOT (i.customer_remark <=> #{customerRemark}
|
||||
AND i.internal_remark <=> #{internalRemark}
|
||||
AND i.warehouse_remark <=> #{warehouseRemark}
|
||||
AND i.customer_service_remark <=> #{customerServiceRemark})
|
||||
""")
|
||||
int syncMutableOrderRemarks(@Param("tenantId") long tenantId, @Param("orderId") long orderId,
|
||||
@Param("customerRemark") String customerRemark,
|
||||
@Param("internalRemark") String internalRemark,
|
||||
@Param("warehouseRemark") String warehouseRemark,
|
||||
@Param("customerServiceRemark") String customerServiceRemark,
|
||||
@Param("operatorId") long operatorId,
|
||||
@Param("operatorName") String operatorName,
|
||||
@Param("excludedItemId") Long excludedItemId);
|
||||
|
||||
@Select("""
|
||||
SELECT DISTINCT i.loading_plan_id
|
||||
FROM fl_loading_plan_item i
|
||||
JOIN fl_loading_plan p ON p.id=i.loading_plan_id AND p.plan_status IN ('EDITING','LOADING')
|
||||
WHERE i.account_id=#{tenantId} AND i.order_id=#{orderId} AND i.deleted=0 AND i.frozen_at IS NULL
|
||||
AND NOT (i.customer_remark <=> #{customerRemark})
|
||||
""")
|
||||
List<Long> findMutablePlanIdsWithDifferentCustomerRemark(@Param("tenantId") long tenantId,
|
||||
@Param("orderId") long orderId,
|
||||
@Param("customerRemark") String customerRemark);
|
||||
|
||||
@Update("""
|
||||
UPDATE fl_loading_plan_item i
|
||||
JOIN fl_loading_plan p ON p.id=i.loading_plan_id AND p.plan_status IN ('EDITING','LOADING')
|
||||
SET i.customer_remark=#{customerRemark}, i.updated_by=#{operatorId}, i.updated_by_name=#{operatorName},
|
||||
i.updated_at=CURRENT_TIMESTAMP(3), i.version=i.version+1
|
||||
WHERE i.account_id=#{tenantId} AND i.order_id=#{orderId} AND i.deleted=0 AND i.frozen_at IS NULL
|
||||
AND NOT (i.customer_remark <=> #{customerRemark})
|
||||
""")
|
||||
int syncMutableOrderCustomerRemark(@Param("tenantId") long tenantId, @Param("orderId") long orderId,
|
||||
@Param("customerRemark") String customerRemark,
|
||||
@Param("operatorId") long operatorId,
|
||||
@Param("operatorName") String operatorName);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package com.baiyue.firstleg.mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baiyue.firstleg.entity.LoadingPlanEntity; import org.apache.ibatis.annotations.*;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baiyue.firstleg.entity.LoadingPlanEntity; import org.apache.ibatis.annotations.*; import java.util.List;
|
||||
@Mapper public interface LoadingPlanMapper extends BaseMapper<LoadingPlanEntity> {
|
||||
@Update("""
|
||||
UPDATE fl_loading_plan SET updated_by=#{operatorId},updated_by_name=#{operatorName},
|
||||
@@ -13,4 +13,16 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baiyue.firstl
|
||||
WHERE id=#{planId} AND plan_status='EDITING'
|
||||
""")
|
||||
int startPicking(@Param("planId") long planId,@Param("operatorId") long operatorId,@Param("operatorName") String operatorName);
|
||||
|
||||
@Update("""
|
||||
<script>
|
||||
UPDATE fl_loading_plan SET updated_by=#{operatorId},updated_by_name=#{operatorName},
|
||||
updated_at=CURRENT_TIMESTAMP(3),version=version+1
|
||||
WHERE plan_status IN ('EDITING','LOADING') AND id IN
|
||||
<foreach collection="planIds" item="planId" open="(" separator="," close=")">#{planId}</foreach>
|
||||
</script>
|
||||
""")
|
||||
int touchForOrderRemarks(@Param("planIds") List<Long> planIds,
|
||||
@Param("operatorId") long operatorId,
|
||||
@Param("operatorName") String operatorName);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.Objects;
|
||||
public class OrderDeclarationSyncService {
|
||||
@Resource private OrderDeclarationSyncMapper mapper;
|
||||
@Resource private ObjectMapper json;
|
||||
@Resource private OrderRemarksSyncService remarksSync;
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public ChannelChangeValidationResponse validateChannelChange(ChannelChangeValidationRequest request) {
|
||||
@@ -86,6 +87,8 @@ public class OrderDeclarationSyncService {
|
||||
normalizeChannel(event.channelCode()), event.channelName(), event.operatorId()) != 1) {
|
||||
throw conflict("Firstleg 入库申报快照已发生变化");
|
||||
}
|
||||
remarksSync.syncCustomerRemark(event.tenantId(), event.orderId(), event.customerRemark(),
|
||||
event.operatorId(), "order-declaration");
|
||||
}
|
||||
|
||||
private void recordEvent(UpdatedEvent event, String hash) {
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.baiyue.firstleg.service;
|
||||
|
||||
import com.baiyue.firstleg.dto.OrderRemarksSync;
|
||||
import com.baiyue.firstleg.mapper.LoadingPlanItemMapper;
|
||||
import com.baiyue.firstleg.mapper.LoadingPlanMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
public class OrderRemarksSyncService {
|
||||
@Resource private LoadingPlanItemMapper items;
|
||||
@Resource private LoadingPlanMapper plans;
|
||||
|
||||
@Transactional
|
||||
public int sync(OrderRemarksSync.Command command) {
|
||||
return sync(command, null, null);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public int sync(OrderRemarksSync.Command command, Long alreadyTouchedPlanId) {
|
||||
return sync(command, alreadyTouchedPlanId, null);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public int sync(OrderRemarksSync.Command command, Long alreadyTouchedPlanId, Long excludedItemId) {
|
||||
List<Long> affectedPlanIds = items.findMutablePlanIdsWithDifferentRemarks(
|
||||
command.tenantId(), command.orderId(), command.customerRemark(), command.internalRemark(), command.warehouseRemark(),
|
||||
command.customerServiceRemark(), excludedItemId);
|
||||
if (affectedPlanIds.isEmpty()) return 0;
|
||||
int updated = items.syncMutableOrderRemarks(command.tenantId(), command.orderId(),
|
||||
command.customerRemark(), command.internalRemark(), command.warehouseRemark(), command.customerServiceRemark(),
|
||||
command.operatorId(), command.operatorName(), excludedItemId);
|
||||
if (updated > 0) {
|
||||
List<Long> plansToTouch = affectedPlanIds.stream()
|
||||
.filter(planId -> !planId.equals(alreadyTouchedPlanId)).toList();
|
||||
if (!plansToTouch.isEmpty()) {
|
||||
plans.touchForOrderRemarks(plansToTouch, command.operatorId(), command.operatorName());
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public int syncCustomerRemark(long tenantId, long orderId, String customerRemark,
|
||||
long operatorId, String operatorName) {
|
||||
List<Long> affectedPlanIds = items.findMutablePlanIdsWithDifferentCustomerRemark(
|
||||
tenantId, orderId, customerRemark);
|
||||
if (affectedPlanIds.isEmpty()) return 0;
|
||||
int updated = items.syncMutableOrderCustomerRemark(
|
||||
tenantId, orderId, customerRemark, operatorId, operatorName);
|
||||
if (updated > 0) plans.touchForOrderRemarks(affectedPlanIds, operatorId, operatorName);
|
||||
return updated;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.common.audit.BusinessAudit;
|
||||
import com.baiyue.firstleg.dto.SmartLoadingDtos.*;
|
||||
import com.baiyue.firstleg.dto.OrderRemarksSync;
|
||||
import com.baiyue.firstleg.domain.SmartLoadingChannelGroupCatalog;
|
||||
import com.baiyue.firstleg.client.OrderCargoClient;
|
||||
import com.baiyue.firstleg.client.PendingReviewOrderClient;
|
||||
@@ -56,6 +57,7 @@ public class SmartLoadingService {
|
||||
@Resource private FbaPricingService fbaPricingService;
|
||||
@Resource private PriceBookQueryUseCase priceBooks;
|
||||
@Resource private FirstlegDocumentNumberGenerator documentNumbers;
|
||||
@Resource private OrderRemarksSyncService orderRemarksSync;
|
||||
@Resource private ObjectMapper objectMapper;
|
||||
@Value("${baiyue.security.internal-service-token:}") private String internalToken;
|
||||
public SmartLoadingService() { }
|
||||
@@ -1099,6 +1101,9 @@ public class SmartLoadingService {
|
||||
LoadingPlanEntity plan = editing(planId, request.expectedPlanVersion(), operatorId, operatorName);
|
||||
LoadingPlanItemEntity item = repository.item(planId, itemId);
|
||||
if (item == null) throw new BizException(ResultCode.NOT_FOUND, "装柜明细不存在");
|
||||
if (item.getVersion() != request.expectedItemVersion()) {
|
||||
throw conflict("装柜计划或明细已被其他人修改,请刷新后重试");
|
||||
}
|
||||
if (Objects.equals(item.getInternalRemark(), internalRemark)
|
||||
&& Objects.equals(item.getWarehouseRemark(), warehouseRemark)
|
||||
&& Objects.equals(item.getCustomerServiceRemark(), customerServiceRemark)) {
|
||||
@@ -1109,16 +1114,30 @@ public class SmartLoadingService {
|
||||
"version", item.getVersion()));
|
||||
try {
|
||||
touch(plan, operatorId, operatorName);
|
||||
ApiResponse<OrderCargoClient.RemarksUpdateResponse> response = orderCargoClient.updateRemarks(
|
||||
internalToken, item.getAccountId(), item.getOrderId(),
|
||||
new OrderCargoClient.RemarksUpdateRequest(internalRemark, warehouseRemark,
|
||||
customerServiceRemark, operatorId));
|
||||
if (response == null || !response.successful() || response.data() == null) {
|
||||
throw new BizException(ResultCode.SERVICE_UNAVAILABLE,
|
||||
response == null ? "订单备注服务暂不可用" : response.message());
|
||||
}
|
||||
if (repository.updateRemarks(planId, itemId, request.expectedPlanVersion() + 1,
|
||||
request.expectedItemVersion(), internalRemark, warehouseRemark, customerServiceRemark,
|
||||
operatorId, operatorName) != 1) {
|
||||
request.expectedItemVersion(), response.data().internalRemark(), response.data().warehouseRemark(),
|
||||
response.data().customerServiceRemark(), operatorId, operatorName) != 1) {
|
||||
throw conflict("装柜计划或明细已被其他人修改,请刷新后重试");
|
||||
}
|
||||
orderRemarksSync.sync(new OrderRemarksSync.Command(item.getAccountId(), item.getOrderId(),
|
||||
response.data().customerRemark(),
|
||||
response.data().internalRemark(), response.data().warehouseRemark(),
|
||||
response.data().customerServiceRemark(), operatorId, operatorName), planId, itemId);
|
||||
} catch (DataAccessException exception) {
|
||||
if (hasSqlState(exception, "45000")) {
|
||||
throw conflict("装柜计划或明细状态已变化,备注未保存,请刷新后重试");
|
||||
}
|
||||
throw exception;
|
||||
} catch (FeignException exception) {
|
||||
throw unavailable();
|
||||
}
|
||||
history(planId, itemId, "REMARKS", plan.getPlanStatus(), plan.getPlanStatus(), operation,
|
||||
before, json(values("internalRemark", internalRemark, "warehouseRemark", warehouseRemark,
|
||||
|
||||
@@ -292,6 +292,32 @@ paths:
|
||||
schema: {$ref: '#/components/schemas/OrderDeclarationUpdatedEvent'}
|
||||
responses:
|
||||
'200': {description: 成功、幂等重放或旧版本已忽略;冲突时响应体 code=A0409}
|
||||
/internal/firstleg/v1/inbounds/order-remarks-updated:
|
||||
post:
|
||||
summary: 同步 Order 权威协作备注到未冻结预装明细
|
||||
description: >-
|
||||
仅接受内部服务令牌。按客户与订单关联全部 EDITING/LOADING 且未冻结的预装明细,
|
||||
同步内部、仓库和客服备注并递增受影响计划与明细版本;已完成装柜的冻结快照不修改。
|
||||
security:
|
||||
- internalServiceToken: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [tenantId, orderId, operatorId]
|
||||
properties:
|
||||
tenantId: {type: integer, format: int64, minimum: 1}
|
||||
orderId: {type: integer, format: int64, minimum: 1}
|
||||
customerRemark: {type: string, nullable: true, maxLength: 1000}
|
||||
internalRemark: {type: string, nullable: true, maxLength: 1000}
|
||||
warehouseRemark: {type: string, nullable: true, maxLength: 1000}
|
||||
customerServiceRemark: {type: string, nullable: true, maxLength: 1000}
|
||||
operatorId: {type: integer, format: int64, minimum: 1}
|
||||
operatorName: {type: string, nullable: true, maxLength: 128}
|
||||
responses:
|
||||
'200': {description: data 返回已同步的预装明细数量}
|
||||
/internal/firstleg/v1/inbounds/unified-orders/query:
|
||||
post:
|
||||
summary: 按统一订单条件分页查询履约摘要(Order 内部)
|
||||
|
||||
+3
@@ -7,6 +7,7 @@ import com.baiyue.firstleg.service.InboundOrderCreationService;
|
||||
import com.baiyue.firstleg.service.InboundCartonLabelService;
|
||||
import com.baiyue.firstleg.service.UnifiedInboundQueryService;
|
||||
import com.baiyue.firstleg.service.OrderDeclarationSyncService;
|
||||
import com.baiyue.firstleg.service.OrderRemarksSyncService;
|
||||
import com.baiyue.firstleg.dto.UnifiedInboundQuery;
|
||||
import com.baiyue.firstleg.dto.OrderDeclarationSync;
|
||||
import com.baiyue.common.core.api.PageResult;
|
||||
@@ -36,6 +37,8 @@ class InternalInboundOrderReferenceControllerTest {
|
||||
private UnifiedInboundQueryService unifiedQueryService;
|
||||
@MockBean
|
||||
private OrderDeclarationSyncService declarationSync;
|
||||
@MockBean
|
||||
private OrderRemarksSyncService remarksSync;
|
||||
@Resource
|
||||
private InternalInboundOrderController controller;
|
||||
|
||||
|
||||
+1
@@ -35,6 +35,7 @@ class OrderDeclarationSyncServiceTest {
|
||||
}
|
||||
|
||||
@MockBean private OrderDeclarationSyncMapper mapper;
|
||||
@MockBean private OrderRemarksSyncService remarksSync;
|
||||
@Resource private OrderDeclarationSyncService service;
|
||||
@Resource private ObjectMapper json;
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.baiyue.firstleg.service;
|
||||
|
||||
import com.baiyue.firstleg.dto.OrderRemarksSync;
|
||||
import com.baiyue.firstleg.mapper.LoadingPlanItemMapper;
|
||||
import com.baiyue.firstleg.mapper.LoadingPlanMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SpringJUnitConfig(OrderRemarksSyncService.class)
|
||||
class OrderRemarksSyncServiceTest {
|
||||
@MockBean private LoadingPlanItemMapper items;
|
||||
@MockBean private LoadingPlanMapper plans;
|
||||
|
||||
@jakarta.annotation.Resource private OrderRemarksSyncService service;
|
||||
|
||||
@Test
|
||||
void updatesAllMutableOrderItemsAndTouchesAffectedPlans() {
|
||||
var command = new OrderRemarksSync.Command(10L, 20L, "客户", "内部", "仓库", "客服", 30L, "操作人");
|
||||
when(items.findMutablePlanIdsWithDifferentRemarks(
|
||||
10L, 20L, "客户", "内部", "仓库", "客服", null)).thenReturn(List.of(101L, 102L));
|
||||
when(items.syncMutableOrderRemarks(
|
||||
10L, 20L, "客户", "内部", "仓库", "客服", 30L, "操作人", null)).thenReturn(3);
|
||||
|
||||
assertThat(service.sync(command)).isEqualTo(3);
|
||||
|
||||
verify(plans).touchForOrderRemarks(List.of(101L, 102L), 30L, "操作人");
|
||||
}
|
||||
|
||||
@Test
|
||||
void leavesFrozenOrAlreadyMatchingPlansUntouched() {
|
||||
var command = new OrderRemarksSync.Command(10L, 20L, null, null, null, null, 30L, null);
|
||||
when(items.findMutablePlanIdsWithDifferentRemarks(
|
||||
10L, 20L, null, null, null, null, null)).thenReturn(List.of());
|
||||
|
||||
assertThat(service.sync(command)).isZero();
|
||||
|
||||
verify(items, never()).syncMutableOrderRemarks(
|
||||
10L, 20L, null, null, null, null, 30L, null, null);
|
||||
verify(plans, never()).touchForOrderRemarks(org.mockito.ArgumentMatchers.anyList(),
|
||||
org.mockito.ArgumentMatchers.anyLong(), org.mockito.ArgumentMatchers.nullable(String.class));
|
||||
}
|
||||
}
|
||||
@@ -102,6 +102,7 @@ class SmartLoadingServiceTest {
|
||||
@MockBean private PriceBookQueryUseCase priceBooks;
|
||||
@MockBean private FirstlegDocumentNumberGenerator documentNumbers;
|
||||
@MockBean private DropshipPalletizationMapper dropshipPallets;
|
||||
@MockBean private OrderRemarksSyncService orderRemarksSync;
|
||||
@Resource private SmartLoadingService service;
|
||||
|
||||
@TestConfiguration
|
||||
@@ -119,6 +120,12 @@ class SmartLoadingServiceTest {
|
||||
when(cargoClient.detail(anyString(), anyLong(), anyLong(), anyLong())).thenReturn(
|
||||
ApiResponse.success(new OrderCargoClient.CargoBinding(20L, 30L, 1, "货物", 5,
|
||||
new BigDecimal("10"), new BigDecimal("2"))));
|
||||
when(cargoClient.updateRemarks(anyString(), anyLong(), anyLong(), any()))
|
||||
.thenAnswer(invocation -> {
|
||||
OrderCargoClient.RemarksUpdateRequest request = invocation.getArgument(3);
|
||||
return ApiResponse.success(new OrderCargoClient.RemarksUpdateResponse(2, null,
|
||||
request.internalRemark(), request.warehouseRemark(), request.customerServiceRemark()));
|
||||
});
|
||||
when(fbaPricingService.recalculateUnlockedContainerCustomerFees(anyLong(), anyLong(), anyString()))
|
||||
.thenReturn(new FbaPricingService.ContainerFeeRecalculationResult(
|
||||
FbaPricingService.ContainerFeeRecalculationStatus.NOT_READY, 0));
|
||||
@@ -1955,6 +1962,7 @@ class SmartLoadingServiceTest {
|
||||
private static LoadingPlanItemEntity item(long id, long account, long detail, int boxes) {
|
||||
LoadingPlanItemEntity value = new LoadingPlanItemEntity();
|
||||
value.setId(id); value.setLoadingPlanId(1L); value.setAccountId(account);
|
||||
value.setOrderId(30L); value.setOrderNo("O30");
|
||||
value.setInboundId(10L); value.setInboundDetailId(detail); value.setPackageCount(boxes);
|
||||
value.setVersion(0); value.setDeleted(false);
|
||||
return value;
|
||||
|
||||
Reference in New Issue
Block a user