Files
BMS/bms-back/bms-system/src/main/resources/mapper/receivable/ArProfitMapper.xml
T
2026-11-11 11:27:54 +08:00

141 lines
9.0 KiB
XML

<?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.bms.receivable.mapper.ArProfitMapper">
<resultMap id="row" type="com.bms.receivable.profit.ArProfitRow">
<id property="arBillId" column="ar_bill_id"/>
<result property="billNo" column="bill_no"/><result property="billName" column="bill_name"/>
<result property="billDate" column="bill_date"/>
<result property="customerCode" column="customer_code"/><result property="customerName" column="customer_name"/>
<result property="customerArea" column="customer_area"/>
<result property="salesUserName" column="sales_user_name"/><result property="currency" column="currency"/>
<result property="status" column="status"/><result property="salesAmount" column="sales_amount"/>
<result property="productAmount" column="product_amount"/><result property="salesGrossProfit" column="sales_gross_profit"/>
<result property="salesGrossMarginRate" column="sales_gross_margin_rate"/>
<result property="writtenOffAmount" column="written_off_amount"/><result property="unwrittenAmount" column="unwritten_amount"/>
</resultMap>
<resultMap id="summary" type="com.bms.receivable.profit.ArProfitSummary">
<result property="currency" column="currency"/><result property="billCount" column="bill_count"/>
<result property="salesAmount" column="sales_amount"/><result property="productAmount" column="product_amount"/>
<result property="salesGrossProfit" column="sales_gross_profit"/><result property="salesGrossMarginRate" column="sales_gross_margin_rate"/>
<result property="commissionAmount" column="commission_amount"/>
<result property="writtenOffAmount" column="written_off_amount"/><result property="unwrittenAmount" column="unwritten_amount"/>
</resultMap>
<resultMap id="detail" type="com.bms.receivable.domain.ArBillDetail">
<id property="detailId" column="detail_id"/><result property="orderNo" column="order_no"/>
<result property="productName" column="product_name"/><result property="currency" column="currency"/>
<result property="totalAmount" column="total_amount"/>
</resultMap>
<resultMap id="fee" type="com.bms.receivable.domain.ArBillDetailFee">
<id property="detailFeeId" column="detail_fee_id"/><result property="detailId" column="detail_id"/>
<result property="feeName" column="fee_name"/><result property="feeType" column="fee_type"/>
<result property="amount" column="amount"/><result property="productAmount" column="product_amount"/>
<result property="redlineAmount" column="redline_amount"/><result property="currency" column="currency"/>
</resultMap>
<sql id="scopeCondition">
<choose>
<when test="scope.all"/>
<when test="scope.self or scope.department">
and (1 = 0
<if test="scope.self">or b.profit_sales_user_id = #{scope.userId}</if>
<if test="scope.department">
or exists (select 1 from sys_user u inner join sys_dept dept on dept.dept_id = u.dept_id
where u.user_id = b.profit_sales_user_id and u.del_flag = '0'
and (dept.dept_id = #{scope.deptId} or find_in_set(#{scope.deptId}, dept.ancestors)))
</if>
)
</when>
<otherwise>and 1 = 0</otherwise>
</choose>
</sql>
<sql id="billConditions">
where b.status in ('CONFIRMED', 'PARTIAL_WRITTEN_OFF', 'WRITTEN_OFF') and b.generation_status = 'READY'
<include refid="scopeCondition"/>
<if test="query.customerId != null">and b.customer_id = #{query.customerId}</if>
<if test="query.billNo != null and query.billNo != ''">and b.bill_no like concat('%', #{query.billNo}, '%')</if>
<if test="query.arBillId != null">and b.ar_bill_id = #{query.arBillId}</if>
<if test="query.status != null and query.status != ''">and b.status = #{query.status}</if>
<if test="query.salesUserId != null">and b.profit_sales_user_id = #{query.salesUserId}</if>
<if test="query.beginBillDate != null">and b.bill_date &gt;= #{query.beginBillDate}</if>
<if test="query.endBillDate != null">and b.bill_date &lt;= #{query.endBillDate}</if>
</sql>
<!-- 报表直接读取账单快照。 -->
<sql id="validProfitSnapshot">
b.profit_calc_status = 'READY' and b.total_amount is not null
and ((b.profit_customer_area = #{shenzhenArea} and b.product_amount is not null)
or (b.profit_customer_area = #{guangzhouArea} and b.redline_amount is not null))
</sql>
<sql id="areaProductAmount">
case when b.profit_customer_area = #{shenzhenArea} then b.product_amount
when b.profit_customer_area = #{guangzhouArea} then b.redline_amount else null end
</sql>
<sql id="billRows">
<bind name="shenzhenArea" value="@com.bms.price.enums.ProfitAreaRule@SHENZHEN.getCustomerArea()"/>
<bind name="guangzhouArea" value="@com.bms.price.enums.ProfitAreaRule@GUANGZHOU.getCustomerArea()"/>
select b.ar_bill_id, b.bill_no, b.bill_name, b.bill_date, b.customer_code, b.customer_name,
b.profit_customer_area as customer_area,
b.profit_sales_user_name as sales_user_name, b.currency, b.status,
b.total_amount as sales_amount, b.written_off_amount, b.unwritten_amount,
case when <include refid="validProfitSnapshot"/> then <include refid="areaProductAmount"/> else null end as product_amount,
case when <include refid="validProfitSnapshot"/> then b.total_amount - (<include refid="areaProductAmount"/>) else null end as sales_gross_profit,
case when <include refid="validProfitSnapshot"/> and b.total_amount != 0
then round((b.total_amount - (<include refid="areaProductAmount"/>)) * 100 / b.total_amount, 4) else null end as sales_gross_margin_rate,
case when <include refid="validProfitSnapshot"/> then 0 else 1 end as profit_incomplete
from ar_bill b
<include refid="billConditions"/>
</sql>
<select id="selectBills" resultMap="row">
<include refid="billRows"/>
order by b.bill_date desc, b.ar_bill_id desc
</select>
<select id="selectSummary" resultMap="summary">
select t.currency, count(*) as bill_count,
sum(t.sales_amount) as sales_amount, sum(t.product_amount) as product_amount,
sum(t.sales_gross_profit) as sales_gross_profit,
case when sum(case when t.profit_incomplete = 0 then t.sales_amount else null end) = 0 then null
else round(sum(t.sales_gross_profit) * 100 /
sum(case when t.profit_incomplete = 0 then t.sales_amount else null end), 4) end as sales_gross_margin_rate,
sum(t.written_off_amount) as written_off_amount, sum(t.unwritten_amount) as unwritten_amount,
max(commission.commission_amount) as commission_amount
from (<include refid="billRows"/>) t
left join (
select b.currency, sum(r.commission_amount) as commission_amount
from ar_bill b join ar_profit_commission_result r
on r.ar_bill_id = b.ar_bill_id and r.currency = b.currency and r.result_status = 'READY'
<include refid="billConditions"/>
and b.status = 'WRITTEN_OFF'
group by b.currency
) commission on commission.currency = t.currency
group by t.currency order by t.currency
</select>
<select id="selectSalesOptions" resultType="com.bms.receivable.profit.ArProfitSalesOption">
select u.user_id as userId, u.nick_name as name, u.user_name as code
from sys_user u
where u.del_flag = '0' and u.status = '0'
<if test="keyword != null and keyword != ''">
and (u.nick_name like concat('%', #{keyword}, '%')
or u.user_name like concat('%', #{keyword}, '%'))
</if>
order by u.nick_name, u.user_id
limit 50
</select>
<select id="selectBillDetails" resultMap="detail">
select d.detail_id, d.order_no, d.product_name, d.currency, d.total_amount
from ar_bill_detail d join ar_bill b on b.ar_bill_id = d.ar_bill_id
where b.ar_bill_id = #{query.arBillId}
and b.status in ('CONFIRMED', 'PARTIAL_WRITTEN_OFF', 'WRITTEN_OFF') and b.generation_status = 'READY'
<include refid="scopeCondition"/>
order by d.detail_no, d.detail_id
</select>
<select id="selectFees" resultMap="fee">
select f.* from ar_bill_detail_fee f
join ar_bill_detail d on d.detail_id = f.detail_id
join ar_bill b on b.ar_bill_id = d.ar_bill_id
where d.detail_id = #{query.detailId}
and b.status in ('CONFIRMED', 'PARTIAL_WRITTEN_OFF', 'WRITTEN_OFF') and b.generation_status = 'READY'
<include refid="scopeCondition"/>
order by f.fee_no, f.detail_fee_id
</select>
</mapper>