From e8cf26f2b5d289d7fca71a2c604b4bcd85765178 Mon Sep 17 00:00:00 2001 From: xianpengcheng Date: Thu, 25 May 2023 10:25:52 +0800 Subject: [PATCH] 更新-薪酬额外项字段的计算和添加 --- fw-morax-domain/src/main/java/cn/fw/morax/domain/db/salary/ReportSalaryDim.java | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- fw-morax-server/src/main/java/cn/fw/morax/server/task/SalaryReportTask.java | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 255 insertions(+), 22 deletions(-) diff --git a/fw-morax-domain/src/main/java/cn/fw/morax/domain/db/salary/ReportSalaryDim.java b/fw-morax-domain/src/main/java/cn/fw/morax/domain/db/salary/ReportSalaryDim.java index d973700..5c08ffc 100644 --- a/fw-morax-domain/src/main/java/cn/fw/morax/domain/db/salary/ReportSalaryDim.java +++ b/fw-morax-domain/src/main/java/cn/fw/morax/domain/db/salary/ReportSalaryDim.java @@ -93,7 +93,7 @@ public class ReportSalaryDim extends BaseEntity { private StarLevelEnum starLevel; /** - * 总薪酬 + * 总薪酬 = actRevenueTotalMoney(总收入合计) - actDeductTotalMoney(总扣除合计) */ private BigDecimal totalReward; @@ -102,4 +102,64 @@ public class ReportSalaryDim extends BaseEntity { */ private BigDecimal kpiScoreRatio; + /** + * 总收入合计 + */ + private BigDecimal actRevenueTotalMoney; + + /** + * 总绩效提成 + */ + private BigDecimal actKpiMoney; + + /** + * 总内部奖励 + */ + private BigDecimal actAwardMoney; + + /** + * 总福利补贴 + */ + private BigDecimal actSubsidyMoney; + + /** + * 总试用期工资 + */ + private BigDecimal actProbationMoney; + + /** + * 总岗位最低补偿 + */ + private BigDecimal actJobCompensateMoney; + + /** + * 总考评奖励 + */ + private BigDecimal actEvalAwardMoney; + + /** + * 总扣除合计 + */ + private BigDecimal actDeductTotalMoney; + + /** + * 总内部罚款扣除 + */ + private BigDecimal actPenaltyMoney; + + /** + * 总社保扣除 + */ + private BigDecimal actNecessaryMoney; + + /** + * 总个税扣除 + */ + private BigDecimal actPersonTaxMoney; + + /** + * 总公积金扣除 + */ + private BigDecimal actAccumulationFundMoney; + } diff --git a/fw-morax-server/src/main/java/cn/fw/morax/server/task/SalaryReportTask.java b/fw-morax-server/src/main/java/cn/fw/morax/server/task/SalaryReportTask.java index 53d58de..1949d6f 100644 --- a/fw-morax-server/src/main/java/cn/fw/morax/server/task/SalaryReportTask.java +++ b/fw-morax-server/src/main/java/cn/fw/morax/server/task/SalaryReportTask.java @@ -6,7 +6,7 @@ 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.kpi.IndicatorUserValue; import cn.fw.morax.domain.db.salary.*; import cn.fw.morax.domain.enums.*; import cn.fw.morax.domain.vo.salary.SalaryGroupProjectParamVO; @@ -49,6 +49,8 @@ import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.Lock; import java.util.function.Function; +import java.util.function.Predicate; +import java.util.function.ToDoubleFunction; import java.util.stream.Collectors; /** @@ -86,6 +88,7 @@ public class SalaryReportTask { private final CommonService commonService; private final EhrRpcService ehrRpcService; private final OopRpcService oopRpcService; + private final SalaryPoolDetailService salaryPoolDetailService; @Value("${special-indicator-code.car-series}") @@ -223,10 +226,12 @@ public class SalaryReportTask { List pools, Long reportSalaryId) { MultiKeyMap userSalaryMap = this.getUserIndicatorHitMap(salaryGroupProjects, date, pools); + Map> salaryPoolDetailMap = this.getSalaryPoolDetailMap(date, pools); List reportSalaryValues = new ArrayList<>(); //人的维度为基础,计算各个指标信息对应的数据 for (SalaryPool pool : pools) { - ReportSalaryDim reportSalaryDim = saveStaffDim(pool, date, reportSalaryId); + List salaryPoolIdDetails = Optional.ofNullable(salaryPoolDetailMap.get(pool.getId())).orElse(Collections.emptyList()); + ReportSalaryDim reportSalaryDim = saveStaffDim(pool, date, reportSalaryId,salaryPoolIdDetails); userDims.add(reportSalaryDim); final Long userId = pool.getUserId(); final Long reportSalaryDimId = reportSalaryDim.getId(); @@ -286,9 +291,7 @@ public class SalaryReportTask { 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); + final Long shopReportSalaryDimId = this.saveShopDimDB(shopId, shopMap, date, reportSalaryId, userDims, shopDimReportIds); for (SalaryGroupProjectBO salaryGroupProject : salaryGroupProjects) { BigDecimal value = calcAverageValue(userSalaryValues, shopDimReportIds, salaryGroupProject.getId().toString()); @@ -341,9 +344,9 @@ public class SalaryReportTask { 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); + //BigDecimal kpiScoreRatio = calcAverageKpiScoreRatio(userDims, managerStaffDimReportIds); + //BigDecimal averageSalary = calcAverageTotalSalary(userDims, managerStaffDimReportIds); + final Long reportSalaryDimId = this.saveManagerDimDB(manager, date, reportSalaryId, managerMap,manageStaffIds,managerStaffDimReportIds,userDims); for (SalaryGroupProjectBO salaryGroupProject : salaryGroupProjects) { BigDecimal value = calcAverageValue(userSalaryValues, managerStaffDimReportIds, salaryGroupProject.getId().toString()); childReportSalaryDimValues.add(this.convertProjectValueDB(salaryGroupProject, value)); @@ -371,6 +374,44 @@ public class SalaryReportTask { return staffInfos.stream().collect(Collectors.toMap(StaffBaseInfoDTO::getId, Function.identity(), (v1, v2) -> v1)); } + /** + * 抽象处理平均值计算 + * @param data + * @param predicate + * @param field + * @return + */ + private BigDecimal calcAverage(final Collection data,Predicate predicate, final ToDoubleFunction field) { + if (CollectionUtils.isEmpty(data)) { + return BigDecimal.ZERO; + } + Double averageRatioDouble = data.stream() + .filter(predicate) + .mapToDouble(field) + .average() + .orElse(0); + return BigDecimal.valueOf(averageRatioDouble); + } + + /** + * 抽象处理平均值计算 + * @param data + * @param field + * @return + * @param + */ + private BigDecimal calcAverage(final Collection data, final ToDoubleFunction field) { + if (CollectionUtils.isEmpty(data)) { + return BigDecimal.ZERO; + } + Double averageRatioDouble = data.stream() + .mapToDouble(field) + .average() + .orElse(0); + return BigDecimal.valueOf(averageRatioDouble); + } + + public BigDecimal calcAverageTotalSalary(List dims, Set ReportDimIds) { Double averageRatioDouble = dims.stream() .filter(user -> ReportDimIds.contains(user.getId())) @@ -398,8 +439,12 @@ public class SalaryReportTask { return new BigDecimal(averageRatioDouble.toString()); } - public Long saveShopDimDB(Long shopId, Map shopMap, - LocalDate date, Long reportSalaryId, BigDecimal averageSalary, BigDecimal kpiScoreRatio) { + public Long saveShopDimDB(Long shopId, + Map shopMap, + LocalDate date, + Long reportSalaryId, + List userDims, + Set shopDimReportIds) { ReportSalaryDim reportSalaryDim = new ReportSalaryDim(); reportSalaryDim.setDimension(ReportDimensionEnum.SHOP); reportSalaryDim.setReferId(shopId); @@ -407,24 +452,118 @@ public class SalaryReportTask { reportSalaryDim.setShopName(shopMap.get(shopId)); reportSalaryDim.setDataDate(date); reportSalaryDim.setReportSalaryId(reportSalaryId); - reportSalaryDim.setTotalReward(averageSalary); - reportSalaryDim.setKpiScoreRatio(kpiScoreRatio); + //计算平均值薪酬的额外项 + extCalcAverage(userDims, shopDimReportIds, reportSalaryDim); reportSalaryDimService.save(reportSalaryDim); return reportSalaryDim.getId(); } + + /** + * 计算平均值薪酬的额外项 + * @param userDims + * @param shopDimReportIds + * @param reportSalaryDim + */ + private void extCalcAverage(List userDims, Set shopDimReportIds, ReportSalaryDim reportSalaryDim) { + List filterUserDims = userDims.stream().filter(e -> shopDimReportIds.contains(e.getId())).collect(Collectors.toList()); + //绩效得分率(N) + reportSalaryDim.setKpiScoreRatio(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getKpiScoreRatio()).orElse(BigDecimal.ZERO).doubleValue())); + //收入-平均值 + reportSalaryDim.setActKpiMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActKpiMoney()).orElse(BigDecimal.ZERO).doubleValue())); + reportSalaryDim.setActAwardMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActAwardMoney()).orElse(BigDecimal.ZERO).doubleValue())); + reportSalaryDim.setActSubsidyMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActSubsidyMoney()).orElse(BigDecimal.ZERO).doubleValue())); + reportSalaryDim.setActProbationMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActProbationMoney()).orElse(BigDecimal.ZERO).doubleValue())); + reportSalaryDim.setActJobCompensateMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActJobCompensateMoney()).orElse(BigDecimal.ZERO).doubleValue())); + reportSalaryDim.setActEvalAwardMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActEvalAwardMoney()).orElse(BigDecimal.ZERO).doubleValue())); + //总收入合计平均值 + reportSalaryDim.setActRevenueTotalMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActRevenueTotalMoney()).orElse(BigDecimal.ZERO).doubleValue())); + //reportSalaryDim.setActRevenueTotalMoney( + // reportSalaryDim.getActKpiMoney() + // .add(reportSalaryDim.getActAwardMoney()) + // .add(reportSalaryDim.getActSubsidyMoney()) + // .add(reportSalaryDim.getActProbationMoney()) + // .add(reportSalaryDim.getActJobCompensateMonry()) + // .add(reportSalaryDim.getActEvalAwardMoney()) + //); + //扣除-平均值 + reportSalaryDim.setActPenaltyMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActPenaltyMoney()).orElse(BigDecimal.ZERO).doubleValue())); + reportSalaryDim.setActNecessaryMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActNecessaryMoney()).orElse(BigDecimal.ZERO).doubleValue())); + reportSalaryDim.setActPersonTaxMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActPersonTaxMoney()).orElse(BigDecimal.ZERO).doubleValue())); + reportSalaryDim.setActAccumulationFundMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActAccumulationFundMoney()).orElse(BigDecimal.ZERO).doubleValue())); + //总扣除合计平均值 + reportSalaryDim.setActDeductTotalMoney(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getActDeductTotalMoney()).orElse(BigDecimal.ZERO).doubleValue())); + //reportSalaryDim.setActDeductTotalMoney( + // reportSalaryDim.getActPenaltyMoney() + // .add(reportSalaryDim.getActNecessaryMoney()) + // .add(reportSalaryDim.getActPersonTaxMoney()) + // .add(reportSalaryDim.getActAccumulationFundMoney()) + //); + //总薪酬平均值 = 总收入合计 - 总扣除合计 or 直接取平均值 + reportSalaryDim.setTotalReward(calcAverage(filterUserDims, e -> Optional.ofNullable(e.getTotalReward()).orElse(BigDecimal.ZERO).doubleValue())); + //reportSalaryDim.setTotalReward( + // reportSalaryDim.getActRevenueTotalMoney() + // .subtract(reportSalaryDim.getActDeductTotalMoney())); + } + + /** + * 计算人员的 + * 增加 薪资类型相关项目处理 ++ + * @param salaryPoolDetails + * @param reportSalaryDim + */ + private void extCaleUserMoney(List salaryPoolDetails, ReportSalaryDim reportSalaryDim) { + //额外计算项++ + Map> salaryTypeEnumListMap = salaryPoolDetails + .stream() + .collect(Collectors.groupingBy(SalaryPoolDetail::getType)); + //收入 + reportSalaryDim.setActKpiMoney(getSalaryTypeEnumMoney(salaryTypeEnumListMap,SalaryTypeEnum.ROYALTIES)); + reportSalaryDim.setActAwardMoney(getSalaryTypeEnumMoney(salaryTypeEnumListMap,SalaryTypeEnum.AWARD)); + reportSalaryDim.setActSubsidyMoney(getSalaryTypeEnumMoney(salaryTypeEnumListMap,SalaryTypeEnum.SUBSIDY)); + reportSalaryDim.setActProbationMoney(getSalaryTypeEnumMoney(salaryTypeEnumListMap,SalaryTypeEnum.PROBATION)); + reportSalaryDim.setActJobCompensateMoney(BigDecimal.ZERO); + reportSalaryDim.setActEvalAwardMoney(BigDecimal.ZERO); + //总收入合计 + reportSalaryDim.setActRevenueTotalMoney( + reportSalaryDim.getActKpiMoney() + .add(reportSalaryDim.getActAwardMoney()) + .add(reportSalaryDim.getActSubsidyMoney()) + .add(reportSalaryDim.getActProbationMoney()) + .add(reportSalaryDim.getActJobCompensateMoney()) + .add(reportSalaryDim.getActEvalAwardMoney()) + ); + //扣除 + reportSalaryDim.setActPenaltyMoney(getSalaryTypeEnumMoney(salaryTypeEnumListMap,SalaryTypeEnum.PENALTY)); + reportSalaryDim.setActNecessaryMoney(getSalaryTypeEnumMoney(salaryTypeEnumListMap,SalaryTypeEnum.NECESSARY)); + reportSalaryDim.setActPersonTaxMoney(getSalaryTypeEnumMoney(salaryTypeEnumListMap,SalaryTypeEnum.PERSON_TAX)); + reportSalaryDim.setActAccumulationFundMoney(BigDecimal.ZERO); + //总扣除合计 + reportSalaryDim.setActDeductTotalMoney( + reportSalaryDim.getActPenaltyMoney() + .add(reportSalaryDim.getActNecessaryMoney()) + .add(reportSalaryDim.getActPersonTaxMoney()) + .add(reportSalaryDim.getActAccumulationFundMoney()) + ); + //总薪酬 = 总收入合计 - 总扣除合计 + reportSalaryDim.setTotalReward( + reportSalaryDim.getActRevenueTotalMoney() + .subtract(reportSalaryDim.getActDeductTotalMoney())); + } + + public Long saveManagerDimDB(ManagerDTO manager, LocalDate date, Long reportSalaryId, Map managerMap, - BigDecimal averageSalary, - BigDecimal kpiScoreRatio, - List manageStaffIds) { + List manageStaffIds, + Set managerStaffDimReportIds, + List userDims) { ReportSalaryDim reportSalaryDim = new ReportSalaryDim(); reportSalaryDim.setDimension(ReportDimensionEnum.MANAGER); reportSalaryDim.setUserId(manager.getStaffId()); reportSalaryDim.setUserName(manager.getStaffName()); - reportSalaryDim.setTotalReward(averageSalary); - reportSalaryDim.setKpiScoreRatio(kpiScoreRatio); + //计算平均值薪酬的额外项 + extCalcAverage(userDims, managerStaffDimReportIds, reportSalaryDim); reportSalaryDim.setDataDate(date); reportSalaryDim.setReportSalaryId(reportSalaryId); if (managerMap.containsKey(manager.getStaffId())) { @@ -550,7 +689,22 @@ public class SalaryReportTask { return userGroupIndicatorHitMap; } - + /** + * 这个薪酬详情每天6:00 会计算完成,cn.fw.morax.server.task.SalaryCalcTask#cacheCalculableKpiGroup() + * @param date + * @param pools + * @return <薪酬池id: 薪酬池详情list> + */ + private Map> getSalaryPoolDetailMap(LocalDate date, List pools) { + if (CollectionUtils.isEmpty(pools)){ + return Collections.emptyMap(); + } + List salaryPoolDetailList = salaryPoolDetailService.list(Wrappers.lambdaQuery() + .in(SalaryPoolDetail::getSalaryPoolId, pools.stream().map(SalaryPool::getId).collect(Collectors.toSet())) + .eq(SalaryPoolDetail::getSalaryDate, date) + .eq(SalaryPoolDetail::getYn, Boolean.TRUE)); + return salaryPoolDetailList.stream().collect(Collectors.groupingBy(SalaryPoolDetail::getSalaryPoolId)); + } public Map queryUserTargetValue(Long referId, Long userId, LocalDate dataDate) { List targetHitLogs = salaryGroupProjectTargetHitLogService.list(Wrappers.lambdaQuery() @@ -701,7 +855,8 @@ public class SalaryReportTask { projectBO.setCodeType(codeType); break; } - case FIXATION: CAR_SERIES: { + case FIXATION: + case CAR_SERIES: { projectBO.setCode(project.getCommissionCode()); projectBO.setCodeType(IndicatorCodeTypeEnum.COMBINE_INDICATOR); break; @@ -721,7 +876,7 @@ public class SalaryReportTask { return projects; } - public ReportSalaryDim saveStaffDim(SalaryPool pool, LocalDate date, Long reportSalaryRankId){ + public ReportSalaryDim saveStaffDim(SalaryPool pool, LocalDate date, Long reportSalaryRankId,List salaryPoolDetails){ ReportSalaryDim reportSalaryDim = new ReportSalaryDim(); reportSalaryDim.setDimension(ReportDimensionEnum.STAFF); reportSalaryDim.setReferId(pool.getUserId()); @@ -735,14 +890,32 @@ public class SalaryReportTask { 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)); // } + //薪资类型相关项目处理 + extCaleUserMoney(salaryPoolDetails, reportSalaryDim); reportSalaryDimService.save(reportSalaryDim); return reportSalaryDim; } + /** + * 获取 SalaryTypeEnum 对应的薪酬总值 + * @param salaryTypeEnumListMap + * @param salaryTypeEnum + * @return + */ + private BigDecimal getSalaryTypeEnumMoney(Map> salaryTypeEnumListMap,SalaryTypeEnum salaryTypeEnum){ + if (CollectionUtils.isEmpty(salaryTypeEnumListMap)){ + return BigDecimal.ZERO; + } + List list = salaryTypeEnumListMap.get(salaryTypeEnum); + if (CollectionUtils.isEmpty(list)){ + return BigDecimal.ZERO; + } + return list.stream().filter(Objects::nonNull).map(SalaryPoolDetail::getSalaryAmount).reduce(BigDecimal.ZERO, BigDecimal::add); + } + } -- libgit2 0.22.2