src/main/resources/mapper/sales/ShippingInfoMapper.xml
@@ -2,6 +2,11 @@
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.sales.mapper.ShippingInfoMapper">
    <!--
      发货台账列表 = 发货单(shipping_info) UNION ALL 销售类油品出库(stock_out_record)。
      两分支列顺序必须严格一致(共 31 列),列名以分支 A 为准。
      注意:数据权限拦截器只给第一个 from 的表加条件,分支 B 需在本 XML 里自行补同等过滤。
    -->
    <select id="listPage" resultType="com.ruoyi.sales.dto.ShippingInfoDto">
        SELECT
        s.id,
@@ -24,7 +29,17 @@
        p.product_name,
        sl.customer_name,
        spd.totalQuantity,
        sor.outboundBatches
        sor.outboundBatches,
        'shipping' as source,
        oor.id as stockOutRecordId,
        oor.out_category as outCategory,
        oor.tank_no as tankNo,
        oor.oil_product as oilProduct,
        oor.oil_depot_name as oilDepotName,
        oor.driver_name as driverName,
        oor.contact_person as contactPerson,
        oor.contact_phone as contactPhone,
        oor.batch_no as outBatchNo
        FROM shipping_info s
        LEFT JOIN (select shipping_info_id,sum(quantity) totalQuantity from shipping_product_detail GROUP BY shipping_info_id) spd ON spd.shipping_info_id = s.id
        LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id
@@ -35,6 +50,12 @@
                   from stock_out_record
                   where record_type='13'and approval_status=1
                   group by record_id)sor on sor.record_id= s.id
        <!-- 由油品出库审批通过时生成的发货单:一条出库对应一条自己的 shipping_info,
             故至多命中一行,不会放大行数。手建的发货单没有配对油品出库,这些列为空 -->
        left join stock_out_record oor
            on oor.record_id = s.id
           and TRIM(IFNULL(oor.record_type,'')) = '13'
           and (oor.type IS NULL or oor.type = '')
        WHERE 1=1
        <if test="req.salesContractNo != null and req.salesContractNo != ''">
            AND sl.sales_contract_no LIKE CONCAT('%',#{req.salesContractNo},'%')
@@ -47,6 +68,86 @@
        </if>
        <if test="req.expressNumber != null and req.expressNumber != ''">
            AND s.express_number LIKE CONCAT('%',#{req.expressNumber},'%')
        </if>
        UNION ALL
        SELECT
        o.id,
        o.sales_ledger_id,
        o.out_date as shipping_date,
        o.truck_plate_no as shipping_car_number,
        NULL as express_number,
        NULL as express_company,
        o.outbound_batches as shipping_no,
        NULL as type,
        '已发货' as status,
        o.create_time,
        o.update_time,
        o.create_user,
        o.update_user,
        NULL as tenant_id,
        <!-- 油品出库可绑多个销售台账(多客户),o.sales_ledger_id 只存首项,故从绑定表汇总全部合同号 -->
        IFNULL(
            (select group_concat(distinct slb.sales_contract_no separator ',')
             from stock_out_record_sales_ledger b
                      join sales_ledger slb on slb.id = b.sales_ledger_id
             where b.stock_out_record_id = o.id),
            sl2.sales_contract_no) as sales_contract_no,
        pm2.model as specification_model,
        pm2.unit,
        p2.product_name,
        o.customer_name,
        o.stock_out_num as totalQuantity,
        o.outbound_batches as outboundBatches,
        'oilOut' as source,
        o.id as stockOutRecordId,
        o.out_category as outCategory,
        o.tank_no as tankNo,
        o.oil_product as oilProduct,
        o.oil_depot_name as oilDepotName,
        o.driver_name as driverName,
        o.contact_person as contactPerson,
        o.contact_phone as contactPhone,
        o.batch_no as outBatchNo
        FROM stock_out_record o
        left join product_model pm2 on pm2.id = o.product_model_id
        left join product p2 on p2.id = pm2.product_id
        <!-- 绑定了销售台账的油品出库带出合同号;没绑的行该列仍为空 -->
        left join sales_ledger sl2 on sl2.id = o.sales_ledger_id
        <!-- 只取油品出库(type 为空,全部出库类别);type=0/1 的合格、不合格出库不进发货台账 -->
        WHERE (o.type IS NULL OR o.type = '') AND o.approval_status = 1
        <!-- 已改造成「销售-发货出库」的油品行由分支 A 的 shipping_info 展示,此处排除避免同一批货两行。
             IFNULL 必须加:record_type 为 NULL 时三值逻辑会把整行滤掉 -->
        AND NOT (TRIM(IFNULL(o.record_type,'')) = '13' AND IFNULL(o.record_id,0) > 0)
        <if test="req.salesContractNo != null and req.salesContractNo != ''">
            <!-- 多台账出库要按「任一绑定台账的合同号」都能筛到,不能只看首项 -->
            AND (sl2.sales_contract_no LIKE CONCAT('%',#{req.salesContractNo},'%')
                 OR EXISTS (select 1
                            from stock_out_record_sales_ledger b
                                     join sales_ledger slb on slb.id = b.sales_ledger_id
                            where b.stock_out_record_id = o.id
                              and slb.sales_contract_no LIKE CONCAT('%',#{req.salesContractNo},'%')))
        </if>
        <!-- 油品出库没有快递单,按快递单号筛选时不应返回任何油品行 -->
        <if test="req.expressNumber != null and req.expressNumber != ''">
            AND 1=0
        </if>
        <if test="req.shippingCarNumber != null and req.shippingCarNumber != ''">
            AND o.truck_plate_no LIKE CONCAT('%',#{req.shippingCarNumber},'%')
        </if>
        <if test="req.shippingNo != null and req.shippingNo != ''">
            AND o.outbound_batches LIKE CONCAT('%',#{req.shippingNo},'%')
        </if>
        <if test="req.createUser != null">
            AND o.create_user = #{req.createUser}
        </if>
        <if test="req.deptId != null">
            AND o.dept_id = #{req.deptId}
        </if>
        <if test="req.deptIds != null and req.deptIds.length > 0">
            AND o.dept_id IN
            <foreach collection="req.deptIds" item="deptId" open="(" separator="," close=")">
                #{deptId}
            </foreach>
        </if>
        order by create_time DESC
    </select>
@@ -72,12 +173,14 @@
            slp.product_category,
            slp.specification_model,
            slp.unit,
            slp.product_model_id,
            sor.outbound_batches,
            sor.stock_out_num,
            sor.batch_no,
            slp.tax_inclusive_unit_price,
            GREATEST(sor.stock_out_num - COALESCE(rs.total_return_num, 0), 0) AS un_quantity,
            COALESCE(rs.total_return_num, 0) AS total_return_num
            COALESCE(rs.return_num, 0) AS total_return_num,
            COALESCE(rs.pending_return_num, 0) AS pending_return_num
        FROM shipping_info si
        LEFT JOIN shipping_product_detail spd ON spd.shipping_info_id = si.id
        LEFT JOIN stock_out_record sor ON sor.record_id = si.id and sor.record_type = '13'
@@ -85,7 +188,9 @@
        LEFT JOIN (
        SELECT
        stock_out_record_id,
        SUM(num) AS total_return_num
        SUM(num) AS total_return_num,
        SUM( CASE WHEN rsp.STATUS = 0 THEN rsp.num ELSE 0 END ) AS pending_return_num ,
        SUM( CASE WHEN rsp.STATUS = 1 THEN rsp.num ELSE 0 END ) AS return_num
        FROM return_sale_product rsp
        left join return_management rm on rm.id = rsp.return_management_id
        left join shipping_info si on si.id = rm.shipping_id
@@ -97,10 +202,12 @@
                si.id = #{shippingId}
            </if>
        </where>
        order by sor.id
    </select>
    <select id="getShippingInfoByCustomerName" resultType="com.ruoyi.sales.pojo.ShippingInfo">
        select * from shipping_info si
        select distinct si.* from shipping_info si
        left join sales_ledger sl on si.sales_ledger_id = sl.id
        where  sl.customer_name = #{customerName}
        inner join stock_out_record sor on sor.record_id = si.id and sor.record_type = '13' and sor.approval_status = 1
        where sl.customer_name = #{customerName} and si.status = '审核通过'
    </select>
</mapper>