/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the yifu4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.yifu.social.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.holder.ReadRowHolder;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeContractInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeProject;
import com.yifu.cloud.plus.v1.yifu.archives.vo.*;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.ErrorCodes;
import com.yifu.cloud.plus.v1.yifu.common.core.util.*;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.ArchivesDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.mybatis.base.BaseEntity;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.social.entity.*;
import com.yifu.cloud.plus.v1.yifu.social.mapper.*;
import com.yifu.cloud.plus.v1.yifu.social.service.TDispatchInfoService;
import com.yifu.cloud.plus.v1.yifu.social.vo.DispatchDetailVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TDispatchImportVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TDispatchInfoSearchVo;
import com.yifu.cloud.plus.v1.yifu.social.vo.TDispatchReduceVo;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

/**
 * 派单信息记录表
 *
 * @author fxj
 * @date 2022-07-15 11:38:05
 */
@Log4j2
@RequiredArgsConstructor
@Service
public class TDispatchInfoServiceImpl extends ServiceImpl<TDispatchInfoMapper, TDispatchInfo> implements TDispatchInfoService {

	private final ArchivesDaprUtil archivesDaprUtil;

	private final TSocialFundInfoMapper socialFundMapper;

	private final SysBaseSetInfoMapper baseSetMapper;

	private final TSocialInfoMapper socialMapper;

	private final TProvidentFundMapper fundMapper;



	/**
	 * 派单信息记录表简单分页查询
	 *
	 * @param tDispatchInfo 派单信息记录表
	 * @return
	 */
	@Override
	public IPage<TDispatchInfo> getTDispatchInfoPage(Page<TDispatchInfo> page, TDispatchInfo tDispatchInfo) {
		return baseMapper.getTDispatchInfoPage(page, tDispatchInfo);
	}

