理财收益计提5.0
This commit is contained in:
		
							parent
							
								
									36dc7d9923
								
							
						
					
					
						commit
						48a8d64455
					
				|  | @ -84,16 +84,17 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|             BigDecimal buyAmount = amount.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);//购买金额(千元) |             BigDecimal buyAmount = amount.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);//购买金额(千元) | ||||||
|             row.set(REPORT_FIELDS[4],buyAmount); |             row.set(REPORT_FIELDS[4],buyAmount); | ||||||
| 
 | 
 | ||||||
|  |             BigDecimal netWorth = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[6]); // 购买时单位净值 | ||||||
|             Date buyDate = row.getDate(REPORT_FIELDS[7]); // 购买日 |             Date buyDate = row.getDate(REPORT_FIELDS[7]); // 购买日 | ||||||
|             Date valueDate = row.getDate(REPORT_FIELDS[8]); // 计息日 |             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]); // 预计业绩比较基准(%) |             BigDecimal expectedRate = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[10]); // 预计业绩比较基准(%) | ||||||
|             String basis = row.getString(REPORT_FIELDS[15]);//计息基准 |             String basis = row.getString(REPORT_FIELDS[15]);//计息基准 | ||||||
|  |             BigDecimal startBuyCopies = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[16]); // 购买份额 | ||||||
| 
 | 
 | ||||||
|             // 2. 设置计提日 |             // 2. 设置计提日 | ||||||
|             row.set(DYNAMICS_FIELDS[1], accrualDate); |             row.set(DYNAMICS_FIELDS[1], accrualDate); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|             // 3. 计算产品期限(总天数)=到期日-计息日 |             // 3. 计算产品期限(总天数)=到期日-计息日 | ||||||
|             String term = countProductTerm(valueDate, expireDate, accrualDate, row); |             String term = countProductTerm(valueDate, expireDate, accrualDate, row); | ||||||
| 
 | 
 | ||||||
|  | @ -111,7 +112,6 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|             BigDecimal proRevenue = countProRevenue(expectedRate, term, amount, row,basisDays); |             BigDecimal proRevenue = countProRevenue(expectedRate, term, amount, row,basisDays); | ||||||
|             sumProjectedEarnings=sumProjectedEarnings.add(proRevenue); |             sumProjectedEarnings=sumProjectedEarnings.add(proRevenue); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|             // 理财申购单估值分录相关数据处理 |             // 理财申购单估值分录相关数据处理 | ||||||
|             // 7. 持有份额 = 计提日期向上最近持有份额 |             // 7. 持有份额 = 计提日期向上最近持有份额 | ||||||
|             // 8. 月末单位净值 = 计提日期向上最近一次的净值 |             // 8. 月末单位净值 = 计提日期向上最近一次的净值 | ||||||
|  | @ -119,18 +119,16 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|             // 10. 本月收益(千元)、当月年化收益率% |             // 10. 本月收益(千元)、当月年化收益率% | ||||||
|             // 11. 本年累计收益(千元)、本年累计年化收益率 |             // 11. 本年累计收益(千元)、本年累计年化收益率 | ||||||
|             Long id = row.getLong(REPORT_FIELDS[13]); |             Long id = row.getLong(REPORT_FIELDS[13]); | ||||||
|             BigDecimal redAmount = valuationEntry(accrualDate, buyDate, expireDate2, valueDate, buyAmount, days, basisDays, id, row); |             BigDecimal allRedProductAmount = valuationEntry(accrualDate, buyDate, expireDate2, valueDate, buyAmount, days, basisDays, id, row,netWorth,startBuyCopies); | ||||||
| 
 | 
 | ||||||
|             BigDecimal buyCopies = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[5]); // 持有份额 |             BigDecimal buyCopies = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[5]); // 持有份额 | ||||||
|             BigDecimal netWorth = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[6]); // 购买时单位净值 |  | ||||||
|             BigDecimal monthNetWorth = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[11]); // 月末单位净值 |             BigDecimal monthNetWorth = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[11]); // 月末单位净值 | ||||||
|             BigDecimal startBuyCopies = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[16]); // 购买份额 |  | ||||||
| 
 | 
 | ||||||
