Merge remote-tracking branch 'origin/dev' into test
# Conflicts: # warehouse/src/main/java/com/baiyue/warehouse/dto/WarehouseRequests.java # warehouse/src/main/java/com/baiyue/warehouse/service/WarehouseImportService.java # warehouse/src/main/java/com/baiyue/warehouse/service/WarehouseSaveNormalizer.java # warehouse/src/main/resources/db/warehouse.sql
This commit is contained in:
@@ -45,7 +45,7 @@ public interface FirstlegInboundClient {
|
||||
Boolean customsInspection, String destinationType, Long destinationWarehouseId,
|
||||
String destinationCode, String destinationName, String publicRemark,
|
||||
String expressCompanyName, String expressTrackingNo, Integer totalPackageCount,
|
||||
String pickupMethod, LocalDateTime requestedPickupAt
|
||||
String pickupMethod, LocalDateTime requestedPickupAt, String fulfillmentType
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,8 +73,28 @@ public final class OrderRequests {
|
||||
@Size(max = 64) String shipmentId,
|
||||
@Size(max = 64) String referenceId,
|
||||
@Schema(description = "旧系统入仓码;仅全局 LEGACY_MANUAL 模式接受,AUTO 模式必须留空", example = "NYEXX2608140001", maxLength = 40)
|
||||
@Size(max = 40) @Pattern(regexp = "[A-Za-z0-9._:-]+") String inboundCode
|
||||
@Size(max = 40) @Pattern(regexp = "[A-Za-z0-9._:-]+") String inboundCode,
|
||||
@Schema(description = "Fulfillment type; omitted means STANDARD / 履约类型;省略时为普通头程", allowableValues = {"STANDARD", "ONE_CLICK_DROPSHIP"}, defaultValue = "STANDARD")
|
||||
@Pattern(regexp = "STANDARD|ONE_CLICK_DROPSHIP") String fulfillmentType
|
||||
) {
|
||||
public SaveRequest(Long customerId, String customerName, String transportMode, String tradeTerm,
|
||||
String destinationCountryCode, Long destinationWarehouseId,
|
||||
String destinationWarehouseName, LocalDate expectedShipDate, String customerRemark,
|
||||
Party sender, Party receiver, List<Cargo> cargoes, String pickupMethod,
|
||||
LocalDateTime requestedPickupAt, Long receivingWarehouseId,
|
||||
String receivingWarehouseName, String channelCode, String channelName,
|
||||
Long carrierId, String carrierName, String taxMode, String pricingTaxMode,
|
||||
String containerMode, Boolean customsInspection, String destinationType,
|
||||
String amazonWarehouseCode, String shipmentId, String referenceId,
|
||||
String inboundCode) {
|
||||
this(customerId, customerName, transportMode, tradeTerm, destinationCountryCode,
|
||||
destinationWarehouseId, destinationWarehouseName, expectedShipDate, customerRemark,
|
||||
sender, receiver, cargoes, pickupMethod, requestedPickupAt, receivingWarehouseId,
|
||||
receivingWarehouseName, channelCode, channelName, carrierId, carrierName, taxMode,
|
||||
pricingTaxMode, containerMode, customsInspection, destinationType, amazonWarehouseCode,
|
||||
shipmentId, referenceId, inboundCode, null);
|
||||
}
|
||||
|
||||
public SaveRequest(Long customerId, String customerName, String transportMode, String tradeTerm,
|
||||
String destinationCountryCode, Long destinationWarehouseId,
|
||||
String destinationWarehouseName, LocalDate expectedShipDate, String customerRemark,
|
||||
@@ -89,7 +109,7 @@ public final class OrderRequests {
|
||||
sender, receiver, cargoes, pickupMethod, requestedPickupAt, receivingWarehouseId,
|
||||
receivingWarehouseName, channelCode, channelName, carrierId, carrierName, taxMode,
|
||||
pricingTaxMode, containerMode, customsInspection, destinationType, amazonWarehouseCode,
|
||||
shipmentId, referenceId, null);
|
||||
shipmentId, referenceId, null, null);
|
||||
}
|
||||
|
||||
public SaveRequest(Long customerId, String customerName, String transportMode, String tradeTerm,
|
||||
@@ -106,7 +126,7 @@ public final class OrderRequests {
|
||||
sender, receiver, cargoes, pickupMethod, null, receivingWarehouseId,
|
||||
receivingWarehouseName, channelCode, channelName, carrierId, carrierName, taxMode,
|
||||
pricingTaxMode, containerMode, customsInspection, destinationType, amazonWarehouseCode,
|
||||
shipmentId, referenceId, null);
|
||||
shipmentId, referenceId, null, null);
|
||||
}
|
||||
|
||||
@AssertTrue(message = "承运商 ID 和名称必须同时填写或同时留空")
|
||||
|
||||
@@ -47,6 +47,7 @@ public class OrderEntity extends BaseEntity {
|
||||
private String containerMode;
|
||||
private Boolean customsInspection;
|
||||
private String destinationType;
|
||||
private String fulfillmentType;
|
||||
private String amazonWarehouseCode;
|
||||
private String shipmentId;
|
||||
private String referenceId;
|
||||
|
||||
@@ -23,6 +23,7 @@ public class MerchantBatchDraftService {
|
||||
public MerchantBatchDraftDtos.Response create(long tenantId, long userId, String batchKey,
|
||||
List<MerchantBatchDraftDtos.Item> items) {
|
||||
if (!StringUtils.hasText(batchKey)) throw new BizException("必须提供 Idempotency-Key");
|
||||
if (batchKey.trim().length() > 128) throw new BizException("Idempotency-Key 长度不能超过128");
|
||||
if (items == null || items.isEmpty()) throw new BizException("批量草稿不能为空");
|
||||
if (items.size() > MAX_ITEMS) throw new BizException("批量草稿最多 50 条");
|
||||
List<MerchantBatchDraftDtos.Result> results = new ArrayList<>(items.size());
|
||||
|
||||
@@ -462,6 +462,7 @@ public class OrderApplicationService {
|
||||
order.setPricingTaxMode(request.pricingTaxMode());
|
||||
order.setContainerMode(request.containerMode()); order.setCustomsInspection(request.customsInspection());
|
||||
order.setDestinationType(request.destinationType());
|
||||
order.setFulfillmentType(fulfillmentType(request.fulfillmentType()));
|
||||
order.setAmazonWarehouseCode("FBA".equals(request.destinationType()) && snapshots.destination() != null
|
||||
? snapshots.destination().warehouse().warehouseCode() : request.amazonWarehouseCode());
|
||||
order.setShipmentId(request.shipmentId()); order.setReferenceId(request.referenceId());
|
||||
@@ -486,6 +487,13 @@ public class OrderApplicationService {
|
||||
}
|
||||
order.setInboundCode(normalized);
|
||||
}
|
||||
|
||||
private static String fulfillmentType(String value) {
|
||||
if (value == null) return "STANDARD";
|
||||
if ("STANDARD".equals(value) || "ONE_CLICK_DROPSHIP".equals(value)) return value;
|
||||
throw new BizException(ResultCode.VALIDATION_FAILED,
|
||||
"履约类型必须为 STANDARD 或 ONE_CLICK_DROPSHIP");
|
||||
}
|
||||
private boolean legacyManualMode() {
|
||||
return inboundCodeModeProvider.legacyManual();
|
||||
}
|
||||
@@ -599,7 +607,8 @@ public class OrderApplicationService {
|
||||
order.getContainerMode(), order.getCustomsInspection(), order.getDestinationType(),
|
||||
order.getDestinationWarehouseId(), order.getAmazonWarehouseCode(), order.getDestinationWarehouseName(),
|
||||
order.getCustomerRemark(), order.getExpressCompany(), order.getExpressTrackingNo(), totalPackageCount,
|
||||
order.getPickupMethod(), order.getRequestedPickupAt());
|
||||
order.getPickupMethod(), order.getRequestedPickupAt(),
|
||||
order.getFulfillmentType() == null ? "STANDARD" : order.getFulfillmentType());
|
||||
}
|
||||
private void prepareDraftInbound(OrderEntity order, OrderRequests.SaveRequest request) {
|
||||
FirstlegInboundClient client = firstlegProvider == null ? null : firstlegProvider.getIfAvailable();
|
||||
|
||||
@@ -141,6 +141,7 @@ public class OrderFulfillmentSplitService {
|
||||
child.setDestinationWarehouseName(root.getDestinationWarehouseName()); child.setReceivingWarehouseId(root.getReceivingWarehouseId());
|
||||
child.setReceivingWarehouseName(root.getReceivingWarehouseName()); child.setChannelCode(root.getChannelCode());
|
||||
child.setChannelName(root.getChannelName()); child.setDestinationType(root.getDestinationType());
|
||||
child.setFulfillmentType(root.getFulfillmentType());
|
||||
child.setInboundCode(remainderInboundCode(root, sequence));
|
||||
child.setCreatedBy(operatorId); child.setUpdatedBy(operatorId);
|
||||
if (orders.insert(child) != 1) throw new BizException(ResultCode.CONFLICT, "余量子订单创建失败");
|
||||
|
||||
@@ -35,6 +35,7 @@ CREATE TABLE IF NOT EXISTS ord_order (
|
||||
container_mode VARCHAR(24) NULL COMMENT '整柜或散货',
|
||||
customs_inspection TINYINT(1) NULL COMMENT '是否商检',
|
||||
destination_type VARCHAR(24) NULL COMMENT '目的仓类型:FBA亚马逊仓、OVERSEAS海外仓、PRIVATE私人地址',
|
||||
fulfillment_type VARCHAR(32) NOT NULL DEFAULT 'STANDARD' COMMENT '履约类型:STANDARD普通头程、ONE_CLICK_DROPSHIP一键代发',
|
||||
amazon_warehouse_code VARCHAR(32) NULL COMMENT '亚马逊仓库编码',
|
||||
shipment_id VARCHAR(64) NULL COMMENT '订单级Amazon Shipment ID',
|
||||
reference_id VARCHAR(64) NULL COMMENT '订单级Amazon Reference ID',
|
||||
@@ -61,6 +62,26 @@ CREATE TABLE IF NOT EXISTS ord_order (
|
||||
KEY idx_order_tenant_warehouse (tenant_id, destination_warehouse_id)
|
||||
) ENGINE=InnoDB COMMENT='头程订单主表:保存商户委托、目的仓、运输方式和订单当前状态';
|
||||
|
||||
SET @order_fulfillment_type_sql = IF(
|
||||
EXISTS(
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = 'baiyue_order' AND table_name = 'ord_order'
|
||||
AND column_name = 'fulfillment_type'
|
||||
),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE baiyue_order.ord_order ADD COLUMN fulfillment_type VARCHAR(32) NULL COMMENT ''履约类型:STANDARD普通头程、ONE_CLICK_DROPSHIP一键代发'' AFTER destination_type'
|
||||
);
|
||||
PREPARE order_fulfillment_type_stmt FROM @order_fulfillment_type_sql;
|
||||
EXECUTE order_fulfillment_type_stmt;
|
||||
DEALLOCATE PREPARE order_fulfillment_type_stmt;
|
||||
|
||||
UPDATE baiyue_order.ord_order
|
||||
SET fulfillment_type = 'STANDARD'
|
||||
WHERE fulfillment_type IS NULL OR fulfillment_type = '';
|
||||
ALTER TABLE baiyue_order.ord_order
|
||||
MODIFY COLUMN fulfillment_type VARCHAR(32) NOT NULL DEFAULT 'STANDARD'
|
||||
COMMENT '履约类型:STANDARD普通头程、ONE_CLICK_DROPSHIP一键代发';
|
||||
|
||||
-- 既有开发库必须先确认不存在跨客户重复码;若存在则在此处失败,不自动改写业务数据。
|
||||
SET @order_global_inbound_index_sql = IF(
|
||||
NOT EXISTS(
|
||||
|
||||
@@ -379,6 +379,11 @@ paths:
|
||||
'403': {description: 需要 merchant:order:view 权限}
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
schemas:
|
||||
TenantOrderStatisticsResponse:
|
||||
type: object
|
||||
@@ -391,12 +396,6 @@ components:
|
||||
nextMonthStart: {type: string, format: date-time}
|
||||
zoneId: {type: string, example: Asia/Shanghai}
|
||||
asOf: {type: string, format: date-time}
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
schemas:
|
||||
UnifiedMainStatus:
|
||||
type: string
|
||||
enum: [PENDING_REVIEW, WAIT_MEASURE, INBOUNDED, WAIT_SPLIT, LOADING, LOADED, DELIVERED]
|
||||
@@ -646,6 +645,11 @@ components:
|
||||
type: object
|
||||
required: [pricingTaxMode, cargoes]
|
||||
properties:
|
||||
fulfillmentType:
|
||||
type: string
|
||||
enum: [STANDARD, ONE_CLICK_DROPSHIP]
|
||||
default: STANDARD
|
||||
description: 独立履约类型;省略为普通头程,不复用业务/计费 businessType
|
||||
inboundCode:
|
||||
type: string
|
||||
maxLength: 40
|
||||
@@ -657,7 +661,8 @@ components:
|
||||
minItems: 1
|
||||
items: {$ref: '#/components/schemas/FirstLegOrderCargo'}
|
||||
description: >-
|
||||
订单保存请求中的完整字段以服务端 FirstLegOrderSaveRequest 为准;pricingTaxMode
|
||||
订单保存请求中的完整字段以服务端 FirstLegOrderSaveRequest 为准;fulfillmentType
|
||||
省略时固定为 STANDARD,一键代发必须显式传 ONE_CLICK_DROPSHIP,且不复用计费 businessType;pricingTaxMode
|
||||
是新建和编辑订单的必填报价维度;customerId 不接受客户端指定,服务端始终使用认证企业 ID;
|
||||
发货单位和收货单位仅通过 sender/receiver 保存业务快照。历史存量订单的响应字段仍允许为空。
|
||||
InboundCodePolicy:
|
||||
|
||||
+3
@@ -37,6 +37,9 @@ class MerchantBatchDraftOpenApiContractTest {
|
||||
.contains("merchant:order:create")
|
||||
.contains("FirstLegBatchDraftResponse")
|
||||
.contains("FirstLegBatchDraftResult")
|
||||
.contains("fulfillmentType:")
|
||||
.contains("enum: [STANDARD, ONE_CLICK_DROPSHIP]")
|
||||
.contains("default: STANDARD")
|
||||
.contains("inboundCode:")
|
||||
.contains("errorCode:")
|
||||
.contains("errorMessage:");
|
||||
|
||||
@@ -54,6 +54,25 @@ class OrderRequestsValidationTest {
|
||||
assertThat(validator.validate(draft)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void fulfillmentTypeIsOptionalButRejectsPricingBusinessValues() {
|
||||
var standard = request(null, null, "TAX_INCLUDED");
|
||||
assertThat(validator.validate(standard)).isEmpty();
|
||||
|
||||
var invalid = new OrderRequests.SaveRequest(
|
||||
standard.customerId(), standard.customerName(), standard.transportMode(), standard.tradeTerm(),
|
||||
standard.destinationCountryCode(), standard.destinationWarehouseId(), standard.destinationWarehouseName(),
|
||||
standard.expectedShipDate(), standard.customerRemark(), standard.sender(), standard.receiver(),
|
||||
standard.cargoes(), standard.pickupMethod(), standard.requestedPickupAt(), standard.receivingWarehouseId(),
|
||||
standard.receivingWarehouseName(), standard.channelCode(), standard.channelName(), standard.carrierId(),
|
||||
standard.carrierName(), standard.taxMode(), standard.pricingTaxMode(), standard.containerMode(),
|
||||
standard.customsInspection(), standard.destinationType(), standard.amazonWarehouseCode(),
|
||||
standard.shipmentId(), standard.referenceId(), standard.inboundCode(), "FBA_SEA");
|
||||
|
||||
assertThat(validator.validate(invalid))
|
||||
.anyMatch(violation -> violation.getPropertyPath().toString().equals("fulfillmentType"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void validatesTheManuallyEnteredInboundCodeForSingleAndBatchCallers() {
|
||||
var source = request(null, null, "TAX_INCLUDED");
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.baiyue.order.service;
|
||||
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.order.dto.MerchantBatchDraftDtos;
|
||||
import com.baiyue.order.dto.OrderRequests;
|
||||
import com.baiyue.order.entity.OrderEntity;
|
||||
import jakarta.annotation.Resource;
|
||||
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.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@SpringJUnitConfig(MerchantBatchDraftService.class)
|
||||
class MerchantBatchDraftServiceTest {
|
||||
@MockBean private MerchantBatchDraftItemService itemService;
|
||||
@Resource private MerchantBatchDraftService service;
|
||||
|
||||
@Test
|
||||
void createsEachRowAndReturnsOrderReferences() {
|
||||
doAnswer(invocation -> order(101L, "FL101", "RK-101"))
|
||||
.doAnswer(invocation -> order(102L, "FL102", "RK-102"))
|
||||
.when(itemService).create(anyLong(), anyLong(), any(), anyString());
|
||||
|
||||
var response = service.create(10L, 20L, "batch-key", List.of(
|
||||
item("row-1"), item("row-2")));
|
||||
|
||||
assertThat(response.total()).isEqualTo(2);
|
||||
assertThat(response.succeeded()).isEqualTo(2);
|
||||
assertThat(response.failed()).isZero();
|
||||
assertThat(response.items()).extracting(MerchantBatchDraftDtos.Result::inboundCode)
|
||||
.containsExactly("RK-101", "RK-102");
|
||||
assertThat(response.items()).extracting(MerchantBatchDraftDtos.Result::index)
|
||||
.containsExactly(0, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void keepsSuccessfulRowsWhenAnotherRowFails() {
|
||||
doAnswer(invocation -> order(101L, "FL101", "RK-101"))
|
||||
.doThrow(new BizException("SKU不能为空"))
|
||||
.when(itemService).create(anyLong(), anyLong(), any(), anyString());
|
||||
|
||||
var response = service.create(10L, 20L, "batch-key", List.of(
|
||||
item("row-1"), item("row-2")));
|
||||
|
||||
assertThat(response.succeeded()).isEqualTo(1);
|
||||
assertThat(response.failed()).isEqualTo(1);
|
||||
assertThat(response.items().get(0).success()).isTrue();
|
||||
assertThat(response.items().get(1).success()).isFalse();
|
||||
assertThat(response.items().get(1).errorMessage()).isEqualTo("SKU不能为空");
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsDuplicateRowWithoutCreatingItTwice() {
|
||||
doAnswer(invocation -> order(101L, "FL101", "RK-101"))
|
||||
.when(itemService).create(anyLong(), anyLong(), any(), anyString());
|
||||
|
||||
var response = service.create(10L, 20L, "batch-key", List.of(
|
||||
item("same-row"), item("same-row")));
|
||||
|
||||
assertThat(response.succeeded()).isEqualTo(1);
|
||||
assertThat(response.failed()).isEqualTo(1);
|
||||
assertThat(response.items().get(1).errorCode()).isEqualTo("A0409");
|
||||
verify(itemService).create(anyLong(), anyLong(), any(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void derivesStablePerRowIdempotencyKeys() {
|
||||
String first = MerchantBatchDraftService.derivedKey(" batch-key ", "row-1");
|
||||
String retry = MerchantBatchDraftService.derivedKey("batch-key", "row-1");
|
||||
String anotherRow = MerchantBatchDraftService.derivedKey("batch-key", "row-2");
|
||||
|
||||
assertThat(first).isEqualTo(retry).startsWith("batch-").hasSize(70);
|
||||
assertThat(anotherRow).isNotEqualTo(first);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsInvalidBatchBeforeCreatingRows() {
|
||||
assertThatThrownBy(() -> service.create(10L, 20L, " ", List.of(item("row-1"))))
|
||||
.isInstanceOf(BizException.class);
|
||||
assertThatThrownBy(() -> service.create(10L, 20L, "x".repeat(129), List.of(item("row-1"))))
|
||||
.isInstanceOf(BizException.class);
|
||||
assertThatThrownBy(() -> service.create(10L, 20L, "batch-key", List.of()))
|
||||
.isInstanceOf(BizException.class);
|
||||
verify(itemService, never()).create(anyLong(), anyLong(), any(), anyString());
|
||||
}
|
||||
|
||||
private MerchantBatchDraftDtos.Item item(String rowId) {
|
||||
return new MerchantBatchDraftDtos.Item(rowId, mock(OrderRequests.SaveRequest.class));
|
||||
}
|
||||
|
||||
private OrderEntity order(long id, String orderNo, String inboundCode) {
|
||||
OrderEntity order = new OrderEntity();
|
||||
order.setId(id);
|
||||
order.setOrderNo(orderNo);
|
||||
order.setInboundCode(inboundCode);
|
||||
return order;
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ class OrderApplicationServiceStateTest {
|
||||
assertThat(orderId).isNotNull();
|
||||
verify(eligibility, never()).requireApproved(anyLong());
|
||||
verify(repository).insertOrder(argThat(order -> order.getStatus() == OrderStatus.DRAFT
|
||||
&& order.getInboundCode() == null));
|
||||
&& order.getInboundCode() == null && "STANDARD".equals(order.getFulfillmentType())));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -372,6 +372,31 @@ class OrderApplicationServiceStateTest {
|
||||
assertThat(command.taxMode()).isEqualTo("BUY_DECLARATION");
|
||||
assertThat(command.pricingTaxMode()).isEqualTo("TAX_EXCLUDED");
|
||||
assertThat(command.totalPackageCount()).isEqualTo(4);
|
||||
assertThat(command.fulfillmentType()).isEqualTo("STANDARD");
|
||||
}
|
||||
|
||||
@Test
|
||||
void explicitDropshipFulfillmentTypeIsPersistedAndSentIndependentlyFromPricingBusinessType() {
|
||||
OrderRepository repository = mock(OrderRepository.class);
|
||||
OrderMasterDataGuard masterData = mock(OrderMasterDataGuard.class);
|
||||
OrderRequests.SaveRequest source = request();
|
||||
OrderRequests.SaveRequest dropship = new OrderRequests.SaveRequest(
|
||||
source.customerId(), source.customerName(), source.transportMode(), source.tradeTerm(),
|
||||
source.destinationCountryCode(), source.destinationWarehouseId(), source.destinationWarehouseName(),
|
||||
source.expectedShipDate(), source.customerRemark(), source.sender(), source.receiver(), source.cargoes(),
|
||||
source.pickupMethod(), source.requestedPickupAt(), source.receivingWarehouseId(),
|
||||
source.receivingWarehouseName(), source.channelCode(), source.channelName(), source.carrierId(),
|
||||
source.carrierName(), source.taxMode(), source.pricingTaxMode(), source.containerMode(),
|
||||
source.customsInspection(), source.destinationType(), source.amazonWarehouseCode(), source.shipmentId(),
|
||||
source.referenceId(), source.inboundCode(), "ONE_CLICK_DROPSHIP");
|
||||
when(masterData.validate(10001L, dropship)).thenReturn(snapshots());
|
||||
when(repository.completeIdempotency(anyLong(), any(), anyLong())).thenReturn(1);
|
||||
|
||||
service(repository, mock(OrderEligibilityGuard.class), masterData)
|
||||
.createDraft(10001L, 2L, dropship, "dropship-fulfillment");
|
||||
|
||||
verify(repository).insertOrder(argThat(order -> "ONE_CLICK_DROPSHIP".equals(order.getFulfillmentType())
|
||||
&& "OVERSEAS".equals(order.getDestinationType())));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user