	/**
	 * 派单信息记录表批量导出
	 *
	 * @return
	 */
	@Override
	public void listExport(HttpServletResponse response, TDispatchInfoSearchVo searchVo) {
		String fileName = "不良记录批量导出" + DateUtil.getThisTime() + ".xlsx";
		//获取要导出的列表
		List<TDispatchInfo> list = new ArrayList<>();
		long count = noPageCountDiy(searchVo);
		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			response.setContentType("multipart/form-data");
			response.setCharacterEncoding("utf-8");
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
			// 这里 需要指定写用哪个class去写，然后写到第一个sheet，然后文件流会自动关闭
			//EasyExcel.write(out, TEmpBadRecord.class).sheet("不良记录").doWrite(list);
			ExcelWriter excelWriter = EasyExcel.write(out, TDispatchInfo.class).build();
			int index = 0;
			if (count > CommonConstants.ZERO_INT) {
				for (int i = 0; i <= count; ) {
					// 获取实际记录
					searchVo.setLimitStart(i);
					searchVo.setLimitEnd(CommonConstants.EXCEL_EXPORT_LIMIT);
					list = noPageDiy(searchVo);
					if (Common.isNotNull(list)) {
						ExcelUtil<TDispatchInfo> util = new ExcelUtil<>(TDispatchInfo.class);
						for (TDispatchInfo vo : list) {
							util.convertEntity(vo, null, null, null);
						}
					}
					if (Common.isNotNull(list)) {
						WriteSheet writeSheet = EasyExcel.writerSheet("派单信息记录表" + index).build();
						excelWriter.write(list, writeSheet);
						index++;
					}
					i = i + CommonConstants.EXCEL_EXPORT_LIMIT;
					if (Common.isNotNull(list)) {
						list.clear();
					}
				}
			} else {
				WriteSheet writeSheet = EasyExcel.writerSheet("派单信息记录表" + index).build();
				excelWriter.write(list, writeSheet);
			}
			if (Common.isNotNull(list)) {
				list.clear();
			}
			out.flush();
			excelWriter.finish();
		} catch (Exception e) {
			log.error("执行异常", e);
		} finally {
			try {
				if (null != out) {
					out.close();
				}
			} catch (IOException e) {
				log.error("执行异常", e);
			}
		}
	}

	@Override
	public List<TDispatchInfo> noPageDiy(TDispatchInfoSearchVo searchVo) {
		LambdaQueryWrapper<TDispatchInfo> wrapper = buildQueryWrapper(searchVo);
		List<String> idList = Common.getList(searchVo.getIds());
		if (Common.isNotNull(idList)) {
			wrapper.in(TDispatchInfo::getId, idList);
		}
		if (searchVo.getLimitStart() >= 0 && searchVo.getLimitEnd() > 0) {
			wrapper.last(" limit " + searchVo.getLimitStart() + "," + searchVo.getLimitEnd());
		}
		wrapper.orderByDesc(BaseEntity::getCreateTime);
		return baseMapper.selectList(wrapper);
	}

	private Long noPageCountDiy(TDispatchInfoSearchVo searchVo) {
		LambdaQueryWrapper<TDispatchInfo> wrapper = buildQueryWrapper(searchVo);
		List<String> idList = Common.getList(searchVo.getIds());
		if (Common.isNotNull(idList)) {
			wrapper.in(TDispatchInfo::getId, idList);
		}
		return baseMapper.selectCount(wrapper);
	}

	private LambdaQueryWrapper buildQueryWrapper(TDispatchInfoSearchVo entity) {
		LambdaQueryWrapper<TDispatchInfo> wrapper = Wrappers.lambdaQuery();
		if (ArrayUtil.isNotEmpty(entity.getCreateTimes())) {
			wrapper.ge(TDispatchInfo::getCreateTime, entity.getCreateTimes()[0])
					.le(TDispatchInfo::getCreateTime,
							entity.getCreateTimes()[1]);
		}
		if (Common.isNotNull(entity.getCreateName())) {
			wrapper.eq(TDispatchInfo::getCreateName, entity.getCreateName());
		}
		return wrapper;
	}

	@Override
	public R<List<ErrorMessage>> importDiy(InputStream inputStream) {
		YifuUser user = SecurityUtils.getUser();
		if (Common.isEmpty(user)){
			R.failed(CommonConstants.USER_FAIL);
		}
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<TDispatchImportVo> util1 = new ExcelUtil<>(TDispatchImportVo.class);
		;
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {
			EasyExcel.read(inputStream, TDispatchImportVo.class, new ReadListener<TDispatchImportVo>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				/**
				 *临时存储
				 */
				private List<TDispatchImportVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

				@Override
				public void invoke(TDispatchImportVo data, AnalysisContext context) {
					ReadRowHolder readRowHolder = context.readRowHolder();
					Integer rowIndex = readRowHolder.getRowIndex();
					data.setRowIndex(rowIndex + 1);
					ErrorMessage errorMessage = util1.checkEntity(data, data.getRowIndex());
					if (Common.isNotNull(errorMessage)) {
						errorMessageList.add(errorMessage);
					} else {
						cachedDataList.add(data);
					}
					if (cachedDataList.size() >= BATCH_COUNT) {
						saveData();
						// 存储完成清理 list
						cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
					}
				}

				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
					saveData();
				}

				/**
				 * 加上存储数据库
				 */
				private void saveData() {
					log.info("{}条数据，开始存储数据库！", cachedDataList.size());
					importTDispatchInfo(cachedDataList, errorMessageList,user);
					log.info("存储数据库成功！");
				}
			}).sheet().doRead();
		} catch (Exception e) {
			log.error(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR, e);
			return R.failed(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR);
		}
		return R.ok(errorMessageList);
	}

	@GlobalTransactional
	private void importTDispatchInfo(List<TDispatchImportVo> excelVOList,
									 List<ErrorMessage> errorMessageList,
									 YifuUser user) {
		if (!Common.isNotNull(excelVOList)){
			return;
		}
		Map<String,String> excelVOTemp = new HashMap<>();
		// 个性化校验逻辑
		List<String> idcards = new ArrayList<>();
		List<String> codes = new ArrayList<>();

		List<String> socialholds = new ArrayList<>();
		List<String> fundholds = new ArrayList<>();
		// 初始化参数
		initIdcardAndCode(excelVOList, idcards, codes, socialholds, fundholds);
		// 通过身份证和项目编码获取档案&项目档案&最新合同
		Map<String, DispatchEmpVo> empVoMap = getDispatchEmpVo(idcards, codes);
		// 通过身份证查询社保&公积金&社保公积金查询信息: 身份证维度唯一
		Map<String, TSocialFundInfo> socialFundMap = getSocialFundMap(idcards);
		// 获取结算主体编码数据 以供校验
		Map<String, ProjectSetInfoVo> projectVoMap = getProjectVoMap(codes);
		// 获取所有社保户和公积金户数据
		Map<String, SysBaseSetInfo> socialHoldMap = new HashMap<>();
		Map<String, SysBaseSetInfo> fundHoldMap = new HashMap<>();
		initHoldInfo(socialholds, fundholds, socialHoldMap, fundHoldMap);
		// 员工档案
		Map<String,EmpAddDispatchVo> empAddsMap = new HashMap<>();
		//员工合同
		Map<String,EmpContractDispatchVo> contractsMap = new HashMap<>();
		//员工项目档案
		Map<String,EmpProjectDispatchVo> projectsMap = new HashMap<>();
		//新增社保
		Map<String,TSocialInfo> socialsMap = new HashMap<>();
		//新增公积金
		Map<String,TProvidentFund> fundsMap = new HashMap<>();
		//新增派单信息
		Map<String,TDispatchInfo> dispatchMap = new HashMap<>();
		// 新增社保公积金查询
		Map<String,TSocialFundInfo> socialFundAddMap = new HashMap<>();
		DispatchEmpVo empVo = null;
		SysBaseSetInfo socialSet;
		SysBaseSetInfo fundSet;
		ProjectSetInfoVo setInfoVo;
		TSocialFundInfo socialFund;
		TDispatchImportVo excel;
		EmpDispatchAddVo addVo = new EmpDispatchAddVo();
		// 执行数据插入操作 组装
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			fundSet = fundHoldMap.get(excel.getProvidentHousehold());
			socialSet = socialHoldMap.get(excel.getSocialHousehold());
			socialFund = getSocialFund(socialFundMap,excel);
			setInfoVo = getSetInfoVo(projectVoMap,excel);
			// 数据合法情况
			if (validImport(errorMessageList, excel,setInfoVo,socialFundMap)) {
				excelVOTemp.put(excel.getEmpIdcard(),excel.getEmpIdcard());
				continue;
			}
			if (Common.isNotNull(excel.getSocialHousehold())){
				if (Common.isEmpty(socialSet)){
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_HOLD_NOT_EXIST)));
					excelVOTemp.put(excel.getEmpIdcard(),excel.getEmpIdcard());
					continue;
				}
			}
			if (Common.isNotNull(excel.getProvidentHousehold())){
				if (Common.isEmpty(fundSet)){
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_FUND_HOLD_NOT_EXIST)));
					excelVOTemp.put(excel.getEmpIdcard(),excel.getEmpIdcard());
					continue;
				}
			}
			// 是否可以派单： 派单状态、兼职工伤处理
			if (validDdispatchStatus(errorMessageList, socialFundMap, excel)) {
				excelVOTemp.put(excel.getEmpIdcard(),excel.getEmpIdcard());
				continue;
			}
			if (Common.isNotNull(empVoMap)) {
				empVo = empVoMap.get(excel.getEmpIdcard());
			}
			// 初始化新增信息：档案、项目档案、员工合同
			initAddInfo(empAddsMap, contractsMap, projectsMap, empVo, excel);
			// 新增社保
			initSocialAddInfo(socialsMap, empVo, socialSet, excel,socialFundMap);
			// 新增公积金
			if (initFundAddInfo(errorMessageList, fundsMap, empVo, fundSet, excel,socialFundMap)){
				excelVOTemp.put(excel.getEmpIdcard(),excel.getEmpIdcard());
				continue;
			}
			// 新增派单信息
			initDispatchAddInfo(user, dispatchMap, empVo, socialSet, fundSet, excel);
			// 变更社保公积金查询
			initSocialFundAddInfo(socialFundAddMap, empVo, socialSet, fundSet, setInfoVo, socialFund, excel);
		}
		addVo.setEmpAddsMap(empAddsMap);
		addVo.setContractsMap(contractsMap);
		addVo.setProjectsMap(projectsMap);
		R<EmpDispatchAddVo> res = archivesDaprUtil.addDispatchInfo(addVo);
		// 开始插入各种数据了
		insertAllInfo(excelVOList, errorMessageList, empVoMap, res,socialsMap,fundsMap,socialFundAddMap,dispatchMap,excelVOTemp);
		// 清理map list 等数据
		Common.clear(excelVOList);
		Common.clear(empAddsMap);
		Common.clear(contractsMap);
		Common.clear(projectsMap);
		Common.clear(empVoMap);
		Common.clear(idcards);
		Common.clear(codes);
		Common.clear(socialholds);
		Common.clear(fundholds);
		Common.clear(socialsMap);
		Common.clear(fundsMap);
		Common.clear(dispatchMap);
		Common.clear(socialFundAddMap);
		Common.clear(socialHoldMap);
		Common.clear(fundHoldMap);
		Common.clear(excelVOTemp);
	}
	private ProjectSetInfoVo getSetInfoVo(Map<String, ProjectSetInfoVo> projectVoMap, TDispatchImportVo excel) {
		return Common.isEmpty(projectVoMap)?null:projectVoMap.get(excel.getSettleDomainCode());
	}

	private TSocialFundInfo getSocialFund(Map<String, TSocialFundInfo> socialFundMap, TDispatchImportVo excel) {
		return Common.isEmpty(socialFundMap)?null:socialFundMap.get(excel.getEmpIdcard());
	}

	private void insertAllInfo(List<TDispatchImportVo> excelVOList,
							   List<ErrorMessage> errorMessageList,
							   Map<String, DispatchEmpVo> empVoMap,
							   R<EmpDispatchAddVo> res,
							   Map<String, TSocialInfo> socialsMap,
							   Map<String, TProvidentFund> fundsMap,
							   Map<String, TSocialFundInfo> socialFundAddMap,
							   Map<String, TDispatchInfo> dispatchMap,
							   Map<String,String> excelVOTemp) {
		Map<String, EmpAddDispatchVo> empAddsMap = null;
		Map<String, EmpContractDispatchVo> contractsMap = null;
		Map<String, EmpProjectDispatchVo> projectsMap = null;
		TDispatchImportVo excel;
		DispatchEmpVo empVo;
		EmpContractDispatchVo contract = null;
		EmpProjectDispatchVo project = null;
		EmpAddDispatchVo emp = null;
		TSocialInfo social = null;
		TProvidentFund fund = null;
		TSocialFundInfo socialFund = null;
		TDispatchInfo dispatch = null;
		if (Common.isNotNull(res) && Common.isNotNull(res.getData())){
			empAddsMap =  res.getData().getEmpAddsMap();
			contractsMap = res.getData().getContractsMap();
			projectsMap = res.getData().getProjectsMap();
		}
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			if (Common.isNotNull(excelVOTemp) && Common.isNotNull(excelVOTemp.get(excel.getEmpIdcard()))){
				continue;
			}
			empVo = getEmpVoMap(empVoMap,excel);
			// 验证档案是否插入成功  如果MAP 无数据直接不处理
			if (Common.isEmpty(empVo) && Common.isNotNull(empAddsMap)){
				emp = empAddsMap.get(excel.getEmpIdcard());
				if (Common.isEmpty(emp) || Common.isEmpty(emp.getId())){
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_ADD_EMP_ERROR)));
					continue;
				}
			}else if (Common.isNotNull(empVo)){
				// 验证合同是否插入成功
				if (Common.isEmpty(empVo.getContractType()) && Common.isNotNull(contractsMap)){
					contract = contractsMap.get(excel.getEmpIdcard()+CommonConstants.DOWN_LINE_STRING+excel.getSettleDomainCode());
					if (Common.isEmpty(contract) || Common.isEmpty(contract.getId())){
						errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_ADD_CONTRACT_ERROR)));
						continue;
					}
				}
				// 验证项目档案是否插入成功
				if (Common.isEmpty(empVo.getEmpCode()) && Common.isNotNull(projectsMap)){
					project = projectsMap.get(excel.getEmpIdcard()+CommonConstants.DOWN_LINE_STRING+excel.getSettleDomainCode());
					if (Common.isEmpty(project) || Common.isEmpty(project.getId())){
						errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_ADD_PROJECT_ERROR)));
						continue;
					}
				}
			}
			try {
				// 插入社保信息并封装社保公积金查询信息
				if (Common.isNotNull(socialsMap)){
					social = socialsMap.get(excel.getEmpIdcard());
					insertSocial(emp, social);
				}
				//  插入公积金信息并封装社保公积金查询信息
				if (Common.isNotNull(fundsMap)){
					fund = fundsMap.get(excel.getEmpIdcard());
					insertFund(emp, fund);
				}
				//  插入派单信息
				if (Common.isNotNull(dispatchMap)){
					dispatch = dispatchMap.get(excel.getEmpIdcard());
					if (Common.isNotNull(dispatch)){
						if (Common.isNotNull(social)){
							dispatch.setSocialId(social.getId());
						}
						if (Common.isNotNull(fund)){
							dispatch.setFundId(fund.getId());
						}
						if (Common.isNotNull(contract)){
							dispatch.setContractId(contract.getId());
						}
					}
					insertDispatch(emp, dispatch);
				}
				//  插入或更新社保公积金查询信息  大病在封装社保的时候已经算了 大病技术和金额了
				if (Common.isNotNull(socialFundAddMap)){
					socialFund = socialFundAddMap.get(excel.getEmpIdcard());
					if (Common.isNotNull(socialFund) && Common.isNotNull(dispatch)){
						socialFund.setDispatchId(dispatch.getId());
					}
					initSocialFundAndInsert(emp, social, fund, socialFund,project);
				}
			}catch (Exception e){
				log.error("派单新增异常：", e);
				errorMessageList.add(new ErrorMessage(excel.getRowIndex(), "派单新增异常："+e.getMessage()));
				continue;
			}
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), CommonConstants.SAVE_SUCCESS,CommonConstants.GREEN));
			// 清理map list 等数据
			Common.clear(empAddsMap);
			Common.clear(contractsMap);
			Common.clear(projectsMap);

		}
	}

	private DispatchEmpVo getEmpVoMap(Map<String, DispatchEmpVo> empVoMap, TDispatchImportVo excel) {
		return Common.isNotNull(empVoMap)?empVoMap.get(excel.getEmpIdcard()):null;
	}

	private void insertSocial(EmpAddDispatchVo emp, TSocialInfo social) {
		if (Common.isNotNull(social)){
			if (Common.isNotNull(emp)){
				social.setEmpNo(emp.getEmpCode());
				social.setEmpId(emp.getId());
			}
			socialMapper.insert(social);
		}
	}

	private void insertFund(EmpAddDispatchVo emp, TProvidentFund fund) {
		if (Common.isNotNull(fund)){
			if (Common.isNotNull(emp)){
				fund.setEmpNo(emp.getEmpCode());
				fund.setEmpId(emp.getId());
			}
			fundMapper.insert(fund);
		}
	}

	private void insertDispatch(EmpAddDispatchVo emp, TDispatchInfo dispatch) {
		if (Common.isNotNull(dispatch)){
			if (Common.isNotNull(emp)){
				dispatch.setEmpNo(emp.getEmpCode());
				dispatch.setEmpId(emp.getId());
				dispatch.setSettleDomainCode(emp.getDeptNo());
				dispatch.setSettleDomain(emp.getDeptId());
				dispatch.setSettleDomainName(emp.getDeptName());
			}
			baseMapper.insert(dispatch);
		}
	}

	private void initSocialFundAndInsert(EmpAddDispatchVo emp,
										 TSocialInfo social,
										 TProvidentFund fund,
										 TSocialFundInfo socialFund,
										 EmpProjectDispatchVo project) {
		if (Common.isNotNull(socialFund)){
			if (Common.isNotNull(project)){
				socialFund.setEmpNo(project.getEmpCode());
			}
			if (Common.isNotNull(emp)){
				socialFund.setEmpId(emp.getId());
				socialFund.setEmpName(emp.getEmpName());
				socialFund.setEmpIdcard(emp.getEmpIdcard());
				socialFund.setEmpType(emp.getEmpNatrue());
			}
			if (Common.isNotNull(social)){
				socialFund.setSocialStartDate(social.getSocialStartDate());
				socialFund.setSocialAddStatus(CommonConstants.ZERO_STRING);
				socialFund.setSocialReduceDate(null);
				socialFund.setSocialReduceStatus(CommonConstants.ONE_STRING_NEGATE);
				socialFund.setSocialId(social.getId());
				if (Common.isEmpty(socialFund.getFirstBuyMonthSocial())){
					socialFund.setFirstBuyMonthSocial(social.getSocialStartDate());
				}
				socialFund.setUnitPensionCardinal(social.getUnitPensionCardinal());
				socialFund.setUnitMedicalCardinal(social.getUnitMedicalCardinal());
				socialFund.setUnitUnemploymentCardinal(social.getUnitUnemploymentCardinal());
				socialFund.setUnitBigailmentCardinal(social.getUnitBigailmentCardinal());
				socialFund.setUnitWorkInjuryCardinal(social.getUnitWorkInjuryCardinal());
				socialFund.setUnitBirthCardinal(social.getUnitBirthCardinal());
				socialFund.setPersonalPensionCardinal(social.getPersonalPensionCardinal());
				socialFund.setPersonalMedicalCardinal(social.getPersonalMedicalCardinal());
				socialFund.setPersonalBigailmentCardinal(social.getPersonalBigailmentCardinal());
				socialFund.setPersonalUnemploymentCardinal(social.getPersonalUnemploymentCardinal());
				socialFund.setUnitPensionPer(social.getUnitPensionPer());
				socialFund.setUnitMedicalPer(social.getUnitMedicalPer());
				socialFund.setUnitUnemploymentPer(social.getUnitUnemploymentPer());
				socialFund.setUnitBigailmentPer(social.getUnitBigailmentPer());
				socialFund.setUnitWorkUnjuryPer(social.getUnitWorkUnjuryPer());
				socialFund.setUnitBirthPer(social.getUnitBirthPer());
				socialFund.setPersonalPensionPer(social.getPersonalPensionPer());
				socialFund.setPersonalMedicalPer(social.getPersonalMedicalPer());
				socialFund.setPersonalUnemploymentPer(social.getPersonalUnemploymentPer());
				socialFund.setPersonalBigailmentPer(social.getPersonalBigailmentPer());
				socialFund.setCanOverpay(social.getCanOverpay());
				socialFund.setOverpayNumber(social.getOverpayNumber());
				socialFund.setHaveThisMonth(social.getHaveThisMonth());
				socialFund.setInsuranceBigailment(social.getInsuranceBigailment());
				socialFund.setInsuranceBirth(social.getInsuranceBirth());
				socialFund.setInsuranceInjury(social.getInsuranceInjury());
				socialFund.setInsuranceMedical(social.getInsuranceMedical());
				socialFund.setInsurancePension(social.getInsurancePension());
				socialFund.setInsuranceUnemployment(social.getInsuranceUnemployment());
				socialFund.setLatestCardinality(social.getInsuranceIsLatestCardinality());
				socialFund.setIsIllness(social.getIsIllness());
				socialFund.setCollectType(social.getCollectType());
				socialFund.setValueType(social.getValueType());
				socialFund.setIsChargePersonal(social.getIsChargePersonal());
				socialFund.setRecordBase(social.getRecordBase());
				socialFund.setTrustRemark(social.getTrustRemark());
				socialFund.setPaymentType(social.getPaymentType());
				socialFund.setPensionStart(social.getPensionStart());
				socialFund.setMedicalStart(social.getMedicalStart());
				socialFund.setUnemployStart(social.getUnemployStart());
				socialFund.setWorkInjuryStart(social.getWorkInjuryStart());
				socialFund.setBirthStart(social.getBirthStart());
				socialFund.setBigailmentStart(social.getBigailmentStart());
				socialFund.setPensionHandle(social.getPensionHandle());
				socialFund.setMedicalHandle(social.getMedicalHandle());
				socialFund.setUnemployHandle(social.getUnemployHandle());
				socialFund.setWorkInjuryHandle(social.getWorkInjuryHandle());
				socialFund.setBirthHandle(social.getBirthHandle());
				socialFund.setBigailmentHandle(social.getBigailmentHandle());

				socialFund.setUnitPersionMoney(BigDecimal.ZERO);
				socialFund.setUnitMedicalMoney(BigDecimal.ZERO);
				socialFund.setUnitUnemploymentMoney(BigDecimal.ZERO);
				socialFund.setUnitInjuryMoney(BigDecimal.ZERO);
				socialFund.setUnitBirthMoney(BigDecimal.ZERO);

				socialFund.setUnitPersionMoney(BigDecimalUtils.safeMultiply(social.getUnitPensionCardinal(), social.getUnitPensionPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));
				socialFund.setUnitMedicalMoney(BigDecimalUtils.safeMultiply(social.getUnitMedicalCardinal(), social.getUnitMedicalPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));
				socialFund.setUnitBirthMoney(BigDecimalUtils.safeMultiply(social.getUnitBirthCardinal(), social.getUnitBirthPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));
				socialFund.setUnitInjuryMoney(BigDecimalUtils.safeMultiply(social.getUnitWorkInjuryCardinal(), social.getUnitWorkUnjuryPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));
				socialFund.setUnitUnemploymentMoney(BigDecimalUtils.safeMultiply(social.getUnitUnemploymentCardinal(), social.getUnitUnemploymentPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));

				socialFund.setPersonalPersionMoney(BigDecimalUtils.safeMultiply(social.getPersonalPensionCardinal(), social.getPersonalPensionPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));
				socialFund.setPersonalMedicalMoney(BigDecimalUtils.safeMultiply(social.getPersonalMedicalCardinal(), social.getPersonalMedicalPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));
				socialFund.setPersonalUnemploymentMoney(BigDecimalUtils.safeMultiply(social.getPersonalUnemploymentCardinal(), social.getPersonalUnemploymentPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));

				socialFund.setUnitSocialSum(BigDecimalUtils.safeAdd(socialFund.getUnitPersionMoney()
						, socialFund.getUnitMedicalMoney(), socialFund.getUnitBirthMoney()
						, socialFund.getUnitInjuryMoney()
						, socialFund.getUnitUnemploymentMoney()
						, socialFund.getUnitBigailmentMoney()));
				socialFund.setPersonalSocialSum(BigDecimalUtils.safeAdd(socialFund.getPersonalBigailmentMoney()
						, socialFund.getPersonalPersionMoney()
						, socialFund.getPersonalMedicalMoney()
						, socialFund.getPersonalUnemploymentMoney()));
			}
			if (Common.isNotNull(fund)){
				socialFund.setFundId(fund.getId());
				socialFund.setUnitProvidengCardinal(fund.getUnitProvidengCardinal());
				socialFund.setUnitProvidentPer(fund.getUnitProvidentPer());
				socialFund.setPersonalProvidentCardinal(fund.getPersonalProvidentCardinal());
				socialFund.setPersonalProvidentPer(fund.getPersonalProvidentPer());
				socialFund.setProvidentStart(fund.getProvidentStart());
				socialFund.setFundPayPoint(fund.getFundPayPoint());
				socialFund.setPayPolicy(fund.getFundPayPoint());
				socialFund.setTrustRemarkFund(fund.getTrustRemark());
				socialFund.setCanOverpayFund(fund.getCanOverpay());
				socialFund.setOverpayNumberFund(fund.getOverpayNumber());
				if (Common.isEmpty(socialFund.getFirstBuyMothFund())){
					socialFund.setFirstBuyMothFund(fund.getProvidentStart());
				}
				socialFund.setHaveThisMonthFund(fund.getHaveThisMonth());
				// 设置公积金信息派增 派减状态
				socialFund.setLatestCardinalityFund(fund.getInsuranceIsLatestCardinality());
				socialFund.setFundReduceDate(null);
				socialFund.setFundAddStatus(CommonConstants.ZERO_STRING);
				socialFund.setFundReduceStatus(CommonConstants.ONE_STRING_NEGATE);
				//单边小数点处理逻辑
				if (Common.isNotNull(fund.getFundPayPoint())){
					socialFund.setUnitFundSum(Common.formatMoneyForFund(BigDecimalUtils.safeMultiply(fund.getUnitProvidengCardinal(), fund.getUnitProvidentPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())),Integer.valueOf(fund.getFundPayPoint())));
					socialFund.setPersonalFundSum(Common.formatMoneyForFund(BigDecimalUtils.safeMultiply(fund.getPersonalProvidentCardinal(), fund.getPersonalProvidentPer(),BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())),Integer.valueOf(fund.getFundPayPoint())));
				}
			}
			if (Common.isNotNull(socialFund.getId())){
				socialFundMapper.updateById(socialFund);
			}else {
				socialFundMapper.insert(socialFund);
			}
		}
	}

	private void initSocialFundAddInfo(Map<String, TSocialFundInfo> socialFundAddMap,
									   DispatchEmpVo empVo,
									   SysBaseSetInfo socialSet,
									   SysBaseSetInfo fundSet,
									   ProjectSetInfoVo setInfoVo,
									   TSocialFundInfo socialFund,
									   TDispatchImportVo excel) {
		if (Common.isEmpty(socialFund)){
			socialFund = new TSocialFundInfo();
			if (Common.isNotNull(empVo)){
				socialFund.setEmpNo(empVo.getEmpCode());
				socialFund.setEmpName(empVo.getEmpName());
				socialFund.setEmpIdcard(empVo.getEmpIdcard());
				socialFund.setEmpId(empVo.getId());
				socialFund.setEmpType(excel.getEmpType());
			}
		}
		// 按社保公积金户判断具体封装那些信息，如果社保或公积金新增失败，后面就不会去更新或插入社保公积金查询了
		if (Common.isNotNull(setInfoVo)){
			if (Common.isNotNull(excel.getSocialHousehold())){
				socialFund.setSettleDomain(setInfoVo.getId());
				socialFund.setSettleDomainName(setInfoVo.getDepartName());
				socialFund.setSettleDomainCode(setInfoVo.getDepartNo());
				socialFund.setSettleDomainFund(setInfoVo.getId());
				socialFund.setSettleDomainNameFund(setInfoVo.getDepartName());
				socialFund.setSettleDomainCodeFund(setInfoVo.getDepartNo());
				socialFund.setUnitName(setInfoVo.getCustomerName());
				socialFund.setUnitId(setInfoVo.getCustomerId());
				socialFund.setUnitIdFund(setInfoVo.getCustomerId());
				socialFund.setUnitNameFund(setInfoVo.getCustomerName());
				socialFund.setSocialStatus(CommonConstants.ZERO_STRING);
				socialFund.setSocialStartDate(excel.getPensionStart());
				if (Common.isNotNull(socialSet)){
					socialFund.setSocialHousehold(socialSet.getId());
					socialFund.setSocialHouseholdName(socialSet.getDepartName());
					socialFund.setSocialProvince(Common.isNotNullToStr(socialSet.getProvince()));
					socialFund.setSocialCity(Common.isNotNullToStr(socialSet.getCity()));
					socialFund.setSocialTown(Common.isNotNullToStr(socialSet.getTown()));
					socialFund.setLowerLimit(socialSet.getLowerLimit());
					socialFund.setUpperLimit(socialSet.getUpperLimit());
					socialFund.setPayPolicy(socialSet.getPayPolicy());
				}
			}
			if (Common.isNotNull(excel.getProvidentHousehold())){
				socialFund.setSettleDomain(setInfoVo.getId());
				socialFund.setSettleDomainName(setInfoVo.getDepartName());
				socialFund.setSettleDomainCode(setInfoVo.getDepartNo());
				socialFund.setUnitName(setInfoVo.getCustomerName());
				socialFund.setUnitIdFund(setInfoVo.getCustomerId());
				socialFund.setFundStatus(CommonConstants.ZERO_STRING);
				if (Common.isNotNull(fundSet)){
					socialFund.setProvidentHousehold(fundSet.getId());
					socialFund.setProvidentHouseholdName(fundSet.getDepartName());
					socialFund.setFundProvince(Common.isNotNullToStr(fundSet.getProvince()));
					socialFund.setFundCity(Common.isNotNullToStr(fundSet.getCity()));
					socialFund.setFundTown(Common.isNotNullToStr(fundSet.getTown()));
					socialFund.setLowerLimitFund(fundSet.getLowerLimit());
					socialFund.setUpperLimitFund(fundSet.getUpperLimit());
					socialFund.setPayPolicyFund(fundSet.getPayPolicy());
					socialFund.setProvidentStart(excel.getProvidentStart());
				}
			}

		}
		socialFundAddMap.put(excel.getEmpIdcard(), socialFund);
	}

	private Map<String, ProjectSetInfoVo> getProjectVoMap(List<String> codes) {
		R<SetInfoVo> res = archivesDaprUtil.getSetInfoByCodes(codes);
		if (Common.isNotNull(res) && Common.isNotNull(res.getData())){
			return res.getData().getProjectSetInfoVoMap();
		}
		return new HashMap<>();
	}

	private void initDispatchAddInfo(YifuUser user,
									 Map<String, TDispatchInfo> dispatchMap,
									 DispatchEmpVo empVo,
									 SysBaseSetInfo socialSet,
									 SysBaseSetInfo fundSet,
									 TDispatchImportVo excel) {
		TDispatchInfo dispatch;
		dispatch = new TDispatchInfo();
		dispatch.setContractSubName(excel.getContractSubName());
		dispatch.setContractName(excel.getContractName());
		dispatch.setEmpIdcard(excel.getEmpIdcard());
		dispatch.setEmpName(excel.getEmpName());
		dispatch.setEmpNational(excel.getEmpNational());
		dispatch.setEmpType(excel.getEmpType());
		dispatch.setEmpMobile(excel.getEmpMobile());
		dispatch.setType(CommonConstants.ZERO_STRING);
		dispatch.setCurrentOperator(user.getNickname());
		dispatch.setTrustRemark(excel.getTrustRemark());
		dispatch.setFundHandleStatus(CommonConstants.ZERO_STRING);
		dispatch.setSocialHandleStatus(CommonConstants.ZERO_STRING);
		if (Common.isNotNull(socialSet)){
			dispatch.setSocialProvince(Common.isNotNullToStr(socialSet.getProvince()));
			dispatch.setSocialCity(Common.isNotNullToStr(socialSet.getCity()));
			dispatch.setSocialTown(Common.isNotNullToStr(socialSet.getTown()));
		}
		if (Common.isNotNull(fundSet)){
			dispatch.setFundProvince(Common.isNotNullToStr(fundSet.getProvince()));
			dispatch.setFundCity(Common.isNotNullToStr(fundSet.getCity()));
			dispatch.setFundTown(Common.isNotNullToStr(fundSet.getTown()));
		}
		// 默认待审核
		dispatch.setStatus(CommonConstants.ONE_STRING);
		dispatch.setDeleteFlag(CommonConstants.ZERO_STRING);
		// 封装结算主体客户信息
		dispatch.setSettleDomainName(excel.getDepartName());
		dispatch.setSettleDomain(excel.getSettleDomainId());
		dispatch.setBelongUnit(excel.getCustomerId());
		dispatch.setBelongUnitName(excel.getCustomerName());
		// 封装合同信息 默认取值派单的
		dispatch.setContractStart(excel.getContractStart());
		dispatch.setContractEnd(excel.getContractEnd());
		dispatch.setContractTerm(excel.getContractTerm());
		dispatch.setContractType(excel.getContractType());
		dispatch.setWorkingHours(excel.getWorkingHours());
		// 派单项信息封装 TODO

		// 封装客户信息
		if (Common.isNotNull(empVo)){
			dispatch.setEmpId(empVo.getId());
			dispatch.setEmpNo(empVo.getEmpCode());
			// 封装合同信息 如果有合同取值实际合同信息
			dispatch.setSettleDomainName(empVo.getDeptName());
			dispatch.setContractStart(empVo.getContractStart());
			dispatch.setContractEnd(empVo.getContractEnd());
			dispatch.setContractTerm(empVo.getContractTerm());
			dispatch.setContractType(empVo.getContractType());
			dispatch.setFileProvince(empVo.getFileProvince());
			dispatch.setFileCity(empVo.getFileCity());
			dispatch.setFileTown(empVo.getFileTown());
			dispatch.setContractId(empVo.getContractId());

		}
		dispatchMap.put(excel.getEmpIdcard(),dispatch);
	}

	private boolean initFundAddInfo(List<ErrorMessage> errorMessageList,
									Map<String, TProvidentFund> funds,
									DispatchEmpVo empVo, SysBaseSetInfo fundSet,
									TDispatchImportVo excel, Map<String, TSocialFundInfo> socialFundMap) {
		TProvidentFund fund;
		if (Common.isNotNull(excel.getProvidentHousehold())){
			fund = new TProvidentFund();
			fund.setAuditStatus(CommonConstants.ZERO_STRING);
			fund.setHandleStatus(CommonConstants.ZERO_STRING);
			fund.setDeleteFlag(CommonConstants.ZERO_STRING);
			fund.setBelongUnit(excel.getCustomerId());
			fund.setSettleDomain(excel.getSettleDomainId());
			if (Common.isNotNull(empVo)){
				fund.setEmpId(empVo.getId());
				fund.setEmpNo(empVo.getEmpCode());
			}
			fund.setEmpIdcard(excel.getEmpIdcard());
			fund.setEmpName(excel.getEmpName());
			fund.setTrustRemark(excel.getTrustRemark());
			fund.setUnitProvidengCardinal(excel.getProvidentPer());
			fund.setPersonalProvidentPer(excel.getProvidentPer());
			fund.setUnitProvidengCardinal(excel.getProvidentCardinal());
			fund.setPersonalProvidentCardinal(excel.getProvidentCardinal());
			fund.setProvidentStart(excel.getProvidentStart());
			if (Common.isNotNull(fundSet)){
				fund.setProvidentHousehold(fundSet.getId());
				if (!checkFundPer(fundSet.getFundProList(), excel)){
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_FUND_PERCENT_NOT_EXIST)));
					return true;
				}
				fund.setCanOverpay(fundSet.getCanOverpay());
				fund.setOverpayNumber(fundSet.getOverpayNumber());
				fund.setFundBaseSetId(fundSet.getId());
				if (Common.isNotNull(fundSet.getProvince())){
					fund.setFundProvince(Integer.toString(fundSet.getProvince()));
				}
				if (Common.isNotNull(fundSet.getCity())){
					fund.setFundCity(Integer.toString(fundSet.getCity()));
				}
				if (Common.isNotNull(fundSet.getTown())){
					fund.setFundTown(Integer.toString(fundSet.getTown()));
				}
				fund.setFundPayPoint(Common.isNotNullToStr(fundSet.getFundPayPoint()));
				fund.setHaveThisMonth(fundSet.getHaveThisMonth());
			}
			funds.put(excel.getEmpIdcard(),fund);
		}
		return false;
	}

	/**
	 * @Author fxj
	 * @Description 对比公积金比例，对应上true  false
	 **/
	private boolean checkFundPer(List<SysPayProportion> pays,TDispatchImportVo excel){
		if (Common.isNotNull(excel.getProvidentPer()) && Common.isNotNull(pays)){
			for (SysPayProportion per: pays){
				if (per.getCompanyPro().doubleValue()==excel.getProvidentPer().doubleValue()){
					return true;
				}
			}
		}
		return false;
	}

	private void initAddInfo(Map<String, EmpAddDispatchVo> empAdds,
							 Map<String, EmpContractDispatchVo> contracts,
							 Map<String, EmpProjectDispatchVo> projects,
							 DispatchEmpVo empVo, TDispatchImportVo excel) {
		// 无档案无项目档案无合同无学历
		if (Common.isEmpty(empVo) || Common.isEmpty(empVo.getId())) {
			// 初始化档案
			initEmpAddInfo(empAdds, excel);
			// 初始化项目档案
			initProjectInfo(projects, excel, empVo);
			// 初始化合同
			initContractInfo(contracts, excel, empVo);
		}
		// 有档案无项目档案无合同
		if (Common.isNotNull(empVo) && Common.isEmpty(empVo.getDeptNo())) {
			// 初始化项目档案
			initProjectInfo(projects, excel, empVo);
			// 初始化合同
			initContractInfo(contracts, excel, empVo);
		}
		// 有档案有项目档案无合同
		if (Common.isNotNull(empVo)
				&& Common.isNotNull(empVo.getDeptNo())
				&& Common.isEmpty(empVo.getContractType())) {
			// 初始化合同
			initContractInfo(contracts, excel, empVo);
		}
	}

	private void initSocialAddInfo(Map<String, TSocialInfo> socials,
								   DispatchEmpVo empVo,
								   SysBaseSetInfo socialSet,
								   TDispatchImportVo excel,
								   Map<String, TSocialFundInfo> socialFundMap) {
		TSocialInfo social;
		if (Common.isNotNull(excel.getSocialHousehold())) {
			social = new TSocialInfo();
			social.setAuditStatus(CommonConstants.ZERO_STRING);
			social.setHandleStatus(CommonConstants.ZERO_STRING);
			social.setDeleteFlag(CommonConstants.ZERO_STRING);
			social.setSocialStartDate(excel.getPensionStart());
			//  封装单位信息 结算信息
			social.setBelongUnit(excel.getCustomerId());
			social.setSettleDomain(excel.getSettleDomainId());
			if (Common.isNotNull(empVo)){
				social.setEmpId(empVo.getId());
				social.setEmpName(empVo.getEmpName());
				social.setEmpIdcard(empVo.getEmpIdcard());
				social.setEmpNo(empVo.getEmpCode());
			}
			social.setEmpIdcard(excel.getEmpIdcard());
			social.setBigailmentHandle(CommonConstants.ZERO_STRING);
			social.setBirthHandle(CommonConstants.ZERO_STRING);
			social.setMedicalHandle(CommonConstants.ZERO_STRING);
			social.setPensionHandle(CommonConstants.ZERO_STRING);
			social.setWorkInjuryHandle(CommonConstants.ZERO_STRING);
			social.setUnemployHandle(CommonConstants.ZERO_STRING);
			social.setPaymentType(excel.getPaymentType());
			social.setRecordBase(excel.getRecordBase());
			social.setPensionStart(excel.getPensionStart());
			social.setMedicalStart(ifNull(excel.getMedicalStart(), excel.getPensionStart()));
			social.setUnemployStart(ifNull(excel.getUnemployStart(), excel.getPensionStart()));
			social.setBigailmentStart(ifNull(excel.getBigailmentStart(), excel.getPensionStart()));
			social.setWorkInjuryStart(ifNull(excel.getWorkInjuryStart(), excel.getPensionStart()));
			social.setBirthStart(ifNull(excel.getBirthStart(), excel.getPensionStart()));
			if (CommonConstants.ONE_STRING.equals(excel.getPaymentType())){
				if (Common.isNotNull(socialSet.getProvince())){
					social.setSocialProvince(Integer.toString(socialSet.getProvince()));
				}
				if (Common.isNotNull(socialSet.getCity())){
					social.setSocialCity(Integer.toString(socialSet.getCity()));
				}
				if (Common.isNotNull(socialSet.getTown())){
					social.setSocialTown(Integer.toString(socialSet.getTown()));
				}
				// 自定义各个基数起缴时间初试化
				social.setPersonalPensionCardinal(excel.getPensionCardinal());
				social.setPersonalMedicalCardinal(ifNull(excel.getMedicalCardinal(), excel.getPensionCardinal()));
				social.setPersonalUnemploymentCardinal(ifNull(excel.getUnemploymentCardinal(), excel.getPensionCardinal()));
				social.setPersonalBigailmentCardinal(ifNull(excel.getBigailmentCardinal(), excel.getPensionCardinal()));

				social.setUnitPensionCardinal(excel.getPensionCardinal());
				social.setUnitMedicalCardinal(ifNull(excel.getMedicalCardinal(), excel.getPensionCardinal()));
				social.setUnitUnemploymentCardinal(ifNull(excel.getUnemploymentCardinal(), excel.getPensionCardinal()));
				social.setUnitWorkInjuryCardinal(ifNull(excel.getWorkInjuryCardinal(), excel.getPensionCardinal()));
				social.setUnitBigailmentCardinal(ifNull(excel.getBigailmentCardinal(), excel.getPensionCardinal()));
				social.setUnitBirthCardinal(ifNull(excel.getBirthCardinal(), excel.getPensionCardinal()));
			}
			// 获取到政策后封装相关数据
			if (Common.isNotNull(socialSet)){
				social.setCanOverpay(socialSet.getCanOverpay());
				social.setCardinalId(socialSet.getId());
				social.setSocialHousehold(socialSet.getId());
				social.setCollectMoth(socialSet.getCollectMoth());
				social.setCollectType(socialSet.getCollectType());
				social.setHaveThisMonth(socialSet.getHaveThisMonth());
				social.setInsuranceBigailment(socialSet.getInsuranceBigailment());
				social.setInsuranceBirth(socialSet.getInsuranceBirth());
				social.setInsuranceInjury(socialSet.getInsuranceInjury());
				social.setInsuranceMedical(socialSet.getInsuranceMedical());
				social.setInsurancePension(socialSet.getInsurancePension());
				social.setInsuranceUnemployment(socialSet.getInsuranceUnemployment());
				social.setInsuranceIsLatestCardinality(socialSet.getInsuranceIsLatestCardinality());
				social.setIsChargePersonal(socialSet.getIsChargePersonal());
				social.setIsIllness(socialSet.getIsIllness());
				social.setOverpayNumber(socialSet.getOverpayNumber());
				social.setValueType(socialSet.getValueType());
				// 比例初始化
				social.setPersonalPensionPer(socialSet.getPersonalPersionPro());
				social.setPersonalMedicalPer(socialSet.getPersonalMedicalPro());
				social.setPersonalUnemploymentPer(socialSet.getPersonalUnemploymentPro());
				social.setPersonalBigailmentPer(socialSet.getPayPersonalPro());

				social.setUnitPensionPer(socialSet.getUnitPersionPro());
				social.setUnitMedicalPer(socialSet.getUnitMedicalPro());
				social.setUnitUnemploymentPer(socialSet.getUnitUnemploymentPro());
				social.setUnitWorkUnjuryPer(socialSet.getUnitInjuryPro());
				social.setUnitBigailmentPer(socialSet.getPayCompanyPro());
				social.setUnitBirthPer(socialSet.getUnitBirthPro());

				social.setUnitBigailmentMoney(socialSet.getPayCompany());
				social.setPersonalBigailmentMoney(socialSet.getPayPersonal());
				//按最低
				if (CommonConstants.ZERO_STRING.equals(excel.getPaymentType())){
					social.setPersonalPensionCardinal(socialSet.getLowerLimit());
					social.setPersonalMedicalCardinal(socialSet.getLowerLimit());
					social.setPersonalUnemploymentCardinal(socialSet.getLowerLimit());
					social.setPersonalBigailmentCardinal(socialSet.getLowerLimit());

					social.setUnitPensionCardinal(socialSet.getLowerLimit());
					social.setUnitMedicalCardinal(socialSet.getLowerLimit());
					social.setUnitUnemploymentCardinal(socialSet.getLowerLimit());
					social.setUnitWorkInjuryCardinal(socialSet.getLowerLimit());
					social.setUnitBigailmentCardinal(socialSet.getLowerLimit());
					social.setUnitBirthCardinal(socialSet.getLowerLimit());
				}
				//按最高
				if (CommonConstants.TWO_STRING.equals(excel.getPaymentType())){
					social.setPersonalPensionCardinal(socialSet.getUpperLimit());
					social.setPersonalMedicalCardinal(socialSet.getUpperLimit());
					social.setPersonalUnemploymentCardinal(socialSet.getUpperLimit());
					social.setPersonalBigailmentCardinal(socialSet.getUpperLimit());

					social.setUnitPensionCardinal(socialSet.getUpperLimit());
					social.setUnitMedicalCardinal(socialSet.getUpperLimit());
					social.setUnitUnemploymentCardinal(socialSet.getUpperLimit());
					social.setUnitWorkInjuryCardinal(socialSet.getUpperLimit());
					social.setUnitBigailmentCardinal(socialSet.getUpperLimit());
					social.setUnitBirthCardinal(socialSet.getUpperLimit());
				}
			}
			boolean flag = CommonConstants.ZERO_STRING.equals(social.getIsIllness()) && (CommonConstants.ZERO_STRING.equals(social.getCollectType())||CommonConstants.ONE_STRING.equals(social.getCollectType()));
			if (flag) {
				//收取方式按年 且为指定月份时产生数据
				if (CommonConstants.ZERO_STRING.equals(social.getCollectType()) && Common.isNotNull(socialSet)) {
					//按年收取大病方式按定值
					social.setUnitBigailmentMoney(socialSet.getPayCompany());
					social.setPersonalBigailmentMoney(socialSet.getPayPersonal());
				}else if (CommonConstants.ONE_STRING.equals(social.getCollectType())) {
					//收取方式按月
					if (CommonConstants.ZERO_STRING.equals(social.getValueType())) {
						//收取大病按比例
						social.setUnitBigailmentMoney(BigDecimalUtils.safeMultiply(social.getUnitBigailmentCardinal(), social.getUnitBigailmentPer(), BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));
						social.setPersonalBigailmentMoney(BigDecimalUtils.safeMultiply(social.getPersonalBigailmentCardinal(), social.getPersonalBigailmentPer(), BigDecimal.valueOf(CommonConstants.ONE_OF_PERCENT.doubleValue())));
					} else if (CommonConstants.ONE_STRING.equals(social.getValueType()) && Common.isNotNull(socialSet)) {
						//收取大病方式按定值
						social.setUnitBigailmentMoney(socialSet.getPayCompany());
						social.setPersonalBigailmentMoney(socialSet.getPayPersonal());
					}
				}
			}
			// 处理部分办理失败的情况
			initHandleStatus(excel, socialFundMap, social);
			socials.put(excel.getEmpIdcard(),social);
		}
	}

	private void initHandleStatus(TDispatchImportVo excel, Map<String, TSocialFundInfo> socialFundMap, TSocialInfo social) {
		TSocialFundInfo socialFund;
		if (Common.isNotNull(socialFundMap)) {
			socialFund = socialFundMap.get(excel.getEmpIdcard());
			if (Common.isNotNull(socialFund)){
				if (CommonConstants.ONE_STRING.equals(socialFund.getPensionHandle())){
					social.setPensionHandle(socialFund.getPensionHandle());
				}else {
					socialFund.setUnitPensionCardinal(social.getUnitPensionCardinal());
					socialFund.setUnitPensionPer(social.getUnitPensionPer());
					socialFund.setPersonalPensionCardinal(social.getPersonalPensionCardinal());
					socialFund.setPersonalPensionPer(social.getPersonalPensionPer());
				}
				if (CommonConstants.ONE_STRING.equals(socialFund.getMedicalHandle())){
					social.setMedicalHandle(socialFund.getMedicalHandle());
				}else {
					socialFund.setUnitMedicalCardinal(social.getUnitMedicalCardinal());
					socialFund.setUnitMedicalPer(social.getUnitMedicalPer());
					socialFund.setPersonalMedicalCardinal(social.getUnitMedicalCardinal());
					socialFund.setPersonalMedicalPer(social.getUnitMedicalPer());
				}
				if (CommonConstants.ONE_STRING.equals(socialFund.getUnemployHandle())){
					social.setUnemployHandle(socialFund.getUnemployHandle());
				}else {
					socialFund.setUnitUnemploymentCardinal(social.getUnitUnemploymentCardinal());
					socialFund.setUnitUnemploymentPer(social.getUnitUnemploymentPer());
					socialFund.setPersonalUnemploymentCardinal(social.getUnitUnemploymentCardinal());
					socialFund.setPersonalUnemploymentPer(social.getUnitUnemploymentPer());
				}
				if (CommonConstants.ONE_STRING.equals(socialFund.getWorkInjuryHandle())){
					social.setWorkInjuryHandle(socialFund.getWorkInjuryHandle());
				}else {
					socialFund.setUnitWorkInjuryCardinal(social.getUnitWorkInjuryCardinal());
					socialFund.setPersonalWorkInjuryCardinal(social.getUnitWorkInjuryCardinal());
				}
				if (CommonConstants.ONE_STRING.equals(socialFund.getBirthHandle())){
					social.setBirthHandle(socialFund.getBirthHandle());
				}else {
					socialFund.setUnitBirthCardinal(social.getUnitBirthCardinal());
					socialFund.setUnitBirthPer(social.getUnitBirthPer());
				}
				if (CommonConstants.ONE_STRING.equals(socialFund.getBigailmentHandle())){
					social.setBigailmentHandle(socialFund.getBigailmentHandle());
				}else {
					socialFund.setUnitBigailmentCardinal(social.getUnitBigailmentCardinal());
					socialFund.setUnitBigailmentPer(social.getUnitBigailmentPer());
					socialFund.setPersonalBigailmentCardinal(social.getUnitBigailmentCardinal());
					socialFund.setPersonalBigailmentPer(social.getUnitBigailmentPer());
				}
			}
			socialFundMap.put(excel.getEmpIdcard(),socialFund);
		}
	}

	private BigDecimal ifNull(BigDecimal old,BigDecimal last){
		if (Common.isEmpty(old)){
			return last;
		}
		return old;
	}
	private Date ifNull(Date old,Date last){
		if (Common.isEmpty(old)){
			return last;
		}
		return old;
	}

	private void initHoldInfo(List<String> socialholds,
							  List<String> fundHolds,
							  Map<String, SysBaseSetInfo> socialHoldMap,
							  Map<String, SysBaseSetInfo> fundHoldMap) {
		Date now = DateUtil.getCurrentDateTime();
		if (Common.isNotNull(socialholds)) {
			List<SysBaseSetInfo> socialBases = baseSetMapper.selectList(Wrappers.<SysBaseSetInfo>query().lambda()
					.eq(SysBaseSetInfo::getBaseType, CommonConstants.ZERO_STRING)
					.le(SysBaseSetInfo::getApplyStartDate, now)
					.ge(SysBaseSetInfo::getApplyEndDate, now)
					.in(SysBaseSetInfo::getDepartName,socialholds)
					.eq(SysBaseSetInfo::getDeleteFlag, CommonConstants.ZERO_STRING)
					.groupBy(SysBaseSetInfo::getDepartName));
			if (Common.isNotNull(socialBases)) {
				for (SysBaseSetInfo set:socialBases){
					socialHoldMap.put(set.getDepartName(),set);
				}
			}
			socialBases.clear();
		}
		if (Common.isNotNull(fundHolds)) {
			List<SysBaseSetInfo> fundBases = baseSetMapper.getFundBaseSet(fundHolds);
			if (Common.isNotNull(fundBases)) {
				for (SysBaseSetInfo set:fundBases){
					fundHoldMap.put(set.getDepartName(),set);
				}
			}
			fundBases.clear();
		}
	}

	private void initContractInfo(Map<String, EmpContractDispatchVo> contracts,
								  TDispatchImportVo excel,
								  DispatchEmpVo empVo) {
		// 合同开始时间和截止时间一致直接跳过
		if (excel.getContractStart().equals(empVo.getContractStart())
				&& excel.getContractEnd().equals(empVo.getContractEnd())){
			return;
		}
		EmpContractDispatchVo contract;
		contract = new EmpContractDispatchVo();
		contract.setContractEnd(excel.getContractEnd());
		contract.setContractName(excel.getContractName());
		contract.setContractSubName(excel.getContractSubName());
		contract.setContractType(excel.getContractType());
		contract.setContractStart(excel.getContractStart());
		contract.setContractSubName(excel.getContractSubName());
		contract.setDeptNo(excel.getSettleDomainCode());
		contract.setPost(excel.getPost());
		contract.setSituation(excel.getContractType());
		contract.setEmpIdcard(excel.getEmpIdcard());
		contract.setEmpName(excel.getEmpName());
		if (Common.isNotNull(empVo)) {
			contract.setEmpId(empVo.getId());
			contract.setEmpNo(empVo.getEmpCode());
			contract.setEmpType(empVo.getEmpNatrue());
		}
		contracts.put(excel.getEmpIdcard()+CommonConstants.DOWN_LINE_STRING+excel.getSettleDomainCode(),contract);
	}

	private void initProjectInfo(Map<String, EmpProjectDispatchVo> projects,
								 TDispatchImportVo excel,
								 DispatchEmpVo empVo) {
		EmpProjectDispatchVo project;
		project = new EmpProjectDispatchVo();
		project.setDeptNo(excel.getSettleDomainCode());
		project.setContractType(excel.getContractType());
		project.setEmpIdcard(excel.getEmpIdcard());
		project.setEmpName(excel.getEmpName());
		project.setEmpNatrue(excel.getEmpType());
		project.setPost(excel.getPost());
		project.setWorkingHours(excel.getWorkingHours());
		if (Common.isNotNull(empVo)) {
			project.setEmpId(empVo.getId());
			project.setEmpCode(empVo.getEmpCode());
		}
		projects.put(excel.getEmpIdcard()+CommonConstants.DOWN_LINE_STRING+excel.getSettleDomainCode(),project);
	}

	private void initEmpAddInfo(Map<String, EmpAddDispatchVo> empAdds, TDispatchImportVo excel) {
		EmpAddDispatchVo emp;
		emp = new EmpAddDispatchVo();
		emp.setEmpIdcard(excel.getEmpIdcard());
		emp.setEmpName(excel.getEmpName());
		emp.setEmpNational(excel.getEmpNational());
		emp.setEmpNatrue(excel.getEmpType());
		emp.setEmpPhone(excel.getEmpMobile());
		emp.setEmpRegisType(excel.getEmpRegisType());
		emp.setContractStatus(CommonConstants.ZERO_INT);
		emp.setDeleteFlag(CommonConstants.ZERO_STRING);
		emp.setFileSource(CommonConstants.ONE_STRING);
		emp.setFileProvince(Common.isNotNullToInt(excel.getFileProvince()));
		emp.setFileCity(Common.isNotNullToInt(excel.getFileCity()));
		emp.setFileTown(Common.isNotNullToInt(excel.getFileTown()));
		emp.setFileStatus(CommonConstants.ZERO_INT);
		emp.setStatus(CommonConstants.ZERO_INT);
		emp.setIdProvince(Common.isNotNullToInt(excel.getIdCardProvince()));
		emp.setIdCity(Common.isNotNullToInt(excel.getIdCardCity()));
		emp.setIdTown(Common.isNotNullToInt(excel.getIdCardTown()));
		emp.setProjectNum(CommonConstants.ONE_INT);
		emp.setDeptNo(excel.getSettleDomainCode());
		emp.setPost(excel.getPost());
		emp.setDeptId(excel.getSettleDomainId());
		emp.setDeptNo(excel.getSettleDomainCode());
		emp.setDeptName(excel.getDepartName());
		emp.setUnitName(excel.getCustomerName());
		emp.setUnitNo(excel.getCustomerCode());
		empAdds.put(excel.getEmpIdcard(),emp);
	}

	private boolean validDdispatchStatus(List<ErrorMessage> errorMessageList, Map<String, TSocialFundInfo> socialFundMap,
										 TDispatchImportVo excel) {
		TSocialFundInfo sf;
		if (Common.isNotNull(socialFundMap)) {
			sf = socialFundMap.get(excel.getEmpIdcard());
			if (Common.isNotNull(sf)) {
				// 拒绝新增1：派单待审核、派单待办理、办理成功且未派减成功------ 先排除兼职工伤
				if (CommonConstants.ZERO_STRING.equals(sf.getSocialAddStatus())
						|| CommonConstants.ONE_STRING.equals(sf.getSocialAddStatus())
						|| (CommonConstants.TWO_STRING.equals(sf.getSocialAddStatus())
						&& !CommonConstants.TWO_STRING.equals(sf.getSocialReduceStatus())
						&& BigDecimal.ZERO.compareTo(BigDecimalUtils.isNullToZero(excel.getPensionCardinal())) != 0
						&& BigDecimal.ZERO.compareTo(BigDecimalUtils.isNullToZero(sf.getUnitPensionCardinal())) != 0)
				) {
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_EXISTING)));
					return true;
				}
				// 拒绝新增2：新增兼职工伤---有兼职工伤不可重复增、
				if (BigDecimal.ZERO.compareTo(BigDecimalUtils.isNullToZero(excel.getPensionCardinal())) == 0) {
					// 有兼职工伤不可重复增 (未派减成功不可新增兼职工伤，但是可以新增五险)
					if (BigDecimal.ZERO.compareTo(BigDecimalUtils.isNullToZero(sf.getUnitPensionCardinal())) == 0
							&& !CommonConstants.TWO_STRING.equals(sf.getSocialReduceStatus())) {
						errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_INJURY_EXISTING)));
						return true;
					}
					// 有五险未派减不给新增兼职工伤
					if (BigDecimal.ZERO.compareTo(BigDecimalUtils.isNullToZero(sf.getUnitPensionCardinal())) != 0
							&& Common.isEmpty(sf.getSocialReduceStatus())) {
						errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_NOT_REDUCE)));
						return true;
					}
				}
				// 拒绝新增3：新增五险对应兼职工伤逻辑---有兼职工伤未派减不给增五险、
				if (BigDecimal.ZERO.compareTo(BigDecimalUtils.isNullToZero(excel.getPensionCardinal())) != 0) {
					// 有兼职工伤未派减不给增五险
					if (BigDecimal.ZERO.compareTo(BigDecimalUtils.isNullToZero(sf.getUnitPensionCardinal())) == 0
							&& Common.isEmpty(sf.getSocialReduceStatus())) {
						errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_INJURY_NOT_REDUCE)));
						return true;
					}
				}
			}
		}
		return false;
	}

	private Map<String, TSocialFundInfo> getSocialFundMap(List<String> idcards) {
		List<TSocialFundInfo> list = socialFundMapper.selectList(Wrappers.<TSocialFundInfo>query().lambda()
				.in(TSocialFundInfo::getEmpIdcard, idcards)
				.groupBy(TSocialFundInfo::getEmpIdcard));
		if (Common.isNotNull(list)) {
			Map<String, TSocialFundInfo> map = new HashMap<>();
			for (TSocialFundInfo info:list){
				map.put(info.getEmpIdcard(),info);
			}
			return map;
		}
		return null;
	}

	private void initIdcardAndCode(List<TDispatchImportVo> excelVOList,
								   List<String> idcards, List<String> codes,
								   List<String> socialholds,
								   List<String> fundholds) {
		if (Common.isNotNull(excelVOList)) {
			for (TDispatchImportVo vo : excelVOList) {
				idcards.add(vo.getEmpIdcard());
				codes.add(vo.getSettleDomainCode());
				if (Common.isNotNull(vo.getSocialHousehold())) {
					socialholds.add(vo.getSocialHousehold());
				}
				if (Common.isNotNull(vo.getProvidentHousehold())) {
					fundholds.add(vo.getProvidentHousehold());
				}
			}
		}
	}

	private Map<String, DispatchEmpVo> getDispatchEmpVo(List<String> idcards, List<String> codes) {
		Map<String, DispatchEmpVo> empVoMap = null;
		if (Common.isNotNull(idcards) || Common.isNotNull(codes)) {
			DispatchCheckVo checkVo = new DispatchCheckVo();
			checkVo.setCodes(CollUtil.distinct(codes));
			checkVo.setIdCards(CollUtil.distinct(idcards));
			R<Map<String,DispatchEmpVo>> res = archivesDaprUtil.getDispatchEmpVo(checkVo);
			if (Common.isNotNull(res) && Common.isNotNull(res.getData())) {
				empVoMap = res.getData();
			}
		}
		return empVoMap;
	}

	private boolean validImport(List<ErrorMessage> errorMessageList,
								TDispatchImportVo excel,
								ProjectSetInfoVo setInfoVo,
								Map<String, TSocialFundInfo> socialFundMap) {
		if (Common.isEmpty(setInfoVo)){
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_PROJECT_NOT_FOUND)));
			return true;
		}
		excel.setSettleDomainId(setInfoVo.getId());
		excel.setDepartName(setInfoVo.getDepartName());
		excel.setCustomerCode(setInfoVo.getCustomerCode());
		excel.setCustomerId(setInfoVo.getCustomerId());
		excel.setCustomerName(setInfoVo.getCustomerName());
		if (Common.isEmpty(excel.getSocialHousehold()) && Common.isEmpty(excel.getProvidentHousehold())){
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_AND_FUND_NOT_EMPTY)));
			return true;
		}
		if (Common.isNotNull(excel.getContractName()) && (
				Common.isEmpty(excel.getContractSubName())
						|| Common.isEmpty(excel.getContractType())
						|| Common.isEmpty(excel.getContractStart())
						|| Common.isEmpty(excel.getContractEnd())
		)) {
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_CONTRACT_NOT_EMPTY)));
			return true;
		}
		if (Common.isNotNull(excel.getSocialHousehold()) && (
				Common.isEmpty(excel.getRecordBase())
						|| Common.isEmpty(excel.getPensionStart())
						|| Common.isEmpty(excel.getPaymentType())
						|| Common.isEmpty(excel.getPensionCardinal())
		)) {
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_NOT_EMPTY)));
			return true;
		}
		if (Common.isNotNull(excel.getProvidentHousehold()) && (
				Common.isEmpty(excel.getProvidentCardinal())
						|| Common.isEmpty(excel.getProvidentStart())
						|| Common.isEmpty(excel.getProvidentPer())
		)) {
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_FUND_NOT_EMPTY)));
			return true;
		}

		TSocialFundInfo socialFund = null;
		if (Common.isNotNull(socialFundMap)){
			socialFund = socialFundMap.get(excel.getEmpIdcard());
			if (Common.isNotNull(socialFund)){
				// 社保状态：派增（0待审核、1待办理、2办理中 3办理成功、4部分办理失败 5 办理失败）、派减（6待审核 7待办理 8办理成功 9 办理失败）
				if (Common.isNotNull(excel.getSocialHousehold())
						&& (Common.isEmpty(socialFund.getSocialStatus())
						|| CommonConstants.SIX_STRING.equals(socialFund.getSocialStatus())
						|| CommonConstants.SEVEN_STRING.equals(socialFund.getSocialStatus())
						|| CommonConstants.NINE_STRING.equals(socialFund.getSocialStatus())
						|| CommonConstants.FIVE_STRING.equals(socialFund.getSocialStatus()))
				){
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_EXISTING)));
					return true;
				}
				// 公积金状态：派增（0待审核、1待办理、3办理成功、4办理失败）、派减（5待审核 6待办理 7 办理成功 8 办理失败）
				if (Common.isNotNull(excel.getProvidentHousehold())
						&& (CommonConstants.FIVE_STRING.equals(socialFund.getFundStatus())
						&& CommonConstants.SIX_STRING.equals(socialFund.getFundStatus())
						&& CommonConstants.EIGHT_STRING.equals(socialFund.getFundStatus())
						&& CommonConstants.FOUR_STRING.equals(socialFund.getFundStatus()))){
					errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_FUND_EXISTING)));
					return true;
				}
			}
		}
		return false;
	}


	@Override
	public R<List<ErrorMessage>> importReduceDiy(InputStream inputStream) {
		YifuUser user = SecurityUtils.getUser();
		if (Common.isEmpty(user)){
			R.failed(CommonConstants.USER_FAIL);
		}
		List<ErrorMessage> errorMessageList = new ArrayList<>();
		ExcelUtil<TDispatchReduceVo> util1 = new ExcelUtil<>(TDispatchReduceVo.class);
		;
		// 写法2：
		// 匿名内部类 不用额外写一个DemoDataListener
		// 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
		try {
			EasyExcel.read(inputStream, TDispatchReduceVo.class, new ReadListener<TDispatchReduceVo>() {
				/**
				 * 单次缓存的数据量
				 */
				public static final int BATCH_COUNT = CommonConstants.BATCH_COUNT;
				/**
				 *临时存储
				 */
				private List<TDispatchReduceVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);

				@Override
				public void invoke(TDispatchReduceVo data, AnalysisContext context) {
					ReadRowHolder readRowHolder = context.readRowHolder();
					Integer rowIndex = readRowHolder.getRowIndex();
					data.setRowIndex(rowIndex + 1);
					ErrorMessage errorMessage = util1.checkEntity(data, data.getRowIndex());
					if (Common.isNotNull(errorMessage)) {
						errorMessageList.add(errorMessage);
					} else {
						cachedDataList.add(data);
					}
					if (cachedDataList.size() >= BATCH_COUNT) {
						saveData();
						// 存储完成清理 list
						cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
					}
				}

				@Override
				public void doAfterAllAnalysed(AnalysisContext context) {
					saveData();
				}

				/**
				 * 加上存储数据库
				 */
				private void saveData() {
					log.info("{}条数据，开始存储数据库！", cachedDataList.size());
					batchReduceDispatch(cachedDataList, errorMessageList,user);
					log.info("存储数据库成功！");
				}
			}).sheet().doRead();
		} catch (Exception e) {
			log.error(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR, e);
			return R.failed(CommonConstants.IMPORT_DATA_ANALYSIS_ERROR);
		}
		return R.ok(errorMessageList);
	}

	private void batchReduceDispatch(List<TDispatchReduceVo> excelVOList, List<ErrorMessage> errorMessageList, YifuUser user) {
		if (!Common.isNotNull(excelVOList)){
			return;
		}
		Map<String,String> excelVOTemp = new HashMap<>();
		// 个性化校验逻辑
		List<String> idcards = new ArrayList<>();
		// 通过身份证和项目编码获取档案&项目档案&最新合同
		Map<String, DispatchEmpVo> empVoMap = getDispatchEmpVo(idcards, null);
		// 初始化参数
		initIdcard(excelVOList, idcards);
		// 通过身份证查询社保&公积金&社保公积金查询信息: 身份证维度唯一
		Map<String, TSocialFundInfo> socialFundMap = getSocialFundMap(idcards);
		//新增派单信息
		Map<String,TDispatchInfo> dispatchMap = new HashMap<>();
		// 新增社保公积金查询
		Map<String,TSocialFundInfo> socialFundAddMap = new HashMap<>();
		DispatchEmpVo empVo = null;
		TDispatchInfo dispatch;
		TDispatchReduceVo excel;
		TSocialFundInfo socialFund;
		// 执行数据插入操作 组装
		for (int i = 0; i < excelVOList.size(); i++) {
			excel = excelVOList.get(i);
			socialFund = socialFundMap.get(excel.getEmpIdcard());
			if (Common.isEmpty(socialFund)){
				errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_FUND_NOT_EMPTY)));
				continue;
			}
			// 自定义校验
			if (validReduce(errorMessageList,excelVOTemp, socialFundMap,socialFund, excel)){
				continue;
			}
			if (Common.isNotNull(empVoMap)) {
				empVo = empVoMap.get(excel.getEmpIdcard());
			}
			excelVOTemp.put(excel.getEmpIdcard(),excel.getEmpIdcard());
			// 初始化派单 和 社保公积金查询信息
			dispatch = gettDispatchInfo(empVo, excel, socialFund);
			try {
				baseMapper.insert(dispatch);
				socialFundMapper.updateById(socialFund);
			}catch (Exception e){
				log.error("批量派减异常：",e);
				errorMessageList.add(new ErrorMessage(excel.getRowIndex(), CommonConstants.SAVE_FAILED));
				continue;
			}
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), CommonConstants.SAVE_SUCCESS,CommonConstants.GREEN));
		}
	}

	private TDispatchInfo gettDispatchInfo(DispatchEmpVo empVo, TDispatchReduceVo excel, TSocialFundInfo socialFund) {
		TDispatchInfo dispatch;
		dispatch = new TDispatchInfo();
		dispatch.setEmpId(socialFund.getEmpId());
		dispatch.setEmpName(socialFund.getEmpName());
		dispatch.setEmpNo(socialFund.getEmpNo());
		dispatch.setEmpType(socialFund.getEmpType());
		dispatch.setEmpIdcard(socialFund.getEmpIdcard());
		dispatch.setType(CommonConstants.ONE_STRING);
		dispatch.setLeaveDate(excel.getLeaveDate());
		dispatch.setDeleteFlag(CommonConstants.ZERO_STRING);
		dispatch.setReduceReason(excel.getReasonType());
		dispatch.setTrustRemark(excel.getTrustRemark());
		if (Common.isNotNull(excel.getSocialReduceDate())){
			dispatch.setSocialHandleStatus(CommonConstants.ZERO_STRING);
			dispatch.setSocialId(socialFund.getSocialId());
			dispatch.setSocialReduceDate(excel.getSocialReduceDate());
			dispatch.setSocialProvince(socialFund.getSocialProvince());
			dispatch.setSocialCity(socialFund.getSocialCity());
			dispatch.setSocialTown(socialFund.getSocialTown());
			socialFund.setSocialReduceStatus(CommonConstants.ZERO_STRING);
			socialFund.setSocialReduceDate(excel.getSocialReduceDate());
			socialFund.setSocialReduceStatus(CommonConstants.ZERO_STRING);
			socialFund.setSocialStatus(CommonConstants.SIX_STRING);
		}
		if (Common.isNotNull(excel.getFundReduceDate())){
			dispatch.setFundHandleStatus(CommonConstants.ZERO_STRING);
			dispatch.setFundId(socialFund.getFundId());
			dispatch.setFundReduceDate(excel.getSocialReduceDate());
			dispatch.setFundProvince(socialFund.getFundProvince());
			dispatch.setFundCity(socialFund.getFundCity());
			dispatch.setFundTown(socialFund.getFundTown());
			socialFund.setFundReduceDate(excel.getFundReduceDate());
			socialFund.setFundStatus(CommonConstants.FIVE_STRING);
			socialFund.setFundReduceStatus(CommonConstants.ZERO_STRING);
		}
		dispatch.setBelongUnitName(socialFund.getUnitName());
		dispatch.setBelongUnit(socialFund.getUnitId());
		if (Common.isNotNull(empVo)){
			dispatch.setEmpMobile(empVo.getEmpPhone());
			dispatch.setEmpNational(empVo.getEmpNational());
			dispatch.setEmpId(empVo.getId());
			dispatch.setEmpNo(empVo.getEmpCode());
			// 封装合同信息 如果有合同取值实际合同信息
			dispatch.setSettleDomainName(empVo.getDeptName());
			dispatch.setContractStart(empVo.getContractStart());
			dispatch.setContractEnd(empVo.getContractEnd());
			dispatch.setContractTerm(empVo.getContractTerm());
			dispatch.setContractType(empVo.getContractType());
			dispatch.setFileProvince(empVo.getFileProvince());
			dispatch.setFileCity(empVo.getFileCity());
			dispatch.setFileTown(empVo.getFileTown());
			dispatch.setSettleDomainCode(empVo.getDeptNo());
			dispatch.setSettleDomain(empVo.getDeptId());
		}
		return dispatch;
	}

	private boolean validReduce(List<ErrorMessage> errorMessageList,
								Map<String, String> excelVOTemp,
								Map<String, TSocialFundInfo> socialFundMap,
								TSocialFundInfo socialFund,
								TDispatchReduceVo excel) {
		if (Common.isNotNull(excelVOTemp.get(excel.getEmpIdcard()))){
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_REDUCE_EXISTS)));
			return true;
		}
		if (Common.isEmpty(excel.getFundReduceDate()) && Common.isEmpty(excel.getSocialReduceDate())){
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_REDUCE_SOCIAL_FUND_NOT_EMPTY)));
			return true;
		}
		if (Common.isEmpty(socialFundMap)){
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_SOCIAL_FUND_NOT_EMPTY)));
			return true;
		}
		//社保状态：派增（0待审核、1待办理、2办理中 3办理成功、4部分办理失败 5 办理失败）、派减（6待审核 7待办理 8办理成功 9 办理失败）
		if (Common.isNotNull(excel.getSocialReduceDate())
				&& !socialFund.getSocialStatus().equals(CommonConstants.THREE_STRING)){
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_REDUCE_SOCIAL_STATUS_ERROR)));
			return true;
		}
		//公积金状态：派增（0待审核、1待办理、3办理成功、4办理失败）、派减（5待审核 6待办理 7 办理成功 8 办理失败）
		if (Common.isNotNull(excel.getFundReduceDate())
				&& !socialFund.getFundStatus().equals(CommonConstants.THREE_STRING)){
			errorMessageList.add(new ErrorMessage(excel.getRowIndex(), MsgUtils.getMessage(ErrorCodes.EMP_DISPATCH_REDUCE_FUND_STATUS_ERROR)));
			return true;
		}
		return false;
	}

	private void initIdcard(List<TDispatchReduceVo> excelVOList, List<String> idcards) {
		if (Common.isNotNull(excelVOList)) {
			for (TDispatchReduceVo vo : excelVOList) {
				idcards.add(vo.getEmpIdcard());
			}
		}
	}

	@Override
	public R<Boolean> removeByIdDiy(String id) {
		if (Common.isEmpty(id)){
			return R.failed(CommonConstants.PARAM_IS_NOT_EMPTY);
		}
		TDispatchInfo dispatch  = baseMapper.selectById(id);
		if (Common.isEmpty(dispatch)){
			return R.failed(CommonConstants.PARAM_IS_NOT_ERROR);
		}
		dispatch.setDeleteFlag(CommonConstants.ONE_STRING);
		if(baseMapper.updateById(dispatch)>0){
			return R.ok(true,CommonConstants.SAVE_SUCCESS);
		}else {
			return R.failed(false,CommonConstants.SAVE_FAILED);
		}
	}
	/**
	 * 通过id查询派单相关系信息
	 * @author fxj
	 * @param id id
	 * @return R
	 * @date 2022-07-25 10:19
	 */
	@Override
	public DispatchDetailVo getSocialAndFundInfoById(String id) {
		DispatchDetailVo detailVo = new DispatchDetailVo();
		TDispatchInfo dispatch = baseMapper.selectById(id);
		detailVo.setDispatch(dispatch);
		if (Common.isNotNull(dispatch)){
			if (Common.isNotNull(dispatch.getSocialId())){
				detailVo.setSocial(socialMapper.selectById(dispatch.getSocialId()));
			}
			if (Common.isNotNull(dispatch.getFundId())){
				detailVo.setFund(fundMapper.selectById(dispatch.getFundId()));
			}
			if (Common.isNotNull(dispatch.getContractId())){
				R<TEmployeeContractInfo> res = archivesDaprUtil.getContractById(dispatch.getContractId());
				if (Common.isNotNull(res)){
					detailVo.setContract(res.getData());
				}
			}
			if (Common.isNotNull(dispatch.getSettleDomain()) && Common.isNotNull(dispatch.getEmpId())){
				TEmployeeProject temp = new TEmployeeProject();
				temp.setDeptId(dispatch.getSettleDomain());
				temp.setEmpId(dispatch.getEmpId());
				R<TEmployeeProject> res = archivesDaprUtil.getTEmployeeProjectById(temp);
				if (Common.isNotNull(res)){
					detailVo.setProject(res.getData());
				}
			}
			if (Common.isNotNull(dispatch.getEmpId())){
				R<TEmployeeInfo> res = archivesDaprUtil.getTEmployeeInfoById(dispatch.getEmpId());
				if (Common.isNotNull(res)){
					detailVo.setEmployee(res.getData());
				}
			}
		}
		return detailVo;
	}
}
