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

565 lines
27 KiB
Java

package com.engine.salary.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.push.dto.PushRecordDTO;
import com.engine.salary.entity.push.dto.PushRecordDetailDTO;
import com.engine.salary.entity.push.dto.PushSettingDTO;
import com.engine.salary.entity.push.dto.PushSettingItemDTO;
import com.engine.salary.entity.push.param.*;
import com.engine.salary.entity.push.po.PushRecordDetailPO;
import com.engine.salary.entity.push.po.PushRecordPO;
import com.engine.salary.entity.push.po.PushSettingItemPO;
import com.engine.salary.entity.push.po.PushSettingPO;
import com.engine.salary.entity.salaryacct.bo.CalculateFormulaVarBO;
import com.engine.salary.entity.salaryacct.bo.SalaryAcctCalculateBO;
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.salaryitem.po.SalaryItemPO;
import com.engine.salary.entity.salarysob.dto.SalarySobCycleDTO;
import com.engine.salary.entity.salarysob.po.SalarySobPO;
import com.engine.salary.enums.push.PushItemFieldEnum;
import com.engine.salary.enums.push.PushRecordDetailStatusEnum;
import com.engine.salary.enums.push.PushRecordStatusEnum;
import com.engine.salary.enums.push.PushRecordTypeEnum;
import com.engine.salary.enums.salaryformula.SalarySQLReferenceEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.push.PushRecordDetailMapper;
import com.engine.salary.mapper.push.PushRecordMapper;
import com.engine.salary.mapper.push.PushSettingItemMapper;
import com.engine.salary.mapper.push.PushSettingMapper;
import com.engine.salary.service.*;
import com.engine.salary.sys.enums.TaxDeclarationFunctionEnum;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.engine.salary.util.valid.ValidUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import weaver.conn.RecordSet;
import weaver.formmode.setup.ModeRightInfo;
import weaver.general.TimeUtil;
import weaver.hrm.User;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
/**
* 推送服务
* <p>Copyright: Copyright (c) 2024</p>
* <p>Company: 泛微软件</p>
*
* @author qiantao
* @version 1.0
**/
@Slf4j
public class PushServiceImpl extends Service implements PushService {
private PushSettingMapper getPushSettingMapper() {
return MapperProxyFactory.getProxy(PushSettingMapper.class);
}
private PushSettingItemMapper getPushSettingItemMapper() {
return MapperProxyFactory.getProxy(PushSettingItemMapper.class);
}
private PushRecordMapper getPushRecordMapper() {
return MapperProxyFactory.getProxy(PushRecordMapper.class);
}
private PushRecordDetailMapper getPushRecordDetailMapper() {
return MapperProxyFactory.getProxy(PushRecordDetailMapper.class);
}
private SalaryEmployeeService getSalaryEmployeeService(User user) {
return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
}
private SalaryItemService getSalaryItemService(User user) {
return ServiceUtil.getService(SalaryItemServiceImpl.class, user);
}
private SalaryAcctRecordService getSalaryAcctRecordService(User user) {
return ServiceUtil.getService(SalaryAcctRecordServiceImpl.class, user);
}
private SalarySobService getSalarySobService(User user) {
return ServiceUtil.getService(SalarySobServiceImpl.class, user);
}
private SalaryAcctEmployeeService getSalaryAcctEmployeeService(User user) {
return ServiceUtil.getService(SalaryAcctEmployeeServiceImpl.class, user);
}
private SalaryAcctResultService getSalaryAcctResultService(User user) {
return ServiceUtil.getService(SalaryAcctResultServiceImpl.class, user);
}
@Override
public PageInfo<PushSettingDTO> settingList(PushSettingQueryParam param) {
List<PushSettingPO> pushSettingPOS = getPushSettingMapper().listAll();
List<SalarySobPO> salarySobPOS = getSalarySobService(user).listAll();
Map<Long, SalarySobPO> sobPOMap = SalaryEntityUtil.convert2Map(salarySobPOS, SalarySobPO::getId);
List<PushSettingDTO> list = pushSettingPOS.stream()
.filter(po -> StrUtil.isBlank(param.getName()) || po.getName().contains(param.getName()))
.map(po -> PushSettingDTO.builder()
.id(po.getId())
.name(po.getName())
.tableName(po.getTableName())
.modeName(po.getModeName())
.modeId(po.getModeId())
.able(po.getAble())
.salarySobs(po.getSalarySobIds().stream().map(sobPOMap::get).collect(Collectors.toList()))
.build()).collect(Collectors.toList());
return SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), list, PushSettingDTO.class);
}
@Override
public PushSettingPO save(PushSettingSaveParam param) {
ValidUtil.doValidator(param);
Date now = new Date();
Long id = param.getId();
PushSettingPO po;
if (id == null) {
po = PushSettingPO.builder()
.id(IdGenerator.generate())
.able(param.getAble())
.name(param.getName())
.salarySobIds(param.getSalarySobIds())
.modeId(param.getModeId())
.modeName(param.getModeName())
.tableName(param.getTableName())
.creator((long) user.getUID())
.createTime(now)
.updateTime(now)
.deleteType(0)
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.build();
getPushSettingMapper().insertIgnoreNull(po);
} else {
po = getPushSettingMapper().getById(id);
if (po == null) {
throw new SalaryRunTimeException("推送配置不存在!");
}
po.setAble(param.getAble());
po.setAble(param.getAble());
po.setName(param.getName());
po.setSalarySobIds(param.getSalarySobIds());
po.setModeId(param.getModeId());
po.setModeName(param.getModeName());
po.setTableName(param.getTableName());
po.setUpdateTime(now);
getPushSettingMapper().update(po);
}
return po;
}
@Override
public void delete(Long id) {
getPushSettingMapper().delete(PushSettingPO.builder().id(id).build());
getPushSettingItemMapper().delete(PushSettingItemPO.builder().settingId(id).build());
}
@Override
public PageInfo<PushSettingItemDTO> itemList(PushSettingItemQueryParam param) {
List<PushSettingItemPO> pushSettingItemPOS = getPushSettingItemMapper().listSome(PushSettingItemPO.builder().settingId(param.getSettingId()).build());
List<PushSettingItemDTO> list = pushSettingItemPOS.stream().map(po -> PushSettingItemDTO.builder()
.id(po.getId())
.settingId(po.getSettingId())
.item(po.getItem())
.itemName(po.getItemName())
.source(po.getSource())
.sourceName(SalarySQLReferenceEnum.parseByValue(po.getSource()).getDefaultLabel())
.fieldName(po.getFieldName())
.fieldType(PushItemFieldEnum.parseByValue(po.getFieldType()))
.fieldTypeName(PushItemFieldEnum.parseByValue(po.getFieldType()).getDefaultLabel())
.sortedIndex(po.getSortedIndex())
.build()
).collect(Collectors.toList());
return new PageInfo<>(list, PushSettingItemDTO.class);
}
@Override
public PushSettingItemPO saveItem(PushSettingItemSaveParam param) {
ValidUtil.doValidator(param);
Date now = new Date();
Long id = param.getId();
PushSettingItemPO po;
if (id == null) {
po = PushSettingItemPO.builder()
.id(IdGenerator.generate())
.settingId(param.getSettingId())
.item(param.getItem())
.itemName(param.getItemName())
.source(param.getSource())
.fieldName(param.getFieldName())
.fieldType(param.getFieldType().getValue())
.sortedIndex(param.getSortedIndex())
.creator((long) user.getUID())
.createTime(now)
.updateTime(now)
.deleteType(0)
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.build();
getPushSettingItemMapper().insertIgnoreNull(po);
} else {
po = getPushSettingItemMapper().getById(id);
if (po == null) {
throw new SalaryRunTimeException("推送配置明细不存在!");
}
po.setSettingId(param.getSettingId());
po.setItem(param.getItem());
po.setItemName(param.getItemName());
po.setSource(param.getSource());
po.setFieldName(param.getFieldName());
po.setFieldType(param.getFieldType().getValue());
po.setSortedIndex(param.getSortedIndex());
po.setUpdateTime(now);
getPushSettingItemMapper().update(po);
}
return po;
}
@Override
public void deleteItem(Long id) {
getPushSettingItemMapper().delete(PushSettingItemPO.builder().id(id).build());
}
@Override
public void createPushRecord(Long salaryAcctRecordId) {
Date now = new Date();
SalaryAcctRecordPO salaryAcctRecordPO = getSalaryAcctRecordService(user).getById(salaryAcctRecordId);
if (salaryAcctRecordPO == null) {
throw new SalaryRunTimeException("核算记录不存在!");
}
//查询推送配置
List<PushSettingPO> pushSettingPOS = getPushSettingMapper().listSome(PushSettingPO.builder().able(1).build());
if (CollUtil.isEmpty(pushSettingPOS)) {
return;
}
//查询核算人员
List<SalaryAcctEmployeePO> salaryAcctEmployeePOS = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordId(salaryAcctRecordPO.getId());
//薪资项目
List<SalaryItemPO> salaryItemPOS = getSalaryItemService(user).listAll();
//查询薪资核算记录的薪资周期、考勤周期等
SalarySobCycleDTO salarySobCycleDTO = getSalaryAcctRecordService(user).getSalarySobCycleById(salaryAcctRecordPO.getId());
SalaryAcctCalculateBO salaryAcctCalculateBO = new SalaryAcctCalculateBO()
.setSalaryAcctRecordPO(salaryAcctRecordPO)
.setSalarySobPO(new SalarySobPO())
.setSalarySobCycleDTO(salarySobCycleDTO)
.setOtherSalaryAcctRecordPOS(new ArrayList<>())
.setSalarySobItemPOS(new ArrayList<>())
.setSalaryItemIdWithPriorityList(new ArrayList<>())
.setExpressFormulas(new ArrayList<>())
.setSalaryItemPOS(salaryItemPOS)
.setSalarySobAdjustRulePOS(new ArrayList<>())
.setWelfareColumns(new HashMap<>())
.setAttendQuoteFieldListDTOS(new ArrayList<>())
.setSalaryAcctEmployeePOS(salaryAcctEmployeePOS)
.setIssuedFieldIds(new HashSet<>())
.setChildMonitor(null)
.setResults(null)
.setCalculateKey(null)
.setVariableItems(new ArrayList<>())
.setTaxDeclarationFunction(TaxDeclarationFunctionEnum.OPEN);
List<Long> employeeIds = SalaryEntityUtil.properties(salaryAcctCalculateBO.getSalaryAcctEmployeePOS(), SalaryAcctEmployeePO::getEmployeeId, Collectors.toList());
List<DataCollectionEmployee> simpleEmployees = getSalaryEmployeeService(user).getEmployeeByIdsAll(employeeIds);
List<Long> salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctCalculateBO.getSalaryAcctEmployeePOS(), SalaryAcctEmployeePO::getId, Collectors.toList());
List<SalaryAcctResultPO> salaryAcctResultPOS = getSalaryAcctResultService(user).listBySalaryAcctEmployeeIds(salaryAcctEmployeeIds);
CalculateFormulaVarBO calculateFormulaVarBO = new CalculateFormulaVarBO(simpleEmployees, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), salaryAcctResultPOS, new ArrayList<>(), new ArrayList<>());
Map<String, List<CalculateFormulaVarBO.FormulaVarValue>> formulaVarMap = calculateFormulaVarBO.convert2FormulaVar(salaryAcctCalculateBO);
//推送记录id
List<Long> recordIds = new ArrayList<>();
try {
pushSettingPOS.stream()
.filter(setting -> setting.getSalarySobIds().contains(salaryAcctRecordPO.getSalarySobId()))
.forEach(setting -> {
long recordId = IdGenerator.generate();
recordIds.add(recordId);
PushRecordPO record = PushRecordPO.builder()
.id(recordId)
.name(setting.getName())
.settingId(setting.getId())
.modeId(setting.getModeId())
.tableName(setting.getTableName())
.acctRecordId(salaryAcctRecordId)
.type(PushRecordTypeEnum.PUSH.getValue())
.status(PushRecordStatusEnum.DATA_PREPARE.getValue())
.createTime(now)
.updateTime(now)
.creator((long) user.getUID())
.deleteType(NumberUtils.INTEGER_ZERO)
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.build();
getPushRecordMapper().insertIgnoreNull(record);
Long id = setting.getId();
List<PushSettingItemPO> pushSettingItemPOS = getPushSettingItemMapper().listSome(PushSettingItemPO.builder().settingId(id).build());
//构建数据,每个人员生成一天明细
salaryAcctEmployeePOS.forEach(emp -> {
//1 获取当前薪资核算人员的公式中的变量的值
List<CalculateFormulaVarBO.FormulaVarValue> formulaVarValues = formulaVarMap.get(emp.getEmployeeId() + "_" + emp.getTaxAgentId());
//2 人员信息
List<CalculateFormulaVarBO.FormulaVarValue> empInfo = formulaVarMap.get(emp.getEmployeeId() + "");
formulaVarValues.addAll(empInfo);
Map<String, String> formulaVarValueMap = SalaryEntityUtil.convert2Map(formulaVarValues, CalculateFormulaVarBO.FormulaVarValue::getFieldId, CalculateFormulaVarBO.FormulaVarValue::getFieldValue);
Integer modeId = setting.getModeId();
List<String> fields = new ArrayList<String>() {{
add("formmodeid");
add("modedatacreater");
add("modedatacreatertype");
add("modedatacreatedate");
add("modedatacreatetime");
}};
String currDate = TimeUtil.getCurrentDateString();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currTime = sdf.format(new Date());
List<Object> values = new ArrayList<Object>() {{
add(modeId);
add(1);
add(0);
add(String.format("'%s'", currDate));
add(String.format("'%s'", currTime));
}};
for (PushSettingItemPO item : pushSettingItemPOS) {
//数据库字段
String fieldName = item.getFieldName();
fields.add(fieldName);
// 公式变量的值
String field = item.getItem();
String value = formulaVarValueMap.getOrDefault(field, StringUtils.EMPTY);
PushItemFieldEnum pushItemFieldEnum = PushItemFieldEnum.parseByValue(item.getFieldType());
values.add(pushItemFieldEnum.convertValue(value));
}
String tableName = setting.getTableName();
String sql = String.format("insert into %s (%s) values (%s)", tableName, String.join(",", fields), values.stream().map(Object::toString).collect(Collectors.joining(",")));
PushRecordDetailPO pushRecordDetailPO = PushRecordDetailPO.builder()
.id(IdGenerator.generate())
.acctEmpId(emp.getId())
.recordId(record.getId())
.status(PushRecordDetailStatusEnum.PREPARE.getValue())
.formula(sql)
.createTime(now)
.updateTime(now)
.creator((long) user.getUID())
.deleteType(NumberUtils.INTEGER_ZERO)
.tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY)
.build();
getPushRecordDetailMapper().insertIgnoreNull(pushRecordDetailPO);
});
//数据构建完毕
record.setUpdateTime(new Date());
record.setStatus(PushRecordStatusEnum.DATA_FINISH.getValue());
getPushRecordMapper().updateIgnoreNull(record);
}
);
} catch (Exception e) {
log.error("创建推送记录失败", e);
removeRecords(recordIds);
throw new SalaryRunTimeException("创建推送记录失败");
}
//开始
recordIds.forEach(this::push);
}
@Override
public void withdrawPushRecord(Long salaryAcctRecordId) {
List<PushRecordPO> pushRecordPOS = getPushRecordMapper().listSome(PushRecordPO.builder().acctRecordId(salaryAcctRecordId).status(PushRecordStatusEnum.RUN_SUCCESS.getValue()).build());
if (CollUtil.isEmpty(pushRecordPOS)) {
return;
}
pushRecordPOS.stream().map(PushRecordPO::getId).forEach(this::withdraw);
}
@Override
public void push(Long id) {
//待推送
PushRecordPO pushRecordPO = getPushRecordMapper().getById(id);
try {
pushRecordPO.setStartTime(new Date());
pushRecordPO.setStatus(PushRecordStatusEnum.RUN_PROGRESS.getValue());
getPushRecordMapper().updateIgnoreNull(pushRecordPO);
List<PushRecordDetailPO> pushRecordDetailPOS = getPushRecordDetailMapper().listSome(PushRecordDetailPO.builder().recordId(pushRecordPO.getId()).build());
pushRecordDetailPOS.forEach(pushRecordDetailPO -> {
try {
String formula = pushRecordDetailPO.getFormula();
RecordSet rs = new RecordSet();
boolean success = rs.execute(formula);
if (success) {
//建模需要权限重构
Integer modeId = pushRecordPO.getModeId();
if (modeId != null) {
String tableName = pushRecordPO.getTableName();
rs.executeQuery("select max(id) from " + tableName);
int mainId = 0;
if (rs.next()) {
mainId = rs.getInt(1);
}
ModeRightInfo ModeRightInfo = new ModeRightInfo();
ModeRightInfo.setNewRight(true);
ModeRightInfo.editModeDataShare(1, modeId, mainId);
//记录数据id
pushRecordDetailPO.setDataId((long) mainId);
}
pushRecordDetailPO.setStatus(PushRecordDetailStatusEnum.SUCCESS.getValue());
} else {
pushRecordDetailPO.setFailReason("sql执行失败");
pushRecordDetailPO.setStatus(PushRecordDetailStatusEnum.FAIL.getValue());
}
} catch (Exception e) {
pushRecordDetailPO.setFailReason(e.getMessage());
pushRecordDetailPO.setStatus(PushRecordDetailStatusEnum.FAIL.getValue());
}
getPushRecordDetailMapper().updateIgnoreNull(pushRecordDetailPO);
});
pushRecordPO.setEndTime(new Date());
pushRecordPO.setStatus(PushRecordStatusEnum.RUN_SUCCESS.getValue());
} catch (Exception e) {
pushRecordPO.setFailReason(e.getMessage());
pushRecordPO.setStatus(PushRecordStatusEnum.RUN_FAIL.getValue());
}
getPushRecordMapper().updateIgnoreNull(pushRecordPO);
}
@Override
public void withdraw(Long id) {
//待撤回
PushRecordPO pushRecordPO = getPushRecordMapper().getById(id);
try {
pushRecordPO.setStartTime(new Date());
pushRecordPO.setStatus(PushRecordStatusEnum.WITHDRAW.getValue());
getPushRecordMapper().updateIgnoreNull(pushRecordPO);
PushSettingPO pushSettingPO = getPushSettingMapper().getById(pushRecordPO.getSettingId());
String tableName = pushSettingPO.getTableName();
List<PushRecordDetailPO> pushRecordDetailPOS = getPushRecordDetailMapper().listSome(PushRecordDetailPO.builder().recordId(pushRecordPO.getId()).build());
pushRecordDetailPOS.forEach(pushRecordDetailPO -> {
try {
RecordSet rs = new RecordSet();
String sql = String.format("delete from %s where id = %s", tableName, pushRecordDetailPO.getDataId());
boolean execute = rs.execute(sql);
if (execute) {
pushRecordDetailPO.setStatus(PushRecordDetailStatusEnum.WITHDRAW_SUCCESS.getValue());
} else {
pushRecordDetailPO.setFailReason("sql执行失败");
pushRecordDetailPO.setStatus(PushRecordDetailStatusEnum.WITHDRAW_FAIL.getValue());
}
} catch (Exception e) {
pushRecordDetailPO.setFailReason(e.getMessage());
pushRecordDetailPO.setStatus(PushRecordDetailStatusEnum.WITHDRAW_FAIL.getValue());
}
getPushRecordDetailMapper().updateIgnoreNull(pushRecordDetailPO);
});
pushRecordPO.setEndTime(new Date());
pushRecordPO.setStatus(PushRecordStatusEnum.WITHDRAW_SUCCESS.getValue());
} catch (Exception e) {
pushRecordPO.setFailReason(e.getMessage());
pushRecordPO.setStatus(PushRecordStatusEnum.WITHDRAW_FAIL.getValue());
}
getPushRecordMapper().updateIgnoreNull(pushRecordPO);
}
@Override
public void removeRecords(List<Long> recordIds) {
recordIds.forEach(recordId -> {
PushRecordPO recordPO = getPushRecordMapper().getById(recordId);
if (recordPO != null) {
getPushRecordDetailMapper().deleteByRecordId(recordId);
getPushRecordMapper().delete(recordPO);
}
});
}
@Override
public PageInfo<PushRecordDTO> recordList(RecordListQueryParam param) {
List<PushRecordPO> pushRecordPOS = getPushRecordMapper().listAll();
List<PushRecordDTO> listDTOS = pushRecordPOS
.stream()
.filter(po -> StrUtil.isBlank(param.getName()) || po.getName().contains(param.getName()))
.map(po -> PushRecordDTO.builder()
.id(po.getId())
.name(po.getName())
.settingId(po.getId())
.modeId(po.getModeId())
.tableName(po.getTableName())
.acctRecordId(po.getAcctRecordId())
.type(po.getType())
.status(po.getStatus())
.statusName(PushRecordStatusEnum.parseByValue(po.getStatus()).getDefaultLabel())
.startTime(po.getStartTime())
.endTime(po.getEndTime())
.build())
.collect(Collectors.toList());
PageInfo<PushRecordDTO> pageInfo = SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), listDTOS, PushRecordDTO.class);
return pageInfo;
}
@Override
public PageInfo<PushRecordDetailDTO> recordDetailList(RecordDetailListQueryParam param) {
ValidUtil.doValidator(param);
List<PushRecordDetailDTO> list = getPushRecordDetailMapper().listDTO(PushRecordDetailDTO.builder().recordId(param.getRecordId()).build());
List<PushRecordDetailDTO> listDTOS = SalaryPageUtil.subList(param.getCurrent(), param.getPageSize(), list);
listDTOS.forEach(dto -> dto.setStatusName(PushRecordDetailStatusEnum.parseByValue(dto.getStatus()).getDefaultLabel()));
PageInfo<PushRecordDetailDTO> pageInfo = SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), PushRecordDetailDTO.class);
pageInfo.setList(listDTOS);
pageInfo.setTotal(list.size());
return pageInfo;
}
}