package com.engine.salary.service.impl; import cn.hutool.core.util.StrUtil; import com.api.formmode.mybatis.util.SqlProxyHandle; import com.engine.common.util.ServiceUtil; import com.engine.core.impl.Service; import com.engine.salary.biz.SalaryArchiveBiz; import com.engine.salary.biz.SalaryArchiveItemBiz; import com.engine.salary.biz.SalaryItemBiz; import com.engine.salary.common.LocalDateRange; import com.engine.salary.config.SalaryElogConfig; import com.engine.salary.constant.SalaryDefaultTenantConstant; import com.engine.salary.entity.datacollection.DataCollectionEmployee; import com.engine.salary.entity.salaryarchive.config.ArchiveFieldConfig; import com.engine.salary.entity.salaryarchive.dto.SalaryArchiveListDTO; import com.engine.salary.entity.salaryarchive.dto.SalaryItemAdjustRecordListDTO; import com.engine.salary.entity.salaryarchive.param.*; import com.engine.salary.entity.salaryarchive.po.SalaryArchiveItemPO; import com.engine.salary.entity.salaryarchive.po.SalaryArchivePO; import com.engine.salary.entity.salaryitem.param.SalaryItemSearchParam; import com.engine.salary.entity.salaryitem.po.SalaryItemPO; import com.engine.salary.entity.taxagent.param.TaxAgentQueryParam; import com.engine.salary.entity.taxagent.po.TaxAgentPO; import com.engine.salary.enums.UserStatusEnum; import com.engine.salary.enums.auth.AuthFilterTypeEnum; import com.engine.salary.enums.datacollection.UseEmployeeTypeEnum; import com.engine.salary.enums.salaryarchive.SalaryArchiveFieldTypeEnum; import com.engine.salary.enums.salaryarchive.SalaryArchiveItemAdjustReasonEnum; import com.engine.salary.enums.salaryarchive.SalaryArchiveStatusEnum; import com.engine.salary.exception.SalaryRunTimeException; import com.engine.salary.mapper.archive.SalaryArchiveItemMapper; import com.engine.salary.mapper.salaryitem.SalaryItemMapper; import com.engine.salary.service.*; import com.engine.salary.sys.entity.vo.UploadConfigResponse; import com.engine.salary.util.SalaryDateUtil; import com.engine.salary.util.SalaryEntityUtil; import com.engine.salary.util.SalaryI18nUtil; import com.engine.salary.util.SalaryLoggerUtil; import com.engine.salary.util.db.IdGenerator; import com.engine.salary.util.db.MapperProxyFactory; import com.engine.salary.util.excel.ExcelUtil; import com.engine.salary.util.page.PageInfo; import com.engine.salary.util.valid.ValidUtil; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.math.NumberUtils; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import weaver.hrm.User; import weaver.wechat.util.Utils; import java.text.SimpleDateFormat; import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; /** * 薪资档案薪资项目 *

Copyright: Copyright (c) 2022

*

Company: 泛微软件

* * @author qiantao * @version 1.0 **/ @Slf4j public class SalaryArchiveItemServiceImpl extends Service implements SalaryArchiveItemService { private SalaryArchiveBiz salaryArchiveMapper = new SalaryArchiveBiz(); private SalaryItemBiz salaryItemMapper = new SalaryItemBiz(); private SalaryArchiveItemBiz salaryArchiveItemMapper = new SalaryArchiveItemBiz(); private SalaryArchiveItemMapper getSalaryArchiveItemMapper() { return MapperProxyFactory.getProxy(SalaryArchiveItemMapper.class); } private SalaryItemMapper getSalaryItemMapper() { return SqlProxyHandle.getProxy(SalaryItemMapper.class); } @Override public SalaryArchiveItemPO getById(Long salaryArchiveItemId) { return salaryArchiveItemMapper.getById(salaryArchiveItemId); } private SalaryArchiveItemService getSalaryArchiveItemService(User user) { return ServiceUtil.getService(SalaryArchiveItemServiceImpl.class, user); } private TaxAgentService getTaxAgentService(User user) { return ServiceUtil.getService(TaxAgentServiceImpl.class, user); } private SalaryItemService getSalaryItemService(User user) { return ServiceUtil.getService(SalaryItemServiceImpl.class, user); } private SalaryArchiveService getSalaryArchiveService(User user) { return ServiceUtil.getService(SalaryArchiveServiceImpl.class, user); } private SalaryEmployeeService getSalaryEmployeeService(User user) { return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user); } /** * 获取未生效 lt * * @param salaryArchiveId * @param salaryItemIds * @return */ private List getIneffectiveSalaryItems(Long salaryArchiveId, List salaryItemIds) { // 没有薪资项目时,给个不存在的,否则加载所有不合理 salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds; ArrayList salaryArchiveIds = new ArrayList<>(); salaryArchiveIds.add(salaryArchiveId); return salaryArchiveItemMapper.getIneffectiveSalaryItems(SalaryArchiveItemQueryParam.builder() .salaryArchiveId(salaryArchiveId) .salaryArchivesIds(salaryArchiveIds) .salaryItemIds(salaryItemIds) .effectiveTime(new Date()).build()); } private List getIneffectiveSalaryItems(Collection salaryArchivesIds, Collection salaryItemIds) { // 薪资档案id List salaryArchiveIds = CollectionUtils.isEmpty(salaryArchivesIds) ? Collections.singletonList(0L) : (List) salaryArchivesIds; // 没有薪资项目时,给个不存在的,否则加载所有不合理 salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds; return salaryArchiveItemMapper.getIneffectiveSalaryItems(SalaryArchiveItemQueryParam.builder() .salaryArchivesIds(salaryArchiveIds) .salaryItemIds(salaryItemIds) .effectiveTime(new Date()).build()); } @Override public List getSalaryItemsBySalaryArchiveIdAndItemIds(Long salaryArchiveId, List salaryItemIds) { // 没有薪资项目时,给个不存在的,否则加载所有不合理 salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds; return salaryArchiveItemMapper.getEffectiveSalaryItems(SalaryArchiveItemQueryParam.builder() .salaryArchiveId(salaryArchiveId) .salaryItemIds(salaryItemIds) .build()); } /** * 获取当前已生效 gt * * @param salaryArchiveId * @param salaryItemIds * @return */ @Override public List getEffectiveSalaryItems(Long salaryArchiveId, List salaryItemIds) { // 没有薪资项目时,给个不存在的,否则加载所有不合理 salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds; return salaryArchiveItemMapper.getEffectiveSalaryItems(SalaryArchiveItemQueryParam.builder() .salaryArchiveId(salaryArchiveId) .salaryItemIds(salaryItemIds) .effectiveTime(new Date()).build()); } /** * 获取薪资档案对应的当前生效的薪资项目 * * @param salaryArchivesIds * @return */ @Override public List getCurrentEffectiveItemList(Collection salaryArchivesIds, Collection salaryItemIds) { // 没有薪资项目时,给个不存在的,否则加载所有不合理 salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds; // 薪资档案id List salaryArchiveIds = CollectionUtils.isEmpty(salaryArchivesIds) ? Collections.singletonList(0L) : (List) salaryArchivesIds; List salaryArchiveItems = this.getEffectiveItemList(salaryArchiveIds, salaryItemIds); return salaryArchiveItems.stream() .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getSalaryArchiveId() + "-" + f.getSalaryItemId()))), ArrayList::new)); } /** * 获取当前已生效列表 * * @param salaryArchiveIds * @param salaryItemIds * @return */ private List getEffectiveItemList(Collection salaryArchiveIds, Collection salaryItemIds) { List salaryArchiveItems = Lists.newArrayList(); List> partition = Lists.partition(Lists.newArrayList(salaryArchiveIds), 999); partition.forEach(part -> salaryArchiveItems.addAll( salaryArchiveItemMapper.getEffectiveSalaryItems(SalaryArchiveItemQueryParam.builder() .salaryArchivesIds(part) .salaryItemIds(salaryItemIds) .effectiveTime(new Date()).build())) ); // 解密 return salaryArchiveItems; } @Override public Map> getEffectiveItemListMap(Collection salaryArchiveIds, boolean isNoNeedSalaryItem, Collection salaryItemIds) { // 没有薪资项目时,给个不存在的,否则加载所有不合理 salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds; // 薪资档案id List saIds = CollectionUtils.isEmpty(salaryArchiveIds) ? Collections.singletonList(0L) : (List) salaryArchiveIds; List salaryArchiveItems = Lists.newArrayList(); if (isNoNeedSalaryItem) { salaryArchiveItems.addAll(getEffectiveItemList(saIds, salaryItemIds)); } else { salaryArchiveItems = this.getEffectiveItemList(saIds, salaryItemIds); } return SalaryEntityUtil.group2Map(salaryArchiveItems, k -> k.getSalaryArchiveId() + "-" + k.getSalaryItemId()); } @Override public Map> getIneffectiveItemListMap(Collection salaryArchiveIds, boolean isNoNeedSalaryItem, Collection salaryItemIds) { // 没有薪资项目时,给个不存在的,否则加载所有不合理 salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds; // 薪资档案id Collection saIds = CollectionUtils.isEmpty(salaryArchiveIds) ? Collections.singletonList(0L) : salaryArchiveIds; List salaryArchiveItems = Lists.newArrayList(); if (isNoNeedSalaryItem) { salaryArchiveItems.addAll(getIneffectiveSalaryItems(saIds, salaryItemIds)); } else { List> partition = Lists.partition((List) saIds, 1000); Collection finalSalaryItemIds = salaryItemIds; partition.forEach(part -> { salaryArchiveItems.addAll(getIneffectiveSalaryItems(saIds, finalSalaryItemIds)); }); } return SalaryEntityUtil.group2Map(salaryArchiveItems, k -> k.getSalaryArchiveId() + "-" + k.getSalaryItemId()); } @Override public String editSingleSalaryItem(SalaryArchiveItemSaveParam salaryArchiveItemSaveParam) { // 检查参数 SalaryArchiveItemSaveParam.checkParam(salaryArchiveItemSaveParam); Long salaryArchiveId = salaryArchiveItemSaveParam.getSalaryArchiveId(); // 获取所有可被引用的薪资项目 List salaryItems = getCanAdjustSalaryItems(); Map salaryItemMap = SalaryEntityUtil.convert2Map(salaryItems, SalaryItemPO::getId); // 待处理薪资项目 List salaryArchiveItems = salaryArchiveItemSaveParam.getSalaryArchiveItems().stream() .filter(e -> salaryItemMap.containsKey(e.getSalaryItemId())) .collect(Collectors.toList()); List salaryItemIds = salaryArchiveItems.stream().map(SalaryArchiveItemDetailSaveParam::getSalaryItemId).collect(Collectors.toList()); // 薪资档案 SalaryArchivePO salaryArchive = salaryArchiveMapper.getById(salaryArchiveId); if (salaryArchive != null) { // 停薪列表禁止操作 boolean isDisabled = salaryArchive.getRunStatus().equals(SalaryArchiveStatusEnum.STOP_FROM_PENDING.getValue()) || salaryArchive.getRunStatus().equals(SalaryArchiveStatusEnum.STOP_FROM_SUSPEND.getValue()); if (isDisabled) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(115437, "停薪列表禁止操作")); } SalaryArchiveItemPO salaryArchiveItem = null; if (salaryArchiveItemSaveParam.getSalaryArchiveItemId() != null) { salaryArchiveItem = salaryArchiveItemMapper.getById(salaryArchiveItemSaveParam.getSalaryArchiveItemId()); if (salaryArchiveItem == null || !salaryArchiveItem.getSalaryArchiveId().equals(salaryArchiveId)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100428, "该薪资档案的薪资项目的调整记录不存在")); } if (salaryArchiveItemSaveParam.getSalaryArchiveItems().size() > 1) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(149535, "单个调整不能处理多个薪资项目")); } else if (!salaryArchiveItems.get(0).getSalaryItemId().equals(salaryArchiveItem.getSalaryItemId())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(149539, "单个调薪的目标项目和调整明细项目id不一致")); } } // 构建更新PO SalaryArchiveItemPO updateSalaryArchiveItemPO = buildUpdateSalaryArchiveItemPO(salaryArchiveItemSaveParam, salaryArchiveItems, salaryItemIds, salaryArchiveItem); salaryArchiveItemMapper.updateIgnoreNull(updateSalaryArchiveItemPO); // 查询更新后的po SalaryArchiveItemPO saiNew = salaryArchiveItemMapper.getById(updateSalaryArchiveItemPO.getId()); // 记录操作日志 String name = SalaryI18nUtil.getI18nLabel(0, "编辑调薪记录"); SalaryLoggerUtil.recordUpdateSingleLog(SalaryElogConfig.salaryArchiveItemAdjustLoggerTemplate, saiNew.getId(), name + ":" + saiNew.getId(), name, name + ":" + saiNew.getId(), salaryArchiveItem, saiNew, user ); } return StringUtils.EMPTY; } /** * @return null * @description 构建薪资档案中调薪的更新PO * @author Harryxzy * @date 2022/11/14 14:24 */ private SalaryArchiveItemPO buildUpdateSalaryArchiveItemPO(SalaryArchiveItemSaveParam salaryArchiveItemSaveParam, List salaryArchiveItems, List salaryItemIds, SalaryArchiveItemPO salaryArchiveItem) { // 获取所有可被引用的薪资项目 List salaryItems = getSalaryArchiveItemService(user).getCanAdjustSalaryItems(); // 获取生效+未生效的数据 List salaryItemsBySalaryArchiveIdAndItemIds = getSalaryItemsBySalaryArchiveIdAndItemIds(salaryArchiveItemSaveParam.getSalaryArchiveId(), salaryItemIds); // 获取当前已生效数据 // List effectiveSalaryItems = getEffectiveSalaryItems(salaryArchiveItemSaveParam.getSalaryArchiveId(), salaryItemIds); // 待保存生效时间 Date saveEffectiveTime = salaryArchiveItemSaveParam.getEffectiveTime(); salaryArchiveItems.forEach(e -> { // 已生效 // List effectiveList = effectiveSalaryItems.stream().filter(i -> i.getSalaryItemId().equals(e.getSalaryItemId())).collect(Collectors.toList()); // 当前已生效 // SalaryArchiveItemPO effectiveSalaryItem = CollectionUtils.isNotEmpty(effectiveList) && effectiveList.size() > 0 ? effectiveList.get(0) : null; List list = salaryItemsBySalaryArchiveIdAndItemIds.stream().filter(i -> i.getSalaryItemId().equals(e.getSalaryItemId())).collect(Collectors.toList()); // 判断该薪资项目是否是数字 Optional optional = salaryItems.stream().filter(i -> i.getId().equals(e.getSalaryItemId())).findFirst(); if (optional.isPresent()) { SalaryItemPO salaryItemPO = optional.get(); boolean isNotNumber = salaryItemPO.getDataType().equals(SalaryArchiveFieldTypeEnum.NUMBER.getValue()) && StringUtils.isNotEmpty(e.getAdjustValue()) && !Pattern.matches(SalaryEntityUtil.NUMBER_REGEX, e.getAdjustValue()); if (isNotNumber) { throw new SalaryRunTimeException(salaryItemPO.getName() + ":" + SalaryI18nUtil.getI18nLabel(100581, "请输入数字")); } } // 修改了生效日期 if (!salaryArchiveItemSaveParam.getEffectiveTime().equals(salaryArchiveItem.getEffectiveTime())) { boolean isEffectiveTimeRepeat = list.stream().anyMatch(it -> it.getEffectiveTime().equals(saveEffectiveTime)); if (isEffectiveTimeRepeat) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(153539, "已经存在该生效日期的调整记录,请修改生效日期")); } } // 1.检验是否可以调整 // if (effectiveSalaryItem != null) { // 当前已经生效的时间 // Date effectiveTime = effectiveSalaryItem.getEffectiveTime(); // 1.1 如果保存的生效日期早于<当前已生效 // if (saveEffectiveTime.before(effectiveTime)) { // if(salaryArchiveItemSaveParam.getCanOperator() == Boolean.TRUE){ // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100429, "生效日期不可早于当前已生效的调整日期")); // } // // 仅可编辑说明 // salaryArchiveItemMapper.updateIgnoreNull( SalaryArchiveItemPO.builder().id(salaryArchiveItemSaveParam.getSalaryArchiveItemId()) // .description(salaryArchiveItemSaveParam.getDescription()).build()); // } // } }); return SalaryArchiveItemPO.builder().id(salaryArchiveItemSaveParam.getSalaryArchiveItemId()).effectiveTime(salaryArchiveItemSaveParam.getEffectiveTime()).adjustReason(salaryArchiveItemSaveParam.getAdjustReason()) .description(salaryArchiveItemSaveParam.getDescription()).itemValue(salaryArchiveItemSaveParam.getSalaryArchiveItems().get(0).getAdjustValue()).build(); } @Override public List getCurrentEffectiveItemListIngoreValue(Collection salaryArchivesIds, List salaryItemIds) { // 没有薪资项目时,给个不存在的,否则加载所有不合理 salaryItemIds = CollectionUtils.isEmpty(salaryItemIds) ? Collections.singletonList(0L) : salaryItemIds; // 薪资档案id List salaryArchiveIds = CollectionUtils.isEmpty(salaryArchivesIds) ? Collections.singletonList(0L) : (List) salaryArchivesIds; List salaryArchiveItems = Lists.newArrayList(); List> partition = Lists.partition(Lists.newArrayList(salaryArchiveIds), 999); List finalSalaryItemIds = salaryItemIds; partition.forEach(part -> salaryArchiveItems.addAll(salaryArchiveItemMapper.getEffectiveSalaryItems(SalaryArchiveItemQueryParam.builder() .salaryArchivesIds(finalSalaryItemIds) .salaryItemIds(finalSalaryItemIds) .effectiveTime(new Date()).build()))); return salaryArchiveItems; } @Override public String getSalaryItemAdjustBeforeValue(SalaryItemAdjustBeforeParam adjustBeforeParam) { ValidUtil.doValidator(adjustBeforeParam); List archiveItemList; if (adjustBeforeParam.getSalaryArchiveItemId() == null) { archiveItemList = getEffectiveSalaryItems(adjustBeforeParam.getSalaryArchiveId(), Collections.singletonList(adjustBeforeParam.getSalaryItemId())); } else { SalaryArchiveItemPO salaryArchiveItem = salaryArchiveItemMapper.getById(adjustBeforeParam.getSalaryArchiveItemId()); if (salaryArchiveItem == null) { return ""; } // 如果不是当前记录的 if (!salaryArchiveItem.getSalaryItemId().equals(adjustBeforeParam.getSalaryItemId())) { archiveItemList = getEffectiveSalaryItems(adjustBeforeParam.getSalaryArchiveId(), Collections.singletonList(adjustBeforeParam.getSalaryItemId())); } else { archiveItemList = salaryArchiveItemMapper.getIneffectiveSalaryItems(SalaryArchiveItemQueryParam.builder() .salaryArchiveId(adjustBeforeParam.getSalaryArchiveId()) .salaryItemId(salaryArchiveItem.getSalaryItemId()) .effectiveTime(salaryArchiveItem.getEffectiveTime()).build()); } } return CollectionUtils.isNotEmpty(archiveItemList) ? archiveItemList.get(0).getItemValue() : ""; } @Override public String saveSalaryItem(SalaryArchiveItemSaveParam saveParam) { // 检查参数 SalaryArchiveItemSaveParam.checkParam(saveParam); Long salaryArchiveId = saveParam.getSalaryArchiveId(); // 获取所有可被引用的薪资项目 List salaryItems = getCanAdjustSalaryItems(); // 待处理薪资项目 List salaryArchiveItems = saveParam.getSalaryArchiveItems().stream().filter(e -> { Optional optional = salaryItems.stream().filter(i -> i.getId().equals(e.getSalaryItemId())).findFirst(); return optional.isPresent(); }).collect(Collectors.toList()); List salaryItemIds = salaryArchiveItems.stream().map(SalaryArchiveItemDetailSaveParam::getSalaryItemId).collect(Collectors.toList()); // 薪资档案 SalaryArchivePO salaryArchive = salaryArchiveMapper.getById(salaryArchiveId); if (salaryArchive == null) { throw new SalaryRunTimeException("薪资档案不存在!"); } if (salaryArchive.getRunStatus().equals(SalaryArchiveStatusEnum.PENDING.getValue())) { throw new SalaryRunTimeException("薪资档案在待定薪列表,请先定薪并设为发薪人员后再调薪!"); } // 获取当前已生效数据 List effectiveSalaryItems = getEffectiveSalaryItems(salaryArchiveId, salaryItemIds); // 获取未生效数据 List ineffectiveSalaryItems = getIneffectiveSalaryItems(salaryArchiveId, salaryItemIds); // 待保存生效时间 Date saveEffectiveTime = saveParam.getEffectiveTime(); // 当天 Date today = new Date(); // 当前时间 Date nowTime = new Date(); List effectiveSalaryItemDels = Lists.newArrayList(); List salaryArchiveItemNews = Lists.newArrayList(); for (int j = 0; j < salaryArchiveItems.size(); j++) { SalaryArchiveItemDetailSaveParam e = salaryArchiveItems.get(j); // 已生效 List effectiveList = effectiveSalaryItems.stream().filter(i -> i.getSalaryItemId().equals(e.getSalaryItemId())).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 optionalIneffective = ineffectiveSalaryItems.stream().filter(i -> i.getSalaryItemId().equals(e.getSalaryItemId())).findFirst(); SalaryArchiveItemPO ineffectiveSalaryItem = optionalIneffective.orElse(null); // 1.检验是否可以调整 if (effectiveSalaryItem != null) { // 当前已经生效的时间 Date effectiveTime = effectiveSalaryItem.getEffectiveTime(); // 1.1 如果早于<当前已生效 if (saveEffectiveTime.before(effectiveTime)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100429, "生效日期不可早于当前已生效的调整日期")); // 1.2 如果等于当前已生效 fixme 日期比较可能有bug } else if (saveEffectiveTime.equals(effectiveTime)) { if (effectiveBeforeSalaryItem != null && effectiveBeforeSalaryItem.getItemValue().equals(e.getAdjustValue())) { // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同")); continue; } if (ineffectiveSalaryItem != null && ineffectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同")); } // 1.3 如果>已经生效且<=今天 } else if (saveEffectiveTime.after(effectiveTime) && !saveEffectiveTime.after(today)) { if (effectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同")); continue; } if (ineffectiveSalaryItem != null && ineffectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同")); } // 1.4 如果>今天 } else if (saveEffectiveTime.after(today) && effectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同")); continue; } } else if (ineffectiveSalaryItem != null && ineffectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同")); } // 2.数据处理 if (effectiveSalaryItem != null && saveEffectiveTime.equals(effectiveSalaryItem.getEffectiveTime())) { effectiveSalaryItemDels.add(effectiveSalaryItem.getId()); } if (ineffectiveSalaryItem != null && saveEffectiveTime.after(today)) { effectiveSalaryItemDels.add(ineffectiveSalaryItem.getId()); } salaryArchiveItemNews.add(buildInsert(salaryArchive, e.getSalaryItemId(), e.getAdjustValue(), saveParam, nowTime, e.getDescription())); } // 落库处理 if (CollectionUtils.isNotEmpty(effectiveSalaryItemDels)) { salaryArchiveItemMapper.deleteBatchIds(effectiveSalaryItemDels); } if (CollectionUtils.isNotEmpty(salaryArchiveItemNews)) { salaryArchiveItemMapper.batchInsert(salaryArchiveItemNews, user); } // 万德隆,调薪时如果薪资档案是停薪列表,则将薪资档案状态改为发薪并清空最后发薪日期 if (salaryArchive.getRunStatus().equals(SalaryArchiveStatusEnum.STOP_FROM_PENDING.getValue()) || salaryArchive.getRunStatus().equals(SalaryArchiveStatusEnum.STOP_FROM_SUSPEND.getValue())) { getSalaryArchiveService(user).forceToFixed(Collections.singletonList(salaryArchive.getId())); } return StringUtils.EMPTY; } @Override public String checkSaveSalaryItem(SalaryArchiveItemSaveParam saveParam) { // 检查参数 SalaryArchiveItemSaveParam.checkParam(saveParam); Long salaryArchiveId = saveParam.getSalaryArchiveId(); // 获取所有可被引用的薪资项目 List salaryItems = getCanAdjustSalaryItems(); // 待处理薪资项目 List salaryArchiveItems = saveParam.getSalaryArchiveItems().stream().filter(e -> { Optional optional = salaryItems.stream().filter(i -> i.getId().equals(e.getSalaryItemId())).findFirst(); return optional.isPresent(); }).collect(Collectors.toList()); List salaryItemIds = salaryArchiveItems.stream().map(SalaryArchiveItemDetailSaveParam::getSalaryItemId).collect(Collectors.toList()); // 薪资档案 SalaryArchivePO salaryArchive = salaryArchiveMapper.getById(salaryArchiveId); // 获取当前已生效数据 List effectiveSalaryItems = getEffectiveSalaryItems(salaryArchiveId, salaryItemIds); // 获取未生效数据 List ineffectiveSalaryItems = getIneffectiveSalaryItems(salaryArchiveId, salaryItemIds); // 待保存生效时间 Date saveEffectiveTime = saveParam.getEffectiveTime(); // 当天 Date today = new Date(); // 当前时间 Date nowTime = new Date(); List effectiveSalaryItemDels = Lists.newArrayList(); List salaryArchiveItemNews = Lists.newArrayList(); salaryArchiveItems.forEach(e -> { // 已生效 List effectiveList = effectiveSalaryItems.stream().filter(i -> i.getSalaryItemId().equals(e.getSalaryItemId())).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 optionalIneffective = ineffectiveSalaryItems.stream().filter(i -> i.getSalaryItemId().equals(e.getSalaryItemId())).findFirst(); SalaryArchiveItemPO ineffectiveSalaryItem = optionalIneffective.orElse(null); // 1.检验是否可以调整 if (effectiveSalaryItem != null) { // 当前已经生效的时间 Date effectiveTime = effectiveSalaryItem.getEffectiveTime(); // 1.1 如果早于<当前已生效 if (saveEffectiveTime.before(effectiveTime)) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100429, "生效日期不可早于当前已生效的调整日期")); // 1.2 如果等于当前已生效 fixme 日期比较可能有bug } else if (saveEffectiveTime.equals(effectiveTime)) { if (effectiveBeforeSalaryItem != null && effectiveBeforeSalaryItem.getItemValue().equals(e.getAdjustValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同")); } if (ineffectiveSalaryItem != null && ineffectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同")); } // 1.3 如果>已经生效且<=今天 } else if (saveEffectiveTime.after(effectiveTime) && !saveEffectiveTime.after(today)) { if (effectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同")); } if (ineffectiveSalaryItem != null && ineffectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同")); } // 1.4 如果>今天 } else if (saveEffectiveTime.after(today) && effectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100432, "调整前后不可相同")); } } else if (ineffectiveSalaryItem != null && ineffectiveSalaryItem.getItemValue().equals(e.getAdjustValue())) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100434, "与未生效的调整后不可相同")); } }); return StringUtils.EMPTY; } /** * 插入 * * @param salaryArchive * @param saveParam */ private SalaryArchiveItemPO buildInsert(SalaryArchivePO salaryArchive, Long salaryItemId, String adjustValue, SalaryArchiveItemSaveParam saveParam, Date now, String description) { return SalaryArchiveItemPO.builder() .salaryArchiveId(saveParam.getSalaryArchiveId()) .employeeId(salaryArchive.getEmployeeId()) .effectiveTime(saveParam.getEffectiveTime()) .adjustReason(saveParam.getAdjustReason()) .description(StringUtils.isBlank(description) ? Utils.null2String(saveParam.getDescription()) : description) .salaryItemId(salaryItemId) // 调整后 .itemValue(adjustValue) .operator((long) user.getUID()) .operateTime(now) .createTime(now) .updateTime(now) .creator((long) user.getUID()) .tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY) .build(); } @Override public String deleteSalaryItem(Long salaryArchiveItemId) { SalaryArchiveItemPO salaryArchiveItem = salaryArchiveItemMapper.getById(salaryArchiveItemId); if (salaryArchiveItem == null) { throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98299, "参数错误,薪资项目不存在或已被删除")); } // if (salaryArchiveItem.getEffectiveTime().after(new Date())) { salaryArchiveItem.setDeleteType(1); // 删除未生效数据 salaryArchiveItemMapper.updateById(salaryArchiveItem); // 记录日志 String operateName = SalaryI18nUtil.getI18nLabel(0, "删除调薪记录"); SalaryLoggerUtil.recordDeleteSingleLog(SalaryElogConfig.salaryArchiveItemAdjustLoggerTemplate, salaryArchiveItem.getId(), operateName + ":" + salaryArchiveItem.getId(), operateName, operateName, salaryArchiveItem, user); // } else { // throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98299, "该薪资项目已生效不可删除")); // } return StringUtils.EMPTY; } /** * 获取所有可被引用的薪资项目 * * @return */ @Override public List getCanAdjustSalaryItems() { TaxAgentQueryParam param = TaxAgentQueryParam.builder().build(); param.setFilterType(AuthFilterTypeEnum.QUERY_DATA); Collection taxAgentList = getTaxAgentService(user).listAuth(param); List taxAgentIds = SalaryEntityUtil.properties(taxAgentList, TaxAgentPO::getId, Collectors.toList()); List canAdjustSalaryItems = salaryItemMapper.getCanAdjustSalaryItems(); canAdjustSalaryItems = canAdjustSalaryItems.stream() .filter(item -> item.getSharedType() == null || 0 == item.getSharedType() || (StringUtils.isNotBlank(item.getTaxAgentIds()) && SalaryEntityUtil.judgeIntersection(taxAgentIds, Arrays.stream(item.getTaxAgentIds().split(",")).map(Long::valueOf).collect(Collectors.toList())))) .collect(Collectors.toList()); return canAdjustSalaryItems; } @Override public PageInfo salaryItemAdjustRecordListPage(SalaryItemAdjustRecordQueryParam queryParam, List salaryItemIds) { return salaryArchiveItemMapper.salaryItemAdjustRecordListPage(queryParam, salaryItemIds); } @Override public List salaryItemAdjustRecordList(SalaryItemAdjustRecordQueryParam queryParam, List salaryItemIds) { return salaryArchiveItemMapper.salaryItemAdjustRecordList(queryParam, salaryItemIds); } @Override public XSSFWorkbook exportAdjustRecordList(SalaryItemAdjustRecordQueryParam queryParam) { // 1.工作簿名称 String sheetName = SalaryI18nUtil.getI18nLabel(85368, "薪资项目调整记录"); // 获取所有可被引用的薪资项目 List salaryItems = salaryItemMapper.getCanAdjustSalaryItems(); String[] header = { SalaryI18nUtil.getI18nLabel(85429, "姓名"), SalaryI18nUtil.getI18nLabel(86187, "员工状态"), SalaryI18nUtil.getI18nLabel(86185, "部门"), SalaryI18nUtil.getI18nLabel(84960, "薪资项目"), SalaryI18nUtil.getI18nLabel(85433, "调整前"), SalaryI18nUtil.getI18nLabel(85434, "调整后"), SalaryI18nUtil.getI18nLabel(85431, "调整原因"), SalaryI18nUtil.getI18nLabel(85904, "生效日期"), SalaryI18nUtil.getI18nLabel(85435, "操作人"), SalaryI18nUtil.getI18nLabel(85436, "操作时间"), SalaryI18nUtil.getI18nLabel(84961, "备注") }; // 2.表头 List headerList = new ArrayList<>(Arrays.asList(header)); // 3.表数据 // 获取所有可被引用的薪资项目 List salaryItemList = getCanAdjustSalaryItems(); List salaryItemIds = salaryItemList.stream().map(SalaryItemPO::getId).collect(Collectors.toList()); //分权 SalaryArchiveQueryParam archiveQueryParam = new SalaryArchiveQueryParam(); archiveQueryParam.setFilterType(AuthFilterTypeEnum.QUERY_DATA); List salaryArchiveIds = getSalaryArchiveService(user).list(archiveQueryParam).stream().map(SalaryArchiveListDTO::getId).collect(Collectors.toList()); queryParam.setSalaryArchiveIds(salaryArchiveIds); List employeeList = getSalaryEmployeeService(user).listAll(UseEmployeeTypeEnum.ALL); Map employeeMap = SalaryEntityUtil.convert2Map(employeeList, DataCollectionEmployee::getEmployeeId); List listResult = getSalaryArchiveItemService(user).salaryItemAdjustRecordList(queryParam, salaryItemIds); listResult = listResult.stream() .filter(r -> { DataCollectionEmployee employee = employeeMap.getOrDefault(r.getEmployeeId(), new DataCollectionEmployee()); String username = queryParam.getUsername(); List departmentIds = queryParam.getDepartmentIds(); List positionIds = queryParam.getPositionIds(); String userstatus = queryParam.getUserstatus(); r.setUsername(employee.getUsername()); r.setDepartmentName(employee.getDepartmentName()); r.setEmployeeStatus(UserStatusEnum.getDefaultLabelByValue(Integer.parseInt(NumberUtils.isCreatable(employee.getStatus()) ? employee.getStatus() : "-1"))); r.setAdjustReason(SalaryArchiveItemAdjustReasonEnum.getDefaultLabelByValue(r.getAdjustReason())); return (StringUtils.isBlank(username) || employee.getUsername().contains(username)) && (CollectionUtils.isEmpty(departmentIds) || departmentIds.contains(employee.getDepartmentId())) && (CollectionUtils.isEmpty(positionIds) || positionIds.contains(employee.getJobtitleId())) && (StringUtils.isBlank(userstatus) || Objects.equals(employee.getStatus(), userstatus)) && (CollectionUtils.isEmpty(positionIds) || positionIds.contains(employee.getJobtitleId())) ; }) .collect(Collectors.toList()); SalaryI18nUtil.i18nList(listResult); List listAll = salaryArchiveItemMapper.salaryItemAdjustRecordList(SalaryItemAdjustRecordQueryParam.builder().build(), salaryItemIds); // 人员信息赋值 listResult.forEach(m -> { if (!org.springframework.util.CollectionUtils.isEmpty(listAll)) { listAll.removeIf(a -> a.getId().equals(m.getId())); } Optional optional = listAll.stream().filter(f -> f.getSalaryArchiveId().equals(m.getSalaryArchiveId()) && f.getSalaryItemId().equals(m.getSalaryItemId())).findFirst(); m.setAdjustBefore(optional.isPresent() ? optional.get().getAdjustAfter() : ""); }); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); List> rows = new ArrayList<>(); rows.add(headerList); for (SalaryItemAdjustRecordListDTO dto : listResult) { List row = new ArrayList<>(); row.add(dto.getUsername()); row.add(dto.getEmployeeStatus()); row.add(dto.getDepartmentName()); row.add(dto.getAdjustItem()); row.add(dto.getAdjustBefore()); row.add(dto.getAdjustAfter()); row.add(dto.getAdjustReason()); row.add(SalaryDateUtil.getFormatDate(dto.getEffectiveTime())); row.add(dto.getOperator()); row.add(format.format(dto.getOperateTime())); row.add(dto.getDescription()); rows.add(row); } return ExcelUtil.genWorkbookV2(rows, sheetName); } @Override public ArchiveFieldConfig getConfig() { List salaryItemPOList = getSalaryItemService(user).listByParam(SalaryItemSearchParam.builder().useInEmployeeSalary(1).build()); return ArchiveFieldConfig.builder().salaryItems(salaryItemPOList).build(); } @Override public UploadConfigResponse.Result parseConfig(ArchiveFieldConfig config) { UploadConfigResponse.Result result = UploadConfigResponse.Result.builder() .message("档案字段加载完毕") .success(new ArrayList<>()) .warning(new ArrayList<>()) .error(new ArrayList<>()) .build(); long uid = user.getUID(); List salaryItemPOList = getSalaryItemService(user).listAll(); Map nameMap = SalaryEntityUtil.convert2Map(salaryItemPOList, SalaryItemPO::getName); Map codeMap = SalaryEntityUtil.convert2Map(salaryItemPOList, SalaryItemPO::getCode); Optional.ofNullable(config.getSalaryItems()) .orElse(new ArrayList<>()) .forEach(itemPO -> { try { if (nameMap.containsKey(itemPO.getName())) { SalaryItemPO salaryItemPO = nameMap.get(itemPO.getName()); if (!StrUtil.equals(salaryItemPO.getCode(), itemPO.getCode())) { result.getWarning().add(String.format("警告,档案字段[%s]名称已存在,但项目code不一致,迁入code:%s,当前系统code:%s", itemPO.getName(), itemPO.getCode(), salaryItemPO.getCode())); } itemPO.setId(salaryItemPO.getId()); //不许修改code itemPO.setCode(null); itemPO.setCreator(uid); getSalaryItemMapper().updateIgnoreNull(itemPO); } else if (codeMap.containsKey(itemPO.getCode())) { SalaryItemPO salaryItemPO = codeMap.get(itemPO.getCode()); if (!StrUtil.equals(salaryItemPO.getName(), itemPO.getName())) { result.getWarning().add(String.format("警告,档案字段[%s]code已存在,但项目code不一致,迁入名称:%s,当前系统名称:%s", itemPO.getName(), itemPO.getName(), salaryItemPO.getName())); } itemPO.setId(salaryItemPO.getId()); //不许修改名字 itemPO.setName(null); itemPO.setCreator(uid); getSalaryItemMapper().updateIgnoreNull(itemPO); } else { itemPO.setId(IdGenerator.generate()); getSalaryItemMapper().insertIgnoreNull(itemPO); } result.getSuccess().add(String.format("成功,薪资项目[%s]加载成功", itemPO.getName())); } catch (Exception e) { log.error("{}字段加载异常,", itemPO.getName(), e); result.getError().add(String.format("错误,档案字段[%s]加载异常,%s", itemPO.getName(), e.getMessage())); } }); return result; } @Override public List listByArchiveIdAndEffectiveTime(List salaryArchiveIds, LocalDateRange dateRange) { if (CollectionUtils.isEmpty(salaryArchiveIds)) { return Collections.emptyList(); } List resultList = new ArrayList<>(); List> partition = Lists.partition(salaryArchiveIds, 1000); partition.forEach(part -> { resultList.addAll(getSalaryArchiveItemMapper().listByArchiveIdAndEffectiveTime(part, dateRange)); }); return resultList; } }