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

1625 lines
82 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 cn.hutool.core.lang.Validator;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.api.formmode.mybatis.util.SqlProxyHandle;
import com.cloudstore.dev.api.bean.MessageBean;
import com.cloudstore.dev.api.bean.MessageType;
import com.cloudstore.dev.api.util.Util_Message;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.biz.SalarySendBiz;
import com.engine.salary.biz.SalarySendInfoBiz;
import com.engine.salary.constant.SalaryArchiveConstant;
import com.engine.salary.constant.SalaryItemConstant;
import com.engine.salary.constant.SalaryTemplateSalaryItemSetGroupConstant;
import com.engine.salary.encrypt.EncryptUtil;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.salaryBill.bo.SalaryBillBO;
import com.engine.salary.entity.salaryBill.dto.*;
import com.engine.salary.entity.salaryBill.param.*;
import com.engine.salary.entity.salaryBill.po.SalarySendInfoPO;
import com.engine.salary.entity.salaryBill.po.SalarySendPO;
import com.engine.salary.entity.salaryBill.po.SalaryTemplatePO;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctFormulaBO;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctResultBO;
import com.engine.salary.entity.salaryacct.param.SalaryAcctResultQueryParam;
import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO;
import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO;
import com.engine.salary.entity.salaryformula.dto.SalaryFormulaEmployeeDTO;
import com.engine.salary.entity.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO;
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.salaryaccounting.SalaryAcctRecordStatusEnum;
import com.engine.salary.enums.salaryarchive.SalaryArchiveFieldTypeEnum;
import com.engine.salary.enums.salarybill.BillConfimStatusEnum;
import com.engine.salary.enums.salarybill.BillReadStatusEnum;
import com.engine.salary.enums.salarybill.SalarySendStatusEnum;
import com.engine.salary.enums.salarybill.SalaryTemplateReplenishRuleEnum;
import com.engine.salary.enums.salaryitem.SalaryDataTypeEnum;
import com.engine.salary.enums.salarysend.SalarySendGrantTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.salaryacct.SalaryAcctEmployeeMapper;
import com.engine.salary.mapper.salaryacct.SalaryAcctRecordMapper;
import com.engine.salary.mapper.salaryacct.SalaryAcctResultMapper;
import com.engine.salary.mapper.salarybill.SalarySendInfoMapper;
import com.engine.salary.mapper.salarybill.SalarySendMapper;
import com.engine.salary.service.*;
import com.engine.salary.sys.constant.SalarySysConstant;
import com.engine.salary.sys.entity.po.SalarySysConfPO;
import com.engine.salary.sys.entity.vo.OrderRuleVO;
import com.engine.salary.sys.service.SalarySysConfService;
import com.engine.salary.sys.service.impl.SalarySysConfServiceImpl;
import com.engine.salary.util.JsonUtil;
import com.engine.salary.util.SalaryDateUtil;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.excel.ExcelUtil;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.google.common.collect.Lists;
import dm.jdbc.util.IdGenerator;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import weaver.common.MessageUtil;
import weaver.general.BaseBean;
import weaver.hrm.User;
import weaver.hrm.company.SubCompanyComInfo;
import weaver.hrm.resource.ResourceComInfo;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.stream.Collectors;
import static com.engine.salary.cache.SalaryCacheKey.SALARY_CACHE_SMS_CODE;
/**
* @Description: 工资单发放
* @Author: wangxiangzhong
* @Date: 2021-12-11 11:28
*/
public class SalarySendServiceImpl extends Service implements SalarySendService {
private static final Logger log = LoggerFactory.getLogger(SalarySendServiceImpl.class);
private EncryptUtil encryptUtil = new EncryptUtil();
private SalarySendBiz mapper = new SalarySendBiz();
private SalarySendInfoBiz salarySendInfoMapper = new SalarySendInfoBiz();
private SalarySendRangeService getSalarySendRangeService(User user) {
return ServiceUtil.getService(SalarySendRangeServiceImpl.class, user);
}
private SalaryTemplateService getSalaryTemplateService(User user) {
return ServiceUtil.getService(SalaryTemplateServiceImpl.class, user);
}
private SalarySendMapper getSalarySendMapper() {
return SqlProxyHandle.getProxy(SalarySendMapper.class);
}
private SalaryAcctRecordService getSalaryAcctRecordService(User user) {
return ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user);
}
private SalaryAcctRecordMapper getSalaryAcctRecordMapper() {
return SqlProxyHandle.getProxy(SalaryAcctRecordMapper.class);
}
private SalaryAcctEmployeeMapper getSalaryAcctEmployeeMapper() {
return SqlProxyHandle.getProxy(SalaryAcctEmployeeMapper.class);
}
//
private SalaryAcctResultMapper getSalaryAcctResultMapper() {
return SqlProxyHandle.getProxy(SalaryAcctResultMapper.class);
}
private TaxAgentService getTaxAgentService(User user) {
return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
}
private SalaryEmployeeService getSalaryEmployeeService(User user) {
return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
}
private SalarySendInfoMapper getSalarySendInfoMapper() {
return SqlProxyHandle.getProxy(SalarySendInfoMapper.class);
}
private SalarySysConfService getSalarySysConfService(User user) {
return ServiceUtil.getService(SalarySysConfServiceImpl.class, user);
}
private SalarySobService getSalarySobService(User user) {
return ServiceUtil.getService(SalarySobServiceImpl.class, user);
}
private SalaryItemService getSalaryItemService(User user) {
return ServiceUtil.getService(SalaryItemServiceImpl.class, user);
}
private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) {
return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user);
}
private SalaryAcctResultService getSalaryAcctResultService(User user) {
return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user);
}
private SalarySobItemService getSalarySobItemService(User user) {
return ServiceUtil.getService(SalarySobItemServiceImpl.class, user);
}
private SalarySobBackItemService getSalarySobBackItemService(User user) {
return ServiceUtil.getService(SalarySobBackItemServiceImpl.class, user);
}
private SalaryBillService getSalaryBillService(User user) {
return ServiceUtil.getService(SalaryBillServiceImpl.class, user);
}
private SalaryCacheService getSalaryCacheService(User user) {
return ServiceUtil.getService(SalaryCacheServiceImpl.class, user);
}
@Override
public SalarySendPO getById(Long salarySendId) {
return mapper.getById(salarySendId);
}
@Override
public List<Long> findReAccountingIdsByAcctIds(List<Long> salaryAccountingIds, String tenantKey) {
// 校验salaryAccountingId
if (CollectionUtils.isEmpty(salaryAccountingIds)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100497, "核算id必传"));
}
// List<SalarySendPO> salarySends = new LambdaQueryChainWrapper<>(mapper)
// .eq(SalarySendPO::getDeleteType, 0)
// .eq(SalarySendPO::getSendNum, 0)
// .in(SalarySendPO::getSalaryAccountingId, salaryAccountingIds)
// .list();
Map<String, Object> condition = new HashMap<>();
condition.put("deleteType", 0);
condition.put("sendNum", 0);
condition.put("salaryAccountingIds", salaryAccountingIds);
List<SalarySendPO> salarySends = mapper.listSomeWithCondition(condition);
return salarySends.stream().map(SalarySendPO::getSalaryAccountingId).collect(Collectors.toList());
}
@Override
public String generateSalaryBill(Long salaryAccountingId) {
// 校验salaryAccountingId
if (salaryAccountingId == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100497, "核算id必传"));
}
SalaryAcctRecordPO recordPo = new SalaryAcctRecordPO();
recordPo.setDeleteType(0);
recordPo.setId(salaryAccountingId);
recordPo.setStatus(SalaryAcctRecordStatusEnum.ARCHIVED.getValue());
List<SalaryAcctRecordPO> acctRecords = getSalaryAcctRecordMapper().listSome(recordPo);
// 检查核算的归档记录
if (CollectionUtils.isEmpty(acctRecords)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100498, "核算记录不存在"));
}
List<SalaryAcctEmployeePO> salaryAcctEmployees = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordIds(Collections.singletonList(salaryAccountingId));
// 根据人员id去重
salaryAcctEmployees = salaryAcctEmployees.stream()
.collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(SalaryAcctEmployeePO::getEmployeeId))), ArrayList::new));
// 1.回算如果是回算todo 要等原始核算发完或者上一个回算记录发完才行,目前最多只有一个回算记录
if (Objects.equals(acctRecords.get(0).getBackCalcStatus(), (NumberUtils.INTEGER_ONE))) {
SalarySendPO sendPO = new SalarySendPO();
sendPO.setDeleteType(0);
sendPO.setSalaryAccountingId(salaryAccountingId);
List<SalarySendPO> salarySends = mapper.listSome(sendPO);
if (CollectionUtils.isEmpty(salarySends)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(139700, "还没有正常核算,不能进行回算"));
}
// todo 一般只有一个未冻结,同一个原始核算id后面如果有多级回算就会换成不同核算id
SalarySendPO salarySend = salarySends.stream().filter(s -> s.getSendStatus().equals(NumberUtils.INTEGER_ZERO)).findFirst().orElse(null);
// 根据工资单补发模板规则过滤人员,已发补发的合计项目不等于0的进行过滤
SalarySobPO salarySob = getSalarySobService(user).getById(acctRecords.get(0).getSalarySobId());
List<SalaryTemplatePO> salaryTemplates = getSalaryTemplateService(user)
.getDefaultTemplates(Arrays.asList(acctRecords.get(0).getSalarySobId(), salarySob == null ? 0L : salarySob.getId()));
// 如果有默认模板,且规则不是全部
if (CollectionUtils.isNotEmpty(salaryTemplates) && StringUtils.isEmpty(salaryTemplates.get(0).getReplenishRule())) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(140649, "请维护补发工资单模板信息"));
}
Long backCalcItemId =
CollectionUtils.isNotEmpty(salaryTemplates) && !SalaryTemplateReplenishRuleEnum.ALL.getValue().equals(salaryTemplates.get(0).getReplenishRule()) ? Long
.parseLong(salaryTemplates.get(0).getReplenishRule()) : 0L;
SalaryItemPO salaryItem = getSalaryItemService(user).getById(backCalcItemId);
if (salaryItem != null && salaryItem.getDataType().equals(SalaryArchiveFieldTypeEnum.NUMBER.getValue())) {
// 目前是单个薪资项目
List<SalaryAcctResultPO> salaryAcctResultValues = getSalaryAcctResultService(user).listBySalaryAcctRecordIdsAndSalaryItemIds(Collections.singleton(salaryAccountingId), Collections.singleton(backCalcItemId));
Set<Long> salaryAcctEmployeeIds = salaryAcctResultValues.stream()
.filter(salaryAcctResultPO -> SalaryEntityUtil.empty2Zero(salaryAcctResultPO.getResultValue()).compareTo(BigDecimal.ZERO)
!= 0)
.map(SalaryAcctResultPO::getSalaryAcctEmpId)
.collect(Collectors.toSet());
salaryAcctEmployees = salaryAcctEmployees.stream().filter(se -> salaryAcctEmployeeIds.contains(se.getId())).collect(Collectors.toList());
}
// 将未冻结的给冻结掉
if (salarySend != null) {
salarySend.setSendStatus(NumberUtils.INTEGER_ONE);
mapper.updateById(salarySend);
}
// 2.正常核算
} else {
SalarySendPO sendPO = new SalarySendPO();
sendPO.setDeleteType(0);
sendPO.setSalaryAccountingId(salaryAccountingId);
List<SalarySendPO> salarySends = mapper.listSome(sendPO);
if (CollectionUtils.isNotEmpty(salarySends)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100499, "工资单已生成过,不可再重复生成"));
}
}
Long salarySendId = IdGenerator.generate();
SalaryAcctRecordPO salaryAcctRecord = acctRecords.get(0);
// 工资单模板类型0正常核算1是回算todo 后续可能还有别的算,需要改这里
Integer templateType = salaryAcctRecord.getBackCalcStatus();
// 构建工资单发放数据
List<SalarySendInfoPO> salarySendInfos = salaryAcctEmployees.stream().map(m ->
SalarySendInfoPO.builder()
.id(IdGenerator.generate())
.salarySendId(salarySendId)
.employeeId(m.getEmployeeId())
.salaryMonth(m.getSalaryMonth())
.taxAgentId(m.getTaxAgentId())
.salaryAcctRecordId(m.getSalaryAcctRecordId())
.sendStatus(SalarySendStatusEnum.UNSEND.getValue())
.salaryTemplate("")
.salaryAcctType(templateType)
.creator((long) user.getUID())
.createTime(new Date())
.updateTime(new Date())
.build()
).collect(Collectors.toList());
SalarySendPO salarySend = SalarySendPO.builder()
.id(salarySendId)
.salaryMonth(salaryAcctRecord.getSalaryMonth())
.salaryAccountingId(salaryAccountingId)
.salarySobId(salaryAcctRecord.getSalarySobId())
.sendNum(0)
.sendTotal(salarySendInfos.size())
.sendStatus(NumberUtils.INTEGER_ZERO) // 未冻结
.salaryAcctType(templateType)
.lastSendTime(new Date())
.creator((long) user.getUID())
.createTime(new Date())
.updateTime(new Date())
.build();
// 插入工资单发放记录
mapper.insert(salarySend);
// 插入工资单人员记录
salarySendInfoMapper.batchInsert(salarySendInfos);
return "";
}
@Override
public void revokeSalaryBill(SalaryAcctRecordPO salaryAcctRecord) {
// 校验salaryAccountingId
// if (salaryAcctRecord == null) {
// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100497, "核算id必传"));
// }
//
// SalaryAcctRecordPO po = SalaryAcctRecordPO.builder().id(salaryAccountingId).build();
// List<SalaryAcctRecordPO> acctRecords = getSalaryAcctRecordMapper().listSome(po);
// 检查核算的归档记录
if (salaryAcctRecord == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100498, "核算记录不存在"));
}
SalarySendPO build = SalarySendPO.builder().salaryAccountingId(salaryAcctRecord.getId()).deleteType(0).build();
List<SalarySendPO> salarySends = getSalarySendMapper().listSome(build);
if (CollectionUtils.isEmpty(salarySends)) {
return;
// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100505, "工资单不存在"));
}
SalarySendPO salarySend;
if (salaryAcctRecord.getBackCalcStatus() != null && salaryAcctRecord.getBackCalcStatus().equals(NumberUtils.INTEGER_ONE)) {
// todo 一般只有一个未冻结,同一个原始核算id后面如果有多级回算就会换成不同核算id
salarySend = salarySends.stream().filter(s -> s.getSendStatus().equals(NumberUtils.INTEGER_ZERO)).findFirst().orElse(null);
// if (salarySend != null && salarySend.getSendNum() < salarySend.getSendTotal()) {
// throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(139702, "正常原始核算或上一个回算尚未全部发送完成,不能进行撤回"));
// }
if (salarySend != null) {
// 将上一版本未冻结的给冻结掉
salarySend.setSendStatus(NumberUtils.INTEGER_ONE);
getSalarySendMapper().updateIgnoreNull(salarySend);
}
// 已经回算的删除 todo 以后多级回算注意要修改
salarySend = salarySends.stream().filter(s -> s.getSalaryAcctType() != null && s.getSalaryAcctType().equals(NumberUtils.INTEGER_ONE)).findFirst().orElse(null);
handleDelSalaryBill(salarySend);
// 2.正常核算处理
} else {
salarySend = salarySends.stream().filter(s -> s.getSendStatus().equals(NumberUtils.INTEGER_ZERO)).findFirst().orElse(null);
handleDelSalaryBill(salarySend);
}
}
private void handleDelSalaryBill(SalarySendPO salarySend) {
if (salarySend == null) {
return;
}
// 已发送工资单
SalarySendInfoPO sendInfo = SalarySendInfoPO.builder()
.deleteType(0)
.salarySendId(salarySend.getId())
.sendStatus(SalarySendStatusEnum.ALREADYSEND.getValue())
.salaryAcctType(NumberUtils.INTEGER_ZERO).build();
List<SalarySendInfoPO> salarySendInfos = getSalarySendInfoMapper().listSome(sendInfo);
if ((salarySend.getSendNum() > 0 || CollectionUtils.isNotEmpty(salarySendInfos)) && Objects.equals(salarySend.getSalaryAcctType(), NumberUtils.INTEGER_ONE)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100507, "补发工资单已经发放,不可进行回算"));
} else if (salarySend.getSendNum() > 0 || CollectionUtils.isNotEmpty(salarySendInfos)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100507, "工资单已经发放,不可撤销,可以进行回算"));
}
// 删除工资单
SalarySendPO salarySendPO = SalarySendPO.builder()
.id(salarySend.getId())
.sendNum(0)
.deleteType(1)
.build();
getSalarySendMapper().updateIgnoreNull(salarySendPO);
// 删除工资单发放
SalarySendInfoPO infoPO = SalarySendInfoPO.builder()
.salarySendId(salarySend.getId())
.deleteType(1)
.build();
getSalarySendInfoMapper().updateGrantWithdraw(infoPO, salarySend.getId(), null, null);
}
@Override
public PageInfo<SalarySendListDTO> listPage(SalarySendQueryParam queryParam) {
List<SalarySendListDTO> list = mapper.list(queryParam);
PageInfo<SalarySendListDTO> pageInfo = new PageInfo<>(list, SalarySendListDTO.class);
return pageInfo;
}
@Override
public SalarySendBaseInfoDTO getBaseInfo(Long id) {
SalarySendPO salarySend = mapper.getById(id);
if (salarySend == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100512, "工资单发放不存在"));
}
Long salaryAcctId = salarySend.getSalaryAccountingId();
SalarySobCycleDTO salarySobCycleDTO = getSalaryAcctRecordService(user).getSalarySobCycleById(salaryAcctId);
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
// List<SalaryAcctRecordPO> salaryAcctRecordPOS = getSalaryAcctRecordService(user).listBySalarySobIds(Collections.singletonList(salarySobCycleDTO.getSalarySobId()));
// // 是否有回算记录
// boolean haveBackCalc = salaryAcctRecordPOS.stream().filter(PO -> Objects.equals(PO.getBackCalcStatus(), NumberUtils.INTEGER_ONE) &&
// Objects.equals(sdf.format(PO.getSalaryMonth()), SalaryDateUtil.MONTH_FORMATTER.format(salarySobCycleDTO.getSalaryMonth()))).collect(Collectors.toList()).size() > 0;
String template = "";
// 获取默认模板
List<SalaryTemplatePO> salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(Collections.singletonList(salarySend.getSalarySobId()));
if (CollectionUtils.isNotEmpty(salaryTemplates)) {
// 是否是回算
if (Objects.equals(salarySend.getSalaryAcctType(), NumberUtils.INTEGER_ONE)) {
template = salaryTemplates.get(0).getReplenishName();
} else {
template = salaryTemplates.get(0).getName();
}
}
Boolean canSend = true;
SalaryAcctRecordPO acctRecord = getSalaryAcctRecordService(user).getById(salaryAcctId);
// 回算过,但是查看的是普通工资单(不能发);回算过,但是查看的是回算工资单(可以发);记录没回算过(可以发)
if(Objects.equals(acctRecord.getBackCalcStatus(), NumberUtils.INTEGER_ONE) && Objects.equals(salarySend.getSalaryAcctType(),NumberUtils.INTEGER_ZERO)){
canSend = false;
}
return SalarySendBaseInfoDTO.builder()
.salaryMonth(salarySobCycleDTO.getSalaryMonth())
.template(template)
.salarySobCycle(salarySobCycleDTO)
.sendNum(salarySend.getSendNum())
.sendTotal(salarySend.getSendTotal())
.canSend(canSend)
// .salaryAcctType(salarySend.getSalaryAcctType().toString())
// .haveBackCalc(haveBackCalc ? NumberUtils.INTEGER_ONE : NumberUtils.INTEGER_ZERO)
.build();
}
@Override
public Map<String, Object> mySalaryBill(Long salaryInfoId, Long currentEmployeeId) {
// List<SalarySendInfoPO> salarySendInfos = new LambdaQueryChainWrapper<>(salarySendInfoMapper)
// .eq(SalarySendInfoPO::getDeleteType, 0)
// .eq(SalarySendInfoPO::getTenantKey, currentTenantKey)
// .eq(SalarySendInfoPO::getId, salaryInfoId).list();
if (salaryInfoId == null) {
throw new SalaryRunTimeException("工资单记录不存在!");
}
SalarySendInfoPO po = new SalarySendInfoPO();
po.setDeleteType(0);
po.setId(salaryInfoId);
List<SalarySendInfoPO> salarySendInfos = salarySendInfoMapper.listSome(po);
if (CollectionUtils.isEmpty(salarySendInfos)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100511, "工资单信息不存在"));
}
if(currentEmployeeId.compareTo(salarySendInfos.get(0).getEmployeeId()) != 0){
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100511, "当前账号无法查看此工资单"));
}
SalarySendInfoPO salarySendInfo = salarySendInfos.get(0);
// 更新查看状态
if(salarySendInfo.getBillReadStatus() == null || NumberUtils.compare(salarySendInfo.getBillReadStatus(),BillReadStatusEnum.UNREAD.getValue()) == 0 ){
salarySendInfo.setBillReadStatus(BillReadStatusEnum.READED.getValue());
salarySendInfo.setUpdateTime(new Date());
getSalarySendInfoMapper().updateIgnoreNull(salarySendInfo);
}
// List<SalarySendPO> salarySends = new LambdaQueryChainWrapper<>(mapper)
// .eq(SalarySendPO::getDeleteType, 0)
// .eq(SalarySendPO::getTenantKey, currentTenantKey)
// .eq(SalarySendPO::getId, salarySendInfo.getSalarySendId()).list();
SalarySendPO sendPo = new SalarySendPO();
sendPo.setDeleteType(0);
sendPo.setId(salarySendInfo.getSalarySendId());
List<SalarySendPO> salarySends = mapper.listSome(sendPo);
if (CollectionUtils.isEmpty(salarySends)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100512, "工资单发放不存在"));
}
SalarySendPO salarySend = salarySends.get(0);
Date salaryMonth = salarySend.getSalaryMonth();
// 获取模板
String salaryTemplateContent = salarySendInfo.getSalaryTemplate();
if (StringUtils.isBlank(salaryTemplateContent)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100513, "没有默认模板,无法查看"));
}
SalaryTemplatePO salaryTemplate = buildSalaryTemplateContent(salaryTemplateContent);
// 判断是否是补发
boolean isReplenish = NumberUtils.INTEGER_ONE.equals(salarySendInfo.getSalaryAcctType());
// if (StringUtils.isNotBlank(salaryTemplate.getBackground())) {
// FileData fileByte = fileDownloadClient.getFileByte(Long.valueOf(salaryTemplate.getBackground()), currentTenantKey);
// String encode = Base64Encoder.encode(fileByte.getData());
// salaryTemplate.setBackground(encode);
// }
// 获取薪资项目数据
SalaryAcctResultPO acctPo = new SalaryAcctResultPO();
acctPo.setDeleteType(0);
acctPo.setSalaryAcctRecordId(salarySendInfo.getSalaryAcctRecordId());
acctPo.setEmployeeId(currentEmployeeId);
List<SalaryAcctResultPO> salaryAcctResultPOS = getSalaryAcctResultMapper().listSome(acctPo);
encryptUtil.decryptList(salaryAcctResultPOS, SalaryAcctResultPO.class);
SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(salarySendInfo.getSalaryAcctRecordId());
if (salaryAcctRecordPO == null) {
throw new SalaryRunTimeException("薪资核算记录不存在!");
}
List<Map<String, Object>> salaryAcctResultS = null;
if (Objects.equals(salaryAcctRecordPO.getBackCalcStatus(), NumberUtils.INTEGER_ONE) && !isReplenish) {
// 该记录回算过,并且获取的不是回算后的工资单
salaryAcctResultS = salaryAcctResultPOS.stream().map(m -> {
Map<String, Object> map = new LinkedHashMap<>();
map.put("salaryItemId", m.getSalaryItemId());
map.put("resultValue", m.getOriginResultValue());
return map;
}).collect(Collectors.toList());
} else {
salaryAcctResultS = salaryAcctResultPOS.stream().map(m -> {
Map<String, Object> map = new LinkedHashMap<>();
map.put("salaryItemId", m.getSalaryItemId());
map.put("resultValue", m.getResultValue());
return map;
}).collect(Collectors.toList());
}
Map<String, Object> map = new LinkedHashMap<>();
map.put("tenantName", "");
map.put("sendTime", SalaryDateUtil.getFormatLocalDateTime(salarySendInfo.getSendTime()));
List<SalaryTemplateSalaryItemSetListDTO> listDTOS = JSONArray.parseArray(isReplenish ? salaryTemplate.getReplenishSalaryItemSetting() : salaryTemplate.getSalaryItemSetting(), SalaryTemplateSalaryItemSetListDTO.class);
Optional<SalaryTemplateSalaryItemSetListDTO> optionalEmployeeInformation = listDTOS.stream().filter(e -> SalaryTemplateSalaryItemSetGroupConstant.EMPLOYEE_INFO_GROUP_ID.equals(e.getGroupId())).findFirst();
SalaryTemplateSalaryItemSetListDTO employeeInformation = optionalEmployeeInformation.orElse(null);
List<SalaryTemplateSalaryItemSetListDTO> itemSetListDTOS = listDTOS.stream().filter(e -> !SalaryTemplateSalaryItemSetGroupConstant.EMPLOYEE_INFO_GROUP_ID.equals(e.getGroupId())).collect(Collectors.toList());
List<Map<String, Object>> finalSalaryAcctResultS = salaryAcctResultS;
itemSetListDTOS.stream().forEach(item -> {
item.getItems()
.forEach(e -> {
if (CollectionUtils.isEmpty(finalSalaryAcctResultS)) {
e.setSalaryItemValue("");
} else {
Object o = finalSalaryAcctResultS.stream()
.filter(f -> f.get("salaryItemId") != null && String.valueOf(f.get("salaryItemId")).equals(e.getSalaryItemId())).findFirst()
.orElse(new HashMap<>())
.get("resultValue");
e.setSalaryItemValue(o == null ? "" : (String) o);
}
});
});
/**
* 过滤空
*/
if (Objects.equals(1, salaryTemplate.getSalaryItemNullStatus())) {
for (SalaryTemplateSalaryItemSetListDTO itemSetListDTO : itemSetListDTOS) {
List<SalaryTemplateSalaryItemListDTO> items = itemSetListDTO.getItems();
List<SalaryTemplateSalaryItemListDTO> collect = items.stream().filter(item -> StringUtils.isNotBlank(item.getSalaryItemValue())).collect(Collectors.toList());
itemSetListDTO.setItems(collect);
}
}
/**
* 过滤0
*/
if (Objects.equals(1, salaryTemplate.getSalaryItemZeroStatus())) {
for (SalaryTemplateSalaryItemSetListDTO itemSetListDTO : itemSetListDTOS) {
List<SalaryTemplateSalaryItemListDTO> items = itemSetListDTO.getItems();
List<SalaryTemplateSalaryItemListDTO> collect = items.stream()
.filter(item -> SalaryEntityUtil.string2BigDecimal(item.getSalaryItemValue()) == null
|| BigDecimal.ZERO.compareTo(SalaryEntityUtil.string2BigDecimal(item.getSalaryItemValue())) != 0)
.collect(Collectors.toList());
itemSetListDTO.setItems(collect);
}
}
TaxAgentPO taxAgentPO = getTaxAgentService(user).getById(salarySendInfo.getTaxAgentId());
DataCollectionEmployee simpleEmployee = getSalaryEmployeeService(user).getEmployeeById(salarySendInfo.getEmployeeId());
buildEmployeeInfo(employeeInformation, simpleEmployee, taxAgentPO.getName(), SalaryAcctResultBO.buildEmployeeFieldName());
map.put("employeeInformation", employeeInformation);
map.put("salaryGroups", itemSetListDTOS);
salaryTemplate.setTheme(getBillTitle(salaryTemplate.getTheme(), salaryMonth, currentEmployeeId));
// 工资单水印文本型动态变量 == 处理
handleSalaryWatermark(salaryTemplate, salarySendInfo, currentEmployeeId);
map.put("salaryTemplate", salaryTemplate);
map.put("salaryAcctResult", salaryAcctResultS);
// 工资单发送人、是否已确认
map.put("confirmStatus", salarySendInfo.getBillConfirmStatus() == null ? "0" : salarySendInfo.getBillConfirmStatus().toString());
map.put("sendEmployeeId", salarySendInfo.getSalarySendId());
BaseBean baseBean = new BaseBean();
String workFlowId = baseBean.getPropValue("hrmSalary", "feedbackWorkflowId");
map.put("feedbackWorkflowId",workFlowId);
return map;
}
/**
* 工资单水印文本型动态变量 == 处理
*
* @param salaryTemplate
* @param salarySendInfo
*/
private void handleSalaryWatermark(SalaryTemplatePO salaryTemplate, SalarySendInfoPO salarySendInfo, Long currentEmployeeId) {
SalaryBillWatermarkDTO salaryBillWatermark = JsonUtil.parseObject(salaryTemplate.getSalaryWatermark(), SalaryBillWatermarkDTO.class);
if (Objects.isNull(salaryBillWatermark) || Boolean.FALSE.equals(salaryBillWatermark.getWatermarkStatus()) ) {
return;
}
// 发送时已经处理好变量字段,可直接获取判断
List<String> wmTextFieldIds = (List<String>) salaryBillWatermark.getWmSetting().getOrDefault("wmSelectedFieldIds", Lists.newArrayList());
if (CollectionUtils.isEmpty(wmTextFieldIds)) {
return;
}
boolean needQueryEmp = (boolean) salaryBillWatermark.getWmSetting().getOrDefault("needQueryEmp", false);
DataCollectionEmployee simpleEmployee = null;
if (needQueryEmp) {
simpleEmployee = getSalaryEmployeeService(user).getEmployeeById(currentEmployeeId);
}
String wmText = salaryBillWatermark.getWmSetting().getOrDefault("wmText", StringUtils.EMPTY).toString();
wmText = SalaryBillBO.handleWmText(wmText, wmTextFieldIds, simpleEmployee);
// 重新设回水印
salaryBillWatermark.getWmSetting().put("wmText", wmText);
salaryTemplate.setSalaryWatermark(JSON.toJSONString(salaryBillWatermark));
}
@Override
public PageInfo<SalarySendInfoListDTO> salarySendInfoListPage(SalarySendInfoQueryParam queryParam) {
//排序配置
OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
queryParam.setOrderRule(orderRule);
List<SalarySendInfoListDTO> page = salarySendInfoMapper.list(queryParam);
PageInfo<SalarySendInfoListDTO> pageInfo = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(),
page, SalarySendInfoListDTO.class);
SalarySysConfPO needFeedBack = getSalarySysConfService(user).getOneByCode(SalarySysConstant.SALARY_SEND_FEEDBACK);
if(ObjectUtils.isNotEmpty(needFeedBack) && StringUtils.equals(needFeedBack.getConfValue(),"1")){
// 默认为空时,未读未确认
pageInfo.getList().stream().forEach(obj -> {
SalarySendInfoListDTO dto = (SalarySendInfoListDTO) obj;
if (StringUtils.isBlank( dto.getBillReadStatus() )){
dto.setBillReadStatus(BillReadStatusEnum.UNREAD.getDefaultLabel());
} else {
dto.setBillReadStatus(BillReadStatusEnum.getDefaultLabelByValue( Integer.valueOf(dto.getBillReadStatus()) ));
}
if (StringUtils.isBlank(dto.getBillConfirmStatus())){
dto.setBillConfirmStatus(BillConfimStatusEnum.UNCONFIRMED.getDefaultLabel());
} else {
dto.setBillConfirmStatus(BillConfimStatusEnum.getDefaultLabelByValue( Integer.valueOf(dto.getBillConfirmStatus()) ));
}
});
}
return pageInfo;
}
@Override
public List<SalarySendInfoListDTO> salarySendInfoList(Long salarySendId) {
return salarySendInfoMapper.list(SalarySendInfoQueryParam.builder().salarySendId(salarySendId).build());
}
@Override
public PageInfo<SalaryMySalaryBillListDTO> mySalaryBillListPage(SalaryBillQueryParam queryParam) {
List<SalaryMySalaryBillListDTO> list = salarySendInfoMapper.mySalaryBillList(queryParam);
PageInfo<SalaryMySalaryBillListDTO> pageInfo = new PageInfo<>(list, SalaryMySalaryBillListDTO.class);
pageInfo.setTotal(list.size());
pageInfo.setPageNum(queryParam.getCurrent());
pageInfo.setPageSize(queryParam.getPageSize());
return pageInfo;
}
@Override
public PageInfo<SalarySendDetailListDTO> salarySendInfoDetailListPage(SalarySendDetailQueryParam queryParam) {
//排序配置
OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
queryParam.setOrderRule(orderRule);
Set<Long> otherSalaryAcctRecordIds = null;
if (queryParam.getMergeCountTax() != null && queryParam.getMergeCountTax()) {
//查询关联的核酸id这里认为一次发放只对应一条核算记录
Long salaryAccRecordId =
salarySendInfoMapper.listSalaryAccRecordIds(queryParam).stream().findFirst().orElse(null);
// 查询合并计税的其他薪资核算记录
List<SalaryAcctRecordPO> otherSalaryAcctRecordPOS =
getSalaryAcctRecordService(user).listById4OtherConsolidatedTax(salaryAccRecordId);
if (CollectionUtils.isEmpty(otherSalaryAcctRecordPOS)) {
return new PageInfo<>();
}
// 查询合并计税的薪资核算人员
otherSalaryAcctRecordIds = SalaryEntityUtil.properties(otherSalaryAcctRecordPOS, SalaryAcctRecordPO::getId);
if (otherSalaryAcctRecordIds.isEmpty()) {
return new PageInfo<>();
}
}
List<SalarySendDetailListDTO> list = MapperProxyFactory.getProxy(SalarySendInfoMapper.class).detailList(queryParam, otherSalaryAcctRecordIds);
return SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(),
list, SalarySendDetailListDTO.class);
}
/**
* 获取工资单标题
*
* @param theme
* @param salaryMonth
* @param currentEmployeeId
* @return
*/
private String getBillTitle(String theme, Date salaryMonth, Long currentEmployeeId) {
String yearI18n = SalaryI18nUtil.getI18nLabel(100325, "");
String monthI18n = SalaryI18nUtil.getI18nLabel(100326, "");
String companyName = "";
if (currentEmployeeId != null) {
ResourceComInfo resourceComInfo = null;
SubCompanyComInfo subCompanyComInfo = new SubCompanyComInfo();
try {
resourceComInfo = new ResourceComInfo();
subCompanyComInfo = new SubCompanyComInfo();
} catch (Exception e) {
log.error("资源异常", e);
}
companyName = subCompanyComInfo.getSubCompanyname(resourceComInfo.getSubCompanyID(currentEmployeeId + ""));
}
return theme
.replace("${companyName}", companyName)
.replace("${salaryMonth}", new SimpleDateFormat("yyyy年MM月").format(salaryMonth));
}
/**
* 根据模板内容转为工资单模板对象
* 注意:不要通过反序列化,可能会因为历史原因修改字段名称而无法序列化
*
* @param salaryTemplateContent
* @return
*/
private SalaryTemplatePO buildSalaryTemplateContent(String salaryTemplateContent) {
Map<String, Object> map = JsonUtil.parseMap(salaryTemplateContent, Object.class);
return SalaryTemplatePO.builder()
.id(Long.valueOf(map.getOrDefault("id", "0").toString()))
.name(map.getOrDefault("name", "").toString())
.salarySobId(Long.valueOf(map.getOrDefault("salarySobId", "0").toString()))
.useType(Integer.valueOf(map.getOrDefault("useType", "0").toString()))
.description(map.getOrDefault("description", "").toString())
.emailStatus(Integer.valueOf(map.getOrDefault("emailStatus", "0").toString()))
.sendEmailId(Long.valueOf(map.getOrDefault("sendEmailId", "0").toString()))
.msgStatus(Integer.valueOf(map.getOrDefault("msgStatus", "0").toString()))
.salaryWatermark(map.getOrDefault("salaryWatermark", StringUtils.EMPTY).toString())
.theme(map.getOrDefault("theme", "").toString())
.background(map.getOrDefault("background", "").toString())
.textContent(map.getOrDefault("textContent", "").toString())
.textContentPosition(Integer.valueOf(map.getOrDefault("textContentPosition", "0").toString()))
.salaryItemNullStatus(Integer.valueOf(map.getOrDefault("salaryItemNullStatus", "0").toString()))
.salaryItemZeroStatus(Integer.valueOf(map.getOrDefault("salaryItemZeroStatus", "0").toString()))
.salaryItemSetting(map.getOrDefault("salaryItemSetting", "").toString())
.replenishName(map.getOrDefault("replenishName", "").toString())
.replenishSalaryItemSetting(map.getOrDefault("replenishSalaryItemSetting", "").toString())
.build();
}
/**
* 构建工资单中的人员信息
*
* @param employeeInformation
* @param simpleEmployee
* @param taxAgentName
* @param employeeField
*/
private void buildEmployeeInfo(SalaryTemplateSalaryItemSetListDTO employeeInformation, DataCollectionEmployee simpleEmployee, String taxAgentName, Map<String, String> employeeField) {
if (employeeInformation == null) {
return;
}
if (CollectionUtils.isNotEmpty(employeeInformation.getItems())) {
//获取员工信息的字段名和中文描述的map关系
SalaryFormulaEmployeeDTO salaryFormulaEmployeeDTO = SalaryFormulaEmployeeDTO.builder().employeeId(simpleEmployee.getEmployeeId())
.birthday(simpleEmployee.getBirthday())
.departmentName(simpleEmployee.getDepartmentName())
.email(StringUtils.isEmpty(simpleEmployee.getEmail()) ? "" : simpleEmployee.getEmail())
.jobcall(simpleEmployee.getJobcall())
.companystartdate(simpleEmployee.getCompanystartdate())
.sex("0".equals(simpleEmployee.getSex()) ? "" : "")
.mobile(StringUtils.isEmpty(simpleEmployee.getMobile()) ? "" : simpleEmployee.getMobile())
.jobtitleName(simpleEmployee.getJobtitleName())
.status(simpleEmployee.getStatus() == null ? "" : simpleEmployee.getStatus())
.telephone(StringUtils.isEmpty(simpleEmployee.getTelephone()) ? "" : simpleEmployee.getTelephone())
.username(StringUtils.isEmpty(simpleEmployee.getUsername()) ? "" : simpleEmployee.getUsername())
.workcode(StringUtils.isEmpty(simpleEmployee.getWorkcode()) ? "" : simpleEmployee.getWorkcode())
.taxAgentName(taxAgentName)
.build();
List<SalaryTemplateSalaryItemListDTO> items = employeeInformation.getItems();
Set<Map.Entry<String, String>> entries = employeeField.entrySet();
for (SalaryTemplateSalaryItemListDTO e : items) {
Optional<Map.Entry<String, String>> entry = entries.stream().filter(f -> Objects.equals(e.getName(), f.getValue())).findFirst();
if (entry.isPresent()) {
String key = entry.get().getKey();
if (StringUtils.isNotBlank(key)) {
String getter = "get" + key.substring(0, 1).toUpperCase() + key.substring(1);
try {
Method method = salaryFormulaEmployeeDTO.getClass().getMethod(getter);
Object invoke = method.invoke(salaryFormulaEmployeeDTO);
e.setSalaryItemValue((String) invoke);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
log.error("no such method", e);
}
}
}
}
}
}
/**
* 组装详情数据
*
* @param salaryItems
* @param list
* @param salaryAccountingId
*/
@Override
public List<Map<String, Object>> buildDetailList(List<SalaryTemplateSalaryItemListDTO> salaryItems, List<SalarySendDetailListDTO> list, Long salaryAccountingId) {
List<Map<String, Object>> listMaps = new ArrayList<>();
if (CollectionUtils.isEmpty(list)) {
return listMaps;
}
// 获取薪资项目数据
// List<SalaryAcctResultPO> salaryAccountingResults = new LambdaQueryChainWrapper<>(salaryAcctResultMapper)
// .eq(SalaryAcctResultPO::getDeleteType, 0)
// .eq(SalaryAcctResultPO::getSalaryAcctRecordId, salaryAccountingId).list();
SalaryAcctResultPO po = new SalaryAcctResultPO();
po.setDeleteType(0);
po.setSalaryAcctRecordId(salaryAccountingId);
po.setEmployeeIds(list.stream().map(SalarySendDetailListDTO::getEmployeeId).collect(Collectors.toList()));
List<SalaryAcctResultPO> salaryAccountingResults = getSalaryAcctResultMapper().listSome(po);
encryptUtil.decryptList(salaryAccountingResults, SalaryAcctResultPO.class);
// 动态列
list.forEach(e -> {
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", e.getId());
map.put("employeeId", e.getEmployeeId());
map.put("username", e.getUsername());
map.put("taxAgent", e.getTaxAgent());
map.put("department", e.getDepartment());
map.put("mobile", e.getMobile());
map.put("jobNum", e.getJobNum());
map.put("email", e.getEmail());
salaryItems.forEach(i -> {
Optional<SalaryAcctResultPO> optional = salaryAccountingResults.stream()
.filter(r -> r.getEmployeeId().equals(e.getEmployeeId()) && r.getSalaryItemId().equals(Long.valueOf(i.getSalaryItemId()))).findFirst();
map.put(i.getSalaryItemId() + SalaryItemConstant.DYNAMIC_SUFFIX, optional.isPresent() ? optional.get().getResultValue() : "");
});
listMaps.add(map);
});
return listMaps;
}
/**
* 组装详情数据
*
* @param list
* @param salaryAcctResultValues
* @return
*/
@Override
public List<Map<String, Object>> buildDetailList(List<SalarySendInfoListDTO> list,
List<SalaryAcctEmployeePO> salaryAcctEmployees, List<SalaryAcctResultPO> salaryAcctResultValues) {
List<Map<String, Object>> listMaps = new ArrayList<>();
if (CollectionUtils.isEmpty(list)) {
return listMaps;
}
// 所有个税扣缴义务人
// Map<Long, String> taxAgentMap = SalaryEntityUtil.convert2Map(getTaxAgentService(user).listAll(), TaxAgentPO::getId, TaxAgentPO::getName);
// 按人员分组核算数据
// Map<Long, List<SalaryAcctEmployeePO>> relationSalaryAcctEmployeeMap = SalaryEntityUtil.group2Map(salaryAcctEmployees, SalaryAcctEmployeePO::getEmployeeId);
Map<String, SalaryAcctEmployeePO> salaryAcctEmployeeMap = SalaryEntityUtil.convert2Map(salaryAcctEmployees, salaryAcctEmployee -> salaryAcctEmployee.getEmployeeId() + "-" + salaryAcctEmployee.getTaxAgentId());
Map<Long, List<SalaryAcctResultPO>> singleEmpAcctMap = SalaryEntityUtil.group2Map(salaryAcctResultValues, SalaryAcctResultPO::getSalaryAcctEmpId);
List<Long> employeeIds = list.stream().map(SalarySendInfoListDTO::getEmployeeId).distinct().collect(Collectors.toList());
// 查询分部 查询部门
List<DataCollectionEmployee> comInfos = getSalaryEmployeeService(user).getEmployeeByIdsAll(employeeIds);
Map<Long, DataCollectionEmployee> empComMap = SalaryEntityUtil.convert2Map(comInfos, DataCollectionEmployee::getEmployeeId);
// 当前查询核算记录是回算,但是发放不是回算的,那么就取源头核算结果
boolean isOrigin = false;
SalaryAcctRecordPO salaryAcctRecord = CollectionUtils.isEmpty(list) ? null : getSalaryAcctRecordService(user).getById(list.get(0).getSalaryAcctRecordId());
if (Objects.nonNull(salaryAcctRecord) && Objects.nonNull(salaryAcctRecord.getBackCalcStatus())) {
isOrigin = !NumberUtils.INTEGER_ONE.equals(list.get(0).getSalaryAcctType()) && salaryAcctRecord.getBackCalcStatus().equals(NumberUtils.INTEGER_ONE);
}
// 动态列
long l = System.currentTimeMillis();
Map<Long, DataCollectionEmployee> finalEmpSubComMap = empComMap;
boolean finalIsOrigin = isOrigin;
list.forEach(e -> {
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", e.getId() + "");
DataCollectionEmployee hrmDepartmentComInfo = finalEmpSubComMap.get(e.getEmployeeId());
if (hrmDepartmentComInfo != null) {
map.put("subCompanyName", hrmDepartmentComInfo.getSubcompanyName());
} else {
map.put("subCompanyName", "");
}
if (hrmDepartmentComInfo != null) {
map.put("department", e.getDepartment());
}
map.put("employeeId", e.getEmployeeId() + "");
map.put("username", e.getUsername());
map.put("mobile", e.getMobile());
map.put("jobNum", e.getJobNum());
map.put("email", e.getEmail());
// map.put("employeeType", SalarySendEmployeeTypeEnum.getNameByValue(e.getEmployeeType()));
// 单个人的核算数据
List<SalaryAcctResultPO> resultValues = Lists.newArrayList();
// 个税扣缴义务人
// if (incomeCategorys.size() > 1) {
// List<SalaryAcctEmployeePO> acctEmployees = relationSalaryAcctEmployeeMap.getOrDefault(e.getEmployeeId(), Collections.emptyList());
// for (SalaryAcctEmployeePO salaryAcctEmployee : acctEmployees) {
// if (singleEmpAcctMap.containsKey(salaryAcctEmployee.getId())) {
// resultValues.add(singleEmpAcctMap.get(salaryAcctEmployee.getId()));
// }
// }
// } else {
// SalaryAcctEmployeePO salaryAcctEmployee = salaryAcctEmployeeMap.get(e.getEmployeeId() + "-" + e.getTaxAgent());
// if (salaryAcctEmployee != null && singleEmpAcctMap.containsKey(salaryAcctEmployee.getId())) {
// resultValues.add(singleEmpAcctMap.get(salaryAcctEmployee.getId()));
// }
// }
SalaryAcctEmployeePO salaryAcctEmployee = salaryAcctEmployeeMap.get(e.getEmployeeId() + "-" + e.getTaxAgentId());
if (salaryAcctEmployee != null && singleEmpAcctMap.containsKey(salaryAcctEmployee.getId())) {
resultValues.addAll(singleEmpAcctMap.get(salaryAcctEmployee.getId()));
}
// 薪资项目
// singleEmpAcctResultList.forEach(i-> map.put(i.getSalaryItemId() + SalaryArchiveConstant.DYNAMIC_SUFFIX, i.getResultValue()));
for (SalaryAcctResultPO salaryAcctResultValue : resultValues) {
if (finalIsOrigin) {
map.put(salaryAcctResultValue.getSalaryItemId() + SalaryArchiveConstant.DYNAMIC_SUFFIX, salaryAcctResultValue.getResultValue());
} else {
map.put(salaryAcctResultValue.getSalaryItemId() + SalaryArchiveConstant.DYNAMIC_SUFFIX, salaryAcctResultValue.getResultValue());
}
}
listMaps.add(map);
});
log.info("工资单详情构建总耗时:{}毫秒", System.currentTimeMillis() - l);
return listMaps;
}
/**
* 通过薪资账套获取模板的薪资项目
*
* @param salaryTemplate
* @return
*/
@Override
public List<SalaryTemplateSalaryItemListDTO> getSalaryItemsSetting(SalaryTemplatePO salaryTemplate, boolean isReplenish) {
List<SalaryTemplateSalaryItemListDTO> salaryItems = new ArrayList<>();
if (salaryTemplate == null) {
return salaryItems;
}
// 正常模板
if (!isReplenish && StringUtils.isNotEmpty(salaryTemplate.getSalaryItemSetting())) {
List<SalaryTemplateSalaryItemSetListDTO> salaryTemplateShowSetData = JsonUtil.parseList(salaryTemplate.getSalaryItemSetting(),
SalaryTemplateSalaryItemSetListDTO.class);
salaryTemplateShowSetData.stream().filter(f -> !f.getGroupId().equals(SalaryTemplateSalaryItemSetGroupConstant.EMPLOYEE_INFO_GROUP_ID)).forEach(e -> {
salaryItems.addAll(e.getItems());
});
}
// 补发模板
if (isReplenish && StringUtils.isNotEmpty(salaryTemplate.getReplenishSalaryItemSetting())) {
List<SalaryTemplateSalaryItemSetListDTO> salaryTemplateShowSetData = JsonUtil.parseList(salaryTemplate.getReplenishSalaryItemSetting(),
SalaryTemplateSalaryItemSetListDTO.class);
salaryTemplateShowSetData.stream().filter(f -> !f.getGroupId().equals(SalaryTemplateSalaryItemSetGroupConstant.EMPLOYEE_INFO_GROUP_ID)).forEach(e ->
salaryItems.addAll(e.getItems())
);
}
return salaryItems;
}
@Override
public Map<String, Object> grant(SalarySendGrantParam param) {
if (param.getSalarySendId() == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100327, "工资单发放Id必传"));
}
Long salarySendId = param.getSalarySendId();
Collection<Long> ids = param.getIds();
if (param.getSalarySendRangeIds() != null) {
//如果传了范围id则使用范围id发放
ids = getSalarySendRangeService(user)
.getSendInfoIdsBySendId(salarySendId, param.getSalarySendRangeIds(), SalarySendGrantTypeEnum.GRANT);
if (ids.isEmpty()) {// 由于查出来是空的,会导致全部发放,在此进行拦截
throw new SalaryRunTimeException("工资发放范围内没有匹配员工");
}
}
SalarySendPO salarySend = mapper.getById(salarySendId);
if (salarySend == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100512, "工资单发放不存在"));
}
// 已经冻结不能操作
if (Objects.equals(salarySend.getSendStatus(), NumberUtils.INTEGER_ONE)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(0, "工资单已冻结"));
}
// 获取默认模板
List<SalaryTemplatePO> salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(Collections.singletonList(salarySend.getSalarySobId()));
if (CollectionUtils.isEmpty(salaryTemplates)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100518, "没有默认模板,无法发送"));
}
SalaryTemplatePO templatePO = salaryTemplates.get(0);
Date sendTime = new Date();
// 获取可发送的列表
List<Map<String, Object>> enableSendList = getEnableSendList(salarySend, ids, templatePO);
// 1.发放
SalarySendInfoPO po = new SalarySendInfoPO();
po.setSendStatus(SalarySendStatusEnum.ALREADYSEND.getValue());
po.setSendTime(sendTime);
po.setSalaryTemplate(JsonUtil.toJsonString(templatePO));
salarySendInfoMapper.updateGrantWithdraw(po, salarySendId, Arrays.asList(SalarySendStatusEnum.UNSEND.getValue(), SalarySendStatusEnum.WITHDRAW.getValue()), ids);
List<SalarySendInfoPO> list = salarySendInfoMapper.listSome(SalarySendInfoPO.builder().salarySendId(salarySendId).build());
//需要发送工资的人
List<SalarySendInfoPO> sendList = list.stream().filter(e -> e.getSendStatus().equals(SalarySendStatusEnum.ALREADYSEND.getValue())).collect(Collectors.toList());
int sendNum = sendList.size();
int sendTotal = list.size();
SalarySendPO salarySendNew = new SalarySendPO();
try {
BeanUtils.copyProperties(salarySendNew, salarySend);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
salarySendNew.setSendNum(sendNum);
salarySendNew.setSendTotal(sendTotal);
salarySendNew.setLastSendTime(sendTime);
mapper.updateById(salarySendNew);
List<SalarySendInfoPO> needSendList = Lists.newArrayList();
enableSendList.forEach(map -> {
sendList.forEach(item -> {
if (item.getId() == Long.valueOf(map.get("id").toString()).longValue()) {
needSendList.add(item);
}
});
});
// 发送消息
param.setTemplate(templatePO);
sendMessage(true, needSendList, param, salarySend);
Map<String, Object> map = new HashMap<>(2);
map.put("sendNum", sendNum);
map.put("sendTotal", sendTotal);
return map;
}
/**
* 发送消息
*
* @param sendFlag true 发送 false 撤回
* @param list
* @param param
* @param salarySend
*/
private void sendMessage(boolean sendFlag, List<SalarySendInfoPO> list, SalarySendGrantParam param, SalarySendPO salarySend) {
new Thread() {
public void run() {
List<SalarySendInfoPO> pos = list;
if (CollectionUtils.isNotEmpty(param.getIds())) {
pos = list.stream().filter(f -> param.getIds().contains(f.getId())).collect(Collectors.toList());
}
pos.forEach(po -> {
Long employeeId = po.getEmployeeId();
if (sendFlag) {
sendPayRollEMMessage(po, param.getTemplate(), employeeId);
} else {
withdrawPayrollEMMessage(po, employeeId);
}
});
}
}.start();
}
/**
* 发送Em消息
*/
private void sendPayRollEMMessage(SalarySendInfoPO po, SalaryTemplatePO template, Long employeeId) {
// try {
// MessageUtil.sendSMS(mobile, content);
// } catch (Exception e) {
// kqLog.info("SendSMS error.resourceId:" + resourceId + ">>>>>>mobile>>>>>>" + mobile);
// log.writeLog(e);
// }
Long id = po.getId();
String background = template.getBackground();
String billTitle = getBillTitle(template.getTheme(), po.getSalaryMonth(), employeeId);
MessageType messageType = MessageType.newInstance(499); // 消息来源(见文档第四点补充 必填)
Set<String> userIdList = new HashSet<>(); // 接收人id 必填
userIdList.add(employeeId.toString());
String title = billTitle; // 标题
String context = "点击查看详情"; // 内容
// PC端链接
String linkUrl = weaver.general.GCONST.getContextPath() + "/spa/hrmSalary/static/index.html#/main/hrmSalary/mobilepayroll?id=" + id + "&recipient=" + employeeId;
// 移动端链接
String linkMobileUrl = weaver.general.GCONST.getContextPath() + "/spa/hrmSalary/static/index.html#/main/hrmSalary/mobilepayroll?type=phone&id=" + id + "&recipient=" + employeeId;
try {
MessageBean messageBean = Util_Message.createMessage(messageType, userIdList, title, context, linkUrl, linkMobileUrl);
messageBean.setCreater(user.getUID());// 创建人id
messageBean.setBizState("0");// 需要修改消息为已处理等状态时传入,表示消息最初状态为待处理
messageBean.setTargetId("499|" + id); //消息来源code +“|”+业务id需要修改消息为已处理等状态时传入
if (StringUtils.isNotBlank(background)) {
messageBean.setPictureUrl(background);
} else {
messageBean.setPictureUrl("/hrm/hrm_e9/images/payroll.jpg?pictype=jpg");
}
Util_Message.store(messageBean);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 撤回EM消息
*
* @param po
*/
private void withdrawPayrollEMMessage(SalarySendInfoPO po, Long employeeId) {
try {
MessageBean messageBean = Util_Message.createMessage();
messageBean.setUserList(new HashSet<>());//接收人id
messageBean.setUserId(employeeId.intValue());
messageBean.setTargetId("499|" + po.getId()); //code + “|” + 业务id
//messageBean.setMessageType(MessageType.newInstance(121));//消息来源code(传了代表code也做为删除时的条件默认不传
Util_Message.delMessageTargetid(messageBean);
} catch (Exception e) {
e.printStackTrace();
}
}
private List<Map<String, Object>> getEnableSendList(SalarySendPO salarySend, Collection<Long> ids, SalaryTemplatePO salaryTemplate) {
// 1.根据模板获取薪资项目设置
SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salarySend.getSalaryAccountingId());
boolean isReplenish = salaryAcctRecord != null && Objects.equals(salaryAcctRecord.getBackCalcStatus(), (NumberUtils.INTEGER_ONE));
List<SalaryTemplateSalaryItemListDTO> salaryItems = getSalaryItemsSetting(salaryTemplate, isReplenish);
SalarySendDetailQueryParam queryParam = new SalarySendDetailQueryParam();
queryParam.setSalarySendId(salarySend.getId());
// 空就是所有
queryParam.setIds(ids);
queryParam.setSendStatuss(Arrays.asList(SalarySendStatusEnum.UNSEND.getValue(), SalarySendStatusEnum.WITHDRAW.getValue()));
// 2.获取基本数据
List<SalarySendDetailListDTO> list = salarySendInfoMapper.detailList(queryParam, null);
// 3.组装详情数据
List<Map<String, Object>> listMaps = buildDetailList(salaryItems, list, salarySend.getSalaryAccountingId());
return listMaps;
}
// /**
// * 发送消息
// *
// * @param salarySend
// * @param enableSendList
// * @param salaryTemplate
// * @param currentTenantKey
// */
// private void sendMessage(SalarySendPO salarySend, List<Map<String, Object>> enableSendList, SalaryTemplatePO salaryTemplate, String tenantName, Long currentEmployeeId, String currentTenantKey) {
// if (StringUtils.isNotBlank(salaryTemplate.getBackground())) {
// FileData fileByte = fileDownloadClient.getFileByte(Long.valueOf(salaryTemplate.getBackground()), currentTenantKey);
// String encode = Base64Encoder.encode(fileByte.getData());
// salaryTemplate.setBackground(encode);
// }
// // 邮箱打开
// boolean isEmailOpen = salaryTemplate.getEmailStatus().equals(SalaryTemplateWhetherEnum.TRUE.getValue());
//
// LocalDate salaryMonth = salarySend.getSalaryMonth();
// String yearI18n = SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100325, "年");
// String monthI18n = SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100326, "月");
// String text = salaryMonth.getYear() +
// yearI18n +
// salaryMonth.getMonth().getValue() +
// monthI18n +
// SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100520, "工资待发明细");
//
// UserEntity sendUser = null;
// // 标题
// String title = getBillTitle(salaryTemplate.getTheme(), salaryMonth, tenantName, currentEmployeeId, currentTenantKey);
//
// // 获取所有人员信息
// List<Long> ids = enableSendList.stream().map(e->Long.valueOf(e.get("employeeId").toString())).collect(Collectors.toList());
// List<DataCollectionEmployee> allEmployees = hrmCommonEmployeeService.getEmployeeByIds(ids, currentTenantKey);
// List<SalaryTemplateSalaryItemSetListDTO> listDTOS = JSONArray.parseArray(salaryTemplate.getSalaryItemSetting(), SalaryTemplateSalaryItemSetListDTO.class);
// Optional<SalaryTemplateSalaryItemSetListDTO> optionalEmployeeInformation = listDTOS.stream().filter(e -> SalaryTemplateSalaryItemSetGroupConstant.EMPLOYEE_INFO_GROUP_ID.equals(e.getGroupId())).findFirst();
// SalaryTemplateSalaryItemSetListDTO employeeInformation = optionalEmployeeInformation.orElse(null);
// Map<String, String> employeeField = SalaryAcctResultBO.buildEmployeeFieldName();
// enableSendList.forEach(e -> {
// Optional<DataCollectionEmployee> optionalSimpleEmployee = allEmployees.stream().filter(f->f.getEmployeeId().equals(Long.valueOf(e.get("employeeId").toString()))).findFirst();
// if (optionalSimpleEmployee.isPresent()) {
// buildEmployeeInfo(employeeInformation, optionalSimpleEmployee.get(), e.get("taxAgent").toString(), employeeField);
// }
//
// List<UserEntity> receivers = Collections.singletonList(
// SalarySendBO.buildUser(Long.valueOf(e.get("employeeId").toString()), e.get("email") == null ? "" : e.get("email").toString(), currentTenantKey));
// Entity entity = SalarySendBO.buildEntity(e.get("id").toString(), SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 94626, "工资单"));
// EmailEntity emailInfo = new EmailEntity();
// // 邮箱打开
// if (isEmailOpen) {
// String emailContent = SalarySendBO.buildEmailContent(e, employeeInformation, title, salaryTemplate);
// emailInfo = SalarySendBO.buildEmailInfo(text, emailContent, salaryTemplate.getSendEmailId());
// }
// SendMessageEntity message = SalarySendBO.buildSendMessageEntity(text, sendUser, receivers, entity, emailInfo);
// log.info("开始发送============:{}", JsonUtil.toJsonString(message));
// // 开始发送
// log.info("发送结果===:{}", JsonUtil.toJsonString(asyncSystemMessageRest.sendMsg(message)));
// });
// }
@Override
public Map<String, Object> withdraw(SalarySendWithdrawParam param) {
if (param.getSalarySendId() == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100327, "工资单发放Id必传"));
}
Long salarySendId = param.getSalarySendId();
Collection<Long> ids = param.getIds();
// 获取可撤回的工资单
if (param.getSalarySendRangeIds() != null) {
//如果传了范围id则使用范围id撤回
ids = getSalarySendRangeService(user)
.getSendInfoIdsBySendId(salarySendId, param.getSalarySendRangeIds(), SalarySendGrantTypeEnum.WITHDRAW);
if (ids.isEmpty()) {// 由于查出来是空的,会导致全部发放,在此进行拦截
throw new SalaryRunTimeException("工资撤回范围内没有匹配的员工");
}
}
SalarySendPO salarySend = mapper.getById(salarySendId);
if (salarySend == null) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(100512, "工资单发放不存在"));
}
// 撤回
SalarySendInfoPO po = new SalarySendInfoPO();
po.setSendStatus(SalarySendStatusEnum.WITHDRAW.getValue());
List<Integer> statusList = new ArrayList<>();
statusList.add(SalarySendStatusEnum.ALREADYSEND.getValue());
salarySendInfoMapper.updateGrantWithdraw(po, salarySendId, statusList, ids);
po = new SalarySendInfoPO();
po.setDeleteType(0);
po.setSalarySendId(salarySendId);
List<SalarySendInfoPO> list = salarySendInfoMapper.listSome(po);
int sendNum = (int) list.stream().filter(e -> e.getSendStatus().equals(SalarySendStatusEnum.ALREADYSEND.getValue())).count();
int sendTotal = list.size();
SalarySendPO salarySendNew = new SalarySendPO();
try {
BeanUtils.copyProperties(salarySendNew, salarySend);
} catch (Exception e) {
throw new SalaryRunTimeException("数据转换异常, " + e.getMessage());
}
salarySendNew.setSendNum(sendNum);
salarySendNew.setSendTotal(sendTotal);
mapper.updateById(salarySendNew);
// 记录日志
// SalaryLoggerUtil.recordUpdateSingleLog(salarySendLoggerTemplate,
// salarySend.getId(),
// salarySend.getSalaryMonth() + "-" + (CollectionUtils.isNotEmpty(salarySobs) ? salarySobs.get(0).getName() : ""),
// SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100521, "撤回工资单发放"),
// SalaryI18nUtil.getI18nLabel(currentTenantKey, currentEmployeeId, 100521, "撤回工资单发放"),
// salarySend,
// salarySendNew);
SalarySendGrantParam grantParam = SalarySendGrantParam.builder().ids(param.getIds()).salarySendId(param.getSalarySendId()).build();
// 异步发送消息:先修改数据再发消息,避免出错后无法撤回撤回消息
sendMessage(false, list, grantParam, salarySend);
Map<String, Object> map = new HashMap<>(2);
map.put("sendNum", sendNum);
map.put("sendTotal", sendTotal);
return map;
}
@Override
public XSSFWorkbook exportInfoList(SalarySendInfoQueryParam queryParam) {
// 1.工作簿名称
String sheetName = SalaryI18nUtil.getI18nLabel(100528, "工资单发放信息");
List<Object> header = new ArrayList<>();
header.add(SalaryI18nUtil.getI18nLabel(85429, "姓名"));
header.add(SalaryI18nUtil.getI18nLabel(86184, "个税扣缴义务人"));
header.add(SalaryI18nUtil.getI18nLabel(86185, "部门"));
header.add(SalaryI18nUtil.getI18nLabel(86186, "手机号"));
header.add(SalaryI18nUtil.getI18nLabel(86317, "工号"));
header.add(SalaryI18nUtil.getI18nLabel(86317, "发送状态"));
List<List<Object>> rows = new ArrayList<>();
// 2.表头
rows.add(header);
// 校验
SalarySendInfoQueryParam.checkParam(queryParam);
// 获取行数据
//排序配置
OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
queryParam.setOrderRule(orderRule);
List<SalarySendInfoListDTO> list = salarySendInfoMapper.list(queryParam);
list.forEach(e -> {
// 发放状态
e.setSendStatus(SalarySendStatusEnum.getDefaultLabelByValue(Integer.valueOf(e.getSendStatus())));
});
// 3.添加行记录
// 3.表数据
for (SalarySendInfoListDTO dto : list) {
List<Object> row = new ArrayList<>();
row.add(dto.getUsername());
row.add(dto.getTaxAgent());
row.add(dto.getDepartment());
row.add(dto.getMobile());
row.add(dto.getJobNum());
row.add(dto.getSendStatus());
rows.add(row);
}
return ExcelUtil.genWorkbookV2(rows, sheetName);
}
// @BatchExportHandler("exportSalarySendInfo")
// public void salarySendInfoExportHandler() {
// BatchCallbackMessage message = BatchExportContext.getBatchCallbackMessage();
// System.out.println("接受到导出的结果" + JSONObject.toJSONString(message));
// }
@Override
public XSSFWorkbook exportDetailList(SalarySendPO salarySend, SalarySendDetailQueryParam queryParam) {
// 1.根据模板获取薪资项目设置
SalaryAcctRecordPO salaryAcctRecord = getSalaryAcctRecordService(user).getById(salarySend.getSalaryAccountingId());
boolean isReplenish = salaryAcctRecord != null && Objects.equals(salaryAcctRecord.getBackCalcStatus(), (NumberUtils.INTEGER_ONE));
List<SalaryTemplatePO> salaryTemplates = getSalaryTemplateService(user).getDefaultTemplates(Collections.singletonList(salarySend.getSalarySobId()));
List<SalaryTemplateSalaryItemListDTO> salaryItems = getSalaryItemsSetting(CollectionUtils.isNotEmpty(salaryTemplates) ? salaryTemplates.get(0) : null, isReplenish);
// 2.获取基本数据
//排序配置
OrderRuleVO orderRule = getSalarySysConfService(user).orderRule();
queryParam.setOrderRule(orderRule);
List<SalarySendDetailListDTO> list = salarySendInfoMapper.detailList(queryParam, null);
// 3.组装详情数据
List<Map<String, Object>> listMaps = buildDetailList(salaryItems, list, salarySend.getSalaryAccountingId());
// 1.工作簿名称
String sheetName = SalaryI18nUtil.getI18nLabel(97036, "工资单发放详情");
List<Object> header = new ArrayList<>();
header.add(SalaryI18nUtil.getI18nLabel(85429, "姓名"));
header.add(SalaryI18nUtil.getI18nLabel(86185, "部门"));
header.add(SalaryI18nUtil.getI18nLabel(86186, "手机号"));
header.add(SalaryI18nUtil.getI18nLabel(86317, "工号"));
// 动态列
if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(salaryItems)) {
for (SalaryTemplateSalaryItemListDTO salaryItem : salaryItems) {
header.add(salaryItem.getName());
}
}
List<List<Object>> rows = new ArrayList<>();
// 2.表头
rows.add(header);
// 3.表数据
for (Map<String, Object> dto : listMaps) {
List<Object> row = new ArrayList<>();
row.add(dto.get("username"));
row.add(dto.get("department"));
row.add(dto.get("mobile"));
row.add(dto.get("jobNum"));
// 动态列
Map<String, Object> mapColumn = listMaps.get(0);
for (SalaryTemplateSalaryItemListDTO salaryItem : salaryItems) {
if (mapColumn.containsKey(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX)) {
row.add(dto.get(salaryItem.getId() + SalaryItemConstant.DYNAMIC_SUFFIX));
}
}
rows.add(row);
}
return ExcelUtil.genWorkbookV2(rows, sheetName);
}
@Override
public List<SalarySendCheckDTO> getSalarySendCheckResult(Set<Long> salaryAcctRecordIds) {
if (CollectionUtils.isEmpty(salaryAcctRecordIds)) {
return Collections.emptyList();
}
Map<String, Object> condition = new HashMap<>();
condition.put("salaryAccountingIds", salaryAcctRecordIds);
List<SalarySendPO> salarySendPOS = getSalarySendMapper().listSomeWithCondition(condition);
Map<Long, SalarySendPO> map = SalaryEntityUtil.convert2Map(salarySendPOS, SalarySendPO::getSalaryAccountingId);
return salaryAcctRecordIds.stream().map(m -> {
SalarySendPO salarySend = map.get(m);
SalarySendCheckDTO salarySendCheck = new SalarySendCheckDTO();
salarySendCheck.setSalaryAcctId(m);
// 是否存在已经发送
salarySendCheck.setAlreadySend(salarySend != null && salarySend.getSendNum() > 0);
// 是否已经发送完成
salarySendCheck.setSendFinished(salarySend != null && Objects.equals(salarySend.getSendNum(), salarySend.getSendTotal()));
return salarySendCheck;
}).collect(Collectors.toList());
}
@Override
public void handleHistory() {
mapper.batchHandleSendStatusHistory();
mapper.batchHandleSalaryAcctTypeHistory();
}
//
// @BatchExportHandler("exportSalarySendDetail")
// public void salarySendDetailExportHandler() {
// BatchCallbackMessage message = BatchExportContext.getBatchCallbackMessage();
// System.out.println("接受到导出的结果" + JSONObject.toJSONString(message));
// }
@Override
public Map<String, Object> sumRow(SalarySendInfoQueryParam param) {
Long salarySendId = param.getSalarySendId();
// 获取薪资核算ID
SalarySendPO salarySendPO = getById(salarySendId);
if (Objects.isNull(salarySendPO)) {
throw new SalaryRunTimeException("工资发放记录不存在或已被删除");
}
SalaryAcctResultQueryParam queryParam = SalaryAcctResultQueryParam.builder().salaryAcctRecordId(salarySendPO.getSalaryAccountingId()).build();
// 查询薪资核算人员
List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = getSalaryAcctEmployeeService(user)
.listByResultQueryParam(queryParam);
if (org.apache.commons.collections4.CollectionUtils.isEmpty(salaryAcctEmployeePOS)) {
return Collections.emptyMap();
}
// 查询薪资核算记录
SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(queryParam.getSalaryAcctRecordId());
if (Objects.isNull(salaryAcctRecordPO)) {
throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98747, "薪资核算记录不存在或已被删除"));
}
// 查询薪资核算所用薪资账套的薪资项目
List<SalarySobItemPO> salarySobItemPOS = getSalarySobItemService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
Set<Long> salaryItemIds = SalaryEntityUtil.properties(salarySobItemPOS, SalarySobItemPO::getSalaryItemId);
if (Objects.equals(salaryAcctRecordPO.getBackCalcStatus(), NumberUtils.INTEGER_ONE)) {
// 是回算,获取回算项
List<SalarySobBackItemPO> salarySobBackItemPOS = getSalarySobBackItemService(user).listBySalarySobId(salaryAcctRecordPO.getSalarySobId());
salaryItemIds.addAll(salarySobBackItemPOS.stream().map(SalarySobBackItemPO::getSalaryItemId).collect(Collectors.toList()));
}
List<SalaryItemPO> salaryItemPOS = getSalaryItemService(user).listByIds(salaryItemIds);
// 查询薪资核算结果
List<Long> salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctEmployeePOS, SalaryAcctEmployeePO::getId, Collectors.toList());
List<SalaryAcctResultPO> salaryAcctResultPOS = getSalaryAcctResultService(user).listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds);
// 是否是补发工资单
List<SalarySendInfoPO> salarySendInfoPOS = getSalarySendInfoMapper().listSome(SalarySendInfoPO.builder().salarySendId(salarySendId).build());
List<Long> sendEmployeeIds = salarySendInfoPOS.stream().map(SalarySendInfoPO::getEmployeeId).collect(Collectors.toList());
salaryAcctResultPOS = salaryAcctResultPOS.stream().filter(po -> sendEmployeeIds.contains(po.getEmployeeId())).collect(Collectors.toList());
Map<String, Object> map = new HashMap<>();
Map<Long, List<SalaryAcctResultPO>> acctResultMap = SalaryEntityUtil.group2Map(salaryAcctResultPOS, SalaryAcctResultPO::getSalaryItemId);
salaryItemPOS.stream().filter(item -> SalaryDataTypeEnum.NUMBER.getValue().equals(item.getDataType())).forEach(item -> {
BigDecimal sum = Optional.ofNullable(acctResultMap.get(item.getId()))
.orElse(new ArrayList<>())
.stream()
.map(SalaryAcctResultPO::getResultValue)
.filter(NumberUtils::isCreatable)
.map(BigDecimal::new)
.reduce(BigDecimal.ZERO, BigDecimal::add);
map.put(item.getId().toString(), SalaryAcctFormulaBO.roundResultValue(sum.toString(), item, Collections.emptyList(), Collections.emptyMap()));
});
return map;
}
@Override
public void deleteBySalaryAcctRecordIds(Collection<Long> ids) {
if (CollectionUtils.isNotEmpty(ids)) {
getSalarySendMapper().deleteBySalaryAcctRecordIds(ids);
getSalarySendInfoMapper().deleteBySalaryAcctRecordIds(ids);
}
}
@Override
public void sendMobileCode(SMSCodeSendParam param) {
Long id = param.getId();
SalarySendInfoPO po = getSalarySendInfoMapper().getById(id);
if (po == null) {
throw new SalaryRunTimeException("未获取工资单发放信息");
}
Long employeeId = po.getEmployeeId();
DataCollectionEmployee employee = getSalaryEmployeeService(user).getEmployeeById(employeeId);
if (employee == null) {
throw new SalaryRunTimeException("未获取人员信息");
}
String mobile = employee.getMobile();
if (Validator.isMobile(mobile)) {
throw new SalaryRunTimeException("手机号信息有误");
}
boolean checkSendSMS = MessageUtil.checkSendSMS();
if (!checkSendSMS) {
throw new SalaryRunTimeException("短信服务异常");
}
//1、生成6位验证码
String mobileCode = (int) ((Math.random() * 9 + 1) * 100000) + "";
//失效时间
long expirationTime = LocalDateTime.now().plusMinutes(10L).toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
String cacheValue = mobileCode + "_" + expirationTime;
//2、验证码缓存10分钟失效
getSalaryCacheService(user).set(SALARY_CACHE_SMS_CODE + "_" + id, cacheValue);
//3、发送短信
MessageUtil.sendSMS(mobile, "验证码:" + mobileCode + "有效时间10分钟用于查看工资单请不要告诉他人。");
}
@Override
public Boolean checkMobileCode(SMSCodeCheckParam param) {
Long id = param.getId();
String mobileCode = param.getMobileCode();
//取出验证码
String cacheValue = getSalaryCacheService(user).get(SALARY_CACHE_SMS_CODE + "_" + id);
String[] cache = cacheValue.split("_");
String code = cache[0];
//失效时间
long expirationTime = Long.parseLong(cache[1]);
long nowTime = LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli();
if (nowTime > expirationTime) {
throw new SalaryRunTimeException("验证码已失效,请重新发送");
}
if (!StringUtils.equals(code, mobileCode)) {
throw new SalaryRunTimeException("验证码错误");
}
return true;
}
@Override
public List<SalarySendInfoPO> getNeedSendInfoList(List<Long> salarySendIds) {
if(CollectionUtils.isEmpty(salarySendIds)){
return Collections.emptyList();
}
return getSalarySendInfoMapper().getNeedSendInfoList(salarySendIds);
}
@Override
public List<SalarySendPO> getNeedSendListBySalarySobIds(List<Long> salarySobIds) {
if(CollectionUtils.isEmpty(salarySobIds)){
return Collections.emptyList();
}
return getSalarySendMapper().getNeedSendListBySalarySobIds(salarySobIds);
}
@Override
public List<SalarySendInfoPO> listAllUnConfirmedSendInfo() {
return getSalarySendInfoMapper().listSome(SalarySendInfoPO.builder().billConfirmStatus(BillConfimStatusEnum.UNCONFIRMED.getValue()).build());
}
@Override
public void autoConfirmSalaryBill(List<Long> needAutoSendIds) {
if(CollectionUtils.isEmpty(needAutoSendIds)){
return;
}
getSalarySendInfoMapper().autoConfirmSalaryBill(needAutoSendIds);
}
}