理财报表优化3.0
This commit is contained in:
		
							parent
							
								
									f1ff3dff9b
								
							
						
					
					
						commit
						f54bb8c5b8
					
				|  | @ -74,21 +74,52 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|         BigDecimal sumProvisionEarnings =BigDecimal.ZERO;//收益计提汇总 | ||||
|         BigDecimal sumMonthEarnings =BigDecimal.ZERO;//本月收益汇总 | ||||
|         BigDecimal sumYearEarnings =BigDecimal.ZERO;//本年收益汇总 | ||||
|         BigDecimal sumActualEarnings =BigDecimal.ZERO;//实际收益汇总 | ||||
| 
 | ||||
| 
 | ||||
|         while (iterator.hasNext()) { | ||||
|             DynamicObject row = iterator.next(); | ||||
|             // 基础字段获取(添加null检查) | ||||
|             //1.金额(千元)设置 | ||||
|             BigDecimal amount = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[4]); // 原始金额(元) | ||||
|             BigDecimal buyAmount = amount.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);//购买金额(千元) | ||||
|             row.set(REPORT_FIELDS[4],buyAmount); | ||||
| 
 | ||||
|             Date buyDate = row.getDate(REPORT_FIELDS[7]); // 购买日 | ||||
|             Date valueDate = row.getDate(REPORT_FIELDS[8]); // 计息日 | ||||
|             Date expireDate = row.getDate(REPORT_FIELDS[9]); // 到期日 | ||||
|             Date expireDate = row.getDate(REPORT_FIELDS[9]); // 到期日-初始值 | ||||
|             BigDecimal expectedRate = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[10]); // 预计业绩比较基准(%) | ||||
|             String basis = row.getString(REPORT_FIELDS[15]);//计息基准 | ||||
|             //理财申购单估值分录处理 | ||||
| 
 | ||||
|             // 2. 设置计提日 | ||||
|             row.set(DYNAMICS_FIELDS[1], accrualDate); | ||||
| 
 | ||||
| 
 | ||||
|             // 3. 计算产品期限(总天数)=到期日-计息日 | ||||
|             String term = countProductTerm(valueDate, expireDate, accrualDate, row); | ||||
| 
 | ||||
|             // 4. 计算天数 = 计提日 - 计息日 | ||||
|             // 计提日<=到期日:计提日 - 计息日 | ||||
|             // 计提日>到期日:到期日 - 计息日 | ||||
|             Date expireDate2 = row.getDate(REPORT_FIELDS[9]);//到期日-改动值 | ||||
| 
 | ||||
|             BigDecimal days = countDays(valueDate,expireDate2, accrualDate, row); | ||||
| 
 | ||||
|             // 5.计息基准天数 | ||||
|             BigDecimal basisDays = computeBasisDays(basis); | ||||
| 
 | ||||
|             // 6. 预计收益 = 产品期限 * 金额(千元) * 预计业绩比较基准 / 365 | ||||
|             BigDecimal proRevenue = countProRevenue(expectedRate, term, amount, row,basisDays); | ||||
|             sumProjectedEarnings=sumProjectedEarnings.add(proRevenue); | ||||
| 
 | ||||
| 
 | ||||
|             // 理财申购单估值分录相关数据处理 | ||||
|             // 7. 持有份额 = 计提日期向上最近持有份额 | ||||
|             // 8. 月末单位净值 = 计提日期向上最近一次的净值 | ||||
|             // 9. 月末净值报告日 = 计提日期向上最近一次的估值日期 | ||||
|             // 10. 本月收益(千元)、当月年化收益率% | ||||
|             // 11. 本年累计收益(千元)、本年累计年化收益率 | ||||
|             Long id = row.getLong(REPORT_FIELDS[13]); | ||||
|             valuationEntry(accrualDate,buyDate,buyAmount,id,row); | ||||
|             valuationEntry(accrualDate,buyDate,expireDate2,valueDate,buyAmount,days,basisDays,id,row); | ||||
| 
 | ||||
|             BigDecimal buyCopies = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[5]); // 持有份额 | ||||
|             BigDecimal netWorth = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[6]); // 购买时单位净值 | ||||
|  | @ -96,33 +127,22 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|             BigDecimal startBuyCopies = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[16]); // 购买份额 | ||||
| 
 | ||||
| 
 | ||||
