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:
|
||||
|
||||
Reference in New Issue
Block a user