weaver-hrm-salary/src/com/engine/salary/service/impl/SalaryArchiveServiceImpl.java

1707 lines
93 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.engine.salary.service.impl;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.biz.*;
import com.engine.salary.common.LocalDateRange;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.constant.SalaryItemConstant;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.salaryarchive.bo.SalaryArchiveBO;
import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveDataDTO;
import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveInitImportDTO;
import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveInitImportSameDTO;
import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveListDTO;
import com.engine.salary.entity.salaryarchive.param.*;
import com.engine.salary.entity.salaryarchive.po.SalaryArchiveDimissionPO;
import com.engine.salary.entity.salaryarchive.po.SalaryArchiveItemPO;
import com.engine.salary.entity.salaryarchive.po.SalaryArchivePO;
import com.engine.salary.entity.salaryarchive.po.SalaryArchiveTaxAgentPO;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.taxagent.dto.TaxAgentEmployeeDTO;
import com.engine.salary.entity.taxagent.dto.TaxAgentManageRangeEmployeeDTO;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.enums.UserStatusEnum;
import com.engine.salary.enums.salaryarchive.SalaryArchiveImportTypeEnum;
import com.engine.salary.enums.salaryarchive.SalaryArchiveItemAdjustReasonEnum;
import com.engine.salary.enums.salaryarchive.SalaryArchiveStatusEnum;
import com.engine.salary.enums.salaryarchive.SalaryArchiveTaxAgentAdjustReasonEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.archive.SalaryArchiveItemMapper;
import com.engine.salary.mapper.archive.SalaryArchiveMapper;
import com.engine.salary.service.SalaryAcctEmployeeService;
import com.engine.salary.service.SalaryArchiveService;
import com.engine.salary.service.TaxAgentService;
import com.engine.salary.sys.service.SalarySysConfService;
import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.excel.ExcelComment;
import com.engine.salary.util.excel.ExcelParseHelper;
import com.engine.salary.util.excel.ExcelSupport;
import com.engine.salary.util.excel.ExcelUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.util.valid.ValidUtil;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import dm.jdbc.util.IdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jetbrains.annotations.NotNull;
import weaver.file.ImageFileManager;
import weaver.general.Util;
import weaver.hrm.User;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static com.engine.salary.util.excel.ExcelSupport.EXCEL_TYPE_XLSX;
/**
* 薪资档案
* <p>Copyright: Copyright (c) 2022</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class SalaryArchiveServiceImpl extends Service implements SalaryArchiveService {
private SalaryArchiveBiz salaryArchiveMapper = new SalaryArchiveBiz();
private EmployBiz employBiz = new EmployBiz();
private SalaryArchiveItemBiz salaryArchiveItemMapper = new SalaryArchiveItemBiz();
private SalaryArchiveTaxAgentBiz salaryArchiveTaxAgentMapper = new SalaryArchiveTaxAgentBiz();
private SalaryArchiveDimissionBiz salaryArchiveDimissionMapper = new SalaryArchiveDimissionBiz();
private SalaryItemBiz salaryItemMapper = new SalaryItemBiz();
private TaxAgentService getTaxAgentService(User user) {
return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
}
private SalaryArchiveMapper getSalaryArchiveMapper() {
return MapperProxyFactory.getProxy(SalaryArchiveMapper.class);
}
private SalaryArchiveItemMapper getSalaryArchiveItemMapper() {
return MapperProxyFactory.getProxy(SalaryArchiveItemMapper.class);
}
private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) {
return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user);
}
private SalarySysConfService getSalarySysConfService(User user) {
return ServiceUtil.getService(SalarySysConfServiceImpl.class, user);
}
@Override
public SalaryArchivePO getById(Long salaryArchiveId) {
return salaryArchiveMapper.getById(salaryArchiveId);
}
@Override
public List<SalaryArchivePO> listSome(SalaryArchivePO po) {
// 获取薪资档案数据
return getSalaryArchiveMapper().listSome(po);
}
@Override
public PageInfo<SalaryArchiveListDTO> listPage(SalaryArchiveQueryParam queryParam) {
long currentEmployeeId = user.getUID();
// 1.历史数据处理
handleHistory(currentEmployeeId);
Boolean needAuth = getTaxAgentService(user).isNeedAuth(currentEmployeeId);
//获取管理的人员范围
List<TaxAgentManageRangeEmployeeDTO> taxAgentEmployeeDTOS = getTaxAgentService(user).listTaxAgentAndEmployeeTree(currentEmployeeId);
Map<Long, List<TaxAgentManageRangeEmployeeDTO.TaxAgentEmployee>> taxAgentEmployeesMap = SalaryEntityUtil.convert2Map(taxAgentEmployeeDTOS, TaxAgentManageRangeEmployeeDTO::getTaxAgentId, TaxAgentManageRangeEmployeeDTO::getEmployeeList);
//排序配置
getSalarySysConfService(user).orderRule();
if (needAuth) {
Boolean adminEnable = getTaxAgentService(user).isAdminEnable(currentEmployeeId);
//不是管理员看不到数据,返回空
if (!adminEnable) {
PageInfo<SalaryArchiveListDTO> pageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), SalaryArchiveListDTO.class);
return pageInfo;
}
// 获取作为管理员的所有个税扣缴义务人列表
Collection<TaxAgentPO> taxAgentPOS = getTaxAgentService(user).listAllTaxAgentsAsAdmin(currentEmployeeId);
Set<Long> taxAgentIds = SalaryEntityUtil.properties(taxAgentPOS, TaxAgentPO::getId);
//获取所有薪资档案
List<SalaryArchiveListDTO> list = getSalaryArchiveMapper().list(queryParam);
List<SalaryArchiveListDTO> finalAllArchive = list.stream().filter(dto -> taxAgentIds.contains(dto.getTaxAgentId())).collect(Collectors.toList());
//设置档案状态
finalAllArchive = setSalaryArchiveStatus(taxAgentEmployeesMap, finalAllArchive);
//过滤档案状态
if (StringUtils.isNotBlank(queryParam.getArchiveStatus())) {
finalAllArchive = finalAllArchive.stream().filter(dto -> StringUtils.equals(queryParam.getArchiveStatus(), dto.getArchiveStatus())).collect(Collectors.toList());
}
PageInfo<SalaryArchiveListDTO> pageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), SalaryArchiveListDTO.class);
pageInfo.setTotal(finalAllArchive.size());
pageInfo.setList(SalaryPageUtil.subList(queryParam.getCurrent(), queryParam.getPageSize(), finalAllArchive));
return pageInfo;
} else {
List<SalaryArchiveListDTO> list = getSalaryArchiveMapper().list(queryParam);
//设置档案状态
list = setSalaryArchiveStatus(taxAgentEmployeesMap, list);
//过滤档案状态
if (StringUtils.isNotBlank(queryParam.getArchiveStatus())) {
list = list.stream().filter(dto -> StringUtils.equals(queryParam.getArchiveStatus(), dto.getArchiveStatus())).collect(Collectors.toList());
}
PageInfo<SalaryArchiveListDTO> pageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), SalaryArchiveListDTO.class);
pageInfo.setTotal(list.size());
pageInfo.setList(SalaryPageUtil.subList(queryParam.getCurrent(), queryParam.getPageSize(), list));
return pageInfo;
}
}
/**
* 设置档案状态
*
* @param taxAgentEmployeesMap
* @param list
* @return
*/
@NotNull
private List<SalaryArchiveListDTO> setSalaryArchiveStatus(Map<Long, List<TaxAgentManageRangeEmployeeDTO.TaxAgentEmployee>> taxAgentEmployeesMap, List<SalaryArchiveListDTO> list) {
list = list.stream().peek(dto -> {
List<TaxAgentManageRangeEmployeeDTO.TaxAgentEmployee> taxAgentEmployees = taxAgentEmployeesMap.get(dto.getTaxAgentId());
Set<Long> employeeIds = SalaryEntityUtil.properties(taxAgentEmployees, TaxAgentManageRangeEmployeeDTO.TaxAgentEmployee::getEmployeeId);
if (employeeIds.contains(dto.getEmployeeId())) {
dto.setArchiveStatus(SalaryArchiveStatusEnum.EFFICIENT.getValue());
} else {
dto.setArchiveStatus(SalaryArchiveStatusEnum.ARCHIVE.getValue());
}
}).collect(Collectors.toList());
return list;
}
@Override
public List<SalaryArchiveListDTO> list(SalaryArchiveQueryParam queryParam) {
long currentEmployeeId = user.getUID();
Boolean needAuth = getTaxAgentService(user).isNeedAuth(currentEmployeeId);
if (needAuth) {
Boolean adminEnable = getTaxAgentService(user).isAdminEnable(currentEmployeeId);
//不是管理员看不到数据,返回空
if (!adminEnable) {
return new ArrayList<>();
}
//获取管理的人员范围
List<TaxAgentEmployeeDTO> taxAgentEmployeeDTOS = getTaxAgentService(user).listTaxAgentAndEmployee(currentEmployeeId);
Set<Long> employeeId = SalaryEntityUtil.properties(taxAgentEmployeeDTOS, TaxAgentEmployeeDTO::getEmployeeId);
Collection<TaxAgentPO> taxAgentPOS = getTaxAgentService(user).listAllTaxAgentsAsAdmin(currentEmployeeId);
Set<Long> taxAgentIds = SalaryEntityUtil.properties(taxAgentPOS, TaxAgentPO::getId);
//获取所有薪资档案
List<SalaryArchiveListDTO> list = getSalaryArchiveMapper().list(queryParam);
List<SalaryArchiveListDTO> finalAllArchive = list.stream().filter(dto -> employeeId.contains(dto.getEmployeeId()) && taxAgentIds.contains(dto.getTaxAgentId())).collect(Collectors.toList());
return finalAllArchive;
} else {
return getSalaryArchiveMapper().list(queryParam);
}
}
/**
* 获取薪资档案对应的当前生效的薪资项目
*
* @param salaryArchivesIds
* @return
*/
@Override
public List<SalaryArchiveItemPO> getCurrentEffectiveItemList(Collection<Long> salaryArchivesIds, Collection<Long> salaryItemIds) {
if (CollectionUtils.isEmpty(salaryItemIds)) {
return Collections.EMPTY_LIST;
}
List<SalaryArchiveItemPO> salaryArchiveItems = salaryArchiveItemMapper.getCurrentEffectiveItemList(SalaryArchiveItemQueryParam.builder().salaryArchivesIds(salaryArchivesIds).salaryItemIds(salaryItemIds).effectiveTime(new Date()).build());
return salaryArchiveItems.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getSalaryArchiveId() + "-" + f.getSalaryItemId()))), ArrayList::new));
}
/**
* 获取薪资档案对应的当前生效的个税扣缴义务人
*
* @param salaryArchivesIds
* @return
*/
@Override
public List<SalaryArchiveTaxAgentPO> getCurrentEffectiveTaxAgentList(Collection<Long> salaryArchivesIds) {
if (CollectionUtils.isEmpty(salaryArchivesIds)) {
return Collections.EMPTY_LIST;
}
List<SalaryArchiveTaxAgentPO> salaryArchiveTaxAgents = salaryArchiveTaxAgentMapper.listByParam(SalaryArchiveTaxAgentQueryParam.builder().salaryArchivesIds(salaryArchivesIds).effectiveTime(new Date()).build());
return salaryArchiveTaxAgents.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SalaryArchiveTaxAgentPO::getSalaryArchiveId))), ArrayList::new));
}
/**
* 构建薪资档案数据
*
* @param salaryArchives
* @param taxAgentLists
* @param salaryItems
* @param isPage
* @return
*/
@Override
public List<Map<String, Object>> buildSalaryArchiveData(Collection<SalaryArchiveListDTO> salaryArchives, Collection<TaxAgentPO> taxAgentLists, List<SalaryItemPO> salaryItems, Boolean isPage) {
// 分页用于表格展示,否则用于导出
Collection<Long> ids = isPage ? salaryArchives.stream().map(SalaryArchiveListDTO::getId).collect(Collectors.toList()) : CollectionUtils.emptyCollection();
List<Long> salaryItemIds = salaryItems.stream().map(SalaryItemPO::getId).collect(Collectors.toList());
// 1.获取薪资档案所对应的当前生效的薪资项目数据
List<SalaryArchiveItemPO> salaryArchiveItemList = getCurrentEffectiveItemList(ids, salaryItemIds);
List<Map<String, Object>> salaryArchiveItemData = salaryArchives.stream().map(m -> {
Map<String, Object> map = Maps.newHashMap();
map.put("salaryArchiveId", m.getId());
map.put("archiveStatus", m.getArchiveStatus());
List<SalaryArchiveItemPO> salaryArchiveItemValuelList = salaryArchiveItemList.stream().filter(i -> i.getSalaryArchiveId().equals(m.getId())).collect(Collectors.toList());
salaryArchiveItemValuelList.forEach(i -> {
map.put(i.getSalaryItemId() + SalaryItemConstant.DYNAMIC_SUFFIX, i.getItemValue());
});
return map;
}).collect(Collectors.toList());
//2.获取薪资档案所对应的当前生效的个税扣缴义务人列表
// List<SalaryArchiveTaxAgentPO> taxAgentList = getCurrentEffectiveTaxAgentList(ids);
// List<Map<String, Object>> taxAgentData = taxAgentList.stream().map(m -> {
// Map<String, Object> map = Maps.newHashMap();
// map.put("salaryArchiveId", m.getSalaryArchiveId());
// map.put("taxAgentId", m.getTaxAgentId());
// Optional<TaxAgentPO> optional = taxAgentLists.stream().filter(f -> f.getId().equals(m.getTaxAgentId())).findFirst();
// map.put("taxAgentName", optional.isPresent() ? optional.get().getName() : "");
// map.put("taxAgentEffectiveTime", m.getEffectiveTime());
// return map;
// }).collect(Collectors.toList());
Map<Long, TaxAgentPO> longTaxAgentPOMap = SalaryEntityUtil.convert2Map(taxAgentLists, TaxAgentPO::getId);
// 3.组装数据
List<Map<String, Object>> listMaps = new ArrayList<>();
salaryArchives.forEach(e -> {
e.setEmployeeStatus(UserStatusEnum.getDefaultLabelByValue(Integer.parseInt(e.getEmployeeStatus())));
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", e.getId());
map.put("username", e.getUsername());
map.put("employeeId", e.getEmployeeId());
// Optional<Map<String, Object>> optionalTaxAgent = taxAgentData.stream().filter(f -> f.get("salaryArchiveId").toString().equals(e.getId().toString())).findFirst();
TaxAgentPO taxAgentPO = longTaxAgentPOMap.get(e.getTaxAgentId());
map.put("taxAgentName", Optional.ofNullable(taxAgentPO).map(TaxAgentPO::getName).orElse(""));
map.put("taxAgentId", Optional.ofNullable(taxAgentPO).map(TaxAgentPO::getId).orElse(0L));
// map.put("taxAgentEffectiveTime", optionalTaxAgent.isPresent() ? optionalTaxAgent.get().get("taxAgentEffectiveTime") : "");
map.put("subcompanyName", e.getSubcompanyName());
map.put("departmentName", e.getDepartmentName());
map.put("mobile", e.getMobile());
map.put("workcode", e.getWorkcode());
map.put("employeeStatus", e.getEmployeeStatus());
map.put("payStartDate", SalaryDateUtil.getFormatLocalDate(e.getPayStartDate()));
map.put("payEndDate", SalaryDateUtil.getFormatLocalDate(e.getPayEndDate()));
// 薪资项目动态
Optional<Map<String, Object>> optionalItem = salaryArchiveItemData.stream().filter(f -> f.get("salaryArchiveId").toString().equals(e.getId().toString())).findFirst();
optionalItem.ifPresent(map::putAll);
listMaps.add(map);
});
return listMaps;
}
@Override
public XSSFWorkbook exportList(SalaryArchiveQueryParam queryParam) {
long employeeId = user.getUID();
// 1.工作簿名称
String sheetName = SalaryI18nUtil.getI18nLabel(85368, "薪资档案");
// 获取所有可被引用的薪资项目
List<SalaryItemPO> salaryItems = salaryItemMapper.getCanAdjustSalaryItems();
String[] header = {
SalaryI18nUtil.getI18nLabel(85429, "姓名"),
SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"),
SalaryI18nUtil.getI18nLabel(86185, "部门"),
SalaryI18nUtil.getI18nLabel(86186, "手机号"),
SalaryI18nUtil.getI18nLabel(91075, "状态"),
SalaryI18nUtil.getI18nLabel(91075, "起始发薪日期"),
SalaryI18nUtil.getI18nLabel(91075, "最后发薪日期")
};
// 2.表头
List<Object> headerList = new ArrayList<>(Arrays.asList(header));
for (SalaryItemPO salaryItem : salaryItems) {
headerList.add(salaryItem.getName());
}
// 获取所有个税扣缴义务人
Collection<TaxAgentPO> taxAgentList = getTaxAgentService(user).listAll();
Collection<SalaryArchiveListDTO> salaryArchives = getSalaryArchiveMapper().list(queryParam);
//分权
Boolean needAuth = getTaxAgentService(user).isNeedAuth(employeeId);
if (needAuth) {
Boolean adminEnable = getTaxAgentService(user).isAdminEnable(employeeId);
if (!adminEnable) {
salaryArchives = new ArrayList<>();
} else {
Collection<TaxAgentPO> taxAgentPOS = getTaxAgentService(user).listAllTaxAgentsAsAdmin((long) user.getUID());
Set<Long> taxAgentIds = SalaryEntityUtil.properties(taxAgentPOS, TaxAgentPO::getId);
//获取管理扣缴单位薪资档案
salaryArchives = salaryArchives.stream().filter(dto -> taxAgentIds.contains(dto.getTaxAgentId())).collect(Collectors.toList());
//过滤档案状态
if (StringUtils.isNotBlank(queryParam.getArchiveStatus())) {
salaryArchives = salaryArchives.stream().filter(dto -> StringUtils.equals(queryParam.getArchiveStatus(), dto.getArchiveStatus())).collect(Collectors.toList());
}
}
}
List<Map<String, Object>> listMaps = buildSalaryArchiveData(salaryArchives, taxAgentList, salaryItems, Boolean.FALSE);
// 组装数据
List<List<Object>> rows = new ArrayList<>();
rows.add(headerList);
listMaps.forEach(e -> {
List<Object> row = new ArrayList<>();
row.add(Util.null2String(e.get("username")));
row.add(Util.null2String(e.get("taxAgentName")));
row.add(Util.null2String(e.get("departmentName")));
row.add(Util.null2String(e.get("mobile")));
row.add(Util.null2String(e.get("employeeStatus")));
row.add(Util.null2String(e.get("payStartDate")));
row.add(Util.null2String(e.get("payEndDate")));
// 薪资项目数据
for (SalaryItemPO salaryItem : salaryItems) {
row.add(e.containsKey(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) ? (e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) == null ? "" : e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX).toString()) : "");
}
rows.add(row);
});
// 3.表数据
return ExcelUtil.genWorkbookV2(rows, sheetName);
}
@Override
public XSSFWorkbook downloadTemplate(SalaryArchiveImportTypeEnum salaryArchiveImportTypeEnum, SalaryArchiveQueryParam queryParam) {
long employeeId = user.getUID();
boolean isInit = salaryArchiveImportTypeEnum.getValue().equals(SalaryArchiveImportTypeEnum.INIT.getValue());
boolean isTaxAgentAdjust = salaryArchiveImportTypeEnum.getValue().equals(SalaryArchiveImportTypeEnum.TAXAGENTADJUST.getValue());
boolean isSalaryItemAdjust = salaryArchiveImportTypeEnum.getValue().equals(SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getValue());
String nameI18n = SalaryI18nUtil.getI18nLabel(101601, "薪资档案导入模板");
// 初始化
if (isInit) {
nameI18n += "-" + SalaryI18nUtil.getI18nLabel(SalaryArchiveImportTypeEnum.INIT.getLabelId(), SalaryArchiveImportTypeEnum.INIT.getDefaultLabel());
// 调整个税扣缴义务人
} else if (isTaxAgentAdjust) {
nameI18n += "-" + SalaryI18nUtil.getI18nLabel(SalaryArchiveImportTypeEnum.TAXAGENTADJUST.getLabelId(), SalaryArchiveImportTypeEnum.TAXAGENTADJUST.getDefaultLabel());
// 调薪
} else if (isSalaryItemAdjust) {
nameI18n += "-" + SalaryI18nUtil.getI18nLabel(SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getLabelId(), SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getDefaultLabel());
}
// 1.工作簿名称
String sheetName = nameI18n;
// 获取所有可被引用的薪资项目
List<SalaryItemPO> salaryItems = salaryItemMapper.getCanAdjustSalaryItems();
// 2.表头
List<Object> header = Lists.newArrayList();
header.add(SalaryI18nUtil.getI18nLabel(85429, "姓名"));
header.add(SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"));
if (isSalaryItemAdjust) {
header.add(SalaryI18nUtil.getI18nLabel(85904, "生效日期"));
}
if (isTaxAgentAdjust || isSalaryItemAdjust) {
header.add(SalaryI18nUtil.getI18nLabel(85431, "调整原因"));
}
header.add(SalaryI18nUtil.getI18nLabel(86185, "部门"));
header.add(SalaryI18nUtil.getI18nLabel(86186, "手机号"));
header.add(SalaryI18nUtil.getI18nLabel(86317, "工号"));
header.add(SalaryI18nUtil.getI18nLabel(91075, "状态"));
if (isInit) {
header.add(SalaryI18nUtil.getI18nLabel(91075, "起始发薪日期"));
header.add(SalaryI18nUtil.getI18nLabel(91075, "最后发薪日期"));
}
if (isInit || isSalaryItemAdjust) {
for (SalaryItemPO salaryItem : salaryItems) {
header.add(salaryItem.getName());
}
}
// 组装数据
List<List<Object>> rows = new ArrayList<>();
rows.add(header);
//模板是否含数据
if (queryParam.getHasData() != null && queryParam.getHasData()) {
// 获取所有个税扣缴义务人
Collection<TaxAgentPO> taxAgentList = getTaxAgentService(user).listAll();
List<SalaryArchiveListDTO> salaryArchives = list(queryParam);
List<Map<String, Object>> listMaps = buildSalaryArchiveData(salaryArchives, taxAgentList, salaryItems, Boolean.FALSE);
listMaps.forEach(e -> {
List<Object> row = new ArrayList<>();
row.add(Util.null2String(e.get("username")));
row.add(Util.null2String(e.get("taxAgentName")));
if (isTaxAgentAdjust || isSalaryItemAdjust) {
row.add(isTaxAgentAdjust ? e.get("taxAgentEffectiveTime") : "");
}
if (isSalaryItemAdjust) {
row.add("");
}
row.add(Util.null2String(e.get("departmentName")));
row.add(Util.null2String(e.get("mobile")));
row.add(Util.null2String(e.get("workcode")));
row.add(Util.null2String(e.get("employeeStatus")));
if (isInit) {
row.add(Util.null2String(e.get("payStartDate")));
row.add(Util.null2String(e.get("payEndDate")));
}
// 调薪
if (isInit || isSalaryItemAdjust) {
// 薪资项目数据
for (SalaryItemPO salaryItem : salaryItems) {
row.add(e.containsKey(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) ? (e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX) == null ? "" : e.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX).toString()) : "");
}
}
rows.add(row);
});
}
// 3.表数据
// 4.注释
List<ExcelComment> excelComments = Lists.newArrayList();
excelComments.add(new ExcelComment(0, 0, 3, 2, SalaryI18nUtil.getI18nLabel(100344, "必填")));
excelComments.add(new ExcelComment(1, 0, 4, 2, SalaryI18nUtil.getI18nLabel(100344, "必填")));
if (isSalaryItemAdjust) {
excelComments.add(new ExcelComment(2, 0, 5, 2, SalaryI18nUtil.getI18nLabel(100458, "必填,格式样例为'2022-01-01'、'2022/1/1'")));
}
//调整个税扣缴义务人
if (isTaxAgentAdjust) {
excelComments.add(new ExcelComment(3, 0, 6, 2, SalaryI18nUtil.getI18nLabel(100952, "必填,可填写如:调动,变更,入职,离职,其他,初始化")));
// 调薪
} else if (isSalaryItemAdjust) {
excelComments.add(new ExcelComment(3, 0, 6, 2, SalaryI18nUtil.getI18nLabel(100953, "必填,可填写如:入职,转正,调薪,调岗调薪,离职,其他,初始化")));
}
if (isInit) {
excelComments.add(new ExcelComment(5, 0, 8, 2, SalaryI18nUtil.getI18nLabel(100458, "必填,格式样例为'2022-01-01'、'2022/1/1'")));
}
XSSFWorkbook book = ExcelUtil.genWorkbookV2(rows, sheetName, excelComments);
return book;
}
// @BatchExportHandler("exportSalaryArchive")
// public void exportSalaryArchiveHandler() {
// BatchCallbackMessage message = BatchExportContext.getBatchCallbackMessage();
// log.info("接受到薪资档案导出的结果:{}", JSONObject.toJSONString(message));
// }
@Override
public List<SalaryArchiveDimissionPO> dimissionSets() {
return salaryArchiveDimissionMapper.dimissionSets();
}
@Override
public String saveDimissionSet(SalaryArchiveDimissionSaveParam saveParam) {
Date now = new Date();
List<SalaryArchiveDimissionPO> dimissionSets = dimissionSets();
if (CollectionUtils.isNotEmpty(dimissionSets)) {
SalaryArchiveDimissionPO po = dimissionSets.get(0);
po.setDimissionTimeInterval(saveParam.getDimissionTimeInterval().getValue());
po.setUpdateTime(now);
salaryArchiveDimissionMapper.updateById(po);
} else {
salaryArchiveDimissionMapper.insert(SalaryArchiveDimissionPO.builder()
.dimissionTimeInterval(saveParam.getDimissionTimeInterval().getValue()).createTime(now).updateTime(now).creator((long) user.getUID()).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build());
}
return StringUtils.EMPTY;
}
@Override
public List<SalaryArchiveDataDTO> getSalaryArchiveData(LocalDateRange localDateRange, Collection<Long> employeeIds, Long taxAgentId) {
return getSalaryArchiveData(localDateRange, employeeIds, taxAgentId, Boolean.FALSE);
}
@Override
public List<SalaryArchiveDataDTO> getSalaryArchiveTaxAgentData(LocalDateRange localDateRange, Collection<Long> employeeIds, Long taxAgentId) {
return getSalaryArchiveData(localDateRange, employeeIds, taxAgentId, Boolean.TRUE);
}
/**
* 根据日期范围和人员获取薪资档案数据
*
* @param localDateRange
* @param employeeIds
* @param isOnlyTaxAgent
* @return
*/
private List<SalaryArchiveDataDTO> getSalaryArchiveData(LocalDateRange localDateRange, Collection<Long> employeeIds, Long taxAgentId, boolean isOnlyTaxAgent) {
// 获取薪资档案数据
List<SalaryArchivePO> salaryArchiveList = getSalaryArchiveMapper().listSome(SalaryArchivePO.builder().employeeIds(employeeIds).taxAgentId(taxAgentId).build());
List<Long> allEmployeeIds = salaryArchiveList.stream().map(SalaryArchivePO::getEmployeeId).distinct().collect(Collectors.toList());
// 获取所有可被引用的薪资项目
List<SalaryItemPO> salaryItems = salaryItemMapper.getCanAdjustSalaryItems();
Collection<Long> salaryItemIds = salaryItems.stream().map(SalaryItemPO::getId).collect(Collectors.toList());
// 获取薪资项目调整数据,isOnlyTaxAgent为true时不需要薪资项目数据
List<SalaryArchiveItemPO> salaryArchiveItemDataList = isOnlyTaxAgent || CollectionUtils.isEmpty(salaryItemIds) ? Lists.newArrayList() : salaryArchiveItemMapper.listByParam(SalaryArchiveItemQueryParam.builder().salaryItemIds(salaryItemIds).employeeIds(employeeIds).effectiveTime(localDateRange.getEndDate()).build());
return SalaryArchiveBO.buildSalaryArchiveData(salaryArchiveList, salaryArchiveItemDataList, localDateRange, allEmployeeIds, isOnlyTaxAgent);
}
/**
* 导入薪资档案
*/
public Map<String, Object> importSalaryArchive(SalaryArchiveImportHandleParam param, boolean ifImportData) {
//1、参数校验
vaildImportParam(param);
String imageId = param.getImageId();
String importType = param.getImportType();
// 2.构建导入需要的数据
SalaryArchiveImportHandleParam importHandleParam = buildImportHandleParam();
InputStream fileInputStream = null;
try {
fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(imageId));
Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
List<String> headers = ExcelSupport.getSheetHeader(sheet, 0);
//检查导入模板的必填列
checkHeaders(importType, headers);
//excel数据
List<Map<String, Object>> data = ExcelParseHelper.parse2Map(sheet, 1);
int successCount = 0;
int errorCount = 0;
// 用于初始化导入的相同employeeId时的处理
boolean isInit = importType.equals(SalaryArchiveImportTypeEnum.INIT.getValue());
List<SalaryArchiveInitImportDTO> initImportData = Lists.newArrayList();
// 用于调薪和调整个税扣缴义务人的相同employeeId时取第一条记录,如果是初始化导入则有重复
List<Long> allEmployeeIds = Lists.newArrayList();
// 错误sheet数据
List<Map<String, Object>> errorData = new ArrayList<>();
// 错误提示
List<Map<String, String>> excelComments = new ArrayList<>();
for (int i = 0; i < data.size(); i++) {
Map<String, Object> map = data.get(i);
map.put("index", i + 2);
// 3.校验行内容
boolean isError = singleRowCheck(importType, allEmployeeIds, map, headers, excelComments, errorCount, importHandleParam);
if (isError) {
errorCount += 1;
// 添加错误数据
errorData.add(map);
} else {
successCount += 1;
}
// 初始化导入对重复记录校验
if (isInit) {
Map<String, Object> validMap = validInitImportData(isError, i, map, excelComments, errorCount, successCount, errorData, initImportData, importHandleParam);
errorCount = Integer.parseInt(validMap.getOrDefault("errorCount", errorCount).toString());
successCount = Integer.parseInt(validMap.getOrDefault("successCount", successCount).toString());
}
}
// 4.数据入库处理
if (ifImportData) {
handleImportData(isInit, importHandleParam);
}
Map<String, Object> apidatas = new HashMap<>();
apidatas.put("successCount", successCount);
apidatas.put("errorCount", errorCount);
apidatas.put("errorNotice", excelComments);
return apidatas;
} finally {
IOUtils.closeQuietly(fileInputStream);
}
}
public Map<String, Object> importSalaryArchive(SalaryArchiveImportHandleParam param) {
return importSalaryArchive(param, true);
}
/**
* 导入薪资档案action使用
*
* @param importData 导入参数
* @return
*/
public Map<String, Object> importSalaryArchiveAction(SalaryArchiveImportActionParam importData, boolean ifImportData) {
// 1.构建导入需要的数据
SalaryArchiveImportHandleParam importHandleParam = buildImportHandleParam();
//导入类型
String importType = importData.getImportType();
// 需要导入的数据
List<Map<String, Object>> data = importData.getImportDatas();
// 成功数量
int successCount = 0;
// 错误数量
int errorCount = 0;
// 错误数据
List<Map<String, Object>> errorData = Lists.newArrayList();
// 错误提示
List<Map<String, String>> excelComments = new ArrayList<>();
List<SalaryArchiveInitImportDTO> initImportData = Lists.newArrayList();
boolean isInit = importType.equals(SalaryArchiveImportTypeEnum.INIT.getValue());
for (int i = 0; i < data.size(); i++) {
Map<String, Object> map = data.get(i);
List<String> headers = Lists.newArrayList();
map.keySet().forEach(headers::add);
map.put("index", i + 2);
// 3.校验行内容
boolean isError = singleRowCheck(importType, Lists.newArrayList(), map, headers, excelComments, errorCount, importHandleParam);
if (isError) {
errorCount += 1;
// 添加错误数据
errorData.add(map);
} else {
successCount += 1;
}
// 初始化导入对重复记录校验
if (isInit) {
Map<String, Object> validMap = validInitImportData(isError, i, map, excelComments, errorCount, successCount, errorData, initImportData, importHandleParam);
errorCount = Integer.parseInt(validMap.getOrDefault("errorCount", errorCount).toString());
successCount = Integer.parseInt(validMap.getOrDefault("successCount", successCount).toString());
}
}
// 4.数据入库处理
if (ifImportData) {
handleImportData(isInit, importHandleParam);
}
Map<String, Object> apidatas = new HashMap<>();
apidatas.put("successCount", successCount);
apidatas.put("errorCount", errorCount);
apidatas.put("errorNotice", excelComments);
return apidatas;
}
@Override
public void stopSalary(SalaryArchiveStopParam stopSalaryParam) {
ValidUtil.doValidator(stopSalaryParam);
stopSalaryParam.setPayEndDate(SalaryDateUtil.stringToDate(stopSalaryParam.getPayEndDateStr()));
SalaryArchivePO po = getSalaryArchiveMapper().getById(stopSalaryParam.getSalaryArchiveId());
if (po == null) {
throw new SalaryRunTimeException("未找到薪资档案");
}
Date payStartDate = po.getPayStartDate();
Date payEndDate = stopSalaryParam.getPayEndDate();
if(payEndDate.before(payStartDate)){
throw new SalaryRunTimeException("最后缴纳日期应大于起始缴纳日期");
}
po.setPayEndDate(payEndDate);
po.setUpdateTime(new Date());
getSalaryArchiveMapper().update(po);
}
@Override
public Map<String, Object> preview(SalaryArchiveImportHandleParam param) {
//1、参数校验
vaildImportParam(param);
Map<String, Object> map = new HashMap<>();
InputStream fileInputStream = null;
try {
fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));
Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
List<String> headers = ExcelSupport.getSheetHeader(sheet, 0);
map.put("headers", headers);
map.put("list", ExcelParseHelper.parse2List(sheet, 1));
return map;
} finally {
IOUtils.closeQuietly(fileInputStream);
}
}
private void vaildImportParam(SalaryArchiveImportHandleParam param) {
String imageId = param.getImageId();
if (StringUtils.isBlank(imageId)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100593, "文件id为空"));
}
String importType = param.getImportType();
SalaryArchiveImportTypeEnum importTypeEnum = SalaryArchiveImportTypeEnum.parseByValue(importType);
if (importTypeEnum == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100593, "导入类型不正确"));
}
}
/**
* 构建导入处理参数
*
* @return
*/
private SalaryArchiveImportHandleParam buildImportHandleParam() {
long employeeId = user.getUID();
// 获取所有可被引用的薪资项目
List<SalaryItemPO> salaryItems = salaryItemMapper.getCanAdjustSalaryItems();
Collection<Long> salaryItemIds = salaryItems.stream().map(SalaryItemPO::getId).collect(Collectors.toList());
Date now = new Date();
return SalaryArchiveImportHandleParam.builder().openDevolution(getTaxAgentService(user).isOpenDevolution()).listTaxAgentAndEmployeeTree(getTaxAgentService(user).listTaxAgentAndEmployeeTree(employeeId))
// 获取租户下所有的人员
.employees(employBiz.listEmployee())
// 获取所有个税扣缴义务人
.taxAgentList(getTaxAgentService(user).listAllTaxAgentsAsAdmin(employeeId)).salaryItems(salaryItems)
// 查询已有的薪资档案基本数据
.salaryArchives(list(SalaryArchiveQueryParam.builder().build())).salaryItemIds(salaryItemIds)
// 查询已生效的薪资项目数据
.effectiveItemList(getEffectiveItemList(salaryItemIds))
// 查询未生效的薪资项目数据
.ineffectiveItemList(getIneffectiveItemList(salaryItemIds))
// 查询已生效的个税扣缴义务人数据
.effectiveTaxAgentList(getEffectiveTaxAgentList())
// 查询未生效的个税扣缴义务人数据
.ineffectiveTaxAgentList(getIneffectiveTaxAgentList())
// 当前时间
.nowTime(now)
// 当天
.today(now)
// 待保存薪资档案
.salaryArchiveSaves(Lists.newArrayList())
// 待修改薪资档案-
.salaryArchiveUpdates(Lists.newArrayList())
// 待保存薪资档案-个税扣缴义务人
.salaryArchiveTaxAgentSaves(Lists.newArrayList())
// 待保存薪资档案-薪资项目
.salaryArchiveItemSaves(Lists.newArrayList())
// 待删除薪资档案-个税扣缴义务人
.salaryArchiveTaxAgentDelTaxAgentIds(Lists.newArrayList())
// 待删除薪资档案-薪资项目
.salaryArchiveItemDelSalaryItemIds(Lists.newArrayList()).build();
}
/**
* 初始化导入数据校验
* 说明:如果一个人的多条记录中有一个错那么就全部弄到错误文档中
*
* @param isError
* @param rowNo
* @param map
* @param excelComments
* @param errorCount
* @param successCount
* @param errorData
* @param initImportData
* @param importHandleParam
*/
private Map<String, Object> validInitImportData(boolean isError, int rowNo, Map<String, Object> map, List<Map<String, String>> excelComments, int errorCount, int successCount, List<Map<String, Object>> errorData, List<SalaryArchiveInitImportDTO> initImportData, SalaryArchiveImportHandleParam importHandleParam) {
Long employeeId = Long.valueOf(Optional.ofNullable(map.get("employeeId")).orElse("0").toString());
Optional<SalaryArchiveInitImportDTO> optionalInitImport = initImportData.stream().filter(f -> f.getEmployeeId().equals(employeeId)).findFirst();
Map<String, Object> validMap = new HashMap<>();
validMap.put("errorCount", errorCount);
validMap.put("successCount", successCount);
if (employeeId.equals(0L)) {
return validMap;
}
AtomicInteger finalErrorCount = new AtomicInteger(errorCount);
AtomicInteger finalSuccessCount = new AtomicInteger(successCount);
if (optionalInitImport.isPresent()) {
SalaryArchiveInitImportDTO initImport = optionalInitImport.get();
List<SalaryArchiveInitImportSameDTO> sames = initImport.getSames();
sames.add(SalaryArchiveInitImportSameDTO.builder().isError(isError).rowNo(rowNo).row(map).build());
Optional<SalaryArchiveInitImportSameDTO> optionalSame = sames.stream().filter(SalaryArchiveInitImportSameDTO::isError).findFirst();
// 只要是其中一行有错误
if (optionalSame.isPresent()) {
sames.forEach(e -> {
if (!e.isError()) {
e.setError(Boolean.TRUE);
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", "该员工的薪资档案记录有误,请检查");
excelComments.add(errorMessageMap);
finalErrorCount.addAndGet(1);
errorData.add(e.getRow());
finalSuccessCount.addAndGet(-1);
}
});
// 如果到目前为止都没错的话,则相互之间检验调整记录
} else {
int nums = sames.size();
// 1.生效时间不可重复
List<String> effectiveTimeList = sames.stream().map(m -> Optional.ofNullable(m.getRow().get("payStartDate")).orElse("").toString()).distinct().collect(Collectors.toList());
// 2.个税扣缴义务人和薪资项目共同决定是否重复
List<String> rowSameList = sames.stream().map(m -> {
Map<String, Object> row = m.getRow();
String taxAgent = Optional.ofNullable(row.get("taxAgent")).orElse("").toString();
String salaryItem = Optional.ofNullable(row.get("salaryItemVal")).orElse("").toString();
return taxAgent + salaryItem;
}).distinct().collect(Collectors.toList());
if (/** effectiveTimeList.size() != nums || */rowSameList.size() != nums) {
sames.forEach(e -> {
if (!e.isError()) {
e.setError(Boolean.TRUE);
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", "该员工的薪资档案记录有误");
excelComments.add(errorMessageMap);
finalErrorCount.addAndGet(1);
errorData.add(e.getRow());
finalSuccessCount.addAndGet(-1);
}
});
}
}
initImport.setSames(sames);
} else {
SalaryArchiveInitImportDTO initImport = new SalaryArchiveInitImportDTO();
initImport.setEmployeeId(employeeId);
List<SalaryArchiveInitImportSameDTO> sames = Lists.newArrayList();
sames.add(SalaryArchiveInitImportSameDTO.builder().isError(isError).rowNo(rowNo).row(map).build());
initImport.setSames(sames);
initImportData.add(initImport);
}
// 如果出现错误
if (isError || errorCount != finalErrorCount.get() || successCount != finalSuccessCount.get()) {
validMap.put("errorCount", finalErrorCount.get());
validMap.put("successCount", finalSuccessCount.get());
// 将前面添加好的数据给过滤掉
importHandleParam.setSalaryArchiveSaves(importHandleParam.getSalaryArchiveSaves().stream().filter(f -> !f.getEmployeeId().equals(employeeId)).collect(Collectors.toList()));
importHandleParam.setSalaryArchiveTaxAgentSaves(importHandleParam.getSalaryArchiveTaxAgentSaves().stream().filter(f -> !f.getEmployeeId().equals(employeeId)).collect(Collectors.toList()));
importHandleParam.setSalaryArchiveItemSaves(importHandleParam.getSalaryArchiveItemSaves().stream().filter(f -> !f.getEmployeeId().equals(employeeId)).collect(Collectors.toList()));
}
return validMap;
}
/**
* 校验单行数据
*
* @param importType
* @param allEmployeeIds
* @param map
* @param headers
* @param excelComments
* @param errorCount
* @param importHandleParam
* @return
*/
private boolean singleRowCheck(String importType, List<Long> allEmployeeIds, Map<String, Object> map, List<String> headers, List<Map<String, String>> excelComments, int errorCount, SalaryArchiveImportHandleParam importHandleParam) {
boolean isError = false;
boolean isInit = importType.equals(SalaryArchiveImportTypeEnum.INIT.getValue());
boolean isTaxAgentAdjust = importType.equals(SalaryArchiveImportTypeEnum.TAXAGENTADJUST.getValue());
boolean isSalaryItemAdjust = importType.equals(SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getValue());
String userNameI18n = SalaryI18nUtil.getI18nLabel(85429, "姓名");
String taxAgentI18n = SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人");
String effectiveTimeI18n = SalaryI18nUtil.getI18nLabel(85904, "生效日期");
String payStartDateI18n = SalaryI18nUtil.getI18nLabel(85904, "起始发薪日期");
String payEndDateI18n = SalaryI18nUtil.getI18nLabel(85904, "最后发薪日期");
String adjustReasonI18n = SalaryI18nUtil.getI18nLabel(85431, "调整原因");
String rowindex = "" + map.get("index") + "";
// 1.姓名
String userName = Optional.ofNullable(map.get(userNameI18n)).orElse("").toString();
String deparmentName = Optional.ofNullable(map.get(SalaryI18nUtil.getI18nLabel(86185, "部门"))).orElse("").toString();
String mobile = Optional.ofNullable(map.get(SalaryI18nUtil.getI18nLabel(86186, "手机号"))).orElse("").toString();
String workcode = Optional.ofNullable(map.get(SalaryI18nUtil.getI18nLabel(86317, "工号"))).orElse("").toString();
//筛选导入人员信息可以在人力资源池中匹配到的人员信息
List<DataCollectionEmployee> emps = getSalaryAcctEmployeeService(user).matchImportEmployee(importHandleParam.getEmployees(), userName, deparmentName, mobile, workcode);
List<Long> employeeSameIds = new ArrayList<>();
if (CollectionUtils.isNotEmpty(emps) && emps.size() > 1) {
employeeSameIds = emps.stream().filter(e -> UserStatusEnum.getNormalStatus().contains(e.getStatus())).map(DataCollectionEmployee::getEmployeeId).collect(Collectors.toList());
}
if (CollectionUtils.isNotEmpty(emps) && emps.size() == 1) {
employeeSameIds = emps.stream().map(DataCollectionEmployee::getEmployeeId).collect(Collectors.toList());
}
Long employeeId = CollectionUtils.isNotEmpty(employeeSameIds) && employeeSameIds.size() == 1 && employeeSameIds.get(0) > 0 ? employeeSameIds.get(0) : null;
// 调薪和调整个税扣缴义务人的存在相同的取第一条
if (employeeId != null && allEmployeeIds.contains(employeeId) && (isTaxAgentAdjust || isSalaryItemAdjust)) {
return isError;
}
if (employeeId != null) {
allEmployeeIds.add(employeeId);
}
// 用于初始化导入数据校验
map.put("employeeId", employeeId);
map.put("rowId", employeeId);
// 2.生效日期
String effectiveTimeCellVal = Optional.ofNullable(map.get(effectiveTimeI18n)).orElse("").toString().replaceAll(" 00:00:00", "");
// 免得失败后,会追加 00:00:00
map.put(effectiveTimeI18n, effectiveTimeCellVal);
map.put("effectiveTime", effectiveTimeCellVal);
Date effectiveTime = SalaryDateUtil.checkDay(effectiveTimeCellVal) ? dateStrToLocalDate(effectiveTimeCellVal) : null;
// 3.个税扣缴义务人
String taxAgentCellVal = Optional.ofNullable(map.get(taxAgentI18n)).orElse("").toString();
// 用于初始化导入的同一个人的记录校验
map.put("taxAgent", taxAgentCellVal);
Optional<TaxAgentPO> optionalTaxAgent = importHandleParam.getTaxAgentList().stream().filter(m -> m.getName().equals(taxAgentCellVal)).findFirst();
Long taxAgentId = optionalTaxAgent.map(TaxAgentPO::getId).orElse(null);
// 4.调整原因
String adjustReason = "";
if (isTaxAgentAdjust) {
// 4.调整原因[个税扣缴义务人]
adjustReason = SalaryArchiveTaxAgentAdjustReasonEnum.getValueByDefaultLabel(Optional.ofNullable(map.get(adjustReasonI18n)).orElse("").toString());
} else if (isSalaryItemAdjust) {
// 4.调整原因[薪资项目]
adjustReason = SalaryArchiveItemAdjustReasonEnum.getValueByDefaultLabel(Optional.ofNullable(map.get(adjustReasonI18n)).orElse("").toString());
}
// 5.起始发薪日期
String payStartDateCellVal = Optional.ofNullable(map.get(payStartDateI18n)).orElse("").toString().replaceAll(" 00:00:00", "");
// 免得失败后,会追加 00:00:00
map.put(payStartDateI18n, payStartDateCellVal);
map.put("payStartDate", payStartDateCellVal);
Date payStartDate = SalaryDateUtil.checkDay(payStartDateCellVal) ? dateStrToLocalDate(payStartDateCellVal) : null;
// 6.最后发薪日期
String payEndDateCellVal = Optional.ofNullable(map.get(payEndDateI18n)).orElse("").toString().replaceAll(" 00:00:00", "");
// 免得失败后,会追加 00:00:00
map.put(payEndDateI18n, payEndDateCellVal);
map.put("payEndDate", payEndDateCellVal);
Date payEndDate = SalaryDateUtil.checkDay(payEndDateCellVal) ? dateStrToLocalDate(payEndDateCellVal) : null;
// 构建薪资档案
SalaryArchivePO finalSalaryArchive = buildSalaryArchive(isInit, payStartDate, payEndDate, employeeId, taxAgentId, importHandleParam);
for (int j = 0; j < headers.size(); j++) {
String key = headers.get(j);
String cellVal = Optional.ofNullable(map.get(key)).orElse("").toString();
boolean isEmpty = StringUtils.isEmpty(cellVal) && (userNameI18n.equals(key)
// 个税扣缴义务人列判空(初始化导入或调整个税扣缴义务人)
|| (taxAgentI18n.equals(key) && (isInit || isTaxAgentAdjust)) || (effectiveTimeI18n.equals(key) && isSalaryItemAdjust)
// 调整原因列判空(调薪或调整个税扣缴义务人)
|| (adjustReasonI18n.equals(key) && (isTaxAgentAdjust || isSalaryItemAdjust)));
// 判空
if (userNameI18n.equals(key) && StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "不能为空");
excelComments.add(errorMessageMap);
}
// 个税扣缴义务人列判空(初始化导入或调整个税扣缴义务人)
if ((taxAgentI18n.equals(key) && (isInit || isTaxAgentAdjust)) && StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "不能为空");
excelComments.add(errorMessageMap);
}
// 调整原因列判空(调薪或调整个税扣缴义务人)
if ((adjustReasonI18n.equals(key) && (isTaxAgentAdjust || isSalaryItemAdjust)) && StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "不能为空");
excelComments.add(errorMessageMap);
}
//调薪生效时间不能为空
if (isSalaryItemAdjust && effectiveTimeI18n.equals(key) && StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "不能为空");
excelComments.add(errorMessageMap);
}
//定薪起始时间不能为空
if (isInit && payStartDateI18n.equals(key) && StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "不能为空");
excelComments.add(errorMessageMap);
}
if (isEmpty) {
isError = true;
}
// 1.姓名列处理
if (!isEmpty && userNameI18n.equals(key)) {
if (CollectionUtils.isEmpty(employeeSameIds) || employeeSameIds.size() > 1) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "员工信息不能为空且不可重复(姓名、部门和手机号同时确认唯一)");
excelComments.add(errorMessageMap);
isError = true;
} else if (employeeId == null) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "姓名错误,系统内不存在该姓名");
excelComments.add(errorMessageMap);
isError = true;
// (调薪或调整个税扣缴义务人)
} else if (finalSalaryArchive == null && (isTaxAgentAdjust || isSalaryItemAdjust)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "该人员的薪资档案不存在,请先初始化");
excelComments.add(errorMessageMap);
isError = true;
}
//设置当前的待校验人员id
importHandleParam.setEmployeeId(employeeId);
} else if (!isEmpty && taxAgentI18n.equals(key) && (isInit || isTaxAgentAdjust)) {
// 2.个税扣缴义务人列处理(初始化导入或调整个税扣缴义务人)
isError = handleTaxAgent(isError, isInit, excelComments, errorCount, j, taxAgentId, effectiveTime, finalSalaryArchive, adjustReason, importHandleParam, map);
} else if (!isEmpty && payStartDateI18n.equals(key) && payStartDate == null) {
// 起始发薪日期
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "发薪起始日期格式不正确,正确格式示例为'2022-01-01'、'2022/1/1'");
excelComments.add(errorMessageMap);
isError = true;
} else if (!isEmpty && payEndDateI18n.equals(key) && !payEndDateCellVal.equals("") && !SalaryDateUtil.checkDay(payEndDateCellVal)) {
// 最后发薪日期
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "最后发薪日期格式不正确,正确格式示例为'2022-01-01'、'2022/1/1'");
excelComments.add(errorMessageMap);
isError = true;
// 5.薪资项目列处理(初始化导入或调薪)
} else if (!isEmpty && effectiveTimeI18n.equals(key) && effectiveTime == null) {
// 3.生效时间处理
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "生效日期错误或格式不正确,正确格式示例为'2022-01-01'、'2022/1/1'");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(102497, "生效日期错误或格式不正确,正确格式示例为'2022-01-01'、'2022/1/1'"), errorCount + 1, errorCount + 1, j, j);
isError = true;
// 4.调整原因列处理(调薪或调整个税扣缴义务人)
} else if (!isEmpty && adjustReasonI18n.equals(key) && (isTaxAgentAdjust || isSalaryItemAdjust) && StringUtils.isEmpty(adjustReason)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "调整原因异常");
excelComments.add(errorMessageMap);
isError = true;
// 5.薪资项目列处理(初始化导入或调薪)
} else {
// 薪资项目数据
if (isInit) {
effectiveTime = payStartDate;
}
if (effectiveTime == null || finalSalaryArchive == null || !(isInit || isSalaryItemAdjust)) {
continue;
}
isError = handleSalaryItem(isError, isInit, excelComments, effectiveTime, finalSalaryArchive, adjustReason, importHandleParam, key, cellVal, map);
}
}
return isError;
}
/**
* 构建薪资档案
*
* @param isInit
* @param payStartDate
* @param payEndDate
* @param employeeId
* @param taxAgentId
* @param importHandleParam
* @return
*/
private SalaryArchivePO buildSalaryArchive(boolean isInit, Date payStartDate, Date payEndDate, Long employeeId, Long taxAgentId, SalaryArchiveImportHandleParam importHandleParam) {
Optional<SalaryArchiveListDTO> optionalSA = importHandleParam.getSalaryArchives().stream()
.filter(p -> p.getEmployeeId().equals(employeeId) && p.getTaxAgentId().equals(taxAgentId))
.findFirst();
SalaryArchivePO salaryArchive = null;
if (optionalSA.isPresent()) {
// 修改档案
SalaryArchiveListDTO sa = optionalSA.get();
salaryArchive = SalaryArchivePO.builder()
.id(sa.getId())
.employeeId(sa.getEmployeeId())
.taxAgentId(sa.getTaxAgentId())
.payStartDate(payStartDate)
.payEndDate(payEndDate)
.createTime(importHandleParam.getNowTime())
.updateTime(importHandleParam.getNowTime())
.creator((long) user.getUID())
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.deleteType(0)
.build();
importHandleParam.getSalaryArchiveUpdates().add(salaryArchive);
} else if (employeeId != null && isInit) {
// 新增档案
salaryArchive = SalaryArchivePO.builder()
.id(IdGenerator.generate())
.employeeId(employeeId)
.taxAgentId(taxAgentId)
.payStartDate(payStartDate)
.payEndDate(payEndDate)
.createTime(importHandleParam.getNowTime())
.updateTime(importHandleParam.getNowTime())
.creator((long) user.getUID())
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.deleteType(0)
.build();
importHandleParam.getSalaryArchiveSaves().add(salaryArchive);
}
return salaryArchive;
}
/**
* 个税扣缴义务人处理
*
* @param isError
* @param excelComments
* @param errorCount
* @param j
* @param taxAgentId
* @param effectiveTime
* @param finalSalaryArchive
* @param taxAgentAdjustReason
* @param importHandleParam
* @return
*/
private boolean handleTaxAgent(boolean isError, boolean isInit, List<Map<String, String>> excelComments, int errorCount, int j, Long taxAgentId, Date effectiveTime, SalaryArchivePO finalSalaryArchive, String taxAgentAdjustReason, SalaryArchiveImportHandleParam importHandleParam, Map<String, Object> map) {
String rowindex = "" + map.get("index") + "";
//分权
Boolean openDevolution = importHandleParam.getOpenDevolution();
Collection<TaxAgentPO> taxAgentList = importHandleParam.getTaxAgentList();
Set<Long> taxAgents = SalaryEntityUtil.properties(taxAgentList, TaxAgentPO::getId);
if (taxAgentId == null) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "个税扣缴义务人不存在");
excelComments.add(errorMessageMap);
isError = true;
} else if (!taxAgents.contains(taxAgentId)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "没有该个税扣缴义务人的权限");
excelComments.add(errorMessageMap);
isError = true;
}
//人员是否在扣缴义务人范围内
if (openDevolution) {
Optional<TaxAgentManageRangeEmployeeDTO> taxAgentEmployees = importHandleParam.getListTaxAgentAndEmployeeTree().stream().filter(m -> m.getTaxAgentId().equals(taxAgentId)).findFirst();
if (!taxAgentEmployees.isPresent()) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "该条数据的扣缴义务人不存在");
excelComments.add(errorMessageMap);
isError = true;
} else {
List<TaxAgentManageRangeEmployeeDTO.TaxAgentEmployee> employeeList = taxAgentEmployees.get().getEmployeeList();
if (CollectionUtils.isEmpty(employeeList)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "该条数据的扣缴义务人未设置人员范围");
excelComments.add(errorMessageMap);
isError = true;
} else {
Optional<TaxAgentManageRangeEmployeeDTO.TaxAgentEmployee> optionalTaxAgentEmp = employeeList.stream().filter(f -> f.getEmployeeId().equals(importHandleParam.getEmployeeId())).findFirst();
if (!optionalTaxAgentEmp.isPresent()) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "该条数据不在个税扣缴义务人人员范围内,不可导入");
excelComments.add(errorMessageMap);
isError = true;
}
}
}
}
if (effectiveTime != null && finalSalaryArchive != null) {
boolean isBeforeError = false;
if (!isInit) {
// 前后调整校验
// 已生效
List<SalaryArchiveTaxAgentPO> effectiveList = importHandleParam.getEffectiveTaxAgentList().stream().filter(i -> finalSalaryArchive.getId().equals(i.getSalaryArchiveId())).collect(Collectors.toList());
// 当前已生效
SalaryArchiveTaxAgentPO effectiveTaxAgent = CollectionUtils.isNotEmpty(effectiveList) && effectiveList.size() > 0 ? effectiveList.get(0) : null;
// 当前已生效的前一次调整
SalaryArchiveTaxAgentPO effectiveBeforeTaxAgent = CollectionUtils.isNotEmpty(effectiveList) && effectiveList.size() > 1 ? effectiveList.get(1) : null;
// 未生效
Optional<SalaryArchiveTaxAgentPO> optionalIneffective = importHandleParam.getIneffectiveTaxAgentList().stream().filter(i -> finalSalaryArchive.getId().equals(i.getSalaryArchiveId())).findFirst();
SalaryArchiveTaxAgentPO ineffectiveTaxAgent = optionalIneffective.orElse(null);
// 1.检验是否可以调整
if (effectiveTaxAgent != null) {
// 当前已经生效的时间
Date currentEffectiveTime = effectiveTaxAgent.getEffectiveTime();
// 1.1 如果早于<当前已生效
if (effectiveTime.before(currentEffectiveTime)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "个税扣缴义务人生效日期不可早于当前已生效的调整日期");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100429, "生效日期不可早于当前已生效的调整日期"), errorCount + 1, errorCount + 1, effectiveTimeIndex, effectiveTimeIndex);
isError = true;
isBeforeError = true;
// 1.2 如果等于当前已生效
} else if (effectiveTime.equals(currentEffectiveTime)) {
if (effectiveBeforeTaxAgent != null && effectiveBeforeTaxAgent.getTaxAgentId().equals(taxAgentId)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "个税扣缴义务人调整前后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
if (ineffectiveTaxAgent != null && ineffectiveTaxAgent.getTaxAgentId().equals(taxAgentId)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "个税扣缴义务人与未生效的调整后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
// 1.3 如果>已经生效且<=今天
} else if (effectiveTime.after(currentEffectiveTime) && !effectiveTime.after(importHandleParam.getToday())) {
if (effectiveTaxAgent.getTaxAgentId().equals(taxAgentId)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "个税扣缴义务人调整前后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
if (ineffectiveTaxAgent != null && ineffectiveTaxAgent.getTaxAgentId().equals(taxAgentId)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "个税扣缴义务人与未生效的调整后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
// 1.4 如果>今天
} else if (effectiveTime.after(importHandleParam.getToday()) && effectiveTaxAgent.getTaxAgentId().equals(taxAgentId)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "个税扣缴义务人调整前后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
} else if (ineffectiveTaxAgent != null && ineffectiveTaxAgent.getTaxAgentId().equals(taxAgentId)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + "个税扣缴义务人与未生效的调整后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
// 2.数据处理,有的就先删后增
if (effectiveTaxAgent != null && effectiveTime.equals(effectiveTaxAgent.getEffectiveTime())) {
importHandleParam.getSalaryArchiveTaxAgentDelTaxAgentIds().add(effectiveTaxAgent.getId());
}
if (ineffectiveTaxAgent != null && effectiveTime.after(importHandleParam.getToday())) {
importHandleParam.getSalaryArchiveTaxAgentDelTaxAgentIds().add(ineffectiveTaxAgent.getId());
}
}
if (!isBeforeError) {
importHandleParam.getSalaryArchiveTaxAgentSaves().add(SalaryArchiveTaxAgentPO.builder()
.salaryArchiveId(finalSalaryArchive.getId()).employeeId(finalSalaryArchive.getEmployeeId()).taxAgentId(taxAgentId).effectiveTime(effectiveTime).adjustReason(StringUtils.isEmpty(taxAgentAdjustReason) ? SalaryArchiveTaxAgentAdjustReasonEnum.INIT.getValue() : taxAgentAdjustReason).operator((long) user.getUID()).operateTime(importHandleParam.getNowTime()).createTime(importHandleParam.getNowTime()).updateTime(importHandleParam.getNowTime()).creator((long) user.getUID()).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build());
}
}
return isError;
}
/**
* 薪资项目处理
*
* @param isError
* @param excelComments
* @param effectiveTime
* @param finalSalaryArchive
* @param salaryItemAdjustReason
* @param importHandleParam
* @param cellVal
* @return
*/
private boolean handleSalaryItem(boolean isError, boolean isInit, List<Map<String, String>> excelComments, Date effectiveTime, SalaryArchivePO finalSalaryArchive, String salaryItemAdjustReason, SalaryArchiveImportHandleParam importHandleParam, String key, String cellVal, Map<String, Object> map) {
String rowindex = "" + map.get("index") + "";
Optional<SalaryItemPO> optionalSalaryItem = importHandleParam.getSalaryItems().stream().filter(e -> e.getName().equals(key)).findFirst();
if (optionalSalaryItem.isPresent()) {
Long salaryItemId = optionalSalaryItem.get().getId();
boolean isBeforeError = false;
if (!isInit) {
// 已生效
List<SalaryArchiveItemPO> effectiveList = importHandleParam.getEffectiveItemList().stream().filter(i -> finalSalaryArchive.getId().equals(i.getSalaryArchiveId()) && i.getSalaryItemId().equals(salaryItemId)).collect(Collectors.toList());
// 当前已生效
SalaryArchiveItemPO effectiveSalaryItem = CollectionUtils.isNotEmpty(effectiveList) && effectiveList.size() > 0 ? effectiveList.get(0) : null;
// 当前已生效的前一次调整
SalaryArchiveItemPO effectiveBeforeSalaryItem = CollectionUtils.isNotEmpty(effectiveList) && effectiveList.size() > 1 ? effectiveList.get(1) : null;
// 未生效
Optional<SalaryArchiveItemPO> optionalIneffective = importHandleParam.getIneffectiveItemList().stream().filter(i -> finalSalaryArchive.getId().equals(i.getSalaryArchiveId()) && i.getSalaryItemId().equals(salaryItemId)).findFirst();
SalaryArchiveItemPO ineffectiveSalaryItem = optionalIneffective.orElse(null);
// 1.检验是否可以调整
if (effectiveSalaryItem != null) {
// 当前已经生效的时间
Date currentEffectiveTime = effectiveSalaryItem.getEffectiveTime();
// 1.1 如果早于<当前已生效
if (effectiveTime.before(currentEffectiveTime)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "生效日期不可早于当前已生效的调整日期");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100429, "生效日期不可早于当前已生效的调整日期"), errorCount + 1, errorCount + 1, effectiveTimeIndex, effectiveTimeIndex);
isError = true;
isBeforeError = true;
// 1.2 如果等于当前已生效
} else if (effectiveTime.equals(currentEffectiveTime)) {
if (effectiveBeforeSalaryItem != null && effectiveBeforeSalaryItem.getItemValue().equals(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "调整前后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
if (ineffectiveSalaryItem != null && ineffectiveSalaryItem.getItemValue().equals(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "与未生效的调整后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
// 1.3 如果>已经生效且<=今天
} else if (effectiveTime.after(currentEffectiveTime) && !effectiveTime.after(importHandleParam.getToday())) {
if (effectiveSalaryItem.getItemValue().equals(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "调整前后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
if (ineffectiveSalaryItem != null && ineffectiveSalaryItem.getItemValue().equals(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "与未生效的调整后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
// 1.4 如果>今天
} else if (effectiveTime.after(importHandleParam.getToday()) && effectiveSalaryItem.getItemValue().equals(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "调整前后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
} else if (ineffectiveSalaryItem != null && ineffectiveSalaryItem.getItemValue().equals(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", rowindex + key + "与未生效的调整后不可相同");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
// 2.数据处理
if (effectiveSalaryItem != null && effectiveTime.equals(effectiveSalaryItem.getEffectiveTime())) {
importHandleParam.getSalaryArchiveItemDelSalaryItemIds().add(effectiveSalaryItem.getId());
}
if (ineffectiveSalaryItem != null && effectiveTime.after(importHandleParam.getToday())) {
importHandleParam.getSalaryArchiveItemDelSalaryItemIds().add(ineffectiveSalaryItem.getId());
}
}
if (!isBeforeError) {
importHandleParam.getSalaryArchiveItemSaves().add(SalaryArchiveItemPO.builder()
.salaryArchiveId(finalSalaryArchive.getId()).employeeId(finalSalaryArchive.getEmployeeId()).effectiveTime(effectiveTime).adjustReason(StringUtils.isEmpty(salaryItemAdjustReason) ? SalaryArchiveItemAdjustReasonEnum.INIT.getValue() : salaryItemAdjustReason).salaryItemId(salaryItemId).itemValue(cellVal).description("").operator((long) user.getUID()).operateTime(importHandleParam.getNowTime()).createTime(importHandleParam.getNowTime()).updateTime(importHandleParam.getNowTime()).creator((long) user.getUID()).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build());
}
// 用于初始化导入,同一个人的多行记录之间的薪资项目是否调整
map.put("salaryItemVal", Optional.ofNullable(map.get("salaryItemVal")).orElse("").toString() + salaryItemId + cellVal);
}
return isError;
}
/**
* 字符串转日期
* 兼容/和-
*
* @param effectiveTime
* @return
*/
private Date dateStrToLocalDate(String effectiveTime) {
Date localDate = null;
try {
if (effectiveTime.contains("/")) {
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
localDate = format.parse(effectiveTime);
} else if (effectiveTime.contains("-")) {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
localDate = format.parse(effectiveTime);
}
} catch (Exception e) {
localDate = null;
}
return localDate;
}
private List<SalaryArchiveItemPO> getEffectiveItemList(Collection<Long> salaryItemIds) {
long currentEmployeeId = user.getUID();
// 没有薪资项目时,给个不存在的,否则加载所有不合理
if (CollectionUtils.isEmpty(salaryItemIds)) {
return new ArrayList<>();
}
Date truncate = DateUtils.truncate(new Date(), Calendar.DATE);
return salaryArchiveItemMapper.getEffectiveSalaryItems(SalaryArchiveItemQueryParam.builder().effectiveTime(truncate).salaryItemIds(salaryItemIds).build());
}
private List<SalaryArchiveItemPO> getIneffectiveItemList(Collection<Long> salaryItemIds) {
long currentEmployeeId = user.getUID();
// 没有薪资项目时,给个不存在的,否则加载所有不合理
if (CollectionUtils.isEmpty(salaryItemIds)) {
return new ArrayList<>();
}
Date truncate = DateUtils.truncate(new Date(), Calendar.DATE);
return salaryArchiveItemMapper.getIneffectiveSalaryItems(SalaryArchiveItemQueryParam.builder().salaryItemIds(salaryItemIds).effectiveTime(truncate).build());
}
private List<SalaryArchiveTaxAgentPO> getEffectiveTaxAgentList() {
Date truncate = DateUtils.truncate(new Date(), Calendar.DATE);
return salaryArchiveTaxAgentMapper.getEffectiveTaxAgentList(SalaryArchiveTaxAgentQueryParam.builder().effectiveTime(truncate).build());
}
private List<SalaryArchiveTaxAgentPO> getIneffectiveTaxAgentList() {
Date truncate = DateUtils.truncate(new Date(), Calendar.DATE);
return salaryArchiveTaxAgentMapper.getIneffectiveTaxAgentList(SalaryArchiveTaxAgentQueryParam.builder().effectiveTime(truncate).build());
}
/**
* 检查列头
*
* @param importType
* @param headers
* @return
*/
private boolean checkHeaders(String importType, List<String> headers) {
boolean isValid = true;
boolean isInit = importType.equals(SalaryArchiveImportTypeEnum.INIT.getValue());
boolean isTaxAgentAdjust = importType.equals(SalaryArchiveImportTypeEnum.TAXAGENTADJUST.getValue());
boolean isSalaryItemAdjust = importType.equals(SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getValue());
String userNameI18n = SalaryI18nUtil.getI18nLabel(85429, "姓名");
String taxAgentI18n = SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人");
String effectiveTimeI18n = SalaryI18nUtil.getI18nLabel(85904, "生效日期");
String payStartDateI18n = SalaryI18nUtil.getI18nLabel(85904, "起始发薪日期");
String payEndDateI18n = SalaryI18nUtil.getI18nLabel(85904, "最后发薪日期");
String adjustReasonI18n = SalaryI18nUtil.getI18nLabel(85431, "调整原因");
List<String> mustHeaders = Lists.newArrayList();
if (isInit) {
mustHeaders.add(userNameI18n);
mustHeaders.add(taxAgentI18n);
mustHeaders.add(payStartDateI18n);
} else if (isTaxAgentAdjust) {
mustHeaders.add(userNameI18n);
mustHeaders.add(taxAgentI18n);
mustHeaders.add(effectiveTimeI18n);
mustHeaders.add(adjustReasonI18n);
} else if (isSalaryItemAdjust) {
mustHeaders.add(userNameI18n);
mustHeaders.add(effectiveTimeI18n);
mustHeaders.add(adjustReasonI18n);
}
// 缺少的必须列
List<String> lackHeaders = mustHeaders.stream().filter(item -> !headers.contains(item)).collect(Collectors.toList());
String errorMsg = "";
String checkHeaderI18n = SalaryI18nUtil.getI18nLabel(101850, "缺少如下列,请检查:");
if (CollectionUtils.isNotEmpty(lackHeaders)) {
errorMsg = checkHeaderI18n + Joiner.on(",").join((Iterable<?>) lackHeaders);
}
// 有错误信息发送
if (StringUtils.isNotEmpty(errorMsg)) {
throw new SalaryRunTimeException(errorMsg);
}
return isValid;
}
/**
* 数据落库处理
*
* @param importHandleParam
*/
private void handleImportData(boolean isInit, SalaryArchiveImportHandleParam importHandleParam) {
List<SalaryArchivePO> salaryArchiveSaves = importHandleParam.getSalaryArchiveSaves();
List<SalaryArchivePO> salaryArchiveUpdates = importHandleParam.getSalaryArchiveUpdates();
List<SalaryArchiveItemPO> salaryArchiveItemSaves = importHandleParam.getSalaryArchiveItemSaves();
List<Long> salaryArchiveItemDelSalaryItemIds = importHandleParam.getSalaryArchiveItemDelSalaryItemIds();
// 初始化导入
if (isInit) {
// List<Long> salaryArchiveTaxAgentIds = importHandleParam.getSalaryArchiveTaxAgentSaves().stream().map(SalaryArchiveTaxAgentPO::getSalaryArchiveId).distinct().collect(Collectors.toList());
List<Long> salaryArchiveItemIds = importHandleParam.getSalaryArchiveItemSaves().stream().map(SalaryArchiveItemPO::getSalaryArchiveId).distinct().collect(Collectors.toList());
List<Long> salaryArchiveIds = salaryArchiveItemIds;
if (CollectionUtils.isNotEmpty(salaryArchiveIds)) {
List<List<Long>> partitionSalaryArchiveIds = Lists.partition(salaryArchiveIds, 1000);
for (List<Long> partitions : partitionSalaryArchiveIds) {
salaryArchiveTaxAgentMapper.deleteBySalaryArchiveId(partitions);
salaryArchiveItemMapper.deleteBySalaryArchiveId(partitions);
}
}
} else {
if (CollectionUtils.isNotEmpty(salaryArchiveItemDelSalaryItemIds)) {
salaryArchiveItemMapper.deleteBatchIds(salaryArchiveItemDelSalaryItemIds);
}
}
// 修改薪资档案
if (isInit && CollectionUtils.isNotEmpty(salaryArchiveUpdates)) {
salaryArchiveUpdates.forEach(getSalaryArchiveMapper()::update);
}
// 新增薪资档案
if (CollectionUtils.isNotEmpty(salaryArchiveSaves)) {
// 薪资档案
salaryArchiveMapper.batchInsert(salaryArchiveSaves);
}
// 薪资档案-薪资项目
if (CollectionUtils.isNotEmpty(salaryArchiveItemSaves)) {
salaryArchiveItemMapper.batchInsert(salaryArchiveItemSaves);
}
}
/**
* 处理历史数据
* 下回发版可删除
*/
public void handleHistory(Long currentEmployeeId) {
// 待定薪没设置过的默认为正常工资薪金所得
// new LambdaUpdateChainWrapper<>(salaryArchiveMapper)
// .eq(SalaryArchivePO::getDeleteType, 0)
// .eq(SalaryArchivePO::getTenantKey, tenantKey)
// .eq(SalaryArchivePO::getRunStatus, SalaryArchiveStatusEnum.PENDING.getValue())
// .isNull(SalaryArchivePO::getIncomeCategory)
// .set(SalaryArchivePO::getIncomeCategory, IncomeCategoryEnum.WAGES_AND_SALARIES.getValue())
// .update();
List<SalaryArchivePO> salaryArchives = getSalaryArchiveMapper().getHistoryData();
log.info("处理历史数据开始,数据总量==============={}", salaryArchives.size());
if (CollectionUtils.isEmpty(salaryArchives)) {
return;
}
Date today = new Date();
List<SalaryArchiveTaxAgentPO> salaryArchiveTaxAgents = getEffectiveTaxAgentList();
List<SalaryArchiveItemPO> salaryArchiveItems = salaryArchiveItemMapper.getEffectiveSalaryItems(SalaryArchiveItemQueryParam.builder().effectiveTime(today).build());
List<Long> salaryArchiveDelIds = salaryArchives.stream().map(SalaryArchivePO::getId).collect(Collectors.toList());
List<Long> salaryArchiveTaxAgentDelIds = salaryArchiveTaxAgents.stream().map(SalaryArchiveTaxAgentPO::getId).collect(Collectors.toList());
List<Long> salaryArchiveItemDelIds = salaryArchiveItems.stream().map(SalaryArchiveItemPO::getId).collect(Collectors.toList());
List<SalaryArchivePO> salaryArchiveAddList = Lists.newArrayList();
List<SalaryArchiveItemPO> salaryArchiveItemAddList = Lists.newArrayList();
Date endDate = today;
for (SalaryArchivePO sa : salaryArchives) {
List<SalaryArchiveTaxAgentPO> saTaxAgents = salaryArchiveTaxAgents.stream().filter(t -> t.getSalaryArchiveId().equals(sa.getId())).collect(Collectors.toList());
// 去重获取最新生效的个税口角义务人列表
saTaxAgents = saTaxAgents.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getSalaryArchiveId() + "-" + f.getTaxAgentId()))), ArrayList::new));
List<SalaryArchiveItemPO> saItemList = salaryArchiveItems.stream().filter(i -> i.getSalaryArchiveId().equals(sa.getId())).collect(Collectors.toList());
for (SalaryArchiveTaxAgentPO st : saTaxAgents) {
Date finalEndDate = endDate;
List<SalaryArchiveItemPO> saItems = saItemList.stream().filter(si -> !si.getEffectiveTime().after(finalEndDate)).collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getSalaryArchiveId() + "-" + f.getSalaryItemId()))), ArrayList::new));
SalaryArchivePO newSA = SalaryArchivePO.builder().id(IdGenerator.generate()).employeeId(sa.getEmployeeId()).taxAgentId(st.getTaxAgentId()).payStartDate(st.getEffectiveTime())
// .runStatus(SalaryArchiveStatusEnum.FIXED.getValue())
// .modifier(0L)
.createTime(today).updateTime(today).creator(currentEmployeeId).deleteType(NumberUtils.INTEGER_ZERO).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build();
salaryArchiveAddList.add(newSA);
saItems.forEach(sf -> {
salaryArchiveItemAddList.add(SalaryArchiveItemPO.builder()
.salaryArchiveId(newSA.getId()).employeeId(newSA.getEmployeeId()).effectiveTime(sf.getEffectiveTime()).adjustReason(sf.getAdjustReason()).salaryItemId(sf.getSalaryItemId()).itemValue(sf.getItemValue()).description(sf.getDescription())
// 不用设置操作人
.operator(currentEmployeeId).operateTime(today).createTime(today).updateTime(today).creator(currentEmployeeId).deleteType(NumberUtils.INTEGER_ZERO).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build());
});
// endDate = st.getEffectiveTime();
}
}
// 逻辑删除历史数据
List<List<Long>> partition = Lists.partition(salaryArchiveDelIds, 999);
for (List<Long> part : partition) {
salaryArchiveMapper.batchDeleteHistoryData(SalaryArchivePO.builder().ids(part).build());
}
List<List<Long>> partitionTA = Lists.partition(salaryArchiveTaxAgentDelIds, 999);
for (List<Long> part : partitionTA) {
salaryArchiveTaxAgentMapper.batchDeleteHistoryData(SalaryArchiveTaxAgentPO.builder().ids(part).build());
}
List<List<Long>> partitionItem = Lists.partition(salaryArchiveItemDelIds, 999);
for (List<Long> part : partitionItem) {
salaryArchiveItemMapper.batchDeleteHistoryData(SalaryArchiveItemPO.builder().ids(part).build());
}
// 新增迁移数据
if (CollectionUtils.isNotEmpty(salaryArchiveAddList)) {
this.salaryArchiveMapper.batchInsert(salaryArchiveAddList);
}
if (CollectionUtils.isNotEmpty(salaryArchiveItemAddList)) {
this.salaryArchiveItemMapper.batchInsert(salaryArchiveItemAddList);
}
log.info("处理历史数据结束===============");
}
@Override
public Map<String, Object> selectSalaryArchiveColumns(SalaryArchiveImportTypeEnum salaryArchiveImportTypeEnum) {
HashMap<String, Object> map = Maps.newHashMap();
//类型为档案初始化
boolean isInit = salaryArchiveImportTypeEnum.getValue().equals(SalaryArchiveImportTypeEnum.INIT.getValue());
//类型为调整个税扣缴义务人
boolean isTaxAgentAdjust = salaryArchiveImportTypeEnum.getValue().equals(SalaryArchiveImportTypeEnum.TAXAGENTADJUST.getValue());
//类型为调薪
boolean isSalaryItemAdjust = salaryArchiveImportTypeEnum.getValue().equals(SalaryArchiveImportTypeEnum.SALARYITEMADJUST.getValue());
//固定列
map.put(SalaryI18nUtil.getI18nLabel(85429, "姓名"), "username");
map.put(SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"), "taxAgentName");
map.put(SalaryI18nUtil.getI18nLabel(85904, "生效日期"), "taxAgentEffectiveTime");
map.put(SalaryI18nUtil.getI18nLabel(86185, "部门"), "departmentName");
map.put(SalaryI18nUtil.getI18nLabel(86186, "手机号"), "mobile");
map.put(SalaryI18nUtil.getI18nLabel(91075, "员工状态"), "employeeStatus");
List<SalaryItemPO> salaryItems = salaryItemMapper.getCanAdjustSalaryItems();
if (isTaxAgentAdjust || isSalaryItemAdjust) {
map.put(SalaryI18nUtil.getI18nLabel(85431, "调整原因"), "adjustReason");
}
//动态列
// 获取所有可被引用的薪资项目
if (isInit || isSalaryItemAdjust) {
for (SalaryItemPO salaryItem : salaryItems) {
map.put(salaryItem.getName(), salaryItem.getCode());
}
}
return map;
}
}