package com.sifang.modules.flowable.dao;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.flowable.constants.ItemConstants;
import com.sifang.modules.flowable.entity.ItemManage;
import com.sifang.modules.flowable.utils.FormUtils;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.persistence.BaseDao;
import com.sifang.modules.sys.common.persistence.Parameter;
import com.sifang.modules.sys.entity.Operator;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.util.ParaUtils;
import com.sifang.modules.sys.util.SqlBuilder;
import com.sifang.modules.taskdispatch.util.ReviewGroupUtil;
import org.hibernate.SQLQuery;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;


@Repository
public class ItemManageDao extends BaseDao<ItemManage> {

    public List<Record> waiteDealItemList(LayuiPage<Record> page, Map<String, String> map, Operator operator,List<String> authEntry,List<String> changeEntry){
        if (authEntry == null || authEntry.isEmpty()) {
           authEntry.add("-1");
        }
        if (changeEntry == null || changeEntry.isEmpty()) {
            changeEntry.add("-1");
        }
        SqlBuilder sqlBuilder=new SqlBuilder();
       /* sqlBuilder.line(" SELECT  t.ID_ AS taskId ,ifnull(t.`FORM_KEY_`,m.form_key) AS formKey ,DATE_FORMAT(t.`CREATE_TIME_`,'%Y-%m-%d %H:%i:%s') AS taskCreateTime,m.name  ");
        sqlBuilder.line(",m.`create_name` AS createName  ,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS createTime,t.CATEGORY_ as taskCategory,m.application_id ");
        sqlBuilder.line(",ifnull(t.NAME_,m.name)  as taskName ");
        sqlBuilder.line(" FROM  `crm_item_manage` m  ");
        sqlBuilder.line(" LEFT JOIN  `act_ru_task` t  ON (t.PROC_INST_ID_=m.`process_instance_id` and t.CATEGORY_='1') or (t.CATEGORY_='3' AND t.PARENT_TASK_ID_=m.`process_instance_id`) ");
        sqlBuilder.line(" WHERE  ((t.ASSIGNEE_ =? and m.status!='0')  ",operator.getUserId());
        sqlBuilder.inst("OR (m.form_key IN  ", authEntry );
        sqlBuilder.line(" and m.status='1')) ");*/
        sqlBuilder.line("  SELECT b.* FROM    ( SELECT e.partner_id as partnerId, t.ID_ AS taskId ,IFNULL(t.`FORM_KEY_`,m.form_key) AS formKey ,DATE_FORMAT(t.`CREATE_TIME_`,'%Y-%m-%d %H:%i:%s') AS taskCreateTime," +
                "m.name,");
//                "if(e.status<='4'," +
//                "replace(m.NAME,e.tenant_name,CONCAT(e.province, e.area,e.tenant_name,trim(trailing '.' from TRIM( trailing'0' from round(e.design_capacity/1000,3))),'KW光伏电站'))," +
//                "replace(m.NAME,e.tenant_name,CONCAT(e.province, e.area,e.tenant_name,trim(trailing '.' from TRIM( trailing'0' from round(e.actual_capacity/1000,3))),'KW光伏电站'))) name, ");
        sqlBuilder.line(" m.`create_name` AS createName  ,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS createTime,t.CATEGORY_ AS taskCategory,m.application_id,");
        sqlBuilder.line(" IFNULL(t.NAME_,m.name)  AS taskName,m.process_instance_id    FROM  `crm_item_manage` m  LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id");
        sqlBuilder.line(" LEFT JOIN  `act_ru_task` t  ON (t.PROC_INST_ID_=m.`process_instance_id` AND t.CATEGORY_='1') OR (t.CATEGORY_='3' AND t.PARENT_TASK_ID_=m.`process_instance_id`) ");
        sqlBuilder.line("  WHERE  t.ASSIGNEE_ =? AND m.status in('1','2') ",operator.getUserId());
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  UNION ALL ");  //这个是查询电站流程中的审核
        sqlBuilder.line("  SELECT e.partner_id as partnerId, NULL AS taskId,  m.form_key AS formKey,NULL AS taskCreateTime," +
                        "m.name,"+
//                "if(e.status<='4'," +
//                "replace(m.NAME,e.tenant_name,CONCAT(e.province, e.area,e.tenant_name,trim(trailing '.' from TRIM( trailing'0' from round(e.design_capacity/1000,3))),'KW光伏电站'))," +
//                "replace(m.NAME,e.tenant_name,CONCAT(e.province, e.area,e.tenant_name,trim(trailing '.' from TRIM( trailing'0' from round(e.actual_capacity/1000,3))),'KW光伏电站'))) name," +
                "m.`create_name` AS createName,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS createTime, ");
        sqlBuilder.line("  NULL AS taskCategory ,m.application_id,m.name AS taskName ,m.process_instance_id FROM ");
        sqlBuilder.line("  `crm_item_manage` m  LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id WHERE   m.status='1' AND  ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   e.distributor_id = ? AND  ",map.get("traderId"));
        }
        sqlBuilder.inst("  m.form_key IN   ",authEntry);
        getEntryAuthoryCondition(sqlBuilder,map);
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line(" UNION ALL ");   //这个是查询电站变更里面的任务
        sqlBuilder.line("  SELECT e.partner_id as partnerId, NULL AS taskId,  m.form_key AS formKey,NULL AS taskCreateTime," +
                "m.name,"+
//                "if(e.status<='4'," +
//                "replace(m.NAME,e.tenant_name,CONCAT(e.province, e.area,e.tenant_name,trim(trailing '.' from TRIM( trailing'0' from round(e.design_capacity/1000,3))),'KW光伏电站'))," +
//                "replace(m.NAME,e.tenant_name,CONCAT(e.province, e.area,e.tenant_name,trim(trailing '.' from TRIM( trailing'0' from round(e.actual_capacity/1000,3))),'KW光伏电站'))) name," +
                "m.`create_name` AS createName,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS createTime, ");
        sqlBuilder.line("   NULL AS taskCategory ,m.application_id,m.name AS taskName ,m.process_instance_id FROM   `crm_item_manage` m  LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id");
        sqlBuilder.line("   WHERE   m.status='1' AND  ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   e.distributor_id = ? AND  ",map.get("traderId"));
        }
        sqlBuilder.inst("  m.form_key IN   ",changeEntry);
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  ) AS b ");
        sqlBuilder.line(" ORDER BY b.createTime DESC  ");
        if (page != null) {
            sqlBuilder.line(" limit " + page.getLimit() + " offset " + (page.getPage() - 1) * page.getLimit());
            Long count = getListCount(map,operator,authEntry,changeEntry);
            page.setCount(count);
        }
        return Db.find(sqlBuilder.build(),sqlBuilder.params());
    }

    public List<Record> LcWaiteDealItemList(LayuiPage<Record> page, Map<String, String> map, Operator operator,List<String> authEntry,List<String> changeEntry){
        SqlBuilder sqlBuilder=new SqlBuilder();
        sqlBuilder.line("   SELECT  t.ID_ AS taskId ,IFNULL(t.`FORM_KEY_`,m.form_key) AS formKey ,DATE_FORMAT(t.`CREATE_TIME_`,'%Y-%m-%d %H:%i:%s') AS taskCreateTime,m.name, ");
        sqlBuilder.line(" m.`create_name` AS createName  ,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS createTime,t.CATEGORY_ AS taskCategory,m.application_id,");
        sqlBuilder.line(" IFNULL(t.NAME_,m.name)  AS taskName,m.process_instance_id    FROM  `crm_item_manage` m  ");
        sqlBuilder.line(" LEFT JOIN  `act_ru_task` t  ON (t.PROC_INST_ID_=m.`process_instance_id` AND t.CATEGORY_='1') OR (t.CATEGORY_='3' AND t.PARENT_TASK_ID_=m.`process_instance_id`) ");
        sqlBuilder.line("  WHERE  m.status in('1','2') ");
        sqlBuilder.inst("and  m.form_key in", FormUtils.getProcessFormKeys());
        if (!operator.getUserId().equals("1")){
            sqlBuilder.line(" and t.ASSIGNEE_ =?",operator.getUserId());
        }
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line(" ORDER BY m.create_time DESC  ");
        if (page != null) {
            sqlBuilder.line(" limit " + page.getLimit() + " offset " + (page.getPage() - 1) * page.getLimit());
            Long count = LcGetListCount(map,operator,authEntry,changeEntry);
            page.setCount(count);
        }
        return Db.find(sqlBuilder.build(),sqlBuilder.params());
    }

    public Long LcGetListCount(Map<String, String> map,Operator operator,List<String> authEntry,List<String> changeEntry){
        SqlBuilder sqlBuilder=new SqlBuilder();
        sqlBuilder.line("   SELECT count(m.NAME) ");
        sqlBuilder.line("   FROM  `crm_item_manage` m  ");
        sqlBuilder.line(" LEFT JOIN  `act_ru_task` t  ON (t.PROC_INST_ID_=m.`process_instance_id` AND t.CATEGORY_='1') OR (t.CATEGORY_='3' AND t.PARENT_TASK_ID_=m.`process_instance_id`) ");
        sqlBuilder.line("  WHERE  m.status in('1','2') ");
        sqlBuilder.inst("and  m.form_key in", FormUtils.getProcessFormKeys());
        if (!operator.getUserId().equals("1")){
            sqlBuilder.line(" and t.ASSIGNEE_ =?",operator.getUserId());
        }
        getSqlCondition(sqlBuilder,map);
        Long count=Db.queryLong(sqlBuilder.build(),sqlBuilder.params());
        return count;
    }

    public List<Record> lcEndDealItemList(LayuiPage<Record> page, Map<String, String> map, Operator operator){
        SqlBuilder sqlBuilder=new SqlBuilder();
        //这个是查询电站流程中的审核
        sqlBuilder.line("  SELECT NULL AS taskId,  m.form_key AS formKey,NULL AS taskCreateTime,m.name,m.`create_name` AS createName,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS createTime, e.power_station_code,e.scheme_type_name,e.province,e.city,e.area ,");
        sqlBuilder.line("  NULL AS taskCategory ,m.application_id,m.name AS taskName ,m.process_instance_id , d.handle_result,m.current_task_name,m.end_time ,d.handle_user_name ,DATE_FORMAT( d.handle_time, '%Y-%m-%d %H:%i:%s' ) AS handleTime  , t.name  as traderName FROM ");
        sqlBuilder.line("  `crm_item_manage` m  LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id  LEFT JOIN crm_item_task_detail d on  d.process_instance_id=m.process_instance_id  LEFT JOIN crm_trader t on t.id = m.trader_id WHERE   m.status='2' ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("  and e.distributor_id = ? AND  ",map.get("traderId"));
        }
        sqlBuilder.inst("and  m.form_key in", FormUtils.getProcessFormKeys());
        if (!operator.getUserId().equals("1")){
            sqlBuilder.line(" and d.handle_user_id= ?",operator.getUserId());
        }
        getListByInfo(sqlBuilder,map);
        sqlBuilder.line(" ORDER BY m.end_time DESC  ");
        if (page != null) {
            sqlBuilder.line(" limit " + page.getLimit() + " offset " + (page.getPage() - 1) * page.getLimit());
            Long count = getLcEndDealItem(map,operator);
            page.setCount(count);
        }
        return Db.find(sqlBuilder.build(),sqlBuilder.params());
    }

    public Long getLcEndDealItem(Map<String,String> map,Operator operator){
        SqlBuilder sqlBuilder=new SqlBuilder();
        sqlBuilder.line("  SELECT COUNT(1) FROM ");
        sqlBuilder.line("  `crm_item_manage` m  LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id  LEFT JOIN crm_item_task_detail d on  d.process_instance_id=m.process_instance_id LEFT JOIN crm_trader t on t.id = m.trader_id  WHERE   m.status='2'");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line(" AND e.distributor_id = ? AND  ",map.get("traderId"));
        }
        sqlBuilder.inst("and  m.form_key in", FormUtils.getProcessFormKeys());
        if (!operator.getUserId().equals("1")){
            sqlBuilder.line(" and d.handle_user_id= ?",operator.getUserId());
        }
        getListByInfo(sqlBuilder,map);
        return Db.queryLong(sqlBuilder.build(),sqlBuilder.params());
    }

    //项目审核

    /**
     * @param type WAIT_AUDIT 待审核， WAIT_ASSIGN 待分配
     */
    public List<Record> projWaiteDealItemListBy(LayuiPage<Record> page, Map<String, String> map, Operator operator, List<String> authEntry, List<String> changeEntry, String type){
        if (authEntry == null || authEntry.isEmpty()) {
            authEntry.add("-1");
        }
        if (changeEntry == null || changeEntry.isEmpty()) {
            changeEntry.add("-1");
        }
        SqlBuilder sqlBuilder=new SqlBuilder();
        List<String> perms = new ArrayList<>(authEntry);
        perms.addAll(changeEntry);
        sqlBuilder.line("  SELECT m.id,NULL AS taskId,  m.form_key AS formKey,NULL AS taskCreateTime,e.partner_name as partnerName, e.partner_id ," +
                "m.name,"+
                "m.`create_name` AS createName,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS createTime, m.assign_audit_user_id,");
        sqlBuilder.line("   NULL AS taskCategory ,m.application_id,m.name AS taskName ,m.process_instance_id,DATE_FORMAT(m.assign_time,'%Y-%m-%d %H:%i:%s') AS assignTime,assignee,e.power_station_code,e.tenant_name as tenantName,e.province,e.city,e.area");
        sqlBuilder.line("   FROM   `crm_item_manage` m  LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id");
        sqlBuilder.line("   WHERE   m.status='1' ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   AND e.distributor_id = ?",map.get("traderId"));
        }
        sqlBuilder.inst("and m.form_key in", FormUtils.getProjectFormKeys());
        if(Objects.equals(type, ItemConstants.QUERY_TYPE_WAIT_AUDIT)) {
            sqlBuilder.line("and m.assign_audit_user_id is not null ");
        } else if (Objects.equals(type, ItemConstants.QUERY_TYPE_WAIT_ASSIGN)) {
            sqlBuilder.line("and m.assign_audit_user_id is null ");
        } else {
            throw new IllegalArgumentException("unsupported type: " + type);
        }
        getEntryAuthoryCondition(sqlBuilder,map);
        getSqlCondition(sqlBuilder,map);
        if (Objects.equals(type, ItemConstants.QUERY_TYPE_WAIT_AUDIT) && !ParaUtils.hasValues(map)) {
            sqlBuilder.line("or (m.status='1' and m.assign_audit_user_id=?)", UserUtils.getUser().getId());
        }
        sqlBuilder.line(" ORDER BY m.create_time DESC  ");
        if (page != null) {
            sqlBuilder.line(" limit " + page.getLimit() + " offset " + (page.getPage() - 1) * page.getLimit());
            Long count = projGetListCount(map,operator,perms,type);
            page.setCount(count);
        }
        return Db.find(sqlBuilder.build(),sqlBuilder.params());
    }

    public void getListByInfo(SqlBuilder sqlBuilder,Map<String,String> map){
        if(StringUtil.isNotBlank(map.get("formKey"))){
            sqlBuilder.line(" and m.form_key= ? ",map.get("formKey"));
        }
        if(StringUtil.isNotBlank(map.get("titleName"))){
            sqlBuilder.like(" and m.name like ? ",map.get("titleName"));
        }
        if(StringUtil.isNotBlank(map.get("traderName"))){
            sqlBuilder.like(" and t.name like ? ",map.get("traderName"));
        }
        if(StringUtil.isNotBlank(map.get("type"))){
            sqlBuilder.line(" and e.scheme_type_name= ? ",map.get("type"));
        }
        if(StringUtil.isNotBlank(map.get("createName"))){
            sqlBuilder.line(" and m.create_name like concat('%',?,'%') ",map.get("createName"));
        }
        if(StringUtil.isNotBlank(map.get("createTimeSta"))){
            sqlBuilder.line(" and DATE_FORMAT( m.create_time, '%Y-%m-%d' ) >= ? ",map.get("createTimeSta"));
        }
        if(StringUtil.isNotBlank(map.get("createTimeEnd"))){
            sqlBuilder.line(" and DATE_FORMAT( m.create_time, '%Y-%m-%d' ) <= ? ",map.get("createTimeEnd"));
        }
        if(StringUtil.isNotBlank(map.get("province"))){
            sqlBuilder.line(" and e.province = ? ",map.get("province"));
        }
        if(StringUtil.isNotBlank(map.get("city"))){
            sqlBuilder.line(" and e.city = ? ",map.get("city"));
        }
        if(StringUtil.isNotBlank(map.get("area"))){
            sqlBuilder.line(" and e.area = ? ",map.get("area"));
        }

    }

    public List<Record> projEndDealItemList(LayuiPage<Record> page, Map<String, String> map, Operator operator){
        SqlBuilder sqlBuilder=new SqlBuilder();
        sqlBuilder.line(" SELECT d.id,d.form_key as formKey,d.application_id,d.process_instance_id,d.task_id,d.task_name,d.handle_result,d.handle_user_id,d.handle_user_name,e.partner_name as partnerName ");
        sqlBuilder.line(" ,DATE_FORMAT(d.handle_time,'%Y-%m-%d %H:%i:%s') AS handleTime," +
                "m.name, m.create_name as createName,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s')AS createTime ");
        sqlBuilder.line(" ,DATE_FORMAT(m.end_time,'%Y-%m-%d %H:%i:%s') AS endTime,DATE_FORMAT(d.task_create_time,'%Y-%m-%d %H:%i:%s') AS taskCreateTime ");
        sqlBuilder.line(" ,m.current_task_name,m.status,e.power_station_code,e.partner_id,e.tenant_name as tenantName,e.province,e.city,e.area,m.assignee,DATE_FORMAT(m.assign_time,'%Y-%m-%d %H:%i:%s')AS assignTime,m.task_duration,m.dispatch_duration,m.leader_name");
        sqlBuilder.line(" FROM `crm_item_task_detail` d LEFT JOIN `crm_item_manage` m ON d.process_instance_id=m.process_instance_id ");
        sqlBuilder.line("left join crm_customer_entry as e on e.id=m.application_id");
        sqlBuilder.line(" WHERE m.form_key in('91','92','93','94','95','96','97','98','99','100') ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   AND e.distributor_id = ?",map.get("traderId"));
        }
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  UNION ALL ");
        sqlBuilder.line(" SELECT NULL AS id,m.form_key AS formKey,m.application_id,m.process_instance_id,NULL AS task_id,NULL AS task_name,NULL AS handle_result ,NULL AS handle_user_id,e.partner_name as partnerName");
        sqlBuilder.line(" ,m.create_name AS handle_user_name ,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS handleTime,m.name AS itemName,m.create_name as createName,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s')AS createTime");
        sqlBuilder.line(" ,DATE_FORMAT(m.end_time,'%Y-%m-%d %H:%i:%s') AS endTime,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS taskCreateTime,m.current_task_name,m.status,e.power_station_code,e.partner_id,e.tenant_name as tenantName,e.province,e.city,e.area,m.assignee,DATE_FORMAT(m.assign_time,'%Y-%m-%d %H:%i:%s')AS assignTime,null as task_duration,null as dispatch_duration,m.leader_name");
        sqlBuilder.line(" FROM crm_item_manage m left join crm_customer_entry as e on e.id=m.application_id",operator.getUserId());
        sqlBuilder.line("WHERE m.assign_audit_user_id=? AND m.status='3' and m.form_key in('91','92','93','94','95','96','97','98','99','100') ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   AND e.distributor_id = ?",map.get("traderId"));
        }
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  ORDER BY handleTime DESC     ");
        if (page != null) {
            sqlBuilder.line(" limit " + page.getLimit() + " offset " + (page.getPage() - 1) * page.getLimit());
            Long count = projGetEndDealItem(map,operator);
            page.setCount(count);
        }
        return Db.find(sqlBuilder.build(),sqlBuilder.params());
    }

    public Long projGetEndDealItem(Map<String,String> map,Operator operator){
        SqlBuilder sqlBuilder=new SqlBuilder();
        sqlBuilder.line("  SELECT COUNT(1) from( SELECT d.id FROM `crm_item_task_detail` d  ");
        sqlBuilder.line("  LEFT JOIN `crm_item_manage` m ON d.process_instance_id=m.process_instance_id ");
        sqlBuilder.line("left join crm_customer_entry as e on e.id=m.application_id");
        sqlBuilder.line(" WHERE m.form_key in('91','92','93','94','95','96','97','98','99','100') ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   AND e.distributor_id = ?",map.get("traderId"));
        }
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  UNION ALL ");
        sqlBuilder.line(" SELECT m.id  ");
        sqlBuilder.line(" FROM crm_item_manage m left join crm_customer_entry as e on e.id=m.application_id",operator.getUserId());
        sqlBuilder.line("WHERE m.assign_audit_user_id=? AND m.status='3' and m.form_key in('91','92','93','94','95','96','97','98','99','100') ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   AND e.distributor_id = ?",map.get("traderId"));
        }
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line(" )  AS b ");
        return Db.queryLong(sqlBuilder.build(),sqlBuilder.params());
    }

    public Long projGetListCount(Map<String, String> map,Operator operator,List<String> perms, String type){
        SqlBuilder sqlBuilder=new SqlBuilder();

        sqlBuilder.line(" select count(1) FROM  `crm_item_manage` m  LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id");
        sqlBuilder.line("   WHERE  m.status='1' ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   AND e.distributor_id = ?",map.get("traderId"));
        }
        sqlBuilder.inst("and m.form_key in", FormUtils.getProjectFormKeys());
        if(Objects.equals(type, ItemConstants.QUERY_TYPE_WAIT_AUDIT)) {
            sqlBuilder.line("and m.assign_audit_user_id is not null ");
        } else if (Objects.equals(type, ItemConstants.QUERY_TYPE_WAIT_ASSIGN)) {
            sqlBuilder.line("and m.assign_audit_user_id is null ");
        } else {
            throw new IllegalArgumentException("unsupported type: " + type);
        }
        getEntryAuthoryCondition(sqlBuilder,map);
        getSqlCondition(sqlBuilder,map);
        if (Objects.equals(type, ItemConstants.QUERY_TYPE_WAIT_AUDIT)) {
            sqlBuilder.line("or (m.status='1' and m.assign_audit_user_id=?)", UserUtils.getUser().getId());
        }
        Long count=Db.queryLong(sqlBuilder.build(),sqlBuilder.params());
        return count;
    }

    public Long getListCount(Map<String, String> map,Operator operator,List<String> authEntry,List<String> changeEntry){
        SqlBuilder sqlBuilder=new SqlBuilder();
        sqlBuilder.line("  SELECT SUM(b.cou) FROM ( SELECT COUNT(m.id) AS cou FROM `crm_item_manage` m ");
        sqlBuilder.line("  LEFT JOIN  `act_ru_task` t   ON (t.PROC_INST_ID_=m.`process_instance_id` AND t.CATEGORY_='1') OR (t.CATEGORY_='3' AND t.PARENT_TASK_ID_=m.`process_instance_id`) ");
        sqlBuilder.line("  WHERE  t.ASSIGNEE_ =? AND m.status!='0' ",operator.getUserId());
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  UNION ALL ");
        sqlBuilder.line("  SELECT COUNT(m.id) AS cou FROM  `crm_item_manage` m  ");
        sqlBuilder.line("   LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id WHERE  m.status='1' AND ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   e.distributor_id = ? AND  ",map.get("traderId"));
        }
        sqlBuilder.inst(" m.form_key IN ",authEntry);
        getEntryAuthoryCondition(sqlBuilder,map);
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line(" UNION ALL ");   //这个是查询电站变更里面的任务
        sqlBuilder.line("   SELECT COUNT(m.id) AS cou  FROM   `crm_item_manage` m  LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id");
        sqlBuilder.line("   WHERE   m.status='1' AND  ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   e.distributor_id = ? AND  ",map.get("traderId"));
        }
        sqlBuilder.inst("   m.form_key IN ",changeEntry);
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  )AS b  ");
        BigDecimal count=Db.queryBigDecimal(sqlBuilder.build(),sqlBuilder.params());
        Long cou=Long.valueOf(String.valueOf(count));
        return cou;
    }

    public void getSqlCondition(SqlBuilder sqlBuilder,Map<String,String> map){
        if (StringUtil.isNotBlank(map.get("formKey"))) {
            sqlBuilder.line(" AND m.form_key = ? ", map.get("formKey"));
        }
        if (StringUtil.isNotBlank(map.get("createName"))) {
            sqlBuilder.like(" AND m.create_name LIKE ? ", map.get("createName"));
        }
        if (StringUtil.isNotBlank(map.get("createTimeSta"))) {
            sqlBuilder.line(" AND m.create_time >= ?", map.get("createTimeSta") + " 00:00:00");
        }
        if (StringUtil.isNotBlank(map.get("createTimeEnd"))) {
            sqlBuilder.line(" AND m.create_time <= ?", map.get("createTimeEnd") + " 23:59:59");
        }
        if (StringUtil.isNotBlank(map.get("dispatchTimeSta"))) {
            sqlBuilder.line(" AND m.assign_time >= ?", map.get("dispatchTimeSta") + " 00:00:00");
        }
        if (StringUtil.isNotBlank(map.get("dispatchTimeEnd"))) {
            sqlBuilder.line(" AND m.assign_time <= ?", map.get("dispatchTimeEnd") + " 23:59:59");
        }
        if (StringUtil.isNotBlank(map.get("reviewTimeSta"))) {
            sqlBuilder.line(" AND m.end_time >= ?", map.get("reviewTimeSta") + " 00:00:00");
        }
        if (StringUtil.isNotBlank(map.get("reviewTimeEnd"))) {
            sqlBuilder.line(" AND m.end_time <= ?", map.get("reviewTimeEnd") + " 23:59:59");
        }
        if (StringUtil.isNotBlank(map.get("entryNo"))) {
            sqlBuilder.like(" AND e.power_station_code like ?", map.get("entryNo"));
        }
        if (StringUtil.isNotBlank(map.get("tenantName"))) {
            sqlBuilder.like(" AND e.tenant_name like ?", map.get("tenantName"));
        }
        if (StringUtil.isNotBlank(map.get("province"))) {
            sqlBuilder.line(" AND e.province= ?", map.get("province"));
        }
        if (StringUtil.isNotBlank(map.get("city"))) {
            sqlBuilder.line(" AND e.city= ?", map.get("city"));
        }
        if (StringUtil.isNotBlank(map.get("area"))) {
            sqlBuilder.line(" AND e.area= ?", map.get("area"));
        }
        if (StringUtil.isNotBlank(map.get("employeeUserId"))) {
            sqlBuilder.line(" AND m.assign_audit_user_id= ?", map.get("employeeUserId"));
        }
        if(StringUtil.isNotBlank(map.get("formKeys"))){
            sqlBuilder.inst(" and m.form_key in ", map.get("formKeys").split(","));
        }
        if (StringUtil.isNotBlank(map.get("name"))) {
            sqlBuilder.like(" AND m.name like ?", map.get("name"));
        }
        if (StringUtil.isNotBlank(map.get("partnerId"))) {
            sqlBuilder.line(" AND e.partner_id=?", map.get("partnerId"));
        }
    }

    public void getEntryAuthoryCondition(SqlBuilder sqlBuilder,Map<String,String> map){
        if(StringUtil.isNotBlank(map.get("provinceE"))){
            sqlBuilder.inst(" and e.province in ",map.get("provinceE").split(","));
        }
        if(StringUtil.isNotBlank(map.get("cityE"))){
            sqlBuilder.inst(" and e.city in  ",map.get("cityE").split(","));
        }
        if(StringUtil.isNotBlank(map.get("traderIdsE"))){
            sqlBuilder.inst(" and e.create_trader_id in ",map.get("traderIdsE").split(","));
        }
        if (StringUtil.isNotBlank(map.get("projectNumberE"))) {
            sqlBuilder.inst(" and e.project_id in ", map.get("projectNumberE").split(","));
        }
    }

    public List<Record> endDealItemList(LayuiPage<Record> page, Map<String, String> map, Operator operator){
        SqlBuilder sqlBuilder=new SqlBuilder();
        sqlBuilder.line(" SELECT d.id,d.form_key as formKey,d.application_id,d.process_instance_id,d.task_id,d.task_name,d.handle_result,d.handle_user_id,d.handle_user_name ");
        sqlBuilder.line(" ,DATE_FORMAT(d.handle_time,'%Y-%m-%d %H:%i:%s') AS handleTime,m.name AS itemName,m.create_name,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s')AS createTime ");
        sqlBuilder.line(" ,DATE_FORMAT(m.end_time,'%Y-%m-%d %H:%i:%s') AS endTime,DATE_FORMAT(d.task_create_time,'%Y-%m-%d %H:%i:%s') AS taskCreateTime ");
        sqlBuilder.line(" ,m.current_task_name,m.status ");
        sqlBuilder.line(" FROM `crm_item_task_detail` d LEFT JOIN `crm_item_manage` m ON d.process_instance_id=m.process_instance_id ");
        sqlBuilder.line(" WHERE  d.handle_user_id=? ",operator.getUserId());
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  UNION ALL ");
        sqlBuilder.line(" SELECT NULL AS id,m.form_key AS formKey,m.application_id,m.process_instance_id,NULL AS task_id,NULL AS task_name,NULL AS handle_result ,NULL AS handle_user_id");
        sqlBuilder.line(" ,m.create_name AS handle_user_name ,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS handleTime,m.name AS itemName,m.create_name,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s')AS createTime");
        sqlBuilder.line(" ,DATE_FORMAT(m.end_time,'%Y-%m-%d %H:%i:%s') AS endTime,DATE_FORMAT(m.create_time,'%Y-%m-%d %H:%i:%s') AS taskCreateTime    ,m.current_task_name,m.status ");
        sqlBuilder.line(" FROM crm_item_manage m WHERE m.assign_audit_user_id=? AND m.status='3' ",operator.getUserId());
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  ORDER BY handleTime DESC     ");
        if (page != null) {
            sqlBuilder.line(" limit " + page.getLimit() + " offset " + (page.getPage() - 1) * page.getLimit());
            Long count = getEndDealItem(map,operator);
            page.setCount(count);
        }
        return Db.find(sqlBuilder.build(),sqlBuilder.params());
    }

    public Long getEndDealItem(Map<String,String> map,Operator operator){
        SqlBuilder sqlBuilder=new SqlBuilder();
        sqlBuilder.line("  SELECT COUNT(1) from( SELECT d.id FROM `crm_item_task_detail` d  ");
        sqlBuilder.line("  LEFT JOIN `crm_item_manage` m ON d.process_instance_id=m.process_instance_id ");
        sqlBuilder.line(" WHERE d.handle_user_id=? ",operator.getUserId());
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line("  UNION ALL ");
        sqlBuilder.line(" SELECT m.id  FROM crm_item_manage m WHERE m.assign_audit_user_id=? AND m.status='3' ",operator.getUserId());
        sqlBuilder.line(" )  AS b ");
        return Db.queryLong(sqlBuilder.build(),sqlBuilder.params());
    }

    @Transactional(rollbackFor = Exception.class)
    public ItemManage addItem(String formKey, String applicationId, String processInstanceId, String name, Date createTime,String userName){
        ItemManage itemManage=new ItemManage();
        itemManage.setFormKey(formKey);
        itemManage.setApplicationId(applicationId);
        itemManage.setProcessInstanceId(processInstanceId);
        itemManage.setName(name);
        itemManage.setStatus(ItemConstants.ITEM_STATUS_AUDIT);
        itemManage.setCreateTime(createTime);
        itemManage.setCreateName(userName);
        if(StringUtil.equalsAny(formKey,"91","92","93","94")){//如果是电站的审核，那么要删除上一次还未审核的记录
           Db.update(" UPDATE `crm_item_manage` SET status='0' WHERE form_key=? AND application_id=? ",formKey,applicationId);
            //获取最近一次的审核人
            String userId = getLastAuditUserId(formKey, applicationId);
            if (StringUtil.isNotBlank(userId)) {
                itemManage.setPreferUserId(userId);
            }
        }
        save(itemManage);
        return itemManage;
    }
    @Transactional(rollbackFor = Exception.class)
    public ItemManage addItem(String formKey, String applicationId, String processInstanceId, String name, Date createTime,String userName,String traderId){
        ItemManage itemManage=new ItemManage();
        itemManage.setFormKey(formKey);
        itemManage.setApplicationId(applicationId);
        itemManage.setProcessInstanceId(processInstanceId);
        itemManage.setName(name);
        itemManage.setStatus(ItemConstants.ITEM_STATUS_AUDIT);
        itemManage.setCreateTime(createTime);
        itemManage.setCreateName(userName);
        itemManage.setTraderId(traderId);
        if(StringUtil.equalsAny(formKey,"91","92","93","94")){//如果是电站的审核，那么要删除上一次还未审核的记录
            Db.update(" UPDATE `crm_item_manage` SET status='0' WHERE form_key=? AND application_id=? ",formKey,applicationId);
            //获取最近一次的审核人
            String userId = getLastAuditUserId(formKey, applicationId);
            if (StringUtil.isNotBlank(userId)) {
                itemManage.setPreferUserId(userId);
            }
        }
        save(itemManage);
        return itemManage;
    }

    //这个是电站变更时用的，还需要保存一个
    public ItemManage addItemChange(String formKey,String applicationId,String entryId,String name, Date createTime,String userName){
        ItemManage itemManage=new ItemManage();
        itemManage.setFormKey(formKey);
        itemManage.setApplicationId(applicationId);
        itemManage.setProcessInstanceId(entryId);
        itemManage.setName(name);
        itemManage.setStatus(ItemConstants.ITEM_STATUS_AUDIT);
        itemManage.setCreateTime(createTime);
        itemManage.setCreateName(userName);
        return itemManage;
    }

    public ItemManage getItemManagementByEntryId(String entryId,String formKye){
        return getByHql("from ItemManage  WHERE  applicationId =:p1 and  formKey=:p2 and status='1' ", new Parameter(entryId,formKye));
    }

    public ItemManage getItemManagementByProcessInstanceId(String processInstanceId,String formKye){
        return getByHql("from ItemManage  WHERE  processInstanceId =:p1 and  formKey=:p2 and status='1' ", new Parameter(processInstanceId,formKye));
    }

    //获取最近一次审批的userId
    public String getLastAuditUserId(String formKeys,String entryId){
        String sql=" SELECT handle_user_id  FROM `crm_item_task_detail` d WHERE d.form_key IN("+StringUtil.joinInSql(formKeys.split(","))+") " +
                " AND (application_id=? OR process_instance_id=? ) ORDER BY handle_time DESC LIMIT 1 ";
        return Db.queryStr(sql,entryId,entryId);
    }

    public Record getById(String id) {
        List<Record> records = findByIds(Collections.singletonList(id));
        return records.get(0);
    }

    public List<Record> findByIds(List<String> itemIds) {
        if (CollectionUtils.isEmpty(itemIds)) {
            return new ArrayList<>();
        }
        SqlBuilder sb = new SqlBuilder()
                .line("select * from crm_item_manage");
        if (itemIds.size() == 1) {
            sb.line("where id=?", itemIds.get(0));
        } else {
            sb.inst("where id in ", itemIds);
        }
        return Db.find(sb.build(), sb.params());
    }

    public int assignUserId(String itemId, String assigneeUserId, Date dispatchTime, String assignee, String dispatchId) {
        SqlBuilder sb = new SqlBuilder()
                .line("update crm_item_manage set assign_audit_user_id=:uid,assign_time=:assignTime,assignee=:assignee,latest_assign_time=:assignTime,latest_dispatch_id=:dispatchId,is_priority=:isPriority ")
                .line("where id=:itemId and (assign_audit_user_id is null or assign_audit_user_id='') and end_time is null");
        SQLQuery query = getSession().createSQLQuery(sb.build());
        query.setParameter("uid", assigneeUserId);
        query.setParameter("itemId", itemId);
        query.setParameter("assignTime", dispatchTime);
        query.setParameter("assignee", assignee);
        query.setParameter("dispatchId", dispatchId);
        query.setParameter("isPriority", "0");
        return query.executeUpdate();
    }

    public int reAssignUserId(String itemId, String userId, Date reDispatchTime, String assignee, String dispatchId) {
        SqlBuilder sb = new SqlBuilder()
                .line("update crm_item_manage set assign_audit_user_id=:uid,assignee=:assignee,latest_assign_time=:time,latest_dispatch_id=:dispatchId")
                .line("where id=:itemId and assign_time is not null and end_time is null");
        SQLQuery query = getSession().createSQLQuery(sb.build());
        query.setParameter("uid", userId);
        query.setParameter("itemId", itemId);
        query.setParameter("time", reDispatchTime);
        query.setParameter("assignee", assignee);
        query.setParameter("dispatchId", dispatchId);
        return query.executeUpdate();
    }

    public void incFailTimes(String itemId) {
        Db.update("update crm_item_manage set fail_times=fail_times+1 where id=? and end_time is null and status='1'", itemId);
    }

    /**
     * 91设计审核 92档案审核 93安装验收 94并网验收 95勘测信息变更 96 完工信息变更 97设计变更 98客户信息变更 99物料变更)
     */
    public List<Record> findUnAssignedItemsByGroup(String partnerId, List<String> formKeys, long limit, List<String> excludeIds) {
        SqlBuilder sb = new SqlBuilder()
                .line("select m.id,m.form_key,m.create_time,e.city,e.province,m.prefer_user_id")
                .line("from crm_item_manage as m")
                .line("inner join crm_customer_entry as e on e.id=m.application_id and e.partner_id=?", partnerId)
                .inst("where m.form_key in ", formKeys)
                .line("and m.assign_audit_user_id is null and m.end_time is null and m.status='1'")
                .line("and (m.fail_times<3 or m.fail_times is null)");

        if (!CollectionUtils.isEmpty(excludeIds)) {
            sb.inst("and m.id not in", excludeIds);
        }
        sb.line("order by m.create_time asc").line("limit " + limit);
        return Db.find(sb.build(), sb.params());
    }

    public long assignedTaskCount(String userId) {
        SqlBuilder sb = new SqlBuilder()
                .line("select count(*)")
                .line("from crm_item_manage as m")
                .line("where end_time is null and status='1'")
                .line("and m.assign_audit_user_id=?", userId);
        return Db.queryLong(sb.build(), sb.params());
    }

    public List<Record> findUnAssignedItemsByLoc(String partnerId, String groupType, String provinces, String cities, int limit, List<String> excludeIds) {
        List<String> formKeys = ReviewGroupUtil.mapGroupType2FormKey(groupType);
        SqlBuilder sb = new SqlBuilder()
                .line("select m.id,m.form_key,m.create_time,e.city,e.province,m.prefer_user_id")
                .line("from crm_item_manage as m")
                .line("inner join crm_customer_entry as e on e.id=m.application_id and e.partner_id=?", partnerId)
                .inst("where m.form_key in ", formKeys)
                .line("and m.assign_audit_user_id is null and m.end_time is null and m.status='1'")
                .line("and (m.fail_times<3 or m.fail_times is null)");

        if (!CollectionUtils.isEmpty(excludeIds)) {
            sb.inst("and m.id not in", excludeIds);
        }

        if (StringUtil.isNotBlank(provinces)) {
            sb.inst("and e.province in", provinces.split(","));
        }
        if (StringUtil.isNotBlank(cities)) {
            sb.inst("and e.city in", cities.split(","));
        }
        sb.line("order by create_time asc");
        sb.line("limit " + limit);
        return Db.find(sb.build(), sb.params());
    }

    public List<Record> getExamineLogList(Map<String, String> map){
        SqlBuilder sqlBuilder=new SqlBuilder();
        sqlBuilder.line(" SELECT m.id,m.form_key AS formKey,m.application_id,e.power_station_code,m.process_instance_id,e.partner_id ");
        sqlBuilder.line(" FROM `crm_item_manage` m  LEFT JOIN `crm_customer_entry` e ON m.application_id=e.id ");
        sqlBuilder.line(" WHERE m.status='1' ");
        if (map.get("traderId")!= null && !Objects.equals(map.get("traderId"), "")){
            sqlBuilder.line("   AND e.distributor_id = ?",map.get("traderId"));
        }
        if (map.get("isPriority")!= null && !Objects.equals(map.get("isPriority"), "")){
            sqlBuilder.line("   AND m.is_priority = ?",map.get("isPriority"));
        }
        getEntryAuthoryCondition(sqlBuilder,map);
        getSqlCondition(sqlBuilder,map);
        sqlBuilder.line(" ORDER BY m.create_time DESC ");
        return Db.find(sqlBuilder.build(), sqlBuilder.params());
    }

    public long priorityTaskCount(String userId,String isPriority) {
        SqlBuilder sb = new SqlBuilder()
                .line("select count(*)")
                .line("from crm_item_manage as m")
                .line("where end_time is null and status='1'")
                .line("and m.assign_audit_user_id=?", userId)
                .line("and m.is_priority=?", isPriority);
        return Db.queryLong(sb.build(), sb.params());
    }

}
