1、计息单增加对方单位类型、对方单位、对方账户、对方开户行

2、计息生成付款单调整
This commit is contained in:
XiangLingFeng 2025-12-16 16:49:57 +08:00
parent 16c64e2e49
commit 6bcb892378
2 changed files with 288 additions and 2 deletions

View File

@ -13,7 +13,6 @@ import kd.bos.entity.plugin.args.BeforeOperationArgs;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.sdk.plugin.Plugin;
@ -71,11 +70,13 @@ public class CdmInterestAccrualPlugin extends AbstractOperationServicePlugIn imp
HashMap<String, Object> dataMap = new HashMap<>();
dataMap.put("issueDate",issueDate);
dataMap.put("draftbillexpireDate",draftbillexpireDate);
dataMap.put("billNo",billNo);
QFilter filter = new QFilter("entry.srcbillno", QCP.equals, billNo);
filter.and("feetype.number",QCP.in, feeTypeNumSet).and("kdsz_pushjx",QCP.not_equals,"B");
//费用明细所需字段
String FeeBillSelectField = "id,billno,org,feetype,currency,amountrate,payamt,kdsz_pushjx";
String FeeBillSelectField = "id,billno,org,feetype,currency,amountrate,payamt,oppunittype," +
"oppunit,oppacctbank,oppbebank,kdsz_pushjx";
DynamicObject[] feeBills = BusinessDataServiceHelper.load(FeeBill_KEY, FeeBillSelectField, new QFilter[]{filter});
if (feeBills == null || feeBills.length == 0){
logger.info("应付票据:" + billNo + "没有费用明细需要下推!");
@ -132,6 +133,7 @@ public class CdmInterestAccrualPlugin extends AbstractOperationServicePlugIn imp
DynamicObjectCollection JXBills = new DynamicObjectCollection();
Date issueDate = (Date)dataMap.get("issueDate");
Date draftbillexpireDate = (Date)dataMap.get("draftbillexpireDate");
String originBillNo = (String)dataMap.get("billNo");
for (DynamicObject feeBill : feeBills) {
DynamicObject JXBill = BusinessDataServiceHelper.newDynamicObject(INTERESTACCRUAL_KEY);
//参数组装
@ -140,6 +142,10 @@ public class CdmInterestAccrualPlugin extends AbstractOperationServicePlugIn imp
DynamicObject currency = feeBill.getDynamicObject("currency");//币种
BigDecimal amountRate = feeBill.getBigDecimal("amountrate");//费率
BigDecimal feeAmt = feeBill.getBigDecimal("payamt");//费用金额
String oppUnitType = feeBill.getString("oppunittype");//对方单位类型
DynamicObject oppUnit = feeBill.getDynamicObject("oppunit");//对方单位
String oppAcctBank = feeBill.getString("oppacctbank");//对方银行账号
DynamicObject oppBeBank = feeBill.getDynamicObject("oppbebank");//对方开户行
// Date 转换为 LocalDate忽略时间部分
LocalDate localIssueDate = issueDate.toInstant()
.atZone(ZoneId.systemDefault())
@ -153,6 +159,7 @@ public class CdmInterestAccrualPlugin extends AbstractOperationServicePlugIn imp
BigDecimal payAmt = feeAmt.multiply(new BigDecimal(term)).multiply(amountRate)
.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);//付息金额
JXBill.set("kdsz_originbillno", originBillNo);//票据单号
JXBill.set("billstatus","A");
JXBill.set("org", org);//业务组织
JXBill.set("kdsz_valuedate", issueDate);//计息开始日
@ -161,6 +168,10 @@ public class CdmInterestAccrualPlugin extends AbstractOperationServicePlugIn imp
JXBill.set("kdsz_currency", currency);//付息币别
JXBill.set("kdsz_feerate", amountRate);//费率
JXBill.set("kdsz_totalamount", payAmt);//付息金额
JXBill.set("kdsz_oppunittype", oppUnitType);//对方单位类型
JXBill.set("kdsz_oppunit", oppUnit);//对方单位名称
JXBill.set("kdsz_oppbankacc", oppAcctBank);//对方银行账号
JXBill.set("kdsz_oppbebank", oppBeBank);//对方开户行
JXBill.set("kdsz_srcentity",FeeBill_KEY);//源单类型
JXBill.set("kdsz_srcbillno",feeBill.getString("billno"));//源单编号
JXBill.set("kdsz_srcbillid",feeBill.getPkValue());//源单id
@ -182,6 +193,7 @@ public class CdmInterestAccrualPlugin extends AbstractOperationServicePlugIn imp
//关联费用明细
DynamicObjectCollection billheadLk = JXBill.getDynamicObjectCollection("billhead_lk");
DynamicObject lk = billheadLk.addNew();
lk.set("seq",1);
lk.set("billhead_lk_stableid",FeeBill_TableID);
lk.set("billhead_lk_sbillid",feeBill.getPkValue());
lk.set("billhead_lk_sid",feeBill.getPkValue());

View File

@ -0,0 +1,274 @@
package kdsz.zyf25.tmc.cfm.plugin.operate;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.botp.runtime.TableDefine;
import kd.bos.entity.operate.result.IOperateInfo;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.args.BeforeOperationArgs;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.i18n.mservice.I18nServiceHelper;
import kd.bos.i18n.mservice.utils.AmountConvertResult;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.sdk.plugin.Plugin;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;
/**
* 单据操作插件
*/
public class InterestAccrualGenPaymentOperationPlugin extends AbstractOperationServicePlugIn implements Plugin {
private static final Logger logger = LoggerFactory.getLogger(InterestAccrualGenPaymentOperationPlugin.class);
private static DynamicObject payBillType = null;//付款单单据类型
private static DynamicObject payType = null;//付款类型
private static DynamicObject settleType = null;//结算方式
private static Long JxBill_TableID = 0L;
static {
TableDefine tableDefine = EntityMetadataCache.loadTableDefine("kdsz_interestaccrual", "kdsz_interestaccrual");
JxBill_TableID = tableDefine.getTableId();
payType = BusinessDataServiceHelper.loadSingle("cas_paymentbilltype"
, new QFilter[]{new QFilter("number", QCP.equals, "999")});
payBillType = BusinessDataServiceHelper.loadSingle("bos_billtype"
, new QFilter[]{new QFilter("number", QCP.equals, "cas_paybill_other_BT_S")});
settleType = BusinessDataServiceHelper.loadSingle("bd_settlementtype"
, new QFilter[]{new QFilter("number", QCP.equals, "JSFS05")});
if (payType == null){
logger.error("未找到编码为【999】的付款类型【其他费用】");
throw new RuntimeException("未找到编码为【999】的付款类型【其他费用】");
}
if (payBillType == null){
logger.error("未找到编码为【cas_paybill_other_BT_S】的付款单类型【其他付款】");
throw new RuntimeException("未找到编码为【cas_paybill_other_BT_S】的付款单类型【其他付款】");
}
if (settleType == null){
logger.error("未找到编码为【JSFS04】的结算方式【电汇财资");
throw new RuntimeException("未找到编码为【JSFS04】的结算方式【电汇财资");
}
}
@Override
public void onAddValidators(AddValidatorsEventArgs e) {
e.addValidator(new AbstractValidator() {
@Override
public void validate() {
ExtendedDataEntity[] extBills = this.getDataEntities();
StringBuilder logInfo = new StringBuilder();
for (ExtendedDataEntity extBill : extBills) {
DynamicObject bill = extBill.getDataEntity();
if (!"C".equals(bill.getString("billstatus"))){
addErrorMessage(extBill, "计息单:"+extBill.getBillNo()+"未审核,不允许下推。\n");
logInfo.append("计息单:").append(extBill.getBillNo()).append("未审核,不允许下推。\n");
continue;
}
String selectRowsStr = this.getOption().getVariableValue(bill.getString("id"));
if (selectRowsStr == null || selectRowsStr.length() == 0){
addErrorMessage(extBill, "计息单:"+extBill.getBillNo()+"请选择要下推的行。\n");
logInfo.append("计息单:").append(extBill.getBillNo()).append("请选择要下推的行。\n");
continue;
}
selectRowsStr = StringUtils.deleteWhitespace(selectRowsStr);
selectRowsStr = selectRowsStr.substring(1, selectRowsStr.length() - 1);
String[] selectRowsArray = selectRowsStr.split(",");
int[] selectRows = new int[selectRowsArray.length];
for (int i = 0; i < selectRows.length; i++) {
selectRows[i] = Integer.parseInt(selectRowsArray[i]);
}
DynamicObjectCollection entries = bill.getDynamicObjectCollection("entryentity");
for (int selectRow : selectRows) {
DynamicObject entry = entries.get(selectRow);
DynamicObject payBill = entry.getDynamicObject("kdsz_e_paybill");
if (payBill != null){
addErrorMessage(extBill, "计息单:"+extBill.getBillNo()+"已生成付款单,不允许下推。\n");
logInfo.append("计息单:").append(extBill.getBillNo()).append("已生成付款单,不允许下推。\n");
}
}
}
if (logInfo.length() > 0){
logger.error(logInfo.toString());
}
}
});
}
@Override
public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
super.beforeExecuteOperationTransaction(e);
DynamicObject[] bills = e.getDataEntities();
for (DynamicObject bill : bills) {
String billNo = bill.getString("billno");
String selectRowsStr = this.getOption().getVariableValue(bill.getString("id"));
selectRowsStr = StringUtils.deleteWhitespace(selectRowsStr);
selectRowsStr = selectRowsStr.substring(1, selectRowsStr.length() - 1);
String[] selectRowsArray = selectRowsStr.split(",");
int[] selectRows = new int[selectRowsArray.length];
for (int i = 0; i < selectRows.length; i++) {
selectRows[i] = Integer.parseInt(selectRowsArray[i]);
}
//生成付款单
OperationResult result = generatePaymentBill(bill,selectRows);
if (result.isSuccess()){
logger.info("------计息单:"+billNo+"生成付款单成功");
writeLkInfo(bill,selectRows,result.getSuccessPkIds().get(0));
}else {
StringBuilder str = new StringBuilder();
str.append("生成付款单失败。");
List<IOperateInfo> allErrorOrValidateInfo = result.getAllErrorOrValidateInfo();
if (allErrorOrValidateInfo != null){
str.append("message\n");
for (IOperateInfo iOperateInfo : allErrorOrValidateInfo) {
str.append(iOperateInfo.getMessage()).append("\n");
}
}
logger.error(str.toString());
e.setCancel( true);
e.setCancelMessage(str.toString());
}
}
}
//生成付款单
private OperationResult generatePaymentBill(DynamicObject JxBill,int[] selectRows){
DynamicObjectCollection jxEntities = JxBill.getDynamicObjectCollection("entryentity");
BigDecimal totalAmt = BigDecimal.ZERO;
DynamicObject currency = JxBill.getDynamicObject("kdsz_currency");//付息币种
DynamicObject payBank = JxBill.getDynamicObject("kdsz_paybank");//付息开户行
DynamicObject payBankAcc = JxBill.getDynamicObject("kdsz_bankaccnum");//付息银行账号
DynamicObject oppBeBank = JxBill.getDynamicObject("kdsz_oppbebank");//对方开户银行
String oppBankAcc = JxBill.getString("kdsz_oppbankacc");//对方银行账号
// String oppUnitType = JxBill.getString("kdsz_oppunittype");//对方单位类型
DynamicObject oppUnit = JxBill.getDynamicObject("kdsz_oppunit");//对方单位
//当前日期
Date currentDate = Date.from(
LocalDate.now().atStartOfDay() // 将LocalDate转换为当天的LocalDateTime (00:00:00)
.atZone(ZoneId.systemDefault()) // 添加系统默认时区得到ZonedDateTime
.toInstant() // 转换为Instant (时间戳)
);
//创建付款单对象
DynamicObject payBill = BusinessDataServiceHelper.newDynamicObject("cas_paybill");
payBill.set("org",JxBill.getDynamicObject("org"));//付款人
payBill.set("billstatus","A");//单据状态
payBill.set("currency",currency);//付款币种
payBill.set("payerbank",payBank);//付款银行
payBill.set("payeracctbank",payBankAcc);//付款银行账号
if (oppBeBank != null){
payBill.set("payeebank",oppBeBank);//收款银行
payBill.set("payeebankname",oppBeBank.getString("name"));//收款银行名称
payBill.set("kdsz_textfield2",oppBeBank.getString("name"));//收款银行账户名称
}
payBill.set("paymenttype",payType);//付款类型
payBill.set("billtype",payBillType);//单据类型
payBill.set("payeetype","other");//收款人类型默认其它
if (oppUnit != null){
payBill.set("payeename",oppUnit.getString("name"));//收款人名称
// payBill.set("payee",supplier.getPkValue());//收款人id
payBill.set("recaccbankname",oppUnit.getString("name"));//收款人实名
}
payBill.set("payeebanknum",oppBankAcc);//收款账号
payBill.set("sourcebilltype",JxBill.getDataEntityType().getName());//源单类型
payBill.set("sourcebillnumber",JxBill.getString("billno"));//源单编号
payBill.set("sourcebillid",JxBill.getPkValue());//源单id
payBill.set("exchangerate",BigDecimal.ONE);//付款汇率
payBill.set("priority","public");//紧急程度 默认普通
payBill.set("paymentchannel","counter");//支付渠道柜台默认
payBill.set("bizdate", currentDate);//业务日期
payBill.set("settletype",settleType);//结算方式
payBill.set("kdsz_czpaystatue","1");//财资付款状态 默认无需推送
DynamicObjectCollection entries = payBill.getDynamicObjectCollection("entry");//付款明细
for (int i = 0; i < selectRows.length; i++) {
DynamicObject jxEntry = jxEntities.get(selectRows[i]);
BigDecimal principal = jxEntry.getBigDecimal("kdsz_e_principal");//付息本金
totalAmt = totalAmt.add(principal);//用于表头金额
DynamicObject entry = entries.addNew();
entry.set("seq",i + 1);
entry.set("e_payableamt",principal);//应付金额
entry.set("e_sourcebillid",JxBill.getPkValue());//源单id
entry.set("e_sourcebillentryid",jxEntry.getPkValue());//源单分录id
// entry.set("e_payablelocamt",principal);//应付折本币
// entry.set("e_actamt",principal);//实付金额
// entry.set("e_localamt",principal);//实付折本币
// entry.set("e_unlockamt",principal);//未锁定金额
// entry.set("e_unsettledamt",principal);//未结算金额
// entry.set("e_unsettledlocalamt",principal);//未结算金额折本币
//关联关系
DynamicObjectCollection entryLks = entry.getDynamicObjectCollection("entry_lk");
DynamicObject entryLk = entryLks.addNew();
entryLk.set("seq",1);
entryLk.set("entry_lk_stableid",JxBill_TableID);
entryLk.set("entry_lk_sbillid",JxBill.getPkValue());
entryLk.set("entry_lk_sid",jxEntry.getPkValue());
}
payBill.set("actpayamt",totalAmt);//付款金额
// payBill.set("unsettleamount",totalAmt);//未结算金额
// payBill.set("unsettleamountbase",totalAmt);//未结算金额本币
//金额大写
String amtStr = totalAmt.toString();
int index = amtStr.indexOf(".");
if (amtStr.length() > index + 2 ) {
String amt = amtStr.substring(0, index + 3);
//金额大写接口
AmountConvertResult zhAmtResult = I18nServiceHelper.amountConvertUppercase("ZH", currency.getString("number"), amt, "false");
if (zhAmtResult.isSuccess()){
String zhAmt = zhAmtResult.getResult();
payBill.set("kdsz_daxiejine1",zhAmt);
}else {
logger.error("金额大写转换失败!\n"+zhAmtResult.getErrorMsg());
throw new RuntimeException("金额大写转换失败!\n"+zhAmtResult.getErrorMsg());
}
}
return OperationServiceHelper.executeOperate("save","cas_paybill", new DynamicObject[]{payBill}, OperateOption.create());
}
//反写关联信息
private void writeLkInfo(DynamicObject JxBill,int[] selectRows, Object successPkId){
DynamicObject payBill = BusinessDataServiceHelper.loadSingle(successPkId, "cas_paybill");
//反写计息单
DynamicObjectCollection jxEntries = JxBill.getDynamicObjectCollection("entryentity");
for (int selectRow : selectRows) {
jxEntries.get(selectRow).set("kdsz_e_paybill",payBill);
}
SaveServiceHelper.update(JxBill);
//反写计息的源单
// TODO: 2025/12/11 暂定为开票登记
// String payableBillSelectStr = "kdsz_payentry.kdsz_interestbillid,kdsz_payentry.kdsz_paylinkentry," +
// "kdsz_payentry.kdsz_paylinkentry.kdsz_paymentbill,kdsz_payentry.kdsz_paylinkentry.seq," +
// "kdsz_payentry.kdsz_paylinkentry.kdsz_paybillid,kdsz_payentry.kdsz_paylinkentry.kdsz_paybillno," +
// "kdsz_payentry.kdsz_paylinkentry.kdsz_netinterestpaid";
// DynamicObject[] payableBills = BusinessDataServiceHelper.load("cdm_payablebill", payableBillSelectStr,
// new QFilter[]{new QFilter("kdsz_payentry.kdsz_interestbillid", QCP.equals, JxBill.getPkValue())});
DynamicObject[] payableBills = BusinessDataServiceHelper.load("cdm_payablebill", "id",
new QFilter[]{new QFilter("kdsz_payentry.kdsz_interestbillid", QCP.equals, JxBill.getPkValue())});
for (int i = 0; i < payableBills.length; i++) {
payableBills[i] = BusinessDataServiceHelper.loadSingle(payableBills[i].getPkValue(), "cdm_payablebill");
DynamicObjectCollection payEntries = payableBills[i].getDynamicObjectCollection("kdsz_payentry");
for (DynamicObject payEntry : payEntries) {
long lk_jxBillId = payEntry.getLong("kdsz_interestbillid");
long JxId = JxBill.getLong("id");
if (lk_jxBillId == JxId){
DynamicObjectCollection payLkEntries = payEntry.getDynamicObjectCollection("kdsz_paylinkentry");
int size = payLkEntries.size();
DynamicObject newLkEntry = payLkEntries.addNew();
newLkEntry.set("seq",size);
newLkEntry.set("kdsz_paymentbill",payBill);
newLkEntry.set("kdsz_paybillno",payBill.getString("billno"));
newLkEntry.set("kdsz_paybillid",payBill.getPkValue());
newLkEntry.set("kdsz_netinterestpaid",payBill.getBigDecimal("actpayamt"));
}
}
}
SaveServiceHelper.save(payableBills);
}
}