package com.engine.kq.cmd.attendanceEvent;

import com.alibaba.fastjson.JSON;
import com.engine.kq.biz.KQAttFlowSetBiz;
import com.engine.kq.biz.KQAttProcSetComInfo;
import com.engine.kq.enums.KqSplitFlowTypeEnum;
import com.engine.kq.log.KQLog;
import com.engine.kq.util.KQTransMethod;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.lang3.StringUtils;
import weaver.common.DateUtil;
import weaver.common.StringUtil;
import weaver.conn.RecordSet;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.systeminfo.SystemEnv;
import weaver.workflow.workflow.WorkflowRequestComInfo;

public class CheckRuleUtil {
  public String[] ori_str = new String[]{"#requestname_link#","#requestname#"};
  public String[] ori_count_str = new String[]{"#num_type#","#num_count#"};
  private KQLog kqLog = new KQLog();

  public void checkRule(Set<Entry<String, Object>> checkRuleDataSet,
      Map<String, Object> retmap, User user, String kqtype, int requestid,int nodetype,String attid) {
    try{

      if(attid.length() == 0 || Util.getIntValue(attid) < 0 || kqtype.length() == 0 || Util.getIntValue(kqtype) < 0){
        return ;
      }
      RecordSet rs = new RecordSet();
      RecordSet rs1 = new RecordSet();
      RecordSet rs2 = new RecordSet();
      String workflowid = "";
      String wf_sql = "select * from  kq_att_proc_set where id = ?";
      rs.executeQuery(wf_sql, attid);
      if(rs.next()){
        workflowid = rs.getString("field001");
      }

      String sql = "select * from kq_att_checkrule_set where attid=? ";
      rs.executeQuery(sql, attid);
      while (rs.next()){
        if(!retmap.isEmpty() && retmap.containsKey("status")){
          if("-1".equalsIgnoreCase(Util.null2String(retmap.get("status")))){
            return;
          }
        }
        String ruleid = rs.getString("ruleid");
        String rule_type_uuid = rs.getString("rule_type_uuid");
        String type_sql = "select * from kq_att_checkrule_type where uuid=? and att_type=? ";
        rs1.executeQuery(type_sql, rule_type_uuid,kqtype);
        if(rs1.next()){
          String rule_table = rs1.getString("rule_table");
          if("kq_att_duplicate_rule".equalsIgnoreCase(rule_table)){
            //如果是重复校验，走重复校验的逻辑
            String table_sql = "select * from "+rule_table+" where id=? ";
            rs2.executeQuery(table_sql, ruleid);
            if(rs2.next()){
              check_duplicate_rule(checkRuleDataSet,retmap, user, kqtype, requestid,nodetype,workflowid,rs2);
            }
          }else if("kq_att_frequency_rule".equalsIgnoreCase(rule_table)){
            //如果是次数校验，走次数校验的逻辑
            String table_sql = "select * from "+rule_table+" where id=? ";
            rs2.executeQuery(table_sql, ruleid);
            if(rs2.next()){
              check_frequency_rule(checkRuleDataSet,retmap, user, kqtype, requestid,nodetype,attid,rs2);
            }
          }
        }
      }
    }catch (Exception e){
      StringWriter errorsWriter = new StringWriter();
      e.printStackTrace(new PrintWriter(errorsWriter));
      kqLog.info(errorsWriter.toString());
    }
  }

  /**
   * 补卡流程，有两种控制:
   * 重复校验只需要控制打卡日期时间是否重复了
   * 次数校验需要控制，每日，每周，每月可提交的补卡次数
   * 当前是次数校验
   * @param checkRuleDataSet
   * @param retmap
   * @param user
   * @param kqtype
   * @param requestid
   * @param nodetype
   * @param attid
   * @param rs2
   */
  private void check_frequency_rule(Set<Entry<String, Object>> checkRuleDataSet, Map<String, Object> retmap, User user, String kqtype, int requestid, int nodetype, String attid,
      RecordSet rs2) throws Exception{
//    校验类型
    String frequency_rule = rs2.getString("frequency_rule");
    String frequency_rule_content = new KQTransMethod().getFrequencyContent(frequency_rule,user.getLanguage());
//    校验次数
    String frequency_rule_count = rs2.getString("frequency_rule_count");
    if(frequency_rule_count.length() == 0 || Util.getIntValue(frequency_rule_count) <= 0){
      return ;
    }
//    校验强度
    String frequency_level = rs2.getString("frequency_level");
    if("2".equalsIgnoreCase(frequency_level)){
      //不校验
      return ;
    }
//    提示语句
    String frequency_message = Util.null2String(rs2.getString("frequency_message"));

    RecordSet rs = new RecordSet();
    KQAttFlowSetBiz kqAttFlowSetBiz = new KQAttFlowSetBiz();
    Map<String,String> daterangeMap = Maps.newConcurrentMap();
    List<Map<String,String>> dataList = Lists.newArrayList();
    for (Entry<String, Object> entry : checkRuleDataSet) {
      String duplicateValue = Util.null2String(entry.getValue());
      String[] duplicateValues = duplicateValue.split("_",-1);
      if (duplicateValues.length == 3) {
        Map<String,String> dataMap = Maps.newConcurrentMap();
        String resourceId = duplicateValues[0];
        String signdate = duplicateValues[1];
        if(resourceId.length() == 0 || signdate.length() == 0){
          continue;
        }
        String dateRange = getDateRangeByFrequency_rule(frequency_rule,signdate);
        if(daterangeMap.containsKey(dateRange)){
          int tmp = Util.getIntValue(Util.null2s(daterangeMap.get(dateRange),"1"));
          daterangeMap.put(dateRange, ""+(1+tmp));
        }else{
          daterangeMap.put(dateRange, "1");
        }
        dataMap.put("resourceId", resourceId);
        dataMap.put("signdate", signdate);
        dataMap.put("dateRange", dateRange);
        dataList.add(dataMap);
      }
    }

    if(!daterangeMap.isEmpty()){
      for(Map.Entry<String,String> me : daterangeMap.entrySet()){
        String key = me.getKey();
        int tmp = Util.getIntValue(Util.null2s(daterangeMap.get(key),"1"));
        if(tmp > Util.getIntValue(frequency_rule_count)){
          retmap.put("status", "-1");
          if("1".equalsIgnoreCase(frequency_level)){
            //弱控
            retmap.put("status", "-2");
          }
          String[] replace_str = new String[]{frequency_rule_content,frequency_rule_count};
          frequency_message = StringUtils.replaceEach(frequency_message, ori_count_str,replace_str);
          retmap.put("message",  frequency_message);
          return ;
        }
      }
    }
    for(Map<String,String> mapData : dataList){
      String resourceId = mapData.get("resourceId");
      String signdate = mapData.get("signdate");
      String dateRange = mapData.get("dateRange");
      String custome_sql = "";
      if(dateRange.length() > 0 && dateRange.split("_").length == 2){
        String daterange_start = dateRange.split("_")[0];
        String daterange_end = dateRange.split("_")[1];
        if(daterange_start.length() > 0 && daterange_end.length() > 0){
          custome_sql = " detail_signdate between '"+daterange_start+"' and '"+daterange_end+"'";
        }
      }
      if(custome_sql.length() == 0){
        continue;
      }
      Map<String, Object> params = Maps.newHashMap();
      params.put("typeselect", "6");
      params.put("tabKey", "3");
      params.put("kqtype", kqtype);
      params.put("isMyKQ", "1");
      params.put("custome_sql", custome_sql);
      params.put("resourceId", resourceId);
      params.put("not_start_node", "1");
      if(requestid > 0){
        params.put("not_requestId", requestid);
      }
	  params.put("isNoAccount", "1");
      Map<String,String> sqlMap = kqAttFlowSetBiz.getFLowSql(params,user);
      String backfields = " * ";
//      String backfields = "  count(requestid) as cnt_request ";
      String fromSql  = Util.null2String(sqlMap.get("from"));
      String sqlWhere = Util.null2String(sqlMap.get("where"));
      String allSql = "select "+ backfields + fromSql+sqlWhere;
      kqLog.info("check_frequency_rule:allSql:"+allSql);
      int request_count = 0;
      Map<String,Integer> tmpdatas = new HashMap<>();
      rs.executeQuery(allSql);
      while (rs.next()){
        String detail_signdate = Util.null2String(rs.getString("detail_signdate"));
        String detail_signtype = Util.null2String(rs.getString("detail_signtype"));
        String detail_signtime = Util.null2String(rs.getString("detail_signtime"));
        String detail_requestid = Util.null2String(rs.getString("requestid"));
        String key = detail_requestid+"#"+detail_signdate+"#"+detail_signtime+"#"+detail_signtype;
        if(tmpdatas.get(key)!=null){
          continue;
        }else{
          request_count ++;
          tmpdatas.put(key,1);
        }
      }

      int cur_flow_count = 0;
      if(daterangeMap.containsKey(dateRange)){
        cur_flow_count = Util.getIntValue(Util.null2s(daterangeMap.get(dateRange),"0"));
      }
      kqLog.info("check_frequency_rule:request_count:"+request_count+":cur_flow_count:"+cur_flow_count);

      if((request_count+cur_flow_count) > Util.getIntValue(frequency_rule_count)){
        retmap.put("status", "-1");
        if("1".equalsIgnoreCase(frequency_level)){
          //弱控
          retmap.put("status", "-2");
        }
        String[] replace_str = new String[]{frequency_rule_content,frequency_rule_count};
        frequency_message = StringUtils.replaceEach(frequency_message, ori_count_str,replace_str);
        retmap.put("message",  frequency_message);
        return;
      }

//      if(rs.next()){
//        int request_count = Util.getIntValue(rs.getString("cnt_request"));
//        int cur_flow_count = 0;
//        if(daterangeMap.containsKey(dateRange)){
//          cur_flow_count = Util.getIntValue(Util.null2s(daterangeMap.get(dateRange),"0"));
//        }
//
//        if((request_count+cur_flow_count) > Util.getIntValue(frequency_rule_count)){
//          retmap.put("status", "-1");
//          if("1".equalsIgnoreCase(frequency_level)){
//            //弱控
//            retmap.put("status", "-2");
//          }
//          String[] replace_str = new String[]{frequency_rule_content,frequency_rule_count};
//          frequency_message = StringUtils.replaceEach(frequency_message, ori_count_str,replace_str);
//          retmap.put("message",  frequency_message);
//          return;
//        }
//      }
    }

  }

