package com.yifu.cloud.plus.v1.yifu.salary.util;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainSelectVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CacheConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ExcelAttribute;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.ValidityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.ExcelException;
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.insurances.util.ValidityUtil;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TConfigSalary;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryAccountItem;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryConfigStandard;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryEmployee;
import com.yifu.cloud.plus.v1.yifu.salary.service.TSalaryAccountService;
import com.yifu.cloud.plus.v1.yifu.salary.service.TSalaryEmployeeService;
import com.yifu.cloud.plus.v1.yifu.salary.vo.SalaryUploadParamVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TSalaryAccountItemVo;
import com.yifu.cloud.plus.v1.yifu.salary.vo.TSalaryAccountVo;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static com.yifu.cloud.plus.v1.yifu.salary.util.SalaryCommonUtil.setFields;

/**
 * @author hgw
 * @Description: EXCEL内容转化为TSalaryAccount
 */
@Data
@Log4j2
public class SalaryAccountUtil implements Serializable {

	/**
	 * 用于返回实体
	 */
	private List<TSalaryAccountVo> entityList;
	/**
	 * 用于返回错误信息
	 */
	private List<ErrorMessage> errorInfo;

	/**
	 * vo.jsonStr         客户原表json内容
	 *
	 * @param dept            项目
	 * @param configSalary    当前项目下的配置（结算月等
	 * @param salaryConfigMap 客户原表-工资模板配置Map
	 * @param empIdCardMap    当前项目下的员工Map
	 * @param empNameMap      当前项目下的员工Map
	 * @param isDuplicateName false：有重名（当前项目下的员工），则不可用姓名查找，必须含有身份证号列
	 *                        repeatFlag      默认 0：不允许重复导入已存在系统内的数据；1：允许重复导入
	 * @param ownEmployeeMap  自有员工所在项目Map
	 * @Description: 将jsonStr数据源的数据导入到 List<TSalaryAccount>
	 * @Author: hgw
	 * @Date: 2019/9/16 17:26
	 * @return: void
	 **/
	public void getJsonStringToList(YifuUser user, SalaryUploadParamVo vo, TSettleDomainSelectVo dept
			, TConfigSalary configSalary, Map<String, TSalaryConfigStandard> salaryConfigMap, Map<String, Boolean> isMustMap
			, Map<String, TSalaryEmployee> empIdCardMap, Map<String, TSalaryEmployee> empNameMap, boolean isDuplicateName
			, List<String> checkListY, String invoiceTitle, TSalaryEmployeeService tSalaryEmployeeService
			, Map<String, Integer> checkMap, Map<String, BigDecimal> specialMap, Map<String, Integer> ownEmployeeMap
			, Map<String, Integer> ownDeptMap, TSalaryAccountService tSalaryAccountService, Map<String, String> bankMap) {
		String jsonStr = vo.getJsonString();
		String salaryType = vo.getSalaryType();
		// 新员工是否更新：0否；1是 hgw 2024-7-18 16:36:31
		String newEmpUpdateFlag = vo.getNewEmpUpdateFlag();
		if (Common.isEmpty(newEmpUpdateFlag)) {
			newEmpUpdateFlag = CommonConstants.ZERO_STRING;
		}
		Integer isIssue = vo.getIsIssue();
		if (Common.isEmpty(isIssue)) {
			isIssue = 0;
		}
		List<TSalaryAccountVo> tList = new ArrayList<>();
		List<HashMap> list = JSONObject.parseArray(jsonStr, HashMap.class);
		List<ErrorMessage> errorList = new ArrayList<>();
		try {
			// 得到数据的条数
			int rows = list.size();
			// 有数据时才处理
			if (rows > 0) {
				// 得到类的所有field
				Field[] allFields = TSalaryAccountVo.class.getDeclaredFields();
				// 从map中得到对应列的field
				Field field;
				// 将有注解的field存放到fieldsMap中
				Map<String, Field> fieldsMap = new HashMap<>();
				for (int i = 0; i < allFields.length; i++) {
					field = allFields[i];
					if (field.isAnnotationPresent(ExcelAttribute.class)) {
						// 设置类的私有字段属性可访问
						field.setAccessible(true);
						fieldsMap.put(field.getName(), field);
					}
				}
				String error;  //校验字段是否符合要求 返回错误信息
				TSalaryAccountVo entity;  // 从第1行开始取数据
				HashMap<String, Object> temp;  // 得到一行中的所有单元格对象.
				ExcelAttribute attr;  //获取属性对应的注解属性
				Object cellValueObj;  //单元格值
				String cellValueStr;  //单元格字符串值
				String dbFiedName;  //单元格值，对应的数据库中文名
				Class<?> fieldType;  // 取得类型,并根据对象类型设置值.
				TSalaryConfigStandard scs;
				TSalaryEmployee emp;
				TSalaryEmployee newEmp;  //新员工
				List<TSalaryAccountItemVo> saiList;
				TSalaryAccountItemVo sai;
				BigDecimal cellValueBig;
				Map<String, Integer> checkIdNumberMap = new HashMap<>();  //验证身份证重复性的Map
				boolean salaryGiveTimeFlag;  //salaryGiveTime == true :立即发；false：暂停发：则不考虑开户行等
				//是否新员工：是：true；否：false
				boolean isNewEmployee;
				String empName;
				String salaryStyle;//工资发放方式（0现金/1银行）/2线下
				BigDecimal relaySalary;  //应发工资
				BigDecimal phoneSubsidy;
				BigDecimal relaySalarySum;  //应发工资合计，算3500与5000使用的
				BigDecimal money3500 = new BigDecimal("3500");  //特殊金额3500
				BigDecimal money5000 = new BigDecimal("5000");  //特殊金额5000
				BigDecimal actualSalarySum;  //实发工资
				// 当前年月
				String nowMonth = DateUtil.addMonth(CommonConstants.ZERO_INT);
				String must;
				// 每一行是否有错误 true : 无错误
				boolean errorFlag;
				// 是否含有年终奖 false 没有
				boolean annualBonusFlag;
				// 是否 不是劳务费（劳务费不用进档，不用档案信息）
				boolean notLabour = !CommonConstants.THREE_STRING.equals(salaryType);
				// 连接查询的数据集合
				List<TSalaryEmployee> updateEmpList = new ArrayList<>();
				// 2024-7-22 10:16:42 hgw 更新卡号等信息
				List<TSalaryEmployee> updateEmpBankList = new ArrayList<>();
				// 2024-7-22 10:16:42 hgw 更新卡号等信息，存储旧人员信息，以增加更新记录使用
				Map<String, TSalaryEmployee> updateEmpBankMap = new HashMap<>();

				List<TSalaryEmployee> checkBankInfoEmpList = new ArrayList<>();
				List<TSalaryEmployee> newEmpList = new ArrayList<>();
				Map<String, TSalaryAccountVo> entityMap = new HashMap<>();
				List<String> otherIdCard = new ArrayList<>();
				BigDecimal phoneSubsidyMoney;
				TSalaryAccountItem phoneSubsidyItem;
				// 基础的数据行，用于返回信息
				int dataRow = 2;
				if (Common.isNotNull(vo.getDataNum())) {
					dataRow = 1 + vo.getDataNum();
				}
				for (int i = 0; i < rows; i++) {
					annualBonusFlag = false;
					errorFlag = true;
					temp = list.get(i);
					entity = new TSalaryAccountVo();
					emp = null;
					newEmp = new TSalaryEmployee();
					newEmp.setLineNums(i);
					salaryGiveTimeFlag = true;
					entity.setSalaryGiveTime(CommonConstants.ZERO_STRING);
					empName = null;
					isNewEmployee = false;
					entity.setIsNewEmployee(CommonConstants.ZERO_STRING);
					saiList = new ArrayList<>();
					salaryStyle = SalaryConstants.SALARY_STYLE_BANK;
					relaySalary = null;
					phoneSubsidy =null;
					actualSalarySum = null;
					entity.setSettlementMonth(nowMonth);
					for (Map.Entry<String, TSalaryConfigStandard> entry : salaryConfigMap.entrySet()) {
						cellValueObj = getFieldValueByName(entry.getKey(), temp);
						scs = entry.getValue();
						if (Common.isNotNull(cellValueObj) && scs != null) {
							cellValueStr = getStringValByObject(cellValueObj);
							if (!StringUtils.isNotBlank(cellValueStr)) {
								errorFlag = false;
								error = "第" + (i + dataRow) + "行：" + entry.getKey() + "列_不识别对象类型";
								errorList.add(new ErrorMessage((i + dataRow), error));
								continue;
							}
							dbFiedName = scs.getDbFiedName();
							if (isMustMap.get(dbFiedName) != null && Boolean.TRUE.equals(isMustMap.get(dbFiedName))) {
								isMustMap.put(dbFiedName, false);
							}
							if (SalaryConstants.ANNUAL_BONUS_JAVA.equals(scs.getJavaFiedName()) && Common.isNotNull(cellValueStr)) {
								annualBonusFlag = true;
							}
							if (SalaryConstants.PHONE_SUBSIDY_JAVA.equals(scs.getJavaFiedName())) {
								phoneSubsidyMoney = NumberUtils.createBigDecimal(cellValueStr);
								if(phoneSubsidyMoney.compareTo(new BigDecimal("300")) > 0) {
									errorFlag = false;
									error = "第" + (i + dataRow) + "行：本次发放"+cellValueStr+"元，超出300元的限制，禁止导入";
									errorList.add(new ErrorMessage((i + dataRow), error));
									continue;
								}
							}
							if (SalaryConstants.ANNUAL_BONUS_TAX_TYPE.equals(scs.getJavaFiedName())) {
								if (SalaryConstants.ANNUAL_BONUS_ALONE.equals(cellValueStr)) {
									entity.setAnnualBonusType(SalaryConstants.ANNUAL_BONUS_TAX_TYPE_VALUE[1]);
								}
								if (SalaryConstants.ANNUAL_BONUS_MERGE.equals(cellValueStr)) {
									entity.setAnnualBonusType(SalaryConstants.ANNUAL_BONUS_TAX_TYPE_VALUE[0]);
								}
							}
							if (SalaryConstants.RELAY_SALARY_JAVA.equals(scs.getJavaFiedName())) {
								try {
									relaySalary = new BigDecimal(cellValueStr.replace(",", ""));
									sai = new TSalaryAccountItemVo();
									sai.setCnName(dbFiedName);
									sai.setJavaFiedName(scs.getJavaFiedName());
									sai.setIsTax(CommonConstants.ZERO_INT);
									sai.setSalaryMoney(relaySalary);
									saiList.add(sai);
								} catch (Exception e) {
									errorFlag = false;
									error = "第" + (i + dataRow) + "行：应发工资：'" + cellValueStr + "'错误，请检查数据";
									errorList.add(new ErrorMessage((i + dataRow), error));
									continue;
								}
							}
							if (SalaryConstants.PHONE_SUBSIDY_JAVA.equals(scs.getJavaFiedName())) {
								try {
									phoneSubsidy = new BigDecimal(cellValueStr.replace(",", ""));
									sai = new TSalaryAccountItemVo();
									sai.setCnName(dbFiedName);
									sai.setJavaFiedName(scs.getJavaFiedName());
									sai.setIsTax(CommonConstants.ONE_INT);
									sai.setSalaryMoney(phoneSubsidy);
									saiList.add(sai);
								} catch (Exception e) {
									errorFlag = false;
									error = "第" + (i + dataRow) + "行：通讯补贴：'" + cellValueStr + "'错误，请检查数据";
									errorList.add(new ErrorMessage((i + dataRow), error));
									continue;
								}
							}
							if (SalaryConstants.ACTUAL_SALARY_SUM_JAVA.equals(scs.getJavaFiedName())) {
								try {
									actualSalarySum = new BigDecimal(cellValueStr.replace(",", ""));
									entity.setActualSalary(actualSalarySum);
								} catch (Exception e) {
									errorFlag = false;
									error = "第" + (i + dataRow) + "行：实发工资：'" + cellValueStr + "'错误，请检查数据";
									errorList.add(new ErrorMessage((i + dataRow), error));
									continue;
								}
							}
							if (SalaryConstants.PDEDUCTION_JAVA.equals(scs.getJavaFiedName())
									|| SalaryConstants.UDEDUCTION_JAVA.equals(scs.getJavaFiedName())
									|| SalaryConstants.ENTERPRISE_ANNUITY_JAVA.equals(scs.getJavaFiedName())
									|| SalaryConstants.ENTERPRISE_ANNUITY_UNIT_JAVA.equals(scs.getJavaFiedName())
									|| scs.getJavaFiedName().contains(SalaryConstants.WITHHOLIDING)) {
								try {
									new BigDecimal(cellValueStr.replace(",", ""));
								} catch (Exception ex) {
									errorFlag = false;
									error = "第" + (i + dataRow) + "行：代扣、企业年金，只能是金额！";
									errorList.add(new ErrorMessage((i + dataRow), error));
									continue;
								}
							}
							if (SalaryConstants.EMP_NAME.equals(dbFiedName)) {
								empName = cellValueStr = cellValueStr.replace(" ", "");
								if (isDuplicateName) {
									emp = empNameMap.get(empName);
								}
								newEmp.setEmpName(empName);
							}

							// cyx-mvp1.7.0修复：去掉重复判断
							if (SalaryConstants.IF_NEW_EMPLOYEE.equals(dbFiedName) && SalaryConstants.IS_NEW.equals(cellValueStr)) {
								isNewEmployee = true;
								entity.setIsNewEmployee(CommonConstants.ONE_STRING);
							}
							if (SalaryConstants.ID_NUMBER.equals(dbFiedName)) {
								if (checkIdNumberMap.get(cellValueStr) == null) {
									checkIdNumberMap.put(cellValueStr, (i + dataRow));
								} else {
									errorFlag = false;
									error = "第" + (i + dataRow) + "行与第：" + checkIdNumberMap.get(cellValueStr) + "行身份证重复:" + cellValueStr;
									errorList.add(new ErrorMessage((i + dataRow), error));
									break;
								}
								if (cellValueStr.contains("x")) {
									cellValueStr = cellValueStr.toUpperCase();
								}
								emp = empIdCardMap.get(cellValueStr);
								newEmp.setEmpIdcard(cellValueStr);
							}


							if (SalaryConstants.SALARY_GIVE_TIME.equals(cellValueStr)) {
								salaryGiveTimeFlag = false;
								entity.setSalaryGiveTime(CommonConstants.ONE_STRING);
							}

							field = fieldsMap.get(scs.getJavaFiedName());
							if (field == null) {
								sai = new TSalaryAccountItemVo();
								sai.setCnName(dbFiedName);
								sai.setJavaFiedName(scs.getJavaFiedName());
								if (scs.getIsTax() != null) {
									sai.setIsTax(scs.getIsTax());
								} else {
									sai.setIsTax(CommonConstants.ZERO_INT);
								}
								try {
									cellValueBig = new BigDecimal(cellValueStr.replace(",", ""));
									cellValueBig = cellValueBig.setScale(2, BigDecimal.ROUND_HALF_UP); //四舍五入
									if (cellValueBig.toString().length() > 11) {
										if (cellValueBig.toString().length() > 500) {
											errorFlag = false;
											errorList.add(new ErrorMessage((i + dataRow), "文本超长！"));
											continue;
										}
										sai.setTextValue(cellValueBig.toString());
									} else {
										sai.setSalaryMoney(cellValueBig);
									}
								} catch (NumberFormatException e) {
									if (cellValueStr.length() > 500) {
										errorFlag = false;
										errorList.add(new ErrorMessage((i + dataRow), "文本超长！"));
										continue;
									}
									sai.setTextValue(cellValueStr);
								}
								saiList.add(sai);
							} else {
								attr = field.getAnnotation(ExcelAttribute.class);
								fieldType = field.getType();
								if (fieldType == null) {
									continue;
								}
								if (SalaryConstants.SALARY_GIVE_TIME_JAVA.equals(scs.getJavaFiedName())
										&& !SalaryConstants.SALARY_GIVE_TIME.equals(cellValueStr)
										&& !SalaryConstants.SALARY_GIVE_TIME_TWO.equals(cellValueStr)) {
									errorFlag = false;
									errorList.add(new ErrorMessage((i + dataRow), "请注意：工资发放时间，只能是【立即发】或【暂停发】！你的内容：【"+cellValueStr+"】"));
									continue;
								}



								if (SalaryConstants.IS_PERSON_TAX.equals(scs.getJavaFiedName())
										&& !SalaryConstants.IS_COMPANY.equals(cellValueStr)
										&& !SalaryConstants.IS_PERSON_OTHER.equals(cellValueStr)
										&& !SalaryConstants.IS_PERSON.equals(cellValueStr)) {
									errorFlag = false;
									errorList.add(new ErrorMessage((i + dataRow), "请注意：是否个人承担部分税费，只能是【"
											+SalaryConstants.IS_COMPANY+"】或【"+SalaryConstants.IS_PERSON_OTHER+"】或【"
											+SalaryConstants.IS_PERSON+"】！你的内容：【"+cellValueStr+"】"));
									continue;
								}
								setFields(field, cellValueStr, attr, fieldType, entity);
								error = validateUtil(cellValueStr, attr, (i + dataRow));
								if (null != error) {
									errorFlag = false;
									errorList.add(new ErrorMessage((i + dataRow), error));
								}
							}
						}
					}
					if (errorFlag) {
						must = null;
						for (Map.Entry<String, Boolean> entry : isMustMap.entrySet()) {
							if (Boolean.TRUE.equals(entry.getValue())) {
								if (Common.isEmpty(must)) {
									must = entry.getKey();
								} else {
									must = must.concat("、").concat(entry.getKey());
								}
							}
						}
						if (Common.isNotNull(must)) {
							error = "第" + (i + dataRow) + "行：" + must + "列_不可缺少";
							errorList.add(new ErrorMessage((i + dataRow), error));
							continue;
						}
						if (Common.isNotNull(phoneSubsidy)) {
							phoneSubsidyItem = tSalaryEmployeeService.selectByIdcard(newEmp.getEmpIdcard(), nowMonth);
							if (phoneSubsidyItem != null && Common.isNotNull(phoneSubsidyItem.getSalaryMoney())
									&& (phoneSubsidyItem.getSalaryMoney().add(phoneSubsidy)).compareTo(new BigDecimal("300")) > 0) {
								error = "第" + (i + dataRow) + "行：当月已发" + phoneSubsidyItem.getSalaryMoney() + "元，本次发放" + phoneSubsidy + "元，累计超出300元限制，禁止发放！";
								errorList.add(new ErrorMessage((i + dataRow), error));
								continue;
							}
						}
						if (annualBonusFlag && Common.isEmpty(entity.getAnnualBonusType())) {
							error = "第" + (i + dataRow) + "行：年终奖有值，【年终奖扣税方式】需填写【单独】/【合并】";
							errorList.add(new ErrorMessage((i + dataRow), error));
							continue;
						}
						if ("3".equals(salaryType) && actualSalarySum == null) {
							error = "第" + (i + dataRow) + "行：【劳务费】列_不可缺少";
							errorList.add(new ErrorMessage((i + dataRow), error));
							continue;
						}
						if ("3".equals(salaryType) && Common.isEmpty(entity.getIsPersonTax())) {
							error = "第" + (i + dataRow) + "行：【是否个人承担部分税费】列_不可为空";
							errorList.add(new ErrorMessage((i + dataRow), error));
							continue;
						}
						if ("4".equals(salaryType) && actualSalarySum == null) {
							error = "第" + (i + dataRow) + "行：【稿酬】列_不可缺少";
							errorList.add(new ErrorMessage((i + dataRow), error));
							continue;
						}

						// 应发、实发、实发劳务费不可都为空
						if (relaySalary == null && actualSalarySum == null) {
							error = "第" + (i + dataRow) + "行：【应发工资】列_不可缺少";
							errorList.add(new ErrorMessage((i + dataRow), error));
							continue;
						}
						// 版本2.6.6判重：对同一“项目”、同一“结算月份”、同一“报表类型”、同一“工资月份”、同一“身份证号”、同一“应发金额”进行校验
						// 2.6.6:校验导入数据重复的Map格式：#身份证号_工资月份_报表类型_应发金额
						entity.setIsRepeat(CommonConstants.ZERO_INT);
						if (relaySalary != null) {
							relaySalary = relaySalary.setScale(2, BigDecimal.ROUND_HALF_UP);
							if (!checkMap.isEmpty() && checkMap.get(entity.getEmpIdcard() + CommonConstants.DOWN_LINE_STRING + DateUtil.addMonth(configSalary.getSalaryMonth())
									+ CommonConstants.DOWN_LINE_STRING + salaryType + CommonConstants.DOWN_LINE_STRING + relaySalary) != null) {
								entity.setIsRepeat(CommonConstants.ONE_INT);
							}
							if (!CommonConstants.THREE_STRING.equals(salaryType) && !CommonConstants.FOUR_STRING.equals(salaryType)) {
								relaySalarySum = BigDecimalUtils.safeAdd(relaySalary, specialMap.get(entity.getEmpIdcard()));
								if (money3500.compareTo(relaySalarySum) == CommonConstants.ZERO_INT
										|| money5000.compareTo(relaySalarySum) == CommonConstants.ZERO_INT) {
									entity.setHaveSpecialFlag(CommonConstants.ONE_INT);
								}
							}
						}
						if (actualSalarySum != null) {
							actualSalarySum = actualSalarySum.setScale(2, BigDecimal.ROUND_HALF_UP);
							if (!checkMap.isEmpty() && checkMap.get(entity.getEmpIdcard() + CommonConstants.DOWN_LINE_STRING + DateUtil.addMonth(configSalary.getSalaryMonth())
									+ CommonConstants.DOWN_LINE_STRING + salaryType + CommonConstants.DOWN_LINE_STRING + actualSalarySum) != null) {
								entity.setIsRepeat(CommonConstants.ONE_INT);
							}
						}
						if (Common.isNotNull(checkListY) && checkListY.contains(entity.getEmpIdcard())) {
							entity.setHaveSalaryFlag(CommonConstants.ONE_INT);
						}
						if (Common.isNotNull(entity.getSalaryStyle())) {
							salaryStyle = entity.getSalaryStyle();
						} else if (configSalary.getGrantType() != null) {
							salaryStyle = String.valueOf(configSalary.getGrantType());
							entity.setSalaryStyle(salaryStyle);
						}
						// 2021-8-31 hgw2.6.5新增手机号校验
						if (newEmp != null && Common.isNotNull(entity.getEmpPhone()) && Common.isEmpty(newEmp.getEmpPhone())) {
							newEmp.setEmpPhone(entity.getEmpPhone());
						}
						newEmp.setIssueStatus(isIssue);
						// 劳务费要使用人员信息
						if (!notLabour) {
							R<TSalaryEmployee> eR = this.getNewEmp(newEmp, i + dataRow, errorList, notLabour, entity, salaryType, dept, user
									, salaryStyle, salaryGiveTimeFlag, invoiceTitle, tSalaryAccountService
									, tSalaryEmployeeService, bankMap);
							if (eR.getCode() != 200) {
								continue;
							} else {
								emp = eR.getData();
								emp.setLineNums(i);
							}
						} else if (emp == null) {
							newEmpList.add(newEmp);
							entityMap.put(newEmp.getEmpIdcard(), entity);
							otherIdCard.add(newEmp.getEmpIdcard());
						}
						if (emp != null) {
							// 新员工是否更新：0否；1是 hgw 2024-7-18 16:36:31
							// newEmpUpdateFlag = CommonConstants.ZERO_STRING
							if (setEntityByEmpInfo(dept, ownEmployeeMap, ownDeptMap, salaryType, isIssue, errorList
									, entity, emp, saiList, salaryGiveTimeFlag, isNewEmployee, empName, salaryStyle
									, nowMonth, updateEmpList, checkBankInfoEmpList, i + dataRow, bankMap
									, newEmpUpdateFlag, updateEmpBankList, updateEmpBankMap))
								continue;
						}
						if (saiList != null && !saiList.isEmpty()) {
							entity.setSaiList(saiList);
						}
						if (Common.isEmpty(entity.getSalaryStyle())) {
							entity.setSalaryStyle(salaryStyle);
						}
						SalaryCommonUtil.setConfigSalary(configSalary, entity);
						// 填充基本数据
						SalaryCommonUtil.setAccountBaseInfo(salaryType, dept, entity, salaryGiveTimeFlag);
						if ("3".equals(salaryType)) {
							if (CommonConstants.dingleDigitStrArray[1].equals(entity.getIsDeductSocial())
									|| CommonConstants.dingleDigitStrArray[1].equals(entity.getIsDeductFund())) {
								error = "第" + (i + dataRow) + "行：劳务费不可扣社保、公积金，请去除【是否扣除社保】列，或写【否】";
								errorList.add(new ErrorMessage((i + dataRow), error));
								continue;
							} else {
								entity.setIsDeductSocial("0");
								entity.setIsDeductFund("0");
							}
						}
						//通讯补贴导入限制



						//验证扣社保以及扣公积金时的关联关系
						if (CommonConstants.dingleDigitStrArray[1].equals(entity.getIsDeductSocial()) && Common.isEmpty(entity.getDeduSocialMonth())) {
							error = "第" + (i + dataRow) + "行：扣社保无社保扣缴月份";
							errorList.add(new ErrorMessage((i + dataRow), error));
							continue;
						}
						if (CommonConstants.dingleDigitStrArray[1].equals(entity.getIsDeductFund()) && Common.isEmpty(entity.getDeduProvidentMonth())) {
							error = "第" + (i + dataRow) + "行：扣公积金无公积金扣缴月份";
							errorList.add(new ErrorMessage((i + dataRow), error));
							continue;
						}
						entity.setInvoiceTitle(invoiceTitle);
						if (entity != null) {
							tList.add(entity);
						}
					}
				}

				// 统一处理连接查询
				if (updateEmpList != null && !updateEmpList.isEmpty()) {
					doSetIntegerArea(updateEmpList);
					tSalaryEmployeeService.updateBatchById(updateEmpList);
				}
				if (!checkBankInfoEmpList.isEmpty()) {
					// 本次不为代发户，并且薪资人员里的代发户标记没去掉，要校验银行卡
					tSalaryEmployeeService.checkBankInfoList(checkBankInfoEmpList, errorList);
				}
				Map<String, TSalaryEmployee> otherEmpMap = new HashMap<>();
				if (!otherIdCard.isEmpty()) {
					otherEmpMap = tSalaryEmployeeService.getByEmpIdCardList(otherIdCard);
				}
				TSalaryEmployee otherEmp;
				List<TSalaryEmployee> saveNewEmpList = new ArrayList<>();
				List<String> checkTaxMonthList = new ArrayList<>();
				boolean isContinue = true;

				if (!newEmpList.isEmpty()) {
					TSalaryEmployee newEmps;
					for (int i = 0; i < newEmpList.size(); i++) {
						newEmps = newEmpList.get(i);
						entity = entityMap.get(newEmps.getEmpIdcard());
						// 先按照身份证查询
						otherEmp = otherEmpMap.get(newEmps.getEmpIdcard());
						if (otherEmp == null) {
							if (CommonConstants.ONE_STRING.equals(entity.getIsNewEmployee())) {
								// 赋值新员工信息
								if (!this.setNewEmpBase(newEmps, newEmps.getLineNums() + dataRow, errorList, notLabour
										, entity, salaryType, dept, user, entity.getSalaryStyle()
										, CommonConstants.ZERO_STRING.equals(entity.getSalaryGiveTime()), invoiceTitle
										, entity.getSaiList(), bankMap)) {
									isContinue = false;
									continue;
								}
								newEmps.setSalaryGiveTime(entity.getSalaryGiveTime());
								saveNewEmpList.add(newEmps);
								checkTaxMonthList.add(newEmps.getEmpIdcard());
							} else {
								if ("3".equals(salaryType) || "4".equals(salaryType)) {
									error = "第" + (newEmps.getLineNums() + dataRow) + "行：薪酬人员查询菜单无此员工，请添加<是否新员工>列，并录入身份证号、开户行总行、开户行省、开户行市、银行卡号、手机号码！";
									errorList.add(new ErrorMessage((newEmps.getLineNums() + dataRow), error));
								} else {
									error = "第" + (newEmps.getLineNums() + dataRow) + "行：薪酬人员查询菜单无此员工，请添加<是否新员工（默认否）>列，并录入身份证号、开户行总行、开户行省、开户行市、银行卡号、计税月份、手机号码！";
									errorList.add(new ErrorMessage(newEmps.getLineNums() + dataRow, error));
								}
								isContinue = false;
							}
						} else {
							// 使用emp信息
							if (setEntityByEmpInfo(dept, ownEmployeeMap, ownDeptMap, salaryType, isIssue, errorList
									, entity, otherEmp, entity.getSaiList()
									, CommonConstants.ZERO_STRING.equals(entity.getSalaryGiveTime())
									, CommonConstants.ONE_STRING.equals(entity.getIsNewEmployee())
									, otherEmp.getEmpName(), entity.getSalaryStyle()
									, nowMonth, updateEmpList, checkBankInfoEmpList, newEmps.getLineNums() + dataRow
									, bankMap, newEmpUpdateFlag, updateEmpBankList, updateEmpBankMap)) {
								isContinue = false;
							}
						}
					}
				}
				if (isContinue) {
					int nowYear = Integer.parseInt(nowMonth.substring(0, 4));
					Map<String, String> minTaxMonthMap = tSalaryAccountService.getMinTaxMonthByNowYearAndList(checkTaxMonthList, nowYear);
					String minTaxMonth;
					boolean canSave = true;
					if (!saveNewEmpList.isEmpty()) {
						TSalaryEmployee saveNewEmp;
						for (int i = 0; i < saveNewEmpList.size(); i++) {
							saveNewEmp = saveNewEmpList.get(i);
							// 新员工校验计税月
							if (!"3".equals(salaryType) && !"4".equals(salaryType)) {
								entity = entityMap.get(saveNewEmp.getEmpIdcard());
								minTaxMonth = minTaxMonthMap.get(saveNewEmp.getEmpIdcard());
								if (Common.isNotNull(minTaxMonth)
										&& !minTaxMonth.equals(entity.getTaxMonth())) {
									error = "第" + (saveNewEmp.getLineNums() + dataRow) + "行：该员工已有发薪记录，计税月份请填写：【" + minTaxMonth + "】" + "，你填写了计税月：【" + entity.getTaxMonth() + "】";
									errorList.add(new ErrorMessage((saveNewEmp.getLineNums() + dataRow), error));
									canSave = false;
								}
							}
						}
					}
					if (!updateEmpBankList.isEmpty()) {
						TSalaryEmployee saveNewEmp;
						for (int i = 0; i < updateEmpBankList.size(); i++) {
							saveNewEmp = updateEmpBankList.get(i);
							// 新员工校验计税月
							if (!"3".equals(salaryType) && !"4".equals(salaryType)) {
								entity = entityMap.get(saveNewEmp.getEmpIdcard());
								minTaxMonth = minTaxMonthMap.get(saveNewEmp.getEmpIdcard());
								if (Common.isNotNull(minTaxMonth)
										&& !minTaxMonth.equals(entity.getTaxMonth())) {
									error = "第" + (saveNewEmp.getLineNums() + dataRow) + "行：该员工已有发薪记录，计税月份请填写：【" + minTaxMonth + "】" + "，你填写了计税月：【" + entity.getTaxMonth() + "】";
									errorList.add(new ErrorMessage((saveNewEmp.getLineNums() + dataRow), error));
									canSave = false;
								}
							}
						}
					}
					if (canSave) {
						// 查本表重
						Map<String, Integer> phoneExcelMap = new HashMap<>();
						// 新增
						if (!saveNewEmpList.isEmpty()) {
							tSalaryEmployeeService.saveNewEmployeeList(saveNewEmpList, errorList, phoneExcelMap);
						}
						// 更新人员信息
						if (!updateEmpBankList.isEmpty()) {
							tSalaryEmployeeService.updateEmployeeBankList(updateEmpBankList, updateEmpBankMap, errorList, phoneExcelMap);
						}
						if (phoneExcelMap != null && !phoneExcelMap.isEmpty()) {
							phoneExcelMap.clear();
						}
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error("将jsonString数据源的数据导入到list异常!");
			throw new ExcelException("工资导入-将jsonString数据源的数据导入到list异常!", e);
		}
		this.setEntityList(tList);
		this.setErrorInfo(errorList);
	}

	// 批量处理字段为汉字的区域
	private void doSetIntegerArea(List<TSalaryEmployee> updateEmpList) {
		String areaProvince;
		String areaCity;
		for (TSalaryEmployee employee : updateEmpList) {
			if (Common.isNotNull(employee.getBankProvince()) && regNumber(employee.getBankProvince())) {
				areaProvince = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + employee.getBankProvince().trim());
				if (Common.isNotNull(areaProvince)) {
					if (Common.isNotNull(employee.getBankCity()) && regNumber(employee.getBankCity())) {
						areaCity = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + employee.getBankCity().trim()
								+ CommonConstants.DOWN_LINE_STRING + employee.getBankProvince().trim());
						if (Common.isNotNull(areaCity)) {
							employee.setBankCity(areaCity);
						}
					}
					employee.setBankProvince(areaProvince);
				}
			}
		}
	}

	private static boolean regNumber(String content) {
		boolean flag = true;
		Pattern p = Pattern.compile("^[0-9]*$");
		Matcher m = p.matcher(content);
		if (m.matches()) {
			flag = false;
		}
		return flag;
	}

	// updateEmpBankList hgw 2024-7-22 10:18:02 更新开户行卡号等信息，以表导入为准
	private boolean setEntityByEmpInfo(TSettleDomainSelectVo dept, Map<String, Integer> ownEmployeeMap
			, Map<String, Integer> ownDeptMap, String salaryType, Integer isIssue, List<ErrorMessage> errorList
			, TSalaryAccountVo entity, TSalaryEmployee emp, List<TSalaryAccountItemVo> saiList
			, boolean salaryGiveTimeFlag, boolean isNewEmployee, String empName, String salaryStyle, String nowMonth
			, List<TSalaryEmployee> updateEmpList, List<TSalaryEmployee> checkBankInfoEmpList, int i
			, Map<String, String> bankMap, String newEmpUpdateFlag, List<TSalaryEmployee> updateEmpBankList
			, Map<String, TSalaryEmployee> updateEmpBankMap) {
		TSalaryAccountItemVo sai;
		String error;
		emp.setLineNums(i);
		if (dept != null && dept.getId() != null && !dept.getId().equals(emp.getDeptId())) {
			emp.setDeptId(dept.getId());
			emp.setDeptName(dept.getDepartName());
			emp.setDeptNo(dept.getDepartNo());
			emp.setUnitId(dept.getCustomerId());
			emp.setUnitNo(dept.getCustomerNo());
			emp.setUnitName(dept.getCustomerName());
		}
		if (Common.isEmpty(emp.getEmpName())) {
			error = "第" + i + "行：薪酬人员查询处-员工姓名-为空，请去薪酬人员查询处更新！";
			errorList.add(new ErrorMessage(i, error));
			return true;
		} else if (Common.isEmpty(empName)) {
			error = "第" + i + "行：模板-员工姓名-为空，请添加员工姓名列！";
			errorList.add(new ErrorMessage(i, error));
			return true;
		} else if (!empName.equals(emp.getEmpName())) {
			error = "第" + i + "行：员工-姓名与身份证-不匹配，请确认薪酬人员查询处信息！";
			errorList.add(new ErrorMessage(i, error));
			return true;
		}
		if (Common.isEmpty(emp.getEmpPhone())) {
			error = "第" + i + "行：薪酬人员查询处-手机号码-为空，请去薪酬人员查询处更新！";
			errorList.add(new ErrorMessage(i, error));
			return true;
		} else if (!ValidityUtil.validateEmpPhone(emp.getEmpPhone())) {
			error = "第" + i + "行：薪酬人员查询处-手机号码格式错误，请去薪酬人员查询处更新:" + emp.getEmpPhone();
			errorList.add(new ErrorMessage(i, error));
			return true;
		}
		if (Common.isEmpty(emp.getTaxMonth()) && !"3".equals(salaryType) && !"4".equals(salaryType)) {
			if (Common.isNotNull(entity.getTaxMonth())) {
				if (entity.getTaxMonth().length() > CommonConstants.dingleDigitIntArray[6]) {
					entity.setTaxMonth(emp.getTaxMonth().substring(0, 6));
				} else if (entity.getTaxMonth().length() < CommonConstants.dingleDigitIntArray[6]) {
					error = "第" + i + "行：工资模板里-计税月份-长度小于6：" + entity.getTaxMonth() + "，请在工资模板修改！";
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				if (DateUtil.compareYearMonth(entity.getTaxMonth(), nowMonth)) {
					error = "第" + i + "行：工资模板里-计税月份-大于当前年月或错误，请调整：" + entity.getTaxMonth();
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				emp.setTaxMonth(entity.getTaxMonth());
				updateEmpList.add(emp);
			} else {
				error = "第" + i + "行：薪酬人员查询处-计税月份-为空，请在工资模板填写-计税月份-列的内容！";
				errorList.add(new ErrorMessage(i, error));
				return true;
			}
		}
		if (ownEmployeeMap.get(emp.getEmpIdcard()) != null
				|| (isNewEmployee && ownDeptMap.get(dept.getId()) != null)) {
			// 自有员工
			entity.setOwnFlag(CommonConstants.ONE_INT);
		} else {
			// 普通员工
			entity.setOwnFlag(CommonConstants.ZERO_INT);
		}
		entity.setProvince(dept.getProvince());
		entity.setCity(dept.getCity());
		entity.setTown(dept.getTown());

		// 本次不为代发户，并且薪资人员里的代发户标记没去掉，要校验银行卡
		if (isIssue == 0 && Common.isNotNull(emp.getBankNo())
				&& Common.isNotNull(emp.getIssueStatus())
				&& CommonConstants.ONE_INT == emp.getIssueStatus()) {
			checkBankInfoEmpList.add(emp);
		}

		// cyx-mvp1.7.0： 新增：本次是代发户，是新员工，要校验银行卡
//		if (isIssue == 1 && isNewEmployee && Common.isNotNull(emp.getBankNo())) {
//			checkBankInfoEmpList.add(emp);
//		}

		entity.setEmpId(emp.getId());
		entity.setEmpIdcard(emp.getEmpIdcard());
		entity.setEmpName(emp.getEmpName());

		// hgs 2024-7-19 09:33:29 新增按照页面开关与新员工字段，来更新员工信息：
		if (SalaryConstants.SALARY_STYLE_BANK.equals(salaryStyle)) {
			if (CommonConstants.ONE_STRING.equals(newEmpUpdateFlag) && isNewEmployee) {
				TSalaryEmployee oldEmp = new TSalaryEmployee();
				BeanUtil.copyProperties(emp,oldEmp);
				updateEmpBankMap.put(emp.getEmpIdcard(), oldEmp);
				if (Common.isEmpty(entity.getBankName())) {
					if (Common.isEmpty(emp.getBankName())) {
						error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-开户行总行-为空，请在工资模板正确填写！";
						errorList.add(new ErrorMessage(i, error));
						return true;
					} else {
						entity.setBankName(emp.getBankName());
					}
				} else {
					emp.setBankName(entity.getBankName());
				}
				if (Common.isEmpty(entity.getBankNo())) {
					if (Common.isEmpty(emp.getBankNo())) {
						error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-银行卡号-为空，请在工资模板正确填写！";
						errorList.add(new ErrorMessage(i, error));
						return true;
					} else {
						entity.setBankNo(emp.getBankNo());
					}
				} else {
					emp.setBankNo(entity.getBankNo());
				}
				if (Common.isEmpty(entity.getBankProvince())) {
					if (Common.isEmpty(emp.getBankProvince())) {
						error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-开户行省-为空，请在工资模板正确填写！";
						errorList.add(new ErrorMessage(i, error));
						return true;
					} else {
						entity.setBankProvince(String.valueOf(emp.getBankProvince()));
					}
				} else {
					emp.setBankProvince(entity.getBankProvince());
				}
				if (Common.isEmpty(entity.getBankCity())) {
					if (Common.isEmpty(emp.getBankCity())) {
						error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-开户行市-为空，请在工资模板正确填写！";
						errorList.add(new ErrorMessage(i, error));
						return true;
					} else {
						entity.setBankCity(String.valueOf(emp.getBankCity()));
					}
				} else {
					emp.setBankCity(entity.getBankCity());
				}

				if (Common.isNotNull(emp.getBankProvince())) {
					String areaInt = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + emp.getBankProvince().trim());
					if (Common.isNotNull(areaInt)) {
						entity.setBankProvince(areaInt);
					} else {
						error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-开户行省错误，请在工资模板正确填写！";
						errorList.add(new ErrorMessage(i, error));
						return true;
					}
					String areaCityInt = null;
					if (Common.isNotNull(emp.getBankCity())) {
						areaCityInt = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + emp.getBankCity().trim()
								+ CommonConstants.DOWN_LINE_STRING + emp.getBankProvince().trim());
						if (Common.isNotNull(areaCityInt)) {
							entity.setBankCity(areaCityInt);
						} else {
							error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-开户行市错误或开户行市不在开户行省内，请在工资模板正确填写！";
							errorList.add(new ErrorMessage(i, error));
							return true;
						}
					}
				}

				if (Common.isEmpty(entity.getBankSubName()) ){
					if (Common.isNotNull(emp.getBankSubName())) {
						entity.setBankSubName(emp.getBankSubName());
					}
				} else {
					emp.setBankSubName(entity.getBankSubName());
				}
				if (bankMap.get(entity.getBankName()) == null) {
					error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-开户行总行-不符合财务要求，请在工资模板正确填写！";
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				// 2025-8-5 17:29:33 以本表为准，且写了是新员工，新增手机号也用表里的 倩倩与荣珍同意
				if (Common.isNotNull(entity.getEmpPhone())){
					emp.setEmpPhone(entity.getEmpPhone());
				} else {
					error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-新员工以本次导入为准，手机号不可为空，请在工资模板正确填写！";
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				updateEmpBankList.add(emp);
			} else if (salaryGiveTimeFlag) {
				if (Common.isEmpty(emp.getBankName())) {
					error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-开户行-为空，请去薪酬人员查询处更新！";
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				if (Common.isEmpty(emp.getBankNo())) {
					error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-银行卡号-为空，请去薪酬人员查询处更新！";
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				if (Common.isEmpty(emp.getBankProvince())) {
					error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-开户行省-为空，请去薪酬人员查询处更新！";
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				if (Common.isEmpty(emp.getBankCity())) {
					error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-开户行市-为空，请去薪酬人员查询处更新！";
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				if (bankMap.get(emp.getBankName()) == null) {
					error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-开户行总行-不符合财务要求，请去薪酬人员查询处更新！";
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				if (Common.isEmpty(emp.getEmpPhone())) {
					error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-手机号-为空，请去薪酬人员查询处更新！";
					errorList.add(new ErrorMessage(i, error));
					return true;
				}
				entity.setBankName(emp.getBankName());
				entity.setBankNo(emp.getBankNo());
				entity.setBankProvince(String.valueOf(emp.getBankProvince()));
				entity.setBankCity(String.valueOf(emp.getBankCity()));
				entity.setBankSubName(emp.getBankSubName());
				entity.setEmpPhone(emp.getEmpPhone());
			} else {
				if (Common.isNotNull(emp.getBankName())) {
					if (bankMap.get(emp.getBankName()) == null) {
						error = "第" + i + SalaryConstants.LINE_EMP + emp.getEmpIdcard() + "-发放方式为银行发放，但是-开户行总行-不符合财务要求，请去薪酬人员查询处更新！";
						errorList.add(new ErrorMessage(i, error));
						return true;
					}
					entity.setBankName(emp.getBankName());
				} else {
					entity.setBankName(null);
				}
				if (Common.isNotNull(emp.getBankNo())) {
					entity.setBankNo(emp.getBankNo());
				} else {
					entity.setBankNo(null);
				}
				if (Common.isNotNull(emp.getBankSubName())) {
					entity.setBankSubName(emp.getBankSubName());
				} else {
					entity.setBankSubName(null);
				}
				if (Common.isNotNull(emp.getBankProvince())) {
					entity.setBankProvince(String.valueOf(emp.getBankProvince()));
				} else {
					entity.setBankProvince(null);
				}
				if (Common.isNotNull(emp.getBankCity())) {
					entity.setBankCity(String.valueOf(emp.getBankCity()));
				} else {
					entity.setBankCity(null);
				}
				entity.setEmpPhone(emp.getEmpPhone());
			}
		} else {
			entity.setEmpPhone(emp.getEmpPhone());
		}
		if (!"3".equals(salaryType) && !"4".equals(salaryType)) {
			if (emp.getTaxMonth().length() > CommonConstants.dingleDigitIntArray[6]) {
				entity.setTaxMonth(emp.getTaxMonth().substring(0, 6));
			} else if (emp.getTaxMonth().length() < CommonConstants.dingleDigitIntArray[6]) {
				error = "第" + i + "行：薪酬人员查询处-计税月份-长度小于6：" + entity.getTaxMonth() + "，请去薪酬人员查询处更新！在工资模板修改无效！";
				errorList.add(new ErrorMessage(i, error));
				return true;
			} else {
				entity.setTaxMonth(emp.getTaxMonth());
			}
			if (DateUtil.compareYearMonth(entity.getTaxMonth(), nowMonth)) {
				error = "第" + i + "行：薪酬人员查询处-计税月份-大于当前年月或错误，请去薪酬人员查询处调整：" + entity.getTaxMonth();
				errorList.add(new ErrorMessage(i, error));
				return true;
			}
			sai = new TSalaryAccountItemVo();
			sai.setCnName(SalaryConstants.COST_REDUCTION);
			sai.setJavaFiedName(SalaryConstants.COST_REDUCTION_JAVA);
			sai.setSalaryMoney(DateUtil.getTaxMonthMoney(entity.getTaxMonth()));
			sai.setIsTax(CommonConstants.ZERO_INT);
			saiList.add(sai);
		}
		return false;
	}

	/**
	 * @Description: 处理表里人员相关数据
	 * @Author: hgw
	 * @Date: 2022/11/9 16:07
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryEmployee>
	 **/
	private R<TSalaryEmployee> getNewEmp(TSalaryEmployee newEmp, int i, List<ErrorMessage> errorList, boolean notLabour
			, TSalaryAccountVo entity, String salaryType, TSettleDomainSelectVo dept, YifuUser user, String salaryStyle
			, boolean salaryGiveTimeFlag, String invoiceTitle, TSalaryAccountService tSalaryAccountService
			, TSalaryEmployeeService tSalaryEmployeeService, Map<String, String> bankMap) {
		String newEmpStr = "新员工";
		if (!notLabour) {
			newEmpStr = "劳务费";
		}
		String error;
		String nowMonth = DateUtil.addMonth(CommonConstants.ZERO_INT);
		//增加工资人员档案：（临时使用）
		if (newEmp != null) {
			if (Common.isEmpty(newEmp.getEmpName())) {
				error = "第" + i + "行：" + newEmpStr + "-姓名-不可为空！";
				errorList.add(new ErrorMessage(i, error));
				return R.failed();
			}
			if (Common.isEmpty(newEmp.getEmpIdcard())) {
				error = "第" + i + "行：" + newEmpStr + "-身份证号-不可为空！";
				errorList.add(new ErrorMessage(i, error));
				return R.failed();
			}

			// 2021-8-31 hgw2.6.5新增手机号校验
			if (Common.isEmpty(newEmp.getEmpPhone())) {
				error = "第" + i + "行：" + newEmpStr + "-手机号码-不可为空！";
				errorList.add(new ErrorMessage(i, error));
				return R.failed();
			} else if (!ValidityUtil.validateEmpPhone(newEmp.getEmpPhone())) {
				error = "第" + i + "行：" + newEmpStr + "-手机号码格式错误：" + newEmp.getEmpPhone();
				errorList.add(new ErrorMessage(i, error));
				return R.failed();
			}
		} else {
			newEmp = new TSalaryEmployee();
		}
		if (entity != null) {
			if (!"3".equals(salaryType) && !"4".equals(salaryType)) {
				if (Common.isEmpty(entity.getTaxMonth())) {
					error = "第" + i + "行：" + newEmpStr + "-计税月份-不可为空！";
					errorList.add(new ErrorMessage(i, error));
					return R.failed();
				} else if (entity.getTaxMonth().length() < CommonConstants.dingleDigitIntArray[6]) {
					error = "第" + i + "行：" + newEmpStr + "-计税月份-长度小于6：" + entity.getTaxMonth();
					errorList.add(new ErrorMessage(i, error));
					return R.failed();
				} else if (DateUtil.compareYearMonth(entity.getTaxMonth(), nowMonth)) {
					error = "第" + i + "行：" + newEmpStr + "-计税月份-大于当前年月或错误，请调整：" + entity.getTaxMonth();
					errorList.add(new ErrorMessage(i, error));
					return R.failed();
				} else {
					newEmp.setTaxMonth(entity.getTaxMonth());
				}
			}
			//工资发放方式（0现金/1银行）/2线下 && salaryGiveTime == true :立即发；false：暂停发：则不考虑开户行等
			//银行+立即发，则考虑和开户行卡号
			String areaStr;
			if (SalaryConstants.SALARY_STYLE_BANK.equals(salaryStyle) && salaryGiveTimeFlag) {
				if (Common.isEmpty(entity.getBankName())) {
					error = "第" + i + "行：" + newEmpStr + "-开户行总行-不可为空！";
					errorList.add(new ErrorMessage(i, error));
					return R.failed();
				} else {
					if (bankMap.get(entity.getBankName()) == null) {
						error = "第" + i + "行：" + newEmpStr + "-开户行总行-不符合财务要求，请去【开户行配置】菜单查询！";
						errorList.add(new ErrorMessage(i, error));
						return R.failed();
					}
					newEmp.setBankName(entity.getBankName());
				}
				if (Common.isEmpty(entity.getBankProvince()) || Common.isEmpty(entity.getBankCity())) {
					error = "第" + i + "行：" + newEmpStr + "-开户行省、市-不可为空！";
					errorList.add(new ErrorMessage(i, error));
					return R.failed();
				} else {
					areaStr = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + entity.getBankProvince().trim());
					if (Common.isNotNull(areaStr)) {
						newEmp.setBankProvince(areaStr);
					} else {
						error = "第" + i + "行：" + newEmpStr + "-开户行省错误：" + entity.getBankProvince();
						errorList.add(new ErrorMessage(i, error));
						return R.failed();
					}
					areaStr = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + entity.getBankCity().trim()
							+ CommonConstants.DOWN_LINE_STRING + entity.getBankProvince().trim());
					if (Common.isNotNull(areaStr)) {
						newEmp.setBankCity(areaStr);
					} else {
						error = "第" + i + "行：" + newEmpStr + "-开户行市错误：" + entity.getBankCity();
						errorList.add(new ErrorMessage(i, error));
						return R.failed();
					}
				}
				if (Common.isEmpty(entity.getBankNo())) {
					error = "第" + i + "行：" + newEmpStr + "-银行卡号-不可为空！";
					errorList.add(new ErrorMessage(i, error));
					return R.failed();
				} else {
					newEmp.setBankNo(entity.getBankNo());
				}
				if (Common.isNotNull(entity.getBankSubName())) {
					newEmp.setBankSubName(entity.getBankSubName());
				}
			} else {
				if (Common.isNotNull(entity.getBankName())) {
					if (bankMap.get(entity.getBankName()) == null) {
						error = "第" + i + "行：" + newEmpStr + "-开户行总行-不符合财务要求，请去【开户行配置】菜单查询！";
						errorList.add(new ErrorMessage(i, error));
						return R.failed();
					}
					newEmp.setBankName(entity.getBankName());
				}
				if (Common.isNotNull(entity.getBankNo())) {
					newEmp.setBankNo(entity.getBankNo());
				}
				if (Common.isNotNull(entity.getBankSubName())) {
					newEmp.setBankSubName(entity.getBankSubName());
				}
				if (Common.isNotNull(entity.getBankProvince())) {
					areaStr = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + entity.getBankProvince().trim());
					if (Common.isNotNull(areaStr)) {
						newEmp.setBankProvince(areaStr);
					}
					if (Common.isNotNull(entity.getBankCity())) {
						areaStr = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + entity.getBankCity().trim()
								+ CommonConstants.DOWN_LINE_STRING + entity.getBankProvince().trim());
						if (Common.isNotNull(areaStr)) {
							newEmp.setBankCity(areaStr);
						}
					}
				}
			}
		}
		newEmp.setFileStatus(CommonConstants.ZERO_STRING);  //临时
		newEmp.setDeptId(dept.getId());
		newEmp.setDeptName(dept.getDepartName());
		newEmp.setDeptNo(dept.getDepartNo());
		newEmp.setUnitId(dept.getCustomerId());
		newEmp.setUnitName(dept.getCustomerName());
		newEmp.setUnitNo(dept.getCustomerCode());
		newEmp.setCreateBy(String.valueOf(user.getId()));
		newEmp.setCreateName(user.getNickname());
		newEmp.setInvoiceTitle(invoiceTitle);
		if (!"3".equals(salaryType) && !"4".equals(salaryType)) {
			int nowYear = Integer.parseInt(nowMonth.substring(0, 4));
			String minTaxMonth = tSalaryAccountService.getMinTaxMonthByNowYear(newEmp.getEmpIdcard(), nowYear);
			if (Common.isNotNull(minTaxMonth)
					&& !minTaxMonth.equals(entity.getTaxMonth())) {
				error = "第" + i + "行：该员工已有发薪记录，计税月份请填写：【" + minTaxMonth + "】" + "，你填写了计税月：【" + entity.getTaxMonth() + "】";
				errorList.add(new ErrorMessage(i, error));
				return R.failed();
			}
		}
		String saveNewEmpReturn = tSalaryEmployeeService.saveNewSalaryEmployee(notLabour, newEmp);
		if (Common.isNotNull(saveNewEmpReturn)) {
			error = "第" + i + "行：该员工新建失败：【" + saveNewEmpReturn + "】";
			errorList.add(new ErrorMessage(i, error));
			return R.failed();
		}
		return R.ok(newEmp);
	}

	private boolean setNewEmpBase(TSalaryEmployee newEmp, int i, List<ErrorMessage> errorList, boolean notLabour
			, TSalaryAccountVo entity, String salaryType, TSettleDomainSelectVo dept, YifuUser user, String salaryStyle
			, boolean salaryGiveTimeFlag, String invoiceTitle, List<TSalaryAccountItemVo> saiList, Map<String, String> bankMap) {
		String newEmpStr = "新员工";
		if (!notLabour) {
			newEmpStr = "劳务费";
		}
		String error;
		String nowMonth = DateUtil.addMonth(CommonConstants.ZERO_INT);
		//增加工资人员档案：（临时使用）
		if (newEmp != null) {
			newEmp.setLineNums(i);
			if (Common.isEmpty(newEmp.getEmpName())) {
				error = "第" + i + "行：" + newEmpStr + "-姓名-不可为空！";
				errorList.add(new ErrorMessage(i, error));
				return false;
			}
			if (Common.isEmpty(newEmp.getEmpIdcard())) {
				error = "第" + i + "行：" + newEmpStr + "-身份证号-不可为空！";
				errorList.add(new ErrorMessage(i, error));
				return false;
			}

			// 2021-8-31 hgw2.6.5新增手机号校验
			if (Common.isEmpty(newEmp.getEmpPhone())) {
				error = "第" + i + "行：" + newEmpStr + "-手机号码-不可为空！";
				errorList.add(new ErrorMessage(i, error));
				return false;
			} else if (!ValidityUtil.validateEmpPhone(newEmp.getEmpPhone())) {
				error = "第" + i + "行：" + newEmpStr + "-手机号码格式错误：" + newEmp.getEmpPhone();
				errorList.add(new ErrorMessage(i, error));
				return false;
			}
		} else {
			newEmp = new TSalaryEmployee();
		}
		if (entity != null) {
			if (!"3".equals(salaryType) && !"4".equals(salaryType)) {
				if (Common.isEmpty(entity.getTaxMonth())) {
					error = "第" + i + "行：" + newEmpStr + "-计税月份-不可为空！";
					errorList.add(new ErrorMessage(i, error));
					return false;
				} else if (entity.getTaxMonth().length() < CommonConstants.dingleDigitIntArray[6]) {
					error = "第" + i + "行：" + newEmpStr + "-计税月份-长度小于6：" + entity.getTaxMonth();
					errorList.add(new ErrorMessage(i, error));
					return false;
				} else if (DateUtil.compareYearMonth(entity.getTaxMonth(), nowMonth)) {
					error = "第" + i + "行：" + newEmpStr + "-计税月份-大于当前年月或错误，请调整：" + entity.getTaxMonth();
					errorList.add(new ErrorMessage(i, error));
					return false;
				} else {
					TSalaryAccountItemVo sai = new TSalaryAccountItemVo();
					sai.setCnName(SalaryConstants.COST_REDUCTION);
					sai.setJavaFiedName(SalaryConstants.COST_REDUCTION_JAVA);
					sai.setSalaryMoney(DateUtil.getTaxMonthMoney(entity.getTaxMonth()));
					sai.setIsTax(CommonConstants.ZERO_INT);
					saiList.add(sai);
					newEmp.setTaxMonth(entity.getTaxMonth());
				}
			}
			//工资发放方式（0现金/1银行）/2线下 && salaryGiveTime == true :立即发；false：暂停发：则不考虑开户行等
			//银行+立即发，则考虑和开户行卡号
			String areaStr;
			if (SalaryConstants.SALARY_STYLE_BANK.equals(salaryStyle) && salaryGiveTimeFlag) {
				if (Common.isEmpty(entity.getBankName())) {
					error = "第" + i + "行：" + newEmpStr + "-开户行总行-不可为空！";
					errorList.add(new ErrorMessage(i, error));
					return false;
				} else {
					if (bankMap.get(entity.getBankName()) == null) {
						error = "第" + i + "行：" + newEmpStr + "-开户行总行-不符合财务要求，请去【开户行配置】菜单查询！";
						errorList.add(new ErrorMessage(i, error));
						return false;
					}
					newEmp.setBankName(entity.getBankName());
				}
				if (Common.isEmpty(entity.getBankProvince()) || Common.isEmpty(entity.getBankCity())) {
					error = "第" + i + "行：" + newEmpStr + "-开户行省、市-不可为空！";
					errorList.add(new ErrorMessage(i, error));
					return false;
				} else {
					areaStr = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + entity.getBankProvince().trim());
					if (Common.isNotNull(areaStr)) {
						newEmp.setBankProvince(areaStr);
					} else {
						error = "第" + i + "行：" + newEmpStr + "-开户行省错误：" + entity.getBankProvince();
						errorList.add(new ErrorMessage(i, error));
						return false;
					}
					areaStr = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + entity.getBankCity().trim()
							+ CommonConstants.DOWN_LINE_STRING + entity.getBankProvince().trim());
					if (Common.isNotNull(areaStr)) {
						newEmp.setBankCity(areaStr);
					} else {
						error = "第" + i + "行：" + newEmpStr + "-开户行市错误：" + entity.getBankCity();
						errorList.add(new ErrorMessage(i, error));
						return false;
					}
				}
				if (Common.isEmpty(entity.getBankNo())) {
					error = "第" + i + "行：" + newEmpStr + "-银行卡号-不可为空！";
					errorList.add(new ErrorMessage(i, error));
					return false;
				} else {
					newEmp.setBankNo(entity.getBankNo());
				}
				if (Common.isNotNull(entity.getBankSubName())) {
					newEmp.setBankSubName(entity.getBankSubName());
				}
			} else {
				if (Common.isNotNull(entity.getBankName())) {
					if (bankMap.get(entity.getBankName()) == null) {
						error = "第" + i + "行：" + newEmpStr + "-开户行总行-不符合财务要求，请去【开户行配置】菜单查询！";
						errorList.add(new ErrorMessage(i, error));
						return false;
					}
					newEmp.setBankName(entity.getBankName());
				}
				if (Common.isNotNull(entity.getBankNo())) {
					newEmp.setBankNo(entity.getBankNo());
				}
				if (Common.isNotNull(entity.getBankSubName())) {
					newEmp.setBankSubName(entity.getBankSubName());
				}
				if (Common.isNotNull(entity.getBankProvince())) {
					areaStr = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + entity.getBankProvince().trim());
					if (Common.isNotNull(areaStr)) {
						newEmp.setBankProvince(areaStr);
					} else {
						error = "第" + i + "行：" + newEmpStr + "-开户行省错误：" + entity.getBankProvince();
						errorList.add(new ErrorMessage(i, error));
						return false;
					}
					if (Common.isNotNull(entity.getBankCity())) {
						areaStr = ExcelUtil.getRedisAreaValue(CacheConstants.AREA_VALUE + entity.getBankCity().trim()
								+ CommonConstants.DOWN_LINE_STRING + entity.getBankProvince().trim());
						if (Common.isNotNull(areaStr)) {
							newEmp.setBankCity(areaStr);
						} else {
							error = "第" + i + "行：" + newEmpStr + "-开户行市错误：" + entity.getBankCity();
							errorList.add(new ErrorMessage(i, error));
							return false;
						}
					}
				}
			}
		}
		entity.setBankProvince(String.valueOf(newEmp.getBankProvince()));
		entity.setBankCity(String.valueOf(newEmp.getBankCity()));
		newEmp.setFileStatus(CommonConstants.ZERO_STRING);  //临时
		newEmp.setDeptId(dept.getId());
		newEmp.setDeptName(dept.getDepartName());
		newEmp.setDeptNo(dept.getDepartNo());
		newEmp.setUnitId(dept.getCustomerId());
		newEmp.setUnitName(dept.getCustomerName());
		newEmp.setUnitNo(dept.getCustomerCode());
		newEmp.setCreateBy(String.valueOf(user.getId()));
		newEmp.setCreateName(user.getNickname());
		newEmp.setInvoiceTitle(invoiceTitle);
		return true;
	}

	/**
	 * 按类型统一返回String内容
	 *
	 * @param param
	 * @return
	 */
	private static String getStringValByObject(Object param) {
		if (null == param) {
			return null;
		} else if (param instanceof Integer) {
			return Integer.toString(((Integer) param).intValue());
		} else if (param instanceof String) {
			return (String) param;
		} else if (param instanceof Double) {
			return Double.toString(((Double) param).doubleValue());
		} else if (param instanceof Float) {
			return Float.toString(((Float) param).floatValue());
		} else if (param instanceof Long) {
			return Long.toString(((Long) param).longValue());
		} else if (param instanceof Boolean) {
			return Boolean.toString(((Boolean) param).booleanValue());
		} else if (param instanceof Date) {
			return DateUtil.dateToString((Date) param);
		} else if (param instanceof LocalDateTime) {
			return LocalDateTimeUtils.formatTime((LocalDateTime) param, DateUtil.DATETIME_PATTERN_SECOND);
		} else {
			return param.toString();
		}
	}

	/**
	 * 根据属性名获取属性值
	 *
	 * @param fieldName
	 * @param hashMap
	 * @return
	 */
	private static Object getFieldValueByName(String fieldName, HashMap<String, Object> hashMap) {
		try {
			return hashMap.get(fieldName);
		} catch (Exception e) {
			return null;
		}
	}

	/**
	 * 输出错误数据
	 *
	 * @param attr
	 * @param msg
	 * @param i
	 * @return
	 */
	private String errorInfo(ExcelAttribute attr, String msg, Integer i) {
		if (Common.isNotNull(msg)) {
			return "第" + i + "行：" + attr.name() + msg;
		} else if (Common.isNotNull(attr.errorInfo())) {
			return "第" + i + "行：" + attr.errorInfo();
		}
		return "";
	}

	/**
	 * 实现各种校验方式的错误返回新
	 *
	 * @param c
	 * @param attr
	 * @param i
	 * @return
	 */
	public String validateUtil(String c, ExcelAttribute attr, int i) {
		//非空校验
		if (attr.isNotEmpty() && Common.isEmpty(c)) {
			return errorInfo(attr, "_字段不可为空", i);
		}
		if (Common.isNotNull(c)) {
			//日期格式校验
			if (attr.isDate()) {
				DateUtil.stringToDate(c.trim(), attr.dateFormat());
			}
			//手机号码校验
			if (attr.isPhone() && getMatchRes(c, attr, ValidityConstants.MOBILE_PATTERN)) {
				return errorInfo(attr, "_手机号码有误", i);
			}
			//身份证校验
			if (attr.isIdCard() && getMatchRes(c, attr, ValidityConstants.IDCARD_PATTERN)) {
				return errorInfo(attr, "_身份证格式有误", i);
			}
			//邮箱验证
			if (attr.isEmail() && getMatchRes(c, attr, ValidityConstants.EMAIL_PATTERN)) {
				return errorInfo(attr, "_邮箱格式有误", i);
			}
			//integer 验证
			if (attr.isInteger() && getMatchRes(c, attr, ValidityConstants.INTEGER_PATTERN)) {
				return errorInfo(attr, "_整数格式有误", i);
			}
			//float、double 验证
			if (attr.isFloat() && getMatchRes(c, attr, ValidityConstants.FLOAT_PATTERN)) {
				return errorInfo(attr, "_数字格式有误", i);
			}
			//最大长度校验
			if (attr.maxLength() > 0 && c.length() > attr.maxLength()) {
				return errorInfo(attr, "_超出最大长度", i);
			}
			//最大值校验
			if (Integer.parseInt(attr.max()) > 0) {
				if (Common.isNumber(c)) {
					if (Integer.parseInt(c) > attr.maxLength()) {
						return errorInfo(attr, "_超出最大值", i);
					}
				} else {
					return "第" + i + "行：" + "_必须为数字";
				}
			}
			//最小值校验
			if (attr.min() > 0) {
				if (Common.isNumber(c)) {
					if (Integer.parseInt(c) > attr.maxLength()) {
						return errorInfo(attr, "_小于最小值", i);
					}
				} else {
					return "第" + i + "行：" + "_必须为数字";
				}
			}
		}
		return null;
	}

	/**
	 * 正则匹配返回
	 *
	 * @param c
	 * @param attr
	 * @param pattern
	 * @return
	 * @Author fxj
	 * @Date 2019-08-06
	 **/
	private boolean getMatchRes(String c, ExcelAttribute attr, String pattern) {
		return !c.matches(Common.isEmpty(attr.pattern()) ? pattern : attr.pattern());
	}

	/**
	 * @param from 源
	 * @param to   反射后的目标
	 * @Description: 反射实体类
	 * @Author: hgw
	 * @Date: 2019/11/1 16:38
	 * @return: void
	 **/
	public static void reflectionAttr(Object from, Object to) {
		try {
			Class clazz1 = Class.forName(from.getClass().getName());
			Class clazz2 = Class.forName(to.getClass().getName());
			// 获取两个实体类的所有属性
			Field[] fields1 = clazz1.getDeclaredFields();
			Field[] fields2 = clazz2.getDeclaredFields();
			SalaryAccountUtil cr = new SalaryAccountUtil();
			// 遍历class1Bean，获取逐个属性值，然后遍历class2Bean查找是否有相同的属性，如有相同则赋值
			for (Field f1 : fields1) {
				if (f1.getName().equals("id"))
					continue;
				Object value = cr.invokeGetMethod(from, f1.getName(), null);
				for (Field f2 : fields2) {
					if (f1.getName().equals(f2.getName()) && !f2.getName().equals("serialVersionUID")
							&& !f2.getName().equals("saiList")) {
						Object[] obj = new Object[1];
						obj[0] = value;
						cr.invokeSetMethod(to, f2.getName(), obj);
					}
				}
			}
		} catch (Exception e) {
			log.error("反射失败", e);
			e.printStackTrace();
		}
	}

	/**
	 * 执行某个Field的getField方法
	 *
	 * @param clazz     类
	 * @param fieldName 类的属性名称
	 * @param args      参数，默认为null
	 * @return
	 */
	public Object invokeGetMethod(Object clazz, String fieldName, Object[] args) {
		String methodName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
		Method method = null;
		try {
			if (methodName.equals("SerialVersionUID")) {
				return "";
			}
			method = Class.forName(clazz.getClass().getName()).getDeclaredMethod("get" + methodName);
			return method.invoke(clazz);
		} catch (Exception e) {
			log.error("执行某个Field的getField方法异常!!", e);
			return "";
		}
	}

	/**
	 * 执行某个Field的setField方法
	 *
	 * @param clazz     类
	 * @param fieldName 类的属性名称
	 * @param args      参数，默认为null
	 * @return
	 */
	@SuppressWarnings({"unchecked", "rawtypes"})
	private Object invokeSetMethod(Object clazz, String fieldName, Object[] args) {
		String methodName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
		Method method = null;
		try {
			Class[] parameterTypes = new Class[1];
			Class c = Class.forName(clazz.getClass().getName());
			Field field = c.getDeclaredField(fieldName);
			parameterTypes[0] = field.getType();
			method = c.getDeclaredMethod("set" + methodName, parameterTypes);
			return method.invoke(clazz, args);
		} catch (Exception e) {
			log.error("执行某个Field的setField方法异常!", e);
			return "";
		}
	}

}
