package com.engine.salary.service.impl;
import cn.hutool.core.util.NumberUtil;
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.hrmelog.entity.dto.LoggerContext;
import com.engine.salary.biz.SalaryItemBiz;
import com.engine.salary.biz.SysSalaryItemBiz;
import com.engine.salary.config.SalaryElogConfig;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.salaryformula.param.SalaryFormulaSaveParam;
import com.engine.salary.entity.salaryformula.po.FormulaPO;
import com.engine.salary.entity.salaryformula.po.FormulaVar;
import com.engine.salary.entity.salaryitem.bo.SalaryItemBO;
import com.engine.salary.entity.salaryitem.config.SalaryItemConfig;
import com.engine.salary.entity.salaryitem.config.SalaryItemExcelConfig;
import com.engine.salary.entity.salaryitem.param.*;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salaryitem.po.SysSalaryItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobBackItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobItemPO;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.enums.*;
import com.engine.salary.enums.salaryformula.ReferenceTypeEnum;
import com.engine.salary.enums.salaryformula.ReturnTypeEnum;
import com.engine.salary.enums.salaryitem.SalaryDataTypeEnum;
import com.engine.salary.enums.sicategory.SharedTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.salaryitem.SalaryItemMapper;
import com.engine.salary.service.*;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.excel.ExcelParseHelper;
import com.engine.salary.util.excel.ImportExcelResponse;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.util.valid.ValidUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import weaver.file.ImageFileManager;
import weaver.hrm.User;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;
import static com.engine.salary.util.excel.ExcelSupport.EXCEL_TYPE_XLSX;
/**
* 薪资项目
*
Copyright: Copyright (c) 2022
* Company: 泛微软件
*
* @author qiantao
* @version 1.0
**/
public class SalaryItemServiceImpl extends Service implements SalaryItemService {
private SalaryItemBiz salaryItemBiz = new SalaryItemBiz();
private SalarySobItemService getSalarySobItemService(User user) {
return ServiceUtil.getService(SalarySobItemServiceImpl.class, user);
}
private TaxAgentService getTaxAgentService(User user) {
return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
}
private SysSalaryItemService getSysSalaryItemService(User user) {
return ServiceUtil.getService(SysSalaryItemServiceImpl.class, user);
}
private SalaryFormulaService getSalaryFormulaService(User user) {
return ServiceUtil.getService(SalaryFormulaServiceImpl.class, user);
}
private SalarySobBackItemService getSalarySobBackItemService(User user) {
return ServiceUtil.getService(SalarySobBackItemServiceImpl.class, user);
}
public SalarySobService getSalarySobService(User user) {
return ServiceUtil.getService(SalarySobServiceImpl.class, user);
}
private SysSalaryItemBiz sysSalaryItemBiz = new SysSalaryItemBiz();
private SalaryItemMapper getSalaryItemMapper() {
return SqlProxyHandle.getProxy(SalaryItemMapper.class);
}
@Override
public SalaryItemPO getById(Long id) {
return salaryItemBiz.getById(id);
}
@Override
public List listAll() {
return salaryItemBiz.listAll();
}
@Override
public List listByIds(Collection ids) {
if (CollectionUtils.isEmpty(ids)) {
return Collections.emptyList();
}
return salaryItemBiz.listSome(SalaryItemPO.builder().ids(ids).build());
}
@Override
public List listBySysSalaryItemIds(Collection sysSalaryItemIds) {
if (CollectionUtils.isEmpty(sysSalaryItemIds)) {
return Collections.emptyList();
}
return salaryItemBiz.listSome(SalaryItemPO.builder().sysSalaryItemIds(sysSalaryItemIds).build());
}
@Override
public List listByName(String name) {
return salaryItemBiz.listSome(SalaryItemPO.builder().name(name).build());
}
@Override
public SalaryItemPO getByName(String name) {
return getSalaryItemMapper().getByName(name);
}
@Override
public List listBySystemType(SalarySystemTypeEnum systemType) {
return salaryItemBiz.listSome(SalaryItemPO.builder().systemType(systemType.getValue()).build());
}
@Override
public List listBySystemTypeAndUseDefault(SalarySystemTypeEnum systemType, Integer useDefault) {
return salaryItemBiz.listSome(SalaryItemPO.builder().systemType(systemType.getValue()).useDefault(useDefault).build());
}
@Override
public List listByParam(SalaryItemSearchParam searchParam) {
return salaryItemBiz.listByParam(searchParam);
}
@Override
public List listByParamOrderById(SalaryItemSearchParam searchParam) {
return salaryItemBiz.listByParamOrderById(searchParam);
}
@Override
public PageInfo listPageByParam(SalaryItemSearchParam searchParam) {
Boolean needAuth = getTaxAgentService(user).isNeedAuth((long) user.getUID());
Boolean isAdminEnable = getTaxAgentService(user).isAdminEnable((long) user.getUID());
List salaryItemPOS = salaryItemBiz.listByParam(searchParam);
if (needAuth) {
if (isAdminEnable) {
//管理员
Set userTaxAgentIds = getTaxAgentService(user).listAllTaxAgents((long) user.getUID())
.stream().map(TaxAgentPO::getId).collect(Collectors.toSet());
salaryItemPOS = salaryItemPOS.stream()
.filter(po -> filterInRange(userTaxAgentIds, po))
.sorted(new Comparator() {
@Override
public int compare(SalaryItemPO o1, SalaryItemPO o2) {
if (o1.getSortedIndex() == null && o2.getSortedIndex() == null) {
Integer systemType1 = o1.getSystemType() == null ? 0 : o1.getSystemType();
Integer systemType2 = o2.getSystemType() == null ? 0 : o2.getSystemType();
return systemType1.compareTo(systemType2);
} else {
Integer sortedIndex1 = o1.getSortedIndex() == null ? 0 : o1.getSortedIndex();
Integer sortedIndex2 = o2.getSortedIndex() == null ? 0 : o2.getSortedIndex();
return sortedIndex2.compareTo(sortedIndex1);
}
}
})
.collect(Collectors.toList());
} else {
//普通用户
salaryItemPOS = new ArrayList<>();
}
}
return SalaryPageUtil.buildPage(searchParam.getCurrent(), searchParam.getPageSize(), salaryItemPOS);
}
@Override
public boolean filterInRange(Set userTaxAgentIds, SalaryItemPO po) {
return null == po.getSharedType()
|| SharedTypeEnum.PUBLIC.getValue().equals(po.getSharedType().toString())
|| (StrUtil.isNotBlank(po.getTaxAgentIds())
&& Arrays.stream(po.getTaxAgentIds().split(","))
.map(Long::valueOf)
.anyMatch(userTaxAgentIds::contains));
}
// @Override
// public Page listPageByParam(SalaryItemSearchParam searchParam, String tenantKey) {
// // 分页参数
// Page page = SalaryPageUtil.buildPage(searchParam.getCurrent(), searchParam.getPageSize());
// // 构建查询参数
// Wrapper queryWrapper = SalaryItemBO.buildQueryWrapper(searchParam, tenantKey);
// // 返回查询结果
// return SalaryItemBiz.selectPage(page, queryWrapper);
// }
@Override
public SalaryItemPO save(SalaryItemSaveParam saveParam) {
// 名称不能和已有的自定义薪资项目重名
List salaryItemPOS = listByName(saveParam.getName());
if (CollectionUtils.isNotEmpty(salaryItemPOS)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98326, "薪资项目名称已存在,请重新命名"));
}
// 名称不能和已有的系统薪资项目重名
SysSalaryItemPO sysSalaryItem = sysSalaryItemBiz.selectOneByName(saveParam.getName());
if (sysSalaryItem != null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98328, "自定义薪资项目的名称不能和系统薪资项目的名称重名"));
}
SalaryItemPO salaryItemPO = SalaryItemBO.convert2SalaryItemPO(saveParam, (long) user.getUID());
salaryItemBiz.insert(salaryItemPO);
return salaryItemPO;
}
@Override
public void batchSave(Collection salaryItemPOS) {
salaryItemBiz.batchSave(salaryItemPOS);
}
@Override
public SalaryItemPO update(SalaryItemSaveParam saveParam) {
// 查询薪资项目,判断薪资项目是否存在
SalaryItemPO salaryItemPO = getById(saveParam.getId());
if (Objects.isNull(salaryItemPO)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98299, "参数错误,薪资项目不存在或已被删除"));
}
// 名称不能和已有的自定义薪资项目重名
List salaryItemPOS = listByName(saveParam.getName());
boolean nameExist = salaryItemPOS.stream().anyMatch(e -> !Objects.equals(salaryItemPO.getId(), e.getId()));
if (nameExist) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98326, "薪资项目名称已存在,请重新命名"));
}
// 名称不能和已有的系统薪资项目重名
List sysSalaryItemPOS = sysSalaryItemBiz.listSome(SysSalaryItemPO.builder().name(saveParam.getName()).build());
boolean sysNameExist = sysSalaryItemPOS.stream().anyMatch(e -> !Objects.equals(salaryItemPO.getSysSalaryItemId(), e.getId()));
if (sysNameExist) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98328, "自定义薪资项目的名称不能和系统薪资项目的名称重名"));
}
// 更新薪资项目
SalaryItemPO newSalaryItemPO = new SalaryItemPO();
BeanUtils.copyProperties(salaryItemPO, newSalaryItemPO);
newSalaryItemPO.setName(saveParam.getName());
newSalaryItemPO.setUseDefault(saveParam.getUseDefault());
newSalaryItemPO.setUseInEmployeeSalary(saveParam.getUseInEmployeeSalary());
newSalaryItemPO.setHideDefault(saveParam.getHideDefault());
newSalaryItemPO.setRoundingMode(saveParam.getRoundingMode());
newSalaryItemPO.setPattern(saveParam.getPattern());
newSalaryItemPO.setValueType(saveParam.getValueType());
newSalaryItemPO.setDataType(saveParam.getDataType());
newSalaryItemPO.setFormulaId(Objects.equals(saveParam.getValueType(), SalaryValueTypeEnum.INPUT.getValue()) ? 0L : saveParam.getFormulaId());
newSalaryItemPO.setDescription(saveParam.getDescription());
newSalaryItemPO.setUpdateTime(new Date());
newSalaryItemPO.setSharedType(saveParam.getSharedType());
newSalaryItemPO.setTaxAgentIds(saveParam.getTaxAgentIds());
newSalaryItemPO.setSortedIndex(saveParam.getSortedIndex());
newSalaryItemPO.setWidth(saveParam.getWidth());
newSalaryItemPO.setDefaultValue(saveParam.getDefaultValue());
salaryItemBiz.updateById(newSalaryItemPO);
//改名后更新公式
String oldName = salaryItemPO.getName();
String newName = saveParam.getName();
if (!StringUtils.equals(oldName, newName)) {
//薪资项目
if (newSalaryItemPO.getUseInEmployeeSalary() == 0) {
String itemPrefix = "salaryItem_";
String fieldNamePrefix = "{薪资项目.%s}";
changeName(salaryItemPO, oldName, newName, itemPrefix, fieldNamePrefix);
}
if (newSalaryItemPO.getUseInEmployeeSalary() == 1) {
//引用档案
String itemPrefix = "salaryArchives_";
String fieldNamePrefix = "{薪资档案.%s}";
changeName(salaryItemPO, oldName, newName, itemPrefix, fieldNamePrefix);
//引用项目
itemPrefix = "salaryItem_";
fieldNamePrefix = "{薪资项目.%s}";
changeName(salaryItemPO, oldName, newName, itemPrefix, fieldNamePrefix);
}
}
return salaryItemPO;
}
private void changeName(SalaryItemPO salaryItemPO, String oldName, String newName, String itemPrefix, String fieldNamePrefix) {
String code = itemPrefix + salaryItemPO.getCode();
Date now = new Date();
List formulaVars = getSalaryFormulaService(user).listByCode(code);
formulaVars.forEach(v -> {
FormulaVar formulaVar = FormulaVar.builder()
.id(v.getId())
.name(newName)
.fieldName(String.format(fieldNamePrefix, newName))
.updateTime(now)
.build();
getSalaryFormulaService(user).updateVar(formulaVar);
});
List formulaIds = SalaryEntityUtil.properties(formulaVars, FormulaVar::getFormulaId, Collectors.toList());
List formulaPOS = getSalaryFormulaService(user).listByIds(formulaIds);
formulaPOS.forEach(f -> {
String formula = f.getFormula();
formula = formula.replace(String.format(fieldNamePrefix, oldName), String.format(fieldNamePrefix, newName));
FormulaPO formulaPO = FormulaPO.builder()
.id(f.getId())
.formula(formula)
.updateTime(now)
.build();
getSalaryFormulaService(user).update(formulaPO);
});
}
@Override
public void deleteByIds(Collection ids) {
SalaryItemServiceImpl.UsingItem usingItem = getUsingItem();
List usingItemIds = usingItem.getUsingItemIds();
List usingCodes = usingItem.getUsingCodes();
// 查询薪资项目
List salaryItemPOS = listByIds(ids);
if (CollectionUtils.isEmpty(salaryItemPOS)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98299, "参数错误,薪资项目不存在或已被删除"));
}
if (CollectionUtils.containsAny(usingItemIds, ids)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98322, "薪资账套正在使用该薪资项目,不允许删除"));
}
List codes = SalaryEntityUtil.properties(salaryItemPOS, SalaryItemPO::getCode, Collectors.toList());
if (CollectionUtils.containsAny(usingCodes, codes)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98322, "公式正在使用该薪资项目,不允许删除"));
}
// 删除薪资项目
ids = SalaryEntityUtil.properties(salaryItemPOS, SalaryItemPO::getId);
salaryItemBiz.deleteByIds(ids);
Integer useInEmployeeSalary = salaryItemPOS.get(0).getUseInEmployeeSalary();
// 记录删除日志
if (useInEmployeeSalary == 0) {
// 薪资项目
salaryItemPOS.forEach(salaryItemPO -> {
LoggerContext loggerContext = new LoggerContext<>();
loggerContext.setUser(user);
loggerContext.setTargetId(String.valueOf(salaryItemPO.getId()));
loggerContext.setTargetName(salaryItemPO.getName());
loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "删除薪资项目"));
loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "删除薪资项目") + ": " + salaryItemPO.getName());
loggerContext.setOldValues(salaryItemPO);
SalaryElogConfig.salaryItemLoggerTemplate.write(loggerContext);
});
} else {
// 字段管理
salaryItemPOS.forEach(salaryItemPO -> {
LoggerContext loggerContext = new LoggerContext<>();
loggerContext.setUser(user);
loggerContext.setTargetId(String.valueOf(salaryItemPO.getId()));
loggerContext.setTargetName(salaryItemPO.getName());
loggerContext.setOperateType(OperateTypeEnum.DELETE.getValue());
loggerContext.setOperateTypeName(SalaryI18nUtil.getI18nLabel(0, "删除字段"));
loggerContext.setOperatedesc(SalaryI18nUtil.getI18nLabel(0, "删除字段") + ": " + salaryItemPO.getName());
loggerContext.setOldValues(salaryItemPO);
SalaryElogConfig.salaryArchiveFieldLoggerTemplate.write(loggerContext);
});
}
}
/**
* 获取使用中的项目id、项目编码、公式id
*
* @return 项目id、项目编码、公式id
*/
@Override
public UsingItem getUsingItem() {
//系统项目
List sysItems = getSysSalaryItemService(user).listAll();
List sysItemFormulaIds = SalaryEntityUtil.properties(sysItems, SysSalaryItemPO::getFormulaId, Collectors.toList());
//薪资项目
List items = listAll();
List itemFormulaIds = SalaryEntityUtil.properties(items, SalaryItemPO::getFormulaId, Collectors.toList());
//账套项目
List sobItems = getSalarySobItemService(user).list();
List sobItemFormulaIds = SalaryEntityUtil.properties(sobItems, SalarySobItemPO::getFormulaId, Collectors.toList());
//回算项目
List backItems = getSalarySobBackItemService(user).listAll();
List backItemFormulaIds = SalaryEntityUtil.properties(backItems, SalarySobBackItemPO::getFormulaId, Collectors.toList());
List usingFormulaIds = new ArrayList<>();
usingFormulaIds.addAll(sysItemFormulaIds);
usingFormulaIds.addAll(itemFormulaIds);
usingFormulaIds.addAll(sobItemFormulaIds);
usingFormulaIds.addAll(backItemFormulaIds);
//账套里的项目,项目里的项目
List sobItemIds = SalaryEntityUtil.properties(sobItems, SalarySobItemPO::getSalaryItemId, Collectors.toList());
List backItemIds = SalaryEntityUtil.properties(backItems, SalarySobBackItemPO::getSalaryItemId, Collectors.toList());
List usingItemIds = new ArrayList<>();
usingItemIds.addAll(sobItemIds);
usingItemIds.addAll(backItemIds);
//使用中的code
List formulaVars = getSalaryFormulaService(user).listVarByFormulaIds(usingFormulaIds);
List itemCode = formulaVars.stream()
.map(FormulaVar::getFieldId)
.map(v -> v.replaceAll("salaryItem_", ""))
.map(v -> v.replaceAll("salaryArchives_", ""))
.map(v -> v.replaceAll("ISSUED_", ""))
.collect(Collectors.toList());
return UsingItem.builder().usingFormulaIds(usingFormulaIds).usingItemIds(usingItemIds).usingCodes(itemCode).build();
}
@Override
public void batchUpdateSortedIndex(List values) {
salaryItemBiz.batchUpdateSortedIndex(values);
}
@Override
public List