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

1238 lines
69 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.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.taxrate.TaxAgent;
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.SalaryArchiveTaxAgentAdjustReasonEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.service.SalaryArchiveService;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryI18nUtil;
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.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import dm.jdbc.util.IdGenerator;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import weaver.file.ImageFileManager;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
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
**/
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 SalaryBatchService salaryBatchService;
private TaxAgentBiz taxAgentService = new TaxAgentBiz();
private ExecutorService taskExecutor;
@Override
public SalaryArchivePO getById(Long salaryArchiveId) {
return SalaryArchiveMapper.getById(salaryArchiveId);
}
@Override
public PageInfo<SalaryArchiveListDTO> listPage(SalaryArchiveQueryParam queryParam) {
return SalaryArchiveMapper.listPage(queryParam);
}
/**
* 获取薪资档案对应的当前生效的薪资项目
*
* @param salaryArchivesIds
* @return
*/
@Override
public List<SalaryArchiveItemPO> getCurrentEffectiveItemList(Collection<Long> salaryArchivesIds, Collection<Long> salaryItemIds) {
// 没有薪资项目时,给个不存在的,否则加载所有不合理 fixme
salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds;
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) {
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<TaxAgent> 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());
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<TaxAgent> 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());
// 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();
map.put("taxAgentName", optionalTaxAgent.isPresent() ? optionalTaxAgent.get().get("taxAgentName").toString() : "");
map.put("taxAgentId", optionalTaxAgent.isPresent() ? optionalTaxAgent.get().get("taxAgentId").toString() : "");
map.put("taxAgentEffectiveTime", optionalTaxAgent.isPresent() ? optionalTaxAgent.get().get("taxAgentEffectiveTime").toString() : "");
map.put("departmentName", e.getDepartmentName());
map.put("mobile", e.getMobile());
map.put("employeeStatus", e.getEmployeeStatus());
// 薪资项目动态
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) {
// 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, "状态")
};
// 2.表头
List<Object> headerList = new ArrayList<>(Arrays.asList(header));
for (SalaryItemPO salaryItem : salaryItems) {
headerList.add(salaryItem.getName());
}
// 获取所有个税扣缴义务人
Collection<TaxAgent> taxAgentList = taxAgentService.listAll();
Collection<SalaryArchiveListDTO> salaryArchives = SalaryArchiveMapper.list(queryParam);
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(e.get("username").toString());
row.add(e.get("taxAgentName").toString());
row.add(e.get("departmentName").toString());
row.add(e.get("mobile") == null ? "" : e.get("mobile").toString());
row.add(e.get("employeeStatus").toString());
// 薪资项目数据
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) {
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, "个税扣缴义务人"));
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(91075, "状态"));
if (isInit || isSalaryItemAdjust) {
for (SalaryItemPO salaryItem : salaryItems) {
header.add(salaryItem.getName());
}
}
// 获取所有个税扣缴义务人
Collection<TaxAgent> taxAgentList = taxAgentService.listAll();
Collection<SalaryArchiveListDTO> salaryArchives = SalaryArchiveMapper.list(queryParam);
List<Map<String, Object>> listMaps = buildSalaryArchiveData(salaryArchives, taxAgentList, salaryItems, Boolean.FALSE);
// 组装数据
List<List<Object>> rows = new ArrayList<>();
rows.add(header);
listMaps.forEach(e -> {
List<Object> row = new ArrayList<>();
row.add(e.get("username").toString());
row.add(e.get("taxAgentName").toString());
if (isTaxAgentAdjust || isSalaryItemAdjust) {
row.add(isTaxAgentAdjust ? e.get("taxAgentEffectiveTime").toString() : "");
}
row.add("");
row.add(e.get("departmentName").toString());
row.add(e.get("mobile") == null ? "" : e.get("mobile").toString());
row.add(e.get("employeeStatus").toString());
// 调薪
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, "必填")));
if (isInit || isTaxAgentAdjust) {
excelComments.add(new ExcelComment(1, 0, 4, 2, SalaryI18nUtil.getI18nLabel(100344, "必填")));
}
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, "必填,可填写如:入职,转正,调薪,调岗调薪,离职,其他,初始化")));
}
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()
// .id(IdGenerator.generate())
.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) {
return getSalaryArchiveData(localDateRange, employeeIds, Boolean.FALSE);
}
@Override
public List<SalaryArchiveDataDTO> getSalaryArchiveTaxAgentData(LocalDateRange localDateRange, Collection<Long> employeeIds) {
return getSalaryArchiveData(localDateRange, employeeIds, Boolean.TRUE);
}
/**
* 根据日期范围和人员获取薪资档案数据
*
* @param localDateRange
* @param employeeIds
* @param isOnlyTaxAgent
* @return
*/
private List<SalaryArchiveDataDTO> getSalaryArchiveData(LocalDateRange localDateRange, Collection<Long> employeeIds, boolean isOnlyTaxAgent) {
// 获取个税扣缴义务人调整数据
List<SalaryArchiveTaxAgentPO> salaryArchiveTaxAgentList = salaryArchiveTaxAgentMapper.listByParam(SalaryArchiveTaxAgentQueryParam.builder().employeeIds(employeeIds).effectiveTime(localDateRange.getEndDate()).build());
List<Long> allEmployeeIds = salaryArchiveTaxAgentList.stream().map(SalaryArchiveTaxAgentPO::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;
if (isOnlyTaxAgent || CollectionUtils.isEmpty(salaryItemIds)) {
salaryArchiveItemDataList = Lists.newArrayList();
} else {
salaryArchiveItemDataList = salaryArchiveItemMapper.listByParam(SalaryArchiveItemQueryParam.builder().salaryItemIds(salaryItemIds).employeeIds(employeeIds).effectiveTime(new Date()).build());
}
return SalaryArchiveBO.buildSalaryArchiveData(salaryArchiveTaxAgentList,
salaryArchiveItemDataList,
localDateRange,
allEmployeeIds,
isOnlyTaxAgent);
}
/**
* 导入薪资档案
*/
public Map<String,Object> importSalaryArchive(SalaryArchiveImportHandleParam param) {
//1、参数校验
vaildImportParam(param);
String imageId = param.getImageId();
String importType = param.getImportType();
// 2.构建导入需要的数据
SalaryArchiveImportHandleParam importHandleParam = buildImportHandleParam();
InputStream fileInputStream = null;
try {
// try {
fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(imageId));
// fileInputStream = new FileInputStream("C:\\Users\\钱涛\\Desktop\\salaryItemAdjust.xlsx");
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
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();
int effectiveTimeIndex = 0;
for (int j = 0; j < headers.size(); j++) {
if (headers.get(j).equals(SalaryI18nUtil.getI18nLabel(85904, "生效日期"))) {
effectiveTimeIndex = j;
break;
}
}
// 错误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);
// 3.校验行内容
boolean isError = singleRowCheck(importType, allEmployeeIds, map, headers, effectiveTimeIndex, 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.数据入库处理
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);
}
}
@Override
public Map<String, Object> preview(SalaryArchiveImportHandleParam param) {
//1、参数校验
vaildImportParam(param);
Map<String, Object> map = new HashMap<>();
InputStream fileInputStream = null;
try {
// try {
fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));
// fileInputStream = new FileInputStream("C:\\Users\\钱涛\\Desktop\\salaryItemAdjust.xlsx");
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// }
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() {
// 获取所有可被引用的薪资项目
List<SalaryItemPO> salaryItems = salaryItemMapper.getCanAdjustSalaryItems();
Collection<Long> salaryItemIds = salaryItems.stream().map(SalaryItemPO::getId).collect(Collectors.toList());
Date now = new Date();
return SalaryArchiveImportHandleParam.builder()
// 获取租户下所有的人员
.employees(employBiz.listEmployee())
// 获取所有个税扣缴义务人
.taxAgentList(taxAgentService.listAll())
.salaryItems(salaryItems)
// 查询已有的薪资档案基本数据
.salaryArchives(SalaryArchiveMapper.list(SalaryArchiveQueryParam.builder().build()))
.salaryItemIds(salaryItemIds)
// 查询已生效的薪资项目数据
.effectiveItemList(getEffectiveItemList(salaryItemIds))
// 查询未生效的薪资项目数据
.ineffectiveItemList(getIneffectiveItemList(salaryItemIds))
// 查询已生效的个税扣缴义务人数据
.effectiveTaxAgentList(getEffectiveTaxAgentList())
// 查询未生效的个税扣缴义务人数据
.ineffectiveTaxAgentList(getIneffectiveTaxAgentList())
// 当前时间
.nowTime(now)
// 当天
.today(now)
// 待保存薪资档案
.salaryArchiveSaves(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);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(101723, "该员工的薪资档案记录有误,请检查"), finalErrorCount.get() + 1, finalErrorCount.get() + 1, 0, 0);
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("effectiveTime")).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);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(101723, "该员工的薪资档案记录有误,请检查"), finalErrorCount.get() + 1, finalErrorCount.get() + 1, 0, 0);
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, int effectiveTimeIndex,
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 adjustReasonI18n = SalaryI18nUtil.getI18nLabel(85431, "调整原因");
// 1.姓名
String userName = Optional.ofNullable(map.get(userNameI18n)).orElse("").toString();
String deparmentName = Optional.ofNullable(map.get(SalaryI18nUtil.getI18nLabel(86185, "部门"))).orElse("").toString();
List<Long> employeeSameIds = importHandleParam.getEmployees().stream().filter(e -> (StringUtils.isBlank(userName) || Objects.equals(e.getUsername(), userName))
&& (StringUtils.isBlank(deparmentName) || Objects.equals(e.getDepartmentName(), deparmentName))).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<TaxAgent> optionalTaxAgent = importHandleParam.getTaxAgentList().stream().filter(m -> m.getName().equals(taxAgentCellVal)).findFirst();
Long taxAgentId = optionalTaxAgent.map(TaxAgent::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());
}
// 构建薪资档案
SalaryArchivePO finalSalaryArchive = buildSalaryArchive(isInit, employeeId, 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)
// 调整原因列判空(调薪或调整个税扣缴义务人)
|| (adjustReasonI18n.equals(key) && (isTaxAgentAdjust || isSalaryItemAdjust)));
// 判空
if (userNameI18n.equals(key) && StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", key + "不能为空");
excelComments.add(errorMessageMap);
}
// 个税扣缴义务人列判空(初始化导入或调整个税扣缴义务人)
if ((taxAgentI18n.equals(key) && (isInit || isTaxAgentAdjust)) && StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", key + "不能为空");
excelComments.add(errorMessageMap);
}
if (effectiveTimeI18n.equals(key) && StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", key + "不能为空");
excelComments.add(errorMessageMap);
}
// 调整原因列判空(调薪或调整个税扣缴义务人)
if ((adjustReasonI18n.equals(key) && (isTaxAgentAdjust || isSalaryItemAdjust)) && StringUtils.isEmpty(cellVal)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message", key + "不能为空");
excelComments.add(errorMessageMap);
}
if (isEmpty) {
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100577, "不能为空"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
// 1.姓名列处理
if (!isEmpty && userNameI18n.equals(key)) {
if (CollectionUtils.isEmpty(employeeSameIds) || employeeSameIds.size() > 1) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message","员工信息不能为空且不可重复(姓名与部门同时确认唯一)");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100578, "员工信息不能为空且不可重复(姓名与部门同时确认唯一)"), errorCount + 1, errorCount + 1, j, j);
isError = true;
} else if (employeeId == null) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message","姓名错误,系统内不存在该姓名");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100579, "姓名错误,系统内不存在该姓名"), errorCount + 1, errorCount + 1, j, j);
isError = true;
// (调薪或调整个税扣缴义务人)
} else if (finalSalaryArchive == null && (isTaxAgentAdjust || isSalaryItemAdjust)) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message","该人员的薪资档案不存在,请先初始化");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(101653, "该人员的薪资档案不存在,请先初始化"), errorCount + 1, errorCount + 1, j, j);
isError = true;
}
// 2.个税扣缴义务人列处理(初始化导入或调整个税扣缴义务人)
} else if (!isEmpty && taxAgentI18n.equals(key) && (isInit || isTaxAgentAdjust)) {
isError = handleTaxAgent(isError, isInit, effectiveTimeIndex, excelComments, errorCount, j, taxAgentId, effectiveTime, finalSalaryArchive, adjustReason, importHandleParam);
// 3.生效时间处理
} else if (!isEmpty && effectiveTimeI18n.equals(key) && effectiveTime == null) {
Map<String, String> errorMessageMap = Maps.newHashMap();
errorMessageMap.put("message","生效日期错误或格式不正确,正确格式示例为'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","调整原因不存在");
excelComments.add(errorMessageMap);
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100591, "调整原因不存在"), errorCount + 1, errorCount + 1, j, j);
isError = true;
// 5.薪资项目列处理(初始化导入或调薪)
} else {
// 薪资项目数据
if (effectiveTime == null || finalSalaryArchive == null || !(isInit || isSalaryItemAdjust)) {
continue;
}
isError = handleSalaryItem(isError, isInit, effectiveTimeIndex, excelComments, errorCount, j,
effectiveTime, finalSalaryArchive, adjustReason, importHandleParam, key, cellVal, map);
}
}
return isError;
}
private SalaryArchivePO buildSalaryArchive(boolean isInit, Long employeeId, SalaryArchiveImportHandleParam importHandleParam) {
Optional<SalaryArchiveListDTO> optionalSA = importHandleParam.getSalaryArchives().stream().filter(p -> p.getEmployeeId().toString().equals(employeeId != null ? employeeId.toString() : "")).findFirst();
SalaryArchivePO salaryArchive = null;
if (optionalSA.isPresent()) {
// 修改档案
SalaryArchiveListDTO sa = optionalSA.get();
salaryArchive = new SalaryArchivePO();
salaryArchive.setId(sa.getId());
salaryArchive.setEmployeeId(sa.getEmployeeId());
} else if (employeeId != null && isInit) {
// 新增档案
salaryArchive = SalaryArchivePO.builder()
.id(IdGenerator.generate())
.employeeId(employeeId)
.createTime(importHandleParam.getNowTime())
.updateTime(importHandleParam.getNowTime())
.creator((long) user.getUID())
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.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, int effectiveTimeIndex,
List<Map<String, String>> excelComments, int errorCount, int j,
Long taxAgentId, Date effectiveTime, SalaryArchivePO finalSalaryArchive, String taxAgentAdjustReason, SalaryArchiveImportHandleParam importHandleParam) {
if (taxAgentId == null) {
// salaryBatchService.createExcelComment(excelComments, SalaryI18nUtil.getI18nLabel(100545, "个税扣缴义务人不存在"), errorCount + 1, errorCount + 1, j, j);
isError = true;
} else 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","生效日期不可早于当前已生效的调整日期");
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","调整前后不可相同");
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","与未生效的调整后不可相同");
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","调整前后不可相同");
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","与未生效的调整后不可相同");
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","调整前后不可相同");
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","与未生效的调整后不可相同");
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()
// .id(IdGenerator.generate())
.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 errorCount
* @param j
* @param effectiveTime
* @param finalSalaryArchive
* @param salaryItemAdjustReason
* @param importHandleParam
* @param cellVal
* @return
*/
private boolean handleSalaryItem(boolean isError, boolean isInit, int effectiveTimeIndex,
List<Map<String, String>> excelComments, int errorCount, int j,
Date effectiveTime, SalaryArchivePO finalSalaryArchive, String salaryItemAdjustReason, SalaryArchiveImportHandleParam importHandleParam,
String key, String cellVal, Map<String, Object> map) {
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","生效日期不可早于当前已生效的调整日期");
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","调整前后不可相同");
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","与未生效的调整后不可相同");
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","调整前后不可相同");
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","与未生效的调整后不可相同");
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","调整前后不可相同");
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","与未生效的调整后不可相同");
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()
// .id(IdGenerator.generate())
.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) {
// 没有薪资项目时,给个不存在的,否则加载所有不合理
salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds;
return salaryArchiveItemMapper.getEffectiveSalaryItems(SalaryArchiveItemQueryParam.builder().effectiveTime(new Date()).salaryItemIds(salaryItemIds).build());
}
private List<SalaryArchiveItemPO> getIneffectiveItemList(Collection<Long> salaryItemIds) {
// 没有薪资项目时,给个不存在的,否则加载所有不合理
salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds;
return salaryArchiveItemMapper.getIneffectiveSalaryItems(SalaryArchiveItemQueryParam.builder().salaryItemIds(salaryItemIds).effectiveTime(new Date()).build());
}
private List<SalaryArchiveTaxAgentPO> getEffectiveTaxAgentList() {
return salaryArchiveTaxAgentMapper.getEffectiveTaxAgentList(SalaryArchiveTaxAgentQueryParam.builder().effectiveTime(new Date()).build());
}
private List<SalaryArchiveTaxAgentPO> getIneffectiveTaxAgentList() {
return salaryArchiveTaxAgentMapper.getIneffectiveTaxAgentList(SalaryArchiveTaxAgentQueryParam.builder().effectiveTime(new Date()).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 adjustReasonI18n = SalaryI18nUtil.getI18nLabel(85431, "调整原因");
List<String> mustHeaders = Lists.newArrayList();
if (isInit) {
mustHeaders.add(userNameI18n);
mustHeaders.add(taxAgentI18n);
mustHeaders.add(effectiveTimeI18n);
} 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<SalaryArchiveTaxAgentPO> salaryArchiveTaxAgentSaves = importHandleParam.getSalaryArchiveTaxAgentSaves();
List<SalaryArchiveItemPO> salaryArchiveItemSaves = importHandleParam.getSalaryArchiveItemSaves();
List<Long> salaryArchiveTaxAgentDelTaxAgentIds = importHandleParam.getSalaryArchiveTaxAgentDelTaxAgentIds();
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 = salaryArchiveTaxAgentIds.stream().filter(salaryArchiveItemIds::contains).collect(Collectors.toList());
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(salaryArchiveTaxAgentDelTaxAgentIds)) {
salaryArchiveTaxAgentMapper.deleteBatchIds(salaryArchiveTaxAgentDelTaxAgentIds);
}
if (CollectionUtils.isNotEmpty(salaryArchiveItemDelSalaryItemIds)) {
salaryArchiveItemMapper.deleteBatchIds(salaryArchiveItemDelSalaryItemIds);
}
}
// 新增薪资档案
if (CollectionUtils.isNotEmpty(salaryArchiveSaves)) {
// 薪资档案
SalaryArchiveMapper.batchInsert(salaryArchiveSaves);
}
// 薪资档案-个税扣缴义务人
if (CollectionUtils.isNotEmpty(salaryArchiveTaxAgentSaves)) {
salaryArchiveTaxAgentMapper.batchInsert(salaryArchiveTaxAgentSaves);
}
// 薪资档案-薪资项目
if (CollectionUtils.isNotEmpty(salaryArchiveItemSaves)) {
salaryArchiveItemMapper.batchInsert(salaryArchiveItemSaves);
}
}
}