✨ 完善应收账单毛利分析与提成展示

This commit is contained in:
caojia
2026-11-10 17:25:21 +08:00
parent 9004a1b921
commit 3e5ef25153
10 changed files with 215 additions and 31 deletions
@@ -7,6 +7,7 @@ import com.bms.ar.profit.ArCommissionRate;
import com.bms.ar.profit.ArWriteoffRate;
import com.bms.ar.profit.ArCommissionResult;
import com.bms.ar.profit.ArCommissionSummary;
import com.bms.ar.profit.ArProfitScope;
public interface ArCommissionMapper
{
@@ -25,6 +26,7 @@ public interface ArCommissionMapper
int countMissingRates(@Param("billId") Long billId);
int confirmMissingRate(@Param("writeoffId") Long writeoffId, @Param("rate") java.math.BigDecimal rate,
@Param("operator") String operator, @Param("remark") String remark);
List<ArCommissionResult> selectResults(@Param("billId") Long billId, @Param("includeReversed") boolean includeReversed);
List<ArCommissionSummary> selectCommissionSummary(@Param("billId") Long billId);
List<ArCommissionResult> selectResults(@Param("billId") Long billId, @Param("includeReversed") boolean includeReversed,
@Param("scope") ArProfitScope scope);
List<ArCommissionSummary> selectCommissionSummary(@Param("billId") Long billId, @Param("scope") ArProfitScope scope);
}
@@ -97,14 +97,17 @@ public class ArCommissionService
public List<ArCommissionResult> results(Long billId, boolean includeReversed)
{
requireFinance();
return mapper.selectResults(billId, includeReversed);
return mapper.selectResults(billId, includeReversed, scopeResolver.resolve());
}
public List<ArCommissionSummary> summary(Long billId)
{
requireFinance();
return mapper.selectCommissionSummary(billId);
return mapper.selectCommissionSummary(billId, scopeResolver.resolve());
}
public List<ArCommissionResult> exportResults(Long billId)
{
return mapper.selectResults(billId, false, requireFinance());
}
public List<ArWriteoffRate> writeoffRates(Long billId)
@@ -141,8 +144,10 @@ public class ArCommissionService
}
}
private void requireFinance()
private ArProfitScope requireFinance()
{
if (!scopeResolver.resolve().all()) throw new ServiceException("仅财务和系统管理员可查看或维护提成");
ArProfitScope scope = scopeResolver.resolve();
if (!scope.all()) throw new ServiceException("仅财务和系统管理员可使用提成管理功能");
return scope;
}
}
@@ -11,6 +11,7 @@ public class ArProfitRow
{
private Long arBillId;
@Excel(name = "账单号", width = 20) private String billNo;
@Excel(name = "账单名称", width = 24) private String billName;
@Excel(name = "客户代码", width = 16) private String customerCode;
@Excel(name = "客户名称", width = 24) private String customerName;
private String customerArea;
@@ -12,6 +12,7 @@ public class ArProfitSummary
private BigDecimal productAmount;
private BigDecimal salesGrossProfit;
private BigDecimal salesGrossMarginRate;
private BigDecimal commissionAmount;
private BigDecimal writtenOffAmount;
private BigDecimal unwrittenAmount;
}
@@ -104,6 +104,7 @@
<otherwise>and r.result_status != 'REVERSED' and b.status = 'WRITTEN_OFF' and b.generation_status = 'READY'</otherwise>
</choose>
<if test="billId != null">and r.ar_bill_id = #{billId}</if>
<include refid="com.bms.ar.mapper.ArProfitMapper.scopeCondition"/>
order by r.result_id desc
</select>
<select id="selectCommissionSummary" resultMap="commissionSummary">
@@ -120,6 +121,7 @@
from ar_profit_commission_result r join ar_bill b on b.ar_bill_id = r.ar_bill_id
where r.result_status != 'REVERSED' and b.status = 'WRITTEN_OFF' and b.generation_status = 'READY'
<if test="billId != null">and r.ar_bill_id = #{billId}</if>
<include refid="com.bms.ar.mapper.ArProfitMapper.scopeCondition"/>
group by r.sales_user_id, r.currency
order by sales_user_name, r.currency
</select>
@@ -3,7 +3,8 @@
<mapper namespace="com.bms.ar.mapper.ArProfitMapper">
<resultMap id="row" type="com.bms.ar.profit.ArProfitRow">
<id property="arBillId" column="ar_bill_id"/>
<result property="billNo" column="bill_no"/><result property="billDate" column="bill_date"/>
<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"/>
@@ -16,6 +17,7 @@
<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.ar.domain.ArBillDetail">
@@ -62,7 +64,7 @@
<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_date, b.customer_code, b.customer_name,
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,
@@ -118,8 +120,18 @@
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
from (<include refid="billRows"/>) t group by t.currency order by t.currency
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.ar.profit.ArProfitSalesOption">
select u.user_id as userId, u.nick_name as name, u.user_name as code