package com.sifang.modules.sunshine.SystemSetting.service;

import com.google.common.collect.Maps;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.sifang.modules.config.SfCacheService;
import com.sifang.modules.customer.constant.SourceConstants;
import com.sifang.modules.order.utils.excelExt.ExcelReader;
import com.sifang.modules.sunshine.SystemSetting.dao.*;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmElectricPlan;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmElectricSet;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmPlan;
import com.sifang.modules.sunshine.SystemSetting.entity.CrmPlanMaterial;
import com.sifang.modules.sunshine.SystemSetting.form.*;
import com.sifang.modules.sunshine.SystemSetting.utils.BusinessException;
import com.sifang.modules.sunshine.SystemSetting.utils.CustomException;
import com.sifang.modules.sunshine.SystemSetting.utils.StringUtil;
import com.sifang.modules.sunshine.handler.ElectricMaterialImportHandler;
import com.sifang.modules.sunshine.handler.PlanExcelImportHandler;
import com.sifang.modules.sunshine.handler.TraderExcelImportHandler;
import com.sifang.modules.sys.common.UserUtils;
import com.sifang.modules.sys.common.entity.User;
import com.sifang.modules.sys.util.CrmUtils;
import com.sifang.modules.sys.util.LayuiPage;
import com.sifang.modules.sys.util.SqlBuilder;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * @author hongzq
 */
@Service
public class PlanService {

    @Autowired
    PlanDao planDao;

    @Autowired
    PlanMaterialDao planMaterialDao;

    @Autowired
    ElectricPlanDao electricPlanDao;

    @Autowired
    ElectricSetDao electricSetDao;
    @Autowired
    SfCacheService cacheService;

    @Autowired
    private ProjectInstallDao projectInstallDao;

    public List<Record> findAllPlan(){

        List<Record> list ;
            List<Record> projectInstalls = projectInstallDao.findProjectInstalls("");
            for (Record r : projectInstalls) {
                r.set("allPlan", new Gson().toJson(planDao.findAllPlanByTypeId(r.getStr("id"))));
            }
            list = projectInstalls;

        return list;
    }

    public List<Record> findPlanByAssembly(String projectId, String name, String planType){

        if(StringUtil.isNotBlank(projectId) && StringUtil.isBlank(planType)){

                String planList = cacheService.get(projectId);
                List<Record> list ;
                if (StringUtil.isNotBlank(planList)) {
                    list = new Gson().fromJson(planList, new TypeToken< List<Record>>() {
                    }.getType());
                }else
                {
                    List<Record> li = planDao.findPlanByAssembly(name,planType);
                    list = li;
                    cacheService.set(projectId, new Gson().toJson(list));
                }
                return list;
        }
        List<Record> rds=planDao.findPlanByAssembly(name, planType);

        return rds;
    }

    public Record getPlanById(String id){
        return planDao.getPlanById(id);
    }

    public List<Record> listMaterialByPlanId(String id){
        return planMaterialDao.listMaterialByPlanId(id);
    }

    public List<Record> listMatchedMaterialByPlanId(String entryId){
        return planMaterialDao.listMatchedMaterialByPlanId(entryId);
    }

    public Record findElectricPlan(String assembly,String num){
        return planMaterialDao.findElectricPlan(assembly,num);
    }

    /**
     * 根据项目id获取匹配方案
    */
    public List<Record> findComposePlanByEntryId(String enteyId){
        return planMaterialDao.findComposePlanByEntryId(enteyId);
    }

    @Transactional(rollbackFor = Exception.class)
    public void addOrEditPlan(AddPlan req){
        if(StrKit.isBlank(req.getId())){
            addPlan(req);
        }else {
            editPlan(req);
        }
        cacheService.del("planList");
    }

    @Transactional(rollbackFor = Exception.class)
    public void addElectricPlan(AddElectricPlan req){
        if(StrKit.isBlank(req.getId())){
            addElectric(req);
        }else {
            editElectric(req);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void addPlan(AddPlan req){
        if (checkPlanCodeExists(req.getCode(), "",req.getType())) {
            throw new BusinessException("方案编号已存在");
        }
//        checkMaterialCodeExists(req.getMaterialList(), "");
        CrmPlan plan = new CrmPlan();
        setCommonFieldForPlan(req, plan);
        plan.setStatus(SourceConstants.ZERO);
        plan.setCreateBy(UserUtils.getUser().getId());
        plan.setCreator(CrmUtils.getUserXM(UserUtils.getUser()));
        plan.setCreateTime(new Date());
        planDao.save(plan);
      //  List<AddPlanMaterial> materials = req.getMaterialList();
       // createMaterials(materials, plan.getId());

    }

    @Transactional(rollbackFor = Exception.class)
    public void editPlan(AddPlan req){
        if (checkPlanCodeExists(req.getCode(), req.getId(), req.getType())) {
            throw new BusinessException("方案编号已存在");
        }
//        checkMaterialCodeExists(req.getMaterialList(), req.getId());
        CrmPlan plan = planDao.get(req.getId());
        setCommonFieldForPlan(req, plan);
        plan.setUpdateBy(UserUtils.getUser().getId());
        plan.setUpdater(CrmUtils.getUserXM(UserUtils.getUser()));
        plan.setUpdateTime(new Date());
        planDao.save(plan);
       // planMaterialDao.deleteByPlanId(req.getId());
       // List<AddPlanMaterial> materials = req.getMaterialList();
       // createMaterials(materials, plan.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    public void deletePlan(String planIds){
        for (String planId : planIds.split(",")) {
            CrmPlan plan = planDao.get(planId);
            plan.setStatus(SourceConstants.ONE);
            plan.setUpdateBy(UserUtils.getUser().getId());
            plan.setUpdater(CrmUtils.getUserXM(UserUtils.getUser()));
            plan.setUpdateTime(new Date());
            planDao.save(plan);
        }
        cacheService.del("planList");
    }

    private void createMaterials(List<AddPlanMaterial> materials, String planId) {
        int i = 0;
        Set<String> codeSet = new HashSet<>();
        for (AddPlanMaterial material : materials) {
            if(!codeSet.add(material.getCode())){
                throw new BusinessException("第" + (i+1) + "行料号重复");
            }
            CrmPlanMaterial planMaterial = new CrmPlanMaterial();
            planMaterial.setPlanId(planId);
            planMaterial.setCode(material.getCode());
            planMaterial.setName(material.getName());
            planMaterial.setSpec(material.getSpec());
            planMaterial.setUnit(material.getUnit());
            planMaterial.setAmount(material.getAmount());
            planMaterial.setSort(i++);
            planMaterialDao.save(planMaterial);
        }
    }

    private void setCommonFieldForPlan(AddPlan req, CrmPlan plan){
        if("2".equals(req.getType())){
          if(checkCommon(req)){
              throw new BusinessException("名称+类型+组件规格 重复了！");
          }
        }
        plan.setCode(req.getCode());
        plan.setName(req.getName());
        plan.setAttach(req.getAttach());
        plan.setAttachName(req.getAttachName());
        plan.setType(req.getType());
        plan.setPlanTypeId(req.getPlanTypeId());
          plan.setPlanType(req.getPlanType());

    }

    public boolean checkCommon(AddPlan req){
        StringBuilder sb=new StringBuilder();
        sb.append(" SELECT COUNT(p.id) FROM `crm_plan` p ");
        sb.append(" WHERE CONCAT(p.name,p.plan_type,p.assembly)=? AND p.status='0'  ");
        if(StringUtil.isNotBlank(req.getId())){
            sb.append(" AND p.id <>'" +req.getId()+ "' ");
        }
        Long count=Db.queryLong(sb.toString(),req.getName().trim()+req.getPlanType().trim()+req.getAssembly().trim());
        return count>0?true:false;
    }

    public void listPlan(LayuiPage<Record> page, Map<String, String> map){
        page.setData(selectListPlan(page, map));
        page.setCount(countListPlan(map));
    }

    public List<Record> selectListPlan(LayuiPage<Record> page, Map<String, String> map) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("select p.id, p.name, p.code, p.attach, p.create_time,p.plan_type,p.attach2,p.assembly,p.assembly_count ")
                .line("from crm_plan p")
                .line("where p.status='0'");
        appendCondition(builder, map);
        builder.line("order by p.create_time desc")
                .limit(page.getPage(), page.getLimit());
        return Db.find(builder.build(), builder.params());
    }

    public Long countListPlan(Map<String, String> map) {
        SqlBuilder builder = new SqlBuilder();
        builder.line("select count(*) ")
                .line("from crm_plan p")
                .line("where p.status='0'");
        appendCondition(builder, map);
        return Db.queryLong(builder.build(), builder.params());
    }

    private boolean checkPlanCodeExists(String code, String excludeId,String type){
        SqlBuilder builder = new SqlBuilder();
        builder.line("select count(1)")
                .line("from crm_plan p")
                .line("where p.status='0' and p.code=?  ", code)
                .line("and p.type=? ",type);
        if (StrKit.notBlank(excludeId)) {
            builder.line("and p.id != ?", excludeId);
        }
        return Db.queryLong(builder.build(), builder.params()) != 0;
    }

    public void checkMaterialCodeExists(List<AddPlanMaterial> materials, String excludeId) {
        if (CollectionUtils.isEmpty(materials)) {
            return;
        }
        List<String> codeList = new ArrayList<>();
        for (AddPlanMaterial material : materials) {
            codeList.add(material.getCode());
        }
        List<String> existsCode = findExistsCode(codeList, excludeId);
        for (int i = 0; i < codeList.size(); i++) {
            if (existsCode.contains(codeList.get(i))) {
                throw new BusinessException("第" + (i + 1) + "行料号已存在");
            }
        }
    }

    public List<String> findExistsCode(List<String> codeList, String excludeId){
        SqlBuilder builder = new SqlBuilder();
        builder.line("select m.code")
                .line("from crm_plan p")
                .line("inner join crm_plan_material m on p.id=m.plan_id")
                .line("where p.status='0'")
                .inst("and m.code in ", codeList);
        if(StrKit.notBlank(excludeId)){
            builder.line("and p.id != ?", excludeId);
        }
        return Db.query(builder.build(), builder.params());
    }

    private void appendCondition(SqlBuilder builder, Map<String, String> map) {
        if(StringUtil.checkParamsValid(map.get("type"))){
            builder.line("and p.type='"+map.get("type")+"' ");
        }
        if (StringUtil.checkParamsValid(map.get("name"))) {
            builder.line("and p.name like concat('%', ?, '%')", map.get("name").trim());
        }
        if (StringUtil.checkParamsValid(map.get("code"))) {
            builder.line("and p.code like concat('%', ?, '%')", map.get("code").trim());
        }
        if (StringUtil.checkParamsValid(map.get("materialCode"))) {
            builder.line("and exists (select 1 from crm_plan_material where plan_id=p.id and code like concat('%', ?, '%'))", map.get("materialCode").trim());
        }
        if (StringUtil.checkParamsValid(map.get("materialName"))) {
            builder.line("and exists (select 1 from crm_plan_material where plan_id=p.id and name like concat('%', ?, '%'))", map.get("materialName").trim());
        }
        if (StringUtil.checkParamsValid(map.get("materialSpec"))) {
            builder.line("and exists (select 1 from crm_plan_material where plan_id=p.id and spec like concat('%', ?, '%'))", map.get("materialSpec").trim());
        }
        if(StringUtil.checkParamsValid(map.get("planType"))){
            builder.line("and p.plan_type like '%"+map.get("planType")+"%' ");
        }
        if(StringUtil.checkParamsValid(map.get("assembly"))){
            builder.line("and p.assembly like '%"+map.get("assembly")+"%' ");
        }
        if(StringUtil.checkParamsValid(map.get("assemblyCount"))){
            builder.line("and p.assembly_count='"+map.get("assemblyCount")+"' ");

        } if(StringUtil.checkParamsValid(map.get("planTypeId"))){
            builder.line("and p.plan_type_id='"+map.get("planTypeId")+"' ");
        }
        if(StringUtil.checkParamsValid(map.get("createTimeSta"))){
            builder.line(" and p.create_time >='"+map.get("createTimeSta") +" 00:00:00'");
        }
        if(StringUtil.checkParamsValid(map.get("createTimeEnd"))){
            builder.line(" and p.create_time <='"+map.get("createTimeEnd") +" 23:59:29'");
        }
    }

    /**
     * 校验导入物料数据
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> checkImportPlan(Map<String, String> params, InputStream in) {
        Map<String, Object> retMap = Maps.newHashMap();
        retMap.put("operType", "check");
        PlanExcelImportHandler handler=new PlanExcelImportHandler();
        handler.setStartSheet(1);
        handler.setStartRow(2);
        try {
            new ExcelReader().check(in, params.get("extName"), handler);
            Map<String, Object> map = (Map<String, Object>) handler.getHandlerResult();
            String templateError = (String) map.get("TemplateError");
            if(!handler.isCheckFlag()){
                handler.appendErrorDetail("<p>未填充数据</p>");
            }
            String hanl = handler.getErrorDetail();
            if (StrKit.notBlank(templateError)){
                retMap.put("errorDetail", templateError);
                retMap.put("errorMessage", "y");
            }else if (StringUtils.isNotBlank(hanl)) {
                retMap.put("errorDetail", hanl);
                retMap.put("errorMessage", "y");
            } else if ("overLimit".equalsIgnoreCase((String) map.get("overLimit"))) {
                retMap.put("overLimit", "y");
            } else {
                retMap.put("pass", "y");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return retMap;
    }

    /**
     * 导入物料数据
     */
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> importPlan(Map<String, String> params, InputStream in) {
        Map<String, Object> retMap = Maps.newHashMap();
        retMap.put("operType", "import");
        PlanExcelImportHandler handler=new PlanExcelImportHandler();
        handler.setStartSheet(1);
        handler.setStartRow(3);

        try {
            new ExcelReader().readExcel(in, params.get("fileName"), handler);

            retMap.put("pass", "y");
            retMap.put("materialList", handler.getRetList());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return retMap;
    }
    @Transactional(rollbackFor = Exception.class)
    public void addElectric(AddElectricPlan req){
        CrmElectricPlan plan=new CrmElectricPlan();
        setCommonElectricField(req,plan);
        plan.setStatus(SourceConstants.ZERO);
        plan.setCreateBy(UserUtils.getUser().getId());
        plan.setCreator(CrmUtils.getUserXM(UserUtils.getUser()));
        plan.setCreateTime(new Date());
        electricPlanDao.save(plan);


    }

    @Transactional(rollbackFor = Exception.class)
    public void editElectric(AddElectricPlan req){
        CrmElectricPlan plan=electricPlanDao.get(req.getId());
        setCommonElectricField(req,plan);
        plan.setUpdateBy(UserUtils.getUser().getId());
        plan.setUpdater(CrmUtils.getUserXM(UserUtils.getUser()));
        plan.setUpdateTime(new Date());
        electricPlanDao.save(plan);
        planMaterialDao.deleteByPlanId(req.getId());

    }

    public void setCommonElectricField(AddElectricPlan req,CrmElectricPlan plan){
        plan.setAssembly(req.getAssembly());
        if(req.getAssemblyMax()<= req.getAssemblyMin()){
            throw new BusinessException("组件块数区间不符规范，请重新输入！");
        }
        //判断组件块数 不能有重复区间
        if(!checkAssembleSame(req)){
            throw new BusinessException("相同的组件规格，组件块数区间不能重复！");
        }
        plan.setAssemblyMax(req.getAssemblyMax());
        plan.setAssemblyMin(req.getAssemblyMin());
        plan.setInverter1(req.getInverter1());
        plan.setInverter2(req.getInverter2());
        plan.setInverter3(req.getInverter3());
        plan.setBox1(req.getBox1());
        plan.setBox2(req.getBox2());
        plan.setBox3(req.getBox3());
    }

    public boolean checkAssembleSame(AddElectricPlan req){
         StringBuilder sb=new StringBuilder();
         sb.append(" SELECT COUNT(id) FROM `crm_electric_plan` WHERE ((assembly_max>=? AND  assembly_min<=? )OR (assembly_max>=? AND assembly_min<=? ))  and assembly=? and status='0' ");
         if(StringUtil.isNotBlank(req.getId())){
          sb.append(" and id <>'"+ req.getId()+"' ");
         }
         long count= Db.queryLong(sb.toString(),req.getAssemblyMax(),req.getAssemblyMax(),req.getAssemblyMin(),req.getAssemblyMin(),req.getAssembly());
        return count>0?false:true;
    }


    @Transactional(rollbackFor = Exception.class)
    public void deleteElectricPlan(String planIds){
        for (String planId : planIds.split(",")) {
            CrmElectricPlan plan = electricPlanDao.get(planId);
            plan.setStatus(SourceConstants.ONE);
            plan.setUpdateBy(UserUtils.getUser().getId());
            plan.setUpdater(CrmUtils.getUserXM(UserUtils.getUser()));
            plan.setUpdateTime(new Date());
            electricPlanDao.save(plan);
        }
    }

    public void listElectricPlan(LayuiPage<Record> page, Map<String, String> map){
        page.setData(listElectricDate(page,map));
        page.setCount(countElectric(map));
    }

    public List<Record> listElectricDate(LayuiPage<Record> page, Map<String, String> map){
        SqlBuilder builder = new SqlBuilder();
        builder.line(" SELECT p.id,p.assembly,p.assembly_max,p.assembly_min,p.inverter1,p.inverter2,p.inverter3,p.box1,p.box2,p.box3,p.create_time ")
               .line(" FROM `crm_electric_plan` p WHERE p.status='0' ");
        condition(builder,map);
        builder.line("order by p.create_time desc")
                .limit(page.getPage(), page.getLimit());
        return Db.find(builder.build(),builder.params());
    }

    public Long countElectric(Map<String, String> map){
        SqlBuilder builder = new SqlBuilder();
        builder.line(" select count(p.id) ")
        .line(" from `crm_electric_plan` p WHERE p.status='0' ");
        appendCondition(builder, map);
        return Db.queryLong(builder.build(),builder.params());
    }

    public void condition(SqlBuilder builder, Map<String, String> map){
        if(StringUtil.checkParamsValid(map.get("assembly"))){
            builder.line(" and p.assembly like '%"+map.get("assembly")+"%' ");
        }
        if(StringUtil.checkParamsValid(map.get("assemblyMax"))){
            builder.line(" and p.assembly_max <="+map.get("assemblyMax"));
        }
        if(StringUtil.checkParamsValid(map.get("assemblyMin"))){
            builder.line(" and p.assembly_min >="+map.get("assemblyMin"));
        }
        if(StringUtil.checkParamsValid(map.get("createTimeSta"))){
            builder.line(" and p.create_time >='"+map.get("createTimeSta") +" 00:00:00'");
        }
        if(StringUtil.checkParamsValid(map.get("createTimeEnd"))){
            builder.line(" and p.create_time <='"+map.get("createTimeEnd") +" 23:59:29'");
        }
    }

    public List<Record> getElectricSet(String type){
//        String sql=" SELECT s.id,s.name,s.model,s.unit FROM `crm_electric_set` s WHERE s.status='0' AND s.type=? order by s.model+0 asc ";
        String sql=" SELECT s.id,s.name,s.model,s.unit,s.material_model FROM `crm_electric_set` s WHERE s.status='0' AND s.type=? GROUP BY s.model  order by s.model+0 asc ";
        return Db.find(sql,type);
    }

    public List<Record> getElectricSetModel(String type){
        String sql=" SELECT DISTINCT(s.model) FROM `crm_electric_set` s WHERE s.status='0' AND s.type= ? ORDER BY  CAST(model AS SIGNED) asc";
        return Db.find(sql,type);
    }

    public Record getElectricPlanById(String id){
        return electricPlanDao.getElectricPlanById(id);
    }

    public void electricMaterialSetList(LayuiPage<Record> page, Map<String, String> map){
           page.setData(electricMaterialSetDate(page,map));
           page.setCount(electricMaterialSetCount(map));
    }

    public List<Record> electricMaterialSetDate(LayuiPage<Record> page, Map<String, String> map){
        SqlBuilder builder = new SqlBuilder();
        builder.line(" SELECT s.id,s.code,t.name as type,s.name,s.model,s.unit,s.create_time,s.remarks,s.material_model ")
                .line(" FROM `crm_electric_set` s ")
                .line(" left join crm_supply_material_type t on t.id=s.type ")
                .line(" WHERE s.status='0' ");
        materialSetCondition(builder,map);
        builder.line("order by s.create_time desc")
                .limit(page.getPage(), page.getLimit());
        return Db.find(builder.build(),builder.params());
    }

    public Long electricMaterialSetCount(Map<String, String> map){
        SqlBuilder builder = new SqlBuilder();
        builder.line(" select count(s.id) ")
                .line(" FROM `crm_electric_set` s ")
                .line(" WHERE s.status='0' ");
        materialSetCondition(builder,map);
        return Db.queryLong(builder.build(),builder.params());
    }

  public void materialSetCondition(SqlBuilder builder,Map<String, String> map){
      if(StringUtil.checkParamsValid(map.get("code"))){
          builder.line(" and s.code like '%"+map.get("code")+"%' ");
      }
      if(StringUtil.checkParamsValid(map.get("type"))){
          builder.line(" and s.type='"+map.get("type")+"' ");
      }
      if(StringUtil.checkParamsValid(map.get("name"))){
          builder.line(" and s.name like '%"+map.get("name")+"%' ");
      }
      if(StringUtil.checkParamsValid(map.get("model"))){
          builder.line(" and s.model like '%"+map.get("model")+"%' ");
      }
      if(StringUtil.checkParamsValid(map.get("createTimeSta"))){
          builder.line(" and s.create_time >='"+map.get("createTimeSta") +" 00:00:00'");
      }
      if(StringUtil.checkParamsValid(map.get("createTimeEnd"))){
          builder.line(" and s.create_time <='"+map.get("createTimeEnd") +" 23:59:29'");
      }
  }

    @Transactional(rollbackFor = Exception.class)
    public void addElectricMaterialSet(AddElectricMaterialSet req){
        if(StrKit.isBlank(req.getId())){
            saveElectricMaterialSet(req);
        }else {
            editElectricMaterialSet(req);
        }
    }

    /**
     * 增加电器材料
    */
  @Transactional(rollbackFor = Exception.class)
  public void saveElectricMaterialSet(AddElectricMaterialSet req){
      CrmElectricSet electricSet=new CrmElectricSet();
      setElectricMaterialField(req,electricSet);
      electricSet.setStatus(SourceConstants.ZERO);
      electricSet.setCreateBy(UserUtils.getUser().getId());
      electricSet.setCreateTime(new Date());
      electricSet.setRemarks(req.getRemarks());
      electricSetDao.save(electricSet);
  }
    /**
     * 修改电器材料
     */
  @Transactional(rollbackFor = Exception.class)
  public void editElectricMaterialSet(AddElectricMaterialSet req){
      CrmElectricSet electricSet=electricSetDao.get(req.getId());
      setElectricMaterialField(req,electricSet);
      electricSet.setUpdateBy(UserUtils.getUser().getId());
      electricSet.setUpdateTime(new Date());
      electricSet.setRemarks(req.getRemarks());
      electricSetDao.save(electricSet);
  }

  public void setElectricMaterialField(AddElectricMaterialSet req,CrmElectricSet electricSet){
        //校验 料号和规格唯一
        if(checkSameCode(req)){
           throw new BusinessException(" 该料号已存在，请勿重复添加！");
        }
        if(checkSameModel(req)){
            throw new BusinessException(" 该规格已存在，请勿重复添加！");
        }
        electricSet.setCode(req.getCode());
        electricSet.setType(req.getType());
        electricSet.setName(req.getName());
        electricSet.setModel(req.getModel());
        electricSet.setUnit(req.getUnit());
  }

  public Boolean checkSameCode(AddElectricMaterialSet req){
        StringBuilder sb=new StringBuilder();
        sb.append(" SELECT COUNT(s.id) FROM `crm_electric_set` s WHERE s.status='0'  AND s.code=?  ");
        if(StringUtil.isNotBlank(req.getId())){
            sb.append(" AND s.id <>'"+ req.getId() +"' ");
        }
        Long count=Db.queryLong(sb.toString(),req.getCode());
        return count>0?true:false;
  }

    public Boolean checkSameModel(AddElectricMaterialSet req){
        StringBuilder sb=new StringBuilder();
        sb.append(" SELECT COUNT(s.id) FROM `crm_electric_set` s WHERE s.status='0'  AND s.model=?  ");
        if(StringUtil.isNotBlank(req.getId())){
            sb.append(" AND s.id <>'"+ req.getId() +"' ");
        }
        Long count=Db.queryLong(sb.toString(),req.getModel());
        return count>0?true:false;
    }

    public Record getElectricMaterielSetDetail(String id){
        return electricSetDao.getElectricMaterielSetDetail(id);
    }



    /**
     * 删除电器材料
     */
    @Transactional(rollbackFor = Exception.class)
    public void deleteElectricMaterialSet(String ids){
        for (String id : ids.split(",")) {
            CrmElectricSet set = electricSetDao.get(id);
            set.setStatus(SourceConstants.ONE);
            set.setUpdateBy(UserUtils.getUser().getId());
            set.setUpdateTime(new Date());
            electricSetDao.save(set);
        }
    }

    public HSSFWorkbook downLoadMaterilList(String id){
        List<Record> list=listMaterialByPlanId(id);
        // 第一步，创建一个webbook，对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();
        // 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
        HSSFSheet sheet = wb.createSheet("物料明细");
        // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
        HSSFRow row = sheet.createRow((int) 0);
        // 第四步，创建单元格，并设置值表头 设置表头居中
       /* HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTE); */// 创建一个居中格式
        HSSFCell cell = row.createCell((short) 0);
        cell.setCellValue("序号");
        cell = row.createCell((short) 1);
        cell.setCellValue("料号");
        cell = row.createCell((short) 2);
        cell.setCellValue("名称");
        cell = row.createCell((short) 3);
        cell.setCellValue("规格");
        cell = row.createCell((short) 4);
        cell.setCellValue("单位");
        cell = row.createCell((short) 5);
        cell.setCellValue("数量");
        int i=1;
        for(Record record:list){
            row=sheet.createRow(i);
            row.createCell((short) 0).setCellValue(i);
            row.createCell((short) 1).setCellValue(record.getStr("code"));
            row.createCell((short) 2).setCellValue(record.getStr("name"));
            row.createCell((short) 3).setCellValue(record.getStr("spec"));
            row.createCell((short) 4).setCellValue(record.getStr("unit"));
            row.createCell((short) 5).setCellValue(record.getInt("amount"));
            i++;
        }
        return wb;
    }

    /**
     * 校验导入物料数据
     */
    @SuppressWarnings("unchecked")
    public Map<String, Object> checkImportElectricMaterialSet(Map<String, String> params, InputStream in) {
        Map<String, Object> retMap = Maps.newHashMap();
        retMap.put("operType", "check");
        ElectricMaterialImportHandler handler=new ElectricMaterialImportHandler();
        handler.setStartSheet(1);
        handler.setStartRow(2);
        try {
            new ExcelReader().check(in, params.get("extName"), handler);
            Map<String, Object> map = (Map<String, Object>) handler.getHandlerResult();
            String templateError = (String) map.get("TemplateError");
            if(!handler.isCheckFlag()){
                handler.appendErrorDetail("<p>未填充数据</p>");
            }
            String hanl = handler.getErrorDetail();
            if (StrKit.notBlank(templateError)){
                retMap.put("errorDetail", templateError);
                retMap.put("errorMessage", "y");
            }else if (StringUtils.isNotBlank(hanl)) {
                retMap.put("errorDetail", hanl);
                retMap.put("errorMessage", "y");
            } else if ("overLimit".equalsIgnoreCase((String) map.get("overLimit"))) {
                retMap.put("overLimit", "y");
            } else {
                retMap.put("pass", "y");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return retMap;
    }

    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> importElectricMaterialSet(Map<String, String> params, InputStream in) {
        Map<String, Object> retMap = Maps.newHashMap();
        retMap.put("operType", "import");
        ElectricMaterialImportHandler handler=new ElectricMaterialImportHandler();
        handler.setStartSheet(1);
        handler.setStartRow(3);

        try {
            new ExcelReader().readExcel(in, params.get("fileName"), handler);
            List<AddElectricMaterialSet> sets = handler.getRetList();
            batchAddSets(sets);
            retMap.put("pass", "y");
            retMap.put("successCount", handler.getSuccessCount());
            retMap.put("errorCount", 0);
            retMap.put("importHints", "y");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return retMap;
    }

   public List<String> findCommonCode(List<String> codeList){
       SqlBuilder builder = new SqlBuilder();
       builder.line(" select s.code  ")
               .line(" FROM `crm_electric_set` s WHERE s.status='0' ")
               .line(" and s.code in (" + StringUtil.joinInSql(codeList.toArray(new String[codeList.size()])) + ") ");
        return Db.query(builder.build(),builder.params());
   }

    public List<String> findCommonModel(List<String> modelList){
        SqlBuilder builder = new SqlBuilder();
        builder.line(" select s.model  ")
                .line(" FROM `crm_electric_set` s WHERE s.status='0' ")
                .line(" and s.model in (" + StringUtil.joinInSql(modelList.toArray(new String[modelList.size()])) +") ");
        return Db.query(builder.build(),builder.params());
    }

    @Transactional(rollbackFor = Exception.class)
    public void batchAddSets(List<AddElectricMaterialSet> sets){
        User user= UserUtils.getUser();
        Date date=new Date();
        List<CrmElectricSet> list=new ArrayList<>();
        for(AddElectricMaterialSet set:sets){
            CrmElectricSet electricSet=new CrmElectricSet();
            setElectricMaterialField(set,electricSet);
            electricSet.setStatus(SourceConstants.ZERO);
            electricSet.setCreateBy(user.getId());
            electricSet.setCreateTime(date);
            list.add(electricSet);
        }
        electricSetDao.save(list);
    }

    /**
     * 获取电器材料
     */
    public List<Record> findAllElectric() {
        return electricSetDao.findAllElectric();
    }

    /**
     * 获取逆变器的材料
     */
    public List<Record> findAllInverter() {
        return electricSetDao.findAllInverter();
    }
    /**
     * 获取逆变器的材料 区分型号
     */
    public List<Record> findAllInverter2() {
        return electricSetDao.findAllInverter2();
    }

    public List<Record> getElectricSetGF(String type) {
        String sql=" SELECT s.id,s.name,s.model,concat(IFNULL(s.material_model,''),'|',s.model) as material_model,s.unit FROM `crm_electric_set` s WHERE s.status='0' AND s.type=? order by s.model+0 asc ";
        return Db.find(sql,type);
    }

    public List<Record> findAllInverterGF() {
        return electricSetDao.findAllInverterGF();
    }
    public List<Record> findAllInverterGF2() {
        return electricSetDao.findAllInverterGF2();
    }
}
