计提报表本年本月收益优化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 { 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_depositstartdate", "shjh_depositstopdate", "shjh_term", "shjh_interestrate",
"shjh_frequency", "shjh_amount", "shjh_accrualdate", "shjh_accrualdays", "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 @Override
public void processRowData(String gridPK, DynamicObjectCollection rowData, ReportQueryParam queryParam) { 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 filterDate = queryParam.getFilter().getDate("shjh_filterdate");
Date depositStartDate = row.getDate(FIELDS[4]); 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; BigDecimal accruedInterest = BigDecimal.ZERO;
@ -77,32 +80,23 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
if (isValidPeriod) { if (isValidPeriod) {
//计提天数 //计提天数
dayDiff = this.calculationDays(row, filterDate, depositStartDate); dayDiff = this.calculationDays(row, filterDate, depositStartDate);
//若计提日期 = 实际到期日期 计提利息=实际收益
/* 计提利息 = (金额 × 天利率 × 计提天数) */ if (filterDate.equals(depositEndDate)){
accruedInterest = amount.multiply(rate) accruedInterest = row.getBigDecimal(FIELDS[18]);
.multiply(new BigDecimal(dayDiff)) }else {
.divide(basisDay, 10, RoundingMode.HALF_UP) /* 计提利息 = (金额 × 天利率 × 计提天数) */
.setScale(2, RoundingMode.HALF_UP); accruedInterest = amount.multiply(rate)
.multiply(new BigDecimal(dayDiff))
/* 计算本月收益 = 金额 × 天利率 × 当月有效天数 */ .divide(basisDay, 10, RoundingMode.HALF_UP)
monthlyIncome = this.calculationMonthAmount(filterDate, depositStartDate, amount, rate, basisDay); .setScale(2, RoundingMode.HALF_UP);
}
} }
/* 计算本年累计收益 = 金额 × 利率 × 当年有效天数 */ /* 计算本月收益 = 金额 × 天利率 × 当月有效天数 */
Date validYearEnd = null; // 有效结束日期 monthlyIncome = this.calculationMonthAmount(filterDate, depositStartDate,depositEndDate, amount, rate, basisDay,row);
if (filterDate.before(depositStartDate)) { /* 计算本年累计收益 = 金额 × 天利率 × 当年有效天数 */
// 当日期早于存款起期本年累计收益 = 0 yearlyIncome = this.calculationYearAmount(filterDate,depositStartDate,depositEndDate,amount,rate,basisDay,row);
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);
}
} }
} }
@ -260,90 +254,195 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
* 计算本月累计收益 * 计算本月累计收益
* @param filterDate 计提日期 * @param filterDate 计提日期
* @param depositStartDate 起始日期 * @param depositStartDate 起始日期
* @param depositEndDate 结束日期
* @param amount 金额 * @param amount 金额
* @param rate 利率 * @param rate 利率
* @param basisDay 计息基准 * @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,
Calendar cal = Calendar.getInstance(); Date depositEndDate, BigDecimal amount,
cal.setTime(filterDate); BigDecimal rate, BigDecimal basisDay,
DynamicObject row) {
// 获取解活日期
Date redeemDate = row.getDate("shjh_redeemdate");
// 当月第一天 // 情况1计提日 >= 结束日期
cal.set(Calendar.DAY_OF_MONTH, 1); if (!filterDate.before(depositEndDate)) {
Date monthStart = cal.getTime(); // 1.1 三个日期同月且解活日期不为null取实际收益
if (isSameMonth(filterDate, depositStartDate)
// 当月有效天数存款起期与当月首日的较晚者 && isSameMonth(filterDate, depositEndDate)
Date validMonthStart = depositStartDate.after(monthStart) ? depositStartDate : monthStart; && redeemDate != null) {
return row.getBigDecimal(FIELDS[18]);
long monthDays = TimeUnit.DAYS.convert( }
filterDate.getTime() - validMonthStart.getTime(), // 1.2 起始日期和计提日期同月算头不算尾
TimeUnit.MILLISECONDS); else if (isSameMonth(filterDate, depositStartDate)) {
long days = TimeUnit.DAYS.convert(
// 检查filterDate和depositStartDate是否在同年同月 depositEndDate.getTime() - depositStartDate.getTime(),
Calendar filterCal = Calendar.getInstance(); TimeUnit.MILLISECONDS);
filterCal.setTime(filterDate); return calculateInterest(amount, rate, basisDay, days);
Calendar depositCal = Calendar.getInstance(); }
depositCal.setTime(depositStartDate); // 1.3 不同月算头算尾
else if (isSameMonth(filterDate, depositEndDate)){
boolean sameYearMonth = filterCal.get(Calendar.YEAR) == depositCal.get(Calendar.YEAR) long days = TimeUnit.DAYS.convert(
&& filterCal.get(Calendar.MONTH) == depositCal.get(Calendar.MONTH); depositEndDate.getTime() - depositStartDate.getTime(),
TimeUnit.MILLISECONDS) + 1;
// 如果是同年同月天数加1 return calculateInterest(amount, rate, basisDay, days);
if (sameYearMonth) { }else {
monthDays += 1; 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 validStart = depositStartDate.after(monthStart)
? depositStartDate : monthStart;
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) return amount.multiply(rate)
.multiply(new BigDecimal(monthDays)) .multiply(new BigDecimal(days))
.divide(basisDay, 10, RoundingMode.HALF_UP) .divide(basisDay, 10, RoundingMode.HALF_UP)
.setScale(2, RoundingMode.HALF_UP); .setScale(2, RoundingMode.HALF_UP);
} }
/** /**
* 计算本年累计收益 * 计算本年累计收益
* @param filterDate 计提日期 * @param filterDate 计提日期
* @param validYearEnd 结束有效日期
* @param depositStartDate 起始日期 * @param depositStartDate 起始日期
* @param depositEndDate 结束日期
* @param amount 金额 * @param amount 金额
* @param rate 利率 * @param rate 利率
* @param basisDay 计息基准 * @param basisDay 计息基准
* @param row 数据行
* @return 本年累计收益 * @return 本年累计收益
*/ */
private BigDecimal calculationYearAmount(Date filterDate,Date validYearEnd, Date depositStartDate, BigDecimal amount, BigDecimal rate, BigDecimal basisDay) { private BigDecimal calculationYearAmount(Date filterDate, Date depositStartDate,
// 计算当年第一天1月1日 Date depositEndDate, BigDecimal amount,
Calendar cal = Calendar.getInstance(); BigDecimal rate, BigDecimal basisDay,
cal.setTime(validYearEnd); DynamicObject row) {
cal.set(Calendar.MONTH, Calendar.JANUARY); // 获取解活日期
cal.set(Calendar.DAY_OF_MONTH, 1); Date redeemDate = row.getDate("shjh_redeemdate");
Date yearStart = cal.getTime();
// 有效起始日期取存款起期和年初较晚者 // 情况1计提日 >= 结束日期
Date validYearStart = depositStartDate.after(yearStart) ? if (!filterDate.before(depositEndDate)) {
depositStartDate : yearStart; // 1.1 三个日期同年且解活日期不为null取实际收益
if (isSameYear(filterDate, depositStartDate)
// 有效天数 = validYearEnd - validYearStart && isSameYear(filterDate, depositEndDate)
long yearDays = TimeUnit.DAYS.convert( && redeemDate != null) {
validYearEnd.getTime() - validYearStart.getTime(), return row.getBigDecimal(FIELDS[18]); // 假设FIELDS[17]是本年实际收益字段
TimeUnit.MILLISECONDS }
); // 1.2 起始日期和计提日期同年算头不算尾
else if (isSameYear(filterDate, depositStartDate)) {
// 检查filterDate和depositStartDate是否在同年 long days = TimeUnit.DAYS.convert(
Calendar filterCal = Calendar.getInstance(); depositEndDate.getTime() - depositStartDate.getTime(),
filterCal.setTime(filterDate); TimeUnit.MILLISECONDS);
Calendar depositCal = Calendar.getInstance(); return calculateInterest(amount, rate, basisDay, days);
depositCal.setTime(depositStartDate); }
// 1.3 不同年算头算尾
boolean sameYear = filterCal.get(Calendar.YEAR) == depositCal.get(Calendar.YEAR); else if (isSameYear(filterDate, depositEndDate)){
long days = TimeUnit.DAYS.convert(
// 如果是同年天数加1 depositEndDate.getTime() - depositStartDate.getTime(),
if (sameYear) { TimeUnit.MILLISECONDS) + 1;
yearDays += 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(filterDate);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date yearStart = cal.getTime();
return amount.multiply(rate) // 有效起始日取存款起始日和当年首日的较晚者
.multiply(new BigDecimal(yearDays)) Date validStart = depositStartDate.after(yearStart)
.divide(basisDay, 10, RoundingMode.HALF_UP) ? depositStartDate : yearStart;
.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; package shjh.jhzj7.fi.fi.plugin.report;
import kd.bos.algo.DataSet; import kd.bos.algo.DataSet;
import kd.bos.algo.JoinType;
import kd.bos.dataentity.entity.DynamicObject; import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.report.AbstractReportListDataPlugin; import kd.bos.entity.report.AbstractReportListDataPlugin;
import kd.bos.entity.report.FilterItemInfo; 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[] 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)); 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 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_depositstartdate
//截止日shjh_depositstopdate //截止日shjh_depositstopdate
@ -100,7 +109,9 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
.addField("'-'",FIELDS[8])//计息基准 .addField("'-'",FIELDS[8])//计息基准
.addField("0L",FIELDS[9])//收益方案 .addField("0L",FIELDS[9])//收益方案
.addField("0L",FIELDS[11])//存款模型 .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++) { for (int i = 1; i < FIELDS.length; i++) {
if (i==13){ if (i==15){
break; break;
} }
selectExpression.append(", ").append(FIELDS[i]); selectExpression.append(", ").append(FIELDS[i]);
@ -126,7 +137,7 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
} }
// 按组织名称排序这样底部的合计数据就会与上面的组织名称排在一起 // 按组织名称排序这样底部的合计数据就会与上面的组织名称排在一起
assert unionDataSet != null; assert unionDataSet != null;
return unionDataSet.orderBy(new String[]{FIELDS[0]}); return unionDataSet.orderBy(new String[]{"shjh_orgname asc","shjh_depositstartdate asc"});
} }
/** /**