计提报表优化

This commit is contained in:
李贵强 2025-05-21 18:38:50 +08:00
parent e6cc9aebb4
commit 909f23f56d
2 changed files with 170 additions and 52 deletions

View File

@ -21,7 +21,7 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
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_accrualinterest","shjh_monthearnings","shjh_yearearnings","shjh_depositmodel","shjh_basis"};
@Override @Override
public void processRowData(String gridPK, DynamicObjectCollection rowData, ReportQueryParam queryParam) { public void processRowData(String gridPK, DynamicObjectCollection rowData, ReportQueryParam queryParam) {
super.processRowData(gridPK, rowData, queryParam); super.processRowData(gridPK, rowData, queryParam);
@ -44,33 +44,46 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
BigDecimal accruedInterest = BigDecimal.ZERO; BigDecimal accruedInterest = BigDecimal.ZERO;
BigDecimal monthlyIncome = BigDecimal.ZERO; BigDecimal monthlyIncome = BigDecimal.ZERO;
BigDecimal yearlyIncome = BigDecimal.ZERO; BigDecimal yearlyIncome = BigDecimal.ZERO;
long dayDiff = 0; long dayDiff=0;
if (filterDate != null && depositStartDate != null && depositEndDate != null) { if (filterDate != null && depositStartDate != null && depositEndDate != null) {
// 检查计提日期是否在有效区间(存款起期 <= 计提日期 <= 存款止期)
boolean isValidPeriod = !filterDate.before(depositStartDate) &&
!filterDate.after(depositEndDate);
// 计算天数差只在有效区间计算 // 获取金额
BigDecimal amount = row.getBigDecimal(FIELDS[9]);
//计息基准
String basis = row.getString(FIELDS[16]);
BigDecimal basisDay;
switch (basis){
case "Actual_365":
default:
basisDay= BigDecimal.valueOf(365);
break;
case "Actual_360":
case "DEP_30_360":
basisDay= BigDecimal.valueOf(360);
break;
}
//天利率=定存利率/计息基准
BigDecimal rate = row.getBigDecimal(FIELDS[7])
.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
if (amount != null && amount.compareTo(BigDecimal.ZERO) != 0 && rate.compareTo(BigDecimal.ZERO) != 0 ) {
// 检查计提日期是否在有效区间(存款起期 <= 计提日期 <= 存款止期)
boolean isValidPeriod = !filterDate.before(depositStartDate) &&
!filterDate.after(depositEndDate);
if (isValidPeriod) { if (isValidPeriod) {
dayDiff = TimeUnit.DAYS.convert( //计提天数
filterDate.getTime() - depositStartDate.getTime(), dayDiff = this.calculationDays(row,filterDate,depositStartDate);
TimeUnit.MILLISECONDS); /* 计提利息 = (金额 × 天利率 × 计提天数) */
// 获取金额和利率利率需要除以100
BigDecimal amount = row.getBigDecimal(FIELDS[9]);
BigDecimal rate = new BigDecimal(row.getLong(FIELDS[7]))
.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP);
if (amount != null && amount.compareTo(BigDecimal.ZERO) != 0 &&
rate.compareTo(BigDecimal.ZERO) != 0 && dayDiff > 0) {
/* 计提利息 = (金额 × 利率 × 计提天数) / 365 */
accruedInterest = amount.multiply(rate) accruedInterest = amount.multiply(rate)
.multiply(new BigDecimal(dayDiff)) .multiply(new BigDecimal(dayDiff))
.divide(new BigDecimal(365), 2, RoundingMode.HALF_UP); .divide(basisDay,10, RoundingMode.HALF_UP)
.setScale(2, RoundingMode.HALF_UP);
/* 计算本月收益 = 金额 × 利率 × 当月有效天数 */ /* 计算本月收益 = 金额 × 天利率 × 当月有效天数 */
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.setTime(filterDate); cal.setTime(filterDate);
@ -88,29 +101,55 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
monthlyIncome = amount.multiply(rate) monthlyIncome = amount.multiply(rate)
.multiply(new BigDecimal(monthDays)) .multiply(new BigDecimal(monthDays))
.setScale(2, RoundingMode.HALF_UP); .divide(basisDay,10, RoundingMode.HALF_UP)
/* 计算本年累计收益 = 金额 × 利率 × 当年有效天数 */
// 当年第一天
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 validYearEnd = filterDate.before(depositEndDate) ?
filterDate : depositEndDate;
long yearDays = TimeUnit.DAYS.convert(
validYearEnd.getTime() - validYearStart.getTime(),
TimeUnit.MILLISECONDS);
yearlyIncome = amount.multiply(rate)
.multiply(new BigDecimal(yearDays))
.setScale(2, RoundingMode.HALF_UP); .setScale(2, RoundingMode.HALF_UP);
} }
/* 计算本年累计收益 = 金额 × 利率 × 当年有效天数 */
//Date currentDate = new Date(); // 当前日期
Date validYearEnd = null; // 有效结束日期
if (filterDate.before(depositStartDate)) {
// 当日期早于存款起期本年累计收益 = 0
yearlyIncome = BigDecimal.ZERO;
} else if (filterDate.after(depositEndDate)) {
// 当日期晚于存款到期日计算到 depositEndDate 的累计收益
validYearEnd = depositEndDate;
yearlyIncome = this.calculationYearAmount(validYearEnd, depositStartDate, amount, rate, basisDay);
} else {
// 当前日期在有效期内计算到当前日期的累计收益
validYearEnd = filterDate;
yearlyIncome = this.calculationYearAmount(validYearEnd, depositStartDate, amount, rate, basisDay);
}
} }
// else {
// //TODO:计提日期年份大于截至日期;计提日期小于启始日期 ---跳过
// // 计提日期不在有效区间内的情况处理
// Calendar filterCal = Calendar.getInstance();
// filterCal.setTime(filterDate);
//
// Calendar startCal = Calendar.getInstance();
// startCal.setTime(depositStartDate);
//
// Calendar endCal = Calendar.getInstance();
// endCal.setTime(depositEndDate);
//
// // 检查是否不在同一年
// boolean notSameYearBefore = filterCal.get(Calendar.YEAR) != startCal.get(Calendar.YEAR);
// boolean notSameYearAfter = filterCal.get(Calendar.YEAR) != endCal.get(Calendar.YEAR);
//
// if (filterDate.before(depositStartDate) && notSameYearBefore) {
// // 计提日期小于起始日期且不在同一年 ---跳过
// iterator.remove();
// continue;
// }
// if (filterDate.after(depositEndDate) && notSameYearAfter) {
// // 计提日期大于截至日期且不在同一年 ---跳过
// iterator.remove();
// continue;
// }
// }
} }
if (companyName.contains("小计")){ if (companyName.contains("小计")){
row.set(FIELDS[11], ""); // 计提天数 row.set(FIELDS[11], ""); // 计提天数
@ -126,7 +165,7 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
subMonthAmt=subMonthAmt.add(monthlyIncome); subMonthAmt=subMonthAmt.add(monthlyIncome);
subYearAmt=subYearAmt.add(yearlyIncome); subYearAmt=subYearAmt.add(yearlyIncome);
// 设置结果 // 设置结果
row.set(FIELDS[11], String.valueOf(dayDiff)); // 计提天数 row.set(FIELDS[11], dayDiff==0 ? null:String.valueOf(dayDiff)); // 计提天数
row.set(FIELDS[12], accruedInterest); // 计提利息/365计算 row.set(FIELDS[12], accruedInterest); // 计提利息/365计算
row.set(FIELDS[13], monthlyIncome); // 本月收益金额×利率×有效天数 row.set(FIELDS[13], monthlyIncome); // 本月收益金额×利率×有效天数
row.set(FIELDS[14], yearlyIncome); // 本年累计收益金额×利率×有效天数 row.set(FIELDS[14], yearlyIncome); // 本年累计收益金额×利率×有效天数
@ -151,8 +190,7 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
List<DynamicObject> rowsToRemove = new ArrayList<>(); List<DynamicObject> rowsToRemove = new ArrayList<>();
for (DynamicObject row : rowData) { for (DynamicObject row : rowData) {
String companyName = row.getString(FIELDS[0]); String companyName = row.getString(FIELDS[0]);//公司名称
// 如果是"公司名称-小计"格式的行 // 如果是"公司名称-小计"格式的行
if (companyName != null && companyName.contains("-小计")) { if (companyName != null && companyName.contains("-小计")) {
// 如果是第一次遇到该公司的小计行 // 如果是第一次遇到该公司的小计行
@ -165,6 +203,15 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
rowsToRemove.add(row); rowsToRemove.add(row);
} }
} }
String term = row.getString(FIELDS[6]);//存期处理
if (term !=null && !"-".equals(term)){
//term的格式4y5m25d4y30d转换为4年5月25天格式
// term的格式4y5m25d4y30d转换为4年5月25天格式
term = term.replaceAll("(\\d+)y", "$1年") // 替换y为年
.replaceAll("(\\d+)m", "$1月") // 替换m为月
.replaceAll("(\\d+)d", "$1天"); // 替换d为天
row.set(FIELDS[6],term);
}
} }
// 移除重复的小计行 // 移除重复的小计行
@ -214,4 +261,64 @@ public class RegularFormReport extends AbstractReportFormPlugin implements Plugi
rowData.add(dynamicObject); rowData.add(dynamicObject);
} }
/**
* 计算计提天数
* @param row
* @param filterDate 计提日期
* @param depositStartDate 启始日期
* @return
*/
private long calculationDays(DynamicObject row,Date filterDate,Date depositStartDate){
long dayDiff = 0;
//默认规则
String calculationRule="headnotail";
DynamicObject depositModel = row.getDynamicObject(FIELDS[15]);
if (depositModel!=null){
calculationRule=depositModel.getString("intheadtailrule");
}
switch (calculationRule){
case "headnotail"://算头不算尾
case "noheadtail"://算尾不算头
default:
dayDiff = TimeUnit.DAYS.convert(
filterDate.getTime() - depositStartDate.getTime(),
TimeUnit.MILLISECONDS);
break;
case "headtail"://算头又算尾
dayDiff = TimeUnit.DAYS.convert(
filterDate.getTime() - depositStartDate.getTime() + 1,
TimeUnit.MILLISECONDS);
break;
case "noheadnotail"://头尾都不算
dayDiff = TimeUnit.DAYS.convert(
filterDate.getTime() - depositStartDate.getTime() - 1,
TimeUnit.MILLISECONDS);
break;
}
return dayDiff;
}
private BigDecimal calculationYearAmount(Date validYearEnd,Date depositStartDate, BigDecimal amount,BigDecimal rate,BigDecimal basisDay){
// 计算当年第一天1月1日
Calendar cal = Calendar.getInstance();
cal.setTime(validYearEnd);
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DAY_OF_MONTH, 1);
Date yearStart = cal.getTime();
// 有效起始日期取存款起期和年初较晚者
Date validYearStart = depositStartDate.after(yearStart) ?
depositStartDate : yearStart;
// 有效天数 = validYearEnd - validYearStart
long yearDays = TimeUnit.DAYS.convert(
validYearEnd.getTime() - validYearStart.getTime(),
TimeUnit.MILLISECONDS
);
return amount.multiply(rate)
.multiply(new BigDecimal(yearDays))
.divide(basisDay,10, RoundingMode.HALF_UP)
.setScale(2, RoundingMode.HALF_UP);
}
} }

