SAP应付凭证定时拉取任务扩展(特定单据类型)

This commit is contained in:
李贵强 2025-10-30 10:11:39 +08:00
parent 2cc0101d74
commit 5caf4c7eea
2 changed files with 730 additions and 6 deletions

View File

@ -0,0 +1,697 @@
package shjh.jhzj7.fi.fi.plugin.task;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.OperateOption;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.operate.OperateOptionConst;
import kd.bos.entity.operate.result.OperationResult;
import kd.bos.exception.KDException;
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.schedule.executor.AbstractTask;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.sdk.plugin.Plugin;
import shjh.jhzj7.fi.fi.utils.EsbUtils;
import shjh.jhzj7.fi.fi.utils.JhzjUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import static shjh.jhzj7.fi.fi.plugin.form.SappzFormPlugin.*;
import static shjh.jhzj7.fi.fi.utils.SapUtils.vouchers_payable;
import static shjh.jhzj7.fi.fi.webapi.ApplyBillControler.*;
/**
* 后台任务插件
*/
public class QuerySapCreatePayApplyExtTask extends AbstractTask implements Plugin {
public static final String apimenthod = "定时调用SAP应付凭证接口生成付款申请单(临期)";//bd_accountview
private final static Log logger = LogFactory.getLog(QuerySapCreatePayApplyExtTask.class);
@Override
public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
// 获取临期天数并转换
String lqBefore = (String) map.get("临期_前");
String lqAfter = (String) map.get("临期_后");
Set<String> filterSet = new HashSet<>();
String filterType = (String) map.get("执行类型");
if (filterType != null && !filterType.trim().isEmpty()) {
// 按分号分割并去除前后空格
String[] types = filterType.split(";");
for (String type : types) {
String trimmedType = type.trim();
if (!trimmedType.isEmpty()) {
filterSet.add(trimmedType);
}
}
}
// 检查是否有有效的临期数据
if (StringUtils.isEmpty(lqBefore) || StringUtils.isEmpty(lqAfter)) {
return;
}
//获取当前日期
LocalDate currentDate = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
int daysBefore = Integer.parseInt(lqBefore);//临期_前
int daysAfter = Integer.parseInt(lqAfter);//临期_后
int totalDays = daysBefore + daysAfter;//总天数
int callInterval = 20; // 调用间隔天数
// 根据总天数和间隔天数计算调用次数向上取整
int callCount = (int) Math.ceil((double) totalDays / callInterval);
// 计算开始日期临期_前表示今天之前的天数
LocalDate startDate = currentDate.minusDays(daysBefore);
// 计算结束日期临期_后表示今天之后的天数
LocalDate endDate = currentDate.plusDays(daysAfter);
JSONArray IT_LIST = new JSONArray(3);
JSONObject result;//sap应付凭证接口返回值
JSONObject sapdata;//sap应付凭证接口返回值data
String formatStartDate; // 开始日期-文本
String formatEndDate; // 结束日期-文本
String record;//日期拼接记录
Map<String, DynamicObject> payapplys;//付款申请单处理结果集
//以调用次数开始循环
for (int i = 1; i <= callCount; i++) {
formatStartDate = startDate.format(formatter);
if(i == callCount){
//如果是最后一次循环结束日期用endDate
formatEndDate = endDate.format(formatter);
}else{
//否则结束日期用开始日期加上间隔天数
formatEndDate = startDate.plusDays(callInterval).format(formatter);
}
IT_LIST.clear();//使用之前先清空
// 添加SAP应付凭到期日过滤条件
addFilterCondition(IT_LIST, "FAEDT", formatStartDate, formatEndDate);
//供应商账户组作为筛选条件此时需要剔除D200 D201两个选项
removeSupplierGroupFilter(IT_LIST);
record = formatStartDate+"临期第"+i+""+formatEndDate;
logger.info(record);
result = vouchers_payable(IT_LIST,record);
if (null != result && result.containsKey("data")) {
// 处理查询结果
sapdata = (JSONObject) result.get("data");
if (null != sapdata && sapdata.containsKey("IT_ITEM")) {
JSONArray IT_ITEMs = (JSONArray) sapdata.get("IT_ITEM");
if (!IT_ITEMs.isEmpty()) {
payapplys = getPayapply(IT_ITEMs,filterSet);
//若多条数据相同,则合并为一条数据处理
OperateOption option = OperateOption.create();
option.setVariableValue(OperateOptionConst.IGNOREWARN, String.valueOf(false)); // 不执行警告级别校验器
String fkBillNum;
String sapuniquevalue;
for (DynamicObject ap_payapply : payapplys.values()) {
fkBillNum = ap_payapply.getString("shjh_vouchernum");//凭证号
sapuniquevalue = ap_payapply.getString("shjh_sapuniquevalue");//凭证唯一码
// 新增数据
OperationResult saveResult = OperationServiceHelper.executeOperate("save", AP_PAYAPPLY, new DynamicObject[]{ap_payapply}, option);
if (!saveResult.isSuccess()) {
handleAndLogError(saveResult, "保存失败", apimenthod, fkBillNum, sapuniquevalue);
continue;
}
OperationResult submitResult = OperationServiceHelper.executeOperate("submit", AP_PAYAPPLY, new DynamicObject[]{ap_payapply}, option);
if (!submitResult.isSuccess()) {
// 提交失败将保存的数据删除,记录日志
OperationServiceHelper.executeOperate("delete", AP_PAYAPPLY, new DynamicObject[]{ap_payapply}, option);
handleAndLogError(submitResult, "提交失败", apimenthod, fkBillNum, sapuniquevalue);
continue;
}
OperationResult auditResult = OperationServiceHelper.executeOperate("audit", AP_PAYAPPLY, new DynamicObject[]{ap_payapply}, option);
if (!auditResult.isSuccess()) {
handleAndLogError(auditResult, "审核失败", apimenthod, fkBillNum, sapuniquevalue);
continue;
}
logger.info("审核成功,凭证号:" + sapuniquevalue);
}
}
}
}
//一次循环结束后开始日期变为加上间隔天数+1后的日期
startDate = startDate.plusDays(callInterval+1);
}
}
//增加供应商账户组的过滤条件剔除这两个选项 D200 D201
private void removeSupplierGroupFilter(JSONArray IT_LIST){
JSONObject jsonObject0 = new JSONObject();
jsonObject0.put("FIELD", "KTOKK"); // 字段名称
jsonObject0.put("SIGN", "E"); // I:包含 E排除
jsonObject0.put("LOW", "D200"); // LOW 枚举字段所代表值的区间开始值
jsonObject0.put("HIGH", "D200"); // HIGH枚举字段所代表值的区间结束值
jsonObject0.put("OPTION", "EQ"); // 默认BT:单条
IT_LIST.add(jsonObject0);
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("FIELD", "KTOKK"); // 字段名称
jsonObject1.put("SIGN", "E"); // I:包含 E排除
jsonObject1.put("LOW", "D201"); // LOW 枚举字段所代表值的区间开始值
jsonObject1.put("HIGH", "D201"); // HIGH枚举字段所代表值的区间结束值
jsonObject1.put("OPTION", "EQ"); // 默认BT:单条
IT_LIST.add(jsonObject1);
}
/**
* 通过SAP接口查询应付凭证数据并生成应付付款申请单
*/
private Map<String, DynamicObject> getPayapply(JSONArray IT_ITEMs,Set<String> filterSet){
Map<String, DynamicObject> bills = new HashMap<>();
JSONObject it_list;//sap单个应付凭证
String shjh_payee = "";//往来类型
String shjh_payeebanknum = "";//往来户名称
// 定义往来类型和对应值的映射
Map<String, String> asstactTypeMap = new HashMap<>();
asstactTypeMap.put("供应商", "bd_supplier");
asstactTypeMap.put("客户", "bd_customer");
String[][] currencyInfo = {
{"paycurrency", "付款币别"},
{"settlecurrency", "结算币别"}
};
//常量字段处理
DynamicObject ds_paytype = BusinessDataServiceHelper.loadSingle(CAS_PAYMENTBILLTYPE,
new QFilter[]{new QFilter("name", QCP.equals, "对私付款")});
DynamicObject dg_paytype = BusinessDataServiceHelper.loadSingle(CAS_PAYMENTBILLTYPE,
new QFilter[]{new QFilter("name", QCP.equals, "对公付款")});
DynamicObject default_settletype = BusinessDataServiceHelper.loadSingle("bd_settlementtype",
new QFilter[]{new QFilter("number", QCP.equals, "T")});//银企直连
//单据类型
DynamicObject billtype = BusinessDataServiceHelper.loadSingle(BOS_BILLTYPE,
new QFilter[]{new QFilter("name", QCP.equals, "其他付款申请")});
//汇率表
DynamicObject exrate = BusinessDataServiceHelper.loadSingle(BD_EXRATETABLE,
new QFilter[]{new QFilter("number", QCP.equals, "ERT-01")});
for (Object itItem : IT_ITEMs) {
it_list = (JSONObject) itItem;
String uuid = it_list.getString("XBLNR");//单据号
// 判断uuid是否包含filterSet中的任何字符串
boolean shouldSkip = false;
for (String filter : filterSet) {
if (uuid.contains(filter)) {
shouldSkip = true;
break;
}
}
if (!shouldSkip) {
continue; // 跳过当前循环
}
String bukrs = it_list.getString("BUKRS");//公司编号
String fkBillNum = it_list.getString("BELNR");//凭证号
String gjahr = it_list.getString("GJAHR");//会计年度
String accountingsubject = it_list.getString("HKONT");//会计科目
String ebelp = it_list.getString("BUZEI");//会计科目行项目号
BigDecimal wrbtr = new BigDecimal(it_list.getString("WRBTR"));//未清金额
//汇率
BigDecimal KURSF = new BigDecimal(it_list.getString("KURSF"));
if (KURSF.compareTo(BigDecimal.ZERO) == 0) {
KURSF = BigDecimal.ONE;
}
BigDecimal dmbtr = new BigDecimal(it_list.getString("DMBTR"));//申请金额折结算币别
Date FAEDTs = null;//到期日,净价到期日
String FAEDT = it_list.getString("FAEDT");
if (StringUtils.isNotEmpty(FAEDT)) {
FAEDTs = StrToDate(FAEDT);
}
Date BUDATs = null;//记账日期,凭证中的过帐日期
String BUDAT = it_list.getString("BUDAT");
if (StringUtils.isNotEmpty(BUDAT)) {
BUDATs = StrToDate(BUDAT);
}
Date BLDATs = null;//凭证日期,凭证中的凭证日期
String BLDAT = it_list.getString("BLDAT");
if (StringUtils.isNotEmpty(BLDAT)) {
BLDATs = StrToDate(BLDAT);
}
Date ZFBDTs = null;//基准日期,用于到期日计算的基准日期
String ZFBDT = it_list.getString("ZFBDT");
if (StringUtils.isNotEmpty(ZFBDT)) {
ZFBDTs = StrToDate(ZFBDT);
}
String kunnr = it_list.getString("KUNNR");//客户员工
String lifnr = it_list.getString("LIFNR");//供应商
if (StringUtils.isNotEmpty(kunnr)) {
shjh_payee = "客户";
shjh_payeebanknum = kunnr;
} else {
shjh_payee = "供应商";
shjh_payeebanknum = lifnr;
}
String assacct = it_list.getString("BVTYP");//合作银行类型
//原因码
String reasoncode =it_list.getString("RSTGR");
//todo:资金计划分类
// String zreqDept = it_list.getString("ZREQ_DEPT");//二级部门
String procurementeam = it_list.getString("EKGRP");//采购组
String isselfprocurment = it_list.getString("ZZXCG_FLAG");//是否自行采购
String waers = it_list.getString("WAERS");//付款币别编号CNY,货币码 && 结算币别编号,货币码
String paymentterms = it_list.getString("ZTERM");// 付款条件_付款条件代码
String refertoinvoicenumber = it_list.getString("XBLNR");// 参照发票号
// 公司编号 bukrs
QFilter Q1 = new QFilter("number", QCP.equals, bukrs);
DynamicObject org = BusinessDataServiceHelper.loadSingle(orgEntName, new QFilter[]{Q1});
if(org == null){
logger.error("同步失败,凭证号:" + fkBillNum + "的公司未在金蝶找到对应公司");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,SAP的公司未在金蝶找到对应公司", false, "API");
continue;
}
// 申请金额 , 汇率 , 申请金额折结算币别
BigDecimal amount = BigDecimal.ZERO;
// 未清金额 amount
try {
wrbtr = wrbtr.setScale(2, RoundingMode.HALF_UP);
amount = wrbtr;
} catch (NumberFormatException e) {
logger.error("未清金额格式错误", e.getMessage());
continue;
}
// 往来类型 shjh_payee
// 往来户 party
QFilter Q3 = new QFilter("number", QCP.equals, shjh_payeebanknum);
DynamicObject party = "供应商".equals(shjh_payee)
? BusinessDataServiceHelper.loadSingle(BD_SUPPLIER, new QFilter[]{Q3})
: BusinessDataServiceHelper.loadSingle(BD_CUSTOMER, new QFilter[]{Q3});
if(party == null){
logger.error("同步失败,凭证号:" + fkBillNum + "的客商未在金蝶找到对应数据");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,SAP的客商未在金蝶找到对应数据", false, "API");
continue;
}
// 新增应付付款申请单
DynamicObject ap_payapply = BusinessDataServiceHelper.newDynamicObject(AP_PAYAPPLY);
//防重校验条件1根据入参中的应付凭证ID作为唯一值去金蝶的付款申请单中查找有无此记录如果有且单据中SAP锁定
// 状态为已锁定则校验失败记录日志数据库层面将应付凭证ID建立唯一约束
QFilter Q4 = new QFilter("shjh_vouchernum", QCP.equals, fkBillNum);//凭证号
QFilter Q5 = new QFilter("applyorg.number", QCP.equals, bukrs);
QFilter Q6 = new QFilter("shjh_voucheryear", QCP.equals, gjahr);//会计年度
QFilter Q7 = new QFilter("shjh_voucherentrynum", QCP.equals, ebelp);//会计科目行项目号
DynamicObject ap_payapplys = BusinessDataServiceHelper.loadSingle(AP_PAYAPPLY, new QFilter[]{Q4, Q5, Q6, Q7});
if (null != ap_payapplys) {
boolean shjhSapwhetherlocking = ap_payapplys.getBoolean("shjh_sapwhetherlocking");//SAP是否锁定
if (shjhSapwhetherlocking) {
logger.error("同步失败,凭证号:" + fkBillNum + "的单据SAP已锁定");
continue;
} else {
//存在付款申请单且单据中SAP锁定状态为未锁定,更新数据
ap_payapply = ap_payapplys;
}
}
ap_payapply.set("settleorg", org); // 结算组织
ap_payapply.set("applyorg", org); // 申请组织
ap_payapply.set("payorg", org); // 付款组织
ap_payapply.set("purorg", org); // 采购组织
// 申请日期
ap_payapply.set("applydate", BUDATs);
//SAP会计科目
if (accountingsubject != null && !accountingsubject.isEmpty()) {
QFilter Q8 = new QFilter("number", QCP.equals, accountingsubject);//会计科目编号
Q8.and("createorg.id", QCP.equals, org.getPkValue());//当前公司ID
//如果当前数据中心是测试的则使用测试库科目表ID否则用正式的
if("2162562979827025920".equals(RequestContext.get().getAccountId())){
Q8.and("accounttable.id", QCP.equals, 2125524820924832768L);//测试科目表
}else{
Q8.and("accounttable.id", QCP.equals, EsbUtils.ACCTABLE);//正式科目表
}
DynamicObject accountview = BusinessDataServiceHelper.loadSingle(BD_ACCOUNTVIEW, Q8.toArray());
if(accountview == null){
logger.error("同步失败,凭证号:" + fkBillNum + "的SAP会计科目在金蝶中未找到对应科目");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,SAP会计科目在金蝶中未找到对应科目", false, "API");
continue;
}
ap_payapply.set("shjh_sapkjkm", accountview);
}else{
logger.error("同步失败,凭证号:" + fkBillNum + "的SAP会计科目为空");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,SAP会计科目为空", false, "API");
continue;
}
ap_payapply.set("applycause", "");//请款事由
//币别-处理
for (String[] info : currencyInfo) {
String currencyType = info[0];
// String currencyTypeName = info[1];
// 根据币别类型从 applybill 获取对应的币别编号
String currencyNumber = waers;
if ("RMB".equals(currencyNumber)) {
currencyNumber = "CNY";
}
QFilter filter = new QFilter("number", QCP.equals, currencyNumber);
DynamicObject currency = BusinessDataServiceHelper.loadSingle(BD_CURRENCY, new QFilter[]{filter});
ap_payapply.set(currencyType, currency);
}
//汇率
try {
KURSF = KURSF.setScale(5, RoundingMode.HALF_UP);
ap_payapply.set("exchangerate", KURSF);
} catch (NumberFormatException e) {
logger.error("同步失败,凭证号:" + fkBillNum + "的汇率处理异常");
continue;
}
//申请金额折结算币别
try {
dmbtr = dmbtr.setScale(2, RoundingMode.HALF_UP);
ap_payapply.set("appseleamount", dmbtr);
} catch (NumberFormatException e) {
logger.error("同步失败,凭证号:" + fkBillNum + "的申请金额折结算币别处理异常");
continue;
}
DynamicObjectCollection entry = ap_payapply.getDynamicObjectCollection("entry");//明细
entry.clear();
DynamicObject ap_payapply_entry = entry.addNew();
// 根据往来类型设置值
ap_payapply_entry.set("e_asstacttype", asstactTypeMap.get(shjh_payee));
// 往来户
ap_payapply_entry.set("e_asstact", party);
//如果往来户为供应商,才会有往来账户和银行,根据供应商银行分录里面的合作银行类型来确定往来账户和银行
//往来账户 && 往来银行
if ("供应商".equals(shjh_payee)) {
DynamicObjectCollection bankentrys = party.getDynamicObjectCollection("entry_bank");//银行信息分录
if (!bankentrys.isEmpty()) {
boolean ispp = false;//sap合作银行类型是否与金蝶供应商银行账号匹配
//如果sap的合作银行类型为空再判断供应商银行分录是否只有一个只有一个时携带此银行
if(EsbUtils.isEmpty(assacct) && bankentrys.size() == 1){
DynamicObject bankentry = bankentrys.get(0);
String bankaccount = bankentry.getString("bankaccount");
DynamicObject bank = bankentry.getDynamicObject("bank");
String accountname = bankentry.getString("accountname");
// 检查银行账号,开户银行,账户名称是否为空
if (bankaccount == null || bankaccount.trim().isEmpty()) {
logger.error("同步失败,凭证号:" + fkBillNum + "的银行账号为空(供应商)");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的银行账号为空(供应商)", false, "API");
continue;
}
if (null == bank) {
logger.error("同步失败,凭证号:" + fkBillNum + "的开户银行为空(供应商)");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的开户银行为空(供应商)", false, "API");
continue;
}
if (accountname == null || accountname.trim().isEmpty()) {
logger.error("同步失败,凭证号:" + fkBillNum + "的账户名称为空(供应商)");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的账户名称为空(供应商)", false, "API");
continue;
}
//20250814开发培训时沟通判断银行的账号状态如果是E 则代表已被sap删了不可使用
if("E".equalsIgnoreCase(bankentry.getString("shjh_bankstatus"))){
logger.error("同步失败,凭证号:" + fkBillNum + "的账户状态为E不可使用");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的账户状态为E不可使用", false, "API");
continue;
}
ap_payapply_entry.set("e_assacct", bankaccount);//银行账号
ap_payapply_entry.set("e_bebank", bank);//开户银行
ap_payapply_entry.set("shjh_asstactrealname", accountname);//账户名称
ispp = true;
}else if(!EsbUtils.isEmpty(assacct)){
for (DynamicObject bankentry : bankentrys) {
if (assacct.equals(bankentry.getString("shjh_banktype"))) {
String bankaccount = bankentry.getString("bankaccount");
DynamicObject bank = bankentry.getDynamicObject("bank");
String accountname = bankentry.getString("accountname");
// 检查银行账号,开户银行,账户名称是否为空
if (bankaccount == null || bankaccount.trim().isEmpty()) {
logger.error("同步失败,凭证号:" + fkBillNum + "的银行账号为空(供应商)");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的银行账号为空(供应商)", false, "API");
continue;
}
if (null == bank) {
logger.error("同步失败,凭证号:" + fkBillNum + "的开户银行为空(供应商)");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的开户银行为空(供应商)", false, "API");
continue;
}
if (accountname == null || accountname.trim().isEmpty()) {
logger.error("同步失败,凭证号:" + fkBillNum + "的账户名称为空(供应商)");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的账户名称为空(供应商)", false, "API");
continue;
}
//20250814开发培训时沟通判断银行的账号状态如果是E 则代表已被sap删了不可使用
if("E".equalsIgnoreCase(bankentry.getString("shjh_bankstatus"))){
logger.error("同步失败,凭证号:" + fkBillNum + "的账户状态为E不可使用");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的账户状态为E不可使用", false, "API");
continue;
}
ap_payapply_entry.set("e_assacct", bankaccount);//银行账号
ap_payapply_entry.set("e_bebank", bank);//开户银行
ap_payapply_entry.set("shjh_asstactrealname", accountname);//账户名称
ispp = true;
break;
}
}
}
if (!ispp) {
logger.error("同步失败,凭证号:" + fkBillNum + "的合作银行类型无匹配数据(供应商)");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的合作银行类型无匹配数据(供应商)", false, "API");
continue;
}
}else {
logger.error("同步失败,凭证号:" + fkBillNum + "的供应商不存在银行信息");
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "同步失败,凭证号:" + fkBillNum + "的供应商不存在银行信息", false, "API");
continue;
}
}else {
//客户 默认取第一行银行信息
DynamicObjectCollection entryBank = party.getDynamicObjectCollection("entry_bank");
if (!entryBank.isEmpty()) {
DynamicObject bankentry = entryBank.get(0);
String bankaccount = bankentry.getString("bankaccount");//银行账号
DynamicObject bank = bankentry.getDynamicObject("bank");//开户银行
String accountname = bankentry.getString("accountname");//账户名称
ap_payapply_entry.set("e_assacct", bankaccount);//银行账号
ap_payapply_entry.set("e_bebank", bank);//开户银行
ap_payapply_entry.set("shjh_asstactrealname", accountname);//账户名称
}
}
//到期日
ap_payapply_entry.set("e_duedate", FAEDTs);
//分录申请金额
ap_payapply_entry.set("e_applyamount", amount);
//分录申请金额折结算币
ap_payapply_entry.set("e_appseleamount", dmbtr);
//表头申请金额
ap_payapply.set("applyamount", amount);
//凭证抬头文本
ap_payapply.set("shjh_voucherheadertext", it_list.getString("BKTXT"));
//付款类型:对公付款对私付款SAP科目编号1221020200 对私付款费控劳务人员报销单 对私付款其他均赋值为对公付款
if ("1221020200".equals(accountingsubject)) {
ap_payapply_entry.set("e_paymenttype", ds_paytype);//对私付款
} else {
ap_payapply_entry.set("e_paymenttype", dg_paytype);//对公付款
}
//------------------------------默认字段--------------------------------
ap_payapply.set("billtype", billtype);//单据类型
ap_payapply.set("exratetable", exrate);//汇率表
ap_payapply.set("billstatus", "A");//状态:暂存
//select * from t_ap_applypaybill where fid = 2148014743875508224 or fid = 2148018902158815232
//单头:申请人,approvalamount(核准金额),aprseleamount(核准金额折结算币),paystatus(付款状态),freezestate(冻结状态),
// quotation(换算方式),billsrctype(单据来源类型)
//申请人
long currUserId = RequestContext.get().getCurrUserId();//当前用户 creator
ap_payapply.set("creator", currUserId);
// 核准金额
ap_payapply.set("approvalamount", amount);
// 核准金额折结算币
ap_payapply.set("aprseleamount", dmbtr);//Unpaid
// 付款状态
ap_payapply.set("paystatus", "Unpaid");//未付款
// 冻结状态
ap_payapply.set("freezestate", "unfreeze");//未冻结
// 换算方式
ap_payapply.set("quotation", "0");//直接汇率
// 单据来源类型
ap_payapply.set("billsrctype", "2");//后台生成
//select * from t_ap_applypaybillentry where fid = 2148014743875508224 or fid = 2148018902158815232
//明细:seq,e_approvedamt(核准金额),e_approvedseleamt(核准金额折结算币),e_corebilltype(核心单据类型),e_freezestate(冻结状态),
// e_creator(创建人),e_closestatus(行关闭状态)
// 序号
ap_payapply_entry.set("seq", 1);
// 核准金额
ap_payapply_entry.set("e_approvedamt", amount);
// 核准金额折结算币
ap_payapply_entry.set("e_approvedseleamt", dmbtr);
// 核心单据类型
ap_payapply_entry.set("e_corebilltype", "pm_purorderbill");//采购订单
// 冻结状态
ap_payapply_entry.set("e_freezestate", "unfreeze");//未冻结
// 创建人
ap_payapply_entry.set("e_creator", currUserId);
// 行关闭状态
ap_payapply_entry.set("e_closestatus", "A");//正常
//SAP应付凭证号
ap_payapply.set("shjh_vouchernum", fkBillNum);
//SAP应付凭证行号
ap_payapply.set("shjh_voucherentrynum", ebelp);
//SAP应付凭证会计年度
ap_payapply.set("shjh_voucheryear", gjahr);
//采购组
ap_payapply.set("shjh_procurementteam", procurementeam);
//是否自行采购
ap_payapply.set("shjh_zxcg", isselfprocurment);
//原因码
if (reasoncode != null && !reasoncode.isEmpty()) {
QFilter Q11 = new QFilter("number", QCP.equals, reasoncode);
DynamicObject cause = BusinessDataServiceHelper.loadSingle(GL_CASHFLOWITEM, new QFilter[]{Q11});
ap_payapply.set("shjh_yym", cause);
}
//过账日期(记账)
ap_payapply.set("shjh_bookkeepingdate", BUDATs);
//凭证日期
ap_payapply.set("shjh_documentdate", BLDATs);
//结算方式-先设置一个默认值 银企直连然后根据供应商分录判断重新赋值
ap_payapply_entry.set("e_settlementtype", default_settletype);
if ("供应商".equals(shjh_payee)) {
DynamicObjectCollection shjhEntrySap = party.getDynamicObjectCollection("shjh_entry_sap");
if (!shjhEntrySap.isEmpty()) {
for (DynamicObject object : shjhEntrySap) {
if (org.getString("number").equals(object.getString("shjh_companynum"))) {
// 结算方式(付款方式)
DynamicObject settlementtype = BusinessDataServiceHelper.loadSingle("bd_settlementtype",
new QFilter[]{new QFilter("number", QCP.equals, object.getString("shjh_settlementmethod"))});
if (settlementtype != null) {
ap_payapply_entry.set("e_settlementtype", settlementtype);
break;
}
}
}
}
}
ap_payapply.set("shjh_fkdjbh", uuid);
String bizbig = it_list.getString("ZYWDLCODE");//业务大类编
String bizsmall = it_list.getString("ZYWXLCODE");//业务小类编码
//业务大类业务小类
if (kd.bos.util.StringUtils.isNotEmpty(bizbig)) {
DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle("shjh_bizbigtype", new QFilter[]{new QFilter("shjh_fknumber", QCP.equals, bizbig)});
ap_payapply.set("shjh_bizbig", dynamicObject);
}
if (kd.bos.util.StringUtils.isNotEmpty(bizsmall)) {
DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle("shjh_bizsmalltype", new QFilter[]{new QFilter("shjh_fknumber", QCP.equals, bizsmall)});
ap_payapply.set("shjh_basedatafield", dynamicObject);
}
String department = it_list.getString("ZREQ_DEPT");//部门编号
if (kd.bos.util.StringUtils.isNotEmpty(department)) {
DynamicObject adminorg = BusinessDataServiceHelper.loadSingle("bos_adminorg",
new QFilter[]{new QFilter("number", QCP.equals, department)});
ap_payapply.set("shjh_secondarydept", adminorg);
}
// 设置付款类型 外部系统单据类型
setPaymentType(ap_payapply, uuid, dg_paytype, ds_paytype);
//凭证类型
String blart = it_list.getString("BLART");
if (kd.bos.util.StringUtils.isNotEmpty(blart)) {
DynamicObject vouchertype = BusinessDataServiceHelper.loadSingle("gl_vouchertype",
new QFilter[]{new QFilter("number", QCP.equals, blart)});
ap_payapply.set("shjh_documenttype", vouchertype);//凭证类型
}
//基准日期
ap_payapply.set("shjh_basedate", ZFBDTs);
//付款条件
ap_payapply.set("shjh_fktj", paymentterms);
//参照发票号
ap_payapply.set("shjh_czfph", refertoinvoicenumber);
//来源系统
ap_payapply.set("shjh_sourcesystem", "A");//SAP
//到期日
ap_payapply.set("shjh_duedate", FAEDTs);
//SAP应付凭证ID:金蝶组装公司编号+SAP应付凭证会计年度+SAP应付凭证号+SAP应付凭证行号
ap_payapply.set("shjh_sapuniquevalue", bukrs + gjahr + fkBillNum + ebelp);
bills.put(ap_payapply.getString("shjh_sapuniquevalue"), ap_payapply);
//付款申请单校验成功保存日志后续单子保存提交审核没问题的话不再记录日志
JhzjUtils.saveLog(fkBillNum, apimenthod, it_list.toJSONString(), "校验成功", true, "API");
}
return bills;
}
private void setPaymentType(DynamicObject ap_payapply, String uuid, DynamicObject paytype_g, DynamicObject paytype_s){
//根据单据号 uuid 判断
DynamicObjectCollection entry = ap_payapply.getDynamicObjectCollection("entry");
//付款类型 外部系统单据类型
if (uuid.contains("JKY")) {
ap_payapply.set("shjh_externalsystemdocume","A");//员工借款单
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_s);//对私
}
}else if (uuid.contains("TYB")) {
ap_payapply.set("shjh_externalsystemdocume","B");//通用报销单
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_s);//对私
}
}else if (uuid.contains("CLB")) {
ap_payapply.set("shjh_externalsystemdocume","C");//差旅报销单
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_s);//对私
}
}else if (uuid.contains("LWB")) {
ap_payapply.set("shjh_externalsystemdocume","D");//劳务人员报销单
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_s);//对私
}
}else if (uuid.contains("YFK")) {
ap_payapply.set("shjh_externalsystemdocume","E");//预付款单
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_g);//对公
}
}else if (uuid.contains("JCW")) {
ap_payapply.set("shjh_externalsystemdocume","F");//请款单无订单
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_g);//对公
}
}else if (uuid.contains("FWK")) { //服务付款单
ap_payapply.set("shjh_externalsystemdocume","G");
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_g);//对公
}
}else if (uuid.contains("TFK")) {
ap_payapply.set("shjh_externalsystemdocume","I");//其他付款单
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_g);//对公
}
}else if (uuid.contains("SPA")) {
ap_payapply.set("shjh_externalsystemdocume","J");//SPA会员退卡申请单
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_g);//对公
}
}else if (uuid.contains("JCH")) {
// ap_payapply.set("shjh_externalsystemdocume","JC");//TPM_请款单
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_g);//对公JKY0000001
}
}else if (uuid.contains("TYH")) { //TPM_通用报销单
// ap_payapply.set("shjh_externalsystemdocume","TY");
if (!entry.isEmpty()) {
entry.get(0).set("e_paymenttype", paytype_s);//对私
}
}
}
}

