package com.engine.htsc.trip.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.api.htsc.businessMethod.SubUnionBizUtil;
import com.engine.core.impl.Service;
import com.engine.htsc.common.utils.DoubleUtil;
import com.engine.htsc.payment.util.PayUtil;
import com.engine.htsc.trip.pojo.AllowancePO;
import com.engine.htsc.trip.service.ReimbursementService;
import com.engine.htsc.trip.util.LogUtil;
import com.engine.htsc.trip.util.WeaverUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import weaver.conn.RecordSet;
import weaver.conn.RecordSetDataSource;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.company.DepartmentComInfo;
import weaver.hrm.resource.ResourceComInfo;
import weaver.interfaces.htsc.comInfo.PropBean;
import weaver.interfaces.htsc.cus.HTUtil;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by qlk
 */
public class ReimbursementServiceImpl extends Service implements ReimbursementService {

    private final Logger log = LoggerFactory.getLogger(ReimbursementServiceImpl.class);

    @Override
    public List<List<String>> bringDt12(String formTable, String requestIds) {
        RecordSet rs = new RecordSet();
        RecordSet rs2 = new RecordSet();
        RecordSet rs3 = new RecordSet();
        if ("".equals(requestIds)) {
            return null;
        }
        String[] requests = requestIds.split(",");

        String sql_bringOut_Bt_main = "SELECT id,sfhwcc,cclx,cclxzxx FROM " + formTable + " WHERE requestid = ?";
        String sql_bringOut_Bt_detail2 = "SELECT xm FROM " + formTable + "_dt2 WHERE mainid = ?";
        String sql_bringOut_Bt_detail2_name = "SELECT lastname FROM hrmresource WHERE id = ?";
        List<List<String>> result = new ArrayList<>();
        List<String> singleRequestInfo;
        String id;
        String name;
        for (String request : requests) {
            singleRequestInfo = new ArrayList<>();
            rs.executeQuery(sql_bringOut_Bt_main, new Object[]{request});
            if (rs.next()) {
                singleRequestInfo.add(Util.null2String(rs.getString("sfhwcc")));
                singleRequestInfo.add(Util.null2String(rs.getString("cclx")));
                singleRequestInfo.add(Util.null2String(rs.getString("cclxzxx")));
                id = Util.null2String(rs.getString("id"));
                rs2.executeQuery(sql_bringOut_Bt_detail2, new Object[]{id});
                while (rs2.next()) {
                    name = Util.null2String(rs2.getString("xm"));
                    singleRequestInfo.add(name);
                    rs3.executeQuery(sql_bringOut_Bt_detail2_name, new Object[]{name});
                    if (rs3.next()) {
                        singleRequestInfo.add(rs3.getString("lastname"));
                    }
                }
            }
            result.add(singleRequestInfo);
        }

        return result;
    }

    @Override
    public List<List<String>> bringDt13(String formTable, String requestIds) {
        RecordSet rs = new RecordSet();
        String[] requests = requestIds.split(",");
        String sql_bringOut_Bt_detail3 = "select c.lastname,d.cfsj,'9:00' as s,d.fhsj,'18:00' as s1,d.cfdgn,d.mddgn\n" +
                " from formtable_main_27 a\n" +
                " left join formtable_main_27_dt2 b\n" +
                " on a.id=b.mainid\n" +
                " left join hrmresource c\n" +
                " on b.xm=c.id\n" +
                " left join formtable_main_27_dt3 d\n" +
                " on a.id=d.mainid\n" +
                " where requestid=?";
        List<List<String>> results = new ArrayList<>();
        ;
        List<String> info;
        for (String request : requests) {
            rs.executeQuery(sql_bringOut_Bt_detail3, new Object[]{request});
            while (rs.next()) {
                info = new ArrayList<>();
                info.add(Util.null2String(rs.getString("lastname")));
                info.add(Util.null2String(rs.getString("cfsj")));
                info.add(Util.null2String(rs.getString("s")));
                info.add(Util.null2String(rs.getString("fhsj")));
                info.add(Util.null2String(rs.getString("s1")));
                info.add(Util.null2String(rs.getString("cfdgn")));
                info.add(Util.null2String(rs.getString("mddgn")));
                results.add(info);
            }
        }
        return results;
    }

    @Override
    public Map<String, Object> bringClaimant(String formTable, String requestIds) {
        String[] requests = requestIds.split(",");
        RecordSet rs = new RecordSet();
        String sql_bringOut_Main_Claimant = "select c.lastname,c.id,c.loginid\n" +
                " from" + formTable + "a \n" +
                " left join " + formTable + "_dt2 b\n" +
                " on a.id=b.mainid\n" +
                " left join hrmresource c\n" +
                " on b.xm=c.id\n" +
                " where requestid in (" + StringUtils.join(requests, ",") + ")";

        List<String> hrmIds = new ArrayList<>();
        List<String> hrmNames = new ArrayList<>();
        List<String> hrmLoginIds = new ArrayList<>();
        rs.execute(sql_bringOut_Main_Claimant);
        while (rs.next()) {
            hrmIds.add(Util.null2String(rs.getString("id")));
            hrmNames.add(Util.null2String(rs.getString("lastname")));
            hrmLoginIds.add(Util.null2String(rs.getString("loginid")));
        }

        hrmIds = hrmIds.stream().distinct().collect(Collectors.toList());
        hrmNames = hrmNames.stream().distinct().collect(Collectors.toList());
        hrmLoginIds = hrmLoginIds.stream().distinct().collect(Collectors.toList());

        Map<String, Object> result = new HashMap<>();
        result.put("value", hrmIds);
        result.put("specialobj", hrmNames);
        result.put("loginIds", hrmLoginIds);
        return result;
    }

    @Override
    public Boolean checkLeader(String ngr) {
        RecordSet rs = new RecordSet();
        String loginid = "";
        List<String> leader = new ArrayList<>();
        leader.add("002257");
        leader.add("002501");
        leader.add("002603");
        leader.add("001903");
        leader.add("006446");
        leader.add("002151");
        leader.add("004209");
        leader.add("010301");
        leader.add("010524");
        leader.add("004919");
        leader.add("001526");
        leader.add("002509");
        leader.add("010480");
        leader.add("010517");

        String sql_is_leader = "SELECT loginid FROM hrmresource WHERE id=" + ngr;
        rs.execute(sql_is_leader);
        while (rs.next()) {
            loginid = Util.null2String(rs.getString("loginid"));
        }
        if ("".equals(loginid)) {
            return false;
        }
        return leader.contains(loginid);
    }

    @Override
    public List<Map<String, Object>> getApInfo(String lcs) {
        RecordSet rs = new RecordSet();
        List<Map<String, Object>> res = new ArrayList<>();
        String unionReWfid = Util.null2String(new PropBean().getPropName("unionReWfid"));
        String unionReWfidstr = Util.null2String(new PropBean().getWorkflowIdsByUnNumber(unionReWfid));
        List<String> unionReWfidWF = Arrays.asList(unionReWfidstr.split(","));
        String unionwfid = Util.null2String(new PropBean().getPropName("unionwfid"));
        String unionwstr = Util.null2String(new PropBean().getWorkflowIdsByUnNumber(unionwfid));
        List<String> unionwfidWF = Arrays.asList(unionwstr.split(","));
        //报销表单
        String tableNameRe = WeaverUtil.getTableNameByWfid(Util.getIntValue(unionReWfidWF.get(0)));
        //出差表单
        String tableNameCc = WeaverUtil.getTableNameByWfid(Util.getIntValue(unionwfidWF.get(0)));
        String[] lcArr = lcs.split(",");
        String sql4name = "";
        String sql4times = "";
        Map<String, Object> item;
        for (String lc : lcArr) {
            item = new HashMap<>();
            sql4name = "select lcbh from " + tableNameCc + " where requestid=" + lc;
            rs.execute(sql4name);
            if (rs.next()) {
                item.put("requestName", Util.null2String(rs.getString("lcbh")));
            }
            sql4times = "select count(*) as n from " + tableNameRe +
                    " where glcclc like '%" + lc + "%'";
            rs.execute(sql4times);
            if (rs.next()) {
                item.put("requestTimes", Util.null2String(rs.getString("n")));
            }
            res.add(item);
        }
        return res;
    }

    @Override
    public Map<String, Object> getBrowserBtn(String ccr, String lc) {
        RecordSet rs = new RecordSet();
        Map<String, Object> addObj = new HashMap<>();
        if ("".equals(lc)) {
            return addObj;
        }
        List<String> lcs = Arrays.asList(lc.split(",")); //多条流程
        String tableName = ""; //根据流程id获取流程表名
        String query_tablename = "select t1.tablename from workflow_bill t1,workflow_base t2,workflow_requestbase t3\n" +
                " where t1.id =t2.formid and t2.id = t3.workflowid and t3.requestid=" + lcs.get(0);
        rs.execute(query_tablename);
        if (rs.next()) {
            tableName = Util.null2String(rs.getString("tablename"));
        }
        if ("".equals(tableName)) {
            return addObj;
        }
        String sql = "select DISTINCT t1.id,departmentname from hrmdepartment t1\n" +
                " left join " + tableName + "_dt2 t2\n" +
                " on t2.fycdbm=t1.id\n" +
                " left join " + tableName + " t3\n" +
                " on t2.mainid=t3.id\n" +
                " where t3.requestid in (" + lc + ") and t2.xm=" + ccr;

        List<String> values = new ArrayList<>();
        List<String> depNames = new ArrayList<>();
        rs.execute(sql);
        while (rs.next()) {
            values.add(rs.getString("id"));
            depNames.add(rs.getString("departmentname"));
        }


        addObj.put("value", StringUtils.join(values, ","));

        List<Map<String, String>> specialobj = new ArrayList<>();
        Map<String, String> item;
        for (int i = 0; i < values.size(); i++) {
            item = new HashMap<>();
            item.put("id", values.get(i));
            item.put("name", depNames.get(i));
            specialobj.add(item);
        }
        addObj.put("specialobj", specialobj);

        return addObj;
    }

    @Override
    public Map<String, String> getBankInfo(String ngr, String bxr) {
        RecordSet rs = new RecordSet();
        Map<String, String> res = new HashMap<>();
        //拟稿人工号
        String ngrLoginId = WeaverUtil.convertIdToLoginId(ngr, rs);
        //报销人工号
        String bxrLoginId = WeaverUtil.convertIdToLoginId(bxr, rs);
        RecordSetDataSource rsd = new RecordSetDataSource("BankInfo"); //银行信息数据源,华泰方提供
        String sql = "select DISTINCT t2.bankname,t2.cnaps,t3.cardno,t1.provinces,t1.city from emp_common_bankinfo t1\n" +
                " left join t_depositbank t2\n" +
                " on t1.id=t2.id\n" +
                " left join t_bankAccount t3\n" +
                " on t1.id=t3.id\n" +
                " where t1.badge='" + bxrLoginId + "'" +
                " and t1.defender='" + ngrLoginId + "'";
        rsd.execute(sql);
        while (rsd.next()) {
            res.put("khh", Util.null2String(rsd.getString("bankname"))); //开户行
            res.put("cnaps", Util.null2String(rsd.getString("cnaps"))); //开户行编码
            res.put("yhkh", Util.null2String(rsd.getString("cardno"))); //银行卡号
            res.put("province", Util.null2String(rsd.getString("provinces"))); //省或直辖市
            res.put("city", Util.null2String(rsd.getString("city"))); //市
        }
        return res;
    }

