理财报表优化2.0
This commit is contained in:
		
							parent
							
								
									fb167ab6a6
								
							
						
					
					
						commit
						1d09f07205
					
				|  | @ -6,8 +6,11 @@ import kd.bos.entity.report.ReportColumn; | |||
| import kd.bos.entity.report.ReportQueryParam; | ||||
| import kd.bos.logging.Log; | ||||
| import kd.bos.logging.LogFactory; | ||||
| import kd.bos.orm.query.QCP; | ||||
| import kd.bos.orm.query.QFilter; | ||||
| import kd.bos.report.ReportList; | ||||
| import kd.bos.report.plugin.AbstractReportFormPlugin; | ||||
| import kd.bos.servicehelper.BusinessDataServiceHelper; | ||||
| import kd.sdk.plugin.Plugin; | ||||
| import shjh.jhzj7.fi.fi.plugin.report.util.ReportUtils; | ||||
| 
 | ||||
|  | @ -26,14 +29,16 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|     private static final String FILTER_DATE = "shjh_filterdate"; | ||||
| 
 | ||||
|     private static final String[] REPORT_FIELDS = { | ||||
|             "shjh_bankname", "shjh_productname", "shjh_producttype", "shjh_productterm", | ||||
|             "shjh_amount", "shjh_buycopies", "shjh_iopv", "shjh_buydate", "shjh_valuedate", | ||||
|             "shjh_expiredate", "shjh_planrevenue", "shjh_monthiopv", "shjh_monthiopvdate" | ||||
|             "shjh_bankname", "shjh_productname", "shjh_producttype", "shjh_productterm", "shjh_amount", | ||||
|             "shjh_buycopies", "shjh_iopv", "shjh_buydate", "shjh_valuedate", "shjh_expiredate", | ||||
|             "shjh_planrevenue", "shjh_monthiopv", "shjh_monthiopvdate", "shjh_id","shjh_status", | ||||
|             "shjh_basis","shjh_startbuycopies" | ||||
|     }; | ||||
| 
 | ||||
|     private static final String[] DYNAMICS_FIELDS = { | ||||
|             "shjh_projectrevenueamt","shjh_date","shjh_days","shjh_revenueamt", | ||||
|             "shjh_monthrevenueamt","shjh_monthrate","shjh_yearrevenueamt" | ||||
|             "shjh_monthrevenueamt","shjh_monthrate","shjh_yearrevenueamt", | ||||
|             "shjh_yearrate","shjh_actualearnings","shjh_actualrate","shjh_expire" | ||||
|     }; | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -45,8 +50,12 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[2], "天数", ReportColumn.TYPE_BIGINT })); | ||||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[3], "收益计提(千元)", ReportColumn.TYPE_DECIMAL , String.valueOf(2)})); | ||||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[4], "本月收益(千元)", ReportColumn.TYPE_DECIMAL , String.valueOf(2)})); | ||||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[5], "当月收益率(%)", ReportColumn.TYPE_DECIMAL , String.valueOf(2)})); | ||||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[5], "当月年化收益率(%)", ReportColumn.TYPE_DECIMAL , String.valueOf(2)})); | ||||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[6], "本年累计收益(千元)", ReportColumn.TYPE_DECIMAL , String.valueOf(2)})); | ||||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[7], "本年累计年化收益率(%)", ReportColumn.TYPE_DECIMAL , String.valueOf(2)})); | ||||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[8], "实际收益", ReportColumn.TYPE_DECIMAL , String.valueOf(2)})); | ||||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[9], "实际总收益率(%)", ReportColumn.TYPE_DECIMAL , String.valueOf(2)})); | ||||
|         reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[10], "是否已到期", ReportColumn.TYPE_TEXT })); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|  | @ -70,54 +79,68 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|             DynamicObject row = iterator.next(); | ||||
|             // 基础字段获取(添加null检查) | ||||
|             BigDecimal amount = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[4]); // 原始金额(元) | ||||
|             row.set(REPORT_FIELDS[4],amount.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP)); | ||||
| 
 | ||||
