package cn.fw.morax.server.task; import cn.fw.common.cache.locker.DistributedLocker; import cn.fw.morax.common.constant.Constant; import cn.fw.morax.common.constant.TimeTaskConstant; import cn.fw.morax.common.utils.DateUtil; import cn.fw.morax.common.utils.PublicUtil; import cn.fw.morax.domain.bo.salary.SalaryGroupProjectBO; import cn.fw.morax.domain.db.kpi.*; import cn.fw.morax.domain.db.salary.*; import cn.fw.morax.domain.enums.*; import cn.fw.morax.domain.vo.salary.SalaryGroupProjectParamVO; import cn.fw.morax.rpc.ehr.EhrRpcService; import cn.fw.morax.rpc.ehr.dto.ManagerDTO; import cn.fw.morax.rpc.ehr.dto.ManagerStaffRoleDTO; import cn.fw.morax.rpc.ehr.dto.ManagerStaffShopDTO; import cn.fw.morax.rpc.ehr.dto.StaffBaseInfoDTO; import cn.fw.morax.rpc.oop.OopRpcService; import cn.fw.morax.service.biz.CommonService; import cn.fw.morax.service.biz.kpi.KpiPoolCommonService; import cn.fw.morax.service.biz.salary.SalarySettingCommonService; import cn.fw.morax.service.data.kpi.IndicatorUserValueService; import cn.fw.morax.service.data.kpi.KpiPoolService; import cn.fw.morax.service.data.salary.*; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.google.common.collect.Maps; import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.map.MultiKeyMap; import org.redisson.api.RLock; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.time.LocalDate; import java.time.YearMonth; import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.function.Function; import java.util.stream.Collectors; /** * @author : jiangchao * @className : SalaryReportRatioTask * @description : 薪酬报表定时器 * @date : 2022-04-07 15:29 */ @Component @Slf4j @RequiredArgsConstructor @ConditionalOnProperty(prefix = "task", name = "switch", havingValue = "on") public class SalaryReportTask { private final DistributedLocker distributedLocker; private final SalaryGroupService salaryGroupService; private final SalaryPoolService salaryPoolService; private final KpiPoolService kpiPoolService; private final KpiPoolCommonService kpiPoolCommonService; private final ReportSalaryService reportSalaryService; private final TransactionDefinition transactionDefinition; private final ReportSalaryDimService reportSalaryDimService; private final ReportSalaryCodeService reportSalaryCodeService; private final IndicatorUserValueService indicatorUserValueService; private final SalaryGroupProjectService salaryGroupProjectService; private final PlatformTransactionManager platformTransactionManager; private final ReportSalaryDimExtraService reportSalaryDimExtraService; private final ReportSalaryDimValueService reportSalaryDimValueService; private final SalaryGroupProjectHitLogService salaryGroupProjectHitLogService; private final SalaryGeneralSettinService salaryGeneralSettinService; private final SalaryGroupProjectSettinService salaryGroupProjectSettinService; private final SalarySettingCommonService salarySettingCommonService; private final SalaryGroupProjectParamService salaryGroupProjectParamService; private final SalaryGroupProjectTargetHitLogService salaryGroupProjectTargetHitLogService; private final CommonService commonService; private final EhrRpcService ehrRpcService; private final OopRpcService oopRpcService; @Value("${special-indicator-code.car-series}") @Getter private String carSeries; @Value("${special-indicator-code.base-salary}") @Getter private String baseSalaryCode; @Value("${spring.cache.custom.global-prefix}:salary:group:report") @Getter private String salaryGroupReportDistKey; /** * 薪酬报表定时任务 * */ @Scheduled(cron = TimeTaskConstant.SALARY_REPORT) @Transactional(rollbackFor = Exception.class) public void salaryReportTask() { this.salaryReport(LocalDate.now().minusDays(1)); } /** * 薪酬报表最终定时任务( * 人员质量评测每月2号计算上月、计算完成后会操作上月薪酬分,所以再次抽取上月报表) */ @Scheduled(cron = TimeTaskConstant.SALARY_MONTH_FINAL_REPORT) @Transactional(rollbackFor = Exception.class) public void salaryLastMonthReportTask() { LocalDate lastMonthEndDay = LocalDate.now().minusMonths(1).with(TemporalAdjusters.lastDayOfMonth()); YearMonth monthly = YearMonth.now().minusMonths(1); oopRpcService.allGroups().stream().forEach(group -> { final Long groupId = group.getId(); Boolean hasEndAppeal = salarySettingCommonService.lastDayHasClosureForReport(groupId, monthly); if (hasEndAppeal) { this.salaryReport(lastMonthEndDay); } }); } /** * 薪酬报表定时任务 * * @param date */ public void salaryReport(LocalDate date) { Lock lock = distributedLocker.lock(getSalaryGroupReportDistKey()); if (! ((RLock) lock).isLocked()) { return; } TransactionStatus transactionStatus = platformTransactionManager.getTransaction(transactionDefinition); try { log.info("定时任务【薪酬报表数据抽取-新】开始执行"); //清理数据,每天留一条当月最新数据,每个月留一条月最后一天的数据 cleanData(date); //查询所有需要处理的薪酬组 List salaryGroups = salaryGroupService.getAllEffectGroups(DateUtil.localDate2Date(date)); for (SalaryGroup salaryGroup : salaryGroups) { //抽取排名组数据 createReport(salaryGroup, salaryGroup.getGroupId(), date); } platformTransactionManager.commit(transactionStatus); } catch (Exception e){ platformTransactionManager.rollback(transactionStatus); log.error(e.getMessage(), e); } finally { lock.unlock(); } } /** * 薪酬排名组报表数据抽取 * @param salaryGroup * @param groupId * @param date */ private void createReport(SalaryGroup salaryGroup, Long groupId, LocalDate date) { final Long salaryGroupId = salaryGroup.getId(); List pools = salaryPoolService.list(Wrappers.lambdaQuery() .eq(SalaryPool::getSalaryGroupId, salaryGroupId) .eq(SalaryPool::getMonthly, YearMonth.from(date)) .eq(SalaryPool::getYn, Boolean.TRUE) ); if (PublicUtil.isEmpty(pools)) { return; } //保存 报表薪酬排名组 信息 final Long reportSalaryId = saveReportSalary(salaryGroup, groupId, date); //薪酬排名组下归属的所有薪酬组的对应指标集合 List salaryGroupProjects = getProjectBO(salaryGroupId); //一个薪酬排名组对应多个薪酬组,也对应薪酬组下的所有指标集合 saveReportSalaryCodes(date, reportSalaryId, salaryGroupProjects); List userDims = new ArrayList(); //人员维度 List userSalaryValues = calcUser(salaryGroupProjects, userDims, date, pools, reportSalaryId); //门店维度 calcShop(salaryGroupProjects, pools, reportSalaryId, userSalaryValues, userDims, date); //管理层维度 calcManager(salaryGroupProjects, pools, reportSalaryId, userSalaryValues, userDims, date); } private List saveReportSalaryCodes(LocalDate date, Long reportSalaryId, List salaryGroupProjects) { LinkedList reportSalaryCodes = new LinkedList<>(); AtomicInteger order = new AtomicInteger(); for (SalaryGroupProjectBO salaryGroupProject : salaryGroupProjects) { reportSalaryCodes.add(createProjectCode(salaryGroupProject, order)); if (IndicatorCodeTypeEnum.COMBINE_INDICATOR.equals(salaryGroupProject.getCodeType())) { List salaryGroupProjectParamVos = salaryGroupProjectParamService. getSalaryGroupProjectParamVO(salaryGroupProject.getId()); if (salaryGroupProject.getCalMethod().equals(SalaryCalMethodEnum.CAR_SERIES)) { continue; } reportSalaryCodes.addAll(createParamCodes(salaryGroupProject, salaryGroupProjectParamVos, order)); } } if (PublicUtil.isNotEmpty(reportSalaryCodes)) { reportSalaryCodes.forEach(reportSalaryCode -> { reportSalaryCode.setReportSalaryId(reportSalaryId); reportSalaryCode.setDataDate(date); }); reportSalaryCodeService.saveBatch(reportSalaryCodes); } return reportSalaryCodes; } private List calcUser(List salaryGroupProjects, List userDims, LocalDate dataDate, List pools, Long reportSalaryId) { MultiKeyMap userSalaryMap = this.getUserIndicatorHitMap(salaryGroupProjects, dataDate, pools); List reportSalaryValues = new ArrayList<>(); //人的维度为基础,计算各个指标信息对应的数据 for (SalaryPool pool : pools) { //如果计算日期 与 报表数据抽取日期不一致,使用计算日期(计算日期每个人都可能不一致) Boolean changeStaff = pool.getDataDate().compareTo(dataDate) != 0; ReportSalaryDim reportSalaryDim = saveStaffDim(pool, dataDate, reportSalaryId); userDims.add(reportSalaryDim); final Long userId = pool.getUserId(); final Long reportSalaryDimId = reportSalaryDim.getId(); //薪酬排名组下的所有指标集合 for (SalaryGroupProjectBO salaryGroupProject : salaryGroupProjects) { if (! pool.getSalaryGroupId().equals(salaryGroupProject.getSalaryGroupId())) { continue; } final Long salaryGroupProjectId = salaryGroupProject.getId(); BigDecimal salaryValue = userSalaryMap.get(userId, salaryGroupProjectId); if (changeStaff) { salaryValue = this.getUserIndicatorHitValue(salaryGroupProject, pool.getDataDate(), pool); } reportSalaryValues.add(this.convertDB(salaryGroupProject, reportSalaryDimId, dataDate, salaryValue)); List salaryGroupProjectParamVos = salaryGroupProjectParamService.getSalaryGroupProjectParamVO(salaryGroupProject.getId()); if (salaryGroupProject.getCalMethod().equals(SalaryCalMethodEnum.CAR_SERIES)) { continue; } Set paramCodes = new HashSet<>(); for (SalaryGroupProjectParamVO salaryGroupProjectParam : salaryGroupProjectParamVos) { //一个薪酬项目中,指标只能出现一次 if (! paramCodes.add(salaryGroupProjectParam.getIndicatorCode())) { continue; } LocalDate calcDate = (changeStaff) ? pool.getDataDate() : dataDate; if (TargetTypeEnum.NO.equals(salaryGroupProjectParam.getTargetType())) { //无目标 Map userValueMap = queryUserOriginValue(salaryGroupProjectParam.getIndicatorCode(), userId, calcDate); BigDecimal value = userValueMap.getOrDefault(userId, BigDecimal.ZERO); reportSalaryValues.add(this.convertNoTargetDB(salaryGroupProject, salaryGroupProjectParam, dataDate, reportSalaryDimId, value)); } else { //有目标 Map targetHitLogMap = queryUserTargetValue(salaryGroupProjectParam.getId(), userId, calcDate); SalaryGroupProjectTargetHitLog hitLog = targetHitLogMap.get(userId); BigDecimal value = Optional.ofNullable(hitLog).map(SalaryGroupProjectTargetHitLog::getReachValue).orElse(BigDecimal.ZERO); reportSalaryValues.add(this.convertTargetDB(salaryGroupProject, salaryGroupProjectParam, dataDate, reportSalaryDimId, value)); } } } } if (PublicUtil.isNotEmpty(reportSalaryValues)){ reportSalaryDimValueService.saveBatch(reportSalaryValues); } return reportSalaryValues; } public void calcShop(List salaryGroupProjects, List pools, Long reportSalaryId, List userSalaryValues, List userDims, LocalDate date) { Map shopMap = pools.stream().collect(Collectors.toMap(SalaryPool::getShopId, SalaryPool::getShopName, (v1, v2) -> v1)); List reportSalaryDimValues = new ArrayList<>(); for (Long shopId : shopMap.keySet()) { List childReportSalaryDimValues = new ArrayList<>(); Set shopDimReportIds = userDims.stream() .filter(user -> shopId.equals(user.getShopId())) .map(ReportSalaryDim::getId).collect(Collectors.toSet()); if (PublicUtil.isEmpty(shopDimReportIds)) { continue; } BigDecimal averageSalary = calcAverageTotalSalary(userDims, shopDimReportIds); BigDecimal kpiScoreRatio = calcAverageKpiScoreRatio(userDims, shopDimReportIds); final Long shopReportSalaryDimId = this.saveShopDimDB(shopId, shopMap, date, reportSalaryId, averageSalary, kpiScoreRatio); for (SalaryGroupProjectBO salaryGroupProject : salaryGroupProjects) { BigDecimal value = calcAverageValue(userSalaryValues, shopDimReportIds, salaryGroupProject.getId().toString()); childReportSalaryDimValues.add(this.convertProjectValueDB(salaryGroupProject, value)); Set paramCodes = new HashSet<>(); List salaryGroupProjectParamVos = salaryGroupProjectParamService.getSalaryGroupProjectParamVO(salaryGroupProject.getId()); for (SalaryGroupProjectParamVO salaryGroupProjectParam : salaryGroupProjectParamVos) { if (! paramCodes.add(salaryGroupProjectParam.getIndicatorCode())) { continue; } BigDecimal paramValue = calcAverageValue(userSalaryValues, shopDimReportIds, salaryGroupProjectParam.getIndicatorCode()); childReportSalaryDimValues.add(this.convertShopValueDBPcode(salaryGroupProjectParam, paramValue, salaryGroupProject)); } } childReportSalaryDimValues.forEach(reportSalaryDimValue -> { reportSalaryDimValue.setDataDate(date); reportSalaryDimValue.setReportSalaryDimId(shopReportSalaryDimId); }); reportSalaryDimValues.addAll(childReportSalaryDimValues); } if (PublicUtil.isNotEmpty(reportSalaryDimValues)){ reportSalaryDimValueService.saveBatch(reportSalaryDimValues); } } public void calcManager(List salaryGroupProjects, List pools, Long reportSalaryId, List userSalaryValues, List userDims, LocalDate date) { List shopIds = pools.stream().map(SalaryPool::getShopId).collect(Collectors.toList()); List managerDTOS = ehrRpcService.getRealTimeShopManager(new ArrayList<>(shopIds)); log.info("查询门店实时管理者:{},{}", JSON.toJSONString(shopIds), JSON.toJSONString(managerDTOS)); if (PublicUtil.isEmpty(managerDTOS)) { return; } Map managerMap = staffInfoMap(managerDTOS); List reportSalaryDimValues = new ArrayList<>(); for (ManagerDTO manager : managerDTOS) { List childReportSalaryDimValues = new ArrayList<>(); if (PublicUtil.isEmpty(manager.getManageStaffList())) { continue; } List manageStaffIds = manager.getManageStaffList().stream().map(StaffBaseInfoDTO::getId).distinct().collect(Collectors.toList()); Set managerStaffDimReportIds = userDims.stream() .filter(user -> manageStaffIds.contains(user.getUserId())) .map(ReportSalaryDim::getId).collect(Collectors.toSet()); if (PublicUtil.isEmpty(managerStaffDimReportIds)) { continue; } BigDecimal kpiScoreRatio = calcAverageKpiScoreRatio(userDims, managerStaffDimReportIds); BigDecimal averageSalary = calcAverageTotalSalary(userDims, managerStaffDimReportIds); final Long reportSalaryDimId = this.saveManagerDimDB(manager, date, reportSalaryId, managerMap, averageSalary, kpiScoreRatio, manageStaffIds); for (SalaryGroupProjectBO salaryGroupProject : salaryGroupProjects) { BigDecimal value = calcAverageValue(userSalaryValues, managerStaffDimReportIds, salaryGroupProject.getId().toString()); childReportSalaryDimValues.add(this.convertProjectValueDB(salaryGroupProject, value)); List salaryGroupProjectParamVos = salaryGroupProjectParamService.getSalaryGroupProjectParamVO(salaryGroupProject.getId()); for (SalaryGroupProjectParamVO salaryGroupProjectParam : salaryGroupProjectParamVos) { BigDecimal paramValue = calcAverageValue(userSalaryValues, managerStaffDimReportIds, salaryGroupProjectParam.getIndicatorCode()); childReportSalaryDimValues.add(this.convertShopValueDBPcode(salaryGroupProjectParam, paramValue, salaryGroupProject)); } } childReportSalaryDimValues.forEach(reportSalaryDimValue -> { reportSalaryDimValue.setDataDate(date); reportSalaryDimValue.setReportSalaryDimId(reportSalaryDimId); }); reportSalaryDimValues.addAll(childReportSalaryDimValues); } if (PublicUtil.isNotEmpty(reportSalaryDimValues)) { reportSalaryDimValueService.saveBatch(reportSalaryDimValues); } } public Map staffInfoMap(List managerDTOS) { List staffIds = managerDTOS.stream().map(ManagerDTO::getStaffId).collect(Collectors.toList()); List staffInfos = ehrRpcService.queryStaffBaseInfo(staffIds); return staffInfos.stream().collect(Collectors.toMap(StaffBaseInfoDTO::getId, Function.identity(), (v1, v2) -> v1)); } public BigDecimal calcAverageTotalSalary(List dims, Set ReportDimIds) { Double averageRatioDouble = dims.stream() .filter(user -> ReportDimIds.contains(user.getId())) .mapToDouble(userValue -> Optional.ofNullable(userValue.getTotalReward()).orElse(BigDecimal.ZERO).doubleValue()) .average() .orElse(0); return new BigDecimal(averageRatioDouble.toString()); } public BigDecimal calcAverageKpiScoreRatio(List dims, Set ReportDimIds) { Double averageRatioDouble = dims.stream() .filter(user -> ReportDimIds.contains(user.getId())) .mapToDouble(userValue -> Optional.ofNullable(userValue.getKpiScoreRatio()).orElse(BigDecimal.ZERO).doubleValue()) .average() .orElse(0); return new BigDecimal(averageRatioDouble.toString()); } public BigDecimal calcAverageValue(List userSalaryValues, Set ReportDimIds, String code) { Double averageRatioDouble = userSalaryValues.stream() .filter(user -> ReportDimIds.contains(user.getReportSalaryDimId()) && code.equals(user.getCode())) .mapToDouble(userValue -> Optional.ofNullable(userValue.getValue()).orElse(BigDecimal.ZERO).doubleValue()) .average() .orElse(0); return new BigDecimal(averageRatioDouble.toString()); } public Long saveShopDimDB(Long shopId, Map shopMap, LocalDate date, Long reportSalaryId, BigDecimal averageSalary, BigDecimal kpiScoreRatio) { ReportSalaryDim reportSalaryDim = new ReportSalaryDim(); reportSalaryDim.setDimension(ReportDimensionEnum.SHOP); reportSalaryDim.setReferId(shopId); reportSalaryDim.setShopId(shopId); reportSalaryDim.setShopName(shopMap.get(shopId)); reportSalaryDim.setDataDate(date); reportSalaryDim.setReportSalaryId(reportSalaryId); reportSalaryDim.setTotalReward(averageSalary); reportSalaryDim.setKpiScoreRatio(kpiScoreRatio); reportSalaryDimService.save(reportSalaryDim); return reportSalaryDim.getId(); } public Long saveManagerDimDB(ManagerDTO manager, LocalDate date, Long reportSalaryId, Map managerMap, BigDecimal averageSalary, BigDecimal kpiScoreRatio, List manageStaffIds) { ReportSalaryDim reportSalaryDim = new ReportSalaryDim(); reportSalaryDim.setDimension(ReportDimensionEnum.MANAGER); reportSalaryDim.setUserId(manager.getStaffId()); reportSalaryDim.setUserName(manager.getStaffName()); reportSalaryDim.setTotalReward(averageSalary); reportSalaryDim.setKpiScoreRatio(kpiScoreRatio); reportSalaryDim.setDataDate(date); reportSalaryDim.setReportSalaryId(reportSalaryId); if (managerMap.containsKey(manager.getStaffId())) { StaffBaseInfoDTO staffInfo = managerMap.get(manager.getStaffId()); reportSalaryDim.setShopId(staffInfo.getShopId()); reportSalaryDim.setShopName(staffInfo.getShopName()); reportSalaryDim.setPostId(staffInfo.getPostId()); reportSalaryDim.setPostName(staffInfo.getPostName()); } List roleCodes = manager.getScopeList().stream() .flatMap(managerStaffVo -> managerStaffVo.getRoleList().stream()) .map(ManagerStaffRoleDTO::getRoleCode) .distinct() .collect(Collectors.toList()); List roleNames = manager.getScopeList().stream() .flatMap(managerStaffVo -> managerStaffVo.getRoleList().stream()) .map(ManagerStaffRoleDTO::getRoleName) .distinct() .collect(Collectors.toList()); List shopIds = manager.getScopeList().stream() .flatMap(managerStaffVo -> managerStaffVo.getShopList().stream()) .map(ManagerStaffShopDTO::getShopId) .distinct() .collect(Collectors.toList()); reportSalaryDimService.save(reportSalaryDim); ReportSalaryDimExtra reportSalaryDimExtra = new ReportSalaryDimExtra(); reportSalaryDimExtra.setReportSalaryDimId(reportSalaryDim.getId()); ReportSalaryDimExtra dimExtra = ReportSalaryDimExtra.builder() .reportSalaryDimId(reportSalaryDim.getId()) .roleCodes(roleCodes) .roleNames(roleNames) .shopIds(shopIds) .staffIds(manageStaffIds) .build(); reportSalaryDimExtraService.save(dimExtra); return reportSalaryDim.getId(); } public ReportSalaryDimValue convertProjectValueDB(SalaryGroupProjectBO salaryGroupProject, BigDecimal value) { ReportSalaryDimValue reportSalaryValue = new ReportSalaryDimValue(); reportSalaryValue.setCode(salaryGroupProject.getId().toString()); reportSalaryValue.setCodeType(salaryGroupProject.getCodeType()); reportSalaryValue.setValue(value); reportSalaryValue.setSalaryGroupProjectId(salaryGroupProject.getId()); return reportSalaryValue; } public ReportSalaryDimValue convertShopValueDBPcode(SalaryGroupProjectParamVO salaryGroupProjectParam, BigDecimal value,SalaryGroupProjectBO salaryGroupProject) { ReportSalaryDimValue reportSalaryValue = new ReportSalaryDimValue(); reportSalaryValue.setCode(salaryGroupProjectParam.getIndicatorCode()); reportSalaryValue.setCodeType(IndicatorCodeTypeEnum.INDICATOR); reportSalaryValue.setValue(value); reportSalaryValue.setSalaryGroupProjectId(salaryGroupProjectParam.getSalaryGroupProjectId()); reportSalaryValue.setParentCode(salaryGroupProject.getId().toString()); return reportSalaryValue; } public ReportSalaryDimValue convertDB(SalaryGroupProjectBO salaryGroupProject, Long reportSalaryDimId, LocalDate date, BigDecimal salaryValue) { ReportSalaryDimValue reportSalaryValue = new ReportSalaryDimValue(); reportSalaryValue.setCode(salaryGroupProject.getId().toString()); reportSalaryValue.setCodeType(salaryGroupProject.getCodeType()); if (PublicUtil.isEmpty(salaryValue)) { reportSalaryValue.setValue(BigDecimal.ZERO); } else { reportSalaryValue.setValue(salaryValue); } reportSalaryValue.setDataDate(date); reportSalaryValue.setReportSalaryDimId(reportSalaryDimId); reportSalaryValue.setSalaryGroupProjectId(salaryGroupProject.getId()); return reportSalaryValue; } public ReportSalaryDimValue convertNoTargetDB(SalaryGroupProjectBO salaryGroupProject, SalaryGroupProjectParamVO salaryGroupProjectParam, LocalDate date, Long reportSalaryDimId, BigDecimal value) { ReportSalaryDimValue reportSalaryValue = new ReportSalaryDimValue(); reportSalaryValue.setCode(salaryGroupProjectParam.getIndicatorCode()); reportSalaryValue.setCodeType(IndicatorCodeTypeEnum.INDICATOR); reportSalaryValue.setParentCode(salaryGroupProject.getId().toString()); reportSalaryValue.setValue(value); //百分数处理 if (DataTypeEnum.RATIO.equals(salaryGroupProjectParam.getDataType())){ reportSalaryValue.setValue(value.multiply(Constant.ONE_HUNDRED)); } reportSalaryValue.setDataDate(date); reportSalaryValue.setReportSalaryDimId(reportSalaryDimId); reportSalaryValue.setSalaryGroupProjectId(salaryGroupProject.getId()); return reportSalaryValue; } public ReportSalaryDimValue convertTargetDB(SalaryGroupProjectBO salaryGroupProject, SalaryGroupProjectParamVO salaryGroupProjectParam, LocalDate date, Long reportSalaryDimId, BigDecimal value) { ReportSalaryDimValue reportSalaryValue = new ReportSalaryDimValue(); reportSalaryValue.setCode(salaryGroupProjectParam.getIndicatorCode()); reportSalaryValue.setCodeType(IndicatorCodeTypeEnum.INDICATOR); reportSalaryValue.setParentCode(salaryGroupProject.getId().toString()); //有目标 乘以 100 reportSalaryValue.setValue(value.multiply(Constant.ONE_HUNDRED)); reportSalaryValue.setDataDate(date); reportSalaryValue.setReportSalaryDimId(reportSalaryDimId); reportSalaryValue.setSalaryGroupProjectId(salaryGroupProject.getId()); return reportSalaryValue; } public MultiKeyMap getUserIndicatorHitMap(List salaryGroupProjects, LocalDate date, List pools) { List indicatorHitLogs = salaryGroupProjectHitLogService.list(Wrappers.lambdaQuery() .in(SalaryGroupProjectHitLog::getSalaryGroupProjectId, salaryGroupProjects.stream().map(SalaryGroupProjectBO::getId).collect(Collectors.toList())) .in(SalaryGroupProjectHitLog::getUserId, pools.stream().map(SalaryPool::getUserId).collect(Collectors.toList())) .eq(SalaryGroupProjectHitLog::getDataDate, date) .eq(SalaryGroupProjectHitLog::getYn, Boolean.TRUE) ); MultiKeyMap userGroupIndicatorHitMap = new MultiKeyMap<>(); for (SalaryGroupProjectHitLog hitLog : indicatorHitLogs) { userGroupIndicatorHitMap.put(hitLog.getUserId(), hitLog.getSalaryGroupProjectId(), hitLog.getSalaryValue()); } return userGroupIndicatorHitMap; } public BigDecimal getUserIndicatorHitValue(SalaryGroupProjectBO salaryGroupProject, LocalDate date, SalaryPool pool) { SalaryGroupProjectHitLog indicatorHitLog = salaryGroupProjectHitLogService.getOne(Wrappers.lambdaQuery() .eq(SalaryGroupProjectHitLog::getSalaryGroupProjectId, salaryGroupProject.getId()) .eq(SalaryGroupProjectHitLog::getUserId, pool.getUserId()) .eq(SalaryGroupProjectHitLog::getDataDate, date) .eq(SalaryGroupProjectHitLog::getYn, Boolean.TRUE) , Boolean.FALSE ); return Optional.ofNullable(indicatorHitLog).map(SalaryGroupProjectHitLog::getSalaryValue).orElse(BigDecimal.ZERO); } public Map queryUserTargetValue(Long referId, Long userId, LocalDate dataDate) { List targetHitLogs = salaryGroupProjectTargetHitLogService.list(Wrappers.lambdaQuery() .eq(SalaryGroupProjectTargetHitLog::getReferId, referId) .eq(SalaryGroupProjectTargetHitLog::getTargetType, IndicatorTypeEnum.EXAMINE) .eq(SalaryGroupProjectTargetHitLog::getDataDate, dataDate) .eq(SalaryGroupProjectTargetHitLog::getUserId, userId) .eq(SalaryGroupProjectTargetHitLog::getYn, Boolean.TRUE) ); return targetHitLogs.stream() .collect(Collectors.toMap(SalaryGroupProjectTargetHitLog::getUserId, Function.identity(), (v1, v2) -> v1)); } public Map queryUserOriginValue(String code, Long userId, LocalDate dataDate) { Map referValueMap = Maps.newHashMapWithExpectedSize(1); //无目标 LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); queryWrapper.eq(IndicatorUserValue::getUserId, userId); List indicatorUserValues = indicatorUserValueService.list(queryWrapper .eq(IndicatorUserValue::getIndicatorCode, code) .eq(IndicatorUserValue::getDataDate, dataDate) .eq(IndicatorUserValue::getDimensionType, DimensionTypeEnum.STAFF) .eq(IndicatorUserValue::getYn, Boolean.TRUE) ); for (IndicatorUserValue userValue : indicatorUserValues) { BigDecimal indicatorValue = commonService.queryIndicatorValue(code, userValue); referValueMap.put(userValue.getUserId(), indicatorValue); //如果原始值是百分比,乘以100,由于业务系统这个可能不准还是配置指标里面的data_type //if (IndicatorValueTypeEnum.RATIO.equals(userValue.getValueType())){ // referValueMap.put(userValue.getUserId(), indicatorValue.multiply(Constant.ONE_HUNDRED)); //} } return referValueMap; } public ReportSalaryCode createProjectCode(SalaryGroupProjectBO salaryGroupProject,AtomicInteger order) { ReportSalaryCode reportSalaryCode = new ReportSalaryCode(); reportSalaryCode.setSalaryGroupProjectId(salaryGroupProject.getId()); reportSalaryCode.setCode(salaryGroupProject.getId().toString()); reportSalaryCode.setCodeType(salaryGroupProject.getCodeType()); reportSalaryCode.setIndicatorName(salaryGroupProject.getName()); reportSalaryCode.setOrderNum(order.incrementAndGet()); return reportSalaryCode; } public List createParamCodes(SalaryGroupProjectBO salaryGroupProject, List salaryGroupProjectParamVos, AtomicInteger order) { List saveReportSalaryCodes = new ArrayList<>(salaryGroupProjectParamVos.size()); for (SalaryGroupProjectParamVO salaryGroupProjectParam : salaryGroupProjectParamVos) { ReportSalaryCode reportSalaryCode = new ReportSalaryCode(); reportSalaryCode.setSalaryGroupProjectId(salaryGroupProjectParam.getSalaryGroupProjectId()); reportSalaryCode.setCode(salaryGroupProjectParam.getIndicatorCode()); reportSalaryCode.setCodeType(IndicatorCodeTypeEnum.INDICATOR); reportSalaryCode.setIndicatorName(salaryGroupProjectParam.getIndicatorName()); reportSalaryCode.setParentCode(salaryGroupProject.getId().toString()); reportSalaryCode.setOrderNum(order.incrementAndGet()); saveReportSalaryCodes.add(reportSalaryCode); } return saveReportSalaryCodes; } private Long saveReportSalary(SalaryGroup salaryGroup, Long groupId, LocalDate date) { ReportSalary reportSalary = new ReportSalary(); reportSalary.setSalaryGroupId(salaryGroup.getId()); reportSalary.setSalaryName(salaryGroup.getName()); //门店id reportSalary.setShopIds(salaryGroup.getShopIds()); reportSalary.setMonthly(YearMonth.from(date)); reportSalary.setDataDate(date); reportSalary.setGroupId(groupId); reportSalaryService.save(reportSalary); return reportSalary.getId(); } private void cleanData(LocalDate endDate) { List reportSalaries = reportSalaryService.list(Wrappers.lambdaQuery() // .eq(ReportSalary::getSalaryGroupId, salaryGroup.getId()) //.ge(ReportSalary::getDataDate, startDate.with(TemporalAdjusters.firstDayOfMonth())) //取当前日期对应月的第一天 .ge(ReportSalary::getDataDate, endDate.with(TemporalAdjusters.firstDayOfMonth())) .le(ReportSalary::getDataDate, endDate) ); if (PublicUtil.isEmpty(reportSalaries)){ return; } this.cleanData(reportSalaries); } /** * 清理排名组下报表数据 * @param reportSalaries */ public void cleanData(List reportSalaries) { if (CollectionUtils.isEmpty(reportSalaries)){ return; } //薪酬排名组ids List reportSalaryIds = reportSalaries.stream().map(ReportSalary::getId).collect(Collectors.toList()); reportSalaryService.removeByIds(reportSalaryIds); reportSalaryCodeService.remove(Wrappers.lambdaUpdate() .in(ReportSalaryCode::getReportSalaryId, reportSalaryIds) ); //维度的删除要先查询 List reportSalaryDims = reportSalaryDimService.list(Wrappers.lambdaQuery() .in(ReportSalaryDim::getReportSalaryId, reportSalaryIds) ); if (CollectionUtils.isEmpty(reportSalaryDims)){ return; } List reportSalaryDimIds = reportSalaryDims.stream().map(ReportSalaryDim::getId).collect(Collectors.toList()); reportSalaryDimService.removeByIds(reportSalaryDimIds); reportSalaryDimExtraService.remove(Wrappers.lambdaUpdate() .in(ReportSalaryDimExtra::getReportSalaryDimId, reportSalaryDimIds) ); reportSalaryDimValueService.remove(Wrappers.lambdaUpdate() .in(ReportSalaryDimValue::getReportSalaryDimId, reportSalaryDimIds) ); } public LinkedList getProjectBO(Long salaryGroupId) { List salaryGroupProjects = salaryGroupProjectService.list(Wrappers.lambdaQuery() .eq(SalaryGroupProject::getSalaryGroupId, salaryGroupId) .eq(SalaryGroupProject::getYn, Boolean.TRUE) .orderByAsc(SalaryGroupProject::getId) ); if (PublicUtil.isEmpty(salaryGroupProjects)) { return new LinkedList<>(); } LinkedList projects = new LinkedList(); for (SalaryGroupProject project : salaryGroupProjects) { SalaryGroupProjectBO projectBO = PublicUtil.copy(project, SalaryGroupProjectBO.class); switch (projectBO.getCalMethod()) { case STAR: { projectBO.setCode(project.getId().toString()); List params = salaryGroupProjectParamService.getSalaryGroupProjectParamVO(projectBO.getId()); IndicatorCodeTypeEnum codeType = IndicatorCodeTypeEnum.INDICATOR; //有基本工资指标就不下钻 if (PublicUtil.isNotEmpty(params)) { Boolean hasBaseSalary = params.stream().filter(param -> getBaseSalaryCode().equals(param.getIndicatorCode())).findAny().isPresent(); if (! hasBaseSalary) { codeType = IndicatorCodeTypeEnum.COMBINE_INDICATOR; } } projectBO.setCodeType(codeType); break; } case FIXATION: CAR_SERIES: { projectBO.setCode(project.getCommissionCode()); projectBO.setCodeType(IndicatorCodeTypeEnum.COMBINE_INDICATOR); break; } case LADDER: { projectBO.setCode(project.getLadderCode()); projectBO.setCodeType(IndicatorCodeTypeEnum.COMBINE_INDICATOR); break; } } //基本工资不能下钻 if (getBaseSalaryCode().equals(projectBO.getCode())) { projectBO.setCodeType(IndicatorCodeTypeEnum.INDICATOR); } projects.add(projectBO); } return projects; } public ReportSalaryDim saveStaffDim(SalaryPool pool, LocalDate date, Long reportSalaryRankId){ ReportSalaryDim reportSalaryDim = new ReportSalaryDim(); reportSalaryDim.setDimension(ReportDimensionEnum.STAFF); reportSalaryDim.setReferId(pool.getUserId()); reportSalaryDim.setSalaryPoolId(pool.getId()); reportSalaryDim.setUserId(pool.getUserId()); reportSalaryDim.setUserName(pool.getUserName()); reportSalaryDim.setPostId(pool.getPostId()); reportSalaryDim.setPostName(pool.getPostName()); reportSalaryDim.setShopId(pool.getShopId()); reportSalaryDim.setShopName(pool.getShopName()); reportSalaryDim.setDataDate(date); reportSalaryDim.setReportSalaryId(reportSalaryRankId); reportSalaryDim.setStarLevel(pool.getStarLevel()); reportSalaryDim.setTotalReward(pool.getReward()); // KpiPool kpiPool = kpiPoolCommonService.queryPool(pool); // if (PublicUtil.isNotEmpty(kpiPool)) { // BigDecimal kpiScoreRatio = Optional.ofNullable(kpiPool.getKpiScoreRatio()).orElse(BigDecimal.ZERO); // reportSalaryDim.setKpiScoreRatio(kpiScoreRatio.multiply(Constant.ONE_HUNDRED)); // } reportSalaryDimService.save(reportSalaryDim); return reportSalaryDim; } }