| 
 |             // 12. 收益计提 =  (持有份额 *月末单位净值 - 购买份额*购买时单位净值*[(1-赎回比)*N])/ 1000 | ||||||
|             // 12. 收益计提 =  (持有份额 *月末单位净值 - 购买份额*购买时单位净值) / 1000 |             BigDecimal revenueAmt = countRevenueAmt(valueDate,expireDate2, accrualDate,buyCopies, monthNetWorth, netWorth, row,startBuyCopies,allRedProductAmount); | ||||||
|             BigDecimal revenueAmt = countRevenueAmt(valueDate,expireDate2, accrualDate,buyCopies, monthNetWorth, netWorth, row,startBuyCopies,redAmount); |  | ||||||
|             sumProvisionEarnings=sumProvisionEarnings.add(revenueAmt); |             sumProvisionEarnings=sumProvisionEarnings.add(revenueAmt); | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|             // 本月收益计算累计 |             // 本月收益计算累计 | ||||||
|             BigDecimal monthRevenue = ReportUtils.getBigDecimalValue(row, DYNAMICS_FIELDS[4]); |             BigDecimal monthRevenue = ReportUtils.getBigDecimalValue(row, DYNAMICS_FIELDS[4]); | ||||||
|             sumMonthEarnings=sumMonthEarnings.add(monthRevenue); |             sumMonthEarnings=sumMonthEarnings.add(monthRevenue); | ||||||
|  | @ -191,7 +189,7 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|      * @param id 表单id |      * @param id 表单id | ||||||
|      * @return allRedAmount 计提日期之前赎回金额之和 |      * @return allRedAmount 计提日期之前赎回金额之和 | ||||||
|      */ |      */ | ||||||
|     private BigDecimal valuationEntry(Date accrualDate, Date buyDate,Date expireDate,Date valueDate, BigDecimal buyAmount,BigDecimal days,BigDecimal basisDays, Long id, DynamicObject row) { |     private BigDecimal valuationEntry(Date accrualDate, Date buyDate,Date expireDate,Date valueDate, BigDecimal buyAmount,BigDecimal days,BigDecimal basisDays, Long id, DynamicObject row,BigDecimal netWorth,BigDecimal startBuyCopies) { | ||||||
|         // 初始化所有变量 |         // 初始化所有变量 | ||||||
|         BigDecimal buyCopies = BigDecimal.ZERO; |         BigDecimal buyCopies = BigDecimal.ZERO; | ||||||
|         BigDecimal monthIop = BigDecimal.ZERO; |         BigDecimal monthIop = BigDecimal.ZERO; | ||||||
|  | @ -200,8 +198,11 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|         BigDecimal monthAnnualizedRate = BigDecimal.ZERO; |         BigDecimal monthAnnualizedRate = BigDecimal.ZERO; | ||||||
|         BigDecimal yearAmount = BigDecimal.ZERO; |         BigDecimal yearAmount = BigDecimal.ZERO; | ||||||
|         BigDecimal yearAnnualizedRate = BigDecimal.ZERO; |         BigDecimal yearAnnualizedRate = BigDecimal.ZERO; | ||||||
|         //计提日期之前赎回金额之和(用于收益计提计算) |         //计提日期之前赎回金额之和(用于实际收益计算) | ||||||
|         BigDecimal allRedAmount = BigDecimal.ZERO; |         BigDecimal allRedAmount = BigDecimal.ZERO; | ||||||
|  |         //计提日期之前赎回金额之和(用于收益计提计算) | ||||||
|  |         BigDecimal allRedProductAmount = BigDecimal.ZERO; | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|         DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(id, "cim_finsubscribe"); |         DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(id, "cim_finsubscribe"); | ||||||
|  | @ -254,7 +255,6 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|                             closestRecord = object; |                             closestRecord = object; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     allRedAmount=this.getRedAmount(dynamicObjectCollection,closestRecord.getDate("e_valuationdate")); |  | ||||||
| 
 | 
 | ||||||
|                     // 2. 寻找本月最后一次估值记录(相同日期取赎回日期最大的) |                     // 2. 寻找本月最后一次估值记录(相同日期取赎回日期最大的) | ||||||
|                     if (!valuationDate.after(accrualDate)) { |                     if (!valuationDate.after(accrualDate)) { | ||||||
|  | @ -310,9 +310,16 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|                 // 设置持有份额 |                 // 设置持有份额 | ||||||
|                 if (closestRecord != null) { |                 if (closestRecord != null) { | ||||||
|                     buyCopies = closestRecord.getBigDecimal("e_surpcopies"); |                     buyCopies = closestRecord.getBigDecimal("e_surpcopies"); | ||||||
|  | 
 | ||||||
|  |                     //计提日最近估值记录获取——(赎回金额+实际收益)* 所有赎回单 | ||||||
|  |                     allRedAmount=this.getRedAmount(dynamicObjectCollection,closestRecord.getDate("e_valuationdate")); | ||||||
|  | 
 | ||||||
|  |                     //计提日最近估值记录获取——(1-赎回份额/赎回日剩余份额)* 所有赎回单 | ||||||
|  |                     allRedProductAmount=this.getRedProductAmount(dynamicObjectCollection,closestRecord.getDate("e_valuationdate")); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 // 设置月末单位净值 |                 // 设置月末单位净值 | ||||||
|  | @ -425,6 +432,8 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         //计算实际收益 | ||||||
|  |         countActRevenueAmt(buyCopies, monthIop, netWorth, row,startBuyCopies,allRedAmount); | ||||||
|         // 设置结果 |         // 设置结果 | ||||||
|         row.set(REPORT_FIELDS[5], buyCopies); |         row.set(REPORT_FIELDS[5], buyCopies); | ||||||
|         row.set(REPORT_FIELDS[11], monthIop); |         row.set(REPORT_FIELDS[11], monthIop); | ||||||
|  | @ -434,9 +443,11 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|         row.set(DYNAMICS_FIELDS[6], yearAmount); |         row.set(DYNAMICS_FIELDS[6], yearAmount); | ||||||
|         row.set(DYNAMICS_FIELDS[7], yearAnnualizedRate); |         row.set(DYNAMICS_FIELDS[7], yearAnnualizedRate); | ||||||
| 
 | 
 | ||||||
|         return allRedAmount; |         return allRedProductAmount; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * 获取填入日期之前的赎回单中的赎回金额之和 |      * 获取填入日期之前的赎回单中的赎回金额之和 | ||||||
|      * @param entry 估值分录 |      * @param entry 估值分录 | ||||||
|  | @ -491,6 +502,81 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|         return sum; |         return sum; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * 计提日最近估值记录获取——(1-赎回份额/赎回日剩余份额)* 所有赎回单 | ||||||
|  |      * @param entry 输入数据集合 | ||||||
|  |      * @param date 目标日期 | ||||||
|  |      * @return 所有符合条件的赎回单的(1-赎回份额/剩余份额)的乘积 | ||||||
|  |      */ | ||||||
|  |     private BigDecimal getRedProductAmount(DynamicObjectCollection entry, Date date) { | ||||||
|  |         // 1. 按估值日期和赎回日期排序 | ||||||
|  |         DynamicObjectCollection sortedEntries = new DynamicObjectCollection(); | ||||||
|  |         sortedEntries.addAll(entry); | ||||||
|  | 
 | ||||||
|  |         sortedEntries.sort((o1, o2) -> { | ||||||
|  |             // 优先按估值日期排序(从小到大) | ||||||
|  |             Date valDate1 = o1.getDate("e_valuationdate"); | ||||||
|  |             Date valDate2 = o2.getDate("e_valuationdate"); | ||||||
|  |             int compareValDate = valDate1.compareTo(valDate2); | ||||||
|  |             if (compareValDate != 0) { | ||||||
|  |                 return compareValDate; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             // 估值日期相同时,按赎回日期排序 | ||||||
|  |             Date redDate1 = o1.getDate("shjh_shrq"); | ||||||
|  |             Date redDate2 = o2.getDate("shjh_shrq"); | ||||||
|  |             if (redDate1 == null && redDate2 == null) return 0; | ||||||
|  |             if (redDate1 == null) return -1;  // null视为较小值 | ||||||
|  |             if (redDate2 == null) return 1; | ||||||
|  |             return redDate1.compareTo(redDate2); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         // 2. 累乘符合条件的差额,初始值设为1 | ||||||
|  |         BigDecimal product = BigDecimal.ONE; | ||||||
|  | 
 | ||||||
|  |         for (DynamicObject item : sortedEntries) { | ||||||
|  |             try { | ||||||
|  |                 // 检查是否为赎回单(跳过非赎回条目) | ||||||
|  |                 DynamicObject shdh = item.getDynamicObject("shjh_shdh"); | ||||||
|  |                 if (shdh == null) { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // 检查估值日期是否 ≤ 目标日期 | ||||||
|  |                 Date valDate = item.getDate("e_valuationdate"); | ||||||
|  |                 if (valDate == null || valDate.compareTo(date) > 0) { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 Object pkValue = shdh.getPkValue(); | ||||||
|  |                 DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(pkValue, "cim_redeem"); | ||||||
|  | 
 | ||||||
|  |                 // 安全获取数值字段 | ||||||
|  |                 BigDecimal copies = dynamicObject.getBigDecimal("copies"); // 赎回份额 | ||||||
|  |                 BigDecimal remainderCopies = dynamicObject.getBigDecimal("shjh_shrsyfe"); // 赎回日剩余份额 | ||||||
|  | 
 | ||||||
|  |                 if (copies == null || remainderCopies == null || remainderCopies.compareTo(BigDecimal.ZERO) == 0) { | ||||||
|  |                     continue; // 跳过无效数据 | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 // 计算 (1 - 赎回份额/剩余日份额) | ||||||
|  |                 BigDecimal ratio = copies.divide(remainderCopies, 10, RoundingMode.HALF_UP); | ||||||
|  |                 BigDecimal difference = BigDecimal.ONE.subtract(ratio); | ||||||
|  | 
 | ||||||
|  |                 // 累乘 | ||||||
|  |                 product = product.multiply(difference).setScale(10, RoundingMode.HALF_UP); | ||||||
|  | 
 | ||||||
|  |             } catch (Exception e) { | ||||||
|  |                 // 记录错误并跳过当前条目 | ||||||
|  |                 logger.error("处理赎回单数据出错: " + e.getMessage(), e); | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return product; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /** |     /** | ||||||
|      * 计算天数规则: |      * 计算天数规则: | ||||||
|      * 1. 计提日 <= 到期日:天数 = 计提日 - 计息日 |      * 1. 计提日 <= 到期日:天数 = 计提日 - 计息日 | ||||||
|  | @ -543,18 +629,18 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|         String day = "0"; // 默认值设为0 |         String day = "0"; // 默认值设为0 | ||||||
|         Date endDate = (expireDate != null) ? expireDate : accrualDate; |         Date endDate = (expireDate != null) ? expireDate : accrualDate; | ||||||
| 
 | 
 | ||||||
|         BigDecimal actualEarnings = BigDecimal.ZERO; | //        BigDecimal actualEarnings = BigDecimal.ZERO; | ||||||
|         Long id = row.getLong(REPORT_FIELDS[13]); // id |         Long id = row.getLong(REPORT_FIELDS[13]); // id | ||||||
|         DynamicObject[] load = BusinessDataServiceHelper.load("cim_redeem", "id,redeemdate,lastmodifytime,realrevenue", |         DynamicObject[] load = BusinessDataServiceHelper.load("cim_redeem", "id,redeemdate,lastmodifytime,realrevenue", | ||||||
|                 (new QFilter("sourcebillid", QCP.equals, id)).toArray()); |                 (new QFilter("sourcebillid", QCP.equals, id)).toArray()); | ||||||
| 
 | 
 | ||||||
|         // 计算实际收益 |         // 计算实际收益 | ||||||
|         if (load != null && load.length != 0) { | //        if (load != null && load.length != 0) { | ||||||
|             for (DynamicObject dynamicObject : load) { | //            for (DynamicObject dynamicObject : load) { | ||||||
|                 BigDecimal realrevenue = dynamicObject.getBigDecimal("realrevenue"); | //                BigDecimal realrevenue = dynamicObject.getBigDecimal("realrevenue"); | ||||||
|                 actualEarnings = actualEarnings.add(realrevenue); | //                actualEarnings = actualEarnings.add(realrevenue); | ||||||
|             } | //            } | ||||||
|         } | //        } | ||||||
| 
 | 
 | ||||||
|         if (valueDate != null) { |         if (valueDate != null) { | ||||||
|             String status = row.getString(REPORT_FIELDS[14]); // 状态 |             String status = row.getString(REPORT_FIELDS[14]); // 状态 | ||||||
|  | @ -592,7 +678,7 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|         row.set(DYNAMICS_FIELDS[10], isExpired); // 是否到期 |         row.set(DYNAMICS_FIELDS[10], isExpired); // 是否到期 | ||||||
| 
 | 
 | ||||||
|         row.set(REPORT_FIELDS[3], day); // 产品期限天数 |         row.set(REPORT_FIELDS[3], day); // 产品期限天数 | ||||||
|         row.set(DYNAMICS_FIELDS[8], actualEarnings); // 实际收益 |         //row.set(DYNAMICS_FIELDS[8], actualEarnings); // 实际收益 | ||||||
| 
 | 
 | ||||||
|         return day; |         return day; | ||||||
|     } |     } | ||||||
|  | @ -639,7 +725,7 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|             BigDecimal netWorth, |             BigDecimal netWorth, | ||||||
|             DynamicObject row, |             DynamicObject row, | ||||||
|             BigDecimal startBuyCopies, |             BigDecimal startBuyCopies, | ||||||
|             BigDecimal redAmount |             BigDecimal allRedProductAmount | ||||||
|     ) { |     ) { | ||||||
|         if (expireDate==null){ |         if (expireDate==null){ | ||||||
|             expireDate=accrualDate; |             expireDate=accrualDate; | ||||||
|  | @ -649,10 +735,9 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
| 
 | 
 | ||||||
|         // 检查所有参数是否非空 |         // 检查所有参数是否非空 | ||||||
|         if (buyCopies != null && monthNetWorth != null && netWorth != null && startBuyCopies != null) { |         if (buyCopies != null && monthNetWorth != null && netWorth != null && startBuyCopies != null) { | ||||||
|             // 计算:(持有份额 * 月末单位净值 - 购买份额 * 购买时单位净值) / 1000 |             // 计算:(持有份额 * 月末单位净值+(所有赎回单金额+实际收益) - 购买份额 * 购买时单位净值) / 1000 | ||||||
|             revenue = buyCopies.multiply(monthNetWorth) |             revenue = buyCopies.multiply(monthNetWorth) | ||||||
|                     .add(redAmount) |                     .subtract(startBuyCopies.multiply(netWorth).multiply(allRedProductAmount)) | ||||||
|                     .subtract(startBuyCopies.multiply(netWorth)) |  | ||||||
|                     .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); |                     .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||||
| 
 | 
 | ||||||
|             // 设置到表格行 |             // 设置到表格行 | ||||||
|  | @ -669,6 +754,38 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|         return revenue; |         return revenue; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * 实际收益 = (持有份额 * 月末单位净值+(赎回单赎回金额、实际收益之和) - 购买份额 * 购买时单位净值) / 1000 | ||||||
|  |      * @param buyCopies 持有份额(当前份额) | ||||||
|  |      * @param monthNetWorth 月末单位净值(当前净值) | ||||||
|  |      * @param netWorth 购买时单位净值(初始净值) | ||||||
|  |      * @param row 表格行数据 | ||||||
|  |      * @param startBuyCopies 购买份额(初始份额) | ||||||
|  |      * @return 计算后的收益金额(保留2位小数) | ||||||
|  |      */ | ||||||
|  |     private void countActRevenueAmt( | ||||||
|  |                                        BigDecimal buyCopies, | ||||||
|  |                                        BigDecimal monthNetWorth, | ||||||
|  |                                        BigDecimal netWorth, | ||||||
|  |                                        DynamicObject row, | ||||||
|  |                                        BigDecimal startBuyCopies, | ||||||
|  |                                        BigDecimal redAmount | ||||||
|  |     ) { | ||||||
|  | 
 | ||||||
|  |         BigDecimal revenue = BigDecimal.ZERO; | ||||||
|  | 
 | ||||||
|  |         // 检查所有参数是否非空 | ||||||
|  |         if (buyCopies != null && monthNetWorth != null && netWorth != null && startBuyCopies != null) { | ||||||
|  |             // 计算:(持有份额 * 月末单位净值+(所有赎回单金额+实际收益) - 购买份额 * 购买时单位净值) / 1000 | ||||||
|  |             revenue = buyCopies.multiply(monthNetWorth) | ||||||
|  |                     .add(redAmount) | ||||||
|  |                     .subtract(startBuyCopies.multiply(netWorth)) | ||||||
|  |                     .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||||
|  |             row.set(DYNAMICS_FIELDS[8], revenue); // 实际收益 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     // 辅助方法:比较赎回日期 |     // 辅助方法:比较赎回日期 | ||||||
|     private boolean isRedeemDateLater(Date newRedeemDate, Date existingRedeemDate) { |     private boolean isRedeemDateLater(Date newRedeemDate, Date existingRedeemDate) { | ||||||
|         if (newRedeemDate == null) return false; |         if (newRedeemDate == null) return false; | ||||||
|  | @ -676,140 +793,4 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | ||||||
|         return newRedeemDate.after(existingRedeemDate); |         return newRedeemDate.after(existingRedeemDate); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |  | ||||||
|      * 本月收益计算(严格按生效期间计算) |  | ||||||
|      * @param monthNetWorth 月末单位净值 |  | ||||||
|      * @param netWorth 单位净值 |  | ||||||
|      * @param buyCopies 持有份额 |  | ||||||
|      * @param valueDate 计息日 |  | ||||||
|      * @param accrualDate 计提日 |  | ||||||
|      * @param expireDate 到期日 |  | ||||||
|      * @param row 表格 |  | ||||||
|      * @return 本月收益金额 |  | ||||||
|      */ |  | ||||||
|     private BigDecimal countMonthRevenue(BigDecimal monthNetWorth,BigDecimal netWorth,BigDecimal buyCopies,Date valueDate,Date accrualDate,Date expireDate,DynamicObject row){ |  | ||||||
|         BigDecimal monthRevenue = BigDecimal.ZERO; |  | ||||||
|         if (monthNetWorth != null && netWorth != null && buyCopies != null && valueDate != null) { |  | ||||||
| 
 |  | ||||||
|             // 关键判断:计提日必须在计息日之后(产品已生效) |  | ||||||
|             if (!accrualDate.before(valueDate)) { |  | ||||||
| 
 |  | ||||||
|                 // 获取当月第一天(月初) |  | ||||||
|                 Date monthFirstDay = ReportUtils.getFirstDayOfMonth(accrualDate); |  | ||||||
| 
 |  | ||||||
|                 // 情况1:产品已过期 |  | ||||||
|                 if (expireDate != null && expireDate.before(accrualDate)) { |  | ||||||
|                     // 仅在过期当月计算 |  | ||||||
|                     if (ReportUtils.isSameMonth(expireDate, accrualDate)) { |  | ||||||
|                         Date periodStart = valueDate.after(monthFirstDay) ? valueDate : monthFirstDay; |  | ||||||
|                         long effectiveDays = ReportUtils.getDaysBetween(periodStart, expireDate); |  | ||||||
|                         BigDecimal totalRevenue = buyCopies.multiply(monthNetWorth.subtract(netWorth)); |  | ||||||
|                         monthRevenue = ReportUtils.calculateProportionalRevenue( |  | ||||||
|                                 totalRevenue, |  | ||||||
|                                 ReportUtils.getDaysBetween(valueDate, expireDate), |  | ||||||
|                                 effectiveDays |  | ||||||
|                         ); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 // 情况2:产品未过期 |  | ||||||
|                 else { |  | ||||||
|                     Date periodStart = valueDate.after(monthFirstDay) ? valueDate : monthFirstDay; |  | ||||||
|                     long effectiveDays = ReportUtils.getDaysBetween(periodStart, accrualDate); |  | ||||||
|                     BigDecimal totalRevenue = buyCopies.multiply(monthNetWorth.subtract(netWorth)); |  | ||||||
|                     monthRevenue = ReportUtils.calculateProportionalRevenue( |  | ||||||
|                             totalRevenue, |  | ||||||
|                             ReportUtils.getDaysBetween(valueDate, expireDate != null ? expireDate : accrualDate), |  | ||||||
|                             effectiveDays |  | ||||||
|                     ); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             // 计提日在计息日之前(产品未生效)则monthRevenue保持为0 |  | ||||||
|         } |  | ||||||
|         row.set(DYNAMICS_FIELDS[4], monthRevenue.setScale(2, RoundingMode.HALF_UP)); |  | ||||||
|         return monthRevenue; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 当月收益率 = 本月收益 / 金额(千元) * 100 * 12 |  | ||||||
|      * @param amount 投资金额 |  | ||||||
|      * @param monthRevenue 本月收益 |  | ||||||
|      * @param row 表格 |  | ||||||
|      */ |  | ||||||
|     private void countMonthRate(BigDecimal amount,BigDecimal monthRevenue,DynamicObject row){ |  | ||||||
|         if (amount.compareTo(BigDecimal.ZERO) != 0) { |  | ||||||
|             BigDecimal monthRate = monthRevenue |  | ||||||
|                     .divide(amount, 10, RoundingMode.HALF_UP)  // 先计算 (月收入/金额) |  | ||||||
|                     .multiply(new BigDecimal(1200))             // 再 ×1200(假设业务需要) |  | ||||||
|                     .setScale(2, RoundingMode.HALF_UP);        // 最终保留2位小数 |  | ||||||
| 
 |  | ||||||
|             row.set(DYNAMICS_FIELDS[5], monthRate); |  | ||||||
|         } else { |  | ||||||
|             row.set(DYNAMICS_FIELDS[5], BigDecimal.ZERO); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * 本年累计收益 = 当年各月收益之和(按实际持有天数比例计算) |  | ||||||
|      * @param monthNetWorth 月末单位净值 |  | ||||||
|      * @param netWorth 单位净值 |  | ||||||
|      * @param buyCopies 持有份额 |  | ||||||
|      * @param valueDate 计息日 |  | ||||||
|      * @param accrualDate 计提日 |  | ||||||
|      * @param expireDate 到期日 |  | ||||||
|      * @param row 表格 |  | ||||||
|      */ |  | ||||||
|     private BigDecimal countYearRevenue(BigDecimal monthNetWorth,BigDecimal netWorth,BigDecimal buyCopies,Date valueDate,Date accrualDate,Date expireDate,DynamicObject row){ |  | ||||||
|         BigDecimal yearRevenue = BigDecimal.ZERO; |  | ||||||
|         if (monthNetWorth != null && netWorth != null && buyCopies != null && valueDate != null) { |  | ||||||
| 
 |  | ||||||
|             // 获取计提日所在年份的起止时间 |  | ||||||
|             Calendar cal = Calendar.getInstance(); |  | ||||||
|             cal.setTime(accrualDate); |  | ||||||
|             cal.set(Calendar.MONTH, Calendar.JANUARY); |  | ||||||
|             cal.set(Calendar.DAY_OF_MONTH, 1); |  | ||||||
|             cal.set(Calendar.HOUR_OF_DAY, 0); |  | ||||||
|             cal.set(Calendar.MINUTE, 0); |  | ||||||
|             cal.set(Calendar.SECOND, 0); |  | ||||||
|             cal.set(Calendar.MILLISECOND, 0); |  | ||||||
|             Date yearStart = cal.getTime(); |  | ||||||
| 
 |  | ||||||
|             cal.set(Calendar.MONTH, Calendar.DECEMBER); |  | ||||||
|             cal.set(Calendar.DAY_OF_MONTH, 31); |  | ||||||
|             Date yearEnd = cal.getTime(); |  | ||||||
| 
 |  | ||||||
|             // 核心判断:产品在当年有存续期(满足任意一条即可) |  | ||||||
|             // 1. 计息日 <= 年末 且 到期日 >= 年初(跨年产品) |  | ||||||
|             // 2. 到期日为null且计息日 <= 年末(未到期产品) |  | ||||||
|             boolean isEffectiveThisYear = |  | ||||||
|                     (valueDate.before(yearEnd) || ReportUtils.isSameYear(valueDate, yearStart)) && |  | ||||||
|                             (expireDate == null || expireDate.after(yearStart)) || |  | ||||||
|                             (expireDate == null && (valueDate.before(yearEnd) || ReportUtils.isSameYear(valueDate, yearStart))); |  | ||||||
| 
 |  | ||||||
|             if (isEffectiveThisYear) { |  | ||||||
|                 // 计算实际生效时间段 |  | ||||||
|                 Date effectiveStart = valueDate.after(yearStart) ? valueDate : yearStart; |  | ||||||
|                 Date effectiveEnd = (expireDate == null || expireDate.after(yearEnd)) ? yearEnd : expireDate; |  | ||||||
| 
 |  | ||||||
|                 // 计算本年有效天数 |  | ||||||
|                 long effectiveDays = ReportUtils.getDaysBetween(effectiveStart, effectiveEnd); |  | ||||||
| 
 |  | ||||||
|                 // 计算总存续天数 |  | ||||||
|                 long totalDays = ReportUtils.getDaysBetween(valueDate, |  | ||||||
|                         expireDate != null ? expireDate : accrualDate); |  | ||||||
| 
 |  | ||||||
|                 // 计算总收益 |  | ||||||
|                 BigDecimal totalRevenue = buyCopies.multiply(monthNetWorth.subtract(netWorth)); |  | ||||||
| 
 |  | ||||||
|                 // 按比例计算本年收益 |  | ||||||
|                 yearRevenue = ReportUtils.calculateProportionalRevenue( |  | ||||||
|                         totalRevenue, |  | ||||||
|                         totalDays, |  | ||||||
|                         effectiveDays |  | ||||||
|                 ); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         row.set(DYNAMICS_FIELDS[6], yearRevenue.setScale(2, RoundingMode.HALF_UP)); |  | ||||||
|         return yearRevenue; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | @ -59,7 +59,7 @@ public class FinancialListReport extends AbstractReportListDataPlugin implements | ||||||
|         // 2. 查询理财申购单数据 |         // 2. 查询理财申购单数据 | ||||||
|         StringBuilder selectFields = new StringBuilder(); |         StringBuilder selectFields = new StringBuilder(); | ||||||
|         assembleSQL(selectFields); |         assembleSQL(selectFields); | ||||||
|         selectFields.append(",").append("billno"); |         selectFields.append(",").append("billno,finorginfo"); | ||||||
|         DataSet mainDataSet = QueryServiceHelper.queryDataSet( |         DataSet mainDataSet = QueryServiceHelper.queryDataSet( | ||||||
|                 this.getClass().getName(), |                 this.getClass().getName(), | ||||||
|                 "cim_finsubscribe", |                 "cim_finsubscribe", | ||||||
|  | @ -136,7 +136,7 @@ public class FinancialListReport extends AbstractReportListDataPlugin implements | ||||||
|                 filters.add(new QFilter("finorginfo", QCP.in,bankNameIds)); |                 filters.add(new QFilter("finorginfo", QCP.in,bankNameIds)); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (bankNameIds.size()!=0){ |             if (productTypeIds.size()!=0){ | ||||||
|                 filters.add(new QFilter("investvarieties", QCP.in,productTypeIds)); |                 filters.add(new QFilter("investvarieties", QCP.in,productTypeIds)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue