提交人:刘森澳

日期:2025/7/31 18:10
内容:银行贷款查询报表开发
This commit is contained in:
16358 2025-07-31 18:11:22 +08:00
parent b6e3f7f8cb
commit 7d9a47824f
1 changed files with 374 additions and 0 deletions

View File

@ -0,0 +1,374 @@
package shkd.sys.sys.plugin.report;
import kd.bos.algo.*;
import kd.bos.algo.input.CollectionInput;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.metadata.clr.DataEntityPropertyCollection;
import kd.bos.db.DB;
import kd.bos.db.DBRoute;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.report.AbstractReportListDataPlugin;
import kd.bos.entity.report.FastFilter;
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.portal.util.DateUtils;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.MetadataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.util.CollectionUtils;
import kd.ssc.task.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* 报表取数插件
*/
public class BankloanreportListPlugin extends AbstractReportListDataPlugin {
private static Log log = LogFactory.getLog(BankloanreportListPlugin.class);
/**
* 以银行账户为主表取查询
* 显示所选的核算组织下的所有银行账户的流水
*
* @param reportQueryParam
* @param o
* @return
* @throws Throwable
*/
@Override
public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {
HashMap<String, Object> listQFilter = getListQFilter(reportQueryParam);
//1查询借款合同基础数据主数据
MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType("cfm_loancontractbill");
String mainDbRouteKey = dataEntityType.getDBRouteKey();
String selectLoanContarctSql =
"id as loancontractbillid," +
"org.shkd_comcode shkd_comcode," +
"org.shkd_comname shkd_comname," +
"contractno shkd_contractno," +
"org.number shkd_orgnum," +
"org.name shkd_orgname," +
"bizdate shkd_bizdate,"+
"CASE \n" +
" WHEN finproduct.number = 'RZPZ-0002' OR finproduct.number = 'RZPZ-0019' THEN 'F01'\n" +
" WHEN finproduct.number = 'RZPZ-0036' THEN 'F02'\n" +
" WHEN finproduct.number = 'RZPZ-0026' THEN 'F03'\n" +
" ELSE 'F04'\n" +
"END AS shkd_loankind,"+
"CASE \n" +
" WHEN guarantee = ',2,' THEN 'C'\n" +
" WHEN guarantee = ',4,' THEN 'B'\n" +
" WHEN guarantee = ',5,' THEN 'A'\n" +
" WHEN guarantee = ',6,' THEN 'Z'\n" +
" WHEN guarantee = ',7,' THEN 'D'\n" +
" ELSE 'E'\n" +
"END AS shkd_guarantee,"+
"creditortype," +
"loantype," + //借款类型
"billno as loanContarctBillNo," +
"textcreditor";
DataSet loanContractBills = QueryServiceHelper.queryDataSet(this.getClass().getSimpleName(), "cfm_loancontractbill", selectLoanContarctSql, new QFilter[0], null);
//2查询合作金融机构的数据基础资料
String selectFinOrgInfoSql = "id as finorginfoid,number as finorginfonum,name as finorginfoname,finorgtype.number as finorgtypenum";
DataSet finorginfos = QueryServiceHelper.queryDataSet(this.getClass().getSimpleName(), "bd_finorginfo", selectFinOrgInfoSql, new QFilter[0], null);
//3左连接主数据和基础资料数据
DataSet leftjoinOne = loanContractBills.join(finorginfos, JoinType.LEFT).on("textcreditor", "finorginfoname")
.select("loancontractbillid", "shkd_comcode", "shkd_comname", "shkd_contractno", "shkd_orgnum", "shkd_orgname", "shkd_bizdate",
"shkd_loankind", "shkd_guarantee", "creditortype", "textcreditor","loanContarctBillNo","finorgtypenum","finorginfonum","finorginfoname").finish();
//4添加shkd_internalloan的字段
DataSet addFieldOne = leftjoinOne.addField("CASE \n" +
" WHEN (creditortype = 'finorg' and finorgtypenum = 'FI-031') or creditortype = 'innerunit' THEN 'T00'\n" +
" ELSE 'T01' END", "shkd_internalloan");
//5查询提款处理单数据主数据的提款单分录数据
String selectCfmLoanBillSql =
"id as loanbillid," +
"loancontractbill.number as loanbillContractno," +
"creditortype as loanbillCDtype," +
"textcreditor as shkd_textcreditorname," +
"billno as loanbillBillno," +
"currency.sign as shkd_currency," +
"drawamount as shkd_drawamount," +
"bizdate as shkd_syncdrawdate," +
"term as shkd_syncterm," +
"referencerate.number as referenceratenumber," + //参考利率
"rateadjustdate," + //首次利率确定日
"rateadjustcycletype," + //利率重置周期
"rateadjustcycle," + //利率重置周期值
"ratesign," + //利率浮动基点BP
"ratefloatpoint," + //利率浮动基点
"startloanrate," + //起息日利率
"interesttype," + //利率类型
"convertrate"; //折合同币种汇率
DataSet loanbills = QueryServiceHelper.queryDataSet(this.getClass().getSimpleName(), "cfm_loanbill", selectCfmLoanBillSql, new QFilter[0], null);
//6左连接主数据和提款处理单数据
RowMeta rowMeta1 = addFieldOne.getRowMeta();
RowMeta rowMeta2 = loanbills.getRowMeta();
String[] fieldNames1 = rowMeta1.getFieldNames();
String[] fieldNames2 = rowMeta2.getFieldNames();
List<String> selects1 = new ArrayList<>(Arrays.asList(fieldNames1));
List<String> selects2 = new ArrayList<>(Arrays.asList(fieldNames2));
selects1.addAll(selects2);
DataSet leftjoin2 = addFieldOne.join(loanbills, JoinType.LEFT).on("shkd_contractno", "loanbillContractno")
.select(selects1.toArray(new String[0])).finish();
//7查找各种可能的债权人(主体关联在提款单)
//a业务单元
String selectBosOrgSql = "id as bosorgid,number as bosorgnNum,name as bosorgName,country.name as basorgCountryName";
DataSet entry_basorgs = QueryServiceHelper.queryDataSet(this.getClass().getSimpleName(), "bos_org", selectBosOrgSql, new QFilter[0], null);
//b内部金融组织
String selectFinorginfoSql = "id as finorginfoid,number as finorginfoNum,name as finorginfoName,parent.name finorginfoParentName,country.name as finorginfoCountryName";
DataSet entry_finorginfos = QueryServiceHelper.queryDataSet(this.getClass().getSimpleName(), "bd_finorginfo", selectFinorginfoSql, new QFilter[0], null);
//c商务伙伴
String selectBizpartnerSql = "id as bizpartnerid,number as bizpartnerNum,name as bizpartnerName,country.name as bizpartnerCountryName";
DataSet entry_bizpartners = QueryServiceHelper.queryDataSet(this.getClass().getSimpleName(), "bd_bizpartner", selectBizpartnerSql, new QFilter[0], null);
//8左连接主数据和各种可能的债权人关联在提款单上
RowMeta rowMeta3 = leftjoin2.getRowMeta();
RowMeta rowMeta4 = entry_basorgs.getRowMeta();
RowMeta rowMeta5 = entry_finorginfos.getRowMeta();
RowMeta rowMeta6 = entry_bizpartners.getRowMeta();
String[] fieldNames3 = rowMeta3.getFieldNames();
String[] fieldNames4 = rowMeta4.getFieldNames();
String[] fieldNames5 = rowMeta5.getFieldNames();
String[] fieldNames6 = rowMeta6.getFieldNames();
List<String> selects3 = new ArrayList<>(Arrays.asList(fieldNames3));
List<String> selects4 = new ArrayList<>(Arrays.asList(fieldNames4));
List<String> selects5 = new ArrayList<>(Arrays.asList(fieldNames5));
List<String> selects6 = new ArrayList<>(Arrays.asList(fieldNames6));
selects3.addAll(selects4);
DataSet leftjoin3 = leftjoin2.join(entry_basorgs, JoinType.LEFT).on("shkd_textcreditorname", "bosorgName")
.select(selects3.toArray(new String[0])).finish();
selects3.addAll(selects5);
DataSet leftjoin4 = leftjoin3.join(entry_finorginfos, JoinType.LEFT).on("shkd_textcreditorname", "finorginfoName")
.select(selects3.toArray(new String[0])).finish();
selects3.addAll(selects6);
DataSet leftjoin5 = leftjoin4.join(entry_bizpartners, JoinType.LEFT).on("shkd_textcreditorname", "bizpartnerName")
.select(selects3.toArray(new String[0])).finish();
//9赋值债权人编码总行字段,国家
DataSet addField2 = leftjoin5
.addField("CASE \n" +
" WHEN loanbillCDtype = 'innerunit' THEN bosorgnNum\n" +
" WHEN (loanbillCDtype = 'finorg' or loanbillCDtype = 'bank' or loanbillCDtype = 'settlecenter') THEN finorginfoNum\n" +
" WHEN loanbillCDtype = 'custom' THEN bizpartnerNum\n" +
" ELSE '' END", "shkd_textcreditornum")
.addField("CASE \n" +
" WHEN loanbillCDtype = 'innerunit' THEN bosorgName\n" +
" WHEN (loanbillCDtype = 'finorg' or loanbillCDtype = 'bank' or loanbillCDtype = 'settlecenter') THEN finorginfoParentName\n" +
" WHEN loanbillCDtype = 'custom' THEN bizpartnerName\n" +
" ELSE '' END", "shkd_textcreditortrc")
.addField("CASE \n" +
" WHEN loanbillCDtype = 'innerunit' THEN basorgCountryName\n" +
" WHEN (loanbillCDtype = 'finorg' or loanbillCDtype = 'bank' or loanbillCDtype = 'settlecenter') THEN finorginfoCountryName\n" +
" WHEN loanbillCDtype = 'custom' THEN bizpartnerCountryName\n" +
" ELSE '' END", "shkd_country")
.addField("null", "shkd_loanrate")//利率水平
.addField("null", "shkd_amountoricur")//贷款余额原币
.addField("null", "shkd_amountbencur");//贷款余额本币
//10赋值利率水平贷款余额原币贷款余额本币
DynamicObjectCollection plainDynamicObjectCollection = ORM.create().toPlainDynamicObjectCollection(addField2);
Date shkdSelectdate = (Date)listQFilter.get("shkd_selectdate");
if(shkdSelectdate == null) shkdSelectdate = new Date();
for (DynamicObject dataRow : plainDynamicObjectCollection) {
String referenceratenumber = dataRow.getString("referenceratenumber");//参考利率
Date rateadjustdate = dataRow.getDate("rateadjustdate");//首次利率确定日
BigDecimal shkdDrawamount = dataRow.getBigDecimal("shkd_drawamount");//提款金额
String loanbillBillno = dataRow.getString("loanbillBillno");//提款单编码
String rateadjustcycletype = dataRow.getString("rateadjustcycletype");//利率重置周期
Integer rateadjustcycle = dataRow.getInt("rateadjustcycle");//利率重置周期值
String ratesign = dataRow.getString("ratesign");//利率浮动基点BP
BigDecimal ratefloatpoint = dataRow.getBigDecimal("ratefloatpoint");//利率浮动基点
BigDecimal startloanrate = dataRow.getBigDecimal("startloanrate");//起息日利率
String interesttype = dataRow.getString("interesttype");//利率类型
BigDecimal convertrate = dataRow.getBigDecimal("convertrate");//折合同币种汇率
//赋值利率
if ("fixed".equals(interesttype)){
//固定利率 直接赋值startloanrate
dataRow.set("shkd_loanrate", startloanrate);
}else if ("float".equals(interesttype)){
//浮动利率
//计算利率周期
Calendar calendar = Calendar.getInstance();
calendar.setTime(rateadjustdate);
switch (rateadjustcycletype){
case "D": calendar.add(Calendar.DAY_OF_MONTH, rateadjustcycle);
break;
case "W": calendar.add(Calendar.DAY_OF_MONTH, rateadjustcycle * 7);
break;
case "M": calendar.add(Calendar.MONTH, rateadjustcycle);
break;
case "S": calendar.add(Calendar.MONTH, rateadjustcycle * 3);
break;
case "H": calendar.add(Calendar.MONTH, rateadjustcycle * 6);
break;
case "Y": calendar.add(Calendar.YEAR, rateadjustcycle);
break;
default: break;
}
Date enddate = calendar.getTime();
// 比较 shkdSelectdate enddate
DynamicObject dateRate = new DynamicObject();
if (shkdSelectdate != null) {
int comparison = shkdSelectdate.compareTo(enddate);
if (comparison > 0) {
// shkdSelectdate enddate 之后
QFilter qFilter = new QFilter("referrate.number","=",referenceratenumber);
DynamicObject[] cfm_loanbill_bond = BusinessDataServiceHelper.load("md_datarate","endprice",qFilter.toArray(), "bizdate DESC");
if (cfm_loanbill_bond.length > 0) {
dateRate = cfm_loanbill_bond[0];
}
} else {
// shkdSelectdate enddate 之前 或者 shkdSelectdate enddate 相等
QFilter qFilter = new QFilter("referrate.number","=",referenceratenumber);
qFilter.and("bizdate","<=",shkdSelectdate);
DynamicObject[] cfm_loanbill_bond = BusinessDataServiceHelper.load("md_datarate","endprice",qFilter.toArray(), "bizdate DESC");
if (cfm_loanbill_bond.length > 0) {
dateRate = cfm_loanbill_bond[0];
}
}
}
//计算利率
BigDecimal endprice = dateRate.getBigDecimal("endprice");
BigDecimal shkd_loanrate = BigDecimal.ZERO;
if (endprice == null){
endprice = BigDecimal.ZERO;
}
if ("add".equals(ratesign)){
shkd_loanrate = endprice.add(ratefloatpoint.multiply(BigDecimal.valueOf(0.01)));
}else if ("subtract".equals(ratesign)){
shkd_loanrate = endprice.subtract(ratefloatpoint.multiply(BigDecimal.valueOf(0.01)));
}
dataRow.set("shkd_loanrate", shkd_loanrate);
}
//赋值贷款余额原币贷款余额本币
BigDecimal totalAmount = BigDecimal.ZERO;
DynamicObjectCollection repaymentbill = QueryServiceHelper.query("cfm_repaymentbill", "billno,amount", new QFilter("loans.e_loanbill.number", "=", loanbillBillno).and("bizdate","<=",shkdSelectdate).and("billstatus","=","C").toArray());
if (repaymentbill != null && repaymentbill.size() > 0) {
// billno 分组取每组第一条记录
Map<String, DynamicObject> groupedRepayments = new LinkedHashMap<>();
for (DynamicObject repayment : repaymentbill) {
String billno = repayment.getString("billno");
// 如果该 billno 还未添加到 map 则添加这样保证取的是第一条记录
if (!groupedRepayments.containsKey(billno)) {
groupedRepayments.put(billno, repayment);
}
}
// 计算所有分组的 amount 合计
for (DynamicObject repayment : groupedRepayments.values()) {
BigDecimal amount = repayment.getBigDecimal("amount");
if (amount != null) {
totalAmount = totalAmount.add(amount);
}
}
}
BigDecimal shkd_amountoricur = shkdDrawamount.subtract(totalAmount);
dataRow.set("shkd_amountoricur", shkd_amountoricur);
dataRow.set("shkd_amountbencur", shkd_amountoricur.multiply(convertrate));
}
//根据已结清标识符过滤数据
Boolean shkd_beensettled = (Boolean)listQFilter.get("shkd_beensettled");
if (Boolean.FALSE.equals(shkd_beensettled) || shkd_beensettled == null) {
// 执行过滤已结清数据的逻辑
Iterator<DynamicObject> iterator = plainDynamicObjectCollection.iterator();
while (iterator.hasNext()) {
DynamicObject dataRow = iterator.next();
BigDecimal shkd_amountoricur = dataRow.getBigDecimal("shkd_amountoricur");
if (shkd_amountoricur == null || (shkd_amountoricur != null && shkd_amountoricur.compareTo(BigDecimal.ZERO) <= 0)) {
iterator.remove(); // 移除已结清的数据
}
}
}
// 创建一个空的DataSet 将DynamicObjectCollection转化为DataSet
Collection<Object[]> coll = new ArrayList<>();//报表展示数据
// 遍历修改后的数据的所有字段
List<String> displayFields = new ArrayList<>();//列标识
DynamicObject object = plainDynamicObjectCollection.get(0);
DataEntityPropertyCollection properties = object.getDataEntityType().getProperties();
// 获取所有字段
properties.forEach(property -> displayFields.add(property.getName()));
log.info("displayFields列标识{}", displayFields);
for (DynamicObject dataRow : plainDynamicObjectCollection) {
// 将数据放入数组
Object[] objects = new Object[displayFields.size()];
for (int i = 0; i < displayFields.size(); i++) {
objects[i] = dataRow.get(displayFields.get(i));
}
coll.add(objects);
}
// 创建一个空的DataSet 将DynamicObjectCollection转化为DataSet
DataType stringType = DataType.StringType;
DataType dateType = DataType.DateType;
DataType bigDecimalType = DataType.BigDecimalType;
// DataType integerType = DataType.IntegerType;
List<DataType> dataTypes = new ArrayList<>();//列标识
for (String field : displayFields) {
if (field.contains("shkd_syncdrawdate") || field.contains("shkd_bizdate")) {
dataTypes.add(dateType);
} else if (field.contains("shkd_drawamount") || field.contains("shkd_loanrate") || "shkd_amountoricur".equals(field) || "shkd_amountbencur".equals(field)) {
dataTypes.add(bigDecimalType);
} else {
dataTypes.add(stringType);
}
}
log.info("dataTypes数据类型{}", dataTypes);
RowMeta rowMeta = RowMetaFactory.createRowMeta(displayFields.toArray(new String[0]), dataTypes.toArray(new DataType[0]));
CollectionInput inputs = new CollectionInput(rowMeta, coll);
try {
addField2 = Algo.create(this.getClass().getName()).createDataSet(inputs);
} catch (Exception e) {
log.error("数据集创建失败:{}", e.getMessage());
}
return addField2;
}
/**
* 获取报表所有过滤条件
*
* @param reportQueryParam
* @return
*/
public HashMap<String,Object> getListQFilter(ReportQueryParam reportQueryParam) {
//过滤条件数组
HashMap<String, Object> filterMaps = new HashMap<>();
//初始化过滤数据
List<FilterItemInfo> filterItems = reportQueryParam.getFilter().getFilterItems();
if (CollectionUtils.isNotEmpty(filterItems)) {
for (FilterItemInfo info : filterItems) {
filterMaps.put(info.getPropName(),info.getValue());
}
}
return filterMaps;
}
}