|             BigDecimal buyCopies = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[5]); // 持有份额 | ||||
|             BigDecimal netWorth = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[6]); // 购买时单位净值 | ||||
|             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]); // 到期日 | ||||
|             BigDecimal expectedRate = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[10]); // 预计业绩比较基准(%) | ||||
|             String basis = row.getString(REPORT_FIELDS[15]);//计息基准 | ||||
|             //理财申购单估值分录处理 | ||||
|             Long id = row.getLong(REPORT_FIELDS[13]); | ||||
|             valuationEntry(accrualDate,buyDate,buyAmount,id,row); | ||||
| 
 | ||||
|             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 startBuyCopies = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[16]); // 购买份额 | ||||
| 
 | ||||
| 
 | ||||
|             // 1. 设置计提日 | ||||
|             row.set(DYNAMICS_FIELDS[1], accrualDate); | ||||
|             // 2. 计算天数 = 计提日 - 计息日 | ||||
|             countDays(valueDate,accrualDate,row); | ||||
|             // 3. 计算产品期限(总天数)=到期日-购买日,若到期日为空则用计提日-购买日 | ||||
|             String day = countProductTerm(buyDate, expireDate, accrualDate, row); | ||||
|             // 3. 计算产品期限(总天数)=到期日-计息日 | ||||
|             String day = countProductTerm(valueDate, expireDate, accrualDate, row); | ||||
|             // 4. 预计收益 = 产品期限 * 金额(千元) * 预计业绩比较基准 / 365 | ||||
|             BigDecimal proRevenue = countProRevenue(expectedRate, day, amount, row); | ||||
|             BigDecimal proRevenue = countProRevenue(expectedRate, day, amount, row,basis); | ||||
|             sumProjectedEarnings=sumProjectedEarnings.add(proRevenue); | ||||
|             // 5. 收益计提 = 持有份额 * (月末单位净值 - 购买时单位净值) / 1000 | ||||
|             BigDecimal revenueAmt = countRevenueAmt(buyCopies, monthNetWorth, netWorth, row); | ||||
|             // 5. 收益计提 =  (持有份额 *月末单位净值 - 购买份额*购买时单位净值) / 1000 | ||||
|             BigDecimal revenueAmt = countRevenueAmt(buyCopies, monthNetWorth, netWorth, row,startBuyCopies); | ||||
|             sumProvisionEarnings=sumProvisionEarnings.add(revenueAmt); | ||||
|             // 6. 本月收益计算(严格按生效期间计算) | ||||
|             BigDecimal monthRevenue = countMonthRevenue(monthNetWorth, netWorth, buyCopies, valueDate, accrualDate, expireDate, row); | ||||
|             // 本月收益计算累计 | ||||
|             //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); | ||||
|             // 8. 本年累计收益 = 当年各月收益之和(按实际持有天数比例计算) | ||||
|             BigDecimal yearRevenue = countYearRevenue(monthNetWorth, netWorth, buyCopies, valueDate, accrualDate, expireDate, row); | ||||
|             //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)); | ||||
| 
 | ||||
| 
 | ||||
