package com.malk.taisen.service.impl; import cn.hutool.json.JSONArray; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.malk.server.aliwork.YDConf; import com.malk.server.aliwork.YDParam; import com.malk.server.aliwork.YDSearch; import com.malk.server.common.McException; import com.malk.server.dingtalk.DDR_New; import com.malk.service.aliwork.YDClient; import com.malk.service.aliwork.YDService; import com.malk.taisen.service.RtrServer; import com.malk.taisen.util.CusutUtil; import com.malk.taisen.util.HttpUtil; import com.malk.utils.UtilDateTime; import com.malk.utils.UtilMap; import com.malk.utils.UtilNumber; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; @Service @Slf4j public class RtrServerImpl implements RtrServer { @Autowired private YDClient ydClient; @Autowired private YDService ydService; /** * 测试地址 */ @Value(value = "${sap.QA_sapUrl_Poc}") private String QA_sapUrl ; @Value(value = "${sap.JT_sapUrl_Poc}") private String JT_sapUrl ; @Override public void RtrInsetSAP0005(String type,String formUuid, String InstanceId) { DDR_New ddr = ydClient.queryData(YDParam.builder().formInstId(InstanceId).build(), YDConf.FORM_QUERY.retrieve_id); Map dataForm = ddr.getFormData(); JSONObject sapJson = new JSONObject(); // 添加顶级键值对 sapJson.put("BLART", "Z5");//凭证类型 sapJson.put("ZOA_TYPE", "GL");//总账类型 sapJson.put("interface_id", "SAP005"); sapJson.put("ZPAY_AMT", "0"); sapJson.put("ZDUEDATE", CusutUtil.getFormatDate((Long) dataForm.get("dateField_miwh5y85"))); //Due date / 到期日 sapJson.put("ZOA_NUMBER", dataForm.get("textField_mi73dy3n")); //钉钉单据号 sapJson.put("BUKRS", dataForm.get("textField_mejfj9iw"));//公司代码 String uid = "CHN-02200287"; // 2200287 // String uname = ""; if (dataForm.containsKey("employeeField_mhxdzya9_id")&&!dataForm.get("employeeField_mhxdzya9_id").equals("")) { List> conditions = new ArrayList<>(Arrays.asList(buildCondition("textField_l6dddg5k", dataForm.get("employeeField_mhxdzya9_id"), "TEXT", "eq", "TextField"))); String listJson = JSON.toJSONString(conditions); YDParam YGydParam = _getYDTokenZXXZ(listJson); List dataList = (List) ydClient.queryData(YGydParam, YDConf.FORM_QUERY.retrieve_search_form).getData(); if (dataList != null && dataList.size() > 0) { Map map = dataList.get(0); Map formData = (Map) map.get("formData"); uid = formData.get("textField_l6djch1m").toString(); uid = "CHN-0" + uid; } } sapJson.put("USNAM", uid); //过账人 sapJson.put("BLDAT", CusutUtil.getFormatDate((Long) dataForm.get("dateField_l9nsavm3"))); //凭证日期ƒ Date / 申请日期 sapJson.put("BUDAT", CusutUtil.getFormatDate((Long) dataForm.get("dateField_miwh5y85"))); //过账日期 sapJson.put("BKTXT", dataForm.get("textField_miwh5y6z"));//备注 抬头文本 sapJson.put("WAERS", dataForm.get("selectField_mejfoong")); //币种 sapJson.put("BANKA", ""); sapJson.put("BANKN", ""); sapJson.put("KOINH", ""); sapJson.put("LIFNR", ""); sapJson.put("ZINVOICE_AMT","0"); //获取子表 if (type.equals("YWJT")) { JSONArray itemArray = new JSONArray(); Boolean isOtherTypeFor = (formUuid.equals("FORM-66A4F00A1E0E4E67B607D4119B88CEF6FBP6")||formUuid.equals("FORM-2CB3F7D8B4224AB9972A8C24CDBF3464C1OU"))&&"其他".equals(UtilMap.getString(dataForm,"radioField_mj1hb0kj")); int x = 1;//OA单据行号累计用 List tableFils = ydService.queryDetails(YDParam.builder().formInstanceId(InstanceId).formUuid(formUuid).tableFieldId(isOtherTypeFor?"tableField_mk7rt61h":"tableField_mipgl0vx").build()); if (tableFils != null && tableFils.size() > 0) { for (int n = 0; n < tableFils.size(); n++) { Map row = new HashMap(tableFils.get(n)); JSONObject itemObj = new JSONObject(); String sjItemNo = ""; if (x < 10) { sjItemNo += "00" + x; } else if (x < 100) { sjItemNo += "0" + x; } else { sjItemNo += x; } x++; itemObj.put("ZOA_ITEMNO", sjItemNo);//OA单据行号 itemObj.put("SHKZG", "S");// S借方 itemObj.put("ZTAXOUT_AMT", "0"); // 进项转出金额 itemObj.put("ZTAX_AMT", UtilMap.getString_default(row,isOtherTypeFor?"numberField_mk7rt61g_value":"numberField_miwh5y8a_value","0")); // 税额 // itemObj.put("HKONT", String.valueOf(row.get("textField_mipgl0w1"))); //会计科目:取接口行项目接口字段会计科目 HKONT itemObj.put("HKONT", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt617":"textField_miwh5y87"))); //会计科目:取接口行项目接口字段会计科目 HKONT itemObj.put("DMBTR", String.valueOf(row.get(isOtherTypeFor?"numberField_mk7rt619_value":"numberField_mipgl0w2_value"))); //凭证金额:取接口行项目接口字段 DMBTR itemObj.put("KOSTL", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61a":"textField_mipgl0w3"))); //成本中心:取接口行项目接口字段成本中心KOSTL itemObj.put("AUFNR", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61b":"textField_mipgl0w4"))); //订单:取接口行项目接口字段订单 AUFNR itemObj.put("PS_POSID", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61c":"textField_mipgl0w5"))); //WBS:职接口行项目接口字段 WBS元素 PS_POSID itemObj.put("MWSKZ", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61d":"textField_mipgl0w6")));///税码:取总账通用工单的行项目的税码,接口字段MWSKZ itemObj.put("ZUONR", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61e":"textField_mipgl0w7")));///分配:取接口行项目接口字段分配 ZUONR itemObj.put("XREF1", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61f":"textField_miwh5y88")));///参考码1:取接口行项目接口字段 XREF1 itemObj.put("SGTXT", String.valueOf(row.get(isOtherTypeFor?"textareaField_mk7rt616":"textareaField_miwh5y86")));///行项目文本:取接口行项目接口字段行项目文本 SGTXT itemObj.put("VBUND", UtilMap.getString_default(row,isOtherTypeFor?"textField_mo8fsj02":"textField_mo8fsj00","")); //贸易伙伴 VBUND itemArray.put(itemObj); } } List tableFils2 = ydService.queryDetails(YDParam.builder().formInstanceId(InstanceId).formUuid(formUuid).tableFieldId(isOtherTypeFor?"tableField_mk7rt61v":"tableField_miwh5y8n").build()); // List> tableFils2 = (List>) dataForm.get("tableField_miwh5y8n"); if (tableFils2 != null && tableFils2.size() > 0) { for (int n = 0; n < tableFils2.size(); n++) { Map row = new HashMap(tableFils2.get(n)); JSONObject itemObj = new JSONObject(); itemObj.put("SHKZG", "H"); //H贷方 String sjItemNo = ""; if (x < 10) { sjItemNo += "00" + x; } else if (x < 100) { sjItemNo += "0" + x; } else { sjItemNo += x; } x++; itemObj.put("ZOA_ITEMNO", sjItemNo);//OA单据行号 itemObj.put("ZTAXOUT_AMT", "0"); // 进项转出金额 itemObj.put("ZTAX_AMT", UtilMap.getString_default(row,isOtherTypeFor?"numberField_mk7rt61u_value":"numberField_miwh5y8m_value","0")); // 税额 // itemObj.put("HKONT", String.valueOf(row.get("textField_miwh5y8d"))); //会计科目:取接口行项目接口字段会计科目 HKONT itemObj.put("HKONT", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61k":"textField_miwh5y8e"))); //会计科目:取接口行项目接口字段会计科目 HKONT itemObj.put("DMBTR", String.valueOf(row.get(isOtherTypeFor?"numberField_mk7rt61m_value":"numberField_miwh5y8f_value"))); //凭证金额:取接口行项目接口字段 DMBTR itemObj.put("KOSTL", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61n":"textField_miwh5y8g"))); //成本中心:取接口行项目接口字段成本中心KOSTL itemObj.put("AUFNR", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61o":"textField_miwh5y8h"))); //订单:取接口行项目接口字段订单 AUFNR itemObj.put("PS_POSID", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61p":"textField_miwh5y8i"))); //WBS:职接口行项目接口字段 WBS元素 PS_POSID itemObj.put("MWSKZ", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61q":"textField_miwh5y8j")));///税码:取总账通用工单的行项目的税码,接口字段MWSKZ itemObj.put("ZUONR", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61r":"textField_miwh5y8k")));///分配:取接口行项目接口字段分配 ZUONR itemObj.put("XREF1", String.valueOf(row.get(isOtherTypeFor?"textField_mk7rt61s":"textField_miwh5y8l")));///参考码1:取接口行项目接口字段 XREF1 itemObj.put("SGTXT", String.valueOf(row.get(isOtherTypeFor?"textareaField_mk7rt61j":"textareaField_miwh5y8c")));///行项目文本:取接口行项目接口字段行项目文本 SGTXT itemObj.put("VBUND", UtilMap.getString_default(row,isOtherTypeFor?"textField_mo8fsj03":"textField_mo8fsj01","")); //贸易伙伴 VBUND itemArray.put(itemObj); } } sapJson.put("ITEM", itemArray); } /*** * 调用接口 */ System.out.println(sapJson); log.info("发起POST请求:URL={},参数={}", QA_sapUrl + "SAP005", sapJson); String post = HttpUtil.post(QA_sapUrl + "SAP005", null, sapJson.toString(), null); log.info(dataForm.get("textField_mi73dy3n")+"POST反馈={}", post); System.out.println( "POST反馈====="+post); if (!post.equals("")) { JSONArray jsonArray = new JSONArray(post); if (jsonArray.size() > 0) { String voucherNumber = ""; try { cn.hutool.json.JSONObject postJsonObject = jsonArray.getJSONObject(0); String E_SYSMSGTYPE = postJsonObject.getStr("E_SYSMSGTYPE");//状态 String E_MESSAGE = postJsonObject.getStr("E_MESSAGE");//SAP005 接口 反馈值 // prd 重复推送标记成功 if (E_SYSMSGTYPE.equals("S") || "post operation had already been done, repeat is not allowed".equals(E_MESSAGE)) { String e_belnr = postJsonObject.getStr("E_BELNR"); String E_GJAHR = postJsonObject.getStr("E_GJAHR");//凭证年度 // 执行完加入,把更改表单凭证数据 ydClient.operateData(YDParam.builder().formInstanceId(InstanceId).updateFormDataJson(JSON.toJSONString(UtilMap.map("textField_l9nsavm2, textField_mejezfwk, textareaField_mi5kjmxb, selectField_mi72r4s6", E_GJAHR, e_belnr,E_MESSAGE,"成功"))).build(), YDConf.FORM_OPERATION.update); }else { // 报错写入 saveError(InstanceId,E_MESSAGE); } } catch (Exception ex) { log.error("解析异常{}",ex.getMessage()); saveError(InstanceId,post); } } else { log.error("返回值数组为空"); saveError(InstanceId,"返回值数组为空,返回值:"+post); } }else { // 报错写入 saveError(InstanceId,post); } } private void saveError(String InstanceId,String errorMsg){ ydClient.operateData(YDParam.builder().formInstanceId(InstanceId).updateFormDataJson(JSON.toJSONString(UtilMap.map("textareaField_mi5kjmxb, selectField_mi72r4s6", errorMsg,"失败" ))).build(), YDConf.FORM_OPERATION.update); } //匹配条件用 private static final String KEY = "key"; private static final String VALUE = "value"; private static final String TYPE = "type"; private static final String OPERATOR = "operator"; private static final String COMPONENT_NAME = "componentName"; private static Map buildCondition(String key, Object value, String type, String operator, String componentName) { Map condition = new HashMap<>(); condition.put(KEY, key); condition.put(VALUE, value); condition.put(TYPE, type); condition.put(OPERATOR, operator); condition.put(COMPONENT_NAME, componentName); return condition; } /** * 泰森付款 人员档案表 */ public static YDParam _getYDTokenZXXZ(String searchFieldJson) { return YDParam.builder().formUuid("FORM-4J7669A10FO250UJ9C6Q7CM00PC62YPW8DD6LT").searchFieldJson(searchFieldJson).build(); } // 销售计提 @Override public void RtrInsetSAP0020(String type, String formUuid, String InstanceId) { boolean isNew = type.equals("XSJTNEW"); DDR_New ddr = ydClient.queryData(YDParam.builder().formInstId(InstanceId).build(), YDConf.FORM_QUERY.retrieve_id); Map dataForm = ddr.getFormData(); /// 主表字段: 公司代码, 凭证类型, 货币码, 钉钉单据号, 发起人 Map body = UtilMap.map( "BUKRS, BLART, WAERS, XBLNR, USNAM", "textField_mejfj9iw, selectField_mejkjsb5, selectField_mejfoong, serialNumberField_mjc4e95b, textField_mjjs85qn", dataForm); if (dataForm.containsKey("employeeField_mhxdzya9_id")&&!dataForm.get("employeeField_mhxdzya9_id").equals("")) { List> conditions = new ArrayList<>(Arrays.asList(buildCondition("textField_l6dddg5k", dataForm.get("employeeField_mhxdzya9_id"), "TEXT", "eq", "TextField"))); String listJson = JSON.toJSONString(conditions); YDParam YGydParam = _getYDTokenZXXZ(listJson); List dataList = (List) ydClient.queryData(YGydParam, YDConf.FORM_QUERY.retrieve_search_form).getData(); if (dataList != null && dataList.size() > 0) { Map map = dataList.get(0); Map formData = (Map) map.get("formData"); String uid = "CHN-0" + formData.get("textField_l6djch1m").toString(); body.put("USNAM",uid); } } /// 主表字段: 凭证日期, 过账日期, 会计期间 body.put("BLDAT", UtilDateTime.format(new Date(UtilMap.getLong(dataForm, "dateField_mipgl0vv")), "yyyyMMdd")); body.put("BUDAT", UtilDateTime.format(new Date(UtilMap.getLong(dataForm, "dateField_mjc39hdc")), "yyyyMMdd")); if (UtilMap.getString(dataForm, "textField_mipmks2t").contains("-")) { body.put("MONAT", UtilMap.getString(dataForm, "textField_mipmks2t").split("-")[1]); } List details = UtilMap.getList(dataForm, "tableField_mipgl0vx"); if (details.size() == 50) { details = ydService.queryDetails(YDParam.builder().formInstanceId(InstanceId).formUuid(formUuid).tableFieldId("tableField_mipgl0vx").build()); } log.info("销售计提行项目, {}, {}", InstanceId, details.size()); int total = details.size(), succ = 0, fail = 0; // 批量推送Sap凭证: 兼容重试场景 for (Map detail : details) { if ("成功".equals(UtilMap.getString(detail, "selectField_mjihy3si"))) { succ += 1; continue; } /// 主表字段: 上传编号, 抬头文本 String referCode = UtilMap.getString(dataForm, "serialNumberField_mjc4e95b") + UtilMap.getString(detail, "textField_mjif9kha"); body.put("ZUPDNR", referCode); body.put("BKTXT", UtilMap.getString(detail, "textField_mipgl0w4")); /// 明细字段: 凭证货币金额, 项目文本, 利润中心, 分配, 参考码1, 参考码2, 产品号, 销售组织, 分销渠道, 产品组, 客户定义, 物料组包装物料, 销售地区, 客户简称 Map row = UtilMap.map("WRBTR, SGTXT, PRCTR, ZUONR, XREF1, XREF2, ARTNR, VKORG, VTWEG, SPART, KDKG4, MAGRV, BZIRK, WWKCG", "numberField_mipgl0w2, textField_mipgl0w4, textField_mjihy3sn, textField_mipgl0w5, textField_mipgl0w6, textField_mipgl0w7, textField_mipgl0w9, textField_mipgl0wa, textField_mipgl0wb, textField_mipgl0wc, textField_mipgl0wd, textField_mipgl0we, textField_mipgl0wf, textField_mipgl0wg", detail); if (isNew){ body.put("BUKRS",UtilMap.getString(detail, "textField_mejfj9iw")); } row.put("ZUPDNR", referCode); try { Map result = this._pushSap(detail, body, row); // prd 重复推送标记成功 if ("S".equals(result.get("E_SYSMSGTYPE")) || "post operation had already been done, repeat is not allowed".equals(result.get("E_MESSAGE"))) { detail.put("selectField_mjihy3si", "成功"); detail.put("textField_mejezfwk", result.get("E_BELNR")); detail.put("textField_l9nsavm2", result.get("E_GJAHR")); succ += 1; } else { detail.put("selectField_mjihy3si", "失败"); fail += 1; } detail.put("textareaField_mi5kjmxb", result.get("E_MESSAGE")); } catch (McException mc) { detail.put("selectField_mjihy3si", "失败"); detail.put("textareaField_mi5kjmxb", mc.getMessage()); fail +=1; } /// 子表回写: 行项目-凭证号 detail.put("textField_mjihy3sm", referCode); } String state = "已完成"; if (fail > 0) { state = "部分失败"; } if (fail == total) { state = "全部失败"; } Map formData = UtilMap.map("tableField_mipgl0vx, numberField_mjc39hdi, numberField_mjc39hdj, numberField_mjc39hdk, selectField_mi72r4s6", details, total, succ, fail, state); log.info("销售计提执行, {}", formData); ydClient.operateData(YDParam.builder().formInstanceId(InstanceId).updateFormDataJson(JSON.toJSONString(formData)).build(), YDConf.FORM_OPERATION.update); } private static List SYNC_FORM_LIST = Arrays.asList("FORM-0401740B8E6F4DF8894498F0D8783B13QIPI","FORM-66A4F00A1E0E4E67B607D4119B88CEF6FBP6", "FORM-0EB8076C7A8E437A8A47862A1C4CFC61B1LB"); @Override public void syncSAP0005() { LocalDateTime now = LocalDateTime.now();// 10:05 LocalDateTime end = now.minusMinutes(3); LocalDateTime start = end.minusMinutes(60); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String startStr = start.format(formatter); String endStr = end.format(formatter); YDSearch orderState=new YDSearch("selectField_miwh5y55","待过账","单据状态", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ); YDSearch pushState=new YDSearch("selectField_mi72r4s6","待推送","推送状态", YDSearch.Type.TEXT_FIELD,YDSearch.Operator.EQ); for (String formUuId:SYNC_FORM_LIST){ List list= (List) ydClient.queryData(YDParam.builder().formUuid(formUuId) .searchFieldJson(JSONObject.toJSONString(Arrays.asList(orderState,pushState))) .approvedResult("agree").modifiedFromTimeGMT(startStr).modifiedToTimeGMT(endStr).build(), YDConf.FORM_QUERY.retrieve_search_process).getData(); for (Map map:list){ String insetid = map.get("processInstanceId").toString(); log.info("自动推送:{}/{}",formUuId,insetid); this.RtrInsetSAP0005("YWJT",formUuId,insetid); } } } /// 推送Sap private Map _pushSap(Map detail, Map body, Map row) { /// 借贷处理: 行项目号; 记账代码, 借方-40, 贷方-50; 总账科目; List items = new ArrayList<>(); /// 成本中心: 传递到sap,科目大于等于5取值到成本中心行项目,否则则不赋值 String cbzx = UtilMap.getString(detail, "textField_mipgl0w3"); String jfkm = UtilMap.getString(detail, "textField_mipgl0vy"); Map jf = UtilMap.map("ITMNR, BSCHL, HKONT", "001", "40", jfkm); if (Integer.valueOf(jfkm.substring(0, 1)) >= 5) { jf.put("KOSTL", cbzx); } jf.putAll(row); items.add(jf); String dfkm = UtilMap.getString(detail, "textField_mipgl0w1"); Map df = UtilMap.map("ITMNR, BSCHL, HKONT", "002", "50", dfkm); if (Integer.valueOf(dfkm.substring(0, 1)) >= 5) { df.put("KOSTL", cbzx); } df.putAll(row); items.add(df); body.put("ITEMS", items); log.info("销售计提推送 SAP, {}", JSON.toJSONString(body)); String rsp = HttpUtil.post(JT_sapUrl + "&ZUPDNR=" + body.get("ZUPDNR"), null, JSON.toJSONString(body), null); log.info("销售计提 SAP 响应, {}", rsp); List result = JSON.parseArray(rsp, Map.class); McException.assertAccessException(result.isEmpty(), "Sap接口请求异常, 返回空集合, 需重新推送."); return result.get(0); } }