feat: explain supplemental pallet counts

This commit is contained in:
2026-09-11 15:39:38 +08:00
parent cc7c2f0954
commit 774f0472e8
7 changed files with 89 additions and 34 deletions
@@ -17,6 +17,8 @@ public record ContainerInboundPlanPreviewResponse(
int blockedOrderCount,
int pendingOrderCount,
int pendingPalletCount,
int sourcePalletCount,
int supplementPalletCount,
int existingPlannedPalletCount,
int totalSuggestedPalletCount,
int totalPlannedPalletCount,
@@ -31,6 +33,8 @@ public record ContainerInboundPlanPreviewResponse(
int orderCount,
int pendingOrderCount,
int pendingPalletCount,
int sourcePalletCount,
int supplementPalletCount,
int existingPlannedPalletCount,
int suggestedPalletCount,
int plannedPalletCount,
@@ -52,6 +56,9 @@ public record ContainerInboundPlanPreviewResponse(
int packageCount,
BigDecimal volumeCbm,
Integer suggestedPalletCount,
int sourcePalletCount,
int targetPalletCount,
int supplementPalletCount,
Integer plannedPalletCount,
String existingPlanNo,
String planStatus,
@@ -27,7 +27,7 @@ public interface InboundPlanOrderMapper {
String overseasWarehouseName, String fbaWarehouseCode, String destinationWarehouseId,
String destinationWarehouseCode, String destinationWarehouseName, int destinationCount,
boolean detained, int version, String planNo, String planStatus,
Integer plannedPalletCount, Integer materializedPalletCount
Integer plannedPalletCount, Integer materializedPalletCount, Integer sourcePalletCount
) { }
@Select("SELECT o.customer_id AS customerId,o.id AS orderId,o.order_no AS orderNo," +
@@ -45,7 +45,9 @@ public interface InboundPlanOrderMapper {
"o.detained AS detained,o.version AS version,p.plan_no AS planNo,p.status AS planStatus," +
"p.pallet_count AS plannedPalletCount," +
"(SELECT COUNT(*) FROM ll_inbound_plan_pallet pp WHERE pp.customer_id=p.customer_id " +
"AND pp.plan_id=p.id AND pp.warehouse_pallet_id IS NOT NULL) AS materializedPalletCount " +
"AND pp.plan_id=p.id AND pp.warehouse_pallet_id IS NOT NULL) AS materializedPalletCount," +
"(SELECT COUNT(*) FROM ll_order_source_pallet sp WHERE sp.customer_id=o.customer_id " +
"AND sp.order_id=o.id) AS sourcePalletCount " +
"FROM ll_order o LEFT JOIN ll_inbound_plan p ON p.customer_id=o.customer_id AND p.source_order_id=o.id " +
"WHERE o.source_container_booking_id=#{sourceContainerBookingId} ORDER BY o.customer_id,o.id")
List<ContainerPreviewOrderRow> containerPreviewOrders(
@@ -207,6 +207,10 @@ public class InboundPlanService {
items.stream().filter(InboundPlanService::requiresContainerConversion)
.map(InboundPlanService::pendingPalletCount)
.filter(Objects::nonNull).mapToInt(Integer::intValue).sum(),
items.stream().filter(InboundPlanService::requiresContainerConversion)
.mapToInt(ContainerInboundPlanPreviewResponse.Order::sourcePalletCount).sum(),
items.stream().filter(InboundPlanService::requiresContainerConversion)
.mapToInt(ContainerInboundPlanPreviewResponse.Order::supplementPalletCount).sum(),
items.stream().filter(item -> "PLANNED".equals(item.readiness()))
.map(ContainerInboundPlanPreviewResponse.Order::plannedPalletCount)
.filter(Objects::nonNull).mapToInt(Integer::intValue).sum(),
@@ -220,6 +224,10 @@ public class InboundPlanService {
int pendingPallets = orders.stream().filter(InboundPlanService::requiresContainerConversion)
.map(InboundPlanService::pendingPalletCount)
.filter(Objects::nonNull).mapToInt(Integer::intValue).sum();
int sourcePallets = orders.stream().filter(InboundPlanService::requiresContainerConversion)
.mapToInt(ContainerInboundPlanPreviewResponse.Order::sourcePalletCount).sum();
int supplementPallets = orders.stream().filter(InboundPlanService::requiresContainerConversion)
.mapToInt(ContainerInboundPlanPreviewResponse.Order::supplementPalletCount).sum();
int existingPallets = orders.stream().filter(item -> "PLANNED".equals(item.readiness()))
.map(ContainerInboundPlanPreviewResponse.Order::plannedPalletCount)
.filter(Objects::nonNull).mapToInt(Integer::intValue).sum();
@@ -228,7 +236,7 @@ public class InboundPlanService {
bookingId, containerNo, warehouseId, snapshotVersion, orders));
return new ContainerInboundPlanPreviewResponse(bookingId, containerNo, warehouseId, warehouseCode,
warehouseName, snapshotVersion, snapshotHash, orders.size(), orders.size() - blocked, blocked,
pendingOrders, pendingPallets, existingPallets,
pendingOrders, pendingPallets, sourcePallets, supplementPallets, existingPallets,
orders.stream().map(ContainerInboundPlanPreviewResponse.Order::suggestedPalletCount)
.filter(Objects::nonNull).mapToInt(Integer::intValue).sum(),
orders.stream().map(ContainerInboundPlanPreviewResponse.Order::plannedPalletCount)
@@ -258,6 +266,12 @@ public class InboundPlanService {
|| row.packageCount() > 0 && row.volumeCbm().signum() == 0) blockers.add("CARGO_FACT_INVALID");
}
Integer suggested = suggestedPalletCount(row, blockers);
int sourcePalletCount = "ONE_CLICK_DROPSHIP".equals(row.orderType())
? Objects.requireNonNullElse(suggested, 0)
: Objects.requireNonNullElse(row.sourcePalletCount(), 0);
int targetPalletCount = Objects.requireNonNullElse(row.plannedPalletCount(),
Objects.requireNonNullElse(suggested, 0));
int supplementPalletCount = Math.max(0, targetPalletCount - sourcePalletCount);
if (!planned && (suggested == null || suggested <= 0)) blockers.add("PALLET_COUNT_NOT_READY");
String destinationType = destinationType(row);
String fbaWarehouseCode = isFbaDestination(row) ? trimToNull(row.fbaWarehouseCode()) : null;
@@ -281,7 +295,8 @@ public class InboundPlanService {
String.valueOf(row.orderId()), trimToNull(row.orderNo()) == null ? row.sourceOrderNo() : row.orderNo(),
row.inboundCode(), row.orderType(), destinationType, row.destinationWarehouseId(),
destinationCode, row.destinationWarehouseName(), fbaWarehouseCode, row.packageCount(), row.volumeCbm(),
suggested, row.plannedPalletCount(), row.planNo(), row.planStatus(), row.version(), readiness,
suggested, sourcePalletCount, targetPalletCount, supplementPalletCount,
row.plannedPalletCount(), row.planNo(), row.planStatus(), row.version(), readiness,
List.copyOf(blockers));
}
@@ -321,9 +336,7 @@ public class InboundPlanService {
}
private static Integer pendingPalletCount(ContainerInboundPlanPreviewResponse.Order order) {
return "RESOURCE_PENDING".equals(order.readiness())
? Objects.requireNonNullElse(order.plannedPalletCount(), 0)
: Objects.requireNonNullElse(order.suggestedPalletCount(), 0);
return order.targetPalletCount();
}
private static String destinationType(InboundPlanOrderMapper.ContainerPreviewOrderRow row) {