fix(order): project exact customer fulfillment progress in detail

This commit is contained in:
2026-10-15 19:46:34 +08:00
parent 097bec33b1
commit ae33780dae
27 changed files with 391 additions and 50 deletions
@@ -20,6 +20,6 @@ public class InternalCustomerOrderProgressController {
@RequestHeader(value="X-Internal-Service-Token", required=false) String token,
@Valid @RequestBody CustomerOrderProgress.Request request) {
guard.verify(token);
return ApiResponse.success(service.read(request.customerId()));
return ApiResponse.success(service.read(request.customerId(), request.orderIds()));
}
}
@@ -6,7 +6,8 @@ import java.util.List;
public final class CustomerOrderProgress {
private CustomerOrderProgress() {}
public record Request(@NotNull @Positive Long customerId) {}
public record Request(@NotNull @Positive Long customerId,
@jakarta.validation.constraints.Size(min=1,max=200) List<@NotNull @Positive Long> orderIds) {}
public record Source(String orderId, long packages, long scheduledPackages, long deliveringPackages) {}
public record Progress(long orderId, String stage, boolean partial) {}
public record Response(List<Progress> progress) {}
@@ -8,12 +8,17 @@ import java.util.List;
@Mapper
public interface CustomerOrderProgressMapper {
@Select("""
<script>
WITH scheduled AS (
SELECT line.order_id,SUM(a.planned_package_count) AS packages
FROM ll_dispatch_order d
JOIN ll_dispatch_item i ON i.dispatch_order_id=d.id AND i.customer_id=d.customer_id
JOIN ll_inbound_plan_pallet_allocation a ON a.pallet_id=i.plan_pallet_id
JOIN ll_inbound_plan_line line ON line.id=a.line_id AND line.customer_id=d.customer_id
<if test="orderIds != null">
JOIN ll_order planned_source ON planned_source.id=line.order_id AND planned_source.customer_id=#{customerId}
AND planned_source.source_order_id IN <foreach collection="orderIds" item="id" open="(" separator="," close=")">#{id}</foreach>
</if>
WHERE d.customer_id=#{customerId} AND d.status IN ('PENDING_DEPARTURE','PICKING','READY_TO_DEPART')
AND i.warehouse_pallet_id IS NULL
GROUP BY line.order_id
@@ -24,14 +29,32 @@ public interface CustomerOrderProgressMapper {
JOIN ll_inventory_position p ON p.customer_id=d.customer_id AND p.pallet_id=i.warehouse_pallet_id
AND p.overseas_warehouse_id=i.overseas_warehouse_id
JOIN ll_inventory_balance b ON b.id=p.balance_id AND b.customer_id=d.customer_id
LEFT JOIN (SELECT dispatch_item_id,inventory_position_id,SUM(packages) AS packages
FROM ll_dispatch_pda_pick WHERE customer_id=#{customerId}
GROUP BY dispatch_item_id,inventory_position_id) pk
<if test="orderIds != null">
JOIN ll_order stock_source ON stock_source.id=b.inbound_order_id AND stock_source.customer_id=#{customerId}
AND stock_source.source_order_id IN <foreach collection="orderIds" item="id" open="(" separator="," close=")">#{id}</foreach>
</if>
LEFT JOIN (SELECT pick.dispatch_item_id,pick.inventory_position_id,SUM(pick.packages) AS packages
FROM ll_dispatch_pda_pick pick
<if test="orderIds != null">
JOIN ll_inventory_position scoped_position ON scoped_position.id=pick.inventory_position_id
AND scoped_position.customer_id=pick.customer_id
JOIN ll_inventory_balance scoped_balance ON scoped_balance.id=scoped_position.balance_id
AND scoped_balance.customer_id=pick.customer_id
JOIN ll_order scoped_order ON scoped_order.id=scoped_balance.inbound_order_id
AND scoped_order.customer_id=pick.customer_id
AND scoped_order.source_order_id IN <foreach collection="orderIds" item="id" open="(" separator="," close=")">#{id}</foreach>
</if>
WHERE pick.customer_id=#{customerId}
GROUP BY pick.dispatch_item_id,pick.inventory_position_id) pk
ON pk.dispatch_item_id=i.id AND pk.inventory_position_id=p.id
WHERE d.customer_id=#{customerId} AND d.status IN ('PENDING_DEPARTURE','PICKING','READY_TO_DEPART')
AND (i.plan_pallet_id IS NULL OR EXISTS (
SELECT 1 FROM ll_inbound_plan_pallet_allocation a
JOIN ll_inbound_plan_line line ON line.id=a.line_id AND line.customer_id=d.customer_id
<if test="orderIds != null">
JOIN ll_order planned_source ON planned_source.id=line.order_id AND planned_source.customer_id=#{customerId}
AND planned_source.source_order_id IN <foreach collection="orderIds" item="id" open="(" separator="," close=")">#{id}</foreach>
</if>
WHERE a.pallet_id=i.plan_pallet_id AND line.order_id=b.inbound_order_id))
GROUP BY b.inbound_order_id
), departed AS (
@@ -41,6 +64,10 @@ public interface CustomerOrderProgressMapper {
JOIN ll_dispatch_pda_task t ON t.id=p.task_id AND t.customer_id=a.customer_id
JOIN ll_dispatch_order ds ON ds.id=t.dispatch_order_id AND ds.customer_id=a.customer_id
JOIN ll_dispatch_item i ON i.id=p.dispatch_item_id AND i.dispatch_order_id=ds.id AND i.customer_id=a.customer_id
<if test="orderIds != null">
JOIN ll_order departed_source ON departed_source.id=a.order_id AND departed_source.customer_id=#{customerId}
AND departed_source.source_order_id IN <foreach collection="orderIds" item="id" open="(" separator="," close=")">#{id}</foreach>
</if>
WHERE a.customer_id=#{customerId} AND ds.status='DEPARTED' AND ds.depart_at IS NOT NULL
AND EXISTS (
SELECT 1 FROM ll_delivery_order d
@@ -62,7 +89,11 @@ public interface CustomerOrderProgressMapper {
FROM ll_order o WHERE o.customer_id=#{customerId} AND o.source_region='FIRSTLEG'
AND o.source_order_id IS NOT NULL AND o.source_inbound_id IS NOT NULL
AND o.order_type NOT IN ('RELABEL_APPLICATION','WAREHOUSE_TRANSFER')
<if test="orderIds != null">
AND o.source_order_id IN <foreach collection="orderIds" item="id" open="(" separator="," close=")">#{id}</foreach>
</if>
ORDER BY o.id
</script>
""")
List<CustomerOrderProgress.Source> sources(@Param("customerId") String customerId);
List<CustomerOrderProgress.Source> sources(@Param("customerId") String customerId, @Param("orderIds") List<String> orderIds);
}
@@ -12,8 +12,8 @@ public class CustomerOrderProgressService {
private final CustomerOrderProgressMapper mapper;
public CustomerOrderProgressService(CustomerOrderProgressMapper mapper) { this.mapper = mapper; }
@Transactional(readOnly=true)
public CustomerOrderProgress.Response read(long customerId) {
return new CustomerOrderProgress.Response(project(mapper.sources(Long.toString(customerId))));
public CustomerOrderProgress.Response read(long customerId, List<Long> orderIds) {
return new CustomerOrderProgress.Response(project(mapper.sources(Long.toString(customerId), orderIds == null ? null : orderIds.stream().map(String::valueOf).toList())));
}
static List<CustomerOrderProgress.Progress> project(List<CustomerOrderProgress.Source> sources) {
return sources.stream().collect(Collectors.groupingBy(CustomerOrderProgress.Source::orderId))