暂扣 标记合托功能
This commit is contained in:
@@ -195,7 +195,7 @@ CREATE TABLE IF NOT EXISTS ll_overseas_procurement_order (
|
||||
purchase_quantity BIGINT NOT NULL COMMENT '采购数量', budget_unit_price DECIMAL(18,2) NULL COMMENT '预算单价',
|
||||
currency CHAR(3) NOT NULL DEFAULT 'USD' COMMENT '币种', receiving_address VARCHAR(1000) NULL COMMENT '收货地址',
|
||||
contact_name VARCHAR(128) NOT NULL COMMENT '联系人姓名', contact_phone VARCHAR(64) NOT NULL COMMENT '联系人电话',
|
||||
purchase_warehouse_id VARCHAR(128) NULL COMMENT '采购入仓仓库ID', purchase_warehouse_name VARCHAR(255) NULL COMMENT '采购入仓仓库名称',
|
||||
purchase_warehouse_id VARCHAR(128) NULL COMMENT '采购入仓仓库ID', purchase_warehouse_name VARCHAR(255) NULL COMMENT '采购入仓仓库名称', outbound_details JSON NULL COMMENT '出库明细',
|
||||
inbound_quantity BIGINT NOT NULL DEFAULT 0 COMMENT '采购单据累计入库数量', domestic_carrier VARCHAR(128) NULL COMMENT '境内承运商',
|
||||
domestic_tracking_no VARCHAR(128) NULL COMMENT '境内物流单号', overseas_carrier VARCHAR(128) NULL COMMENT '海外承运商',
|
||||
overseas_tracking_no VARCHAR(128) NULL COMMENT '海外物流单号', estimated_arrival_at DATETIME(3) NULL COMMENT '预计到达时间',
|
||||
@@ -211,6 +211,8 @@ CREATE TABLE IF NOT EXISTS ll_overseas_procurement_order (
|
||||
KEY idx_ll_overseas_procurement_list(customer_id,status,created_at),
|
||||
KEY idx_ll_overseas_procurement_warehouse(customer_id,purchase_warehouse_id,created_at)
|
||||
) ENGINE=InnoDB COMMENT='海外采购订单';
|
||||
SET @ddl = (SELECT IF(EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_overseas_procurement_order' AND column_name='outbound_details'), 'SELECT 1', 'ALTER TABLE ll_overseas_procurement_order ADD COLUMN outbound_details JSON NULL COMMENT ''出库明细'' AFTER inbound_quantity'));
|
||||
PREPARE procurement_outbound_stmt FROM @ddl; EXECUTE procurement_outbound_stmt; DEALLOCATE PREPARE procurement_outbound_stmt;
|
||||
|
||||
SET @ddl = (SELECT IF(EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
|
||||
+11
-1
@@ -56,5 +56,15 @@ public final class OverseasProcurementRequests {
|
||||
JsonNode overseasCarrier,
|
||||
JsonNode overseasTrackingNo,
|
||||
JsonNode estimatedArrivalAt,
|
||||
JsonNode remark) {}
|
||||
JsonNode remark,
|
||||
JsonNode outboundDetails) {
|
||||
public Update(Long version, String purchaseCategory, String productName, JsonNode productSpecification,
|
||||
JsonNode productUrl, Long inboundQuantity, JsonNode purchaseWarehouseId, JsonNode purchaseWarehouseName,
|
||||
JsonNode domesticCarrier, JsonNode domesticTrackingNo, JsonNode overseasCarrier, JsonNode overseasTrackingNo,
|
||||
JsonNode estimatedArrivalAt, JsonNode remark) {
|
||||
this(version, purchaseCategory, productName, productSpecification, productUrl, inboundQuantity,
|
||||
purchaseWarehouseId, purchaseWarehouseName, domesticCarrier, domesticTrackingNo, overseasCarrier,
|
||||
overseasTrackingNo, estimatedArrivalAt, remark, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -7,6 +7,8 @@ import java.util.List;
|
||||
public final class OverseasProcurementResponses {
|
||||
private OverseasProcurementResponses() {}
|
||||
|
||||
public record OutboundDetail(String id, long quantity, String carrier, String trackingNo, LocalDateTime shippedAt, String remark) {}
|
||||
|
||||
public record Summary(
|
||||
Long id, String orderNo, String customerId, String customerName,
|
||||
String purchaseCategory, String productName, String productSpecification,
|
||||
@@ -32,5 +34,5 @@ public final class OverseasProcurementResponses {
|
||||
String overseasCarrier, String overseasTrackingNo,
|
||||
LocalDateTime estimatedArrivalAt, String remark,
|
||||
String createdBy, String reviewedBy, String reviewRemark, LocalDateTime reviewedAt,
|
||||
List<History> histories) {}
|
||||
List<History> histories, List<OutboundDetail> outboundDetails) {}
|
||||
}
|
||||
|
||||
+1
@@ -30,6 +30,7 @@ public class OverseasProcurementOrder {
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS) private String purchaseWarehouseId;
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS) private String purchaseWarehouseName;
|
||||
private Long inboundQuantity;
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS) private String outboundDetails;
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS) private String domesticCarrier;
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS) private String domesticTrackingNo;
|
||||
@TableField(updateStrategy = FieldStrategy.ALWAYS) private String overseasCarrier;
|
||||
|
||||
+21
-2
@@ -148,7 +148,7 @@ public class OverseasProcurementService {
|
||||
new OverseasProcurementResponses.History(value.getOperationType(), value.getFromStatus(),
|
||||
value.getToStatus(), value.getOperatorId(), value.getIdempotencyKey(),
|
||||
value.getChangeDetail(), value.getRemark(),
|
||||
value.getCreatedAt())).toList());
|
||||
value.getCreatedAt())).toList(), outboundDetails(order));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -205,6 +205,7 @@ public class OverseasProcurementService {
|
||||
patchText(request.overseasTrackingNo(), 128, "overseasTrackingNo", order::setOverseasTrackingNo);
|
||||
patchDateTime(request.estimatedArrivalAt(), order::setEstimatedArrivalAt);
|
||||
patchText(request.remark(), 1000, "remark", order::setRemark);
|
||||
if (request.outboundDetails() != null) order.setOutboundDetails(normalizeOutbound(request.outboundDetails(), order.getInboundQuantity()));
|
||||
Map<String, Object> after = editableSnapshot(order);
|
||||
if (before.equals(after)) return detail(customerId, orderNo);
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
@@ -230,10 +231,11 @@ public class OverseasProcurementService {
|
||||
|
||||
private OverseasProcurementResponses.Summary summary(OverseasProcurementOrder order) {
|
||||
long inbound = value(order.getInboundQuantity());
|
||||
long outbound = outboundDetails(order).stream().mapToLong(OverseasProcurementResponses.OutboundDetail::quantity).sum();
|
||||
return new OverseasProcurementResponses.Summary(order.getId(), order.getOrderNo(), order.getCustomerId(),
|
||||
order.getCustomerName(), order.getPurchaseCategory(), order.getProductName(),
|
||||
order.getProductSpecification(), value(order.getPurchaseQuantity()), order.getBudgetUnitPrice(),
|
||||
order.getCurrency(), order.getPurchaseWarehouseId(), order.getPurchaseWarehouseName(), inbound, inbound,
|
||||
order.getCurrency(), order.getPurchaseWarehouseId(), order.getPurchaseWarehouseName(), inbound, Math.max(0, inbound - outbound),
|
||||
order.getStatus(), value(order.getVersion()), order.getCreatedAt(), order.getUpdatedAt());
|
||||
}
|
||||
|
||||
@@ -336,9 +338,26 @@ public class OverseasProcurementService {
|
||||
result.put("overseasTrackingNo", order.getOverseasTrackingNo());
|
||||
result.put("estimatedArrivalAt", order.getEstimatedArrivalAt());
|
||||
result.put("remark", order.getRemark());
|
||||
result.put("outboundDetails", order.getOutboundDetails());
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<OverseasProcurementResponses.OutboundDetail> outboundDetails(OverseasProcurementOrder order) {
|
||||
if (!StringUtils.hasText(order.getOutboundDetails())) return List.of();
|
||||
try { return objectMapper.readValue(order.getOutboundDetails(), objectMapper.getTypeFactory().constructCollectionType(List.class, OverseasProcurementResponses.OutboundDetail.class)); }
|
||||
catch (JsonProcessingException e) { return List.of(); }
|
||||
}
|
||||
private String normalizeOutbound(JsonNode node, Long inbound) {
|
||||
if (!node.isArray()) throw badRequest("outboundDetails must be an array");
|
||||
long total = 0;
|
||||
for (JsonNode item : node) {
|
||||
if (!item.isObject() || item.path("quantity").asLong(-1) < 0) throw badRequest("outboundDetails quantity must be non-negative");
|
||||
total += item.path("quantity").asLong();
|
||||
}
|
||||
if (total > value(inbound)) throw badRequest("outbound quantity cannot exceed inbound quantity");
|
||||
try { return objectMapper.writeValueAsString(node); } catch (JsonProcessingException e) { throw badRequest("Invalid outboundDetails"); }
|
||||
}
|
||||
|
||||
private String changeDetail(Map<String, Object> before, Map<String, Object> after) {
|
||||
Map<String, Object> changes = new LinkedHashMap<>();
|
||||
before.forEach((field, oldValue) -> {
|
||||
|
||||
@@ -1556,7 +1556,7 @@ CREATE TABLE IF NOT EXISTS ll_overseas_procurement_order (
|
||||
purchase_quantity BIGINT NOT NULL COMMENT '采购数量', budget_unit_price DECIMAL(18,2) NULL COMMENT '预算单价',
|
||||
currency CHAR(3) NOT NULL DEFAULT 'USD' COMMENT '币种', receiving_address VARCHAR(1000) NULL COMMENT '收货地址',
|
||||
contact_name VARCHAR(128) NOT NULL COMMENT '联系人姓名', contact_phone VARCHAR(64) NOT NULL COMMENT '联系人电话',
|
||||
purchase_warehouse_id VARCHAR(128) NULL COMMENT '采购入仓仓库ID', purchase_warehouse_name VARCHAR(255) NULL COMMENT '采购入仓仓库名称',
|
||||
purchase_warehouse_id VARCHAR(128) NULL COMMENT '采购入仓仓库ID', purchase_warehouse_name VARCHAR(255) NULL COMMENT '采购入仓仓库名称', outbound_details JSON NULL COMMENT '出库明细',
|
||||
inbound_quantity BIGINT NOT NULL DEFAULT 0 COMMENT '采购单据累计入库数量',
|
||||
domestic_carrier VARCHAR(128) NULL COMMENT '境内承运商', domestic_tracking_no VARCHAR(128) NULL COMMENT '境内物流单号',
|
||||
overseas_carrier VARCHAR(128) NULL COMMENT '海外承运商', overseas_tracking_no VARCHAR(128) NULL COMMENT '海外物流单号',
|
||||
|
||||
@@ -1093,6 +1093,19 @@ components:
|
||||
overseasTrackingNo: { $ref: '#/components/schemas/NullableTextPatch' }
|
||||
estimatedArrivalAt: { type: string, format: date-time, nullable: true, description: 缺失不修改;null 或空串清空 }
|
||||
remark: { $ref: '#/components/schemas/NullableTextPatch' }
|
||||
outboundDetails:
|
||||
type: array
|
||||
description: 出库明细,可一次提交多条;总出库量不得超过入库量
|
||||
items:
|
||||
type: object
|
||||
required: [quantity]
|
||||
properties:
|
||||
id: { type: string }
|
||||
quantity: { type: integer, format: int64, minimum: 0 }
|
||||
carrier: { type: string, nullable: true, maxLength: 128 }
|
||||
trackingNo: { type: string, nullable: true, maxLength: 128 }
|
||||
shippedAt: { type: string, format: date-time, nullable: true }
|
||||
remark: { type: string, nullable: true, maxLength: 500 }
|
||||
CustomerOptionResponse:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
Reference in New Issue
Block a user