diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/report/RegularFormReport.java b/main/java/shjh/jhzj7/fi/fi/plugin/report/RegularFormReport.java index 7f62450..5c30b55 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/report/RegularFormReport.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/report/RegularFormReport.java @@ -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); - - /* 计提利息 = (金额 × 天利率 × 计提天数) */ - 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); + //若计提日期 = 实际到期日期 , 计提利息=实际收益 + 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); + } } - /* 计算本年累计收益 = 金额 × 利率 × 当年有效天数 */ - Date validYearEnd = null; // 有效结束日期 + /* 计算本月收益 = 金额 × 天利率 × 当月有效天数 */ + monthlyIncome = this.calculationMonthAmount(filterDate, depositStartDate,depositEndDate, amount, rate, basisDay,row); - 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) { - Calendar cal = Calendar.getInstance(); - cal.setTime(filterDate); + private BigDecimal calculationMonthAmount(Date filterDate, Date depositStartDate, + Date depositEndDate, BigDecimal amount, + BigDecimal rate, BigDecimal basisDay, + DynamicObject row) { + // 获取解活日期 + Date redeemDate = row.getDate("shjh_redeemdate"); - // 当月第一天 - cal.set(Calendar.DAY_OF_MONTH, 1); - Date monthStart = cal.getTime(); - - // 当月有效天数(存款起期与当月首日的较晚者) - Date validMonthStart = 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; + // 情况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 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) - .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日) - Calendar cal = Calendar.getInstance(); - cal.setTime(validYearEnd); - cal.set(Calendar.MONTH, Calendar.JANUARY); - cal.set(Calendar.DAY_OF_MONTH, 1); - Date yearStart = cal.getTime(); + private BigDecimal calculationYearAmount(Date filterDate, Date depositStartDate, + Date depositEndDate, BigDecimal amount, + BigDecimal rate, BigDecimal basisDay, + DynamicObject row) { + // 获取解活日期 + Date redeemDate = row.getDate("shjh_redeemdate"); - // 有效起始日期(取存款起期和年初较晚者) - Date validYearStart = 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; + // 情况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(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)) - .divide(basisDay, 10, RoundingMode.HALF_UP) - .setScale(2, RoundingMode.HALF_UP); + // 有效起始日(取存款起始日和当年首日的较晚者) + Date validStart = depositStartDate.after(yearStart) + ? depositStartDate : yearStart; + + 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); + } + + } \ No newline at end of file diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/report/RegularListReport.java b/main/java/shjh/jhzj7/fi/fi/plugin/report/RegularListReport.java index 9519248..51819d7 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/report/RegularListReport.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/report/RegularListReport.java @@ -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"}); } /**