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; /** * 推送服务 *

Copyright: Copyright (c) 2024

*

Company: 泛微软件

* * @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 settingList(PushSettingQueryParam param) { List pushSettingPOS = getPushSettingMapper().listAll(); List salarySobPOS = getSalarySobService(user).listAll(); Map sobPOMap = SalaryEntityUtil.convert2Map(salarySobPOS, SalarySobPO::getId); List 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 itemList(PushSettingItemQueryParam param) { List pushSettingItemPOS = getPushSettingItemMapper().listSome(PushSettingItemPO.builder().settingId(param.getSettingId()).build()); List 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 pushSettingPOS = getPushSettingMapper().listSome(PushSettingPO.builder().able(1).build()); if (CollUtil.isEmpty(pushSettingPOS)) { return; } //查询核算人员 List salaryAcctEmployeePOS = getSalaryAcctEmployeeService(user).listBySalaryAcctRecordId(salaryAcctRecordPO.getId()); //薪资项目 List 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 employeeIds = SalaryEntityUtil.properties(salaryAcctCalculateBO.getSalaryAcctEmployeePOS(), SalaryAcctEmployeePO::getEmployeeId, Collectors.toList()); List simpleEmployees = getSalaryEmployeeService(user).getEmployeeByIdsAll(employeeIds); List salaryAcctEmployeeIds = SalaryEntityUtil.properties(salaryAcctCalculateBO.getSalaryAcctEmployeePOS(), SalaryAcctEmployeePO::getId, Collectors.toList()); List 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> formulaVarMap = calculateFormulaVarBO.convert2FormulaVar(salaryAcctCalculateBO); //推送记录id List 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 pushSettingItemPOS = getPushSettingItemMapper().listSome(PushSettingItemPO.builder().settingId(id).build()); //构建数据,每个人员生成一天明细 salaryAcctEmployeePOS.forEach(emp -> { //1 获取当前薪资核算人员的公式中的变量的值 List formulaVarValues = formulaVarMap.get(emp.getEmployeeId() + "_" + emp.getTaxAgentId()); //2 人员信息 List empInfo = formulaVarMap.get(emp.getEmployeeId() + ""); formulaVarValues.addAll(empInfo); Map formulaVarValueMap = SalaryEntityUtil.convert2Map(formulaVarValues, CalculateFormulaVarBO.FormulaVarValue::getFieldId, CalculateFormulaVarBO.FormulaVarValue::getFieldValue); Integer modeId = setting.getModeId(); List fields = new ArrayList() {{ 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 values = new ArrayList() {{ 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 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 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 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 recordIds) { recordIds.forEach(recordId -> { PushRecordPO recordPO = getPushRecordMapper().getById(recordId); if (recordPO != null) { getPushRecordDetailMapper().deleteByRecordId(recordId); getPushRecordMapper().delete(recordPO); } }); } @Override public PageInfo recordList(RecordListQueryParam param) { List pushRecordPOS = getPushRecordMapper().listAll(); List 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 pageInfo = SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), listDTOS, PushRecordDTO.class); return pageInfo; } @Override public PageInfo recordDetailList(RecordDetailListQueryParam param) { ValidUtil.doValidator(param); List list = getPushRecordDetailMapper().listDTO(PushRecordDetailDTO.builder().recordId(param.getRecordId()).build()); List listDTOS = SalaryPageUtil.subList(param.getCurrent(), param.getPageSize(), list); listDTOS.forEach(dto -> dto.setStatusName(PushRecordDetailStatusEnum.parseByValue(dto.getStatus()).getDefaultLabel())); PageInfo pageInfo = SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), PushRecordDetailDTO.class); pageInfo.setList(listDTOS); pageInfo.setTotal(list.size()); return pageInfo; } }