View File

@ -30,11 +30,17 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
//计提日期 //计提日期
private static final String KEY_FILTER_DATE = "shjh_filterdate"; private static final String KEY_FILTER_DATE = "shjh_filterdate";
//银行名称
private static final String KEY_FILTER_BANK_NAME = "shjh_filterbankname";
//银行账户
private static final String KEY_FILTER_BANK_NUM = "shjh_filterbanknum";
//定期存款处理表字段 //定期存款处理表字段
private static final String[] DEPOSIT={"org","finorginfo","finaccount","currency","intdate","expiredate","term","interestrate","revenueproject","amount"}; 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_frequency","shjh_amount","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_accrualdays","shjh_accrualinterest","shjh_monthearnings","shjh_yearearnings"};
@ -49,6 +55,7 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
Long orgId=null; Long orgId=null;
String accrualDate=null; String accrualDate=null;
List<QFilter> qFilters=new ArrayList<>(); List<QFilter> qFilters=new ArrayList<>();
qFilters.add(new QFilter("billstatus",QCP.equals,"C"));
for (FilterItemInfo filterItem : filterItems) { for (FilterItemInfo filterItem : filterItems) {
switch (filterItem.getPropName()){ switch (filterItem.getPropName()){
case KEY_FILTER_ORG: case KEY_FILTER_ORG:
@ -56,7 +63,7 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
break; break;
case KEY_FILTER_DATE: case KEY_FILTER_DATE:
accrualDate=(filterItem.getDate()==null) ? null:new SimpleDateFormat("yyyy-MM-dd").format(filterItem.getDate()); accrualDate=(filterItem.getDate()==null) ? null:new SimpleDateFormat("yyyy-MM-dd").format(filterItem.getDate());
selectFields.append("'").append(accrualDate).append("'").append(FIELDS[10]); selectFields.append("'").append(accrualDate).append("'").append(FIELDS[12]);
break; break;
default: default:
break; break;
@ -65,20 +72,24 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
if (orgId!=null){ if (orgId!=null){
qFilters.add(new QFilter("org", QCP.equals,orgId)); qFilters.add(new QFilter("org", QCP.equals,orgId));
} }
//定期存款处理
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 groupDataSet = dataSet.groupBy(new String[]{FIELDS[0]}).sum(FIELDS[9]).finish(); DataSet groupDataSet = dataSet.groupBy(new String[]{FIELDS[0]}).sum(FIELDS[10]).finish();
// 由于分组计算之后Dataset的字段少了一个需要通过addField加回来为之后union做准备 // 由于分组计算之后Dataset的字段少了一个需要通过addField加回来为之后union做准备
groupDataSet = groupDataSet groupDataSet = groupDataSet
.addField("0L", FIELDS[1])//银行名称-id .addField("0L", FIELDS[1])//银行名称-id
.addField("'-'",FIELDS[2])//银行账户 .addField("0L",FIELDS[2])//银行账户
.addField("0L",FIELDS[3])//币种 .addField("0L",FIELDS[3])//币种
.addField("NULL",FIELDS[4])//起款日期 .addField("NULL",FIELDS[4])//起款日期
.addField("NULL",FIELDS[5])//存款止期 .addField("NULL",FIELDS[5])//存款止期
.addField("'-'",FIELDS[6])//存期 .addField("'-'",FIELDS[6])//存期
.addField("0",FIELDS[7])//利率 .addField("0",FIELDS[7])//利率
.addField("0L",FIELDS[8])//频率 .addField("'-'",FIELDS[8])//计息基准
.addField("NULL",FIELDS[10]);//计提日期 .addField("0L",FIELDS[9])//收益方案
.addField("0L",FIELDS[11])//存款模型
.addField("NULL",FIELDS[12]);//计提日期
StringBuilder selectExpression = new StringBuilder(); StringBuilder selectExpression = new StringBuilder();
@ -86,7 +97,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==11){ if (i==13){
break; break;
} }
selectExpression.append(", ").append(FIELDS[i]); selectExpression.append(", ").append(FIELDS[i]);