|             // 1. 设置计提日 | ||||
|             row.set(DYNAMICS_FIELDS[1], accrualDate); | ||||
|             // 2. 计算天数 = 计提日 - 计息日 | ||||
|             countDays(valueDate,accrualDate,row); | ||||
|             // 3. 计算产品期限(总天数)=到期日-计息日 | ||||
|             String day = countProductTerm(valueDate, expireDate, accrualDate, row); | ||||
|             // 4. 预计收益 = 产品期限 * 金额(千元) * 预计业绩比较基准 / 365 | ||||
|             BigDecimal proRevenue = countProRevenue(expectedRate, day, amount, row,basis); | ||||
|             sumProjectedEarnings=sumProjectedEarnings.add(proRevenue); | ||||
|             // 5. 收益计提 =  (持有份额 *月末单位净值 - 购买份额*购买时单位净值) / 1000 | ||||
|             BigDecimal revenueAmt = countRevenueAmt(buyCopies, monthNetWorth, netWorth, row,startBuyCopies); | ||||
|             // 12. 收益计提 =  (持有份额 *月末单位净值 - 购买份额*购买时单位净值) / 1000 | ||||
|             BigDecimal revenueAmt = countRevenueAmt(valueDate,expireDate2, accrualDate,buyCopies, monthNetWorth, netWorth, row,startBuyCopies); | ||||
|             sumProvisionEarnings=sumProvisionEarnings.add(revenueAmt); | ||||
| 
 | ||||
|             // 本月收益计算累计 | ||||
|             //BigDecimal monthRevenue = countMonthRevenue(monthNetWorth, netWorth, buyCopies, valueDate, accrualDate, expireDate, row); | ||||
|             BigDecimal monthRevenue = ReportUtils.getBigDecimalValue(row, DYNAMICS_FIELDS[4]); | ||||
|             sumMonthEarnings=sumMonthEarnings.add(monthRevenue); | ||||
|             // 7. 当月收益率 = 本月收益 / 金额(千元) * 100 * 12 | ||||
|             //countMonthRate(amount,monthRevenue,row); | ||||
| 
 | ||||
|             // 本年收益累计 | ||||
|             //BigDecimal yearRevenue = countYearRevenue(monthNetWorth, netWorth, buyCopies, valueDate, accrualDate, expireDate, row); | ||||
|             BigDecimal yearRevenue = ReportUtils.getBigDecimalValue(row, DYNAMICS_FIELDS[6]); | ||||
|             sumYearEarnings=sumYearEarnings.add(yearRevenue); | ||||
| 
 | ||||
|             //实际总收益率=实际收益/金额 | ||||
|             BigDecimal actualEarnings = ReportUtils.getBigDecimalValue(row, DYNAMICS_FIELDS[8]); | ||||
|             row.set(DYNAMICS_FIELDS[9],actualEarnings.divide(buyAmount,2, RoundingMode.HALF_UP)); | ||||
| 
 | ||||
|             sumActualEarnings=sumActualEarnings.add(actualEarnings); | ||||
| 
 | ||||
|             //小计行合计 | ||||
| //            if (row.getString(REPORT_FIELDS[0]).contains("-小计")){ | ||||
|  | @ -141,6 +161,8 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
| 
 | ||||
|         //小计行处理 | ||||
|         //ReportUtils.changeRowData(rowData,REPORT_FIELDS[0]); | ||||
|         //过滤 | ||||
|         ReportUtils.removeRowData(rowData,REPORT_FIELDS[9],DYNAMICS_FIELDS[1]); | ||||
|         //添加合计 | ||||
|         // 需要配置求和的字段映射(目标字段,来源字段) | ||||
|         List<String[]> sumConfig = new ArrayList<>(); | ||||
|  | @ -151,6 +173,7 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|         sumConfig.add(new String[]{DYNAMICS_FIELDS[3], DYNAMICS_FIELDS[3]}); // shjh_revenueamt | ||||
|         sumConfig.add(new String[]{DYNAMICS_FIELDS[4], DYNAMICS_FIELDS[4]}); // shjh_monthrevenueamt | ||||
|         sumConfig.add(new String[]{DYNAMICS_FIELDS[6], DYNAMICS_FIELDS[6]}); // shjh_yearrevenueamt | ||||
|         sumConfig.add(new String[]{DYNAMICS_FIELDS[8], DYNAMICS_FIELDS[8]}); // shjh_actualearnings | ||||
| 
 | ||||
|         ReportUtils.addTotalRowData(rowData,REPORT_FIELDS[0],"小计","合计",sumConfig); | ||||
| 
 | ||||