|             //小计行合计 | ||||
|             if (row.getString(REPORT_FIELDS[0]).contains("-小计")){ | ||||
|                 row.set(DYNAMICS_FIELDS[0],sumProjectedEarnings); | ||||
|                 row.set(DYNAMICS_FIELDS[3],sumProvisionEarnings); | ||||
|                 row.set(DYNAMICS_FIELDS[4],sumMonthEarnings); | ||||
|                 row.set(DYNAMICS_FIELDS[6],sumYearEarnings); | ||||
|                 //赋值后归0,重新参与合计 | ||||
|                 sumProjectedEarnings=BigDecimal.ZERO; | ||||
|                 sumProvisionEarnings=BigDecimal.ZERO; | ||||
|                 sumMonthEarnings=BigDecimal.ZERO; | ||||
|                 sumYearEarnings=BigDecimal.ZERO; | ||||
|             } | ||||
| //            if (row.getString(REPORT_FIELDS[0]).contains("-小计")){ | ||||
| //                row.set(DYNAMICS_FIELDS[0],sumProjectedEarnings); | ||||
| //                row.set(DYNAMICS_FIELDS[3],sumProvisionEarnings); | ||||
| //                row.set(DYNAMICS_FIELDS[4],sumMonthEarnings); | ||||
| //                row.set(DYNAMICS_FIELDS[6],sumYearEarnings); | ||||
| //                //赋值后归0,重新参与合计 | ||||
| //                sumProjectedEarnings=BigDecimal.ZERO; | ||||
| //                sumProvisionEarnings=BigDecimal.ZERO; | ||||
| //                sumMonthEarnings=BigDecimal.ZERO; | ||||
| //                sumYearEarnings=BigDecimal.ZERO; | ||||
| //            } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         //小计行处理 | ||||
|         ReportUtils.changeRowData(rowData,REPORT_FIELDS[0]); | ||||
|         //ReportUtils.changeRowData(rowData,REPORT_FIELDS[0]); | ||||
|         //添加合计 | ||||
|         // 需要配置求和的字段映射(目标字段,来源字段) | ||||
|         List<String[]> sumConfig = new ArrayList<>(); | ||||
|  | @ -134,6 +157,195 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 获取估值分录数据 | ||||
|      * @param accrualDate 计提日 | ||||
|      * @param buyDate 购买日期 | ||||
|      * @param buyAmount 购买金额 | ||||
|      * @param id 表单id | ||||
|      */ | ||||
|     private void valuationEntry(Date accrualDate, Date buyDate, BigDecimal buyAmount, Long id, DynamicObject row) { | ||||
|         // 初始化所有变量 | ||||
|         BigDecimal buyCopies = BigDecimal.ZERO; | ||||
|         BigDecimal monthIop = BigDecimal.ZERO; | ||||
|         Date monthIopDate = null; | ||||
|         BigDecimal monthAmount = BigDecimal.ZERO; | ||||
|         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) { | ||||
|             DynamicObjectCollection dynamicObjectCollection = dynamicObject.getDynamicObjectCollection("valuationentry"); | ||||
|             if (dynamicObjectCollection != null && dynamicObjectCollection.size() != 0) { | ||||
|                 // 初始化记录变量 | ||||
|                 DynamicObject closestRecord = null; | ||||
|                 DynamicObject latestIopRecord = null; | ||||
|                 DynamicObject lastMonthRecord = null; | ||||
|                 DynamicObject lastYearRecord = null; | ||||
|                 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); | ||||
| 
 | ||||
|                 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; | ||||
| 
 | ||||
|                     Calendar valCal = Calendar.getInstance(); | ||||
|                     valCal.setTime(valuationdate); | ||||
|                     int valYear = valCal.get(Calendar.YEAR); | ||||
|                     int valMonth = valCal.get(Calendar.MONTH); | ||||
| 
 | ||||
|                     // 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; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // 3. 寻找上月最后一次估值记录 | ||||
|                     if ((valYear == accrualYear && valMonth == accrualMonth - 1) || | ||||
|                             (accrualMonth == 0 && valYear == accrualYear - 1 && valMonth == 11)) { | ||||
|                         if (lastMonthRecord == null || valuationdate.after(lastMonthRecord.getDate("e_valuationdate"))) { | ||||
|                             lastMonthRecord = object; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // 4. 寻找上一年最后一次估值记录 | ||||
|                     if (valYear == accrualYear - 1) { | ||||
|                         if (lastYearRecord == null || valuationdate.after(lastYearRecord.getDate("e_valuationdate"))) { | ||||
|                             lastYearRecord = object; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // 5. 寻找本年第一个估值记录 | ||||
|                     if (valYear == accrualYear) { | ||||
|                         if (yearStartRecord == null || valuationdate.before(yearStartRecord.getDate("e_valuationdate"))) { | ||||
|                             yearStartRecord = object; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 // 设置持有份额 | ||||
|                 if (closestRecord != null) { | ||||
|                     buyCopies = closestRecord.getBigDecimal("e_surpcopies"); | ||||
|                 } | ||||
| 
 | ||||
|                 // 设置月末单位净值 | ||||
|                 if (latestIopRecord != null) { | ||||
|                     monthIop = latestIopRecord.getBigDecimal("e_iopv"); | ||||
|                     monthIopDate = latestIopRecord.getDate("e_valuationdate"); | ||||
|                 } | ||||
| 
 | ||||
|                 // 计算本月收益 | ||||
|                 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); | ||||
| 
 | ||||
|                         // 计算当月年化收益率 | ||||
|                         if (lastMonthMarketValue.compareTo(BigDecimal.ZERO) != 0) { | ||||
| 
 | ||||
|                             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 (lastMonthMarketValue.compareTo(BigDecimal.ZERO) != 0) { | ||||
| 
 | ||||
|                             monthAnnualizedRate = monthAmount.divide(buyAmount).multiply(new BigDecimal(1200)).setScale(2, RoundingMode.HALF_UP); | ||||
| 
 | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 // 计算本年累计收益 | ||||
|                 if (latestIopRecord != null) { | ||||
|                     BigDecimal currentMarketValue = latestIopRecord.getBigDecimal("e_iopv").multiply(buyCopies); | ||||
| 
 | ||||
|                     // 只有当上年记录存在时才计算本年累计收益 | ||||
|                     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)) | ||||
|                                     .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))) | ||||
|                                     .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||
| 
 | ||||
|                             int monthCount = accrualMonth -buyMonth; | ||||
|                             if (monthCount==0){ | ||||
|                                 monthCount = 1; | ||||
|                             } | ||||
|                             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); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // 设置结果 | ||||
|         row.set(REPORT_FIELDS[5], buyCopies); | ||||
|         row.set(REPORT_FIELDS[11], monthIop); | ||||
|         row.set(REPORT_FIELDS[12], monthIopDate); | ||||
|         row.set(DYNAMICS_FIELDS[4], monthAmount); | ||||
|         row.set(DYNAMICS_FIELDS[5], monthAnnualizedRate); | ||||
|         row.set(DYNAMICS_FIELDS[6], yearAmount); | ||||
|         row.set(DYNAMICS_FIELDS[7], yearAnnualizedRate); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 计算天数 = 计提日 - 计息日 | ||||
|      * @param valueDate 计息日 | ||||
|  | @ -149,26 +361,61 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 计算产品期限(总天数)=到期日-购买日,若到期日为空则用计提日-购买日 | ||||
|      * @param buyDate 购买日 | ||||
|      * @param expireDate 到期日 | ||||
|      * @param accrualDate 计提日 | ||||
|      * @param row 表格 | ||||
|      * @return 总天数 | ||||
|      */ | ||||
|     private String countProductTerm(Date buyDate,Date expireDate,Date accrualDate,DynamicObject row){ | ||||
|     private String countProductTerm(Date valueDate, Date expireDate, Date accrualDate, DynamicObject row) { | ||||
|         String day = "0"; // 默认值设为0 | ||||
|         if (buyDate != null) { | ||||
|             Date endDate = (expireDate != null) ? expireDate : accrualDate; | ||||
|             // 检查计提日/到期日是否早于购买日 | ||||
|             if (endDate.getTime() >= buyDate.getTime()) { | ||||
|                 long termDays = (endDate.getTime() - buyDate.getTime()) / (1000 * 60 * 60 * 24); | ||||
|         Date endDate = (expireDate != null) ? expireDate : accrualDate; | ||||
| 
 | ||||
|         BigDecimal actualEarnings = BigDecimal.ZERO; | ||||
|         Long id = row.getLong(REPORT_FIELDS[13]); // id | ||||
|         DynamicObject[] load = BusinessDataServiceHelper.load("cim_redeem", "id,redeemdate,lastmodifytime,realrevenue", | ||||
|                 (new QFilter("sourcebillid", QCP.equals, id)).toArray()); | ||||
| 
 | ||||
|         // 计算实际收益 | ||||
|         if (load != null && load.length != 0) { | ||||
|             for (DynamicObject dynamicObject : load) { | ||||
|                 BigDecimal realrevenue = dynamicObject.getBigDecimal("realrevenue"); | ||||
|                 actualEarnings = actualEarnings.add(realrevenue); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (valueDate != null) { | ||||
|             String status = row.getString(REPORT_FIELDS[14]); // 状态 | ||||
|             if (status.equals("subscribe_end")) { | ||||
|                 // 获取最大的redeemdate作为结束日期 | ||||
|                 Date maxRedeemDate = null; | ||||
|                 if (load != null && load.length > 0) { | ||||
|                     for (DynamicObject dynamicObject : load) { | ||||
|                         Date redeemDate = dynamicObject.getDate("redeemdate"); | ||||
|                         if (redeemDate != null && (maxRedeemDate == null || redeemDate.after(maxRedeemDate))) { | ||||
|                             maxRedeemDate = redeemDate; | ||||
|                         } | ||||
|                     } | ||||
|                     if (maxRedeemDate != null) { | ||||
|                         endDate = maxRedeemDate; | ||||
|                         row.set(REPORT_FIELDS[9], endDate); // 设置到期日 | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // 计算产品期限天数 | ||||
|             if (endDate.getTime() >= valueDate.getTime()) { | ||||
|                 long termDays = (endDate.getTime() - valueDate.getTime()) / (1000 * 60 * 60 * 24); | ||||
|                 day = String.valueOf(termDays); | ||||
|             } | ||||
|             // 如果endDate早于buyDate,保持day=0 | ||||
|         } | ||||
|         row.set(REPORT_FIELDS[3], day); | ||||
| 
 | ||||
|         // 设置是否到期状态 | ||||
|         String isExpired = "否"; // 默认未到期 | ||||
|         if (expireDate != null && accrualDate != null) { | ||||
|             if (accrualDate.getTime() >= expireDate.getTime()) { | ||||
|                 isExpired = "是"; // 已到期 | ||||
|             } | ||||
|         } | ||||
|         row.set(DYNAMICS_FIELDS[10], isExpired); // 是否到期 | ||||
| 
 | ||||
|         row.set(REPORT_FIELDS[3], day); // 产品期限天数 | ||||
|         row.set(DYNAMICS_FIELDS[8], actualEarnings); // 实际收益 | ||||
| 
 | ||||
|         return day; | ||||
|     } | ||||
| 
 | ||||
|  | @ -179,31 +426,50 @@ public class FinancialFormReport extends AbstractReportFormPlugin implements Plu | |||
|      * @param amount 投资金额 | ||||
|      * @param row 表格 | ||||
|      */ | ||||
|     private BigDecimal countProRevenue(BigDecimal expectedRate,String day,BigDecimal amount,DynamicObject 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); | ||||
|         } | ||||
|         BigDecimal projectRevenue = BigDecimal.ZERO; | ||||
|         if (expectedRate != null) { | ||||
|             projectRevenue = new BigDecimal(day).multiply(amount.divide(new BigDecimal(1000), 10, RoundingMode.HALF_UP)) | ||||
|                     .multiply(expectedRate.divide(new BigDecimal(100), 10, RoundingMode.HALF_UP)) | ||||
|                     .divide(new BigDecimal(365), 2, RoundingMode.HALF_UP); | ||||
|                     .divide(basisDay, 2, RoundingMode.HALF_UP); | ||||
|             row.set(DYNAMICS_FIELDS[0], projectRevenue); | ||||
|         } | ||||
|         return projectRevenue; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 收益计提 = 持有份额 * (月末单位净值 - 购买时单位净值) / 1000 | ||||
|      * @param buyCopies 持有份额 | ||||
|      * @param monthNetWorth 月末单位净值 | ||||
|      * @param netWorth 购买时单位净值 | ||||
|      * @param row 表格 | ||||
|      * 收益计提 = (持有份额 * 月末单位净值 - 购买份额 * 购买时单位净值) / 1000 | ||||
|      * @param buyCopies 持有份额(当前份额) | ||||
|      * @param monthNetWorth 月末单位净值(当前净值) | ||||
|      * @param netWorth 购买时单位净值(初始净值) | ||||
|      * @param row 表格行数据 | ||||
|      * @param startBuyCopies 购买份额(初始份额) | ||||
|      * @return 计算后的收益金额(保留2位小数) | ||||
|      */ | ||||
|     private BigDecimal countRevenueAmt(BigDecimal buyCopies,BigDecimal monthNetWorth,BigDecimal netWorth,DynamicObject row){ | ||||
|         BigDecimal revenue=BigDecimal.ZERO; | ||||
|         if (buyCopies != null && monthNetWorth != null && netWorth != null) { | ||||
|              revenue = buyCopies.multiply(monthNetWorth.subtract(netWorth)) | ||||
|     private BigDecimal countRevenueAmt( | ||||
|             BigDecimal buyCopies, | ||||
|             BigDecimal monthNetWorth, | ||||
|             BigDecimal netWorth, | ||||
|             DynamicObject row, | ||||
|             BigDecimal startBuyCopies | ||||
|     ) { | ||||
|         BigDecimal revenue = BigDecimal.ZERO; | ||||
| 
 | ||||
|         // 检查所有参数是否非空 | ||||
|         if (buyCopies != null && monthNetWorth != null && netWorth != null && startBuyCopies != null) { | ||||
|             // 计算:(持有份额 * 月末单位净值 - 购买份额 * 购买时单位净值) / 1000 | ||||
|             revenue = buyCopies.multiply(monthNetWorth) | ||||
|                     .subtract(startBuyCopies.multiply(netWorth)) | ||||
|                     .divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); | ||||
| 
 | ||||
|             // 设置到表格行 | ||||
|             row.set(DYNAMICS_FIELDS[3], revenue); | ||||
|         } | ||||
| 
 | ||||
|         return revenue; | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,17 +26,18 @@ import java.util.List; | |||
| public class FinancialListReport extends AbstractReportListDataPlugin implements Plugin { | ||||
|     private static final Log logger = LogFactory.getLog(FinancialListReport.class); | ||||
| 
 | ||||
|     // 理财申购单字段 | ||||
|     // 理财申购单字段--固定取值 | ||||
|     private static final String[] FINANCIAL_FIELDS = { | ||||
|             "finorginfo.name", "productname", "revenuetype", "term", "amount", | ||||
|             "buycopies", "iopv", "purchasedate", "valuedate", "expiredate", "planrevenue" | ||||
|             "finorginfo.name", "productname", "investvarieties", "term", "amount", | ||||
|             "iopv", "purchasedate", "valuedate", "expiredate", "planrevenue", | ||||
|             "id","finservicestatus","basis","buycopies" | ||||
|     }; | ||||
| 
 | ||||
|     // 报表输出字段 | ||||
|     private static final String[] REPORT_FIELDS = { | ||||
|             "shjh_bankname", "shjh_productname", "shjh_producttype", "shjh_productterm", | ||||
|             "shjh_amount", "shjh_buycopies", "shjh_iopv", "shjh_buydate", "shjh_valuedate", | ||||
|             "shjh_expiredate", "shjh_planrevenue", "shjh_monthiopv", "shjh_monthiopvdate" | ||||
|             "shjh_bankname", "shjh_productname", "shjh_producttype", "shjh_productterm", "shjh_amount", | ||||
|             "shjh_iopv", "shjh_buydate", "shjh_valuedate", "shjh_expiredate", "shjh_planrevenue" | ||||
|             ,"shjh_id","shjh_status","shjh_basis","shjh_startbuycopies" | ||||
|     }; | ||||
| 
 | ||||
|     // 筛选条件字段名 | ||||
|  | @ -67,16 +68,17 @@ public class FinancialListReport extends AbstractReportListDataPlugin implements | |||
|         ); | ||||
| 
 | ||||
|         // 3. 查询理财收益预提数据 | ||||
|         DataSet addDataSet = QueryServiceHelper.queryDataSet( | ||||
|                 this.getClass().getName() + "1", | ||||
|                 "cim_intbill_batch", | ||||
|                 "entry.finbillno, entry.shjh_nowamount AS shjh_monthiopv, preintdate AS shjh_monthiopvdate", | ||||
|                 null, | ||||
|                 null | ||||
|         ); | ||||
| //        DataSet addDataSet = QueryServiceHelper.queryDataSet( | ||||
| //                this.getClass().getName() + "1", | ||||
| //                "cim_intbill_batch", | ||||
| //                "entry.finbillno, entry.shjh_nowamount AS shjh_monthiopv, preintdate AS shjh_monthiopvdate", | ||||
| //                null, | ||||
| //                null | ||||
| //        ); | ||||
| 
 | ||||
|         // 4. 合并数据并返回结果 | ||||
|         return processAndMergeDatasets(mainDataSet, addDataSet); | ||||
| //        return processAndMergeDatasets(mainDataSet, addDataSet); | ||||
|         return mainDataSet; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -133,26 +135,27 @@ public class FinancialListReport extends AbstractReportListDataPlugin implements | |||
|                 .finish(); | ||||
| 
 | ||||
|         // 生成按银行分组的小计行 | ||||
|         DataSet summaryDataSet = joinedDataSet.groupBy(new String[]{REPORT_FIELDS[0]}) | ||||
|                 .sum(REPORT_FIELDS[4])  // 对金额字段求和 | ||||
|                 .finish() | ||||
|                 .addField("'-'", REPORT_FIELDS[1])    // 产品名称 | ||||
|                 .addField("'-'", REPORT_FIELDS[2])    // 产品类型 | ||||
|                 .addField("'-'", REPORT_FIELDS[3])    // 产品期限 | ||||
|                 .addField("0L", REPORT_FIELDS[5])     // 持有份数 | ||||
|                 .addField("0L", REPORT_FIELDS[6])     // 单位净值 | ||||
|                 .addField("NULL", REPORT_FIELDS[7])  // 购买日 | ||||
|                 .addField("NULL", REPORT_FIELDS[8])   // 计息日 | ||||
|                 .addField("NULL", REPORT_FIELDS[9])   // 到期日 | ||||
|                 .addField("0L", REPORT_FIELDS[10])    // 预计收益 | ||||
|                 .addField("0L", REPORT_FIELDS[11])    // 月末净值 | ||||
|                 .addField("NULL", REPORT_FIELDS[12])  // 净值报告日 | ||||
|                 .select("concat(shjh_bankname+'-小计') as " + String.join(",", REPORT_FIELDS)) | ||||
|                 .select(String.join(",", REPORT_FIELDS)); | ||||
| 
 | ||||
|         // 合并明细数据和小计数据,并按银行名称排序 | ||||
|         return joinedDataSet.union(summaryDataSet) | ||||
|                 .orderBy(new String[]{REPORT_FIELDS[0]}); | ||||
| //        DataSet summaryDataSet = joinedDataSet.groupBy(new String[]{REPORT_FIELDS[0]}) | ||||
| //                .sum(REPORT_FIELDS[4])  // 对金额字段求和 | ||||
| //                .finish() | ||||
| //                .addField("'-'", REPORT_FIELDS[1])    // 产品名称 | ||||
| //                .addField("'-'", REPORT_FIELDS[2])    // 产品类型 | ||||
| //                .addField("'-'", REPORT_FIELDS[3])    // 产品期限 | ||||
| //                .addField("0L", REPORT_FIELDS[5])     // 持有份数 | ||||
| //                .addField("0L", REPORT_FIELDS[6])     // 单位净值 | ||||
| //                .addField("NULL", REPORT_FIELDS[7])  // 购买日 | ||||
| //                .addField("NULL", REPORT_FIELDS[8])   // 计息日 | ||||
| //                .addField("NULL", REPORT_FIELDS[9])   // 到期日 | ||||
| //                .addField("0L", REPORT_FIELDS[10])    // 预计收益 | ||||
| //                .addField("0L", REPORT_FIELDS[11])    // 月末净值 | ||||
| //                .addField("NULL", REPORT_FIELDS[12])  // 净值报告日 | ||||
| //                .select("concat(shjh_bankname+'-小计') as " + String.join(",", REPORT_FIELDS)) | ||||
| //                .select(String.join(",", REPORT_FIELDS)); | ||||
| // | ||||
| //        // 合并明细数据和小计数据,并按银行名称排序 | ||||
| //        return joinedDataSet.union(summaryDataSet) | ||||
| //                .orderBy(new String[]{REPORT_FIELDS[0]}); | ||||
|         return joinedDataSet; | ||||
|     } | ||||
| 
 | ||||
|         /** | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue