diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/operate/PaybillPushSapOperation.java b/main/java/shjh/jhzj7/fi/fi/plugin/operate/PaybillPushSapOperation.java index 9d8a2b5..53a4c4f 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/operate/PaybillPushSapOperation.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/PaybillPushSapOperation.java @@ -20,14 +20,15 @@ import kd.bos.servicehelper.operation.SaveServiceHelper; import kd.bos.util.StringUtils; 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.JhzjUtils; import shjh.jhzj7.fi.fi.utils.SysUtils; import shjh.jhzj7.fi.fi.utils.domin.ResponseData; +import java.io.IOException; import java.math.BigDecimal; import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; import static shjh.jhzj7.fi.fi.utils.SapUtils.*; @@ -35,10 +36,16 @@ import static shjh.jhzj7.fi.fi.utils.SapUtils.*; /** * 付款单推送SAP凭证操作插件 * shjh_cas_paybill_ext + * 0801增加sap凭证红冲处理 */ public class PaybillPushSapOperation extends AbstractOperationServicePlugIn implements Plugin { private static final String userName = "bos_user";//用户 + private static final String INTERFACE_ID = "ReversalVoucher";//识别被调接口并进行路由-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";//sap红冲凭证的操作标记 @Override public void onAddValidators(AddValidatorsEventArgs e) { @@ -78,6 +85,18 @@ public class PaybillPushSapOperation extends AbstractOperationServicePlugIn impl } } } + }else if(KEY_RED_PUSH.equals(operateKey)){ + //sap凭证红冲处理 前置校验 + ExtendedDataEntity[] entities = this.getDataEntities(); + for (ExtendedDataEntity entity : entities) { + DynamicObject prinfo = entity.getDataEntity(); + prinfo = BusinessDataServiceHelper.loadSingle(prinfo.getPkValue(), "cas_paybill"); + //判断付款处理单是否已生成金蝶凭证 + if(!prinfo.getBoolean("shjh_ispushsap")){ + this.addErrorMessage(entity, "未推送过SAP,无需红冲"); + return; + } + } } } }); @@ -820,9 +839,136 @@ public class PaybillPushSapOperation extends AbstractOperationServicePlugIn impl this.operationResult.addErrorInfo(operateErrorInfo); } } + }else if(KEY_RED_PUSH.equals(operationKey)){ + //sap凭证红冲处理 + DynamicObject[] dos = e.getDataEntities(); + DynamicObject prinfo = null;//付款处理单 + JSONObject sapReturnData; + String billNumber; + StringBuilder message = new StringBuilder(); + for (int i = 0; i < dos.length; i++) { + prinfo = BusinessDataServiceHelper.loadSingle(dos[i].getPkValue(), dos[i].getDataEntityType().getName()); + if(prinfo.getBoolean("shjh_ispushsap")){ + //如果付款处理单已推送sap才需要红冲 + billNumber = prinfo.getString("billno");//单号 + HashMap responseHead = ApiUtils.buildHead(INTERFACE_ID,RECEIVER_ID); + HashMap responseBody = this.assembleRequest(billNumber, prinfo, message); + try { + String response = ApiUtils.sendPost(responseHead, responseBody, API_URL); + if (!EsbUtils.isEmpty(response)) { + boolean success = ApiUtils.parseResponse(response, billNumber, responseBody, "SAP反清账或冲销", message); + if (success){ + //sap红冲凭证成功,反写sap凭证号和推送标记 + sapReturnData = JSONObject.parseObject(response); + JSONObject data = sapReturnData.getJSONObject("data"); + JSONArray rows = data.getJSONArray("IT_ITEM"); + JSONObject resultData = rows.getJSONObject(0); + String key = resultData.getString("OBJ_KEY"); + if(EsbUtils.isEmpty(key)){ + message.append("付款处理【").append(billNumber).append("】:").append("SAP返回的OBJ_KEY为空").append("\n"); + }else{ + //sap红冲凭证号根据返回值更新 + prinfo.set("shjh_hcsappzh",key.length() >= 10 ? key.substring(0, 10) : key); + prinfo.set("shjh_ispushsap",false);//sap已推送标记-置为false,让后续可以再推蓝字凭证 + prinfo.set("shjh_credentialnum",null);//sap凭证号置为空 + prinfo.set("shjh_sapfiscalyear",null);//sap年度置为空 + SaveServiceHelper.update(prinfo); + } + } + }else{ + message.append("付款处理【").append(billNumber).append("】:").append("SAP返回值为空").append("\n"); + } + } catch (IOException ex) { + message.append("付款处理【").append(billNumber).append("】:").append(ex.getMessage()).append("\n"); +// logger.info("调用付款红冲凭证接口异常"+message); + } + } + } + if (message.length() != 0){ + OperateErrorInfo operateErrorInfo = new OperateErrorInfo(); + operateErrorInfo.setMessage(String.valueOf(message)); + operateErrorInfo.setErrorLevel(kd.bos.entity.validate.ErrorLevel.Error.name()); + operateErrorInfo.setPkValue(prinfo.getPkValue()); + this.operationResult.addErrorInfo(operateErrorInfo); + } } } + /** + * 请求头组装 + * @param billNumber 单据编号 + * @param recBill 付款处理 + * @return + */ + private HashMap assembleRequest(String billNumber, DynamicObject recBill, StringBuilder message){ + HashMap responseBody = null; + try { + // 生成唯一事务ID + String rootContextId = UUID.randomUUID().toString(); + // 获取当前请求时间,格式为 yyyy-MM-dd HH:mm:ss.SSS + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + String requestTime = sdf.format(new Date()); + responseBody = new HashMap<>(5); + responseBody.put("rootContextID", rootContextId); + responseBody.put("requestTime", requestTime); + HashMap data = new HashMap<>(1); + List> IT_ITEM = new ArrayList<>(1); + //用户名-从红冲单上获取人员,当前操作人可能是定时任务 + DynamicObject userinfo = BusinessDataServiceHelper.loadSingleFromCache(RequestContext.get().getCurrUserId(), userName); + String oaUser = userinfo.getString("shjh_oauser"); + //冲销原因 + Map IT_ITEMS = new HashMap<>(6); + //红冲所需参数从红字付款单上获取,红单上保留了原蓝字付款单的凭证号和会计年度 + String BUKRS = ""; + if (null != recBill.getDynamicObject("openorg")) { + BUKRS = recBill.getDynamicObject("openorg").getString("number"); + } + if (StringUtils.isEmpty(BUKRS)) { + BUKRS = recBill.getDynamicObject("org").getString("number"); + } + IT_ITEMS.put("BUKRS",BUKRS);//公司代码 + IT_ITEMS.put("BELNR",recBill.getString("shjh_credentialnum"));//会计凭证编号 + IT_ITEMS.put("GJAHR",recBill.getString("shjh_sapfiscalyear"));//会计年度 + IT_ITEMS.put("STGRD","04");//冲销原因 跨期冲销;默认04,冲销日期必传 + if(EsbUtils.isEmpty(oaUser)){ + IT_ITEMS.put("UNAME","资金系统");//用户名 + }else{ + IT_ITEMS.put("UNAME",oaUser);//用户名 + } + SimpleDateFormat sdfdate = new SimpleDateFormat("yyyy-MM-dd"); + Date budate = getVoucherDate(recBill); + if(budate == null){ + budate = recBill.getDate("bizdate"); + if(budate == null){ + IT_ITEMS.put("BUDAT",sdfdate.format(new Date()));//凭证中的过帐日期 + }else{ + IT_ITEMS.put("BUDAT",sdfdate.format(budate));//凭证中的过帐日期 + } + }else { + IT_ITEMS.put("BUDAT",sdfdate.format(budate));//凭证中的过帐日期 + } + 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, KEY_RED_PUSH, "数据异常"); + } + return responseBody; + } + + private Date getVoucherDate(DynamicObject bill){ + //获得付款单对应的凭证记账日期 + QFilter q1 = new QFilter("sourcebill", QCP.equals, bill.getPkValue()); + QFilter q2 = new QFilter("billstatus",QCP.equals,"C"); + DynamicObject gl_voucher = BusinessDataServiceHelper.loadSingle("gl_voucher", + "id,billno,bookeddate", new QFilter[]{q1, q2}); + if(gl_voucher != null){ + return gl_voucher.getDate("bookeddate"); + } + return null; + } + private boolean isWB(DynamicObject bill){ //如果(“异币种支付”=是 )或(“异币种支付”=否 ,且付款币种不等于人民币),取明细行中的 应付折本币 if(bill.getBoolean("isdiffcur") || !"CNY".equals(bill.getString("currency.number"))){ diff --git a/main/java/shjh/jhzj7/fi/fi/plugin/operate/TransupbillOperation.java b/main/java/shjh/jhzj7/fi/fi/plugin/operate/TransupbillOperation.java index eecf91b..b269d49 100644 --- a/main/java/shjh/jhzj7/fi/fi/plugin/operate/TransupbillOperation.java +++ b/main/java/shjh/jhzj7/fi/fi/plugin/operate/TransupbillOperation.java @@ -18,20 +18,24 @@ 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.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.JhzjUtils; import shjh.jhzj7.fi.fi.utils.SapUtils; import shjh.jhzj7.fi.fi.utils.domin.ResponseData; +import java.io.IOException; import java.math.BigDecimal; import java.text.SimpleDateFormat; -import java.util.Map; +import java.util.*; /** * 上划处理 * shjh_fca_transupbill_ext + * 0801增加sap凭证红冲处理 */ public class TransupbillOperation extends AbstractOperationServicePlugIn implements Plugin { @@ -42,6 +46,12 @@ public class TransupbillOperation extends AbstractOperationServicePlugIn impleme private static final String ccName = "bos_costcenter";//成本中心 private static final String glbdName = "gl_assist_bd";//核算项目组合纵表 + private static final String INTERFACE_ID = "ReversalVoucher";//识别被调接口并进行路由-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";//sap红冲凭证的操作标记 + private final static Log logger = LogFactory.getLog(TransdownbillOperation.class); @Override @@ -62,6 +72,21 @@ public class TransupbillOperation extends AbstractOperationServicePlugIn impleme e.setCancel(true); } } + }else if(KEY_RED_PUSH.equals(eok)){ + //sap凭证红冲处理 前置校验 + DynamicObject[] dos = e.getDataEntities(); + DynamicObject prinfo; + for (int i = 0; i < dos.length; i++) { + prinfo = BusinessDataServiceHelper.loadSingle(dos[i].getPkValue(), dos[i].getDataEntityType().getName()); + //判断上划处理单是否已生成金蝶凭证 + if(!prinfo.getBoolean("isvoucher")){ + e.setCancelMessage(prinfo.getString("billno") + "未生成金蝶凭证,无法推送SAP红冲凭证"); + e.setCancel(true); + }else if(!prinfo.getBoolean("shjh_sendsap")){ + e.setCancelMessage(prinfo.getString("billno") + "未推送过SAP,无需红冲"); + e.setCancel(true); + } + } } } @@ -99,9 +124,111 @@ public class TransupbillOperation extends AbstractOperationServicePlugIn impleme } } } + }else if(KEY_RED_PUSH.equals(eok)){ + //sap凭证红冲处理 + DynamicObject[] dos = e.getDataEntities(); + DynamicObject prinfo = null;//上划处理单 + JSONObject sapReturnData; + String billNumber; + StringBuilder message = new StringBuilder(); + for (int i = 0; i < dos.length; i++) { + prinfo = BusinessDataServiceHelper.loadSingle(dos[i].getPkValue(), dos[i].getDataEntityType().getName()); + if(prinfo.getBoolean("shjh_sendsap")){ + //如果上划处理单已推送sap才需要红冲 + billNumber = prinfo.getString("billno");//单号 + HashMap responseHead = ApiUtils.buildHead(INTERFACE_ID,RECEIVER_ID); + HashMap responseBody = this.assembleRequest(billNumber, prinfo, message); + try { + String response = ApiUtils.sendPost(responseHead, responseBody, API_URL); + if (!EsbUtils.isEmpty(response)) { + boolean success = ApiUtils.parseResponse(response, billNumber, responseBody, "SAP反清账或冲销", message); + if (success){ + //sap红冲凭证成功,反写sap凭证号和推送标记 + sapReturnData = JSONObject.parseObject(response); + JSONObject data = sapReturnData.getJSONObject("data"); + JSONArray rows = data.getJSONArray("IT_ITEM"); + JSONObject resultData = rows.getJSONObject(0); + String key = resultData.getString("OBJ_KEY"); + if(EsbUtils.isEmpty(key)){ + message.append("上划处理【").append(billNumber).append("】:").append("SAP返回的OBJ_KEY为空").append("\n"); + }else{ + //sap红冲凭证号根据返回值更新 + prinfo.set("shjh_hcsappzh",key.length() >= 10 ? key.substring(0, 10) : key); + prinfo.set("shjh_sendsap",false);//sap已推送标记-置为false,让后续可以再推蓝字凭证 + prinfo.set("shjh_sappzh",null);//sap凭证号置为空 + prinfo.set("shjh_sapyear",null);//sap年度置为空 + SaveServiceHelper.update(prinfo); + } + } + }else{ + message.append("上划处理【").append(billNumber).append("】:").append("SAP返回值为空").append("\n"); + } + } catch (IOException ex) { + message.append("上划处理【").append(billNumber).append("】:").append(ex.getMessage()).append("\n"); + logger.info("调用上划红冲凭证接口异常"+message); + } + } + } + if (message.length() != 0){ + OperateErrorInfo operateErrorInfo = new OperateErrorInfo(); + operateErrorInfo.setMessage(String.valueOf(message)); + operateErrorInfo.setErrorLevel(kd.bos.entity.validate.ErrorLevel.Error.name()); + operateErrorInfo.setPkValue(prinfo.getPkValue()); + this.operationResult.addErrorInfo(operateErrorInfo); + } } } + /** + * 请求头组装 + * @param billNumber 单据编号 + * @param recBill 上划处理 + * @return + */ + private HashMap assembleRequest(String billNumber, DynamicObject recBill, StringBuilder message){ + HashMap responseBody = null; + try { + // 生成唯一事务ID + String rootContextId = UUID.randomUUID().toString(); + // 获取当前请求时间,格式为 yyyy-MM-dd HH:mm:ss.SSS + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + String requestTime = sdf.format(new Date()); + responseBody = new HashMap<>(5); + responseBody.put("rootContextID", rootContextId); + responseBody.put("requestTime", requestTime); + HashMap data = new HashMap<>(1); + List> IT_ITEM = new ArrayList<>(1); + //用户名-从红冲单上获取人员,当前操作人可能是定时任务 + DynamicObject userinfo = BusinessDataServiceHelper.loadSingleFromCache(RequestContext.get().getCurrUserId(), userName); + String oaUser = userinfo.getString("shjh_oauser"); + //冲销原因 + Map IT_ITEMS = new HashMap<>(6); + //红冲所需参数从红字上划单上获取,红单上保留了原蓝字上划单的凭证号和会计年度 + IT_ITEMS.put("BELNR",recBill.getString("shjh_sappzh"));//会计凭证编号 + IT_ITEMS.put("BUKRS",recBill.getString("company.number"));//公司代码 + IT_ITEMS.put("GJAHR",recBill.getString("shjh_sapyear"));//会计年度 + IT_ITEMS.put("STGRD","04");//冲销原因 跨期冲销;默认04,冲销日期必传 + if(EsbUtils.isEmpty(oaUser)){ + IT_ITEMS.put("UNAME","资金系统");//用户名 + }else{ + IT_ITEMS.put("UNAME",oaUser);//用户名 + } + SimpleDateFormat sdfdate = new SimpleDateFormat("yyyy-MM-dd"); + if(recBill.getDate("transbilldate") == null){ + IT_ITEMS.put("BUDAT",sdfdate.format(new Date()));//凭证中的过帐日期 + }else { + IT_ITEMS.put("BUDAT",sdfdate.format(recBill.getDate("transbilldate")));//凭证中的过帐日期 + } + 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, KEY_RED_PUSH, "数据异常"); + } + return responseBody; + } + private JSONObject sendBlueVoucher(DynamicObject prinfo, Map sapMap){ //SAP上划处理单凭证接口入参组装和调用 JSONObject IS_HEADER = new JSONObject();//抬头