PayBillToolUtil.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package fi.cas.opplugin;
  2. import kd.bos.dataentity.entity.DynamicObject;
  3. import kd.bos.entity.EntityMetadataCache;
  4. import kd.bos.logging.Log;
  5. import kd.bos.logging.LogFactory;
  6. import kd.bos.orm.query.QFilter;
  7. import kd.bos.servicehelper.BusinessDataServiceHelper;
  8. import java.io.*;
  9. import java.math.RoundingMode;
  10. import java.net.Socket;
  11. import java.util.Calendar;
  12. import java.util.Date;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. import kd.bos.servicehelper.operation.OperationServiceHelper;
  16. import kd.bos.servicehelper.operation.SaveServiceHelper;
  17. import org.w3c.dom.Document;
  18. import org.w3c.dom.Element;
  19. import org.json.JSONObject;
  20. import org.json.XML;
  21. import javax.xml.parsers.DocumentBuilder;
  22. import javax.xml.parsers.DocumentBuilderFactory;
  23. import javax.xml.transform.OutputKeys;
  24. import javax.xml.transform.Transformer;
  25. import javax.xml.transform.TransformerFactory;
  26. import javax.xml.transform.dom.DOMSource;
  27. import javax.xml.transform.stream.StreamResult;
  28. public class PayBillToolUtil {
  29. public static final String ENTITY_NAME = "cas_paybill";
  30. protected static final Log log = LogFactory.getLog(PayBillToolUtil.class);
  31. public static String createSinglePaymentRequest(DynamicObject payBillEntity) {
  32. try {
  33. DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
  34. DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
  35. Document doc = dBuilder.newDocument();
  36. Element rootElement = doc.createElement("Message");
  37. doc.appendChild(rootElement);
  38. Element body = doc.createElement("Body");
  39. rootElement.appendChild(body);
  40. createElement(doc, body, "transcode", "BTSCO001");
  41. createElement(doc, body, "trxcode", "jfgx");//渠道交易代码
  42. createElement(doc, body, "channelcode", "经费共享");//发起渠道
  43. Calendar currentdate = Calendar.getInstance();
  44. createElement(doc, body, "channeldate", TypeUtils.date2String(currentdate.getTime(),"yyyyMMdd"));//发起渠道日期
  45. payBillEntity.set("nckd_fqqdrq",TypeUtils.date2String(currentdate.getTime(),"yyyyMMdd"));
  46. String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh");
  47. createElement(doc, body, "channelserno", channelserno);//发起渠道流水
  48. createElement(doc, body, "channeltime", currentdate.get(Calendar.HOUR)+""+currentdate.get(Calendar.MINUTE)+""+currentdate.get(Calendar.SECOND));
  49. createElement(doc, body, "brno", "");//交易发起机构,可为空,默认100800
  50. createElement(doc, body, "bustype", "");//业务类型,可为空,默认为0-汇兑
  51. createElement(doc, body, "buskind", "");//业务种类,可为空,默认为0-普通汇兑
  52. createElement(doc, body, "payeracctype", "1");//付款账户类型 0-对公账户 1-个人账户.待补充
  53. //付款账号
  54. DynamicObject payeracctbankEntity = BusinessDataServiceHelper.loadSingle(payBillEntity.getDynamicObject("payeracctbank").getPkValue(), "am_accountbank");
  55. String payeracc = payeracctbankEntity.getString("bankaccountnumber");
  56. String payername = payeracctbankEntity.getString("acctname");
  57. createElement(doc, body, "payeracc", payeracc);//付款账户
  58. createElement(doc, body, "payername", payername);//付款人名称
  59. createElement(doc, body, "realpayeracc", payeracc);//实际付款人账户
  60. createElement(doc, body, "realpayername", payername);//实际付款人名称
  61. createElement(doc, body, "payeeacc", payBillEntity.getString("payeebanknum"));//收款账号
  62. createElement(doc, body, "payeename", payBillEntity.getString("payeename"));//收款人名称
  63. createElement(doc, body, "amount", payBillEntity.getBigDecimal("actpayamt").setScale(2, RoundingMode.DOWN).toString());//金额
  64. createElement(doc, body, "feeflag", "0");//收费标志0-暂不收费 1-计费 2-按月计费
  65. createElement(doc, body, "postscript", "测试江西银行经费共享系统付款");
  66. DynamicObject skyhinfo = BusinessDataServiceHelper.loadSingle(payBillEntity.getDynamicObject("payeebank").getPkValue(), "bd_bebank");
  67. createElement(doc, body, "recvbank", skyhinfo.getString("union_number"));// 如果是跨行业务,需填写接收行号
  68. createElement(doc, body, "paysysid", "0");// 如果是跨行业务,需填写汇路
  69. TransformerFactory transformerFactory = TransformerFactory.newInstance();
  70. Transformer transformer = transformerFactory.newTransformer();
  71. // 指定编码格式为GBK
  72. transformer.setOutputProperty(OutputKeys.ENCODING, "GBK");
  73. transformer.setOutputProperty(OutputKeys.INDENT, "yes");
  74. DOMSource source = new DOMSource(doc);
  75. StringWriter writer = new StringWriter();
  76. StreamResult result = new StreamResult(writer);
  77. transformer.transform(source, result);
  78. return writer.toString();
  79. } catch (Exception e) {
  80. e.printStackTrace();
  81. return null;
  82. }
  83. }
  84. private static void createElement(Document doc, Element parent, String name, String value) {
  85. Element element = doc.createElement(name);
  86. element.appendChild(doc.createTextNode(value));
  87. parent.appendChild(element);
  88. }
  89. /**
  90. * 支付单同步
  91. * @params billEntities
  92. * @returns 返回报错信息
  93. *
  94. */
  95. public static String payBillForCBSSync(DynamicObject[] billEntities) {
  96. StringBuffer errMsg = new StringBuffer();
  97. //获取接口链接等信息
  98. DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx",new QFilter[]{new QFilter("number","=","paytozfqz")});
  99. String servername = jkpzxx.getString("nckd_servername");
  100. String port = jkpzxx.getString("nckd_port");
  101. for (DynamicObject dataEntity : billEntities) {
  102. boolean isSuccess = false;
  103. boolean isZFQZ = true;
  104. Map<String, String> qzObject = new HashMap<>();
  105. DynamicObject payBillEntity = BusinessDataServiceHelper.loadSingle(dataEntity.getPkValue(), ENTITY_NAME);
  106. String cbsUrlBill ="";
  107. /**
  108. * 判断是否可以走前置支付
  109. * 1、付款单为审核状态
  110. * 2、支付状态为未支付
  111. * 3、版本号>=1时,必须等于付款次数
  112. */
  113. String billNum = payBillEntity.getString("billno");
  114. String billstatusString = payBillEntity.getString("billstatus");
  115. String paystatus = payBillEntity.getString("nckd_paystatus");
  116. int bbh = payBillEntity.getInt("nckd_bbh");
  117. int fkcs = payBillEntity.getInt("nckd_fkcs");
  118. if (!"C".equals(billstatusString)) {
  119. errMsg.append("单据号:").append(billNum).append(",付款单为审核状态,才能提交~\r\n");
  120. isZFQZ = false;
  121. }
  122. if (!"1".equals(paystatus) && !"".equals(paystatus)) {
  123. errMsg.append("单据号:").append(billNum).append(",付款单为未支付,才能提交~\r\n");
  124. isZFQZ = false;
  125. }
  126. if(bbh>=1 && bbh!=fkcs){
  127. errMsg.append("单据号:").append(billNum).append(",付款单未调整,请调整数据,或点击重付~\r\n");
  128. isZFQZ = false;
  129. }
  130. if(payBillEntity.getDynamicObject("payeracctbank")==null) {
  131. errMsg.append("单据号:").append(billNum).append(",付款账户为空~\r\n");
  132. isZFQZ = false;
  133. }
  134. if(payBillEntity.getDynamicObject("payeebank")==null) {
  135. errMsg.append("单据号:").append(billNum).append(",收款账户为空~\r\n");
  136. isZFQZ = false;
  137. }
  138. //构建请求xml
  139. String bodyxml = createSinglePaymentRequest(payBillEntity);
  140. if(bodyxml==null){
  141. isZFQZ = false;
  142. errMsg.append("单据号:").append(billNum).append(",无法拼出正确的xml请求~\r\n");
  143. }
  144. if(!isZFQZ){
  145. continue;
  146. }
  147. log.info("单据号:"+billNum+"传入参数"+bodyxml);
  148. JSONObject cbsReturnJson =socketService(servername,port,bodyxml);
  149. log.info("单据号:"+billNum+"返回参数"+cbsReturnJson.toString());
  150. //存入日志表
  151. savelog(payBillEntity,bodyxml,cbsReturnJson.toString());
  152. if(cbsReturnJson==null){
  153. isSuccess = false;
  154. errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
  155. errMsg.append("错误号:").append("XXXXXXX");
  156. errMsg.append(",错误原因:").append("接口无法连通,未获取到返回结果");
  157. errMsg.append("\r\n");
  158. }else if(cbsReturnJson.getJSONObject("Message")==null){
  159. isSuccess = false;
  160. errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
  161. errMsg.append("错误号:").append("DDDDDD1");
  162. errMsg.append(",错误原因:").append("接口已连通,但未获取到返回结果");
  163. errMsg.append("\r\n");
  164. }else{
  165. JSONObject bodyinfo = cbsReturnJson.getJSONObject("Message").getJSONObject("Body");
  166. if(bodyinfo==null){
  167. isSuccess = false;
  168. errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
  169. errMsg.append("错误号:").append("DDDDDDD2");
  170. errMsg.append(",错误原因:").append("接口已连通,但无法解析返回结果"+cbsReturnJson.toString());
  171. errMsg.append("\r\n");
  172. }else{
  173. String errcode =bodyinfo.getString("errorcode");
  174. if ("FIN0000".equals(errcode)) {//已受理,不代表支付成功
  175. isSuccess = true;
  176. errMsg.append("单据号:").append(billNum).append(",推送支付前置成功!");
  177. payBillEntity.set("nckd_fkcs", fkcs+1);//付款次数+1
  178. payBillEntity.set("nckd_sbyy",bodyinfo.getString("errormsg"));//错误信息
  179. String zfstatus = bodyinfo.getString("status");
  180. if("S".equals(zfstatus)){//成功
  181. payBillEntity.set("nckd_paystatus",3);
  182. }else if("U".equals(zfstatus)){//在途
  183. payBillEntity.set("nckd_paystatus",2);//支付中
  184. }else if("F".equals(zfstatus)){//失败
  185. payBillEntity.set("nckd_paystatus",4);//支付失败
  186. }
  187. } else {//拿到返回结果支付次数就必须加一
  188. isSuccess = false;
  189. errMsg.append("单据号:").append(billNum).append(",推送支付前置失败,");
  190. errMsg.append("错误号:").append(errcode);
  191. errMsg.append(",错误原因:").append(bodyinfo.getString("errormsg"));
  192. errMsg.append("\r\n");
  193. payBillEntity.set("nckd_fkcs", fkcs+1);//付款次数+1
  194. payBillEntity.set("nckd_paystatus",4);//支付失败
  195. payBillEntity.set("nckd_sbyy",bodyinfo.getString("errormsg"));//错误信息
  196. SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
  197. }
  198. }
  199. }
  200. if (isSuccess) {
  201. SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
  202. }
  203. }
  204. return errMsg.toString();
  205. }
  206. public static void savelog(DynamicObject payBillEntity,String qqbw,String fhbw){
  207. try {
  208. DynamicObject logInfo = new DynamicObject( EntityMetadataCache.getDataEntityType("nckd_zfjkdyrz"));
  209. String channelserno = payBillEntity.get("billno")+"-"+payBillEntity.getInt("nckd_bbh");
  210. logInfo.set("number",channelserno);
  211. logInfo.set("name",payBillEntity.get("billno")+"付款日志");
  212. logInfo.set("status","A");
  213. logInfo.set("enable","1");
  214. Calendar currentdate = Calendar.getInstance();
  215. logInfo.set("nckd_redate",currentdate.getTime());
  216. logInfo.set("nckd_billno",payBillEntity.get("billno"));
  217. logInfo.set("nckd_payid",payBillEntity.getPkValue()+"");
  218. logInfo.set("nckd_qqbw_tag",qqbw);
  219. logInfo.set("nckd_fhbw_tag",fhbw);
  220. logInfo.set("nckd_redate",new Date());
  221. logInfo.set("nckd_djlx","1");
  222. OperationServiceHelper.executeOperate("save","nckd_zfjkdyrz",new DynamicObject[]{logInfo});
  223. }catch (Exception e){
  224. log.info("保存日志报错"+e.getMessage());
  225. }
  226. }
  227. public static JSONObject socketService(String serverName,String port,String xmlData){
  228. try {
  229. Socket client = new Socket(serverName,TypeUtils.nullToInt(port));
  230. int messageLength = xmlData.getBytes("GBK").length;
  231. String header = String.format("%08dXMLBTSCO001%%%%%%%%%%%%%%%%%%%%%%%%%%", messageLength);
  232. String fullMessage = header + xmlData;
  233. OutputStream outToServer = client.getOutputStream();
  234. PrintWriter out = new PrintWriter(new OutputStreamWriter(outToServer, "GBK"), true);
  235. out.println(fullMessage);
  236. InputStream inFromServer = client.getInputStream();
  237. BufferedReader in = new BufferedReader(new InputStreamReader(inFromServer, "GBK"));
  238. StringBuilder responseBuilder = new StringBuilder();
  239. String line;
  240. while ((line = in.readLine()) != null) {
  241. responseBuilder.append(line);
  242. }
  243. String responseJson = responseBuilder.toString();
  244. if(responseJson.indexOf("<?xml")>0){
  245. int index = responseJson.indexOf("<?xml");
  246. responseJson = responseJson.substring(index);
  247. }
  248. JSONObject jsonObject = XML.toJSONObject(responseJson);
  249. client.close();
  250. return jsonObject;
  251. } catch (IOException e) {
  252. e.printStackTrace();
  253. log.info(e.getMessage());
  254. }
  255. return null;
  256. }
  257. }