    @Override
    public List<String> getTravelStandardForSingle(String traveler, String destination) {
        RecordSet rs = new RecordSet();
        String[] desInfo = destination.split(","); //省市区
        String ids = Arrays.asList(desInfo).stream().map(s -> "\'" + s + "\'").collect(Collectors.joining(","));
        List<String> standardMsg = new ArrayList<>();
        //回传信息
        String msg = null;
        //城市信息
        //甲类城市
        String[] cityA = {"34", "112", "246", "248", "128", "338", "284", "99"};
        List<String> cityAList = Arrays.asList(cityA);
        //乙类城市
        String[] cityB = {"75", "118", "283", "287", "357", "289", "434273726", "180", "935078239", "179", "157", "197", "30002", "216", "231", "321", "81095659", "126111795", "387", "35", "158", "381", "30003", "311", "49", "346", "74", "89", "114", "129"};
        List<String> cityBList = Arrays.asList(cityB);
        //丙类城市 不包含a,b的
        //人员信息
        //公司领导(董事会487,执行委员会489,党委713)+2
        //去除执行委员会
        List<String> deptLeader = new ArrayList<>();
        String sql_dept = "SELECT id FROM hrmresource WHERE departmentid IN ('487','489','713') AND id IS NOT NULL";
        rs.execute(sql_dept);
        while (rs.next()) {
            deptLeader.add(rs.getString("id"));
        }
        deptLeader.add("6633"); //合规总监,李洪涛
        deptLeader.add("5891"); //宁敖
        //判断标识,匹配金额
        //获取后台部门
        PropBean pp = new PropBean();
        String backdept = pp.getPropName("backdept");
        log.info("====获取配置表中数据:{}", backdept);
        int code = 2;
        if (deptLeader.contains(traveler)) {
            //traveler是实报实销的
            standardMsg.add(null + "|" + null);
            return standardMsg;
        } else {
            //需要判断逻辑,给traveler赋一个code
            //中后台部门 id >> '495','671','717','493','494'
            String sql_traveler_isNot_middle_backstage = "SELECT COUNT(*) AS cnt FROM hrmresource WHERE departmentid IN (" + backdept + ") AND id = ?";
            rs.executeQuery(sql_traveler_isNot_middle_backstage, new Object[]{traveler});
            rs.next();
            if (rs.getInt("cnt") == 1) { //属于中后台
                RecordSet recordSet = new RecordSet();
                String sql_SD_D = "SELECT t1.ID,t1.field9 as field,t2.LOGINID FROM cus_fielddata t1\n" +
                        " left join HRMRESOURCE t2\n" +
                        " on t1.ID=t2.ID\n" +
                        " WHERE t1.scopeid=1 and t1.ID = ?";
                recordSet.executeQuery(sql_SD_D, new Object[]{traveler});
                log.info("==当前人员为中后台");
                if (recordSet.next()) {
                    String field = recordSet.getString("field");
                    String loginid = recordSet.getString("LOGINID");
                    log.info("==当前人员:{},当前职级{}", traveler, field);
                    if ("SD".equals(field) || "D".equals(field)) {
                        code = 1; //traveler属于SD,D
                        log.info("==匹配人员code:{}", code);
                    } else {
                        code = 2; // SS及以下
                        //判断是否为实习生
                        if (loginid.startsWith("sx")) {
                            code = 3;
                        }
                        log.info("==匹配人员code:{}", code);
                    }
                }
            } else {
                //属于前台
                RecordSet recordSet = new RecordSet();
                String sql_MD_ED = "SELECT t1.ID,t1.field9 as field,t2.LOGINID FROM cus_fielddata t1\n" +
                        " left join HRMRESOURCE t2\n" +
                        " on t1.ID=t2.ID\n" +
                        " WHERE t1.scopeid=1 and t1.ID = ?";
                recordSet.executeQuery(sql_MD_ED, new Object[]{traveler});
                log.info("==当前人员为前台");
                if (recordSet.next()) {
                    String field = recordSet.getString("field");
                    String loginid = recordSet.getString("LOGINID");
                    log.info("==当前人员:{},当前职级{}", traveler, field);
                    if ("MD".equals(field) || "ED".equals(field)) {
                        code = 1; //属于SD,D
                    } else {
                        code = 2; //D及以下
                        //判断是否为实习生
                        if (loginid.startsWith("sx")) {
                            code = 3;
                        }
                        log.info("==匹配人员code:{}", code);
                    }
                }
            }
        }

        //code和地区信息组合
        String city = desInfo[1]; //城市,匹配地区信息
        //根据业务，新增L3P差标
        //获取匹配L3P差标人员配置
        Set<String> l3pTravelStandardSet = new HashSet<>(Arrays.asList(pp.getPropName("travel_standard_l3p").split(",")));
        //获取出差人员的华泰工号
        String htWorkCode = "";
        String getHTWorkCodeSql = "select workcode from hrmresource where id = ?";
        rs.executeQuery(getHTWorkCodeSql, traveler);
        while (rs.next()) {
            htWorkCode = rs.getString("workcode");
        }
        if (l3pTravelStandardSet.contains(htWorkCode)) {
            if (cityAList.contains(city)) {
                msg = "1680";
            } else if (cityBList.contains(city)) {
                msg = "1200";
            } else {
                msg = "960";
            }
            //提高机票差标
            msg = String.join("|", msg, "软卧、一等座", "商务舱", "二等舱");
        } else {
            if (code == 1) {
                if (cityAList.contains(city)) {
                    msg = "1680";
                } else if (cityBList.contains(city)) {
                    msg = "1200";
                } else {
                    msg = "960";
                }
                //交通
                if (!"6483".equals(traveler) || !"6579".equals(traveler) || !"2906".equals(traveler)) { //协管领导 L2：职级调整联合出差标准调整（董光启、王超）
                    msg = String.join("|", msg, "软卧、一等座", "经济舱", "二等舱");
                } else {
                    msg += "|" + null;
                }
            } else if (code == 2) {
                if (cityAList.contains(city)) {
                    msg = "1200";
                } else if (cityBList.contains(city)) {
                    msg = "840";
                } else {
                    msg = "672";
                }
                //交通
                if (!"7981".equals(traveler)) { //协管领导
                    msg = String.join("|", msg, "软卧、一等座", "经济舱", "二等舱");
                } else {
                    msg += "|" + null;
                }
            } else if (code == 3) {
                //实习生
                if (cityAList.contains(city)) {
                    msg = "1000";
                } else if (cityBList.contains(city)) {
                    msg = "700";
                } else {
                    msg = "560";
                }
                //交通
                if (!"7981".equals(traveler)) { //协管领导
                    msg = String.join("|", msg, "硬座、二等座", "无", "三等舱");
                } else {
                    msg += "|" + null;
                }
            }
        }

        //遍历查询城市信息
        RecordSetDataSource rsd = new RecordSetDataSource("Travel"); //城市
        for (String des : desInfo) {
            des += "','" + des;
        }
        String sql = "select name from travel_area where code in (" + ids + ") order by instr('" + destination + "',code)";
        List<String> names = new ArrayList<>();
        rsd.execute(sql);
        while (rsd.next()) {
            names.add(rsd.getString("name"));
        }
        msg = String.join("|", msg, String.join(",", names));
        standardMsg.add(msg);
        return standardMsg;
    }

