理财报表优化3.0

This commit is contained in:
李贵强 2025-06-19 18:12:20 +08:00
parent f1ff3dff9b
commit f54bb8c5b8
3 changed files with 312 additions and 108 deletions

View File

@ -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 月末单位净值

View File

@ -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;
}
}

View File

@ -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();