1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.account.mapper.sales.AccountSalesCollectionMapper">
 
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.account.pojo.sales.AccountSalesCollection">
        <id column="id" property="id" />
        <result column="stock_out_record_ids" property="stockOutRecordIds" />
        <result column="create_user" property="createUser" />
        <result column="create_time" property="createTime" />
        <result column="update_user" property="updateUser" />
        <result column="update_time" property="updateTime" />
        <result column="dept_id" property="deptId" />
        <result column="customer_id" property="customerId" />
        <result column="collection_date" property="collectionDate" />
        <result column="collection_amount" property="collectionAmount" />
        <result column="collection_method" property="collectionMethod" />
        <result column="collection_number" property="collectionNumber" />
        <result column="remark" property="remark" />
    </resultMap>
    <select id="listPageAccountSalesCollection"
            resultType="com.ruoyi.account.bean.vo.sales.AccountSalesCollectionVo">
       select
           A.* ,
           if(asd.receipt_number is not null, true, false) as isAccountStatemen
       from (select ascc.*,
               c.customer_name,
               GROUP_CONCAT(sour.outbound_batches SEPARATOR ',') AS outboundBatches
        from account_sales_collection ascc
        left join customer c on ascc.customer_id = c.id
        <!-- 手工发货单出库按 stock_out_record_ids 找,油品出库按绑定行 stock_out_binding_ids 反查所在的出库单 -->
        left join stock_out_record sour on FIND_IN_SET(sour.id, ascc.stock_out_record_ids) > 0
            OR EXISTS (select 1 from stock_out_record_sales_ledger b
                       where b.stock_out_record_id = sour.id
                         and FIND_IN_SET(b.id, ascc.stock_out_binding_ids) > 0)
        GROUP BY ascc.id)A
       left join account_statement_details asd on A.collection_number = asd.receipt_number
         <where>
            <if test="req.customerId != null">
                 AND A.customer_id = #{req.customerId}
            </if>
            <if test="req.collectionNumber != null and req.collectionNumber != ''">
                AND A.collection_number LIKE CONCAT('%',#{req.collectionNumber},'%')
            </if>
            <if test="req.collectionMethod != null and req.collectionMethod != ''">
                AND A.collection_method LIKE CONCAT('%',#{req.collectionMethod},'%')
            </if>
            <if test="req.startDate != null and req.endDate != null">
                AND A.collection_date BETWEEN #{req.startDate} AND #{req.endDate}
            </if>
        </where>
        order by A.id desc
    </select>
    <select id="existsByStockOutRecordId" resultType="java.lang.Boolean">
        SELECT COUNT(*) > 0
        FROM account_sales_collection
        WHERE
        <foreach collection="stockOutRecordIds" item="id" open="(" separator=" OR " close=")">
            FIND_IN_SET(#{id}, stock_out_record_ids)
        </foreach>
    </select>
    <!-- 可收款的销售出库候选。
         ① record_type='13' 的手工发货单出库 → b.id 为 NULL,已收款额按 stock_out_record_ids 汇总;
         ② 油品出库(type 为空)按「出库单×客户」拆到绑定行 → 已收款额按 stock_out_binding_ids 汇总,
         金额只算该客户分摊的那部分。两个 id 空间不能混比,故按 b.id 是否为空分开。
         已收款额改成标量子查询:原来用 LEFT JOIN + GROUP BY outbound_batches 聚合,且条件写成
         acsc.stock_out_record_ids = sor.id(等值比逗号串),一个出库单收过款后面的就再也匹配不上。 -->
    <select id="getOutboundBatchesByCustomer"
            resultType="com.ruoyi.account.bean.vo.sales.SalesOutboundVo">
        SELECT
            id,
            outbound_batches,
            customer_name,
            shipping_date,
            product_name,
            specification_model,
            tax_rate,
            outbound_amount,
            shipping_no,
            sales_contract_no,
            amount_received
        FROM
            (
                SELECT
                    sor.id,
                    sor.outbound_batches,
                    IFNULL(b.customer_name, sl.customer_name) AS customer_name,
                    sor.create_time AS shipping_date,
                    IFNULL(pb.product_name, p.product_name) AS product_name,
                    IFNULL(pmb.model, pm.model) AS specification_model,
                    IFNULL(slpb.tax_rate, slp.tax_rate) AS tax_rate,
                    CASE
                        WHEN b.id IS NOT NULL THEN b.quantity * slpb.tax_inclusive_unit_price
                        ELSE sor.stock_out_num * slp.tax_inclusive_unit_price
                    END AS outbound_amount,
                    s.shipping_no,
                    IFNULL(slb.sales_contract_no, sl.sales_contract_no) AS sales_contract_no,
                    (SELECT COALESCE(SUM(acsc.collection_amount), 0)
                     FROM account_sales_collection acsc
                     WHERE (b.id IS NULL AND FIND_IN_SET(sor.id, acsc.stock_out_record_ids) > 0)
                        OR (b.id IS NOT NULL AND FIND_IN_SET(b.id, acsc.stock_out_binding_ids) > 0)
                    ) AS amount_received
                FROM
                    stock_out_record sor
                        LEFT JOIN stock_out_record_sales_ledger b ON b.stock_out_record_id = sor.id
                        LEFT JOIN shipping_info s ON sor.record_id = s.id
                        LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id
                        LEFT JOIN sales_ledger_product slp ON s.sales_ledger_product_id = slp.id
                        AND slp.type = 1
                        LEFT JOIN sales_ledger slb ON slb.id = b.sales_ledger_id
                        LEFT JOIN sales_ledger_product slpb ON slpb.id = b.sales_ledger_product_id
                        AND slpb.type = 1
                        LEFT JOIN product_model pm ON slp.product_model_id = pm.id
                        LEFT JOIN product p ON pm.product_id = p.id
                        LEFT JOIN product_model pmb ON sor.product_model_id = pmb.id
                        LEFT JOIN product pb ON pmb.product_id = pb.id
                WHERE
                    sor.approval_status = 1
                  AND (
                        sor.record_type = '13'
                     OR (b.id IS NOT NULL AND (sor.type IS NULL OR sor.type = ''))
                      )
                  AND IFNULL(b.customer_id, sl.customer_id) = #{customerId}
                ORDER BY
                    sor.id, IFNULL(b.id, 0)
            ) tempA
        WHERE
            amount_received &lt; outbound_amount
    </select>
    <!-- 油品出库的绑定行与出库单是两个独立 id 空间,判重要分开查 -->
    <select id="existsByStockOutBindingId" resultType="java.lang.Boolean">
        SELECT COUNT(*) > 0
        FROM account_sales_collection
        WHERE
        <foreach collection="stockOutBindingIds" item="id" open="(" separator=" OR " close=")">
            FIND_IN_SET(#{id}, stock_out_binding_ids)
        </foreach>
    </select>
    <select id="selectIncomeStats" resultType="com.ruoyi.home.dto.IncomeExpenseAnalysisDto">
         SELECT DATE_FORMAT(collection_date, #{dateFormat}) AS dateStr,
                IFNULL(SUM(collection_amount), 0)            AS amount
         FROM account_sales_collection
         WHERE collection_date BETWEEN #{startStr} AND #{endStr}
         GROUP BY dateStr
         ORDER BY dateStr
    </select>
 
</mapper>