|  | @ -161,10 +184,13 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|      * 获取估值分录数据 | ||||
|      * @param accrualDate 计提日 | ||||
|      * @param buyDate 购买日期 | ||||
|      * @param expireDate 到期日 | ||||
|      * @param buyAmount 购买金额 | ||||
|      * @param days 天数(计提日-计息日) | ||||
|      * @param basisDays 计息基准天数 | ||||
|      * @param id 表单id | ||||
|      */ | ||||
|     private void valuationEntry(Date accrualDate, Date buyDate, BigDecimal buyAmount, Long id, DynamicObject row) { | ||||
|     private void valuationEntry(Date accrualDate, Date buyDate,Date expireDate,Date valueDate, BigDecimal buyAmount,BigDecimal days,BigDecimal basisDays, Long id, DynamicObject row) { | ||||
|         // 初始化所有变量 | ||||
|         BigDecimal buyCopies = BigDecimal.ZERO; | ||||
|         BigDecimal monthIop = BigDecimal.ZERO; | ||||
|  | @ -173,7 +199,6 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|         BigDecimal monthAnnualizedRate = BigDecimal.ZERO; | ||||
|         BigDecimal yearAmount = BigDecimal.ZERO; | ||||
|         BigDecimal yearAnnualizedRate = BigDecimal.ZERO; | ||||
|         BigDecimal yearStartAmount = buyAmount; | ||||
| 
 | ||||
|         DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(id, "cim_finsubscribe"); | ||||
|         if (dynamicObject != null) { | ||||
|  | @ -187,60 +212,95 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|                 DynamicObject yearStartRecord = null; | ||||
|                 long minDiff = Long.MAX_VALUE; | ||||
| 
 | ||||
|                 // 获取日期信息 | ||||
|                 // 获取计提日期相关信息 | ||||
|                 Calendar accrualCal = Calendar.getInstance(); | ||||
|                 accrualCal.setTime(accrualDate); | ||||
|                 int accrualYear = accrualCal.get(Calendar.YEAR); | ||||
|                 int accrualMonth = accrualCal.get(Calendar.MONTH); | ||||
|                 //与年初相隔天数 | ||||
|                 int daysFromJan1 = accrualCal.get(Calendar.DAY_OF_YEAR) - 1; | ||||
| 
 | ||||
|                 //获取购买日相关信息 | ||||
|                 Calendar buyCal = Calendar.getInstance(); | ||||
|                 buyCal.setTime(buyDate); | ||||
|                 int buyYear = buyCal.get(Calendar.YEAR); | ||||
|                 int buyMonth = buyCal.get(Calendar.MONTH); | ||||
| 
 | ||||
| 
 | ||||
|                 // 遍历估值记录 | ||||
|                 for (DynamicObject object : dynamicObjectCollection) { | ||||
|                     Date valuationdate = object.getDate("e_valuationdate"); | ||||
|                     if (valuationdate == null) continue; | ||||
|                     Date valuationDate = object.getDate("e_valuationdate"); | ||||
|                     if (valuationDate == null) continue; | ||||
| 
 | ||||
|                     Date redeemDate = object.getDate("shjh_shrq"); // 获取赎回日期 | ||||
|                     Calendar valCal = Calendar.getInstance(); | ||||
|                     valCal.setTime(valuationdate); | ||||
|                     valCal.setTime(valuationDate); | ||||
|                     int valYear = valCal.get(Calendar.YEAR); | ||||
|                     int valMonth = valCal.get(Calendar.MONTH); | ||||
| 
 | ||||
|                     // 1. 寻找离计提日最近的份额记录 | ||||
|                     long diff = Math.abs(valuationdate.getTime() - accrualDate.getTime()); | ||||
|                     // 1. 寻找离计提日最近的份额记录(相同日期取赎回日期最大的) | ||||
|                     long diff = Math.abs(valuationDate.getTime() - accrualDate.getTime()); | ||||
|                     if (diff < minDiff) { | ||||
|                         minDiff = diff; | ||||
|                         closestRecord = object; | ||||
|                     } | ||||
| 
 | ||||
|                     // 2. 寻找本月最后一次估值记录 | ||||
|                     if (!valuationdate.after(accrualDate)) { | ||||
|                         if (latestIopRecord == null || valuationdate.after(latestIopRecord.getDate("e_valuationdate"))) { | ||||
|                             latestIopRecord = object; | ||||
|                     } else if (diff == minDiff && closestRecord != null) { | ||||
|                         // 相同估值日期时,比较赎回日期 | ||||
|                         Date currentRedeemDate = closestRecord.getDate("shjh_shrq"); | ||||
|                         if (redeemDate != null && (currentRedeemDate == null || redeemDate.after(currentRedeemDate))) { | ||||
|                             closestRecord = object; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // 3. 寻找上月最后一次估值记录 | ||||
|                     // 2. 寻找本月最后一次估值记录(相同日期取赎回日期最大的) | ||||
|                     if (!valuationDate.after(accrualDate)) { | ||||
|                         if (latestIopRecord == null) { | ||||
|                             latestIopRecord = object; | ||||
|                         } else { | ||||
|                             int dateCompare = valuationDate.compareTo(latestIopRecord.getDate("e_valuationdate")); | ||||
|                             if (dateCompare > 0 || | ||||
|                                     (dateCompare == 0 && isRedeemDateLater(redeemDate, latestIopRecord.getDate("shjh_shrq")))) { | ||||
|                                 latestIopRecord = object; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // 3. 寻找上月最后一次估值记录(相同日期取赎回日期最大的) | ||||
|                     if ((valYear == accrualYear && valMonth == accrualMonth - 1) || | ||||
|                             (accrualMonth == 0 && valYear == accrualYear - 1 && valMonth == 11)) { | ||||
|                         if (lastMonthRecord == null || valuationdate.after(lastMonthRecord.getDate("e_valuationdate"))) { | ||||
|                         if (lastMonthRecord == null) { | ||||
|                             lastMonthRecord = object; | ||||
|                         } else { | ||||
|                             int dateCompare = valuationDate.compareTo(lastMonthRecord.getDate("e_valuationdate")); | ||||
|                             if (dateCompare > 0 || | ||||
|                                     (dateCompare == 0 && isRedeemDateLater(redeemDate, lastMonthRecord.getDate("shjh_shrq")))) { | ||||
|                                 lastMonthRecord = object; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // 4. 寻找上一年最后一次估值记录 | ||||
|                     // 4. 寻找上一年最后一次估值记录(相同日期取赎回日期最大的) | ||||
|                     if (valYear == accrualYear - 1) { | ||||
|                         if (lastYearRecord == null || valuationdate.after(lastYearRecord.getDate("e_valuationdate"))) { | ||||
|                         if (lastYearRecord == null) { | ||||
|                             lastYearRecord = object; | ||||
|                         } else { | ||||
|                             int dateCompare = valuationDate.compareTo(lastYearRecord.getDate("e_valuationdate")); | ||||
|                             if (dateCompare > 0 || | ||||
|                                     (dateCompare == 0 && isRedeemDateLater(redeemDate, lastYearRecord.getDate("shjh_shrq")))) { | ||||
|                                 lastYearRecord = object; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // 5. 寻找本年第一个估值记录 | ||||
|                     // 5. 寻找本年第一个估值记录(相同日期取赎回日期最大的) | ||||
|                     if (valYear == accrualYear) { | ||||
|                         if (yearStartRecord == null || valuationdate.before(yearStartRecord.getDate("e_valuationdate"))) { | ||||
|                         if (yearStartRecord == null) { | ||||
|                             yearStartRecord = object; | ||||
|                         } else { | ||||
|                             int dateCompare = valuationDate.compareTo(yearStartRecord.getDate("e_valuationdate")); | ||||
|                             if (dateCompare < 0 || | ||||
|                                     (dateCompare == 0 && isRedeemDateLater(redeemDate, yearStartRecord.getDate("shjh_shrq")))) { | ||||
|                                 yearStartRecord = object; | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | @ -257,31 +317,55 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|                 } | ||||
| 
 | ||||
|                 // 计算本月收益 | ||||
|                 // 计提日期向上最近一次市值-上月最后一次的市值(表体若没有,置0) | ||||
|                 // 新增逻辑:计息日<计提日<=到期日所在月月底才计算本月收益和收益率 | ||||
|                 if (latestIopRecord != null) { | ||||
|                     BigDecimal currentMarketValue = latestIopRecord.getBigDecimal("e_iopv").multiply(buyCopies); | ||||
| 
 | ||||
|                     // 只有当上月记录存在时才计算本月收益 | ||||
|                     if (lastMonthRecord != null) { | ||||
|                         BigDecimal lastMonthMarketValue = lastMonthRecord.getBigDecimal("e_iopv") | ||||
|                                 .multiply(lastMonthRecord.getBigDecimal("e_surpcopies")); | ||||
|                         monthAmount = currentMarketValue.subtract(lastMonthMarketValue) | ||||
|                                 .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||
|                     // 新增:检查计息日<计提日<=到期日所在月月底 | ||||
|                     boolean isValidPeriod = true; | ||||
|                     if (expireDate != null) { | ||||
|                         // 获取到期日所在月的最后一天 | ||||
|                         Calendar expireCal = Calendar.getInstance(); | ||||
|                         expireCal.setTime(expireDate); | ||||
|                         expireCal.set(Calendar.DAY_OF_MONTH, expireCal.getActualMaximum(Calendar.DAY_OF_MONTH)); | ||||
|                         Date monthEndDate = expireCal.getTime(); | ||||
| 
 | ||||
|                         // 计算当月年化收益率 | ||||
|                         if (lastMonthMarketValue.compareTo(BigDecimal.ZERO) != 0) { | ||||
|                         // 验证计息日 < 计提日 <= 到期日所在月月底 | ||||
|                         isValidPeriod = (valueDate.before(accrualDate) || valueDate.equals(accrualDate)) | ||||
|                                 && (accrualDate.before(monthEndDate) || accrualDate.equals(monthEndDate)); | ||||
|                     } | ||||
| 
 | ||||
|                             monthAnnualizedRate = monthAmount.divide(buyAmount).multiply(new BigDecimal(1200)).setScale(2, RoundingMode.HALF_UP); | ||||
|                         } | ||||
|                     } else if (accrualYear == buyYear && accrualMonth == buyMonth) { | ||||
|                         // 特殊处理:计提月与购买月相同时,使用购买金额作为上月市值 | ||||
|                         BigDecimal lastMonthMarketValue = buyAmount; | ||||
|                         monthAmount = currentMarketValue.subtract(lastMonthMarketValue.multiply(new BigDecimal(1000))) | ||||
|                                 .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||
|                     if (isValidPeriod) { | ||||
|                         // 只有当上月记录存在时才计算本月收益 | ||||
|                         // ①计提日期若与购买日期不同月,取不到上月最后一次,单元格为0 | ||||
|                         if (lastMonthRecord != null) { | ||||
|                             BigDecimal lastMonthMarketValue = lastMonthRecord.getBigDecimal("e_iopv") | ||||
|                                     .multiply(lastMonthRecord.getBigDecimal("e_surpcopies")); | ||||
|                             monthAmount = currentMarketValue.subtract(lastMonthMarketValue) | ||||
|                                     .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||
| 
 | ||||
|                         if (lastMonthMarketValue.compareTo(BigDecimal.ZERO) != 0) { | ||||
| 
 | ||||
|                             monthAnnualizedRate = monthAmount.divide(buyAmount).multiply(new BigDecimal(1200)).setScale(2, RoundingMode.HALF_UP); | ||||
|                             // 计算当月年化收益率 | ||||
|                             // 本月收益/购买金额*100*12 | ||||
|                             if (lastMonthMarketValue.compareTo(BigDecimal.ZERO) != 0) { | ||||
|                                 monthAnnualizedRate = monthAmount | ||||
|                                         .divide(buyAmount, 6, RoundingMode.HALF_UP) | ||||
|                                         .multiply(new BigDecimal(1200)) | ||||
|                                         .setScale(2, RoundingMode.HALF_UP); | ||||
|                             } | ||||
|                         } else if (accrualYear == buyYear && accrualMonth == buyMonth) { | ||||
|                             // 特殊处理:计提月与购买月相同时,使用购买金额作为上月市值 | ||||
|                             // ②如果计提日期和购买日同月,"上月最后一次的市值行"取购买金额 | ||||
|                             monthAmount = currentMarketValue.subtract(buyAmount.multiply(new BigDecimal(1000))) | ||||
|                                     .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||
| 
 | ||||
|                             if (buyAmount.compareTo(BigDecimal.ZERO) != 0) { | ||||
|                                 //本月收益/购买金额*100*12 | ||||
|                                 monthAnnualizedRate = monthAmount | ||||
|                                         .divide(buyAmount, 6, RoundingMode.HALF_UP) | ||||
|                                         .multiply(new BigDecimal(1200)) | ||||
|                                         .setScale(2, RoundingMode.HALF_UP); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | @ -294,42 +378,33 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|                     if (lastYearRecord != null) { | ||||
|                         BigDecimal lastYearMarketValue = lastYearRecord.getBigDecimal("e_iopv") | ||||
|                                 .multiply(lastYearRecord.getBigDecimal("e_surpcopies")); | ||||
| 
 | ||||
|                         yearAmount = currentMarketValue.subtract(lastYearMarketValue) | ||||
|                                 .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||
| 
 | ||||
| //                        // 计算本年累计年化收益率 | ||||
| //                        if (yearStartRecord != null) { | ||||
| //                            yearStartAmount = yearStartRecord.getBigDecimal("e_iopv") | ||||
| //                                    .multiply(yearStartRecord.getBigDecimal("e_surpcopies")); | ||||
| //                        } | ||||
| 
 | ||||
|                         if (lastYearMarketValue.compareTo(BigDecimal.ZERO) != 0) { | ||||
|                             int monthCount = accrualMonth + 1; | ||||
|                             yearAnnualizedRate = yearAmount.multiply(new BigDecimal(1000)) | ||||
|                                     .divide(lastYearMarketValue, 6, RoundingMode.HALF_UP) | ||||
|                                     .divide(new BigDecimal(monthCount), 6, RoundingMode.HALF_UP) | ||||
|                                     .multiply(new BigDecimal(12)) | ||||
|                                     .multiply(new BigDecimal(100)) | ||||
|                         //本年累计年化收益率=(本年累计总收益额/金额)/(计提日期到-年初日期)*计息基准天数 | ||||
|                         if (buyAmount.compareTo(BigDecimal.ZERO) != 0 && BigDecimal.valueOf(daysFromJan1).compareTo(BigDecimal.ZERO) != 0 ) { | ||||
|                             yearAnnualizedRate = yearAmount | ||||
|                                     .divide(buyAmount, 6, RoundingMode.HALF_UP) | ||||
|                                     .divide(BigDecimal.valueOf(daysFromJan1), 6, RoundingMode.HALF_UP) | ||||
|                                     .multiply(basisDays) | ||||
|                                     .setScale(2, RoundingMode.HALF_UP); | ||||
|                         } | ||||
|                     } else if (accrualYear == buyYear) { | ||||
|                         // 特殊处理:计提年与购买年相同时,使用购买金额作为上年市值 | ||||
|                         BigDecimal lastYearMarketValue = buyAmount; | ||||
|                         // 特殊处理:计提年与购买年相同时:本年累计年化收益率=(本年累计总收益额/金额)/天数*计息基准天数 | ||||
|                         // 天数:(计提日期到-计息日) | ||||
| 
 | ||||
|                         if (lastYearMarketValue.compareTo(BigDecimal.ZERO) != 0) { | ||||
|                             yearAmount = currentMarketValue.subtract(lastYearMarketValue.multiply(new BigDecimal(1000))) | ||||
|                         if (buyAmount.compareTo(BigDecimal.ZERO) != 0 ) { | ||||
|                             yearAmount = currentMarketValue.subtract(buyAmount.multiply(new BigDecimal(1000))) | ||||
|                                     .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||
| 
 | ||||
|                             int monthCount = accrualMonth -buyMonth; | ||||
|                             if (monthCount==0){ | ||||
|                                 monthCount = 1; | ||||
|                             if (days.compareTo(BigDecimal.ZERO) !=0 ){ | ||||
|                                 yearAnnualizedRate = yearAmount | ||||
|                                         .divide(buyAmount, 6, RoundingMode.HALF_UP) | ||||
|                                         .divide(days, 6, RoundingMode.HALF_UP) | ||||
|                                         .multiply(basisDays) | ||||
|                                         .setScale(2, RoundingMode.HALF_UP); | ||||
|                             } | ||||
|                             yearAnnualizedRate = yearAmount | ||||
|                                     .divide(lastYearMarketValue, 6, RoundingMode.HALF_UP) | ||||
|                                     .divide(new BigDecimal(monthCount), 6, RoundingMode.HALF_UP) | ||||
|                                     .multiply(new BigDecimal(12)) | ||||
|                                     .multiply(new BigDecimal(100)) | ||||
|                                     .setScale(2, RoundingMode.HALF_UP); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | @ -347,18 +422,51 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 计算天数 = 计提日 - 计息日 | ||||
|      * 计算天数规则: | ||||
|      * 1. 计提日 <= 到期日:天数 = 计提日 - 计息日 | ||||
|      * 2. 计提日 > 到期日:天数 = 到期日 - 计息日 | ||||
|      * @param valueDate 计息日 | ||||
|      * @param expireDate 到期日 | ||||
|      * @param accrualDate 计提日 | ||||
|      * @param row 表格 | ||||
|      * @param row 表格行数据 | ||||
|      * @return 计算得到的天数 | ||||
|      */ | ||||
|     private void countDays(Date valueDate,Date accrualDate,DynamicObject row){ | ||||
|         if (valueDate != null) { | ||||
|             long days = (accrualDate.getTime() - valueDate.getTime()) / (1000 * 60 * 60 * 24); | ||||
|             row.set(DYNAMICS_FIELDS[2], new BigDecimal(days)); | ||||
|         } else { | ||||
|     private BigDecimal countDays(Date valueDate, Date expireDate, Date accrualDate, DynamicObject row) { | ||||
|         if (expireDate==null){ | ||||
|             expireDate=accrualDate; | ||||
|         } | ||||
|         BigDecimal days; | ||||
| 
 | ||||
|         // 检查必要参数是否为空 | ||||
|         if (valueDate == null || accrualDate == null) { | ||||
|             row.set(DYNAMICS_FIELDS[2], BigDecimal.ZERO); | ||||
|             return BigDecimal.ZERO; | ||||
|         } | ||||
| 
 | ||||
|         // 确定结束日期(比较计提日和到期日) | ||||
|         Date endDate = accrualDate; | ||||
|         if (accrualDate.after(expireDate) || expireDate==accrualDate) { | ||||
|             endDate = expireDate; | ||||
|         } | ||||
| 
 | ||||
|         // 计算天数差(毫秒转换为天) | ||||
|         long diffMillis = endDate.getTime() - valueDate.getTime(); | ||||
|         long diffDays = diffMillis / (1000 * 60 * 60 * 24); | ||||
| 
 | ||||
|         // 确保天数不为负 | ||||
|         diffDays = Math.max(diffDays, 0); | ||||
| 
 | ||||
|         days = new BigDecimal(diffDays); | ||||
|         // 验证计息日 <= 计提日 <= 到期日 | ||||
|         boolean isValidPeriod = !valueDate.after(accrualDate) && !accrualDate.after(expireDate); | ||||
|         if (isValidPeriod){ | ||||
|             row.set(DYNAMICS_FIELDS[2], days); | ||||
|         }else { | ||||
|             row.set(DYNAMICS_FIELDS[2], BigDecimal.ZERO); | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         return days; | ||||
|     } | ||||
| 
 | ||||
|     private String countProductTerm(Date valueDate, Date expireDate, Date accrualDate, DynamicObject row) { | ||||
|  | @ -419,6 +527,14 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|         return day; | ||||
|     } | ||||
| 
 | ||||
|     private BigDecimal computeBasisDays(String basis){ | ||||
|         BigDecimal basisDay= BigDecimal.valueOf(365); | ||||
|         if (basis.contains("360")){ | ||||
|             basisDay=BigDecimal.valueOf(360); | ||||
|         } | ||||
|         return basisDay; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 预计收益 = 产品期限 * 金额(千元) * 预计业绩比较基准 / 365 | ||||
|      * @param expectedRate 预计业绩比较基准(%) | ||||
|  | @ -426,11 +542,8 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|      * @param amount 投资金额 | ||||
|      * @param row 表格 | ||||
|      */ | ||||
|     private BigDecimal countProRevenue(BigDecimal expectedRate,String day,BigDecimal amount,DynamicObject row,String basis) { | ||||
|         BigDecimal basisDay= BigDecimal.valueOf(365); | ||||
|         if (basis.contains("360")){ | ||||
|             basisDay=BigDecimal.valueOf(360); | ||||
|         } | ||||
|     private BigDecimal countProRevenue(BigDecimal expectedRate,String day,BigDecimal amount,DynamicObject row,BigDecimal basisDay) { | ||||
| 
 | ||||
|         BigDecimal projectRevenue = BigDecimal.ZERO; | ||||
|         if (expectedRate != null) { | ||||
|             projectRevenue = new BigDecimal(day).multiply(amount.divide(new BigDecimal(1000), 10, RoundingMode.HALF_UP)) | ||||
|  | @ -450,15 +563,19 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|      * @param startBuyCopies 购买份额(初始份额) | ||||
|      * @return 计算后的收益金额(保留2位小数) | ||||
|      */ | ||||
|     private BigDecimal countRevenueAmt( | ||||
|     private BigDecimal countRevenueAmt(Date valueDate, Date expireDate, Date accrualDate, | ||||
|             BigDecimal buyCopies, | ||||
|             BigDecimal monthNetWorth, | ||||
|             BigDecimal netWorth, | ||||
|             DynamicObject row, | ||||
|             BigDecimal startBuyCopies | ||||
|     ) { | ||||
|         if (expireDate==null){ | ||||
|             expireDate=accrualDate; | ||||
|         } | ||||
|         BigDecimal revenue = BigDecimal.ZERO; | ||||
| 
 | ||||
| 
 | ||||
|         // 检查所有参数是否非空 | ||||
|         if (buyCopies != null && monthNetWorth != null && netWorth != null && startBuyCopies != null) { | ||||
|             // 计算:(持有份额 * 月末单位净值 - 购买份额 * 购买时单位净值) / 1000 | ||||
|  | @ -467,12 +584,26 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|                     .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||
| 
 | ||||
|             // 设置到表格行 | ||||
|             row.set(DYNAMICS_FIELDS[3], revenue); | ||||
|             boolean isValidPeriod = !valueDate.after(accrualDate) && !accrualDate.after(expireDate); | ||||
|             if (isValidPeriod){ | ||||
|                 row.set(DYNAMICS_FIELDS[3], revenue); | ||||
|             }else { | ||||
|                 row.set(DYNAMICS_FIELDS[3], BigDecimal.ZERO); | ||||
|                 return BigDecimal.ZERO; | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         return revenue; | ||||
|     } | ||||
| 
 | ||||
|     // 辅助方法:比较赎回日期 | ||||
|     private boolean isRedeemDateLater(Date newRedeemDate, Date existingRedeemDate) { | ||||
|         if (newRedeemDate == null) return false; | ||||
|         if (existingRedeemDate == null) return true; | ||||
|         return newRedeemDate.after(existingRedeemDate); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 本月收益计算(严格按生效期间计算) | ||||
|      * @param monthNetWorth 月末单位净值 | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ package shjh.jhzj7.fi.fi.plugin.report; | |||
| 
 | ||||
| import kd.bos.algo.DataSet; | ||||
| import kd.bos.dataentity.entity.DynamicObject; | ||||
| import kd.bos.dataentity.entity.DynamicObjectCollection; | ||||
| import kd.bos.entity.report.AbstractReportColumn; | ||||
| import kd.bos.entity.report.AbstractReportListDataPlugin; | ||||
| import kd.bos.entity.report.FilterItemInfo; | ||||
|  | @ -67,6 +68,16 @@ public class FinancialListReport extends AbstractReportListDataPlugin implements | |||
|                 null | ||||
|         ); | ||||
| 
 | ||||
|         // 3. 获取过滤日期并提取年份 | ||||
|         Date filterDate = param.getFilter().getDate("shjh_filterdate"); | ||||
|         SimpleDateFormat sdf = new SimpleDateFormat("yyyy"); | ||||
|         String filterYear = sdf.format(filterDate); | ||||
| 
 | ||||
|         // 4. 应用过滤条件 | ||||
|         mainDataSet = mainDataSet.filter( | ||||
|                 "shjh_expiredate IS NULL OR " +  // 保留到期日为空的记录 | ||||
|                         "year(shjh_expiredate) >= " + filterYear  // 计提日年份 <= 到期日年份 | ||||
|         ); | ||||
|         // 3. 查询理财收益预提数据 | ||||
| //        DataSet addDataSet = QueryServiceHelper.queryDataSet( | ||||
| //                this.getClass().getName() + "1", | ||||
|  | @ -86,23 +97,18 @@ public class FinancialListReport extends AbstractReportListDataPlugin implements | |||
|      */ | ||||
|     private List<QFilter> buildFilters(List<FilterItemInfo> filterItems) { | ||||
|         List<QFilter> filters = new ArrayList<>(); | ||||
| 
 | ||||
|         List<Long> bankNameIds =new ArrayList<>(); | ||||
|         List<Long> productTypeIds =new ArrayList<>(); | ||||
|         for (FilterItemInfo filterItem : filterItems) { | ||||
|             Object value = filterItem.getValue(); | ||||
|             Date date = filterItem.getDate(); | ||||
| 
 | ||||
|             switch (filterItem.getPropName()) { | ||||
|                 case FILTER_BANK_NAME:  // 银行筛选 | ||||
|                     if (value != null) { | ||||
|                         Long bankId = (Long) ((DynamicObject) value).getPkValue(); | ||||
|                         filters.add(new QFilter("finorginfo", QCP.equals, bankId)); | ||||
|                     } | ||||
|                     this.getMultipleFilter(filterItem, bankNameIds); | ||||
|                     break; | ||||
|                 case FILTER_PRODUCT_NAME:  // 产品筛选 | ||||
|                     if (value != null) { | ||||
|                         Long productId = (Long) ((DynamicObject) value).getPkValue(); | ||||
|                         filters.add(new QFilter("product", QCP.equals, productId)); | ||||
|                     } | ||||
|                     this.getMultipleFilter(filterItem, productTypeIds); | ||||
|                     break; | ||||
|                 case FILTER_BUY_DATE:  // 购买日筛选 | ||||
|                     if (date != null) { | ||||
|  | @ -120,6 +126,13 @@ public class FinancialListReport extends AbstractReportListDataPlugin implements | |||
|                     } | ||||
|                     break; | ||||
|             } | ||||
|             if (bankNameIds.size()!=0){ | ||||
|                 filters.add(new QFilter("finorginfo", QCP.in,bankNameIds)); | ||||
|             } | ||||
| 
 | ||||
|             if (bankNameIds.size()!=0){ | ||||
|                 filters.add(new QFilter("investvarieties", QCP.in,productTypeIds)); | ||||
|             } | ||||
|         } | ||||
|         return filters; | ||||
|     } | ||||
|  | @ -173,6 +186,22 @@ public class FinancialListReport extends AbstractReportListDataPlugin implements | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取报表多选基础资料过滤数据 | ||||
|      * @param filterItem | ||||
|      * @param bankNameIds | ||||
|      * @return | ||||
|      */ | ||||
|     private List<Long> getMultipleFilter(FilterItemInfo filterItem,List<Long> bankNameIds){ | ||||
|         DynamicObjectCollection value = (DynamicObjectCollection) filterItem.getValue(); | ||||
|         if (value!=null && value.size()!=0){ | ||||
|             for (DynamicObject dynamicObject : value) { | ||||
|                 Long pkValue = (Long) dynamicObject.getPkValue(); | ||||
|                 bankNameIds.add(pkValue); | ||||
|             } | ||||
|         } | ||||
|         return bankNameIds; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -77,7 +77,7 @@ public class ReportUtils { | |||
|             totalRow.set(targetField, totals[i]); | ||||
|         } | ||||
| 
 | ||||
|         rowData.add(totalRow); | ||||
|         rowData.add(0,totalRow); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -122,6 +122,50 @@ public class ReportUtils { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     /** | ||||
|      * 对往年过期数据处理(相对计提日期而言) | ||||
|      * 列表插件已有该过滤-该方法针对提前已结清修改了到期日的数据 | ||||
|      * @param rowData 数据集合 | ||||
|      * @param keyWord1 到期日 | ||||
|      * @param keyWord2 计提日 | ||||
|      */ | ||||
|     public static void removeRowData(DynamicObjectCollection rowData,String keyWord1,String keyWord2) { | ||||
| 
 | ||||
|         List<DynamicObject> rowsToRemove = new ArrayList<>(); | ||||
|         Calendar cal = Calendar.getInstance(); | ||||
| 
 | ||||
|         for (DynamicObject row : rowData) { | ||||
|             Date expireDate = row.getDate(keyWord1); // 到期日 | ||||
|             Date accrualDate = row.getDate(keyWord2); // 计提日 | ||||
| 
 | ||||
|             // 条件1:到期日为null | ||||
|             if (expireDate == null) { | ||||
|                 rowsToRemove.add(row); | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             // 条件2:计提日不为null且到期日所在年 < 计提日所在年 | ||||
|             if (accrualDate != null) { | ||||
|                 cal.setTime(expireDate); | ||||
|                 int expireYear = cal.get(Calendar.YEAR); | ||||
| 
 | ||||
|                 cal.setTime(accrualDate); | ||||
|                 int accrualYear = cal.get(Calendar.YEAR); | ||||
| 
 | ||||
|                 if (expireYear < accrualYear) { | ||||
|                     rowsToRemove.add(row); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // 移除重复的小计行 | ||||
|         if (!rowsToRemove.isEmpty()) { | ||||
|             rowData.removeAll(rowsToRemove); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     // 辅助方法:获取某个月的第一天 | ||||
|     public static Date getFirstDayOfMonth(Date date) { | ||||
|         Calendar cal = Calendar.getInstance(); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue