package com.baiyue.lastleg.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baiyue.lastleg.entity.LastlegOrder; import com.baiyue.lastleg.dto.LastlegOrderRequests; import com.baiyue.lastleg.dto.ContainerPlanProgressDetail; import com.baiyue.lastleg.dto.ContainerPlanProgressSummary; import com.baiyue.lastleg.dto.ContainerArrivalTimeView; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import java.util.List; import java.math.BigDecimal; @Mapper public interface LastlegOrderMapper extends BaseMapper { String WAREHOUSE_FILTER_SQL = "(LOWER(TRIM(overseas_warehouse_code)) LIKE CONCAT('%',LOWER({0}),'%') " + "OR LOWER(TRIM(overseas_warehouse_name)) LIKE CONCAT('%',LOWER({0}),'%'))"; @Select("") List findDispatchStatuses(@Param("orderIds") List orderIds); record DispatchStatusRow(Long orderId, String dispatchStatus) { } record OrderWeightRow(Long orderId, BigDecimal grossWeightKg, BigDecimal netWeightKg) { } @Select("") List findOrderWeights(@Param("orderIds") List orderIds); String CONTAINER_PROGRESS_FILTER = " 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 IS NOT NULL AND o.source_container_booking_id<>'' " + "AND o.container_no LIKE CONCAT('%',#{q.containerNo},'%') " + "AND o.created_at >=#{q.createdFrom} " + "AND o.created_at <=#{q.createdTo} " + "GROUP BY o.source_container_booking_id "; String CONTAINER_PROGRESS_COLUMNS = "SELECT o.source_container_booking_id AS sourceContainerBookingId," + "CASE WHEN COUNT(NULLIF(o.container_no,''))=COUNT(*) AND COUNT(DISTINCT NULLIF(o.container_no,''))=1 " + "THEN MAX(NULLIF(o.container_no,'')) ELSE NULL END AS containerNo," + "CASE WHEN COUNT(DISTINCT NULLIF(o.overseas_warehouse_id,''))=1 THEN MAX(o.overseas_warehouse_id) ELSE NULL END AS overseasWarehouseId," + "CASE WHEN COUNT(DISTINCT NULLIF(o.overseas_warehouse_code,''))=1 THEN MAX(o.overseas_warehouse_code) ELSE NULL END AS overseasWarehouseCode," + "CASE WHEN COUNT(DISTINCT NULLIF(o.overseas_warehouse_name,''))=1 THEN MAX(o.overseas_warehouse_name) ELSE NULL END AS overseasWarehouseName," + "CASE WHEN COUNT(DISTINCT o.receiving_warehouse_version)=1 THEN MAX(o.receiving_warehouse_version) ELSE -1 END AS assignmentVersion," + "CASE WHEN COUNT(DISTINCT o.receiving_warehouse_version)=1 AND NOT EXISTS (SELECT 1 FROM ll_receiving_container_session s WHERE s.source_container_booking_id=o.source_container_booking_id) THEN TRUE ELSE FALSE END AS canChangeReceivingWarehouse," + "CASE WHEN COUNT(DISTINCT o.receiving_warehouse_version)<>1 THEN '柜内接柜仓分配版本不一致' " + "WHEN EXISTS (SELECT 1 FROM ll_receiving_container_session s WHERE s.source_container_booking_id=o.source_container_booking_id) THEN '海外PDA已建立接柜会话,接柜仓已永久锁定' ELSE NULL END AS receivingWarehouseLockReason," + "COUNT(*) AS totalOrderCount,COUNT(DISTINCT NULLIF(TRIM(o.inbound_code),'')) AS inboundCodeCount," + "SUM(CASE WHEN NULLIF(TRIM(o.inbound_code),'') IS NULL THEN 1 ELSE 0 END) AS missingInboundCodeCount," + "COUNT(DISTINCT p.id) AS planCount," + "COUNT(DISTINCT CASE WHEN p.id IS NOT NULL AND NULLIF(TRIM(p.plan_no),'') IS NOT NULL " + "AND NULLIF(TRIM(p.status),'') IS NOT NULL THEN NULLIF(TRIM(o.inbound_code),'') END) AS plannedInboundCodeCount," + "SUM(CASE WHEN p.id IS NULL OR NULLIF(TRIM(p.plan_no),'') IS NULL OR NULLIF(TRIM(p.status),'') IS NULL " + "THEN 1 ELSE 0 END) AS pendingPlanCount," + "SUM(CASE WHEN p.id IS NOT NULL AND p.status IN ('PENDING_ASSIGNMENT','SIGNED') " + "AND COALESCE(p.pallet_count,0)>0 AND " + "(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)<COALESCE(p.pallet_count,0) " + "THEN 1 ELSE 0 END) AS resourcePendingPlanCount," + "CASE WHEN COUNT(o.estimated_warehouse_at)=COUNT(*) " + "AND COUNT(DISTINCT o.estimated_warehouse_at)=1 THEN MAX(o.estimated_warehouse_at) ELSE NULL END AS plannedArrivalAt," + "CASE WHEN SUM(CASE WHEN NULLIF(TRIM(o.inbound_code),'') IS NULL THEN 1 ELSE 0 END)=0 " + "AND SUM(CASE WHEN p.id IS NULL OR NULLIF(TRIM(p.plan_no),'') IS NULL OR NULLIF(TRIM(p.status),'') IS NULL " + "THEN 1 ELSE 0 END)=0 AND COUNT(DISTINCT p.id)=COUNT(*) " + "AND COUNT(NULLIF(o.container_no,''))=COUNT(*) AND COUNT(DISTINCT NULLIF(o.container_no,''))=1 " + "THEN TRUE ELSE FALSE END AS allPlansReady," + "CASE WHEN COUNT(NULLIF(o.container_no,''))<>COUNT(*) " + "OR COUNT(DISTINCT NULLIF(o.container_no,''))<>1 THEN '柜号缺失或不一致' " + "WHEN SUM(CASE WHEN NULLIF(TRIM(o.inbound_code),'') IS NULL THEN 1 ELSE 0 END)>0 " + "THEN CONCAT('存在',SUM(CASE WHEN NULLIF(TRIM(o.inbound_code),'') IS NULL THEN 1 ELSE 0 END),'票缺少入仓码') " + "WHEN SUM(CASE WHEN p.id IS NULL OR NULLIF(TRIM(p.plan_no),'') IS NULL OR NULLIF(TRIM(p.status),'') IS NULL " + "THEN 1 ELSE 0 END)>0 THEN CONCAT('存在',SUM(CASE WHEN p.id IS NULL OR NULLIF(TRIM(p.plan_no),'') IS NULL " + "OR NULLIF(TRIM(p.status),'') IS NULL THEN 1 ELSE 0 END),'票尚未生成有效入库计划') " + "WHEN COUNT(DISTINCT p.id)<>COUNT(*) THEN '入库计划与尾程订单关联不一致' ELSE NULL END AS blockingReason "; @Select("") List pageContainerProgress( @Param("q") LastlegOrderRequests.ContainerProgressQuery query, @Param("offset") long offset, @Param("limit") long limit); @Select("") long countContainerProgress(@Param("q") LastlegOrderRequests.ContainerProgressQuery query); @Select("") ContainerPlanProgressSummary findContainerProgress( @Param("sourceContainerBookingId") String sourceContainerBookingId); @Select("SELECT o.id AS orderId,o.customer_id AS customerId,o.order_no AS orderNo,o.inbound_code AS inboundCode," + "o.current_status AS orderStatus,p.id AS planId,p.plan_no AS planNo,p.status AS planStatus," + "CASE WHEN p.id IS NOT NULL AND NULLIF(TRIM(p.plan_no),'') IS NOT NULL " + "AND NULLIF(TRIM(p.status),'') IS NOT NULL THEN TRUE ELSE FALSE END AS planValid," + "o.estimated_warehouse_at AS plannedArrivalAt 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 CASE WHEN o.estimated_warehouse_at IS NULL THEN 1 ELSE 0 END," + "o.estimated_warehouse_at ASC,o.customer_id ASC,o.id ASC") List findContainerProgressItems( @Param("sourceContainerBookingId") String sourceContainerBookingId); record PalletMergeRelationRow(Long orderId, String relatedInboundNo, String mergeGroupNo) {} @Select("") List findPalletMergeRelations(@Param("orderIds") List orderIds); @Select("SELECT * FROM ll_order WHERE customer_id=#{customerId} AND source_region=#{sourceRegion} " + "AND source_inbound_id=#{sourceInboundId} LIMIT 1") LastlegOrder findSource(@Param("customerId") String customerId, @Param("sourceRegion") String sourceRegion, @Param("sourceInboundId") String sourceInboundId); @Select("SELECT container_no FROM ll_order WHERE source_container_booking_id=#{sourceContainerBookingId} " + "ORDER BY customer_id,id FOR UPDATE") List lockContainerNumbers( @Param("sourceContainerBookingId") String sourceContainerBookingId); @Select("SELECT * FROM ll_order WHERE source_container_booking_id=#{sourceContainerBookingId} ORDER BY customer_id,id FOR UPDATE") List lockContainerOrders(@Param("sourceContainerBookingId") String sourceContainerBookingId); @Select("") List findContainerArrivalTimes(@Param("bookingIds") List bookingIds); @Update("UPDATE ll_order SET estimated_warehouse_at=#{estimatedAt},arrival_time_version=arrival_time_version+1," + "version=version+1,updated_at=NOW(3) WHERE source_container_booking_id=#{bookingId} " + "AND arrival_time_version=#{expectedVersion}") int updateContainerExpectedWarehouseArrival(@Param("bookingId") String bookingId, @Param("estimatedAt") java.time.LocalDateTime estimatedAt, @Param("expectedVersion") int expectedVersion); @Select("SELECT COUNT(*) FROM ll_inbound_plan p JOIN ll_order o " + "ON o.id=p.source_order_id AND o.customer_id=p.customer_id " + "WHERE o.source_container_booking_id=#{bookingId}") long countContainerPlans(@Param("bookingId") String bookingId); @Select("SELECT COUNT(*) FROM ll_receiving_container_session WHERE source_container_booking_id=#{sourceContainerBookingId}") long countReceivingSessions(@Param("sourceContainerBookingId") String sourceContainerBookingId); @Update("UPDATE ll_order SET overseas_warehouse_id=#{warehouseId},overseas_warehouse_code=#{warehouseCode}," + "overseas_warehouse_name=#{warehouseName},receiving_warehouse_version=receiving_warehouse_version+1,updated_at=NOW(3) " + "WHERE source_container_booking_id=#{sourceContainerBookingId} AND receiving_warehouse_version=#{expectedVersion}") int updateContainerReceivingWarehouse(@Param("sourceContainerBookingId") String sourceContainerBookingId, @Param("warehouseId") String warehouseId, @Param("warehouseCode") String warehouseCode, @Param("warehouseName") String warehouseName, @Param("expectedVersion") int expectedVersion); @Update("UPDATE ll_inbound_plan p JOIN ll_order o ON o.id=p.source_order_id AND o.customer_id=p.customer_id " + "SET p.overseas_warehouse_id=#{warehouseId},p.version=p.version+1,p.updated_at=NOW(3) " + "WHERE o.source_container_booking_id=#{sourceContainerBookingId}") int updateContainerPlanReceivingWarehouse(@Param("sourceContainerBookingId") String sourceContainerBookingId, @Param("warehouseId") long warehouseId); @Select("SELECT COUNT(*) FROM ll_order WHERE customer_id=#{customerId} AND container_no=#{containerNo}") long countContainer(@Param("customerId") String customerId, @Param("containerNo") String containerNo); @Select("SELECT * FROM ll_order WHERE customer_id=#{customerId} AND id=#{id} FOR UPDATE") LastlegOrder lockById(@Param("customerId") String customerId, @Param("id") Long id); @Update("UPDATE ll_order SET detained=#{held},hold_chargeable=#{chargeable}," + "hold_reason=CASE WHEN #{held}=1 THEN #{reason} ELSE NULL END,version=version+1,updated_at=#{updatedAt} " + "WHERE customer_id=#{customerId} AND id=#{id} AND version=#{expectedVersion}") int updateHold(@Param("customerId") String customerId, @Param("id") long id, @Param("held") boolean held, @Param("chargeable") boolean chargeable, @Param("reason") String reason, @Param("expectedVersion") int expectedVersion, @Param("updatedAt") java.time.LocalDateTime updatedAt); @Update("UPDATE ll_order SET manual_node_override=1,estimated_arrival_at=#{estimatedArrivalAt}," + "actual_arrival_at=#{actualArrivalAt},estimated_warehouse_at=#{estimatedWarehouseAt}," + "version=version+1,updated_at=#{updatedAt} WHERE customer_id=#{customerId} AND id=#{id} " + "AND version=#{expectedVersion}") int updateManualNodes(@Param("customerId") String customerId, @Param("id") long id, @Param("estimatedArrivalAt") java.time.LocalDateTime estimatedArrivalAt, @Param("actualArrivalAt") java.time.LocalDateTime actualArrivalAt, @Param("estimatedWarehouseAt") java.time.LocalDateTime estimatedWarehouseAt, @Param("expectedVersion") int expectedVersion, @Param("updatedAt") java.time.LocalDateTime updatedAt); @Update("UPDATE ll_order SET picked_package_count=picked_package_count+#{packages},updated_at=NOW() " + "WHERE customer_id=#{customerId} AND id=#{id} AND detained=0 " + "AND package_count-shipped_package_count-picked_package_count >= #{packages}") int increasePicked(@Param("customerId") String customerId, @Param("id") Long id, @Param("packages") long packages); @Update("UPDATE ll_order SET current_status=CASE WHEN shipped_package_count+#{packages}=package_count " + "THEN 'COMPLETED' ELSE 'PARTIALLY_SHIPPED' END," + "picked_package_count=picked_package_count-#{packages}," + "shipped_package_count=shipped_package_count+#{packages},outbound_order_no=#{outboundNo},updated_at=NOW() " + "WHERE customer_id=#{customerId} AND id=#{id} AND detained=0 AND picked_package_count >= #{packages} " + "AND shipped_package_count+#{packages} <= package_count") int transferPickedToShipped(@Param("customerId") String customerId, @Param("id") Long id, @Param("packages") long packages, @Param("outboundNo") String outboundNo); @Update("UPDATE ll_order SET sub_order_status='OUTBOUND:OUTBOUNDED;DELIVERY:WAIT_DELIVERY',updated_at=NOW() " + "WHERE customer_id=#{customerId} AND id=#{id}") int markDispatchOutbound(@Param("customerId") String customerId, @Param("id") Long id); @Update("UPDATE ll_order SET pallet_merge_flag=#{flag}," + "pallet_merge_batch_id=CASE WHEN #{flag} IS NULL THEN NULL ELSE pallet_merge_batch_id END," + "updated_at=#{updatedAt} " + "WHERE customer_id=#{customerId} AND id=#{id}") int updatePalletMergeFlag(@Param("customerId") String customerId, @Param("id") long id, @Param("flag") String flag, @Param("updatedAt") java.time.LocalDateTime updatedAt); @Update("UPDATE ll_order SET pallet_merge_flag=#{flag},pallet_merge_batch_id=#{batchId},updated_at=#{updatedAt} " + "WHERE customer_id=#{customerId} AND id=#{id}") int updatePalletMergeBatch(@Param("customerId") String customerId, @Param("id") long id, @Param("flag") String flag, @Param("batchId") String batchId, @Param("updatedAt") java.time.LocalDateTime updatedAt); }