收款推送sap优化

This commit is contained in:
yuxueliang0813 2025-04-25 16:10:00 +08:00
parent eb0c2a1604
commit c693cb9006
6 changed files with 126 additions and 104 deletions

View File

@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.entity.MainEntityType;
import kd.bos.entity.datamodel.ListSelectedRowCollection;
import kd.bos.form.control.events.BeforeItemClickEvent;
import kd.bos.list.BillList;
@ -82,15 +81,15 @@ public class RecBillChangeListExtendPlugin extends AbstractListPlugin implements
private void changeBillValidator(BeforeItemClickEvent evt,DynamicObject recBill) {
String billStatus = recBill.getString("billstatus");
String sourceBillType = recBill.getString("sourcebilltype");
// String billStatus = recBill.getString("billstatus");
// String sourceBillType = recBill.getString("sourcebilltype");
String voucherNum = recBill.getString("shjh_vouchernum");
String typeNumber = recBill.getString("receivingtype.number");
String qzState = recBill.getString("shjh_qzzt");
BigDecimal actrecamt = recBill.getBigDecimal("actrecamt");
// 凭证号非空
if (voucherNum == null || voucherNum.trim().isEmpty()) {
if (SapUtils.isEmpty(voucherNum)) {
this.getView().showTipNotification("所选单据不满足变更条件SAP凭证号≠空。");
evt.setCancel(true);
return;
@ -143,9 +142,9 @@ public class RecBillChangeListExtendPlugin extends AbstractListPlugin implements
String billNumber = recBill.getString("billno");
String companyCode = recBill.getString("org.number");
String sapFiscalYear = recBill.getString("shjh_sapfiscalyear");
String sapLineNumber = recBill.getString("shjh_sapline");
String response = SapUtils.querySapClearAccountsState(billNumber, companyCode, voucherNum, sapFiscalYear, sapLineNumber);
// String sapLineNumber = recBill.getString("shjh_sapline");
//此时不传行号给sapsap返回这个凭证下的所有行清账标识我方解析只要有一行是已清账就提示
String response = SapUtils.querySapClearAccountsState(billNumber, companyCode, voucherNum, sapFiscalYear);
if (response != null) {
try {
JSONObject json = JSONObject.parseObject(response);
@ -157,19 +156,30 @@ public class RecBillChangeListExtendPlugin extends AbstractListPlugin implements
JSONObject data = json.getJSONObject("data");
JSONArray itItems = data.getJSONArray("IT_ITEMS");
if (itItems != null && !itItems.isEmpty()) {
JSONObject resultItem = itItems.getJSONObject(0);
if ("y".equalsIgnoreCase(resultItem.getString("ZCLEARED"))) {
this.getView().showTipNotification("所选单据不满足变更条件该单据在SAP已清账。");
evt.setCancel(true);
return;
for (int i = 0; i < itItems.size(); i++) {
JSONObject resultItem = itItems.getJSONObject(i);
if ("y".equalsIgnoreCase(resultItem.getString("ZCLEARED"))) {
this.getView().showTipNotification("该收款单不满足变更条件该收款单对应的凭证已在SAP清账");
evt.setCancel(true);
return;
}
}
}else{
this.getView().showTipNotification("SAP收款凭证清账状态查询接口返回值未包含IT_ITEMS");
evt.setCancel(true);
return;
}
} catch (Exception e) {
logger.error("SAP返回清账状态解析异常" + e.getMessage(), e);
this.getView().showTipNotification("SAP清账状态查询失败无法完成校验。");
logger.error("SAP收款凭证清账状态查询接口解析异常:" + e.getMessage(), e);
this.getView().showTipNotification("SAP收款凭证清账状态查询接口查询失败,无法完成校验");
evt.setCancel(true);
return;
}
}else{
this.getView().showTipNotification("SAP收款凭证清账状态查询接口返回值为空");
evt.setCancel(true);
return;
}
// 是否存在付款申请

View File

@ -145,7 +145,7 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl
JSONArray itItem = getIT_ITEM(recBill);
if (itItem == null){
this.getOperationResult().setSuccess(false);//成功true;失败false
this.getOperationResult().setMessage("凭证不存在或未审核"); // 提示内容
this.getOperationResult().setMessage("金蝶凭证不存在或未审核"); // 提示内容
this.getOperationResult().setShowMessage(true); // 是否显示提示消息
continue;
}
@ -153,8 +153,9 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl
//收款类型=推预付款员工还款需要传清账数据
String receivingType = recBill.getString("receivingtype.number");
if ("103".equals(receivingType) || "109".equals(receivingType)) {
//清账数据参考IT_CLEAR仅清账需要输入
//清账数据参考IT_CLEAR仅清账需要输入且此时清账不需要传入行号
data.put("IT_CLEAR", getIT_CLEAR(recBill));
data.put("I_WHXMH", "X");//是否传入行号为否
}
String type = recBill.getString(RecFieldsInfo.PAYER_TYPE);//付款人类型
long id = recBill.getLong("payer");//付款人id
@ -169,13 +170,15 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl
if (null != response) {
String code = (String) response.get("code");
if ("0".equals(code)) {
//sap接口调用成功
ResponseData responseData = ApiUtils.getResponseData(response);
if (responseData!=null){
if (responseData != null){
//sap结果解析成功并更新收款单
recBill.set("shjh_vouchernum",responseData.getNumber());
recBill.set("shjh_sapfiscalyear",responseData.getYear());
recBill.set("shjh_ispushsap", true);
SaveServiceHelper.update(recBill);
}
recBill.set("shjh_ispushsap", true);
SaveServiceHelper.update(recBill);
}else {
OperateErrorInfo operateErrorInfo = new OperateErrorInfo();
operateErrorInfo.setMessage((String) response.get("msg"));
@ -193,7 +196,6 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl
/**
* 获取SAP凭证头信息
*
* @param recBill 收款单动态对象
* @return 包含凭证头信息的JSONObject
*/
@ -491,23 +493,24 @@ public class RecPushVoucherOperation extends AbstractOperationServicePlugIn impl
private JSONObject createClearItem(DynamicObject entry, String customerNum, String supplierNum, BigDecimal clearAmount) {
JSONObject item = new JSONObject();
// 公共字段设置
item.put("BUKRS", entry.getString("realreccompany.number")); // 公司代码
item.put("BELNR", entry.getString("shjh_entryvouchernum")); // 会计凭证编号
item.put("GJAHR", entry.getString("shjh_entryfiscalyear")); // 会计年度
item.put("BUZEI", entry.getString("shjh_linenumber")); // 行编号
item.put("HKONT", entry.getString("shjh_accountsap.number")); // 总账科目
//公共字段设置
item.put("BUKRS", entry.getString("realreccompany.number"));//公司代码
item.put("BELNR", entry.getString("shjh_verificationnum"));//会计凭证编号-原预付款和借款单的凭证号
item.put("GJAHR", entry.getString("shjh_fiscalyear"));//会计年度-原预付款和借款单的会计年度
//行编号--收款即清账的情况仅限于和费控的预付款和员工还款此时不需要传入行号
// item.put("BUZEI", entry.getString("shjh_linenumber"));
item.put("HKONT", entry.getString("shjh_accountsap.number"));//总账科目
// 客户/供应商编号
item.put("KUNNR", customerNum);
item.put("LIFNR", supplierNum);
// 金额相关字段
item.put("UMSKZ", ""); // 特殊总帐标识
item.put("DMBTR", ""); // 未清金额
// item.put("UMSKZ", ""); // 特殊总帐标识
// item.put("DMBTR", ""); // 未清金额
item.put("DMBTR1", clearAmount != null ? clearAmount.toString() : "0"); // 清账金额
item.put("DMBTR2", ""); // 剩余金额
item.put("ERLKZ", ""); // 已完成的未清项标识符
// item.put("DMBTR2", ""); // 剩余金额
// item.put("ERLKZ", ""); // 已完成的未清项标识符
return item;
}

View File

@ -2,7 +2,6 @@ package shjh.jhzj7.fi.fi.plugin.operate;
import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.formula.RowDataModel;
@ -15,14 +14,11 @@ import kd.bos.entity.validate.AbstractValidator;
import kd.bos.entity.validate.ErrorLevel;
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.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.sdk.plugin.Plugin;
import shjh.jhzj7.fi.fi.utils.ApiUtils;
import shjh.jhzj7.fi.fi.utils.EsbUtils;
import shjh.jhzj7.fi.fi.utils.ObjUtils;
import java.io.IOException;
import java.text.SimpleDateFormat;
@ -36,15 +32,15 @@ public class RecRedPushOperation extends AbstractOperationServicePlugIn implemen
private final static Log logger = LogFactory.getLog(RecRedPushOperation.class);
private static final String INTERFACE_ID ="ReversalVoucher";//识别被调接口并进行路由-SAP反清账
private static final String INTERFACE_ID = "ReversalVoucher";//识别被调接口并进行路由-SAP反清账
private static final String RECEIVER_ID ="SAP";//定义的发送者
private static final String RECEIVER_ID = "SAP";//定义的发送者
private static final String API_URL = System.getProperty("url_a");//sap相关接口地址
/**
* 操作标识
*/
private static final String KEY_RED_PUSH= "redpunch";
private static final String KEY_RED_PUSH = "redpunch";
@Override
public void onPreparePropertys(PreparePropertysEventArgs e) {
@ -115,12 +111,13 @@ public class RecRedPushOperation extends AbstractOperationServicePlugIn implemen
String billNumber = recBill.getString("billno");
HashMap<String, String> responseHead = ApiUtils.buildHead(INTERFACE_ID,RECEIVER_ID);
HashMap<String, Object> responseBody = this.assembleRequest(billNumber, recBill,message);
HashMap<String, Object> responseBody = this.assembleRequest(billNumber, recBill, message);
try {
String response = ApiUtils.sendPost(responseHead, responseBody, API_URL);
if (!response.isEmpty()) {
if (!EsbUtils.isEmpty(response)) {
boolean success = ApiUtils.parseResponse(response, billNumber, responseBody, INTERFACE_ID, message);
if (success){
//TODO sap红冲凭证成功反写sap凭证号和推送标记
recBill.set("shjh_ispushsap",true);
SaveServiceHelper.update(recBill);
}
@ -129,7 +126,7 @@ public class RecRedPushOperation extends AbstractOperationServicePlugIn implemen
message.append("收款处理【").append(billNumber).append("】:").append(ex.getMessage()).append("\n");
logger.info("调用收款红冲凭证接口异常"+message);
}
if (message.length()!=0){
if (message.length() != 0){
OperateErrorInfo operateErrorInfo = new OperateErrorInfo();
operateErrorInfo.setMessage(String.valueOf(message));
operateErrorInfo.setErrorLevel(ErrorLevel.Error.name());
@ -142,11 +139,8 @@ public class RecRedPushOperation extends AbstractOperationServicePlugIn implemen
}
}
/**
* 请求头组装
*
* @param billNumber 单据编号
* @param recBill 收款处理
* @return
@ -162,38 +156,40 @@ public class RecRedPushOperation extends AbstractOperationServicePlugIn implemen
responseBody = new HashMap<>(5);
responseBody.put("rootContextID", rootContextId);
responseBody.put("requestTime", requestTime);
HashMap<String, Object> data = new HashMap<>(10);
List<Map<String, Object>> IT_ITEM = new ArrayList<>();
//用户名
HashMap<String, Object> data = new HashMap<>(1);
List<Map<String, Object>> IT_ITEM = new ArrayList<>(1);
//TODO 用户名-从红冲单上获取人员当前操作人可能是定时任务
DynamicObject userinfo = BusinessDataServiceHelper.loadSingleFromCache(RequestContext.get().getCurrUserId(), "bos_user");
String oaUser = userinfo.getString("shjh_oauser");
//冲销原因
String cause="";
Long id = ObjUtils.getLongSafely(recBill, "sourcebillid");
if (id!=0L){
DynamicObject changeBill = BusinessDataServiceHelper.loadSingle("cas_recchgbill", (new QFilter("sourcebillid", QCP.equals, id).toArray()));
if (null!=changeBill){
cause=changeBill.getString("chgreson");
}
}
DynamicObjectCollection entryCollection = recBill.getDynamicObjectCollection("entry");
if (!entryCollection.isEmpty()){
for (DynamicObject entry : entryCollection) {
Map<String, Object> IT_ITEMS = new HashMap<>(6);
IT_ITEMS.put("BELNR",entry.getString("shjh_verificationnum"));//会计凭证编号
IT_ITEMS.put("BUKRS",entry.getString("realreccompany.number"));//公司代码
IT_ITEMS.put("GJAHR",entry.getString("shjh_fiscalyear"));//会计年度
IT_ITEMS.put("STGRD",cause);//冲销原因
IT_ITEMS.put("UNAME",oaUser);//用户名
IT_ITEMS.put("BUDAT",entry.getDate("shjh_postingdate").toString());//凭证中的过帐日期
IT_ITEM.add(IT_ITEMS);
}
}
// String cause = "";
// Long id = ObjUtils.getLongSafely(recBill, "sourcebillid");
// if (id != 0L){
// DynamicObject changeBill = BusinessDataServiceHelper.loadSingle("cas_recchgbill", (new QFilter("sourcebillid", QCP.equals, id).toArray()));
// if (null != changeBill){
// cause = changeBill.getString("chgreson");
// }
// }
// DynamicObjectCollection entryCollection = recBill.getDynamicObjectCollection("entry");
// if (!entryCollection.isEmpty()){
// for (DynamicObject entry : entryCollection) {
// }
// }
Map<String, Object> IT_ITEMS = new HashMap<>(6);
//红冲所需参数从红字收款单上获取红单上保留了原蓝字收款单的凭证号和会计年度
IT_ITEMS.put("BELNR",recBill.getString("shjh_vouchernum"));//会计凭证编号
IT_ITEMS.put("BUKRS",recBill.getString("org.number"));//公司代码
IT_ITEMS.put("GJAHR",recBill.getString("shjh_sapfiscalyear"));//会计年度
IT_ITEMS.put("STGRD","04");//冲销原因 跨期冲销默认04冲销日期必传
IT_ITEMS.put("UNAME",oaUser);//用户名
SimpleDateFormat sdfdate = new SimpleDateFormat("yyyy-MM-dd");
IT_ITEMS.put("BUDAT",sdfdate.format(new Date()));//凭证中的过帐日期
IT_ITEM.add(IT_ITEMS);
data.put("IT_ITEM", IT_ITEM);
responseBody.put("data", data);
} catch (Exception e) {
message.append("收款处理【").append(billNumber).append("】:").append(e.getMessage()).append("\n");
EsbUtils.saveLog(billNumber, INTERFACE_ID, null, e.getMessage(), false, "ESBPushApi", "数据异常");
EsbUtils.saveLog(billNumber, INTERFACE_ID, null, e.getMessage(), false, KEY_RED_PUSH, "数据异常");
}
return responseBody;
}

View File

@ -29,7 +29,7 @@ public class ClosingStatusValidator extends AbstractValidator {
String type = bill.getString(RecFieldsInfo.PAYER_TYPE);
if ("bd_customer".equals(type) || "bd_supplier".equals(type)){
long id = bill.getLong("payer");
if (0L!=id){
if (0L != id){
DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(id, type);
if (null != dynamicObject){
String name = dynamicObject.getString("group.name");
@ -44,38 +44,47 @@ public class ClosingStatusValidator extends AbstractValidator {
}
}
String voucherNum = bill.getString("shjh_vouchernum");
//如果收款单凭证号不为空
if (!voucherNum.isEmpty()){
//则需要调用SAP收款凭证清账状态查询接口
String billNumber = bill.getString("billno");
String companyCode = bill.getString("org.number");
String sapFiscalYear = bill.getString("shjh_sapfiscalyear");
String sapLineNumber = bill.getString("shjh_sapline");
if (!sapLineNumber.isEmpty() && !sapFiscalYear.isEmpty()){
String response = SapUtils.querySapClearAccountsState(billNumber, companyCode, voucherNum, sapFiscalYear, sapLineNumber);
if (response != null) {
try {
JSONObject json = JSONObject.parseObject(response);
String code = json.getString("code");
if (!"0".equals(code)) {
this.addErrorMessage(dataEntity, "SAP收款凭证清账状态查询接口调用失败错误信息"+json.getString("msg"));
return;
}
JSONObject data = json.getJSONObject("data");
JSONArray itItems = data.getJSONArray("IT_ITEMS");
if (itItems != null && !itItems.isEmpty()) {
JSONObject resultItem = itItems.getJSONObject(0);
//如果已清金蝶系统提示当前经办人不允许提交需要前往SAP处理反清账后再做收款变更
if ("y".equalsIgnoreCase(resultItem.getString("ZCLEARED"))) {
this.addErrorMessage(dataEntity, "提交失败所选单据在SAP已清账需前往SAP处理反清账后再做收款变更。");
}
}
} catch (Exception e) {
logger.error("SAP返回清账状态解析异常" + e.getMessage(), e);
this.addErrorMessage(dataEntity, "SAP清账状态查询失败无法完成校验。");
}
if(SapUtils.isEmpty(voucherNum)){
//如果收款单凭证号为空
this.addErrorMessage(dataEntity, "所选单据不满足变更条件SAP凭证号≠空。");
}
//则需要调用SAP收款凭证清账状态查询接口
String billNumber = bill.getString("billno");
String companyCode = bill.getString("org.number");
String sapFiscalYear = bill.getString("shjh_sapfiscalyear");
// String sapLineNumber = bill.getString("shjh_sapline");
//此时不传行号给sapsap返回这个凭证下的所有行清账标识我方解析只要有一行是已清账就提示
String response = SapUtils.querySapClearAccountsState(billNumber, companyCode, voucherNum, sapFiscalYear);
if (response != null) {
try {
JSONObject json = JSONObject.parseObject(response);
String code = json.getString("code");
if (!"0".equals(code)) {
this.addErrorMessage(dataEntity, "SAP收款凭证清账状态查询接口调用失败错误信息"+json.getString("msg"));
return;
}
JSONObject data = json.getJSONObject("data");
JSONArray itItems = data.getJSONArray("IT_ITEMS");
if (itItems != null && !itItems.isEmpty()) {
for (int i = 0; i < itItems.size(); i++) {
JSONObject resultItem = itItems.getJSONObject(i);
//如果已清金蝶系统提示当前经办人不允许提交需要前往SAP处理反清账后再做收款变更
if ("y".equalsIgnoreCase(resultItem.getString("ZCLEARED"))) {
this.addErrorMessage(dataEntity, "提交失败所选单据在SAP已清账需前往SAP处理反清账后再做收款变更。");
break;
}
}
}else{
this.addErrorMessage(dataEntity, "SAP收款凭证清账状态查询接口返回值未包含IT_ITEMS");
}
} catch (Exception e) {
logger.error("SAP返回清账状态解析异常" + e.getMessage(), e);
this.addErrorMessage(dataEntity, "SAP清账状态查询失败无法完成校验。");
}
}else{
this.addErrorMessage(dataEntity, "SAP收款凭证清账状态查询接口返回值为空");
}
}
}

View File

@ -42,7 +42,7 @@ public class ApiUtils {
.setConnectionTimeToLive(30, TimeUnit.SECONDS)
.setDefaultRequestConfig(RequestConfig.custom()
.setConnectTimeout(5000)
.setSocketTimeout(30000)
.setSocketTimeout(60000)
.build())
.build();

View File

@ -72,6 +72,9 @@ public class SapUtils {
private static final String Apimenthod9 = "费控数据校验";
private static final String interfaceID9 = "GetPaymentInfo";//识别被调接口并进行路由
public static boolean isEmpty(String value) {
return value == null || value.trim().length() <= 0;
}
/**
* SAP应付凭证锁定解锁状态回写
@ -623,10 +626,10 @@ public class SapUtils {
* @param companyCode 公司编码
* @param sapVoucherNumber SAP凭证号
* @param sapFiscalYear 会计年度
* @param sapLineNumber 会计凭证中的行项目数
* sapLineNumber 会计凭证中的行项目号-不传判断所有行
* @return 响应参数
*/
public static String querySapClearAccountsState(String billNumber, String companyCode, String sapVoucherNumber, String sapFiscalYear, String sapLineNumber) {
public static String querySapClearAccountsState(String billNumber, String companyCode, String sapVoucherNumber, String sapFiscalYear) {
try {
StringBuilder message = new StringBuilder();
HashMap<String, String> head = ApiUtils.buildHead(INTERFACE_ID4, RECEIVER_ID4);
@ -636,7 +639,7 @@ public class SapUtils {
item.put("BUKRS", companyCode); // 公司编码
item.put("BELNR", sapVoucherNumber); // SAP凭证号
item.put("GJAHR", sapFiscalYear); // 会计年度
item.put("BUZEI", sapLineNumber); // 行项目号
// item.put("BUZEI", sapLineNumber); // 行项目号
List<Map<String, Object>> items = new ArrayList<>();
items.add(item);
@ -651,7 +654,8 @@ public class SapUtils {
body.put("data", data);
String response = ApiUtils.sendPost(head, body, QUERY_STATE_URL);
if (null != response) {
boolean isSuccess = ApiUtils.parseResponse(response, billNumber, body, API_METHOD4, message);
//解析sap接口返回值并保存日志
ApiUtils.parseResponse(response, billNumber, body, API_METHOD4, message);
// if (isSuccess) {
// return response;
// }