    @Override
    public Map<String, Object> getGsxmBrowserBtn(String ccr, String lc) {
        RecordSet rs = new RecordSet();
        Map<String, Object> addObj = new HashMap<>();
        if ("".equals(lc)) {
            return addObj;
        }
        String tableName = ""; //根据流程id获取流程表名
        String query_tablename = "select t1.tablename from workflow_bill t1,workflow_base t2,workflow_requestbase t3\n" +
                " where t1.id =t2.formid and t2.id = t3.workflowid and t3.requestid=" + lc;
        rs.execute(query_tablename);
        if (rs.next()) {
            tableName = Util.null2String(rs.getString("tablename"));
        }
        if ("".equals(tableName)) {
            return addObj;
        }
        String sql = "select t2.workcode,t1.xmjc from " + tableName + " t1\n" +
                " left join hrmresource t2\n" +
                " on t1.ngr=t2.id\n" +
                " where t1.requestid=" + lc;
        rs.execute(sql);
        String workcode = "";
        String xmjc = "";
        if (rs.next()) {
            workcode = Util.null2String(rs.getString("workcode"));
            xmjc = Util.null2String(rs.getString("xmjc"));
        }
        if ("".equals(xmjc)) {
            return addObj;
        }
        //xmjc=项目id
        Map<String, Object> paras = new HashMap<>();
        paras.put("projectId", xmjc);
        String res = new HTUtil().getProjectById(paras);
        new BaseBean().writeLog("===getGsxmBrowserBtn===" + res);
        if ("".equals(res)) {
            return addObj;
        }
        JSONObject jsonObject = JSONObject.parseObject(res);
        String shortName = jsonObject.getString("shortName");
        addObj.put("id", xmjc);
        addObj.put("shortName", shortName);
        return addObj;
    }

    @Override
    public List<String> getAccountingByLocation(String bxd) {
        RecordSet rs = new RecordSet();
        List<String> res = new ArrayList<>();
        String sql = "select fyhj from uf_fykjjd where bgdd in (" + bxd + ") order by instr('" + bxd + "',bgdd)";
        rs.execute(sql);
        while (rs.next()) {
            res.add(Util.null2String(rs.getString("fyhj")));
        }
        return res;
    }

    @Override
    public Map<String, String> getBankInfoFormOADB(String hrmId) {
        RecordSet rs = new RecordSet();
        String workcode = WeaverUtil.convertIdToLoginId(hrmId, rs);
        Map<String, String> returnMap = new HashMap<>();
        String sql = String.format("select * from (\n" +
                "select to_date((MODEDATACREATEDATE ||' '|| MODEDATACREATETIME),'yyyy-mm-dd hh24:mi:ss') as datetime," +
                "khr,yxmc,yxkh,ss,khx from uf_lhclyxxx where khr='%s' order by datetime desc \n" +
                ") where rownum=1", workcode);
        rs.execute(sql);
        if (rs.next()) {
            returnMap.put("yxmc", Util.null2String(rs.getString("yxmc")));
            returnMap.put("yxkh", Util.null2String(rs.getString("yxkh")));
            returnMap.put("ss", Util.null2String(rs.getString("ss")));
            returnMap.put("khx", Util.null2String(rs.getString("khx")));
        }
        return returnMap;
    }

    @Override
    public Map<String, List<String>> getRelatedInfo(String lcs) {
        RecordSet rs = new RecordSet();
        List<String> strings = Arrays.asList(lcs.split(","));
        String unionReWfid = Util.null2String(new PropBean().getPropName("unionReWfid"));
        String unionReWfidstr = Util.null2String(new PropBean().getWorkflowIdsByUnNumber(unionReWfid));
        List<String> unionReWfidWF = Arrays.asList(unionReWfidstr.split(","));
        String unionwfid = Util.null2String(new PropBean().getPropName("unionwfid"));
        String unionwstr = Util.null2String(new PropBean().getWorkflowIdsByUnNumber(unionwfid));
        List<String> unionwfidWF = Arrays.asList(unionwstr.split(","));
        //报销表
        String bxTable = WeaverUtil.getTableNameByWfid(Util.getIntValue(unionReWfidWF.get(0)));
        //出差表
        String ccTable = WeaverUtil.getTableNameByWfid(Util.getIntValue(unionwfidWF.get(0)));
        String lcSQL = "select lcbh from " + ccTable + " where requestid in (" + lcs + ")";
        rs.execute(lcSQL);
        List<String> lcList = new ArrayList<>();
        while (rs.next()) {
            lcList.add(Util.null2String(rs.getString("lcbh")));
        }
        String relateSQL = "";
        Map<String, List<String>> data = new HashMap<>();
        List<String> subData;
        for (int i = 0; i < lcList.size(); i++) {
            subData = new ArrayList<>();
            //统计所有不在拟稿节点的流程
            relateSQL = "select t1.lcbh from " + bxTable + " t1\n" +
                    " left join workflow_requestbase t2\n" +
                    " on t1.REQUESTID=t2.REQUESTID\n" +
                    " where t1.glcclc like '%" + strings.get(i) + "%' and t2.currentnodetype != '0'";
            rs.execute(relateSQL);
            while (rs.next()) {
                subData.add(Util.null2String(rs.getString("lcbh")));
            }
            //单个流程的信息
            data.put(lcList.get(i), subData);
        }
        return data;
    }

    @Override
    public String doBudgetCommit(String requestid, String billStatus) {
        RecordSet rs = new RecordSet();
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LogUtil logUtil = new LogUtil();
        logUtil.writeLog("===出纳按钮,调用预算接口===");

        String tablename = WeaverUtil.getTableNameByRequestId(requestid, rs);

        logUtil.writeLog("[入参: requestid: " + requestid + ", " +
                "tablename: " + tablename + ", billStatus:" + billStatus);

        JSONObject params = new JSONObject();
        HTUtil htUtil = new HTUtil();

        try {
            // 联合子公司通用报销,判断requestId是否属于该流程,true走通用报销逻辑;false走原逻辑
            if (SubUnionBizUtil.equalsTableName(requestid, SubUnionBizUtil.LHTYBX)) {
                String flag = SubUnionBizUtil.doBudgetCommit4Union(requestid, billStatus);
                rs.writeLog(String.format("联合子公司通用报销流程预算返回值: %s, requestid:%s", flag, requestid));
                if ("F1001".equalsIgnoreCase(flag)) {
                    rs.executeUpdate("update uf_zfmx set tbys=0 where reqid=" + requestid);
                    //如果核算同步,更新为已付款
                    rs.executeUpdate("update uf_zfmx set fkzt=0 where reqid=" + requestid + " and tbhs=0");
                }
                return flag;
            }
            // 联合通用付款流程,判断requestId是否属于该流程,true走通用付款逻辑;false走原逻辑
            if (SubUnionBizUtil.equalsTableName(requestid, SubUnionBizUtil.LHTYFK)) {
                String flag = SubUnionBizUtil.doBudgetCommit4UnionFk(requestid, billStatus);
                rs.writeLog(String.format("联合通用付款流程预算返回值: %s, requestid:%s", flag, requestid));
                if ("F1001".equalsIgnoreCase(flag)) {
                    rs.executeUpdate("update uf_zfmx set tbys=0 where reqid=" + requestid);
                    //如果核算同步,更新为已付款
                    rs.executeUpdate("update uf_zfmx set fkzt=0 where reqid=" + requestid + " and tbhs=0");
                }
                return flag;
            }

            //原逻辑
            ResourceComInfo rc = new ResourceComInfo();
            DepartmentComInfo dc = new DepartmentComInfo();
            // 主表
            // 明细表
            String dt8TableName = tablename + "_dt8";
            String dt9TableName = tablename + "_dt9";
            logUtil.writeLog("=====预算接口调用execute,requestId: " + requestid + "====");
            String main_sql = "select t1.lcbh,t1.ngr,t1.id,t2.requestname from " + tablename + " t1\n" +
                    " left join workflow_requestbase t2\n" +
                    " on t1.requestid=t2.requestid\n" +
                    " where t1.requestid=" + requestid;
            logUtil.writeLog("执行main_sql=== " + main_sql);
            rs.execute(main_sql);
            String lcbh = "";
            String requestname = "";
            String ngr = "";
            String mainId = "";
            if (rs.next()) {
                lcbh = Util.null2String(rs.getString("lcbh"));
                requestname = Util.null2String(rs.getString("requestname"));
                ngr = Util.null2String(rs.getString("ngr"));
                mainId = Util.null2String(rs.getString("id"));
            }
            params.put("billnum", requestid);
            params.put("billname", lcbh);
            params.put("billstatus", billStatus);
            params.put("billtitle", requestname);
            params.put("personName", rc.getLastname(ngr));
            params.put("bizdate", df.format(LocalDateTime.now()));
            logUtil.writeLog("参数1" + params);
            //list
            JSONArray levelObjList = new JSONArray();
            JSONObject levelObj;
            String dt8_sql = "select fycdr,yskm as km,ccsqlc from " + dt8TableName + " where mainid=" + mainId;
            logUtil.writeLog("执行dt8_sql===" + dt8_sql);
            rs.execute(dt8_sql);
            int i = 1;
            String km = "";
            String ccsqlc = "";
            while (rs.next()) {
                levelObj = new JSONObject();
                String fycdr = Util.null2String(rs.getString("fycdr"));
                levelObj.put("employeeNum", fycdr);
                levelObj.put("deptNum", Util.null2String(dc.getDepartmentCode(rc.getDepartmentID(fycdr))));
                levelObj.put("bgitem", "86010503");
                levelObj.put("bgElement", "0101");
                levelObj.put("billEntryID", UUID.randomUUID().toString() + "#" + i);
                km = Util.null2String(rs.getString("km"));
                ccsqlc = Util.null2String(rs.getString("ccsqlc"));
                levelObj.put("itemEntryNum", km);
                //科目对应金额
                levelObj.putAll(WeaverUtil.getKjKmCharges(km, dt9TableName, ccsqlc, mainId));
                levelObjList.add(levelObj);
                i++;
            }
            params.put("list", levelObjList);
            logUtil.writeLog("[params]: [" + params + "]");
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("data", params);
            //预算接口调用
            String resp = htUtil.budgetCommit(dataMap);
            logUtil.writeLog("[预算接口response]: 【" + resp + "】");
            if ("F1001".equals(resp)) {
                //更新预算中间表
                Map<String, Object> reqMap = new HashMap<>();
                reqMap.put("lcbm", lcbh);
                reqMap.put("billStatus", billStatus);
                Boolean isUpdate = doBudgetMiddleTable(reqMap);
                if (isUpdate) {
                    //更新uf_zfmx 同步预算,已同步
                    String updateSql = "update uf_zfmx set tbys=0 where reqid=" + requestid;
                    logUtil.writeLog("====更新uf_zfmx, updateSql===" + updateSql);
                    rs.executeUpdate(updateSql);
                    //如果核算同步,更新为已付款
                    rs.executeUpdate("update uf_zfmx set fkzt=0 where reqid=" + requestid + " and tbhs=0");
                }
            }
            return resp;
        } catch (Exception e) {
            logUtil.writeLog("[预算接口response异常]: " + e);
            return "";
        }
    }