  /**
   * 根据校验规则 和当前得到
   * @param frequency_rule
   * @param signdate
   */
  public String getDateRangeByFrequency_rule(String frequency_rule, String signdate) {
    String daterange_start = "";
    String daterange_end = "";
    if("0".equalsIgnoreCase(frequency_rule)){
      //每日
      daterange_start = signdate;
      daterange_end = signdate;
    }else if("1".equalsIgnoreCase(frequency_rule)){
      //每周
      daterange_start = DateUtil.getFirstDayOfWeek(signdate);
      daterange_end = DateUtil.getLastDayOfWeek(signdate);
    }else if("2".equalsIgnoreCase(frequency_rule)){
      //每月
      daterange_start = DateUtil.getFirstDayOfMonth(signdate);
      daterange_end = DateUtil.getLastDayOfMonth(signdate);
    }else if("3".equalsIgnoreCase(frequency_rule)){
      //每季度
      daterange_start = DateUtil.getFirstDayOfQuarter(signdate);
      daterange_end = DateUtil.getLastDayOfQuarter(signdate);
    }else if("4".equalsIgnoreCase(frequency_rule)){
      //每年
      daterange_start = DateUtil.getFirstDayOfYear(signdate);
      daterange_end = DateUtil.getLastDayOfYear(signdate);
    }
    String key = daterange_start+"_"+daterange_end;

    return key;
  }

  /**
   * 重复校验的处理
   * @param checkRuleDataSet
   * @param retmap
   * @param user
   * @param kqtype
   * @param requestid
   * @param nodetype
   * @param workflowid
   * @param rs2
   */
  private void check_duplicate_rule(Set<Entry<String, Object>> checkRuleDataSet,
      Map<String, Object> retmap, User user, String kqtype, int requestid, int nodetype,
      String workflowid, RecordSet rs2) throws Exception{
    List<String> wfids = Lists.newArrayList();
//    校验类型
    String duplicate_rule = rs2.getString("duplicate_rule");
//    校验强度
    String duplicate_level = rs2.getString("duplicate_level");
    if("2".equalsIgnoreCase(duplicate_level)){
      //不校验
      return ;
    }
//    提示语句
    String duplicate_message = Util.null2String(rs2.getString("duplicate_message"),SystemEnv.getHtmlLabelName(516397,weaver.general.Util.getIntValue(user.getLanguage())));

    //补卡流程只需要有自己流程比较，不会和其他流程相互比较的
    if("0".equalsIgnoreCase(duplicate_rule)){
      //同流程
      wfids.add(workflowid);
    }else if("1".equalsIgnoreCase(duplicate_rule)){
      //各个流程之间
//    需校验流程路径
      String duplicate_wfids = rs2.getString("duplicate_wfids");
      if(duplicate_wfids.length() > 0){
        String[] duplicate_wfidArr = duplicate_wfids.split(",");
        for(String wfid : duplicate_wfidArr){
          wfids.add(wfid);
        }
      }
    }else{
      wfids.add(workflowid);
    }
    kqLog.info("check_duplicate_rule:wfids:"+wfids+":duplicate_rule:"+duplicate_rule+":duplicate_level:"+duplicate_level);

    boolean isCard = false;
    boolean isEvection = false;
    boolean isProcess = false;
    if(kqtype.equalsIgnoreCase(""+KqSplitFlowTypeEnum.CARD.getFlowtype())){
      isCard = true;
    }else if(kqtype.equalsIgnoreCase(""+KqSplitFlowTypeEnum.EVECTION.getFlowtype())){
      isEvection = true;
    }else if(kqtype.equalsIgnoreCase(""+KqSplitFlowTypeEnum.PROCESSCHANGE.getFlowtype())){
      isProcess = true;
    }else{
    }
    if(isCard){
      doWhenisDuplicateCard(checkRuleDataSet,requestid,wfids,user,duplicate_message,retmap);
    }else if(isEvection){
      doWhenisDuplicateEvection(checkRuleDataSet,requestid,wfids,user,duplicate_message,retmap);
    }else if(isProcess){
      doWhenisDuplicateProcess(checkRuleDataSet,requestid,wfids,user,duplicate_message,retmap);
    }else{
      doWhenisCommonDuplicate(checkRuleDataSet,requestid,wfids,user,duplicate_message,retmap);
    }
    if("1".equalsIgnoreCase(duplicate_level)){
      //弱控
      if(!retmap.isEmpty()){
        retmap.put("status", "-2");
      }
    }
  }

  /**
   * 考勤变更流程，因为有字段不同，需要单独处理
   * @param checkRuleDataSet
   * @param requestid
   * @param wfids
   * @param user
   * @param duplicate_message
   * @param retmap
   */
  private void doWhenisDuplicateProcess(Set<Entry<String, Object>> checkRuleDataSet, int requestid,
      List<String> wfids, User user, String duplicate_message,
      Map<String, Object> retmap) throws Exception{
    String process_changerequestid = "";
    String process_resourceId = "";
    String process_tablename = "";
    Map<String,String> wftypeMap = Maps.newHashMap();
    RecordSet rs = new RecordSet();
    Map<String, List<String>> mapSqls = Maps.newHashMap();
    Map<String,List<Map<String,String>>> duplicateMaps = Maps.newHashMap();
    for (Entry<String, Object> entry : checkRuleDataSet) {
      String duplicateValue = Util.null2String(entry.getValue());
      String[] duplicateValues = duplicateValue.split("_",-1);
      if(duplicateValues.length == 10){
        String resourceId = duplicateValues[0];
        String fromDate = duplicateValues[1];
        String fromTime = duplicateValues[2];
        String toDate = duplicateValues[3];
        String toTime = duplicateValues[4];
        String changerequestid = duplicateValues[5];
        String attendancefromDate = duplicateValues[6];
        String attendancefromTime = duplicateValues[7];
        String attendancetoDate = duplicateValues[8];
        String attendancetoTime = duplicateValues[9];
        if(fromDate.length() == 0 || fromTime.length() == 0 || toDate.length() == 0 || toTime.length() == 0){
          continue;
        }

        process_changerequestid = changerequestid;
        process_resourceId = resourceId;
        long fromdatetime_long = DateUtil.getCalendar(fromDate+" "+fromTime).getTimeInMillis();
        long todatetime_long = DateUtil.getCalendar(toDate+" "+toTime).getTimeInMillis();
        if(attendancetoDate.length() == 0 || attendancefromTime.length() == 0 || attendancetoDate.length() == 0 || attendancetoTime.length() == 0){
          continue;
        }
        long attendance_fromdatetime_long = DateUtil.getCalendar(attendancefromDate+" "+attendancefromTime).getTimeInMillis();
        long attendance_todatetime_long = DateUtil.getCalendar(attendancetoDate+" "+attendancetoTime).getTimeInMillis();

        buildMap4Process(duplicateMaps,resourceId,fromdatetime_long,todatetime_long,attendance_fromdatetime_long,attendance_todatetime_long);

        for(String wfid : wfids){
          Map<String, Object> params = Maps.newHashMap();
          buildSql(mapSqls, user, wfid, fromDate, toDate, resourceId, requestid,params,wftypeMap);
        }
      }
    }

    //如果变更明细里原数据和变更数据完全一致也需要记录下
    List<String> same_processList = Lists.newArrayList();
    //变更流程的明细数量是不是和被变更流程的明细数量一致
    boolean isSameProcess = false;
    if(!duplicateMaps.isEmpty() && process_changerequestid.length() > 0){
      Map<String, Object> otherparams = Maps.newHashMap();
      otherparams.put("resourceId", process_resourceId);
      otherparams.put("requestid", process_changerequestid);
      GetProcessChangeTypeCmd processChangeTypeCmd = new GetProcessChangeTypeCmd(otherparams, user);
      Map<String, Object> retmaps = processChangeTypeCmd.execute(null);
      if(retmaps != null && !retmaps.isEmpty()){
        if(retmaps.containsKey("process_type") && retmaps.containsKey("process_tablename")){
          process_tablename = Util.null2String(retmaps.get("process_tablename"));
        }
      }

      List<String> processList = Lists.newArrayList();
      String process_sql = "select * from "+process_tablename+" where requestid=? and resourceid=? and status=0 ";
      rs.executeQuery(process_sql, process_changerequestid,process_resourceId);
      //这种情况就是变更流程只是变更了一部分流程数据的话，需要考虑一种特殊情况就是
      //当前被变更的流程和当前变更流程明细之间存在冲突的可能
      while (rs.next()){
        String fromdatedb = rs.getString("fromdatedb");
        String fromtimedb = rs.getString("fromtimedb");
        String todatedb = rs.getString("todatedb");
        String totimedb = rs.getString("totimedb");
        long fromdatetime_long = DateUtil.getCalendar(fromdatedb+" "+fromtimedb).getTimeInMillis();
        long todatetime_long = DateUtil.getCalendar(todatedb+" "+totimedb).getTimeInMillis();
        String key = fromdatetime_long+"_"+todatetime_long;
        if(!processList.contains(key)){
          processList.add(key);
        }
      }
      for(Entry<String,List<Map<String,String>>> me : duplicateMaps.entrySet()){
        boolean is_process_less = false;
        List<Map<String,String>> values = me.getValue();
        if(processList.size() != values.size()){
          is_process_less = true;
        }else{
          isSameProcess = true;
        }
        //针对当前流程本身，如果是明细表，多条明细之间也需要校验
        for(int i = 0 ; i < values.size() ; i++){
          long fromdatetime_long = StringUtil.parseToLong(values.get(i).get("fromdatetime_long"));
          long todatetime_long = StringUtil.parseToLong(values.get(i).get("todatetime_long"));
          long attendance_fromdatetime_long = StringUtil.parseToLong(values.get(i).get("attendance_fromdatetime_long"));
          long attendance_todatetime_long = StringUtil.parseToLong(values.get(i).get("attendance_todatetime_long"));

          if(is_process_less){
            String tmp_key = fromdatetime_long+"_"+todatetime_long;
            if(fromdatetime_long == attendance_fromdatetime_long && todatetime_long == attendance_todatetime_long){
              //如果变更时间和原时间完全一致，不作处理
              same_processList.add(tmp_key);
            }else{
              if(processList.contains(tmp_key)){
                retmap.put("status", "-1");
                String e_duplicate_message= duplicate_message;
                String mobile_duplicate_message= duplicate_message;
                String[] replace_str = new String[]{new KQTransMethod().getWorkFlowUrl(process_changerequestid),new WorkflowRequestComInfo().getRequestName(process_changerequestid)};
                String[] mobile_replace_str = new String[]{new KQTransMethod().getWorkFlowUrl4mobile(process_changerequestid),new WorkflowRequestComInfo().getRequestName(process_changerequestid)};
                String[] e_replace_str = new String[]{new WorkflowRequestComInfo().getRequestName(process_changerequestid),new WorkflowRequestComInfo().getRequestName(process_changerequestid)};
                mobile_duplicate_message = StringUtils.replaceEach(mobile_duplicate_message, ori_str,mobile_replace_str);
                duplicate_message = StringUtils.replaceEach(duplicate_message, ori_str,replace_str);
                e_duplicate_message = StringUtils.replaceEach(e_duplicate_message, ori_str,e_replace_str);
                retmap.put("message",  duplicate_message);
                retmap.put("mobile_message",  mobile_duplicate_message);
                //给小e用的
                retmap.put("e_message",  e_duplicate_message);
                return;
              }
            }
          }
          if(values.size() > 1){
            for(int j = i+1 ; j < values.size() ;j++){
              long j_fromdatetime_long = StringUtil.parseToLong(values.get(j).get("fromdatetime_long"));
              long j_todatetime_long = StringUtil.parseToLong(values.get(j).get("todatetime_long"));
              if(todatetime_long <= j_fromdatetime_long || fromdatetime_long >= j_todatetime_long){
                //这样表示流程不交叉
              }else{
                retmap.put("status", "-1");
                retmap.put("message",  SystemEnv.getHtmlLabelName(516400,user.getLanguage()));
                return;
              }
            }
          }
        }
      }
    }

    kqLog.info("doWhenisDuplicateProcess:mapSqls:"+mapSqls);
    boolean isLeave = false;
    boolean isProcess = false;
    if(retmap.isEmpty() && !mapSqls.isEmpty()){
      RecordSet rs1 = new RecordSet();
      for(Entry<String,List<String>> me : mapSqls.entrySet()){
        String resourceId = me.getKey();
        if(duplicateMaps.containsKey(resourceId)){
          List<String> values = me.getValue();
          for(int i = 0 ; i <values.size() ; i++){
            String tmp_sql = values.get(i);
            rs.executeQuery(tmp_sql);
            while (rs.next()){
              String tmp_wftype = "";
              if(wftypeMap.containsKey(tmp_sql)){
                tmp_wftype = wftypeMap.get(tmp_sql);
              }
                String fromDate_field = "fromDate";
              String fromTime_field = "fromTime";
              String toDate_field = "toDate";
              String toTime_field = "toTime";
              if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.PROCESSCHANGE.getFlowtype()+"")){
                fromDate_field = "detail_fromDate";
                fromTime_field = "detail_fromTime";
                toDate_field = "detail_toDate";
                toTime_field = "detail_toTime";
              }

              String related_requestid = rs.getString("requestid");
              String flow_fromDate = rs.getString(fromDate_field);
              String flow_fromTime = rs.getString(fromTime_field);
              String flow_toDate = rs.getString(toDate_field);
              String flow_toTime = rs.getString(toTime_field);
              Map<String,String> specialMap = getSpecialMap(tmp_wftype,related_requestid,rs,resourceId, user,flow_fromDate,flow_fromTime,flow_toDate,flow_toTime);
              if(specialMap != null && !specialMap.isEmpty()){
                isLeave = Util.null2String(specialMap.get("isLeave")).equalsIgnoreCase("1");
                isProcess = Util.null2String(specialMap.get("isProcess")).equalsIgnoreCase("1");
                if(!isLeave){
                  flow_fromDate = Util.null2String(specialMap.get("fromdatedb"));
                  flow_fromTime = Util.null2String(specialMap.get("fromtimedb"));
                  flow_toDate = Util.null2String(specialMap.get("todatedb"));
                  flow_toTime = Util.null2String(specialMap.get("totimedb"));
                  related_requestid = Util.null2String(specialMap.get("related_requestid"));
                }
                if(isProcess){
                  if(process_changerequestid.equalsIgnoreCase(related_requestid)){
                    if(isSameProcess){
                      continue;
                    }else{
                      if(flow_fromDate.length() > 0 && flow_fromTime.length() > 0 && flow_toDate.length() > 0 && flow_toTime.length() > 0) {
                        long todatetime_long = DateUtil.getCalendar(flow_toDate+" "+flow_toTime).getTimeInMillis();
                        long fromdatetime_long = DateUtil.getCalendar(flow_fromDate+" "+flow_fromTime).getTimeInMillis();
                        String tmp_key = fromdatetime_long+"_"+todatetime_long;
                        if(!same_processList.isEmpty()){
                          if(same_processList.contains(tmp_key)){
                            continue;
                          }
                        }
                      }
                    }
                  }
                }
              }
              if(flow_fromDate.length() > 0 && flow_fromTime.length() > 0 && flow_toDate.length() > 0 && flow_toTime.length() > 0){
                long flow_fromdatetime_long = DateUtil.getCalendar(flow_fromDate+" "+flow_fromTime).getTimeInMillis();
                long flow_todatetime_long = DateUtil.getCalendar(flow_toDate+" "+flow_toTime).getTimeInMillis();
                List<Map<String,String>> duplicateVals = duplicateMaps.get(resourceId);
                checkDuplicateFlow(duplicateVals,retmap,flow_fromdatetime_long,flow_todatetime_long,duplicate_message,related_requestid,
                    isLeave,resourceId);
                if(!retmap.isEmpty()){
                  return ;
                }
              }
            }
          }
        }
      }
    }
  }

  /**
   * 出差流程，因为有陪同人的概念，需要特殊处理
   * @param checkRuleDataSet
   * @param requestid
   * @param wfids
   * @param user
   * @param duplicate_message
   * @param retmap
   */
  private void doWhenisDuplicateEvection(Set<Entry<String, Object>> checkRuleDataSet, int requestid,
      List<String> wfids, User user, String duplicate_message,
      Map<String, Object> retmap) throws Exception{
    Map<String,String> wftypeMap = Maps.newHashMap();
    RecordSet rs = new RecordSet();
    KQAttProcSetComInfo kqAttProcSetComInfo = new KQAttProcSetComInfo();
    Map<String, List<String>> mapSqls = Maps.newHashMap();
    Map<String,List<Map<String,String>>> duplicateMaps = Maps.newHashMap();
    List<Map<String,String>> duplicateLists = Lists.newArrayList();
    List<String> sqls = Lists.newArrayList();
    KQAttFlowSetBiz kqAttFlowSetBiz = new KQAttFlowSetBiz();
    for (Entry<String, Object> entry : checkRuleDataSet) {
      String duplicateValue = Util.null2String(entry.getValue());
      String[] duplicateValues = duplicateValue.split("_",-1);
      if(duplicateValues.length == 6){
        String resourceId = duplicateValues[0];
        String fromDate = duplicateValues[1];
        String fromTime = duplicateValues[2];
        String toDate = duplicateValues[3];
        String toTime = duplicateValues[4];
        String companion = duplicateValues[5];
        if(fromDate.length() == 0 || fromTime.length() == 0 || toDate.length() == 0 || toTime.length() == 0){
          continue;
        }
        long fromdatetime_long = DateUtil.getCalendar(fromDate+" "+fromTime).getTimeInMillis();
        long todatetime_long = DateUtil.getCalendar(toDate+" "+toTime).getTimeInMillis();

        buildMap(duplicateMaps,resourceId,fromdatetime_long,todatetime_long);

        if(companion.length() > 0) {
          Map<String,String> duplicateMap = Maps.newConcurrentMap();
          duplicateMap.put("fromdatetime_long", ""+fromdatetime_long);
          duplicateMap.put("todatetime_long", ""+todatetime_long);
          String[] companions = companion.split(",");
          for (int i = 0; i < companions.length; i++) {
            if(resourceId.equalsIgnoreCase(companions[i])){
              continue;
            }
            if(!duplicateMaps.containsKey(companions[i])){
              duplicateLists = Lists.newArrayList();
              duplicateLists.add(duplicateMap);
              duplicateMaps.put(companions[i], duplicateLists);
            }else{
              List<Map<String,String>> tmpList = duplicateMaps.get(companions[i]);
              tmpList.add(duplicateMap);
            }
          }
        }
        for(String wfid : wfids){
          String tmp_wftype = kqAttProcSetComInfo.getkqType(wfid);
          Map<String, Object> params = Maps.newHashMap();

          buildSql(mapSqls, user, wfid, fromDate, toDate, resourceId, requestid,params,wftypeMap);

          if(companion.length() > 0){
            String[] companions = companion.split(",");
            for(int i = 0 ; i < companions.length ; i++){
              if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.EVECTION.getFlowtype()+"")){
                if (rs.getDBType().equalsIgnoreCase("oracle")||rs.getDBType().equalsIgnoreCase("postgresql")) {
                  params.put("custome_sql", " resourceId='"+companions[i]+"' or ','||to_char(companion)||',' like '%," + companions[i] + ",%' ");
                } else if (rs.getDBType().equalsIgnoreCase("mysql")) {
                  params.put("custome_sql", " resourceId='"+companions[i]+"' or CONCAT(CONCAT(',',companion),',') like '%," + companions[i] + ",%' ");
                } else {
                  params.put("custome_sql", " resourceId='"+companions[i]+"' or ','+cast(companion as varchar(max))+',' like '%," + companions[i] + ",%' ");
                }
              }else{
                params.put("resourceId", companions[i]);
              }
			  params.put("isNoAccount", "1");
              Map<String,String> companion_sqlMap = kqAttFlowSetBiz.getFLowSql(params,user);
              String companion_backfields = "  * ";
              String companion_fromSql  = Util.null2String(companion_sqlMap.get("from"));
              String companion_sqlWhere = Util.null2String(companion_sqlMap.get("where"));
              String companion_allSql = "select "+ companion_backfields + companion_fromSql+companion_sqlWhere;
              wftypeMap.put(companion_allSql,tmp_wftype);
              if(!mapSqls.containsKey(companions[i])){
                //存一下sql对应的考勤流程类型
                sqls = Lists.newArrayList();
                sqls.add(companion_allSql);
                mapSqls.put(companions[i],sqls);
              }else{
                List<String> tmp_sqls = mapSqls.get(companions[i]);
                tmp_sqls.add(companion_allSql);
              }
            }
          }
        }
      }
    }

    if(!duplicateMaps.isEmpty()){
      for(Entry<String,List<Map<String,String>>> me : duplicateMaps.entrySet()){
        List<Map<String,String>> values = me.getValue();
        if(values.size() > 1){
          //针对当前流程本身，如果是明细表，多条明细之间也需要校验
          for(int i = 0 ; i < values.size() ; i++){
            long fromdatetime_long = StringUtil.parseToLong(values.get(i).get("fromdatetime_long"));
            long todatetime_long = StringUtil.parseToLong(values.get(i).get("todatetime_long"));
            for(int j = i+1 ; j < values.size() ;j++){
              long j_fromdatetime_long = StringUtil.parseToLong(values.get(j).get("fromdatetime_long"));
              long j_todatetime_long = StringUtil.parseToLong(values.get(j).get("todatetime_long"));
              if(todatetime_long <= j_fromdatetime_long || fromdatetime_long >= j_todatetime_long){
                //这样表示流程不交叉
              }else{
                retmap.put("status", "-1");
                retmap.put("message",  SystemEnv.getHtmlLabelName(516400,user.getLanguage()));
                return;
              }
            }
          }
        }
      }
    }

    kqLog.info("doWhenisDuplicateEvection:mapSqls:"+mapSqls);
    boolean isLeave = false;
    if(retmap.isEmpty() && !mapSqls.isEmpty()){
      for(Entry<String,List<String>> me : mapSqls.entrySet()){
        String resourceId = me.getKey();
        if(duplicateMaps.containsKey(resourceId)){
          List<String> values = me.getValue();
          for(int i = 0 ; i <values.size() ; i++){
            String tmp_sql = values.get(i);
            rs.executeQuery(tmp_sql);
            while (rs.next()){
              String tmp_wftype = "";
              if(wftypeMap.containsKey(tmp_sql)){
                tmp_wftype = wftypeMap.get(tmp_sql);
              }
              String fromDate_field = "fromDate";
              String fromTime_field = "fromTime";
              String toDate_field = "toDate";
              String toTime_field = "toTime";
              if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.PROCESSCHANGE.getFlowtype()+"")){
                fromDate_field = "detail_fromDate";
                fromTime_field = "detail_fromTime";
                toDate_field = "detail_toDate";
                toTime_field = "detail_toTime";
              }

              String related_requestid = rs.getString("requestid");
              String flow_fromDate = rs.getString(fromDate_field);
              String flow_fromTime = rs.getString(fromTime_field);
              String flow_toDate = rs.getString(toDate_field);
              String flow_toTime = rs.getString(toTime_field);

              Map<String,String> specialMap = getSpecialMap(tmp_wftype,related_requestid,rs,resourceId, user,
                  flow_fromDate, flow_fromTime, flow_toDate, flow_toTime);
              if(specialMap != null && !specialMap.isEmpty()){
                isLeave = Util.null2String(specialMap.get("isLeave")).equalsIgnoreCase("1");
                if(!isLeave){
                  flow_fromDate = Util.null2String(specialMap.get("fromdatedb"));
                  flow_fromTime = Util.null2String(specialMap.get("fromtimedb"));
                  flow_toDate = Util.null2String(specialMap.get("todatedb"));
                  flow_toTime = Util.null2String(specialMap.get("totimedb"));
                  related_requestid = Util.null2String(specialMap.get("related_requestid"));
                }
              }
              if(flow_fromDate.length() > 0 && flow_fromTime.length() > 0 && flow_toDate.length() > 0 && flow_toTime.length() > 0){
                long flow_fromdatetime_long = DateUtil.getCalendar(flow_fromDate+" "+flow_fromTime).getTimeInMillis();
                long flow_todatetime_long = DateUtil.getCalendar(flow_toDate+" "+flow_toTime).getTimeInMillis();
                List<Map<String,String>> duplicateVals = duplicateMaps.get(resourceId);
                checkDuplicateFlow(duplicateVals,retmap,flow_fromdatetime_long,flow_todatetime_long,duplicate_message,related_requestid,
                    isLeave, resourceId);
                if(!retmap.isEmpty()){
                  return ;
                }
              }
            }
          }
        }
      }
    }
  }

  /**
   * 遍历循环考勤变更表，直到找到最后被变更的流程数据
   * @param related_requestid 每次变更后的requestid
   * @param tablename
   * @param loopLevel
   * @param resourceId
   * @param ori_related_requestid 最原始的考勤流程requestid
   * @param flow_fromDate
   * @param flow_fromTime
   * @param flow_toDate
   * @param flow_toTime
   * @return
   */
  public Map<String, String> getProcessChange(String related_requestid, String tablename,
      int loopLevel, String resourceId, String ori_related_requestid,
      String flow_fromDate, String flow_fromTime, String flow_toDate, String flow_toTime) {
    RecordSet rs = new RecordSet();
    String sql = "select distinct leavebackrequestid,status,fromdatedb,fromtimedb,todatedb,totimedb from "+tablename+" "
        + "where requestid=? and resourceId=? and fromdatedb=? and fromtimedb=? and todatedb=? and totimedb=? ";
    if(loopLevel == 1){
      //只有第一次的时候，可以得到原始变更开始日期时间，结束日期时间
      rs.executeQuery(sql, related_requestid,resourceId,flow_fromDate,flow_fromTime,flow_toDate,flow_toTime);
    }else {
      //后面递归的时候，从中间表里就得不到之前的原始变更开始日期时间，结束日期时间了
      sql = "select distinct leavebackrequestid,status,fromdatedb,fromtimedb,todatedb,totimedb from "+tablename+" "
          + "where requestid=? and resourceId=? ";
      rs.executeQuery(sql, related_requestid,resourceId);
    }

    if(rs.next()){
      String leavebackrequestid = rs.getString("leavebackrequestid");
      String fromdatedb = rs.getString("fromdatedb");
      String fromtimedb = rs.getString("fromtimedb");
      String todatedb = rs.getString("todatedb");
      String totimedb = rs.getString("totimedb");
      String status = rs.getString("status");
      if("1".equalsIgnoreCase(status)){
        if(leavebackrequestid.length() > 0 && leavebackrequestid.indexOf(",") > -1){
          leavebackrequestid = leavebackrequestid.substring(1);
        }
        //如果递归超过50次，说明这个流程至少变更了50次，那就放过他
        if (loopLevel > 50){
          return null;
        }
        loopLevel++;
        return getProcessChange(leavebackrequestid, tablename,loopLevel, resourceId,ori_related_requestid,
            fromdatedb, fromtimedb, todatedb, totimedb);
      }else {
        Map<String, String> new_datetimeMap = Maps.newHashMap();
        if(leavebackrequestid.length() > 0){
          if(leavebackrequestid.indexOf(",") > -1){
            leavebackrequestid = leavebackrequestid.substring(1);
          }
//          if(leavebackrequestid.equalsIgnoreCase(ori_related_requestid)){
//            new_datetimeMap.put("fromdatedb", "");
//            new_datetimeMap.put("fromtimedb", "");
//            new_datetimeMap.put("todatedb", "");
//            new_datetimeMap.put("totimedb", "");
//            return new_datetimeMap;
//          }
          new_datetimeMap.put("fromdatedb", fromdatedb);
          new_datetimeMap.put("fromtimedb", fromtimedb);
          new_datetimeMap.put("todatedb", todatedb);
          new_datetimeMap.put("totimedb", totimedb);
          new_datetimeMap.put("related_requestid", related_requestid);
        }
        return new_datetimeMap;
      }
    }else{
      if(loopLevel > 1){
        //如果变更表里有数据，最后又没查询到了，表示被撤销了
        Map<String, String> new_datetimeMap = Maps.newHashMap();
        new_datetimeMap.put("fromdatedb", "");
        new_datetimeMap.put("fromtimedb", "");
        new_datetimeMap.put("todatedb", "");
        new_datetimeMap.put("totimedb", "");
        return new_datetimeMap;
      }
    }
    return Maps.newHashMap();
  }

  /**
   * 非补卡,出差流程，即需要开始日期时间 结束日期时间的流程
   * @param checkRuleDataSet
   * @param requestid
   * @param wfids
   * @param user
   * @param duplicate_message
   * @param retmap
   */
  public void doWhenisCommonDuplicate(Set<Entry<String, Object>> checkRuleDataSet, int requestid,
      List<String> wfids, User user, String duplicate_message,
      Map<String, Object> retmap) throws Exception{
    Map<String,String> wftypeMap = Maps.newHashMap();
    RecordSet rs = new RecordSet();
    Map<String, List<String>> mapSqls = Maps.newHashMap();
    Map<String,List<Map<String,String>>> duplicateMaps = Maps.newHashMap();
    for (Entry<String, Object> entry : checkRuleDataSet) {
      String duplicateValue = Util.null2String(entry.getValue());
      String[] duplicateValues = duplicateValue.split("_",-1);
      if(duplicateValues.length == 5){
        String resourceId = duplicateValues[0];
        String fromDate = duplicateValues[1];
        String fromTime = duplicateValues[2];
        String toDate = duplicateValues[3];
        String toTime = duplicateValues[4];
        if(fromDate.length() == 0 || fromTime.length() == 0 || toDate.length() == 0 || toTime.length() == 0){
          continue;
        }

        long fromdatetime_long = DateUtil.getCalendar(fromDate+" "+fromTime).getTimeInMillis();
        long todatetime_long = DateUtil.getCalendar(toDate+" "+toTime).getTimeInMillis();
        buildMap(duplicateMaps, resourceId, fromdatetime_long, todatetime_long);

        for(String wfid : wfids){
          Map<String, Object> params = Maps.newHashMap();
          buildSql(mapSqls, user, wfid, fromDate, toDate, resourceId, requestid, params, wftypeMap);
        }
      }
    }

    if(!duplicateMaps.isEmpty()){
      for(Entry<String,List<Map<String,String>>> me : duplicateMaps.entrySet()){
        List<Map<String,String>> values = me.getValue();
        if(values.size() > 1){
          //针对当前流程本身，如果是明细表，多条明细之间也需要校验
          for(int i = 0 ; i < values.size() ; i++){
            long fromdatetime_long = StringUtil.parseToLong(values.get(i).get("fromdatetime_long"));
            long todatetime_long = StringUtil.parseToLong(values.get(i).get("todatetime_long"));
            for(int j = i+1 ; j < values.size() ;j++){
              long j_fromdatetime_long = StringUtil.parseToLong(values.get(j).get("fromdatetime_long"));
              long j_todatetime_long = StringUtil.parseToLong(values.get(j).get("todatetime_long"));
              if(todatetime_long <= j_fromdatetime_long || fromdatetime_long >= j_todatetime_long){
                //这样表示流程不交叉
              }else{
                retmap.put("status", "-1");
                retmap.put("message",  SystemEnv.getHtmlLabelName(516400,user.getLanguage()));
                return;
              }
            }
          }
        }
      }
    }
    boolean isLeave = false;
    if(retmap.isEmpty() && !mapSqls.isEmpty()){
      RecordSet rs1 = new RecordSet();
      for(Entry<String,List<String>> me : mapSqls.entrySet()){
        String resourceId = me.getKey();
        if(duplicateMaps.containsKey(resourceId)){
          List<String> values = me.getValue();
          for(int i = 0 ; i <values.size() ; i++){
            String tmp_sql = values.get(i);
            rs.executeQuery(tmp_sql);
            while (rs.next()){
              String tmp_wftype = "";
              if(wftypeMap.containsKey(tmp_sql)){
                tmp_wftype = wftypeMap.get(tmp_sql);
              }
              String fromDate_field = "fromDate";
              String fromTime_field = "fromTime";
              String toDate_field = "toDate";
              String toTime_field = "toTime";
              if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.PROCESSCHANGE.getFlowtype()+"")){
                fromDate_field = "detail_fromDate";
                fromTime_field = "detail_fromTime";
                toDate_field = "detail_toDate";
                toTime_field = "detail_toTime";
              }

              String related_requestid = rs.getString("requestid");
              String flow_fromDate = rs.getString(fromDate_field);
              String flow_fromTime = rs.getString(fromTime_field);
              String flow_toDate = rs.getString(toDate_field);
              String flow_toTime = rs.getString(toTime_field);

              Map<String,String> specialMap = getSpecialMap(tmp_wftype,related_requestid,rs,resourceId, user,
                  flow_fromDate, flow_fromTime, flow_toDate, flow_toTime);
              if(specialMap != null && !specialMap.isEmpty()){
                isLeave = Util.null2String(specialMap.get("isLeave")).equalsIgnoreCase("1");
                if(!isLeave){
                  flow_fromDate = Util.null2String(specialMap.get("fromdatedb"));
                  flow_fromTime = Util.null2String(specialMap.get("fromtimedb"));
                  flow_toDate = Util.null2String(specialMap.get("todatedb"));
                  flow_toTime = Util.null2String(specialMap.get("totimedb"));
                  related_requestid = Util.null2String(specialMap.get("related_requestid"));
                }
              }
              if(flow_fromDate.length() > 0 && flow_fromTime.length() > 0 && flow_toDate.length() > 0 && flow_toTime.length() > 0){
                long flow_fromdatetime_long = DateUtil.getCalendar(flow_fromDate+" "+flow_fromTime).getTimeInMillis();
                long flow_todatetime_long = DateUtil.getCalendar(flow_toDate+" "+flow_toTime).getTimeInMillis();
                List<Map<String,String>> duplicateVals = duplicateMaps.get(resourceId);
                checkDuplicateFlow(duplicateVals,retmap,flow_fromdatetime_long,flow_todatetime_long,duplicate_message,related_requestid,isLeave,
                    resourceId);
                if(!retmap.isEmpty()){
                  return ;
                }
              }
            }
          }
        }
      }
    }
  }

  public boolean getLeaveBack(String related_requestid, long fromdatetime_long,
      long todatetime_long, String resourceId) {
    List<Long> all_long = Lists.newArrayList();
    boolean isInLeaveBack = false;
    RecordSet rs = new RecordSet();
    String sql = "select distinct fromDatedb,fromTimedb,toDatedb,toTimedb from kq_flow_split_leaveback where leavebackrequestid=? and resourceId=?  order by fromDatedb,fromTimedb,toDatedb,toTimedb\n ";
    rs.executeQuery(sql, related_requestid,resourceId);
    while (rs.next()){
      String flow_fromDate = rs.getString("fromDatedb");
      String flow_fromTime = rs.getString("fromTimedb");
      String flow_toDate = rs.getString("toDatedb");
      String flow_toTime = rs.getString("toTimedb");
      long flow_fromdatetime_long = DateUtil.getCalendar(flow_fromDate+" "+flow_fromTime).getTimeInMillis();
      long flow_todatetime_long = DateUtil.getCalendar(flow_toDate+" "+flow_toTime).getTimeInMillis();
      if(!all_long.contains(flow_fromdatetime_long)){
        all_long.add(flow_fromdatetime_long);
      }else{
        all_long.remove(flow_fromdatetime_long);
      }
      if(!all_long.contains(flow_todatetime_long)){
        all_long.add(flow_todatetime_long);
      }else{
        all_long.remove(flow_todatetime_long);
      }
    }
    for(int i = 0 ; i < all_long.size() ;){
      long flow_fromdatetime_long = all_long.get(i);
      long flow_todatetime_long = all_long.get(i+1);
      //如果当前重复的区间刚好在销假区间内
      if(fromdatetime_long >= flow_fromdatetime_long && fromdatetime_long <= flow_todatetime_long
          && todatetime_long >= flow_fromdatetime_long && todatetime_long <= flow_todatetime_long ){
        isInLeaveBack = true;
        break;
      }
      i = i +2;
    }
    return isInLeaveBack;
  }

  /**
   * 补卡流程，有两种控制:
   * 重复校验只需要控制打卡日期时间是否重复了
   * 次数校验需要控制，每日，每周，每月可提交的补卡次数
   * 当前是重复校验
   * @param checkRuleDataSet
   * @param requestid
   * @param wfids
   * @param user
   */
  public void doWhenisDuplicateCard(Set<Entry<String, Object>> checkRuleDataSet, int requestid,
      List<String> wfids, User user, String duplicate_message,
      Map<String, Object> retmap) throws Exception{
    RecordSet rs = new RecordSet();
    KQAttProcSetComInfo kqAttProcSetComInfo = new KQAttProcSetComInfo();
    Map<String, List<String>> mapSqls = Maps.newHashMap();
    Map<String,List<String>> duplicateMaps = Maps.newHashMap();
    List<String> duplicateLists = Lists.newArrayList();
    List<String> sqls = Lists.newArrayList();
    KQAttFlowSetBiz kqAttFlowSetBiz = new KQAttFlowSetBiz();
    for (Entry<String, Object> entry : checkRuleDataSet) {
      String duplicateValue = Util.null2String(entry.getValue());
      String[] duplicateValues = duplicateValue.split("_",-1);
      if(duplicateValues.length == 3){
        String resourceId = duplicateValues[0];
        String signdate = duplicateValues[1];
        String signtime = duplicateValues[2];
        if(resourceId.length() == 0 || signdate.length() == 0 || signtime.length() == 0){
          continue;
        }

        String signdate_time = signdate+"_"+signtime;
        if(duplicateMaps.containsKey(resourceId)){
          List<String> tmp_duplicateLists =duplicateMaps.get(resourceId);
          if(tmp_duplicateLists.contains(signdate_time)){
            retmap.put("status", "-1");
            retmap.put("message",  SystemEnv.getHtmlLabelName(516400,user.getLanguage()));
            return;
          }
        }else{
          duplicateLists = Lists.newArrayList();
          duplicateLists.add(signdate_time);
          duplicateMaps.put(resourceId, duplicateLists);
        }
        for(String wfid : wfids){
          Map<String, Object> params = Maps.newHashMap();
          params.put("typeselect", "6");
          params.put("tabKey", "3");
          params.put("kqtype", kqAttProcSetComInfo.getkqType(wfid));
          params.put("isMyKQ", "1");
          params.put("workflowid", wfid);
          params.put("custome_sql", " detail_signdate='"+signdate+"' and detail_signtime='"+signtime+"' ");
          params.put("resourceId", resourceId);
          params.put("not_start_node", "1");
          if(requestid > 0){
            params.put("not_requestId", requestid);
          }
		  params.put("isNoAccount", "1");
          Map<String,String> sqlMap = kqAttFlowSetBiz.getFLowSql(params,user);
          String backfields = "  * ";
          String fromSql  = Util.null2String(sqlMap.get("from"));
          String sqlWhere = Util.null2String(sqlMap.get("where"));
          String allSql = "select "+ backfields + fromSql+sqlWhere;
          rs.executeQuery(allSql);
          kqLog.info("doWhenisDuplicateCard:allSql:"+allSql);
          if(rs.next()){
            String mobile_duplicate_message= duplicate_message;
            String related_requestid = rs.getString("requestid");
            String e_duplicate_message= duplicate_message;
            String[] replace_str = new String[]{new KQTransMethod().getWorkFlowUrl(related_requestid),new WorkflowRequestComInfo().getRequestName(related_requestid)};
            String[] mobile_replace_str = new String[]{new KQTransMethod().getWorkFlowUrl4mobile(related_requestid),new WorkflowRequestComInfo().getRequestName(related_requestid)};
            String[] e_replace_str = new String[]{new WorkflowRequestComInfo().getRequestName(related_requestid),new WorkflowRequestComInfo().getRequestName(related_requestid)};
            mobile_duplicate_message = StringUtils.replaceEach(mobile_duplicate_message, ori_str,mobile_replace_str);
            duplicate_message = StringUtils.replaceEach(duplicate_message, ori_str,replace_str);
            e_duplicate_message = StringUtils.replaceEach(e_duplicate_message, ori_str,e_replace_str);
            retmap.put("status", "-1");
            retmap.put("message",  duplicate_message);
            retmap.put("mobile_message",  mobile_duplicate_message);
            //给小e用的
            retmap.put("e_message",  e_duplicate_message);
            return;
          }
          if(mapSqls.containsKey(resourceId)){
            List<String> tmp_sqls = mapSqls.get(resourceId);
            tmp_sqls.add(allSql);
          }else{
            sqls = Lists.newArrayList();
            sqls.add(allSql);
            mapSqls.put(resourceId,sqls);
          }
        }
      }
    }
  }

  /**
   * 根据规则组装查询sql
   * @param mapSqls
   * @param user
   * @param wfid
   * @param fromDate
   * @param toDate
   * @param resourceId
   * @param requestid
   * @param params
   */
  public void buildSql(Map<String, List<String>> mapSqls, User user, String wfid, String fromDate,
      String toDate, String resourceId, int requestid,
      Map<String, Object> params,Map<String,String> wftypeMap){
    RecordSet rs = new RecordSet();
    KQAttProcSetComInfo kqAttProcSetComInfo = new KQAttProcSetComInfo();
    KQAttFlowSetBiz kqAttFlowSetBiz = new KQAttFlowSetBiz();
    List<String> sqls = Lists.newArrayList();
    String tmp_wftype = kqAttProcSetComInfo.getkqType(wfid);
    params.put("typeselect", "6");
    params.put("tabKey", "3");
    params.put("kqtype", tmp_wftype);
    params.put("isMyKQ", "1");
    params.put("resourceId", resourceId);
    if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.EVECTION.getFlowtype()+"")){
      params.put("fromDate", fromDate);
      params.put("toDate", toDate);
      if (rs.getDBType().equalsIgnoreCase("oracle")||rs.getDBType().equalsIgnoreCase("postgresql")) {
        params.put("custome_sql", " (resourceId='"+resourceId+"' or ','||to_char(companion)||',' like '%," + resourceId + ",%') ");
      } else if (rs.getDBType().equalsIgnoreCase("mysql")) {
        params.put("custome_sql", " (resourceId='"+resourceId+"' or CONCAT(CONCAT(',',companion),',') like '%," + resourceId + ",%') ");
      } else {
        params.put("custome_sql", " (resourceId='"+resourceId+"' or ','+cast(companion as varchar(max))+',' like '%," + resourceId + ",%') ");
      }
      params.put("resourceId", "");
    }else if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.PROCESSCHANGE.getFlowtype()+"")){
      params.put("custome_sql", " ( detail_fromDate between '"+fromDate+"' and '"+toDate+"' or detail_toDate between '"+fromDate+"' and '"+toDate+"' "
          + " or '"+fromDate+"' between detail_fromDate and detail_toDate or '"+toDate+"' between detail_fromDate and detail_toDate) "
          +" ");
    }else{
      params.put("fromDate", fromDate);
      params.put("toDate", toDate);
    }
    params.put("not_start_node", "1");
    params.put("workflowid", wfid);
    if(requestid > 0){
      params.put("not_requestId", requestid);
    }
	params.put("isNoAccount", "1");
    Map<String,String> sqlMap = kqAttFlowSetBiz.getFLowSql(params,user);
    String backfields = "  * ";
    String fromSql  = Util.null2String(sqlMap.get("from"));
    String sqlWhere = Util.null2String(sqlMap.get("where"));
    String allSql = "select "+ backfields + fromSql+sqlWhere;
    //存一下sql对应的考勤流程类型
    wftypeMap.put(allSql,tmp_wftype);
    if(mapSqls.containsKey(resourceId)){
      List<String> tmp_sqls = mapSqls.get(resourceId);
      tmp_sqls.add(allSql);
    }else{
      sqls = Lists.newArrayList();
      sqls.add(allSql);
      mapSqls.put(resourceId,sqls);
    }
  }

  /**
   * 组装人员和开始结束日期时间的map集合
   * @param duplicateMaps
   * @param resourceId
   * @param fromdatetime_long
   * @param todatetime_long
   */
  public void buildMap(Map<String, List<Map<String, String>>> duplicateMaps, String resourceId,
      long fromdatetime_long, long todatetime_long) {
    Map<String,String> duplicateMap = Maps.newConcurrentMap();
    List<Map<String,String>> duplicateLists = Lists.newArrayList();
    duplicateMap.put("fromdatetime_long", ""+fromdatetime_long);
    duplicateMap.put("todatetime_long", ""+todatetime_long);
    if(duplicateMaps.containsKey(resourceId)){
      List<Map<String,String>> tmp_duplicateLists =duplicateMaps.get(resourceId);
      tmp_duplicateLists.add(duplicateMap);
    }else{
      duplicateLists = Lists.newArrayList();
      duplicateLists.add(duplicateMap);
      duplicateMaps.put(resourceId, duplicateLists);
    }
  }

  /**
   * 组装人员和开始结束日期时间的map集合
   * @param duplicateMaps
   * @param resourceId
   * @param fromdatetime_long
   * @param todatetime_long
   * @param attendance_fromdatetime_long
   * @param attendance_todatetime_long
   */
  public void buildMap4Process(Map<String, List<Map<String, String>>> duplicateMaps,
      String resourceId,
      long fromdatetime_long, long todatetime_long, long attendance_fromdatetime_long,
      long attendance_todatetime_long) {
    Map<String,String> duplicateMap = Maps.newConcurrentMap();
    List<Map<String,String>> duplicateLists = Lists.newArrayList();
    duplicateMap.put("fromdatetime_long", ""+fromdatetime_long);
    duplicateMap.put("todatetime_long", ""+todatetime_long);
    duplicateMap.put("attendance_fromdatetime_long", ""+attendance_fromdatetime_long);
    duplicateMap.put("attendance_todatetime_long", ""+attendance_todatetime_long);
    if(duplicateMaps.containsKey(resourceId)){
      List<Map<String,String>> tmp_duplicateLists =duplicateMaps.get(resourceId);
      tmp_duplicateLists.add(duplicateMap);
    }else{
      duplicateLists = Lists.newArrayList();
      duplicateLists.add(duplicateMap);
      duplicateMaps.put(resourceId, duplicateLists);
    }
  }

  public void checkDuplicateFlow(List<Map<String, String>> duplicateVals,
      Map<String, Object> retmap, long flow_fromdatetime_long, long flow_todatetime_long,
      String duplicate_message, String related_requestid, boolean isLeave,
      String resourceId) {

    for(int j = 0 ; j < duplicateVals.size() ;j++){
      Map<String, String> duplicateMap = duplicateVals.get(j);
      long fromdatetime_long = StringUtil.parseToLong(duplicateMap.get("fromdatetime_long"));
      long todatetime_long = StringUtil.parseToLong(duplicateMap.get("todatetime_long"));
      if(duplicateMap.containsKey("attendance_fromdatetime_long") && duplicateMap.containsKey("attendance_todatetime_long")){
        //考勤变更流程独有的
        long attendance_fromdatetime_long = StringUtil.parseToLong(duplicateMap.get("attendance_fromdatetime_long"));
        long attendance_todatetime_long = StringUtil.parseToLong(duplicateMap.get("attendance_todatetime_long"));
        //这样说明重复的流程刚好是被变更的这条数据
        if(flow_fromdatetime_long == attendance_fromdatetime_long && flow_todatetime_long == attendance_todatetime_long){
          continue;
        }
      }

      if(todatetime_long <= flow_fromdatetime_long || fromdatetime_long >= flow_todatetime_long){
        //这样表示流程不交叉
      }else{
        if(isLeave){
          long back_fromdatetime_long = fromdatetime_long;
          long back_todatetime_long = todatetime_long;
          if(fromdatetime_long < flow_fromdatetime_long){
            back_fromdatetime_long = flow_fromdatetime_long;
          }
          if(todatetime_long > flow_todatetime_long){
            back_todatetime_long = flow_todatetime_long;
          }
          boolean isInLeaveBack = getLeaveBack(related_requestid,back_fromdatetime_long,back_todatetime_long,resourceId);
          if(isInLeaveBack){
            continue;
          }
        }
        retmap.put("status", "-1");
        String mobile_duplicate_message= duplicate_message;
        String e_duplicate_message= duplicate_message;
        String[] replace_str = new String[]{new KQTransMethod().getWorkFlowUrl(related_requestid),new WorkflowRequestComInfo().getRequestName(related_requestid)};
        String[] mobile_replace_str = new String[]{new KQTransMethod().getWorkFlowUrl4mobile(related_requestid),new WorkflowRequestComInfo().getRequestName(related_requestid)};
        String[] e_replace_str = new String[]{new WorkflowRequestComInfo().getRequestName(related_requestid),new WorkflowRequestComInfo().getRequestName(related_requestid)};
        mobile_duplicate_message = StringUtils.replaceEach(mobile_duplicate_message, ori_str,mobile_replace_str);
        duplicate_message = StringUtils.replaceEach(duplicate_message, ori_str,replace_str);
        e_duplicate_message = StringUtils.replaceEach(e_duplicate_message, ori_str,e_replace_str);
        retmap.put("message",  duplicate_message);
        retmap.put("mobile_message",  mobile_duplicate_message);
        //给小e用的
        retmap.put("e_message",  e_duplicate_message);
        return;
      }
    }
  }

  /**
   * 出差，公出流程会受到归档后的变更流程影响
   * 请假流程会受到归档后的销假流程影响
   * @param tmp_wftype
   * @param related_requestid
   * @param rs
   * @param resourceId
   * @param user
   * @param flow_fromDate
   * @param flow_fromTime
   * @param flow_toDate
   * @param flow_toTime
   */
  public Map<String, String> getSpecialMap(String tmp_wftype,
      String related_requestid, RecordSet rs, String resourceId, User user,
      String flow_fromDate, String flow_fromTime, String flow_toDate, String flow_toTime) {
    Map<String, String> specialMap = Maps.newHashMap();

    if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.EVECTION.getFlowtype()+"")){
      specialMap = getProcessChange(related_requestid,KqSplitFlowTypeEnum.EVECTION.getTablename(),1,resourceId,related_requestid,flow_fromDate,flow_fromTime,flow_toDate,flow_toTime);
    }else if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.OUT.getFlowtype()+"")){
      specialMap = getProcessChange(related_requestid,KqSplitFlowTypeEnum.OUT.getTablename(),1,resourceId,related_requestid,
          flow_fromDate, flow_fromTime, flow_toDate, flow_toTime);
    }else if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.PROCESSCHANGE.getFlowtype()+"")){
      String changerequestid = rs.getString("changerequestid");
      Map<String, Object> params = Maps.newHashMap();
      params.put("resourceId", resourceId);
      params.put("requestid", changerequestid);
      params.put("isAll", "1");
      GetProcessChangeTypeCmd processChangeTypeCmd = new GetProcessChangeTypeCmd(params, user);
      Map<String, Object> retmaps = processChangeTypeCmd.execute(null);
      if(retmaps != null && !retmaps.isEmpty()){
        if(retmaps.containsKey("process_tablename")){
          String process_tablename = Util.null2String(retmaps.get("process_tablename"));
          if(process_tablename != null && process_tablename.length() > 0){
            specialMap = getProcessChange(related_requestid,process_tablename,1,resourceId,related_requestid,
                flow_fromDate, flow_fromTime, flow_toDate, flow_toTime);
            if(!specialMap.isEmpty()){
              specialMap.put("isProcess", "1");
            }
          }
        }
      }
    }else if(tmp_wftype.equalsIgnoreCase(KqSplitFlowTypeEnum.LEAVE.getFlowtype()+"")) {
      specialMap.put("isLeave", "1");
    }
    return specialMap;
  }
}
