Files
baiyue-firstleg/common-event-contract/src/main/java/com/baiyue/common/event/FirstLegLoadingPlanCompletedV2.java
T

168 lines
9.9 KiB
Java
Raw Normal View History

2026-08-18 16:03:42 +08:00
package com.baiyue.common.event;
import com.fasterxml.jackson.annotation.JsonProperty;
2026-08-18 16:03:42 +08:00
import java.math.BigDecimal;
import java.util.List;
/** 装柜完成交接快照,包含三类逐货物备注、推荐托数和可复用的头程托盘编号快照。 */
2026-08-18 16:03:42 +08:00
public record FirstLegLoadingPlanCompletedV2(
String loadingPlanId, String planNo,
@JsonProperty("sourceContainerBookingId") String containerBookingId,
2026-08-18 16:03:42 +08:00
String containerNo, String cabinetNo, String warehouseId, String warehouseName,
2026-08-27 16:42:27 +08:00
String estimatedPortArrivalAt, String actualPortArrivalAt, String estimatedWarehouseArrivalAt,
2026-08-18 16:03:42 +08:00
List<Order> orders) {
public FirstLegLoadingPlanCompletedV2 {
if (loadingPlanId == null || loadingPlanId.isBlank()
|| containerBookingId == null || containerBookingId.isBlank()) {
throw new IllegalArgumentException("loadingPlanId and sourceContainerBookingId are required");
}
containerNo = ContainerNumbers.requireCanonical(containerNo);
orders = orders == null ? List.of() : List.copyOf(orders);
if (orders.isEmpty()) throw new IllegalArgumentException("orders are required");
2026-09-01 11:06:26 +08:00
Order owner = orders.get(0);
if (orders.stream().anyMatch(order -> !owner.customerId().equals(order.customerId())
|| !owner.customerName().equals(order.customerName()))) {
throw new IllegalArgumentException("orders must share one immutable customerId/customerName snapshot");
}
}
2026-08-27 16:42:27 +08:00
public FirstLegLoadingPlanCompletedV2(String loadingPlanId, String planNo, String containerBookingId,
String containerNo, String cabinetNo, String warehouseId,
String warehouseName, List<Order> orders) {
this(loadingPlanId, planNo, containerBookingId, containerNo, cabinetNo, warehouseId,
warehouseName, null, null, null, orders);
}
public record Order(
String sourceInboundId, String rootInboundId,
String sourceOrderId, String sourceOrderNo, String rootOrderId,
String inboundCode, String destinationWarehouseId,
String destinationWarehouseCode, String destinationWarehouseName,
int packageCount, Integer productQuantity, Integer palletCount,
BigDecimal grossWeightKg, BigDecimal netWeightKg, BigDecimal volumeCbm,
2026-08-27 16:42:27 +08:00
BigDecimal volumeWeightKg,
2026-08-27 15:56:14 +08:00
List<Item> items, String customerId, String customerName, String orderType, List<PalletSnapshot> pallets,
2026-08-24 17:15:48 +08:00
/** 目的类型:FBA 可按箱数收货,OVERSEAS 必须逐箱扫码。 */
2026-09-06 16:02:11 +08:00
String destinationType, String lxCode) {
public Order {
items = items == null ? List.of() : items;
2026-08-27 15:56:14 +08:00
if (customerId == null || customerId.isBlank()) {
throw new IllegalArgumentException("customerId is required");
}
if (customerName == null || customerName.isBlank()) {
throw new IllegalArgumentException("customerName is required");
}
2026-09-01 11:06:26 +08:00
customerId = customerId.trim();
customerName = customerName.trim();
if (customerId.length() > 128 || customerName.length() > 128) {
throw new IllegalArgumentException("customerId/customerName snapshot is too long");
}
orderType = orderType == null || orderType.isBlank() ? "FIRST_LEG" : orderType;
pallets = pallets == null ? List.of() : pallets;
}
2026-08-24 17:15:48 +08:00
public Order(String sourceInboundId, String rootInboundId,
String sourceOrderId, String sourceOrderNo, String rootOrderId,
String inboundCode, String destinationWarehouseId,
String destinationWarehouseCode, String destinationWarehouseName,
int packageCount, Integer productQuantity, Integer palletCount,
BigDecimal grossWeightKg, BigDecimal netWeightKg, BigDecimal volumeCbm,
2026-08-27 15:56:14 +08:00
List<Item> items, String customerId, String customerName,
String orderType, List<PalletSnapshot> pallets) {
2026-08-24 17:15:48 +08:00
this(sourceInboundId, rootInboundId, sourceOrderId, sourceOrderNo, rootOrderId,
inboundCode, destinationWarehouseId, destinationWarehouseCode,
destinationWarehouseName, packageCount, productQuantity, palletCount,
2026-08-27 16:42:27 +08:00
grossWeightKg, netWeightKg, volumeCbm, null, items, customerId, customerName,
2026-09-06 16:02:11 +08:00
orderType, pallets, null, null);
}
2026-08-27 16:42:27 +08:00
public Order(String sourceInboundId, String rootInboundId,
String sourceOrderId, String sourceOrderNo, String rootOrderId,
String inboundCode, String destinationWarehouseId,
String destinationWarehouseCode, String destinationWarehouseName,
int packageCount, Integer productQuantity, Integer palletCount,
BigDecimal grossWeightKg, BigDecimal netWeightKg, BigDecimal volumeCbm,
List<Item> items, String customerId, String customerName,
String orderType, List<PalletSnapshot> pallets, String destinationType) {
this(sourceInboundId, rootInboundId, sourceOrderId, sourceOrderNo, rootOrderId,
inboundCode, destinationWarehouseId, destinationWarehouseCode,
destinationWarehouseName, packageCount, productQuantity, palletCount,
grossWeightKg, netWeightKg, volumeCbm, null, items, customerId, customerName,
2026-09-06 16:02:11 +08:00
orderType, pallets, destinationType, null);
}
public Order(String sourceInboundId, String rootInboundId,
String sourceOrderId, String sourceOrderNo, String rootOrderId,
String inboundCode, String destinationWarehouseId,
String destinationWarehouseCode, String destinationWarehouseName,
int packageCount, Integer productQuantity, Integer palletCount,
BigDecimal grossWeightKg, BigDecimal netWeightKg, BigDecimal volumeCbm,
BigDecimal volumeWeightKg, List<Item> items, String customerId, String customerName,
String orderType, List<PalletSnapshot> pallets, String destinationType) {
this(sourceInboundId, rootInboundId, sourceOrderId, sourceOrderNo, rootOrderId,
inboundCode, destinationWarehouseId, destinationWarehouseCode, destinationWarehouseName,
packageCount, productQuantity, palletCount, grossWeightKg, netWeightKg, volumeCbm,
volumeWeightKg, items, customerId, customerName, orderType, pallets, destinationType, null);
2026-08-27 16:42:27 +08:00
}
}
public record Item(
String sourceInboundDetailId, String skuCode,
String productNameZh, String productNameEn,
int packageCount, Integer productQuantity, Integer palletCount,
BigDecimal grossWeightKg, BigDecimal netWeightKg,
BigDecimal dimensionalWeightKg, BigDecimal volumeCbm,
String destinationWarehouseId, String destinationWarehouseCode,
String destinationWarehouseName, String fbaTrackingNo,
String shipmentNo, String shippingMark,
String customerRemark, String internalRemark, String warehouseRemark,
2026-08-20 16:45:47 +08:00
String palletNo,
2026-08-22 10:16:45 +08:00
/** 按实装箱数稳定随机冻结的头程箱号;数量与 packageCount 相等且均对应本明细 SKU。 */
2026-08-20 16:45:47 +08:00
List<String> cartonMarks) {
public Item {
cartonMarks = cartonMarks == null ? List.of() : cartonMarks;
}
public Item(String sourceInboundDetailId, String skuCode,
String productNameZh, String productNameEn,
int packageCount, Integer productQuantity, Integer palletCount,
BigDecimal grossWeightKg, BigDecimal netWeightKg,
BigDecimal dimensionalWeightKg, BigDecimal volumeCbm,
String destinationWarehouseId, String destinationWarehouseCode,
String destinationWarehouseName, String fbaTrackingNo,
String shipmentNo, String shippingMark,
String customerRemark, String internalRemark, String warehouseRemark) {
this(sourceInboundDetailId, skuCode, productNameZh, productNameEn, packageCount,
productQuantity, palletCount, grossWeightKg, netWeightKg,
dimensionalWeightKg, volumeCbm, destinationWarehouseId,
destinationWarehouseCode, destinationWarehouseName, fbaTrackingNo,
shipmentNo, shippingMark, customerRemark, internalRemark, warehouseRemark,
null, List.of());
}
}
/** 普通 FBA 只复用 palletNo;一件代发还携带同一物理 DP 的完整清单摘要。 */
public record PalletSnapshot(String palletNo, List<SkuPackageSnapshot> skuPackages,
Integer manifestVersion, Integer manifestPackageCount,
Integer manifestFragmentCount, String manifestHash) {
public PalletSnapshot {
skuPackages = skuPackages == null ? List.of() : List.copyOf(skuPackages);
}
public PalletSnapshot(String palletNo, List<SkuPackageSnapshot> skuPackages) {
this(palletNo, skuPackages, null, null, null, null);
}
}
/** 托盘下来源入库明细、SKU、箱数、数量及箱号冻结快照;同 SKU 多明细按 sourceInboundDetailId 精确区分。 */
public record SkuPackageSnapshot(String sourceInboundDetailId, String skuCode, String productName,
int packageCount, int productQuantity,
List<String> cartonMarks) {
public SkuPackageSnapshot {
if (sourceInboundDetailId == null || sourceInboundDetailId.isBlank()) {
throw new IllegalArgumentException("sourceInboundDetailId is required for each pallet SKU snapshot");
}
}
}
2026-08-18 16:03:42 +08:00
}