    @Override
    public Boolean doBudgetMiddleTable(Map<String, Object> reqMap) {
        if (reqMap.containsKey("lcbm")) {
            LogUtil logUtil = new LogUtil();
            String fname = Util.null2String(reqMap.get("lcbm")); //流程编号
            String billStatus = Util.null2String(reqMap.get("billStatus")); //单据状态
            if ("".equals(fname)) {
                return false;
            }
            logUtil.writeLog("更新预算记录中间表, [" + fname + "]");
            RecordSetDataSource rsd = new RecordSetDataSource("BudgetRecords"); //中间表外部数据源
            String budgetTableName = new PropBean().getPropName("BudgetTableName");
            rsd.execute("select fname from " + budgetTableName + " where fname='" + fname + "'");
            if (rsd.next()) {
                //更新历史数据
//				return WeaverUtil.updateBudgetMiddleTable(fname, billStatus, rsd);
                String deleteAll = String.format("delete from %s where FNAME='%s'", budgetTableName, fname);
                rsd.executeUpdateWithDatasource(deleteAll, "BudgetRecords");
                return WeaverUtil.insertBudgetMiddleTable(fname, billStatus, rsd);
            } else {
                //插入新数据
                return WeaverUtil.insertBudgetMiddleTable(fname, billStatus, rsd);
            }
        } else {
            return false;
        }
    }


