理财收益计提报表
This commit is contained in:
parent
4c4e67cdd3
commit
986d9ac682
|
|
@ -80,8 +80,8 @@ public class RecBillChangeListExtendPlugin extends AbstractListPlugin implements
|
|||
}
|
||||
|
||||
// 收款类型校验
|
||||
if (!Arrays.asList("103", "109", "100").contains(typeNumber)) {
|
||||
this.getView().showTipNotification("所选单据不满足变更条件,只有收款类型=“预付款退回/员工还款/销售回款”的收款单才允许变更。");
|
||||
if (Arrays.asList("103", "109", "100").contains(typeNumber)) {
|
||||
this.getView().showTipNotification("所选单据不满足变更条件,收款类型=“预付款退回/员工还款/销售回款”的收款单不允许变更。");
|
||||
evt.setCancel(true);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,314 @@
|
|||
package shjh.jhzj7.fi.fi.plugin.report;
|
||||
|
||||
import kd.bos.dataentity.entity.DynamicObject;
|
||||
import kd.bos.dataentity.entity.DynamicObjectCollection;
|
||||
import kd.bos.entity.report.FilterItemInfo;
|
||||
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.report.ReportList;
|
||||
import kd.bos.report.plugin.AbstractReportFormPlugin;
|
||||
import kd.sdk.plugin.Plugin;
|
||||
import shjh.jhzj7.fi.fi.plugin.report.util.ReportUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 报表界面插件
|
||||
* 理财收益计提报表界面插件
|
||||
*/
|
||||
public class FinancialFormReport extends AbstractReportFormPlugin implements Plugin {
|
||||
|
||||
private final static Log logger = LogFactory.getLog(FinancialFormReport.class);
|
||||
|
||||
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"
|
||||
};
|
||||
|
||||
private static final String[] DYNAMICS_FIELDS = {
|
||||
"shjh_projectrevenueamt","shjh_date","shjh_days","shjh_revenueamt",
|
||||
"shjh_monthrevenueamt","shjh_monthrate","shjh_yearrevenueamt"
|
||||
};
|
||||
|
||||
@Override
|
||||
public void beforeQuery(ReportQueryParam queryParam) {
|
||||
super.beforeQuery(queryParam);
|
||||
ReportList reportList = getControl("reportlistap");
|
||||
reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[0], "预计收益(千元)", ReportColumn.TYPE_DECIMAL , String.valueOf(2)}));
|
||||
reportList.getColumns().add(ReportUtils.createReportColumn(new String [] { DYNAMICS_FIELDS[1], "计提日", ReportColumn.TYPE_DATE }));
|
||||
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[6], "本年累计收益(千元)", ReportColumn.TYPE_DECIMAL , String.valueOf(2)}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processRowData(String gridPK, DynamicObjectCollection rowData, ReportQueryParam queryParam) {
|
||||
super.processRowData(gridPK, rowData, queryParam);
|
||||
|
||||
// 获取筛选条件中的计提日
|
||||
Date accrualDate = queryParam.getFilter().getDate(FILTER_DATE);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(accrualDate);
|
||||
|
||||
// 遍历每一行数据
|
||||
Iterator<DynamicObject> iterator = rowData.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
DynamicObject row = iterator.next();
|
||||
//跳过小计行
|
||||
if (row.getString(REPORT_FIELDS[0]).contains("-小计")){
|
||||
continue;
|
||||
}
|
||||
// 基础字段获取(添加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]); // 购买时单位净值
|
||||
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]); // 预计业绩比较基准(%)
|
||||
BigDecimal monthNetWorth = ReportUtils.getBigDecimalValue(row, REPORT_FIELDS[11]); // 月末单位净值
|
||||
|
||||
// 1. 设置计提日
|
||||
row.set(DYNAMICS_FIELDS[1], accrualDate);
|
||||
// 2. 计算天数 = 计提日 - 计息日
|
||||
countDays(valueDate,accrualDate,row);
|
||||
// 3. 计算产品期限(总天数)=到期日-购买日,若到期日为空则用计提日-购买日
|
||||
String day = countProductTerm(buyDate, expireDate, accrualDate, row);
|
||||
// 4. 预计收益 = 产品期限 * 金额(千元) * 预计业绩比较基准 / 365
|
||||
BigDecimal proRevenue = countProRevenue(expectedRate, day, amount, row);
|
||||
// 5. 收益计提 = 持有份额 * (月末单位净值 - 购买时单位净值) / 1000
|
||||
BigDecimal revenueAmt = countRevenueAmt(buyCopies, monthNetWorth, netWorth, row);
|
||||
// 6. 本月收益计算(严格按生效期间计算)
|
||||
BigDecimal monthRevenue = countMonthRevenue(monthNetWorth, netWorth, buyCopies, valueDate, accrualDate, expireDate, row);
|
||||
// 7. 当月收益率 = 本月收益 / 金额(千元) * 100 * 12
|
||||
countMonthRate(amount,monthRevenue,row);
|
||||
// 8. 本年累计收益 = 当年各月收益之和(按实际持有天数比例计算)
|
||||
BigDecimal yearRevenue = countYearRevenue(monthNetWorth, netWorth, buyCopies, valueDate, accrualDate, expireDate, row);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算天数 = 计提日 - 计息日
|
||||
* @param valueDate 计息日
|
||||
* @param accrualDate 计提日
|
||||
* @param row 表格
|
||||
*/
|
||||
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 {
|
||||
row.set(DYNAMICS_FIELDS[2], BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算产品期限(总天数)=到期日-购买日,若到期日为空则用计提日-购买日
|
||||
* @param buyDate 购买日
|
||||
* @param expireDate 到期日
|
||||
* @param accrualDate 计提日
|
||||
* @param row 表格
|
||||
* @return 总天数
|
||||
*/
|
||||
private String countProductTerm(Date buyDate,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);
|
||||
day = String.valueOf(termDays);
|
||||
}
|
||||
// 如果endDate早于buyDate,保持day=0
|
||||
}
|
||||
row.set(REPORT_FIELDS[3], day);
|
||||
return day;
|
||||
}
|
||||
|
||||
/**
|
||||
* 预计收益 = 产品期限 * 金额(千元) * 预计业绩比较基准 / 365
|
||||
* @param expectedRate 预计业绩比较基准(%)
|
||||
* @param day 总天数
|
||||
* @param amount 投资金额
|
||||
* @param row 表格
|
||||
*/
|
||||
private BigDecimal countProRevenue(BigDecimal expectedRate,String day,BigDecimal amount,DynamicObject row) {
|
||||
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);
|
||||
row.set(DYNAMICS_FIELDS[0], projectRevenue);
|
||||
}
|
||||
return projectRevenue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 收益计提 = 持有份额 * (月末单位净值 - 购买时单位净值) / 1000
|
||||
* @param buyCopies 持有份额
|
||||
* @param monthNetWorth 月末单位净值
|
||||
* @param netWorth 购买时单位净值
|
||||
* @param row 表格
|
||||
*/
|
||||
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))
|
||||
.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP);
|
||||
row.set(DYNAMICS_FIELDS[3], revenue);
|
||||
}
|
||||
return revenue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 本月收益计算(严格按生效期间计算)
|
||||
* @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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
package shjh.jhzj7.fi.fi.plugin.report;
|
||||
|
||||
import kd.bos.algo.DataSet;
|
||||
import kd.bos.dataentity.entity.DynamicObject;
|
||||
import kd.bos.entity.report.AbstractReportColumn;
|
||||
import kd.bos.entity.report.AbstractReportListDataPlugin;
|
||||
import kd.bos.entity.report.FilterItemInfo;
|
||||
import kd.bos.entity.report.ReportQueryParam;
|
||||
import kd.bos.logging.Log;
|
||||
import kd.bos.logging.LogFactory;
|
||||
import kd.bos.orm.ORM;
|
||||
import kd.bos.orm.query.QCP;
|
||||
import kd.bos.orm.query.QFilter;
|
||||
import kd.bos.servicehelper.QueryServiceHelper;
|
||||
import kd.sdk.plugin.Plugin;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
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"
|
||||
};
|
||||
|
||||
// 报表输出字段
|
||||
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"
|
||||
};
|
||||
|
||||
// 筛选条件字段名
|
||||
private static final String FILTER_BANK_NAME = "shjh_filtername";
|
||||
private static final String FILTER_PRODUCT_NAME = "shjh_filterproduct";
|
||||
private static final String FILTER_BUY_DATE = "shjh_filterbuydate";
|
||||
private static final String FILTER_START_DATE = "shjh_startdate";
|
||||
private static final String FILTER_END_DATE = "shjh_enddate";
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
|
||||
|
||||
@Override
|
||||
public DataSet query(ReportQueryParam param, Object context) throws Throwable {
|
||||
// 1. 构建查询条件
|
||||
List<QFilter> filters = buildFilters(param.getFilter().getFilterItems());
|
||||
filters.add(new QFilter("billstatus", QCP.equals, "C")); // 只查询已审核单据
|
||||
|
||||
// 2. 查询理财申购单数据
|
||||
StringBuilder selectFields = new StringBuilder();
|
||||
assembleSQL(selectFields);
|
||||
selectFields.append(",").append("billno");
|
||||
DataSet mainDataSet = QueryServiceHelper.queryDataSet(
|
||||
this.getClass().getName(),
|
||||
"cim_finsubscribe",
|
||||
String.valueOf(selectFields),
|
||||
filters.toArray(new QFilter[0]),
|
||||
null
|
||||
);
|
||||
|
||||
// 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
|
||||
);
|
||||
|
||||
// 4. 合并数据并返回结果
|
||||
return processAndMergeDatasets(mainDataSet, addDataSet);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据界面筛选条件构建QFilter列表
|
||||
*/
|
||||
private List<QFilter> buildFilters(List<FilterItemInfo> filterItems) {
|
||||
List<QFilter> filters = 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));
|
||||
}
|
||||
break;
|
||||
case FILTER_PRODUCT_NAME: // 产品筛选
|
||||
if (value != null) {
|
||||
Long productId = (Long) ((DynamicObject) value).getPkValue();
|
||||
filters.add(new QFilter("product", QCP.equals, productId));
|
||||
}
|
||||
break;
|
||||
case FILTER_BUY_DATE: // 购买日筛选
|
||||
if (date != null) {
|
||||
filters.add(new QFilter("purchasedate", QCP.equals, DATE_FORMAT.format(date)));
|
||||
}
|
||||
break;
|
||||
case FILTER_START_DATE: // 计息日筛选
|
||||
if (date != null) {
|
||||
filters.add(new QFilter("valuedate", QCP.equals, DATE_FORMAT.format(date)));
|
||||
}
|
||||
break;
|
||||
case FILTER_END_DATE: // 到期日筛选
|
||||
if (date != null) {
|
||||
filters.add(new QFilter("expiredate", QCP.equals, DATE_FORMAT.format(date)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理并合并数据集
|
||||
*/
|
||||
private DataSet processAndMergeDatasets(DataSet mainDataSet, DataSet addDataSet) {
|
||||
// 关联两个数据集
|
||||
DataSet joinedDataSet = mainDataSet.join(addDataSet)
|
||||
.on("billno", "entry.finbillno")
|
||||
.select(REPORT_FIELDS)
|
||||
.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]});
|
||||
}
|
||||
|
||||
/**
|
||||
* 组装SQL
|
||||
*
|
||||
* @param selectFields
|
||||
*/
|
||||
private void assembleSQL(StringBuilder selectFields) {
|
||||
for (int i = 0; i < FINANCIAL_FIELDS.length; i++) {
|
||||
if (i == FINANCIAL_FIELDS.length-1) {
|
||||
selectFields.append(FINANCIAL_FIELDS[i]).append(" as ").append(REPORT_FIELDS[i]);
|
||||
}else {
|
||||
selectFields.append(FINANCIAL_FIELDS[i]).append(" as ").append(REPORT_FIELDS[i]).append(",");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -102,6 +102,7 @@ public class RegularListReport extends AbstractReportListDataPlugin implements P
|
|||
logger.error(e.getMessage());
|
||||
}
|
||||
// 按组织名称排序,这样,底部的合计数据,就会与上面的组织名称排在一起
|
||||
assert unionDataSet != null;
|
||||
return unionDataSet.orderBy(new String[]{FIELDS[0]});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
package shjh.jhzj7.fi.fi.plugin.report.util;
|
||||
|
||||
import kd.bos.dataentity.entity.DynamicObject;
|
||||
import kd.bos.dataentity.entity.LocaleString;
|
||||
import kd.bos.entity.report.ReportColumn;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
public class ReportUtils {
|
||||
|
||||
/**
|
||||
* 动态创建报表列表字段列
|
||||
* @param columnInfo
|
||||
* @return
|
||||
*/
|
||||
public static ReportColumn createReportColumn(String [] columnInfo) {
|
||||
ReportColumn reportColumn = new ReportColumn();
|
||||
// 设置报表列字段的标识
|
||||
reportColumn.setFieldKey(columnInfo[0]);
|
||||
// 设置报表列字段的标识
|
||||
reportColumn.setCaption(new LocaleString(columnInfo[1]));
|
||||
// 设置报表列字段的类型
|
||||
reportColumn.setFieldType(columnInfo[2]);
|
||||
// 设置报表列字段的精度
|
||||
if (columnInfo.length>3){
|
||||
reportColumn.setScale(Integer.parseInt(columnInfo[3]));
|
||||
}
|
||||
return reportColumn;
|
||||
}
|
||||
|
||||
// 辅助方法:获取某个月的第一天
|
||||
public static Date getFirstDayOfMonth(Date date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(date);
|
||||
cal.set(Calendar.DAY_OF_MONTH, 1);
|
||||
return cal.getTime();
|
||||
}
|
||||
|
||||
// 安全获取BigDecimal值
|
||||
public static BigDecimal getBigDecimalValue(DynamicObject row, String fieldName) {
|
||||
Object value = row.get(fieldName);
|
||||
if (value instanceof BigDecimal) {
|
||||
return (BigDecimal) value;
|
||||
} else if (value instanceof Number) {
|
||||
return BigDecimal.valueOf(((Number) value).doubleValue());
|
||||
}
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
// 辅助方法:按比例计算收益
|
||||
public static BigDecimal calculateProportionalRevenue(BigDecimal totalRevenue, long totalDays, long effectiveDays) {
|
||||
if (totalDays <= 0 || effectiveDays <= 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
return totalRevenue
|
||||
.divide(new BigDecimal(totalDays), 10, RoundingMode.HALF_UP)
|
||||
.multiply(new BigDecimal(effectiveDays))
|
||||
.divide(new BigDecimal(1000), 2, RoundingMode.HALF_UP); // 转换为千元单位
|
||||
}
|
||||
|
||||
// 辅助方法:计算两个日期之间的天数
|
||||
public static long getDaysBetween(Date start, Date end) {
|
||||
if (start == null || end == null) return 0;
|
||||
return (end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24) + 1;
|
||||
}
|
||||
|
||||
// 辅助方法:判断是否同月
|
||||
public static boolean isSameMonth(Date date1, Date date2) {
|
||||
Calendar cal1 = Calendar.getInstance();
|
||||
cal1.setTime(date1);
|
||||
Calendar cal2 = Calendar.getInstance();
|
||||
cal2.setTime(date2);
|
||||
return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
|
||||
&& cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
|
||||
}
|
||||
|
||||
// 辅助方法:判断是否同年
|
||||
public static boolean isSameYear(Date date1, Date date2) {
|
||||
Calendar cal1 = Calendar.getInstance();
|
||||
cal1.setTime(date1);
|
||||
Calendar cal2 = Calendar.getInstance();
|
||||
cal2.setTime(date2);
|
||||
return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue