2026-09-10 1e123568c2f561013f5636e45dc0db30b17a3517
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
<?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.cost.mapper.CostAccountingMapper">
 
    <!-- 统一的订单筛选条件:po=生产订单,pm/p=订单成品规格/产品
         订单日期取 create_time,历史数据未回填时回退 start_time,避免筛选丢单 -->
    <sql id="orderFilter">
        <if test="startDate != null">and date(coalesce(po.create_time, po.start_time)) &gt;= #{startDate}</if>
        <if test="endDate != null">and date(coalesce(po.create_time, po.start_time)) &lt;= #{endDate}</if>
        <if test="npsNo != null and npsNo != ''">and po.nps_no like concat('%', #{npsNo}, '%')</if>
        <if test="productName != null and productName != ''">
            and (p.product_name like concat('%', #{productName}, '%')
                or pm.model like concat('%', #{productName}, '%'))
        </if>
    </sql>
 
    <select id="listOrders" resultType="com.ruoyi.cost.bean.vo.CostOrderVo">
        select po.id                                                        as productionOrderId,
               po.nps_no                                                    as npsNo,
               po.product_model_id                                          as productModelId,
               concat(ifnull(p.product_name, ''), '/', ifnull(pm.model, '')) as finishedProduct,
               ifnull(p.product_name, '')                                   as productName,
               ifnull(pm.model, '')                                         as productModel,
               pm.unit                                                      as unit,
               ifnull(po.complete_quantity, 0)                              as completeQty,
               ifnull(po.quantity, 0)                                       as planQty,
               coalesce(po.create_time, po.start_time)                      as createTime
        from production_order po
                 left join product_model pm on pm.id = po.product_model_id
                 left join product p on p.id = pm.product_id
        <where>
            <include refid="orderFilter"/>
        </where>
        order by po.id desc
    </select>
 
    <select id="listMaterialInputs" resultType="com.ruoyi.cost.bean.vo.CostMaterialInputVo">
        select pot.production_order_id            as productionOrderId,
               ppi.product_model_id               as productModelId,
               sum(ifnull(ppi.input_quantity, 0)) as inputQty
        from production_product_input ppi
                 join production_product_main ppm on ppm.id = ppi.production_product_main_id
                 join production_operation_task pot on pot.id = ppm.production_operation_task_id
                 join production_order po on po.id = pot.production_order_id
                 left join product_model pm on pm.id = po.product_model_id
                 left join product p on p.id = pm.product_id
        <where>
            and ppi.product_model_id is not null
            <include refid="orderFilter"/>
        </where>
        group by pot.production_order_id, ppi.product_model_id
    </select>
 
    <select id="listConsumedMaterials" resultType="com.ruoyi.cost.bean.vo.CostMissingPriceVo">
        select ppi.product_model_id                as productModelId,
               ifnull(pmat.product_name, '')       as materialName,
               ifnull(pmm.model, '')               as materialModel,
               pmm.unit                            as unit,
               sum(ifnull(ppi.input_quantity, 0))  as inputQty,
               count(distinct pot.production_order_id) as orderCount,
               max(ppi.create_time)                as lastInputTime
        from production_product_input ppi
                 join production_product_main ppm on ppm.id = ppi.production_product_main_id
                 join production_operation_task pot on pot.id = ppm.production_operation_task_id
                 join production_order po on po.id = pot.production_order_id
                 left join product_model pm on pm.id = po.product_model_id
                 left join product p on p.id = pm.product_id
                 left join product_model pmm on pmm.id = ppi.product_model_id
                 left join product pmat on pmat.id = pmm.product_id
        <where>
            and ppi.product_model_id is not null
            <include refid="orderFilter"/>
        </where>
        group by ppi.product_model_id, pmat.product_name, pmm.model, pmm.unit
        order by inputQty desc
    </select>
 
    <!-- 物料单价来源,priority 越小越优先:价目表 &gt; 采购明细 &gt; 采购入库记录 &gt; 发票登记 -->
    <select id="listMaterialPrices" resultType="com.ruoyi.cost.bean.vo.CostMaterialPriceVo">
        select pm.id                      as productModelId,
               ppm_price.base_price       as price,
               '采购价目表'                as priceSource,
               1                          as priority
        from procurement_price_management ppm_price
                 join product_model pm on pm.product_code = ppm_price.product_code
                 join (select product_code, max(id) as mid
                       from procurement_price_management
                       group by product_code) latest on latest.mid = ppm_price.id
        where ppm_price.product_code is not null and ppm_price.product_code &lt;&gt; ''
          and ifnull(ppm_price.base_price, 0) &gt; 0
        union all
        select slp.product_model_id,
               slp.tax_inclusive_unit_price,
               '采购明细',
               2
        from sales_ledger_product slp
                 join (select product_model_id, max(id) as mid
                       from sales_ledger_product
                       where type = 2 and product_model_id is not null
                       group by product_model_id) latest on latest.mid = slp.id
        where ifnull(slp.tax_inclusive_unit_price, 0) &gt; 0
        union all
        select prs.product_model_id,
               prs.unit_price,
               '采购入库记录',
               3
        from procurement_record_storage prs
                 join (select product_model_id, max(id) as mid
                       from procurement_record_storage
                       where product_model_id is not null
                       group by product_model_id) latest on latest.mid = prs.id
        where ifnull(prs.unit_price, 0) &gt; 0
        union all
        select rec.product_model_id,
               rec.tax_inclusive_unit_price,
               '采购发票登记',
               4
        from product_record rec
                 join (select product_model_id, max(id) as mid
                       from product_record
                       where product_model_id is not null
                       group by product_model_id) latest on latest.mid = rec.id
        where ifnull(rec.tax_inclusive_unit_price, 0) &gt; 0
        order by productModelId, priority
    </select>
 
    <select id="listLaborCosts" resultType="com.ruoyi.cost.bean.vo.CostLaborVo">
        select pot.production_order_id as productionOrderId,
               count(*)                as accountRows,
               sum(cast(
                       case
                           when prc.unit_price is not null
                               then ifnull(pa.finished_num, 0) * prc.unit_price
                           when poro.type = 0
                               then ifnull(pa.work_hours, 0) * ifnull(ppm.work_hour, 0)
                           else ifnull(pa.work_hours, 0) * ifnull(pa.finished_num, 0)
                                * ifnull(cast(nullif(substring_index(pm.model, '*', -1), pm.model) as decimal(18, 4)), 0)
                       end as decimal(18, 2))) as laborCost,
               sum(case when prc.unit_price is null and ifnull(pa.work_hours, 0) = 0 then 1 else 0 end) as noRateRows
        from production_account pa
                 join production_product_main ppm on ppm.id = pa.production_product_main_id
                 join production_operation_task pot on pot.id = ppm.production_operation_task_id
                 join production_order po on po.id = pot.production_order_id
                 left join production_order_routing_operation poro on poro.id = pot.production_order_routing_operation_id
                 left join product_model pm on pm.id = po.product_model_id
                 left join product p on p.id = pm.product_id
                 left join piece_rate_config prc
                           on prc.product_model_id = pm.id
                               and prc.operation_name = pa.technology_operation_name
                               and prc.status = 1
        <where>
            <include refid="orderFilter"/>
        </where>
        group by pot.production_order_id
    </select>
 
    <select id="listSalePrices" resultType="com.ruoyi.cost.bean.vo.CostSalePriceVo">
        select po.id                            as productionOrderId,
               slp.tax_inclusive_unit_price     as salePrice
        from production_order po
                 join production_plan pp
                      on find_in_set(pp.id, replace(replace(replace(po.production_plan_ids, '[', ''), ']', ''), ' ', '')) &gt; 0
                 join sales_ledger_product slp
                      on slp.sales_ledger_id = pp.sales_ledger_id
                          and slp.product_model_id = po.product_model_id
                          and slp.type = 1
                 left join product_model pm on pm.id = po.product_model_id
                 left join product p on p.id = pm.product_id
        <where>
            <include refid="orderFilter"/>
        </where>
        order by po.id, slp.id desc
    </select>
 
    <select id="sumEnergyCost" resultType="com.ruoyi.cost.bean.vo.CostEnergyVo">
        select ifnull(sum(ifnull(eec.sum_num, 0)), 0)                            as kwh,
               ifnull(sum(ifnull(eec.sum_num, 0) * ifnull(ep.price, 0)), 0)      as energyCost
        from equipment_energy_consumption eec
                 left join energy_period ep on ep.date = eec.run_date
        <where>
            <if test="startDate != null">and eec.run_date &gt;= #{startDate}</if>
            <if test="endDate != null">and eec.run_date &lt;= #{endDate}</if>
        </where>
    </select>
</mapper>