    @Override
    public List<Map<String, Object>> monthlyAllowance(Map<String, String> request2Map) {
        RecordSet rs = new RecordSet();
        String mainTable = WeaverUtil.getTableNameByPropName("unionReWfid");
        String date = Util.null2String(request2Map.get("date"));
        //1\判断哪些流程是代付的
        String sql1 = " select distinct t1.requestid from " + mainTable + " t1" +
                " left join workflow_requestbase t2 on t1.requestid=t2.requestid" +
                " left join " + mainTable + "_dt12 t3 on t1.id=t3.mainid" +
                " where t3.xj<>t3.bt" +
                " and t1.ngr !=1 and t2.currentnodetype=3 and substr(t2.LASTOPERATEDATE,1,7)='" + date + "'";
        //2\计算这些流程的补贴金额
        String sql2 = "select distinct tt1.requestid," +
                " tt1.ngr," +
                " tt1.lcbh," +
                " tt2.requestname," +
                " tt1.glcclc," +
                " tt2.LASTOPERATEDATE," +
                " tt4.bxr, (select workcode from hrmresource hr where  hr.id= tt4.bxr )  as workcode, " +
                " tt4.yxzh," +
                " tt4.khx as khxmc," +
                " tt4.yxzfje," +
                " (select mt.departmentcode from HRMDEPARTMENT mt where mt.id=tt4.bm) as departmentcode, " +
                " (select mt.departmentname from HRMDEPARTMENT mt where mt.id=tt4.bm) as departmentname, " +
                " (select mt.departmentcode from HRMDEPARTMENT mt where mt.id=tt3.ccrsjfycdbm) as burdenDeptCode," +
                " (select mt.departmentname from HRMDEPARTMENT mt where mt.id=tt3.ccrsjfycdbm) as burdenDeptName" +
                " from " + mainTable + " tt1" +
                " left join workflow_requestbase tt2 on tt1.requestid=tt2.requestid" +
                " left join " + mainTable + "_dt12 tt3 on tt1.id=tt3.mainid" +
                " left join " + mainTable + "_dt10 tt4 on tt1.id=tt4.mainid" +
                " where tt1.ngr !=1 and tt2.currentnodetype=3 " +
                " and tt3.ccr = tt4.bxr" +
                " and substr(tt2.LASTOPERATEDATE,1,7)='" + date + "'" +
                " and tt1.requestid not in ( " + sql1+" )";
        rs.executeQuery(sql2);
        List<Map<String, Object>> relateWfAllowancesarray = new ArrayList<>();
        while (rs.next()){
            String glcclcs = Util.null2String(rs.getString("glcclc"));
            Map<String, Object> relateWfAllowancesObj = new HashMap<>();
            List<String> tripMark = WeaverUtil.getAssociatedBusinessTripMark(glcclcs);
            relateWfAllowancesObj.put("requestId", Util.null2String(rs.getString("requestid")));
            relateWfAllowancesObj.put("workflowNumber", Util.null2String(rs.getString("lcbh")));
            relateWfAllowancesObj.put("workflowName", Util.null2String(rs.getString("requestname")));
            relateWfAllowancesObj.put("travelApplicationBizNumList", String.join(",", tripMark));
            relateWfAllowancesObj.put("lastOperateTime",Util.null2String(rs.getString("lastoperatedate")));
            relateWfAllowancesObj.put("workcode", Util.null2String(rs.getString("workcode")));
            relateWfAllowancesObj.put("bankCardNum", Util.null2String(rs.getString("yxzh")));
            relateWfAllowancesObj.put("bankName", Util.null2String(rs.getString("khxmc")));
            relateWfAllowancesObj.put("allowance", Util.getDoubleValue(Util.null2String(rs.getString("yxzfje"))));
            relateWfAllowancesObj.put("deptCode", Util.null2String(rs.getString("departmentcode")));
            relateWfAllowancesObj.put("deptName", Util.null2String(rs.getString("departmentname")));
            relateWfAllowancesObj.put("burdenDeptCode", Util.null2String(rs.getString("burdenDeptCode")));
            relateWfAllowancesObj.put("burdenDeptName", Util.null2String(rs.getString("burdenDeptName")));
            relateWfAllowancesarray.add(relateWfAllowancesObj);
        }
        return relateWfAllowancesarray;
    }
//
//    @Override
//    public List<Map<String, Object>> monthlyAllowance(Map<String, String> request2Map) {
//        String date = request2Map.get("date");
//        log.info("====差旅补贴接口开始");
//        log.info("====查询条件,日期@{}@", date);
//        List<Map<String, Object>> allAllowance = new ArrayList<>();
//        if (StringUtils.isEmpty(date)) {
//            log.info("====查询条件,日期为空,方法结束");
//            return allAllowance;
//        }
//        //查询条件封装
//        String whereSql = " where t1.ngr !=1 and t2.currentnodetype=3 and substr(t2.LASTOPERATEDATE,1,7)='" + date + "'";
//        RecordSet rs = new RecordSet();
//        //差旅报销表
//        String mainTable = WeaverUtil.getTableNameByPropName("unionReWfid");
//        String dt12Table = mainTable + "_dt12";
//        //报销流程信息
//        String allowanceTableSql = "select distinct t1.requestid,t1.ngr,t1.lcbh,t2.requestname,t1.glcclc,t2.LASTOPERATEDATE,t3.ccr\n" +
//                " from " + mainTable + " t1\n" +
//                " left join workflow_requestbase t2\n" +
//                " on t1.requestid=t2.requestid\n" +
//                " left join " + dt12Table + " t3\n" +
//                " on t1.id=t3.mainid\n" + whereSql;
//        log.info("====所有出差信息sql@" + allowanceTableSql + "@");
//        //关联到的差补出差人
//        List<String> allCcr = new ArrayList<>();
//        //关联到的报销流程信息
//        List<ReiMAInfo> reiMAInfos = new ArrayList<>();
//        rs.executeQuery(allowanceTableSql);
//        while (rs.next()) {
//            String ccr = Util.null2String(rs.getString("ccr")); //重复项
//            allCcr.add(ccr);
//            ReiMAInfo rmi = new ReiMAInfo();
//            rmi.setRequestId(Util.null2String(rs.getString("requestid")));
//            rmi.setNgr(Util.null2String(rs.getString("ngr")));
//            rmi.setRequestMark(Util.null2String(rs.getString("lcbh")));
//            rmi.setRequestName(Util.null2String(rs.getString("requestname")));
//            rmi.setRelCcReqMark(Util.null2String(rs.getString("glcclc")));
//            rmi.setLastOperateDate(Util.null2String(rs.getString("LASTOPERATEDATE")));
//            rmi.setCcr(Util.null2String(rs.getString("ccr")));
//            reiMAInfos.add(rmi);
//        }
//        allCcr = allCcr.stream().distinct().collect(Collectors.toList());
//        log.info("====差补下关联到的出差人id,去重后@" + allCcr + "@");
//        log.info("====差补下关联到的报销流程信息,未对出差人去重@" + reiMAInfos + "@");
//        //出差人信息
//        Map<String, Object> personalInfo;
//        //出差人相关流程的补贴
//        List<Map<String, Object>> relateWfAllowances;
//        for (String ccr : allCcr) {
//            personalInfo = new HashMap<>();
//            relateWfAllowances = new ArrayList<>();
//            personalInfo.putAll(WeaverUtil.getBankInfoByNgrWorkCode(ccr, WeaverUtil.BX));
//            // ccr 匹配 reiMAInfos 中 ccr
//            List<ReiMAInfo> matchReiInfo = reiMAInfos.stream().distinct().filter(rei -> rei.getCcr().equals(ccr)).collect(Collectors.toList());
//            log.info("====匹配到的报销信息行记录@" + matchReiInfo + "@");
//            //出差人单个流程补贴值
//            Map<String, Object> singleWfAllowance;
//            String refundReqId;
//            String glcclcs;
//            double associatedBusinessAllowance;
//            double allowances = 0.0;
//            for (ReiMAInfo info : matchReiInfo) {
//                singleWfAllowance = new HashMap<>();
//                glcclcs = info.getRelCcReqMark();
//                refundReqId = info.getRequestId();
//                singleWfAllowance.put("refundReqId", refundReqId);
//                singleWfAllowance.put("refundMark", info.getRequestMark());
//                singleWfAllowance.put("refundName", info.getRequestName());
//                associatedBusinessAllowance = WeaverUtil.getAssociatedBusinessAllowance(glcclcs, refundReqId, mainTable);
//                singleWfAllowance.put("allowances", associatedBusinessAllowance);
//                allowances += associatedBusinessAllowance;
//                singleWfAllowance.put("lastOperateTime", info.getLastOperateDate());
//                //新增费用承担部门字段信息(取自报销流程)
//                singleWfAllowance.put("feeBurdenDeptCode", WeaverUtil.getFeeBurdenDept(mainTable, refundReqId));
//                singleWfAllowance.put("businessTripMark",
//                        WeaverUtil.getAssociatedBusinessTripMark(glcclcs, refundReqId, mainTable));
//                relateWfAllowances.add(singleWfAllowance);
//            }
//            personalInfo.put("allowanceCount", allowances);
//            personalInfo.put("relateWfAllowances", relateWfAllowances);
//            allAllowance.add(personalInfo);
//        }
//        return allAllowance;
//    }

    @Override
    public List<Map<String, String>> getSubsidyStandard(String requestid) {
        RecordSet rs = new RecordSet();
        List<Map<String, String>> res = new ArrayList<>();
        String tableName = WeaverUtil.getTableNameByRequestId(requestid, rs);
        rs.writeLog(tableName);
        if (StringUtils.isBlank(tableName)) {
            return res;
        }
        String sql_mainTable = "select id,cclxzxx,sfhwcc from " + tableName + " where requestid=" + requestid;
        rs.execute(sql_mainTable);
        //出差类型  0,1 对应商旅出差-业务出差;2 对应商旅出差-培训学习;3,4 不支付补助
        String ccType = "";
        String mainId = ""; //关联明细表
        String sfhwcc = ""; //是否海外出差,0为海外
        if (rs.next()) {
            ccType = Util.null2String(rs.getString("cclxzxx"));
            mainId = Util.null2String(rs.getString("id"));
            sfhwcc = Util.null2String(rs.getString("sfhwcc"));
        }
        if (StringUtils.isBlank(ccType) || StringUtils.isBlank(mainId) || "0".equals(sfhwcc)) {
            return res;
        }
        String sql_dt4 = "select cfsj,fhsj,mddgn,sfbc from " + tableName + "_dt4 where mainid=" + mainId;
        rs.execute(sql_dt4);
        while (rs.next()) {
            Map<String, String> item = new HashMap<>();
            item.put("cclx", ccType);
            item.put("sfbc", Util.null2String(rs.getString("sfbc")));
            item.put("cfsj", Util.null2String(rs.getString("cfsj")));
            item.put("fhsj", Util.null2String(rs.getString("fhsj")));
            item.put("mddgn", Util.null2String(rs.getString("mddgn")));
            res.add(item);
        }

        if (CollectionUtils.isEmpty(res)) {
            String sql_dt3 = "select cfsj,fhsj,mddgn,sfbc from " + tableName + "_dt3 where mainid=" + mainId;
            rs.execute(sql_dt3);
            while (rs.next()) {
                Map<String, String> item = new HashMap<>();
                item.put("cclx", ccType);
                item.put("sfbc", Util.null2String(rs.getString("sfbc")));
                item.put("cfsj", Util.null2String(rs.getString("cfsj")));
                item.put("fhsj", Util.null2String(rs.getString("fhsj")));
                item.put("mddgn", Util.null2String(rs.getString("mddgn")));
                res.add(item);
            }
        }

        return res;
    }