View File

@ -24,9 +24,7 @@ import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.*;
import static shjh.jhzj7.fi.fi.plugin.form.SappzFormPlugin.*;
import static shjh.jhzj7.fi.fi.utils.SapUtils.vouchers_payable;
@ -34,6 +32,7 @@ import static shjh.jhzj7.fi.fi.webapi.ApplyBillControler.*;
/**
* 定时调用SAP应付凭证接口生成付款申请单过滤参数仅为临期
* 全量类型执行
*/
public class QuerySapCreatePayApplyTask extends AbstractTask {
@ -45,6 +44,20 @@ public class QuerySapCreatePayApplyTask extends AbstractTask {
// 获取临期天数并转换
String lqBefore = (String) map.get("临期_前");
String lqAfter = (String) map.get("临期_后");
Set<String> filterSet = new HashSet<>();
String filterType = (String) map.get("不执行类型");
if (filterType != null && !filterType.trim().isEmpty()) {
// 按分号分割并去除前后空格
String[] types = filterType.split(";");
for (String type : types) {
String trimmedType = type.trim();
if (!trimmedType.isEmpty()) {
filterSet.add(trimmedType);
}
}
}
// 检查是否有有效的临期数据
if (StringUtils.isEmpty(lqBefore) || StringUtils.isEmpty(lqAfter)) {
return;
@ -94,7 +107,7 @@ public class QuerySapCreatePayApplyTask extends AbstractTask {
if (null != sapdata && sapdata.containsKey("IT_ITEM")) {
JSONArray IT_ITEMs = (JSONArray) sapdata.get("IT_ITEM");
if (!IT_ITEMs.isEmpty()) {
payapplys = getPayapply(IT_ITEMs);
payapplys = getPayapply(IT_ITEMs,filterSet);
//若多条数据相同,则合并为一条数据处理
OperateOption option = OperateOption.create();
option.setVariableValue(OperateOptionConst.IGNOREWARN, String.valueOf(false)); // 不执行警告级别校验器
@ -153,7 +166,7 @@ public class QuerySapCreatePayApplyTask extends AbstractTask {
/**
* 通过SAP接口查询应付凭证数据并生成应付付款申请单
*/
private Map<String, DynamicObject> getPayapply(JSONArray IT_ITEMs){
private Map<String, DynamicObject> getPayapply(JSONArray IT_ITEMs,Set<String> filterSet){
Map<String, DynamicObject> bills = new HashMap<>();
JSONObject it_list;//sap单个应付凭证
String shjh_payee = "";//往来类型
@ -182,6 +195,21 @@ public class QuerySapCreatePayApplyTask extends AbstractTask {
for (Object itItem : IT_ITEMs) {
it_list = (JSONObject) itItem;
String uuid = it_list.getString("XBLNR");//单据号
// 判断uuid是否包含filterSet中的任何字符串
boolean shouldSkip = false;
for (String filter : filterSet) {
if (uuid.contains(filter)) {
shouldSkip = true;
break;
}
}
if (shouldSkip) {
continue; // 跳过当前循环
}
String bukrs = it_list.getString("BUKRS");//公司编号
String fkBillNum = it_list.getString("BELNR");//凭证号
String gjahr = it_list.getString("GJAHR");//会计年度
@ -573,7 +601,6 @@ public class QuerySapCreatePayApplyTask extends AbstractTask {
}
}
}
String uuid = it_list.getString("XBLNR");//单据号
ap_payapply.set("shjh_fkdjbh", uuid);
String bizbig = it_list.getString("ZYWDLCODE");//业务大类编
String bizsmall = it_list.getString("ZYWXLCODE");//业务小类编码