package fi.cas.opplugin;
import com.kingdee.util.StringUtils;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.encrypt.Encrypters;
import kd.bos.entity.EntityMetadataCache;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QFilter;
import kd.bos.sdk.util.KHttpClientUtils;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.sql.Timestamp;
import java.util.*;
import kd.bos.servicehelper.operation.OperationServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import nckd.base.helper.CommonHelperUtils;
import org.json.JSONArray;
import org.json.JSONObject;


public class PayBillToolUtil {
    public static final String ENTITY_NAME = "cas_paybill";
    public static final String AGENT_ENTITY_NAME = "cas_agentpaybill";
    protected static final Log log = LogFactory.getLog(PayBillToolUtil.class);
    public static final String CHANNELCODE_PILIANG = "JF";


    /**
     * 代发单付款请求拼接
     *
     * @return
     */
    public static String createSingleAgentPaymentRequest_1(DynamicObject info) {
        try {
            JSONObject param = new JSONObject();
            headJson(param);

            JSONObject data = new JSONObject();

            //单据状态
            if ("C".equals(info.get("billstatus"))) {
                data.put("FBillStatus", "12");
            }

            //EAS付款单据号
            String bbh = info.get("nckd_bbh") + "";//版本号

            data.put("ERP_INS_ID", info.getPkValue() + "@" + bbh);

            //EAS付款单据号
            data.put("ERP_PAYNO", info.get("billno") + "");

            //录入人
            data.put("CREATOR", info.get("creator.name").toString());

            //录入时间
            data.put("CREATE_TIME", TypeUtils.date2String(new Date(((Timestamp) info.get("modifytime")).getTime()), TypeUtils.DEFAULT_DATE_FORMAT));

            //摘要
            data.put("REMARK", info.get("description"));

            data.put("IS_TRANSFER", "0");

            //付款单位--->公司编号
            if (info.get("org") != null) {//付款单位--->公司编号
                String companyNumber = TypeUtils.nullToString(info.get("org.number"));
                data.put("PAY_CLT_NO", companyNumber);
            }

            DynamicObject payeracctbankEntity = BusinessDataServiceHelper.loadSingleFromCache(info.getDynamicObject("payeracctbank").getPkValue(), "am_accountbank");
            String payeracc = payeracctbankEntity.getString("bankaccountnumber");
            String payername = payeracctbankEntity.getString("acctname");

            //付款方账号 ---> 付款账户基础资料银行账号
            data.put("PAY_ACNT_NO", payeracc);

            //付款银行 ---> 金融机构行号编码
            data.put("PAY_CNAPS", payeracctbankEntity.get("bank.number") + "");

            data.put("PAY_DATE", TypeUtils.date2String(new Date(), TypeUtils.DEFAULT_DATE_FORMAT));//付款日期

            //付款金额

            data.put("AMOUNT", info.getBigDecimal("payamount").setScale(2, RoundingMode.DOWN).toString());
            //币别
            data.put("CURRENCY", info.get("currency.number")+"");

            //对公
            if (info.getBoolean("nckd_is_person")) {
                data.put("IS_PERSON", "0");
            } else {
                data.put("IS_PERSON", "1");
            }

            //加急
            if (info.getBoolean("urgentflag")) {
                data.put("URGENT_FLAG", "1");
            } else {
                data.put("URGENT_FLAG", "0");
            }

            //用途
            data.put("PURPOSE", info.get("nckd_usage"));

            //费用类型
            data.put("BUSS_TYPE", info.get("nckd_buss_type")+"");

            //付款类型，工资  997
            if ("997".equals(info.get("paymenttype.number"))) {
                data.put("PAY_FLAG", "2");
            } else {
                data.put("PAY_FLAG", "1");
            }

            //明细条数
            data.put("PAY_NUM", info.getString("count"));


            //明细数据
            JSONArray OP_ACNT_LIST = new JSONArray();

            // 获取分录数据
            DynamicObjectCollection entryList = info.getDynamicObjectCollection("entry");
            Map<String, BigDecimal> decodeAmount = new HashMap(entryList.size());

            for(int i = 0; i < entryList.size(); ++i) {
                DynamicObject entry = (DynamicObject)entryList.get(i);
                String encryptLocalAmtStr;
                if (entry.getDataEntityType().getProperties().get("e_encryptamount") != null) {
                    encryptLocalAmtStr = entry.getString("e_encryptamount");
                    if (encryptLocalAmtStr != null && !encryptLocalAmtStr.trim().isEmpty()) {
                        entry.set("e_amount", getDecodeAmount(encryptLocalAmtStr, decodeAmount));
                    }
                }

                if (entry.getDataEntityType().getProperties().get("e_encryptlocalamt") != null) {
                    encryptLocalAmtStr = entry.getString("e_encryptlocalamt");
                    if (encryptLocalAmtStr != null && !encryptLocalAmtStr.trim().isEmpty()) {
                        entry.set("e_localamt", getDecodeAmount(encryptLocalAmtStr, decodeAmount));
                    }
                }
            }

            for (int i = 0; i < entryList.size(); i++) {
                DynamicObject entry = entryList.get(i);
                JSONObject entrydata = new JSONObject();
                //明细id
                entrydata.put("ERP_PVT_ID", entry.getPkValue() + "");
                //收款方账号
                entrydata.put("RECE_ACC_NO", entry.get("payeeacctbank") + "");
                //收款方户名
                entrydata.put("RECE_ACC_NAME", entry.get("payeename") + "");
                //收款行行号
                entrydata.put("RECE_CNAPS", entry.get("payeebanknumber") + "");
                //付款金额，待补充

                entrydata.put("AMOUNT", entry.getBigDecimal("e_amount").setScale(2, RoundingMode.DOWN).toString());
                //明细用途
                entrydata.put("PURPOSE", info.get("nckd_usage"));

                OP_ACNT_LIST.put(entrydata);
            }
            data.put("OP_ACNT_LIST", OP_ACNT_LIST);
            //结算方式
            if(info.getDynamicObject("settletype") != null) {
                data.put("settletype", info.getDynamicObject("settletype").getString("name"));
            } else {
                data.put("settletype", "");
            }

            //无用字段
            data.put("CLT_NO", JSONObject.NULL);
            data.put("PAY_ACNT_NAME", JSONObject.NULL);
            data.put("PAY_BANK", JSONObject.NULL);
            data.put("CASHAMOUNT", JSONObject.NULL);
            data.put("BILLAMOUNT", JSONObject.NULL);
            data.put("RECE_ACC_NO", JSONObject.NULL);
            data.put("RECE_ACC_NAME", JSONObject.NULL);
            data.put("RECE_OPBANK_NAME", JSONObject.NULL);
            data.put("RECE_OPBANK_NAME", JSONObject.NULL);
            data.put("RECE_BANK_NO", JSONObject.NULL);
            data.put("RECE_CNAPS", JSONObject.NULL);
            data.put("REG_NO", JSONObject.NULL);
            data.put("TERM", JSONObject.NULL);


            param.put("data", data);
            param.put("txDateTime", Utils.getData(new Date(), "yyyyMMddHHmmss"));
            param.put("batchNo", TypeUtils.nullToString(info.get("billno")) + "-" + TypeUtils.nullToString(info.get("nckd_bbh")) + "-" + Utils.getData(new Date(), "yyyyMMddHHmmss"));
            param.put("code", "JY-NSTC-T003");

            return param.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }







    private static BigDecimal getDecodeAmount(String encryptLocalAmtStr, Map<String, BigDecimal> decodeAmount) {
        BigDecimal amount = (BigDecimal)decodeAmount.get(encryptLocalAmtStr);
        if (amount == null) {
            decodeAmount.put(encryptLocalAmtStr, decodeAmount(encryptLocalAmtStr));
        }

        return (BigDecimal)decodeAmount.get(encryptLocalAmtStr);
    }
    public static BigDecimal decodeAmount(String encryptAmount) {
        if (encryptAmount != null && !encryptAmount.trim().isEmpty()) {
            String decode = "";
            if (Encrypters.isEncrypted(encryptAmount)) {
                decode = Encrypters.decode(encryptAmount);
                return new BigDecimal(decode);
            } else {
                return decodeAmountOld(encryptAmount);
            }
        } else {
            return BigDecimal.ZERO;
        }
    }
    public static BigDecimal decodeAmountOld(String encryptAmount) {
        if (encryptAmount != null && !encryptAmount.trim().isEmpty()) {
            byte[] decode = Base64.getDecoder().decode(encryptAmount);
            return new BigDecimal(new String(decode));
        } else {
            return BigDecimal.ZERO;
        }
    }
    /***
     * 拼接json对象
     */
    public static JSONObject getServiceBean_youhua(DynamicObject info) {
        JSONObject data = new JSONObject();

        //单据状态
        if ("C".equals(info.get("billstatus"))) {
            data.put("FBillStatus", "12");
        }


        //录入人
        data.put("CREATOR", info.get("creator.name").toString());

        //录入时间
        data.put("CREATE_TIME", TypeUtils.date2String(new Date(((Timestamp) info.get("modifytime")).getTime()), TypeUtils.DEFAULT_DATE_FORMAT));
        //摘要
        data.put("REMARK", info.get("description"));


        String entrance = info.get("entrance") + "";//是否资金调度,待补充
        if ("SYN".equals(entrance) || "SPAN".equals(entrance)) {
            data.put("IS_TRANSFER", "1");
        } else {
            data.put("IS_TRANSFER", "0");
        }



        String bbh = info.get("nckd_bbh") + "";//版本号
        data.put("ERP_INS_ID", info.getPkValue() + "@" + bbh);

        //EAS付款单据号
        data.put("ERP_PAYNO", info.get("billno") + "");

        //付款日期
        data.put("PAY_DATE", TypeUtils.date2String(new Date(), TypeUtils.DEFAULT_DATE_FORMAT));
        //对公
        if (info.getBoolean("nckd_is_person")) {
            data.put("IS_PERSON", "0");
        } else {
            data.put("IS_PERSON", "1");
        }

        //加急
        if (info.get("priority") != null) {
            if ("prior".equals(info.get("priority"))) {//优先
                data.put("URGENT_FLAG", "1");
            } else {
                data.put("URGENT_FLAG", "0");
            }
        }
        data.put("PURPOSE", info.get("nckd_usage"));

        data.put("BUSS_TYPE", info.get("nckd_buss_type")+"");


        DynamicObject skyhinfo = BusinessDataServiceHelper.loadSingleFromCache(info.getDynamicObject("payeebank").getPkValue(), "bd_bebank");

        //收款方开户行 名称
        data.put("RECE_OPBANK_NAME", skyhinfo.get("name").toString());//收款方开户行 名称

        //收款方开户行 CNAPS号 ，行号,取联行号
        data.put("RECE_CNAPS", skyhinfo.get("union_number") + "");

        //收款方户名
        data.put("RECE_ACC_NAME", info.get("payeename") + "");
        //收款方账号
        data.put("RECE_ACC_NO", info.get("payeebanknum") + "");

        //付款单位--->公司编号
        if (info.get("org") != null) {//付款单位--->公司编号
            String companyNumber = TypeUtils.nullToString(info.get("org.number"));
            data.put("PAY_CLT_NO", companyNumber);
        }


        //付款账号
        DynamicObject payeracctbankEntity = BusinessDataServiceHelper.loadSingle(info.getDynamicObject("payeracctbank").getPkValue(), "am_accountbank");
        String payeracc = payeracctbankEntity.getString("bankaccountnumber");
        String payername = payeracctbankEntity.getString("acctname");

        //付款方账号 ---> 付款账户基础资料银行账号
        data.put("PAY_ACNT_NO", payeracc);

        //付款银行 ---> 金融机构行号编码，是不是就是金融机构编码
        data.put("PAY_CNAPS", payeracctbankEntity.get("bank.number") + "");

        data.put("AMOUNT", info.getBigDecimal("actpayamt").setScale(2, RoundingMode.DOWN));
        //币别
        data.put("CURRENCY", info.get("currency.number"));

        //结算方式
        //结算方式
        if(info.getDynamicObject("settletype") != null) {
            data.put("settletype", info.getDynamicObject("settletype").getString("name"));
        } else {
            data.put("settletype", "");
        }

        //无用字段
        data.put("CLT_NO", JSONObject.NULL);
        data.put("PAY_ACNT_NAME", JSONObject.NULL);
        data.put("PAY_BANK", JSONObject.NULL);
        data.put("CASHAMOUNT", JSONObject.NULL);
        data.put("BILLAMOUNT", JSONObject.NULL);
        data.put("RECE_BANK_NO", JSONObject.NULL);
        data.put("REG_NO", JSONObject.NULL);
        data.put("TERM", JSONObject.NULL);
        data.put("PAY_FLAG", JSONObject.NULL);
        data.put("PAY_NUM", "0");
        data.put("OP_ACNT_LIST", JSONObject.NULL);


        //应付票据逻辑，不需要付息方式了
//        if ("012".equals(info.get("settletype.number"))) { // 012 应付票据（银行承兑汇票）
//            DynamicObject payInterest =info.getDynamicObject("payInterest");
//            if (payInterest != null) {
//                paymentBill.setPAY_INTEREST(payInterest.get("number")+"");
//            }
//        }
        return data;
    }


    public static String createSinglePaymentRequest(DynamicObject payBillEntity, String JKNO) {
        try {
            JSONObject param = new JSONObject();
            headJson(param);
            JSONObject datainfo = getServiceBean_youhua(payBillEntity);
            param.put("data", datainfo);
            param.put("txDateTime", Utils.getData(new Date(), "yyyyMMddHHmmss"));
            param.put("batchNo", TypeUtils.nullToString(payBillEntity.get("billno")) + "-" + TypeUtils.nullToString(payBillEntity.get("nckd_bbh")) + "-" + Utils.getData(new Date(), "yyyyMMddHHmmss"));
            param.put("code", JKNO);
            String text = param.toString();
            return text;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void headJson(JSONObject param) {
        param.put("nodeId", "client.001");
        param.put("channelId", "EAS");
        param.put("clientId", "001");
        param.put("clientName", "金蝶");
    }





    /**
     * 代发单支付
     *
     * @params billEntities
     * @returns 返回报错信息
     */
    public static String agentpayBillForCBSSync(DynamicObject[] billEntities) {
        StringBuffer errMsg = new StringBuffer();
        //获取接口链接等信息
        DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx", new QFilter[]{new QFilter("number", "=", "paytoJHX")});
        String url = jkpzxx.getString("nckd_servername");
        boolean isESBApi = jkpzxx.getBoolean("nckd_isesb");

        for (DynamicObject dataEntity : billEntities) {
            boolean isSuccess = false;//是否成功标识
            boolean isZFQZ = true;
            Map<String, String> qzObject = new HashMap<>();
            DynamicObject payBillEntity = BusinessDataServiceHelper.loadSingle(dataEntity.getPkValue(), AGENT_ENTITY_NAME);


            /**
             *   判断是否可以走前置支付
             *   1、代发单为审核状态
             *   2、支付状态为未支付
             */
            String billNum = payBillEntity.getString("billno");
            String billstatusString = payBillEntity.getString("billstatus");
            String paystatus = payBillEntity.getString("nckd_paystatus");
            int bbh = payBillEntity.getInt("nckd_bbh");
            int fkcs = payBillEntity.getInt("nckd_fkcs");

            if (!"C".equals(billstatusString)) {
                errMsg.append("单据号：").append(billNum).append("，代发单为审核状态，才能提交~\r\n");
                isZFQZ = false;
            }
            if (!"1".equals(paystatus) && !"".equals(paystatus)) {
                errMsg.append("单据号：").append(billNum).append("，代发单为未支付，才能提交~\r\n");
                isZFQZ = false;
            }
            if (bbh >= 1 && bbh != fkcs) {
                errMsg.append("单据号：").append(billNum).append("，代发单未调整，请调整数据，或点击重付~\r\n");
                isZFQZ = false;
            }
            if (payBillEntity.getDynamicObject("payeracctbank") == null) {
                errMsg.append("单据号：").append(billNum).append("，付款账户为空~\r\n");
                isZFQZ = false;
            }
            /***
             * 审批时校验,如果资金银企行号包含，则提交九恒星，否则不提交。待补充
             */


            //构建支付数据导入请求xml
            String qjjson = createSingleAgentPaymentRequest_1(payBillEntity);
            if (qjjson == null) {
                isZFQZ = false;
                errMsg.append("单据号：").append(billNum).append("无法拼出正确的json请求~\r\n");
            }

            if (!isZFQZ) {
                continue;
            }
            log.info("单据号：" + billNum + "传入参数" + qjjson);
            if ("".equals(url)) {
                url = "http://172.16.150.71:7081/FDLKF_OUTER/webservice/TxServiceGateway";
            }
            Date dd = new Date();


//            JSONObject cbsReturnJson = httpjhxService(url, qjjson);
//            log.info("单据号：" + billNum + "返回参数" + cbsReturnJson.toString());
//            //存入日志表
//            saveAgentlog(payBillEntity, qjjson, cbsReturnJson.toString(), "1");

            /***************************************add by wanghaiwu 20225/05/24*************************************************************/


            Map<String, String> tokenMap = getNtscToken();

            if(tokenMap == null){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口异常, 获取token失败");
                errMsg.append("\r\n");
                return errMsg.toString();
            }

            if(!"0".equals(tokenMap.get("code"))){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口异常, 获取token失败, " + tokenMap.get("msg"));
                errMsg.append("\r\n");
                return errMsg.toString();
            }

            String token = tokenMap.get("msg");

            //改成调用轻舟的方式
            Map<String, String> header = new HashMap<>();
            header.put("Content-Type", "application/json; charset=UTF-8");
            header.put("Authorization", "Bearer " + token);

            //如果是esb接口，需要包一层参数
            if(isESBApi) {
                qjjson = buildEsbApiBodyJSON(new JSONObject(qjjson));
            }

            String apiResult = "";
            try {
                apiResult = HttpUtils.postjson(url, header, qjjson);
            } catch (IOException e) {
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口异常, " + e.getMessage());
                errMsg.append("\r\n");
                return errMsg.toString();
            }

            if(StringUtils.isEmpty(apiResult)){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口无法连通，未获取到返回结果");
                errMsg.append("\r\n");

                return errMsg.toString();
            }

            log.info("单据号：" + billNum + "返回参数" + apiResult);
            //存入日志表
            saveAgentlog(payBillEntity, qjjson, apiResult, "1");

            JSONObject esbReturnJson = new JSONObject(apiResult);
            if(esbReturnJson.get("responseData") == null){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("未正常返回responseData参数");
                errMsg.append("\r\n");

                return errMsg.toString();
            }

            JSONArray esbJSONArray = esbReturnJson.getJSONArray("responseData");
            if(esbJSONArray == null || esbJSONArray.length() == 0){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("未正常返回responseData参数");
                errMsg.append("\r\n");

                return errMsg.toString();
            }

            JSONObject cbsReturnJson = esbJSONArray.getJSONObject(0);

            /************************************************************/

            if (cbsReturnJson == null) {
                isSuccess = false;
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口无法连通，未获取到返回结果");
                errMsg.append("\r\n");
            } else if (!"000000".equals(cbsReturnJson.get("resultCode"))) {
                isSuccess = false;
                String resultCode = cbsReturnJson.get("resultCode")+"";
                String resultMsg = cbsReturnJson.get("resultMsg") + "";

                if("JFXXXXC".equals(resultCode)){//超时，有可能成功，所以不处理
                    isSuccess = false;
                    errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                    errMsg.append("错误号：").append(cbsReturnJson.get("resultCode"));
                    errMsg.append("，错误原因：").append(resultMsg);
                    errMsg.append("\r\n");
                }else if (resultMsg.indexOf("单据是非驳回状态") >= 0 || resultMsg.indexOf("付款指令重复") >= 0) {//指令重复，说明已经传过去了，改状态为支付中，查询结果
                    isSuccess = true;
                    errMsg.append("单据号：").append(billNum).append("付款指令重复，说明已推送到资金系统！");
                    payBillEntity.set("nckd_fkcs", fkcs + 1);//付款次数+1
                    payBillEntity.set("nckd_sbyy", "指令重复，已推送到资金系统");//返回信息
                    payBillEntity.set("nckd_tjyhsj", dd);//返回信息
                    payBillEntity.set("nckd_paystatus", 2);//支付中
                } else { //如果不是驳回或重发，失败
                    errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                    errMsg.append("错误号：").append(cbsReturnJson.get("resultCode"));
                    errMsg.append("，错误原因：").append(resultMsg);
                    errMsg.append("\r\n");
                    payBillEntity.set("nckd_fkcs", fkcs + 1);//付款次数+1
                    payBillEntity.set("nckd_paystatus", 4);//传输失败
                    payBillEntity.set("nckd_sbyy", cbsReturnJson.get("resultMsg") + "");//错误信息
                    SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
                }
            } else if ("000000".equals(cbsReturnJson.get("resultCode"))) {//已受理，改为支付中
                String resultMsg = cbsReturnJson.get("resultMsg") + "";
                if ("SUCCESS".equals(resultMsg)) {
                    isSuccess = true;
                    errMsg.append("单据号：").append(billNum).append("，推送资金系统成功！");
                    payBillEntity.set("nckd_fkcs", fkcs + 1);//付款次数+1
                    payBillEntity.set("nckd_sbyy", "传输成功");//返回信息
                    payBillEntity.set("nckd_tjyhsj", dd);//返回信息
                    payBillEntity.set("nckd_paystatus", 2);//支付中
                }
            }
            if (isSuccess) {
                SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
            }
        }
        return errMsg.toString();
    }


    /**
     * 支付单同步
     *
     * @params billEntities
     * @returns 返回报错信息
     */
    public static String payBillForCBSSync(DynamicObject[] billEntities) {
        StringBuffer errMsg = new StringBuffer();
        //获取接口链接等信息
        DynamicObject jkpzxx = BusinessDataServiceHelper.loadSingle("nckd_jkpzxx", new QFilter[]{new QFilter("number", "=", "paytoJHX")});

        String url = jkpzxx.get("nckd_servername") + "";
        boolean isESBApi = jkpzxx.getBoolean("nckd_isesb");

        for (DynamicObject dataEntity : billEntities) {
            boolean isSuccess = false;
            boolean isZFQZ = true;
            DynamicObject payBillEntity = BusinessDataServiceHelper.loadSingle(dataEntity.getPkValue(), ENTITY_NAME);


            /**
             *   判断是否可以走前置支付
             *   1、付款单为审核状态
             *   2、支付状态为未支付
             *   3、版本号>=1时，必须等于付款次数
             */
            String billNum = payBillEntity.getString("billno");
            String billstatusString = payBillEntity.getString("billstatus");
            String paystatus = payBillEntity.getString("nckd_paystatus");
            int bbh = payBillEntity.getInt("nckd_bbh");
            int fkcs = payBillEntity.getInt("nckd_fkcs");


            //查询流水，如果存在流水，则不能支付
            String billno = payBillEntity.get("billno") + "";
//            QFilter orgFilter = new QFilter("nckd_reserve80", "like", "%"+billno+"%");
//            DynamicObject fkclinfo = BusinessDataServiceHelper.loadSingle("bei_transdetail","",new QFilter[]{orgFilter});


            if (!"C".equals(billstatusString)) {
                errMsg.append("单据号：").append(billNum).append("，付款单为审核状态，才能提交~\r\n");
                isZFQZ = false;
            }
            if (!"1".equals(paystatus) && !"".equals(paystatus)) {
                errMsg.append("单据号：").append(billNum).append("，付款单为未支付，才能提交~\r\n");
                isZFQZ = false;
            }
            if (bbh >= 1 && bbh != fkcs) {
                errMsg.append("单据号：").append(billNum).append("，付款单未调整，请调整数据，或点击重付~\r\n");
                isZFQZ = false;
            }
            if (payBillEntity.getDynamicObject("payeracctbank") == null) {
                errMsg.append("单据号：").append(billNum).append("，付款账户为空~\r\n");
                isZFQZ = false;
            }
            if (payBillEntity.getDynamicObject("payeebank") == null) {
                errMsg.append("单据号：").append(billNum).append("，收款账户为空~\r\n");
                isZFQZ = false;
            }
            //流水判断 待补充
//            if(fkclinfo!=null && isZFQZ) {
//                errMsg.append("单据号：").append(billNum).append("，已存在支付流水，为防止重复付款，无法提交。请联系运维核查数据\r\n");
//                isZFQZ = false;
//            }

            //是否资金调度逻辑，用新增入口
            boolean IS_TRANSFER = false;//判断是否资金调度
            String entrance = payBillEntity.get("entrance") + "";
            if ("SYN".equals(entrance) || "SPAN".equals(entrance)) {
                IS_TRANSFER = true;
            }
//            if(IS_TRANSFER){
//                isZFQZ = false;
//                errMsg.append("单据号：").append(billNum).append("，跨主体调拨或者同名转账~\r\n");
//            }

            /***
             * 根据付款单结算方式，结算方式类似承兑的调用资金的票据接口，结算方式为其他的调用资金的对外付款接口
             */
            String JKNO = "";
            String settletype = payBillEntity.get("settletype.number") + "";

            if (settletype != null && !"".equals(settletype)) {
                if (settletype.equals("BILL")) {//票据
                    JKNO = "JY-NSTC-T002";
                } else {
                    JKNO = "JY-NSTC-T001";
                }
            } else {
                isZFQZ = false;
                errMsg.append("单据号：").append(billNum).append("，结算方式为空~\r\n");
            }


            //付款单审批时校验未上线银行基础数据资料表,待补充
            /***
             * 审批时校验,如果资金银企行号包含，则提交九恒星，否则不提交。
             */


            String qjjson = "";
            if (isZFQZ) {
                //构建请求对象
                qjjson = createSinglePaymentRequest(payBillEntity, JKNO);
                if (qjjson == null) {
                    isZFQZ = false;
                    errMsg.append("单据号：").append(billNum).append("，无法拼出正确的json请求~\r\n");
                }
            }

            if (!isZFQZ) {
                continue;
            }

            log.info("单据号：" + billNum + "传入参数" + qjjson);
            if ("".equals(url)) {
                url = "http://172.16.150.71:7081/FDLKF_OUTER/webservice/TxServiceGateway";
            }

            Date dd = new Date();
//            JSONObject cbsReturnJson = httpjhxService(url, qjjson);

//            log.info("单据号：" + billNum + "返回参数" + cbsReturnJson.toString());
//            //存入日志表
//            saveAgentlog(payBillEntity, qjjson, cbsReturnJson.toString(), "1");

            /***************************************add by wanghaiwu 20225/05/24*************************************************************/
            //改成调用restful ebs api的方式

            Map<String, String> tokenMap = getNtscToken();

            if(tokenMap == null){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口异常, 获取token失败");
                errMsg.append("\r\n");
                return errMsg.toString();
            }

            if(!"0".equals(tokenMap.get("code"))){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口异常, 获取token失败, " + tokenMap.get("msg"));
                errMsg.append("\r\n");
                return errMsg.toString();
            }

            String token = tokenMap.get("msg");

            //改成调用轻舟的方式
            Map<String, String> header = new HashMap<>();
            header.put("Content-Type", "application/json; charset=UTF-8");
            header.put("Authorization", "Bearer " + token);

            //如果是esb接口，需要包一层参数
            if(isESBApi) {
                qjjson = buildEsbApiBodyJSON(new JSONObject(qjjson));
            }

            String apiResult = "";
            try {
                apiResult = HttpUtils.postjson(url, header, qjjson);
            } catch (IOException e) {
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口异常, " + e.getMessage());
                errMsg.append("\r\n");
                return errMsg.toString();
            }

            if(StringUtils.isEmpty(apiResult)){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口无法连通，未获取到返回结果");
                errMsg.append("\r\n");

                return errMsg.toString();
            }

            log.info("单据号：" + billNum + "返回参数" + apiResult);
            //存入日志表
            savelog(payBillEntity, qjjson, apiResult);

            JSONObject esbReturnJson = new JSONObject(apiResult);
            if(esbReturnJson.get("responseData") == null){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("未正常返回responseData参数");
                errMsg.append("\r\n");

                return errMsg.toString();
            }

            JSONArray esbJSONArray = esbReturnJson.getJSONArray("responseData");
            if(esbJSONArray == null || esbJSONArray.length() == 0){
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("未正常返回responseData参数");
                errMsg.append("\r\n");

                return errMsg.toString();
            }

            JSONObject cbsReturnJson = esbJSONArray.getJSONObject(0);
            /************************************************************/

            if (cbsReturnJson == null) {
                isSuccess = false;
                errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                errMsg.append("错误号：").append("XXXXXXX");
                errMsg.append("，错误原因：").append("接口无法连通，未获取到返回结果");
                errMsg.append("\r\n");
            }

            if (!"000000".equals(cbsReturnJson.get("resultCode"))) {
                isSuccess = false;
                String resultCode = cbsReturnJson.get("resultCode")+"";
                String resultMsg = cbsReturnJson.get("resultMsg") + "";
                if("JFXXXXC".equals(resultCode)){//超时，有可能成功，所以不处理
                    isSuccess = false;
                    errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                    errMsg.append("错误号：").append(cbsReturnJson.get("resultCode"));
                    errMsg.append("，错误原因：").append(resultMsg);
                    errMsg.append("\r\n");
                }else if (resultMsg.indexOf("单据是非驳回状态") >= 0 || resultMsg.indexOf("付款指令重复") >= 0) {//指令重复，说明已经传过去了，改状态为支付中，查询结果
                    isSuccess = true;
                    errMsg.append("单据号：").append(billNum).append("付款指令重复，说明已推送到资金系统！");
                    payBillEntity.set("nckd_fkcs", fkcs + 1);//付款次数+1
                    payBillEntity.set("nckd_sbyy", "指令重复，已推送到资金系统");//返回信息
                    payBillEntity.set("nckd_tjyhsj", dd);//返回信息
                    payBillEntity.set("nckd_paystatus", 2);//支付中
                } else { //如果不是驳回或重发，失败
                    errMsg.append("单据号：").append(billNum).append(",推送资金系统失败，");
                    errMsg.append("错误号：").append(cbsReturnJson.get("resultCode"));
                    errMsg.append("，错误原因：").append(resultMsg);
                    errMsg.append("\r\n");
                    payBillEntity.set("nckd_fkcs", fkcs + 1);//付款次数+1
                    payBillEntity.set("nckd_paystatus", 4);//传输失败
                    payBillEntity.set("nckd_sbyy", cbsReturnJson.get("resultMsg") + "");//错误信息
                    SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
                }
            } else if ("000000".equals(cbsReturnJson.get("resultCode"))) {//已受理，改为支付中
                String resultMsg = cbsReturnJson.get("resultMsg") + "";
                if ("SUCCESS".equals(resultMsg)) {
                    isSuccess = true;
                    errMsg.append("单据号：").append(billNum).append("，推送资金系统成功！");
                    payBillEntity.set("nckd_fkcs", fkcs + 1);//付款次数+1
                    payBillEntity.set("nckd_sbyy", "传输成功");//返回信息
                    payBillEntity.set("nckd_tjyhsj", dd);//返回信息
                    payBillEntity.set("nckd_paystatus", 2);//支付中
                }
            }

            if (isSuccess) {
                SaveServiceHelper.update(new DynamicObject[]{payBillEntity});
            }
        }
        return errMsg.toString();
    }


    public static void saveAgentlog(DynamicObject payBillEntity, String qqbw, String fhbw, String type) {
        try {
            DynamicObject logInfo = new DynamicObject(EntityMetadataCache.getDataEntityType("nckd_dfjkdyrz"));
            String channelserno = payBillEntity.getString("billno");
            logInfo.set("number", channelserno);
            if ("1".equals(type)) {
                logInfo.set("name", payBillEntity.get("billno") + "支付数据传输日志");
            } else if ("6".equals(type)) {
                logInfo.set("name", payBillEntity.get("billno") + "代发单支付信息查询日志");
            }
            logInfo.set("nckd_jklx", type);
            logInfo.set("status", "A");
            logInfo.set("enable", "1");
            Calendar currentdate = Calendar.getInstance();
            logInfo.set("nckd_redate", currentdate.getTime());
            logInfo.set("nckd_billno", payBillEntity.get("billno"));
            logInfo.set("nckd_payid", payBillEntity.getPkValue() + "");
            logInfo.set("nckd_qqbw_tag", qqbw);
            logInfo.set("nckd_fhbw_tag", fhbw);
            logInfo.set("nckd_redate", new Date());

            logInfo.set("nckd_djlx", "2");
            OperationServiceHelper.executeOperate("save", "nckd_zfjkdyrz", new DynamicObject[]{logInfo});

        } catch (Exception e) {
            log.info("保存日志报错" + e.getMessage());

        }


    }

    public static void savePayDayChecklog(String qqbw, String fhbw) {
        try {
            DynamicObject logInfo = new DynamicObject(EntityMetadataCache.getDataEntityType("nckd_paydaycheck"));
            Calendar currentdate = Calendar.getInstance();
            String enddzrq = TypeUtils.date2String(currentdate.getTime(), "yyyy-MM-dd HH:mm:ss");

            logInfo.set("number", enddzrq);
            logInfo.set("name", enddzrq + "付款日结查询日志");
            logInfo.set("status", "A");
            logInfo.set("enable", "1");
            logInfo.set("nckd_qqbw_tag", qqbw);
            logInfo.set("nckd_fhbw_tag", fhbw);
            OperationServiceHelper.executeOperate("save", "nckd_paydaycheck", new DynamicObject[]{logInfo});

        } catch (Exception e) {
            log.info("保存日志报错" + e.getMessage());

        }


    }


    public static void savelog(DynamicObject payBillEntity, String qqbw, String fhbw) {
        try {
            DynamicObject logInfo = new DynamicObject(EntityMetadataCache.getDataEntityType("nckd_zfjkdyrz"));
            String channelserno = payBillEntity.get("billno") + "-" + payBillEntity.getInt("nckd_bbh");
            logInfo.set("number", channelserno);
            logInfo.set("name", payBillEntity.get("billno") + "付款日志");
            logInfo.set("status", "A");
            logInfo.set("enable", "1");
            Calendar currentdate = Calendar.getInstance();
            logInfo.set("nckd_redate", currentdate.getTime());
            logInfo.set("nckd_billno", payBillEntity.get("billno"));
            logInfo.set("nckd_payid", payBillEntity.getPkValue() + "");
            logInfo.set("nckd_qqbw_tag", qqbw);
            logInfo.set("nckd_fhbw_tag", fhbw);
            logInfo.set("nckd_redate", new Date());

            logInfo.set("nckd_djlx", "1");
            OperationServiceHelper.executeOperate("save", "nckd_zfjkdyrz", new DynamicObject[]{logInfo});

        } catch (Exception e) {
            log.info("保存日志报错" + e.getMessage());

        }


    }


    public static void saveupdatelog(DynamicObject payBillEntity, String qqbw, String fhbw) {
        try {
            DynamicObject logInfo = new DynamicObject(EntityMetadataCache.getDataEntityType("nckd_zfcxjkrz"));
            String channelserno = payBillEntity.get("billno") + "-" + payBillEntity.getInt("nckd_bbh");
            logInfo.set("number", channelserno);
            logInfo.set("name", payBillEntity.get("billno") + "查询状态日志");
            logInfo.set("status", "A");
            logInfo.set("enable", "1");
            Calendar currentdate = Calendar.getInstance();
            logInfo.set("nckd_redate", currentdate.getTime());
            logInfo.set("nckd_billno", payBillEntity.get("billno"));
            logInfo.set("nckd_payid", payBillEntity.getPkValue() + "");
            logInfo.set("nckd_qqbw_tag", qqbw);
            logInfo.set("nckd_fhbw_tag", fhbw);
            logInfo.set("nckd_redate", new Date());

            logInfo.set("nckd_djlx", "1");
            OperationServiceHelper.executeOperate("save", "nckd_zfcxjkrz", new DynamicObject[]{logInfo});

        } catch (Exception e) {
            log.info("保存日志报错" + e.getMessage());

        }


    }

    public static JSONObject httpjhxService(String url, String qjjson) {
        String result = "";
        try {
            Date d1 = new Date();
            TxServiceGatewayProxy txServiceGatewayProxy = new TxServiceGatewayProxy("", url);
            result = txServiceGatewayProxy.send(qjjson);

            Date d2 = new Date();

            long diffs = Math.abs(d2.getTime() - d1.getTime()) / 1000;
            JSONObject jsonObject = new JSONObject(result);
            if (jsonObject != null) {
                if ("{}".equals(jsonObject.toString()) || "".equals(result)) {
                    if (diffs > 60) {//超时

                        jsonObject.put("resultCode", "JFXXXXC");
                        jsonObject.put("resultMsg", "超时");

                    }

                }
                jsonObject.put("请求时间", TypeUtils.date2String(d1, TypeUtils.DEFAULT_TIMESTAMP_FORMAT));
                jsonObject.put("返回时间", TypeUtils.date2String(d2, TypeUtils.DEFAULT_TIMESTAMP_FORMAT));
                jsonObject.put("响应时长", diffs + "");
            }
            return jsonObject;
        } catch (IOException e) {
            e.printStackTrace();
            log.info(e.getMessage());
        }
        return null;
    }


    public static JSONObject JHXServiceQuery(String url, String bodyjson) {
        try {
            Date d1 = new Date();
            TxServiceGatewayProxy txServiceGatewayProxy = new TxServiceGatewayProxy("", url);
            String result = txServiceGatewayProxy.send(bodyjson);

            Date d2 = new Date();

            long diffs = Math.abs(d2.getTime() - d1.getTime()) / 1000;

            JSONObject jsonObject = new JSONObject(result);
            if (jsonObject != null || "".equals(result) || result == null) {
                if ("{}".equals(jsonObject.toString())) {
                    if (diffs > 60) {//超时

                        jsonObject.put("resultCode", "JFXXXXC");
                        jsonObject.put("resultMsg", "超时");
                    }

                }
                jsonObject.put("请求时间", TypeUtils.date2String(d1, TypeUtils.DEFAULT_TIMESTAMP_FORMAT));
                jsonObject.put("返回时间", TypeUtils.date2String(d2, TypeUtils.DEFAULT_TIMESTAMP_FORMAT));
                jsonObject.put("响应时长", diffs + "");
            }

            return jsonObject;
        } catch (IOException e) {
            e.printStackTrace();
            log.info(e.getMessage());
        }
        return null;
    }

    public static Map<String,String> getNtscToken() {
        Map<String,String> returnMap = new HashMap<>();

        Map<String, String> mapentity = CommonHelperUtils.getCommonParams("nstc");
        if(mapentity == null ){
            log.info("PayBillTollUtil：nckd_entryentity is null");

            returnMap.put("code", "1");
            returnMap.put("msg", "未配置九恒星系统对接参数！");
            return returnMap;
        }

        String getTokenApi = mapentity.get("gettoken");
        String grantType = mapentity.get("grant_type");
        String clientId = mapentity.get("client_id");
        String clientSecret = mapentity.get("client_secret");


        if(kd.bos.util.StringUtils.isEmpty(getTokenApi) || kd.bos.util.StringUtils.isEmpty(grantType)
                || kd.bos.util.StringUtils.isEmpty(clientId) || kd.bos.util.StringUtils.isEmpty(clientSecret)){
            returnMap.put("code", "1");
            returnMap.put("msg", "请检查是否配置九恒星获取token参数：gettoken、grant_type、client_id、client_secret");
            return returnMap;
        }


        try {
            JSONObject jsonData = new JSONObject();
            jsonData.put("grant_type", grantType);
            jsonData.put("client_id", clientId);
            jsonData.put("client_secret", clientSecret);

            String response = KHttpClientUtils.postjson(getTokenApi, null, jsonData.toString());
            if(StringUtils.isEmpty(response)){
                returnMap.put("code", "1");
                returnMap.put("msg", "获取token失败, getToken返回为空");

                return returnMap;
            }

            JSONObject resultJSON = new JSONObject(response);
            if (resultJSON !=null &&!StringUtils.isEmpty(resultJSON.get("accessToken").toString())) {
                returnMap.put("code", "0");
                returnMap.put("msg", resultJSON.get("accessToken").toString());
            } else{
                returnMap.put("code","1");
                returnMap.put("msg", response);
            }

            return returnMap;
        } catch(IOException e){
            returnMap.put("code", "1");
            returnMap.put("msg", "获取token失败, " + e.getMessage());

            return returnMap;
        } catch(Exception e){
            returnMap.put("code", "1");
            returnMap.put("msg", "获取token失败, " + e.getMessage());

            return returnMap;
        }
    }


    public static String buildEsbApiBodyJSON(JSONObject inputData){
        JSONObject jsonBody = new JSONObject();

        //requestHead参数
        JSONObject requestHead = new JSONObject();

        requestHead.put("system", "");
        requestHead.put("tenantId", "");
        requestHead.put("apiversion", "");
        requestHead.put("timestamp", "");
        requestHead.put("retrycount", "");
        requestHead.put("mainBodyId", "JY");
        requestHead.put("mainBodyEx1", "");
        requestHead.put("mainBodyEx2", "");
        requestHead.put("mainBodyEx3", "");

        jsonBody.put("requestHead", requestHead);

        //requestData参数
        JSONArray requestData = new JSONArray();
        if(inputData != null) {
            requestData.put(inputData);
        }
        jsonBody.put("requestData", requestData);

        return jsonBody.toString();
    }

}