    @Override
    public List<Map<String, Object>> monthlyAllowance4BusinessTrip(Map<String, String> queryParam) throws Exception {
        String startDate = queryParam.get("startDate");
        String endDate = queryParam.get("endDate");
        if (!isDate(startDate)) {
            throw new Exception("开始日期格式错误");
        }
        if (!isDate(endDate)) {
            throw new Exception("结束日期格式错误");
        }

        //构造数据
        ResourceComInfo rc = new ResourceComInfo();
        DepartmentComInfo dc = new DepartmentComInfo();
        String tableName = PayUtil.getTableNameByUnNumber("ccsq");
        String sql = "select t2.REQUESTNAME,t1.LCBH,t1.REQUESTID,t3.XM,t3.FYCDBM,t1.TXXMBM,t1.TXXMJC,t1.KHMC,t1.KHBM,t1.CB,t2.LASTOPERATEDATE\n" +
                "from " + tableName + " t1\n" +
                "left join workflow_requestbase t2\n" +
                "on t1.requestid=t2.requestid\n" +
                "left join " + tableName + "_DT2 t3\n" +
                "on t1.ID=t3.MAINID\n" +
                "where t1.NGR !=1 and t2.currentnodetype=3 and t1.YWZFFYDBX=1\n" +
                "and to_date(t2.LASTOPERATEDATE, 'yyyy-MM-dd')\n" +
                "between to_date('" + startDate + "','yyyy-MM-dd') AND to_date('" + endDate + "','yyyy-MM-dd')";

        log.info(String.format("monthlyAllowance4BusinessTrip查询sql:%s", sql));

        RecordSet rs = new RecordSet();
        rs.executeQuery(sql);
        List<AllowancePO> allAllowanceList = new ArrayList<>();
        while (rs.next()) {
            AllowancePO apo = new AllowancePO();
            apo.setReqMark(Util.null2String(rs.getString("LCBH")));
            apo.setReqId(Util.null2String(rs.getString("REQUESTID")));
            apo.setReqTitle(Util.null2String(rs.getString("REQUESTNAME")));
            apo.setUid(rc.getWorkcode(Util.null2String(rs.getString("XM"))));
            apo.setProjectCode(Util.null2String(rs.getString("TXXMBM")));
            apo.setProjectName(Util.null2String(rs.getString("TXXMJC")));
            apo.setCrmCode(Util.null2String(rs.getString("KHBM")));
            apo.setCrmName(Util.null2String(rs.getString("KHMC")));
            apo.setAllowance(Util.null2String(rs.getString("CB")));
            apo.setLastOperateTime(Util.null2String(rs.getString("LASTOPERATEDATE")));
            apo.setDeptCode(dc.getDepartmentCode(Util.null2String(rs.getString("FYCDBM"))));
            allAllowanceList.add(apo);
        }

        // group by workcode
        Map<String, List<AllowancePO>> allowanceGroupByUid = allAllowanceList
                .stream()
                .collect(Collectors.groupingBy(AllowancePO::getUid));

        List<Map<String, Object>> resp = new ArrayList<>(); //构造data返回值
        Map<String, Object> singleWfAllowance; //构造差旅信息(出差维度默认为空)
        Map<String, Object> singlePerson; //构造出差申请详情
        for (Map.Entry<String, List<AllowancePO>> entry : allowanceGroupByUid.entrySet()) {
            String uid = entry.getKey();
            List<AllowancePO> ua = entry.getValue();

            String sumAllowances = ua.stream()
                    .map(AllowancePO::getAllowance)
                    .reduce(String.valueOf(BigDecimal.ZERO),
                            (sum, data) -> String.valueOf(DoubleUtil.add(sum, "".equals(data) ? "0" : data, 2)));

            //构造
            singleWfAllowance = new HashMap<>();
            singleWfAllowance.put("refundReqId", "");
            singleWfAllowance.put("refundMark", "");
            singleWfAllowance.put("refundName", "");
            singleWfAllowance.put("allowances", sumAllowances);
            singleWfAllowance.put("lastOperateTime", "");
            singleWfAllowance.put("feeBurdenDeptCode", "");
            singleWfAllowance.put("businessTripMark", ua);

            singlePerson = new HashMap<>(WeaverUtil.getBankInfoByNgrWorkCode(uid, WeaverUtil.CC)); //人员信息
            singlePerson.put("allowanceCount", sumAllowances); //补贴总额
            singlePerson.put("relateWfAllowances", singleWfAllowance); //相关出差流程

            resp.add(singlePerson); //汇总单人数据

        }
        return resp;
    }

    private static boolean isDate(String dat) {
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        formatter.setLenient(false);
        Date result = formatter.parse(dat, pos);
        return !(pos.getIndex() == 0) && dat.equals(formatter.format(result));
    }

    public static void main(String[] args) {
        boolean date = isDate("2020-08-21");
        System.out.println("date = " + date);
    }
}

