计提报表本年本月收益优化2

This commit is contained in:
李贵强 2025-05-26 18:15:29 +08:00
parent dc40897283
commit 1fe3aae591
2 changed files with 201 additions and 91 deletions

View File

@ -18,10 +18,12 @@ import java.util.concurrent.TimeUnit;
*/
public class RegularFormReport extends AbstractReportFormPlugin implements Plugin {
private static final String[] FIELDS = {"shjh_orgname", "shjh_bankname", "shjh_bankaccount", "shjh_currency",
private static final String[] FIELDS = {
"shjh_orgname", "shjh_bankname", "shjh_bankaccount", "shjh_currency",
"shjh_depositstartdate", "shjh_depositstopdate", "shjh_term", "shjh_interestrate",
"shjh_frequency", "shjh_amount", "shjh_accrualdate", "shjh_accrualdays",
"shjh_accrualinterest", "shjh_monthearnings", "shjh_yearearnings", "shjh_depositmodel", "shjh_basis"};
"shjh_accrualinterest", "shjh_monthearnings", "shjh_yearearnings", "shjh_depositmodel",
"shjh_basis","shjh_redeemdate","shjh_realrevenue"};
@Override
public void processRowData(String gridPK, DynamicObjectCollection rowData, ReportQueryParam queryParam) {
@ -39,7 +41,8 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
// 获取日期
Date filterDate = queryParam.getFilter().getDate("shjh_filterdate");
Date depositStartDate = row.getDate(FIELDS[4]);
Date depositEndDate = row.getDate(FIELDS[5]); // 存款到期日保证有值
// 存款到期日:解活日期有值取解活日期没有则取存款日期
Date depositEndDate =row.getDate(FIELDS[17])==null ? row.getDate(FIELDS[5]):row.getDate(FIELDS[17]);
// 初始化计算结果
BigDecimal accruedInterest = BigDecimal.ZERO;
@ -77,32 +80,23 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
if (isValidPeriod) {
//计提天数
dayDiff = this.calculationDays(row, filterDate, depositStartDate);
//若计提日期 = 实际到期日期 计提利息=实际收益
if (filterDate.equals(depositEndDate)){
accruedInterest = row.getBigDecimal(FIELDS[18]);
}else {
/* 计提利息 = (金额 × 天利率 × 计提天数) */
accruedInterest = amount.multiply(rate)
.multiply(new BigDecimal(dayDiff))
.divide(basisDay, 10, RoundingMode.HALF_UP)
.setScale(2, RoundingMode.HALF_UP);
}
}
/* 计算本月收益 = 金额 × 天利率 × 当月有效天数 */
monthlyIncome = this.calculationMonthAmount(filterDate, depositStartDate, amount, rate, basisDay);
}
monthlyIncome = this.calculationMonthAmount(filterDate, depositStartDate,depositEndDate, amount, rate, basisDay,row);
/* 计算本年累计收益 = 金额 × 利率 × 当年有效天数 */
Date validYearEnd = null; // 有效结束日期
if (filterDate.before(depositStartDate)) {
// 当日期早于存款起期本年累计收益 = 0
yearlyIncome = BigDecimal.ZERO;
} else if (filterDate.after(depositEndDate)) {
// 当日期晚于存款到期日计算到 depositEndDate 的累计收益
validYearEnd = depositEndDate;
yearlyIncome = this.calculationYearAmount(filterDate,validYearEnd, depositStartDate, amount, rate, basisDay);
} else {
// 当前日期在有效期内计算到当前日期的累计收益
validYearEnd = filterDate;
yearlyIncome = this.calculationYearAmount(filterDate,validYearEnd, depositStartDate, amount, rate, basisDay);
}
/* 计算本年累计收益 = 金额 × 天利率 × 当年有效天数 */
yearlyIncome = this.calculationYearAmount(filterDate,depositStartDate,depositEndDate,amount,rate,basisDay,row);
}
}
@ -260,90 +254,195 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
* 计算本月累计收益
* @param filterDate 计提日期
* @param depositStartDate 起始日期
* @param depositEndDate 结束日期
* @param amount 金额
* @param rate 利率
* @param basisDay 计息基准
* @return 本年累计收益
* @param row 数据行
* @return 本月累计收益
*/
private BigDecimal calculationMonthAmount(Date filterDate, Date depositStartDate, BigDecimal amount, BigDecimal rate, BigDecimal basisDay) {
private BigDecimal calculationMonthAmount(Date filterDate, Date depositStartDate,
Date depositEndDate, BigDecimal amount,
BigDecimal rate, BigDecimal basisDay,
DynamicObject row) {
// 获取解活日期
Date redeemDate = row.getDate("shjh_redeemdate");
// 情况1计提日 >= 结束日期
if (!filterDate.before(depositEndDate)) {
// 1.1 三个日期同月且解活日期不为null取实际收益
if (isSameMonth(filterDate, depositStartDate)
&& isSameMonth(filterDate, depositEndDate)
&& redeemDate != null) {
return row.getBigDecimal(FIELDS[18]);
}
// 1.2 起始日期和计提日期同月算头不算尾
else if (isSameMonth(filterDate, depositStartDate)) {
long days = TimeUnit.DAYS.convert(
depositEndDate.getTime() - depositStartDate.getTime(),
TimeUnit.MILLISECONDS);
return calculateInterest(amount, rate, basisDay, days);
}
// 1.3 不同月算头算尾
else if (isSameMonth(filterDate, depositEndDate)){
long days = TimeUnit.DAYS.convert(
depositEndDate.getTime() - depositStartDate.getTime(),
TimeUnit.MILLISECONDS) + 1;
return calculateInterest(amount, rate, basisDay, days);
}else {
return BigDecimal.ZERO;
}
}
// 情况2计提日在有效期起始日 <= 计提日 < 结束日
else if (!filterDate.before(depositStartDate)
&& filterDate.before(depositEndDate)) {
// 2.1 计提日与起始日同月算头不算尾
if (isSameMonth(filterDate, depositStartDate)) {
long days = TimeUnit.DAYS.convert(
filterDate.getTime() - depositStartDate.getTime(),
TimeUnit.MILLISECONDS);
return calculateInterest(amount, rate, basisDay, days);
}
// 2.2 不同月算头算尾
else {
// 当月第一天
Calendar cal = Calendar.getInstance();
cal.setTime(filterDate);
// 当月第一天
cal.set(Calendar.DAY_OF_MONTH, 1);
Date monthStart = cal.getTime();
// 当月有效天数存款起期与当月首日的较晚者
Date validMonthStart = depositStartDate.after(monthStart) ? depositStartDate : monthStart;
// 有效起始日取存款起始日和当月首日的较晚者
Date validStart = depositStartDate.after(monthStart)
? depositStartDate : monthStart;
long monthDays = TimeUnit.DAYS.convert(
filterDate.getTime() - validMonthStart.getTime(),
TimeUnit.MILLISECONDS);
// 检查filterDate和depositStartDate是否在同年同月
Calendar filterCal = Calendar.getInstance();
filterCal.setTime(filterDate);
Calendar depositCal = Calendar.getInstance();
depositCal.setTime(depositStartDate);
boolean sameYearMonth = filterCal.get(Calendar.YEAR) == depositCal.get(Calendar.YEAR)
&& filterCal.get(Calendar.MONTH) == depositCal.get(Calendar.MONTH);
// 如果是同年同月天数加1
if (sameYearMonth) {
monthDays += 1;
long days = TimeUnit.DAYS.convert(
filterDate.getTime() - validStart.getTime(),
TimeUnit.MILLISECONDS) + 1;
return calculateInterest(amount, rate, basisDay, days);
}
}
// 情况3其他情况计提日 < 起始日
else {
return BigDecimal.ZERO;
}
}
/**
* 辅助方法计算利息
*/
private BigDecimal calculateInterest(BigDecimal amount, BigDecimal rate,
BigDecimal basisDay, long days) {
return amount.multiply(rate)
.multiply(new BigDecimal(monthDays))
.multiply(new BigDecimal(days))
.divide(basisDay, 10, RoundingMode.HALF_UP)
.setScale(2, RoundingMode.HALF_UP);
}
/**
* 计算本年累计收益
* @param filterDate 计提日期
* @param validYearEnd 结束有效日期
* @param depositStartDate 起始日期
* @param depositEndDate 结束日期
* @param amount 金额
* @param rate 利率
* @param basisDay 计息基准
* @param row 数据行
* @return 本年累计收益
*/
private BigDecimal calculationYearAmount(Date filterDate,Date validYearEnd, Date depositStartDate, BigDecimal amount, BigDecimal rate, BigDecimal basisDay) {
// 计算当年第一天1月1日
private BigDecimal calculationYearAmount(Date filterDate, Date depositStartDate,
Date depositEndDate, BigDecimal amount,
BigDecimal rate, BigDecimal basisDay,
DynamicObject row) {
// 获取解活日期
Date redeemDate = row.getDate("shjh_redeemdate");
// 情况1计提日 >= 结束日期
if (!filterDate.before(depositEndDate)) {
// 1.1 三个日期同年且解活日期不为null取实际收益
if (isSameYear(filterDate, depositStartDate)
&& isSameYear(filterDate, depositEndDate)
&& redeemDate != null) {
return row.getBigDecimal(FIELDS[18]); // 假设FIELDS[17]是本年实际收益字段
}
// 1.2 起始日期和计提日期同年算头不算尾
else if (isSameYear(filterDate, depositStartDate)) {
long days = TimeUnit.DAYS.convert(
depositEndDate.getTime() - depositStartDate.getTime(),
TimeUnit.MILLISECONDS);
return calculateInterest(amount, rate, basisDay, days);
}
// 1.3 不同年算头算尾
else if (isSameYear(filterDate, depositEndDate)){
long days = TimeUnit.DAYS.convert(
depositEndDate.getTime() - depositStartDate.getTime(),
TimeUnit.MILLISECONDS) + 1;
return calculateInterest(amount, rate, basisDay, days);
}else {
return BigDecimal.ZERO;
}
}
// 情况2计提日在有效期起始日 <= 计提日 < 结束日
else if (!filterDate.before(depositStartDate)
&& filterDate.before(depositEndDate)) {
// 2.1 计提日与起始日同年算头不算尾
if (isSameYear(filterDate, depositStartDate)) {
long days = TimeUnit.DAYS.convert(
filterDate.getTime() - depositStartDate.getTime(),
TimeUnit.MILLISECONDS);
return calculateInterest(amount, rate, basisDay, days);
}
// 2.2 不同年算头算尾
else {
// 当年第一天1月1日
Calendar cal = Calendar.getInstance();
cal.setTime(validYearEnd);
cal.setTime(filterDate);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date yearStart = cal.getTime();
// 有效起始日期取存款起期和年初较晚者
Date validYearStart = depositStartDate.after(yearStart) ?
depositStartDate : yearStart;
// 有效起始日取存款起始日和当年首日的较晚者
Date validStart = depositStartDate.after(yearStart)
? depositStartDate : yearStart;
// 有效天数 = validYearEnd - validYearStart
long yearDays = TimeUnit.DAYS.convert(
validYearEnd.getTime() - validYearStart.getTime(),
TimeUnit.MILLISECONDS
);
// 检查filterDate和depositStartDate是否在同年
Calendar filterCal = Calendar.getInstance();
filterCal.setTime(filterDate);
Calendar depositCal = Calendar.getInstance();
depositCal.setTime(depositStartDate);
boolean sameYear = filterCal.get(Calendar.YEAR) == depositCal.get(Calendar.YEAR);
// 如果是同年天数加1
if (sameYear) {
yearDays += 1;
}
return amount.multiply(rate)
.multiply(new BigDecimal(yearDays))
.divide(basisDay, 10, RoundingMode.HALF_UP)
.setScale(2, RoundingMode.HALF_UP);
long days = TimeUnit.DAYS.convert(
filterDate.getTime() - validStart.getTime(),
TimeUnit.MILLISECONDS) + 1;
return calculateInterest(amount, rate, basisDay, days);
}
}
// 情况3其他情况计提日 < 起始日
else {
return BigDecimal.ZERO;
}
}
/**
* 辅助方法判断两个日期是否在同一年同一月份
*/
private boolean isSameMonth(Date date1, Date date2) {
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
&& cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
}
/**
* 辅助方法判断两个日期是否在同一年
*/
private boolean isSameYear(Date date1, Date date2) {
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
}
}

View File

@ -1,6 +1,7 @@
package shjh.jhzj7.fi.fi.plugin.report;
import kd.bos.algo.DataSet;
import kd.bos.algo.JoinType;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.report.AbstractReportListDataPlugin;
import kd.bos.entity.report.FilterItemInfo;
@ -41,7 +42,7 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
private static final String[] DEPOSIT={"org","finorginfo","settleaccount","currency","intdate","expiredate","term","interestrate","basis","revenueproject","amount","productfactory"};
//定期利息计提报表字段
private static final String[] FIELDS={"shjh_orgname","shjh_bankname","shjh_bankaccount","shjh_currency","shjh_depositstartdate","shjh_depositstopdate","shjh_term","shjh_interestrate","shjh_basis","shjh_frequency","shjh_amount","shjh_depositmodel","shjh_accrualdate","shjh_accrualdays","shjh_accrualinterest","shjh_monthearnings","shjh_yearearnings"};
private static final String[] FIELDS={"shjh_orgname","shjh_bankname","shjh_bankaccount","shjh_currency","shjh_depositstartdate","shjh_depositstopdate","shjh_term","shjh_interestrate","shjh_basis","shjh_frequency","shjh_amount","shjh_depositmodel","shjh_accrualdate","shjh_redeemdate","shjh_realrevenue","shjh_accrualdays","shjh_accrualinterest","shjh_monthearnings","shjh_yearearnings"};
@ -74,7 +75,15 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
qFilters.add(new QFilter("org", QCP.equals,orgId));
}
//定期存款处理
selectFields.append(",").append("id");
DataSet dataSet = QueryServiceHelper.queryDataSet(this.getClass().getName(), "cim_deposit", selectFields.toString(), qFilters.toArray(new QFilter[]{}), null);
//定期存款处理解活处理
DataSet deaDataSet = QueryServiceHelper.queryDataSet(this.getClass().getName()+"1","cim_release","sourcebillid,redeemdate AS shjh_redeemdate,realrevenue AS shjh_realrevenue",(new QFilter("billstatus",QCP.equals,"C")).toArray(),null);
//组合
dataSet = dataSet.join(deaDataSet, JoinType.LEFT).on("id","sourcebillid").select(new String[]{"shjh_orgname","shjh_bankname","shjh_bankaccount","shjh_currency","shjh_depositstartdate","shjh_depositstopdate","shjh_term","shjh_interestrate","shjh_basis","shjh_frequency","shjh_amount","shjh_depositmodel","shjh_accrualdate"},new String[]{"shjh_redeemdate","shjh_realrevenue"}).finish();
//过滤----起始日<=计提日<=截至日到截止日年底
//起始日shjh_depositstartdate
//截止日shjh_depositstopdate
@ -100,7 +109,9 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
.addField("'-'",FIELDS[8])//计息基准
.addField("0L",FIELDS[9])//收益方案
.addField("0L",FIELDS[11])//存款模型
.addField("NULL",FIELDS[12]);//计提日期
.addField("NULL",FIELDS[12])//计提日期
.addField("NULL",FIELDS[13])//解活日期
.addField("0",FIELDS[14]);//实际收益
@ -109,7 +120,7 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
// 添加其他字段直接使用原字段名
for (int i = 1; i < FIELDS.length; i++) {
if (i==13){
if (i==15){
break;
}
selectExpression.append(", ").append(FIELDS[i]);
@ -126,7 +137,7 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
}
// 按组织名称排序这样底部的合计数据就会与上面的组织名称排在一起
assert unionDataSet != null;
return unionDataSet.orderBy(new String[]{FIELDS[0]});
return unionDataSet.orderBy(new String[]{"shjh_orgname asc","shjh_depositstartdate asc"});
}
/**