Commit 2af7f4442a8991b981c4e62989bb6dd4bb1ba6c8

Authored by 姜超
2 parents 25fb9737 c5e255e6

Merge branch 'bug-fix' into 'main'

Bug fix



See merge request !596
fw-morax-domain/src/main/java/cn/fw/morax/domain/enums/ExtraSalarySubTypeEnum.java
... ... @@ -40,6 +40,7 @@ public enum ExtraSalarySubTypeEnum implements IEnum<Integer> {
40 40 DISABILITY(44, "残障补贴"),
41 41 OVERSEAS(45, "驻外补贴"),
42 42 TEMPORARY_MEAL(46, "临时餐补"),
  43 + NIGHT_SHIFT(47, "晚班补贴"),
43 44 EVAL_SHOP_ROLE_REWARD(60, "考评门店角色奖励"),
44 45 EVAL_SHOP_ROLE_PUNISH(61, "考评门店角色惩罚"),
45 46 EVAL_SHOP_REWARD_DIST(62, "考评门店奖惩分配"),
... ...
fw-morax-rpc/src/main/java/cn/fw/morax/rpc/ehr/EhrRpcService.java
... ... @@ -393,7 +393,7 @@ public class EhrRpcService {
393 393 * @return
394 394 */
395 395 public List<PerformanceStaffDTO> queryKpiStaff(Long groupId, Long postId, List<Long> shopIds, LocalDate date) {
396   - return this.queryKpiStaffByName(groupId, Lists.newArrayList(postId), shopIds, null, date);
  396 + return this.getPointTimeStaffs(groupId, Lists.newArrayList(postId), shopIds, null, date);
397 397 }
398 398  
399 399 /**
... ... @@ -404,7 +404,7 @@ public class EhrRpcService {
404 404 * @return
405 405 */
406 406 public List<PerformanceStaffDTO> queryKpiStaff(Long groupId, List<Long> postIds, List<Long> shopIds, LocalDate date) {
407   - return this.queryKpiStaffByName(groupId, postIds, shopIds, null, date);
  407 + return this.getPointTimeStaffs(groupId, postIds, shopIds, null, date);
408 408 }
409 409  
410 410 /**
... ... @@ -416,7 +416,7 @@ public class EhrRpcService {
416 416 */
417 417 @Nullable
418 418 public List<PerformanceStaffDTO> queryRealTimeKpiStaff(Long groupId, Long postId, List<Long> shopIds, String staffName) {
419   - return this.queryKpiStaffByName(groupId, Lists.newArrayList(postId), shopIds, staffName, LocalDate.now());
  419 + return this.getPointTimeStaffs(groupId, Lists.newArrayList(postId), shopIds, staffName, LocalDate.now());
420 420 }
421 421  
422 422 /**
... ... @@ -450,6 +450,81 @@ public class EhrRpcService {
450 450 return new ArrayList<>();
451 451 }
452 452  
  453 + /**
  454 + * 获取某一时间点集团人员简要信息
  455 + * <span>
  456 + * 张三: 3-1 A门店 A岗位
  457 + * 3-5 调至B门店 B岗位
  458 + * 3-10 离职
  459 + * pointTime: 3-2、3-5 返回张三 A门店 A岗位;
  460 + * 3-6、3-10 返回张三 B门店 B岗位;
  461 + * 3-11 不会返回张三
  462 + */
  463 + @Nullable
  464 + public List<PerformanceStaffDTO> getPointTimeStaffs(Long groupId, List<Long> postIds, List<Long> shopIds, String staffName, LocalDate date) {
  465 + if (PublicUtil.isEmpty(groupId) || PublicUtil.isEmpty(postIds) ||
  466 + PublicUtil.isEmpty(shopIds) || PublicUtil.isEmpty(date)) {
  467 + return new ArrayList<>();
  468 + }
  469 + Date queryDate = DateUtil.localDateTime2Date(date.atTime(00, 00, 00));
  470 + Long queryDateTime = queryDate.getTime();
  471 + try {
  472 + log.info("StaffApi.getStaffByPostShopList: 开始进行请求。groupId:[{}],queryDate:[{}],time:[{}] ",
  473 + groupId, queryDate, queryDateTime);
  474 + final Message<List<StaffSimpleInfoVo>> msg = staffApi.getPointTimeStaffList(groupId, queryDate.getTime());
  475 + log.info("StaffApi.getPointTimeStaffList: groupId:[{}],queryDate:[{}],time:[{}], msg.code={}, msg.result={}, msg.data={}",
  476 + groupId, queryDate, queryDateTime, msg.getCode(), JSON.toJSONString(msg.getResult()), JSON.toJSONString(msg.getData()));
  477 + if (msg.isSuccess() && !Objects.isNull(msg.getData())) {
  478 + return getSimplePerformanceStaffDTOS(staffName, msg, postIds , shopIds);
  479 + }
  480 + } catch (Exception e) {
  481 + log.error("获取人员信息失败:", e);
  482 + }
  483 + return new ArrayList<>();
  484 + }
  485 +
  486 + private List<PerformanceStaffDTO> getSimplePerformanceStaffDTOS(String staffName, Message<List<StaffSimpleInfoVo>> msg, List<Long> postIds , List<Long> shopIds) {
  487 + List<PerformanceStaffDTO> staffDTOS = new ArrayList<>(msg.getData().size());
  488 + PerformanceStaffDTO staffDTO = null;
  489 + for (StaffSimpleInfoVo staffVo : msg.getData()) {
  490 + //判断岗位、门店
  491 + if (! postIds.contains(staffVo.getPostId()) || (! shopIds.contains(staffVo.getShopId()))) {
  492 + continue;
  493 + }
  494 + if (PublicUtil.isNotEmpty(staffName) && (! staffVo.getStaffName().contains(staffName))) {
  495 + continue;
  496 + }
  497 + staffDTO = PublicUtil.copy(staffVo, PerformanceStaffDTO.class);
  498 + staffDTO.setId(Optional.ofNullable(staffVo.getStaffId()).orElse(-1L));
  499 + staffDTO.setName(Optional.ofNullable(staffVo.getStaffName()).orElse(""));
  500 + ZoneId zoneId = ZoneId.systemDefault();
  501 + if (PublicUtil.isNotEmpty(staffVo.getEntryDate())) {
  502 + staffDTO.setEntryDate(staffVo.getEntryDate().toInstant().atZone(zoneId).toLocalDate());
  503 + }
  504 + if (PublicUtil.isNotEmpty(staffVo.getRegularDate())) {
  505 + staffDTO.setRegularDate(staffVo.getRegularDate().toInstant().atZone(zoneId).toLocalDate());
  506 + }
  507 + if (PublicUtil.isNotEmpty(staffVo.getLeaveDate())) {
  508 + staffDTO.setLeaveDate(DateUtil.date2LocalDate(staffVo.getLeaveDate()));
  509 + }
  510 + staffDTO.setStaffStatus(staffVo.getStaffStatus());
  511 + //原来员工状态 (针对离职员工之前的状态,未离职的就是当前状态一致)
  512 + staffDTO.setOriginStaffStatus(staffVo.getStaffStatus());
  513 + //判断离职员工
  514 + if (StaffStatusEnum.DUTY_OFF.getValue().equals(staffVo.getStaffStatus()) ||
  515 + StaffStatusEnum.LEAVE.getValue().equals(staffVo.getStaffStatus())) {
  516 + //试用期员工 转正时间为空。是否是试用期员工,并修改原始状态
  517 + if (PublicUtil.isEmpty(staffVo.getRegularDate())) {
  518 + staffDTO.setOriginStaffStatus(StaffStatusEnum.PROBATION.getValue());
  519 + } else {
  520 + staffDTO.setOriginStaffStatus(StaffStatusEnum.REGULAR.getValue());
  521 + }
  522 + }
  523 + staffDTOS.add(staffDTO);
  524 + }
  525 + return staffDTOS;
  526 + }
  527 +
453 528 private List<PerformanceStaffDTO> getPerformanceStaffDTOS(String staffName, Message<List<StaffBaseInfo>> msg) {
454 529 List<PerformanceStaffDTO> staffDTOS = new ArrayList<>(msg.getData().size());
455 530 PerformanceStaffDTO staffDTO = null;
... ...
fw-morax-sdk/src/main/java/cn/fw/morax/sdk/dto/common/SalaryExtraProjectSubTypeEnum.java
... ... @@ -22,6 +22,7 @@ public enum SalaryExtraProjectSubTypeEnum {
22 22 DISABILITY(44, "残障补贴"),
23 23 OVERSEAS(45, "驻外补贴"),
24 24 TEMPORARY_MEAL(46, "临时餐补"),
  25 + NIGHT_SHIFT(47, "晚班补贴"),
25 26 SOCIAL_SECURITY(300, "社保"),
26 27 MEDICAL_INSURANCE(301, "医保"),
27 28 ACCUMULATION_FUND(302, "公积金"),
... ...
fw-morax-server/src/main/java/cn/fw/morax/server/task/EvalUserReportTask.java
... ... @@ -427,6 +427,10 @@ public class EvalUserReportTask {
427 427 } else {
428 428 indicatorValue = commonService.queryMonthValue(userId, scopeType, dataDate, param.getCodeType(), param.getCode());
429 429 }
  430 + //计算目标
  431 + if (!TargetTypeEnum.NO.equals(targetType)) {
  432 + indicatorValue = this.calculateTargetValue(param.getTargetCalcType(), param.getTargetValue(), indicatorValue, param.getMinimumStandardValue());
  433 + }
430 434 boolean isCap = Boolean.TRUE.equals(param.getCap());
431 435 BigDecimal proportion = param.getProportion();
432 436 if (isCap) {
... ... @@ -453,6 +457,35 @@ public class EvalUserReportTask {
453 457 }
454 458  
455 459 /**
  460 + * 经过目标计算后的用户指标值
  461 + *
  462 + * @param targetCalcType
  463 + * @param targetValue
  464 + * @param userValue
  465 + * @return
  466 + */
  467 + protected BigDecimal calculateTargetValue(TargetCalcTypeEnum targetCalcType, BigDecimal targetValue,
  468 + BigDecimal userValue, BigDecimal minimumStandardValue) {
  469 + if (Objects.isNull(targetValue) || targetValue.compareTo(BigDecimal.ZERO) <= 0) {
  470 + return userValue;
  471 + }
  472 + if (TargetCalcTypeEnum.TARGET_VALUE.equals(targetCalcType)) {
  473 + return userValue.divide(targetValue, 4, RoundingMode.HALF_UP);
  474 + }
  475 + //最低目标计算方式 高线要求
  476 + BigDecimal diffValue = Optional.ofNullable(minimumStandardValue).orElse(BigDecimal.ONE).subtract(targetValue);
  477 +// BigDecimal diffValue = BigDecimal.ONE.subtract(targetValue);
  478 + BigDecimal userDiffValue = userValue.subtract(targetValue);
  479 + if (userDiffValue.compareTo(BigDecimal.ZERO) <= 0) {
  480 + return BigDecimal.ZERO;
  481 + }
  482 + if (diffValue.compareTo(BigDecimal.ZERO) <= 0) {
  483 + return userDiffValue;
  484 + }
  485 + return userDiffValue.divide(diffValue, 4, RoundingMode.HALF_UP);
  486 + }
  487 +
  488 + /**
456 489 * 人员得分情况
457 490 */
458 491 public MultiKeyMap<Long, BigDecimal> getUserIndicatorScoreMap(List<EvalGroupIndicator> evalGroupIndicators, LocalDate date, List<EvalUserPool> userPools) {
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/CommonService.java
... ... @@ -1128,6 +1128,10 @@ public class CommonService {
1128 1128 if (PublicUtil.isNotEmpty(fundShop)) {
1129 1129 return fundShop;
1130 1130 }
  1131 + fundShop = filterShop(staffShops, StaffShopTypeEnum.LEAVE_SHOP);
  1132 + if (PublicUtil.isNotEmpty(fundShop)) {
  1133 + return fundShop;
  1134 + }
1131 1135 fundShop = filterShop(staffShops, StaffShopTypeEnum.ENTRY_SHOP);
1132 1136 if (PublicUtil.isNotEmpty(fundShop)) {
1133 1137 return fundShop;
... ... @@ -1160,6 +1164,7 @@ public class CommonService {
1160 1164 * 离职配置对比,放最后,优先级最高,可覆盖前面的不考核情况
1161 1165 * 仅 覆盖那种 '正式员工离职' 的,因为试用期员工本来就不考核绩效,没必要进行覆盖
1162 1166 */
  1167 + //离职不考核: 转正员工,离职日期大于等于计算日期
1163 1168 LeaveStaffKpiSalaryConfigDTO config = reqDTO.getConfig();
1164 1169 if (Objects.nonNull(config)
1165 1170 && StaffStatusEnum.REGULAR.getValue().equals(originStaffStatus)
... ... @@ -1341,6 +1346,213 @@ public class CommonService {
1341 1346 }
1342 1347  
1343 1348 /**
  1349 + * 判断是否纳入绩效考核
  1350 + * 当月申请参与绩效考核 保护期标签取消
  1351 + * 1. 试用期不计算绩效
  1352 + * 2. 转正时间15号之后
  1353 + * 3. 转正两个月保护期
  1354 + * 4. 15号以后调岗不计算绩效
  1355 + * 5. 15号之前调岗 原岗位不计算绩效 新岗位计算绩效
  1356 + * 6. 绩效组变动不足完整2个月 绩效开始时间为获得岗位的两个月后
  1357 + * 7. 主动申请不考核绩效
  1358 + * 8. 待岗结束两个月期间
  1359 + * 9. 15号以前离职(正式员工)不计入绩效考核
  1360 + * 10. 请假天数 大于 配置不纳入绩效考核
  1361 + */
  1362 + public IgnoreCauseDTO findStageIgnoreCauseDTO(PerformanceStaffDTO staff, IgnoreCauseReqDTO reqDTO){
  1363 + IgnoreCauseDTO ignoreCauseDTO = new IgnoreCauseDTO();
  1364 + final Long userId = staff.getId();
  1365 + final LocalDate calcDate = reqDTO.getCurrentTime();
  1366 + //用原来员工状态(离职了就是离职前的状态,未离职就是当前自身状态)
  1367 + final Integer originStaffStatus = staff.getOriginStaffStatus();
  1368 +
  1369 + /**
  1370 + * 离职配置对比,放最后,优先级最高,可覆盖前面的不考核情况
  1371 + * 仅 覆盖那种 '正式员工离职' 的,因为试用期员工本来就不考核绩效,没必要进行覆盖
  1372 + */
  1373 + //离职不考核: 转正员工,离职日期大于等于计算日期
  1374 + LeaveStaffKpiSalaryConfigDTO config = reqDTO.getConfig();
  1375 + if (Objects.nonNull(config)
  1376 + && StaffStatusEnum.REGULAR.getValue().equals(originStaffStatus)
  1377 + && Objects.nonNull(staff.getStaffStatus())
  1378 + && Objects.nonNull(staff.getLeaveDate())
  1379 + && staff.getStaffStatus() == 9
  1380 + && calcDate.compareTo(staff.getLeaveDate()) >= 0){
  1381 + if (staff.getLeaveDate().compareTo(config.getKpiRankThresholdLocalDate()) < 0){
  1382 + //离职离得早-不考核绩效-因为会拉低整个绩效组的考核情况
  1383 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.LEAVE_DATE_BEFORE_15);
  1384 + //随便设置一个时间,占个位,怕那个地方取他报错,反正他也离职了,下个月不会有他的数据了
  1385 + ignoreCauseDTO.setStartKpiDate(calcDate.with(TemporalAdjusters.lastDayOfMonth()).plusDays(1));
  1386 + ignoreCauseDTO.setIgnoreCauseDesc(String.join("",config.getKpiRankThresholdLocalDate().getDayOfMonth()+"","号以前离职不计入绩效考核"));
  1387 + ignoreCauseDTO.setIgnoreConfig(config.getKpiRankThresholdDay().toString());
  1388 + }
  1389 + }
  1390 +
  1391 + //当月申请参与绩效考核 保护期标签取消
  1392 + Boolean curMonthlyApplyStartKpi = this.curMonthlyApplyStartKpi(userId, YearMonth.from(calcDate));
  1393 + if (Boolean.TRUE.equals(curMonthlyApplyStartKpi)) {
  1394 + return ignoreCauseDTO;
  1395 + }
  1396 +
  1397 + //试用期不计算绩效 绩效开始时间为试用期转正的两个月后
  1398 + if (StaffStatusEnum.PROBATION.getValue().equals(originStaffStatus)) {
  1399 + LocalDate startKpiDate = PublicUtil.getKpiDateOfProbationStaff(PublicUtil.isNotEmpty(staff.getEntryDate()) ? staff.getEntryDate() : LocalDate.now());
  1400 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.PROBATION);
  1401 + ignoreCauseDTO.setStartKpiDate(startKpiDate);
  1402 + }
  1403 +
  1404 + //转正是否计算绩效判断
  1405 + if (StaffStatusEnum.REGULAR.getValue().equals(originStaffStatus)) {
  1406 + //转正日期
  1407 + final LocalDate regularDate = PublicUtil.isNotEmpty(staff.getRegularDate()) ? staff.getRegularDate() : staff.getEntryDate();
  1408 + final Integer regularDay = regularDate.getDayOfMonth();
  1409 + //转正当月是否纳入绩效考核,日期在当月X之后,次月参与绩效考核
  1410 + final Boolean regularMonthlyIgnoreKpi = regularDay.compareTo(reqDTO.getRegularOneDicValue().intValue()) > 0;
  1411 + //计算日期是否是当月
  1412 + final Boolean curMonthRegular = YearMonth.from(regularDate).compareTo(YearMonth.from(calcDate)) == 0;
  1413 + //当月太晚转正不纳入绩效考核(15号之后,不含15号转正,不纳入绩效考核)(不需要参与人员质量评测。转正保护期需要参与人员质量评测)
  1414 + if (Boolean.TRUE.equals(regularMonthlyIgnoreKpi) && Boolean.TRUE.equals(curMonthRegular)) {
  1415 + LocalDate newStartKpiDate = regularDate.plusMonths(1).with(TemporalAdjusters.firstDayOfMonth());
  1416 + if (this.checkNewStartKpiDateValid(ignoreCauseDTO.getStartKpiDate(), newStartKpiDate, calcDate)) {
  1417 + String regularDayStr = reqDTO.getRegularOneDicValue().stripTrailingZeros().toPlainString();
  1418 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.POSITIVE_AFTER_15);
  1419 + ignoreCauseDTO.setStartKpiDate(newStartKpiDate);
  1420 + ignoreCauseDTO.setIgnoreCauseDesc(String.join("",regularDayStr+"","号以后转正不计算绩效"));
  1421 + ignoreCauseDTO.setIgnoreConfig(regularDayStr);
  1422 + }
  1423 + //再判断 转正保护期
  1424 + } else {
  1425 + Integer regularProtectionMonth = kpiDictBizService.getProtectionMonth(staff.getPostId(), staff.getShopId(),reqDTO.getRegularProtectionMultiMap());
  1426 + if (Objects.nonNull(regularProtectionMonth) && regularProtectionMonth > 0){
  1427 + //有设定保护期,比如销售需要各种培训才能上岗需要保护加持 (当月转正不纳入绩效考核,保护期加一个月)
  1428 + LocalDate newStartKpiDate = this.getNewStartKpiDate(regularDate, regularMonthlyIgnoreKpi, regularProtectionMonth);
  1429 + if (this.checkNewStartKpiDateValid(ignoreCauseDTO.getStartKpiDate(), newStartKpiDate, calcDate)) {
  1430 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.TURN_POSITIVE_AFTER);
  1431 + ignoreCauseDTO.setStartKpiDate(newStartKpiDate);
  1432 + ignoreCauseDTO.setIgnoreConfig(regularProtectionMonth.toString());
  1433 + }
  1434 + }
  1435 + }
  1436 + }
  1437 +
  1438 + //15号以后调岗不计算绩效
  1439 +// LocalDate transPostDate = getTransPostDate(userId);
  1440 +// if (PublicUtil.isNotEmpty(transPostDate)) {
  1441 +// //当月调岗时间分界点
  1442 +// LocalDate transpostLocalDate = kpiDictBizService.getTranspostLocalDate(reqDTO.getAfterTransPostIgnoreKpi(), transPostDate);
  1443 +// Boolean afterDateAfter = transPostDate.isAfter(transpostLocalDate);
  1444 +// LocalDate newStartKpiDate = getNewStartKpiDate(transPostDate, afterDateAfter, 0);
  1445 +// if (this.checkNewStartKpiDateValid(ignoreCauseDTO.getStartKpiDate(), newStartKpiDate, reqDTO.getCurrentTime())) {
  1446 +// ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.TRANSPOST_AFTER_15);
  1447 +// ignoreCauseDTO.setStartKpiDate(newStartKpiDate);
  1448 +// ignoreCauseDTO.setIgnoreCauseDesc(String.join("",transpostLocalDate.getDayOfMonth()+"","号以后调岗不计算绩效"));
  1449 +// ignoreCauseDTO.setIgnoreConfig(reqDTO.getAfterTransPostIgnoreKpi().stripTrailingZeros().toPlainString());
  1450 +// }
  1451 +// }
  1452 +
  1453 + //15号之前调岗 原岗位不计算绩效 新岗位计算绩效
  1454 + LocalDate changePostDate = this.getOldPostChangeDate(userId, staff.getPostId(), staff.getShopId());
  1455 + if (PublicUtil.isNotEmpty(changePostDate) && calcDate.compareTo(changePostDate) >= 0) {
  1456 + LocalDate beforeTransferIgnoreKpiDate = kpiDictBizService.getTranspostLocalDate(reqDTO.getBeforeTransPostIgnoreKpi(), changePostDate);
  1457 + if (changePostDate.isBefore(beforeTransferIgnoreKpiDate)) {
  1458 + //这个岗位开始计算绩效时间,下个月1号
  1459 + LocalDate newStartKpiDate = YearMonth.from(changePostDate).plusMonths(1).atDay(1);
  1460 + //判断配置日期
  1461 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.TRANSPOST_BEFORE_15);
  1462 + ignoreCauseDTO.setStartKpiDate(newStartKpiDate);
  1463 + ignoreCauseDTO.setIgnoreCauseDesc(String.join("",beforeTransferIgnoreKpiDate.getDayOfMonth()+"","号之前调岗不计算绩效"));
  1464 + ignoreCauseDTO.setIgnoreConfig(reqDTO.getBeforeTransPostIgnoreKpi().stripTrailingZeros().toPlainString());
  1465 + }
  1466 + }
  1467 +
  1468 + //15号之前调岗(不包含) 新岗位当月参与绩效考核,旧岗位当月不参与绩效考核
  1469 +// LocalDate oldPostStartKpiDate = this.getOldPostStartKpiDate(userId, staff.getPostId(), staff.getShopId());
  1470 +// if (PublicUtil.isNotEmpty(oldPostStartKpiDate) && oldPostStartKpiDate.compareTo(calcDate) > 0) {
  1471 +// ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.TRANSPOST_BEFORE_15);
  1472 +// ignoreCauseDTO.setStartKpiDate(oldPostStartKpiDate);
  1473 +// ignoreCauseDTO.setIgnoreCauseDesc(String.join("",reqDTO.getBeforeTransPostIgnoreKpi().intValue()+"","号之前调岗不计算绩效"));
  1474 +// ignoreCauseDTO.setIgnoreConfig(reqDTO.getBeforeTransPostIgnoreKpi().stripTrailingZeros().toPlainString());
  1475 +// }
  1476 +
  1477 + //调岗保护期(15号之后调岗 优先)(非降级)
  1478 + LocalDate newPostChangeDate = this.getStaffNonDemotionNewPostChangeDate(userId, staff.getPostId(), staff.getShopId());
  1479 + final LocalDate newPostStartKpiDate = this.getNewPostStartKpiDate(userId, staff.getPostId(), staff.getShopId());
  1480 + final Integer transPostProtectionMonth = kpiDictBizService.getProtectionMonth(staff.getPostId(), staff.getShopId(), reqDTO.getTransPostProtectionMultiMap());
  1481 + if (PublicUtil.isNotEmpty(newPostChangeDate) && PublicUtil.isNotEmpty(transPostProtectionMonth) && transPostProtectionMonth > 0 ){
  1482 + //当月调岗不纳入绩效考核,保护期加一个月
  1483 + Boolean addOneMonthTransPostProtection = PublicUtil.isNotEmpty(newPostStartKpiDate);
  1484 + LocalDate newStartKpiDate = this.getNewStartKpiDate(newPostChangeDate, addOneMonthTransPostProtection, transPostProtectionMonth);
  1485 + if (this.checkNewStartKpiDateValid(ignoreCauseDTO.getStartKpiDate(), newStartKpiDate, calcDate)) {
  1486 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.TURN_POSITIVE_POSITION);
  1487 + ignoreCauseDTO.setStartKpiDate(newStartKpiDate);
  1488 + ignoreCauseDTO.setIgnoreConfig(transPostProtectionMonth.toString());
  1489 + }
  1490 + }
  1491 +
  1492 + //todo 新版本,启用一段时间注释之前逻辑
  1493 + //15号之后调岗(包含) 新岗位次月参与绩效考核,旧岗位当月参与绩效考核
  1494 + if (PublicUtil.isNotEmpty(newPostStartKpiDate) && newPostStartKpiDate.compareTo(calcDate) > 0) {
  1495 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.TRANSPOST_AFTER_15);
  1496 + ignoreCauseDTO.setStartKpiDate(newPostStartKpiDate);
  1497 + ignoreCauseDTO.setIgnoreCauseDesc(String.join("",reqDTO.getAfterTransPostIgnoreKpi().intValue()+"","号以后调岗不计算绩效"));
  1498 + ignoreCauseDTO.setIgnoreConfig(reqDTO.getAfterTransPostIgnoreKpi().stripTrailingZeros().toPlainString());
  1499 + }
  1500 +
  1501 + //绩效组变动不足完整2个月 绩效开始时间为获得岗位的两个月后
  1502 + LocalDate postChangeStartKpiDate = this.getStartKpiDate(userId);
  1503 + if (PublicUtil.isNotEmpty(postChangeStartKpiDate)) {
  1504 + if (this.checkNewStartKpiDateValid(ignoreCauseDTO.getStartKpiDate(), postChangeStartKpiDate, reqDTO.getCurrentTime())) {
  1505 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.TRANSFER_NEW_POSITION_AFTER);
  1506 + ignoreCauseDTO.setStartKpiDate(postChangeStartKpiDate);
  1507 + }
  1508 + }
  1509 +
  1510 + //主动申请不考核绩效 绩效开始时间为设置的申请开始绩效考核时间
  1511 + if (CollectionUtils.isNotEmpty(reqDTO.getUserRuleMap())){
  1512 + KpiStarSpecialRule specialRule = reqDTO.getUserRuleMap().get(userId);
  1513 + //开始考核日期,其实这个人在当前是考核绩效的,已经有星级数据了
  1514 + if (PublicUtil.isNotEmpty(specialRule) && PublicUtil.isNotEmpty(specialRule.getEarliestStartingMonthly())) {
  1515 + LocalDate newStartKpiDate = specialRule.getEarliestStartingMonthly();
  1516 + //当前时间在开始考核时间之之前 审批通过后,前面月份的绩效不纳入后续计算
  1517 + if (this.checkNewStartKpiDateValid(ignoreCauseDTO.getStartKpiDate(), newStartKpiDate, reqDTO.getCurrentTime())) {
  1518 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.APPLY_NO_ASSESSMENT);
  1519 + ignoreCauseDTO.setStartKpiDate(newStartKpiDate);
  1520 + }
  1521 + }
  1522 + }
  1523 +
  1524 + //待岗期间
  1525 + if (PublicUtil.isNotEmpty(staff.getAwaitJob()) && staff.getAwaitJob()) {
  1526 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.AWAIT_JOB_DURATION);
  1527 + //@todo 人事系统待岗中人员没有待岗结束时间
  1528 + ignoreCauseDTO.setStartKpiDate(null);
  1529 + }
  1530 +
  1531 + //待岗结束两个月期间
  1532 + LocalDate afterAwaitJobStartKpiDate = this.getAfterAwaitJobStartKpiDate(userId);
  1533 + if (PublicUtil.isNotEmpty(afterAwaitJobStartKpiDate) ) {
  1534 + if (this.checkNewStartKpiDateValid(ignoreCauseDTO.getStartKpiDate(), afterAwaitJobStartKpiDate, reqDTO.getCurrentTime())) {
  1535 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.AWAIT_JOB_AFTER);
  1536 + ignoreCauseDTO.setStartKpiDate(afterAwaitJobStartKpiDate);
  1537 + }
  1538 + }
  1539 +
  1540 + //请假天数 大于 配置不纳入绩效考核
  1541 + if (PublicUtil.isEmpty(ignoreCauseDTO.getIgnoreCauseEnum())) {
  1542 + BigDecimal leaveDays = staffLeaveSummaryService.getLeaveDays(userId, YearMonth.from(calcDate));
  1543 + if (leaveDays.compareTo(reqDTO.getLeaveIgnoreKpiDays()) >= 0) {
  1544 + ignoreCauseDTO.setIgnoreCauseEnum(KpiIgnoreCauseEnum.LEAVE_DAY_OVERLENGTH_IGNORE_KPI);
  1545 + ignoreCauseDTO.setStartKpiDate(YearMonth.from(reqDTO.getCurrentTime()).plusMonths(1).atDay(1));
  1546 + ignoreCauseDTO.setIgnoreCauseDesc("请假超过" + reqDTO.getLeaveIgnoreKpiDays().intValue() + "天不计入绩效考核");
  1547 + ignoreCauseDTO.setIgnoreConfig(reqDTO.getLeaveIgnoreKpiDays().stripTrailingZeros().toPlainString());
  1548 + }
  1549 + }
  1550 +
  1551 + return ignoreCauseDTO;
  1552 + }
  1553 +
  1554 +
  1555 + /**
1344 1556 * 当月申请参与绩效考核
1345 1557 */
1346 1558 public Boolean curMonthlyApplyStartKpi(Long userId, YearMonth monthly) {
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/eval/EvalGroupUserBizService.java
... ... @@ -81,11 +81,13 @@ public class EvalGroupUserBizService {
81 81 user.setEvalGroupRankStageId(evalGroup.getEvalGroupRankStageId());
82 82 user.setEvalGroupId(evalGroup.getId());
83 83 user.setEgc(evalGroup.getEgc());
84   - //如果忽略 更新表数据
  84 + //阶段按照时间范围计算,25号离职不参与考评,1-10,11-20号继续参与考评计算 13号调岗
85 85 if (Boolean.TRUE.equals(user.getIgnored())) {
86 86 //不纳入绩效后,当月整个考评排名组的考评池设置为不参与绩效考核(张三 2月20号申请次月参与考核,20号之前的所有阶段 设置不参与绩效考核)
87 87 List<EvalUserPool> pools = evalUserPoolService.list(Wrappers.<EvalUserPool>lambdaQuery()
88   - .eq(EvalUserPool::getEvalGroupRankId, user.getEvalGroupRankId())
  88 + .eq(EvalUserPool::getEvalGroupRankStageId, user.getEvalGroupRankStageId())
  89 + //之前更新整个考评
  90 +// .eq(EvalUserPool::getEvalGroupRankId, user.getEvalGroupRankId())
89 91 .eq(EvalUserPool::getMonthly, YearMonth.from(localDate))
90 92 .eq(EvalUserPool::getUserId, user.getUserId())
91 93 .eq(EvalUserPool::getInclusion, Boolean.TRUE)
... ... @@ -190,7 +192,7 @@ public class EvalGroupUserBizService {
190 192 public void handleStaffKpi(PerformanceStaffDTO staff, EvalGroupUser evalUser, IgnoreCauseReqDTO rejectCauseReq) {
191 193 try {
192 194 //获取忽略绩效理由
193   - IgnoreCauseDTO ignoreCauseDTO = commonService.findIgnoreCauseDTO(staff, rejectCauseReq);
  195 + IgnoreCauseDTO ignoreCauseDTO = commonService.findStageIgnoreCauseDTO(staff, rejectCauseReq);
194 196  
195 197 if (PublicUtil.isNotEmpty(ignoreCauseDTO.getIgnoreCauseEnum())) {
196 198 this.handleIgnoredKpiGroupUser(evalUser, ignoreCauseDTO);
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/kpi/KpiCacheService.java
... ... @@ -10,7 +10,9 @@ import cn.fw.morax.domain.db.kpi.*;
10 10 import cn.fw.morax.domain.enums.KpiCalcProcessStatusEnum;
11 11 import cn.fw.morax.domain.enums.KpiCalcStatusEnum;
12 12 import cn.fw.morax.rpc.ehr.EhrRpcService;
  13 +import cn.fw.morax.rpc.ehr.dto.PostInfoDTO;
13 14 import cn.fw.morax.rpc.erp.ErpRpcService;
  15 +import cn.fw.morax.rpc.erp.dto.RoleInfoDTO;
14 16 import cn.fw.morax.rpc.erp.dto.UserAuthRangeDTO;
15 17 import cn.fw.morax.rpc.oop.OopRpcService;
16 18 import cn.fw.morax.rpc.oop.dto.GroupDTO;
... ... @@ -22,6 +24,7 @@ import com.alibaba.fastjson.JSONObject;
22 24 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
23 25 import lombok.RequiredArgsConstructor;
24 26 import lombok.extern.slf4j.Slf4j;
  27 +import org.apache.commons.collections.CollectionUtils;
25 28 import org.redisson.api.RLock;
26 29 import org.springframework.data.redis.core.StringRedisTemplate;
27 30 import org.springframework.stereotype.Service;
... ... @@ -43,6 +46,7 @@ public class KpiCacheService {
43 46  
44 47 private KpiAssessPenaltyStaffService kpiAssessPenaltyStaffService;
45 48 private KpiAssessPenaltyService kpiAssessPenaltyService;
  49 + private KpiAssessDetailService kpiAssessDetailService;
46 50 private KpiCalcProcessService kpiCalcProcessService;
47 51 private KpiGroupRankService kpiGroupRankService;
48 52 private StringRedisTemplate stringRedisTemplate;
... ... @@ -53,6 +57,7 @@ public class KpiCacheService {
53 57 private KpiCalcService kpiCalcService;
54 58 private OopRpcService oopRpcService;
55 59 private ErpRpcService erpRpcService;
  60 + private EhrRpcService ehrRpcService;
56 61 private RoleVal roleVal;
57 62 private KpiVal kpiVal;
58 63 private Map<KpiCalcProcessStatusEnum, KpiCalcProcessStrategy> processCalcMap;
... ... @@ -60,6 +65,7 @@ public class KpiCacheService {
60 65 public KpiCacheService(final KpiAssessPenaltyStaffService kpiAssessPenaltyStaffService,
61 66 final KpiAssessPenaltyService kpiAssessPenaltyService,
62 67 final KpiCalcProcessService kpiCalcProcessService,
  68 + final KpiAssessDetailService kpiAssessDetailService,
63 69 final KpiGroupRankService kpiGroupRankService,
64 70 final StringRedisTemplate stringRedisTemplate,
65 71 final DistributedLocker distributedLocker,
... ... @@ -69,12 +75,14 @@ public class KpiCacheService {
69 75 final KpiCalcService kpiCalcService,
70 76 final OopRpcService oopRpcService,
71 77 final ErpRpcService erpRpcService,
  78 + final EhrRpcService ehrRpcService,
72 79 final RoleVal roleVal,
73 80 final KpiVal kpiVal,
74 81 final List<KpiCalcProcessStrategy> kpiCalcProcessStrategies) {
75 82 this.kpiAssessPenaltyStaffService = kpiAssessPenaltyStaffService;
76 83 this.kpiAssessPenaltyService = kpiAssessPenaltyService;
77 84 this.kpiCalcProcessService = kpiCalcProcessService;
  85 + this.kpiAssessDetailService = kpiAssessDetailService;
78 86 this.kpiGroupRankService = kpiGroupRankService;
79 87 this.stringRedisTemplate = stringRedisTemplate;
80 88 this.distributedLocker = distributedLocker;
... ... @@ -84,6 +92,7 @@ public class KpiCacheService {
84 92 this.kpiCalcService = kpiCalcService;
85 93 this.oopRpcService = oopRpcService;
86 94 this.erpRpcService = erpRpcService;
  95 + this.ehrRpcService = ehrRpcService;
87 96 this.roleVal = roleVal;
88 97 this.kpiVal = kpiVal;
89 98 this.processCalcMap = kpiCalcProcessStrategies.stream().collect(Collectors.toMap(KpiCalcProcessStrategy::getStatus, v -> v));
... ... @@ -117,6 +126,8 @@ public class KpiCacheService {
117 126  
118 127 //删除人员质量评测重复数据
119 128 List<KpiAssess> kpiAssesses = kpiAssessService.getGroupConfigs(calcGroupId, calcDate, calcBackupAssess);
  129 + //要计算人员质量评测的管理岗位
  130 + Set<Long> managePostIds = this.getCalcKpiAssessManagePostIds(calcGroupId, kpiAssesses);
120 131 this.cleanRepeatPenalty(kpiAssesses, calcDate, calcBackupAssess);
121 132  
122 133 //人事绩效排名组
... ... @@ -136,17 +147,24 @@ public class KpiCacheService {
136 147 kpiCalc.setCalcBackupAssess(calcBackupAssess);
137 148 kpiCalc.setIgnoreExtraUser(ignoreExtraUser);
138 149 kpiCalcService.save(kpiCalc);
139   - if (PublicUtil.isNotEmpty(kpiAssesses)) {
140   - //分类
141   - if (hrKpiGroupRankIds.contains(kpiGroupRankId)) {
142   - hrKpiCalcs.add(kpiCalc);
143   - } else if (Boolean.TRUE.equals(calcAssess)) {
144   - assessKpiCalcs.add(kpiCalc);
145   - } else {
  150 + //人员质量评测为空 都归为
  151 + if (PublicUtil.isEmpty(kpiAssesses)) {
  152 + noAssessKpiCalcs.add(kpiCalc);
  153 + continue;
  154 + }
  155 + //人事绩效组
  156 + if (hrKpiGroupRankIds.contains(kpiGroupRankId)) {
  157 + hrKpiCalcs.add(kpiCalc);
  158 + continue;
  159 + }
  160 + //计算人员质量评测
  161 + if (Boolean.TRUE.equals(calcAssess)) {
  162 + assessKpiCalcs.add(kpiCalc);
  163 + //要计算人员质量评测的管理岗位 最终还需要再计算一次
  164 + if (CollectionUtils.containsAny(managePostIds, kpiGroupRank.getPostIds())) {
146 165 noAssessKpiCalcs.add(kpiCalc);
147 166 }
148 167 } else {
149   - //人员质量评测为空 都归为
150 168 noAssessKpiCalcs.add(kpiCalc);
151 169 }
152 170 }
... ... @@ -467,4 +485,30 @@ public class KpiCacheService {
467 485 }
468 486 }
469 487  
  488 + /**
  489 + * 获取要计算人员质量评测的管理岗位
  490 + */
  491 + public Set<Long> getCalcKpiAssessManagePostIds(Long groupId, List<KpiAssess> kpiAssesses) {
  492 + List<RoleInfoDTO> manageRoles = erpRpcService.manageRoles();
  493 + if (PublicUtil.isEmpty(manageRoles) || PublicUtil.isEmpty(kpiAssesses)) {
  494 + return new HashSet<>();
  495 + }
  496 + List<KpiAssessDetail> kpiAssessDetails = kpiAssessDetailService.list(Wrappers.<KpiAssessDetail>lambdaQuery()
  497 + .in(KpiAssessDetail::getKpiAssessId, kpiAssesses.stream().map(KpiAssess::getId).collect(Collectors.toSet()))
  498 + .eq(KpiAssessDetail::getYn, Boolean.TRUE)
  499 + );
  500 + Set<String> kpiAssessRoleCodes = kpiAssessDetails.stream().flatMap(detail -> detail.getRoleCodes().stream()).collect(Collectors.toSet());
  501 + Set<String> manageRoleCodes = manageRoles.stream().map(RoleInfoDTO::getRoleCode).collect(Collectors.toSet());
  502 +
  503 + List<PostInfoDTO> groupPostInfos = ehrRpcService.getGroupPosts(groupId);
  504 + Set<Long> calcKpiAssessManagePostIds = new HashSet<>();
  505 + for (PostInfoDTO postInfoDTO : groupPostInfos) {
  506 + //角色在 管理角色 人员质量考核角色 中
  507 + if (manageRoleCodes.contains(postInfoDTO.getRoleCode()) && kpiAssessRoleCodes.contains(postInfoDTO.getRoleCode())) {
  508 + calcKpiAssessManagePostIds.add(postInfoDTO.getId());
  509 + }
  510 + }
  511 + return calcKpiAssessManagePostIds;
  512 + }
  513 +
470 514 }
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/kpi/KpiPoolBizService.java
... ... @@ -1808,9 +1808,16 @@ public class KpiPoolBizService {
1808 1808 for (KpiPoolVO kpiPoolVO : kpiPoolVOS) {
1809 1809 //处理得分率 乘以 100
1810 1810 kpiPoolVO.setKpiScoreRatio(Optional.ofNullable(kpiPoolVO.getKpiScoreRatio()).orElse(BigDecimal.ZERO).multiply(Constant.ONE_HUNDRED));
1811   - kpiPoolVO.setLastOneKpiScoreRatio(Optional.ofNullable(kpiPoolVO.getLastOneKpiScoreRatio()).orElse(BigDecimal.ZERO).multiply(Constant.ONE_HUNDRED));
1812   - kpiPoolVO.setLastTwoKpiScoreRatio(Optional.ofNullable(kpiPoolVO.getLastTwoKpiScoreRatio()).orElse(BigDecimal.ZERO).multiply(Constant.ONE_HUNDRED));
1813   - kpiPoolVO.setAverageKpiScoreRatio(Optional.ofNullable(kpiPoolVO.getAverageKpiScoreRatio()).orElse(BigDecimal.ZERO).multiply(Constant.ONE_HUNDRED));
  1811 + //上两月绩效不参与考核就不展示
  1812 + if (PublicUtil.isNotEmpty(kpiPoolVO.getLastOneKpiScoreRatio())) {
  1813 + kpiPoolVO.setLastOneKpiScoreRatio(kpiPoolVO.getLastOneKpiScoreRatio().multiply(Constant.ONE_HUNDRED));
  1814 + }
  1815 + if (PublicUtil.isNotEmpty(kpiPoolVO.getLastTwoKpiScoreRatio())) {
  1816 + kpiPoolVO.setLastTwoKpiScoreRatio(kpiPoolVO.getLastTwoKpiScoreRatio().multiply(Constant.ONE_HUNDRED));
  1817 + }
  1818 + if (PublicUtil.isNotEmpty(kpiPoolVO.getAverageKpiScoreRatio())) {
  1819 + kpiPoolVO.setAverageKpiScoreRatio(kpiPoolVO.getAverageKpiScoreRatio().multiply(Constant.ONE_HUNDRED));
  1820 + }
1814 1821 //默认无比较者
1815 1822 kpiPoolVO.setMonthRankHasCompete(Boolean.FALSE);
1816 1823 kpiPoolVO.setRankHasCompete(Boolean.FALSE);
... ...
fw-morax-service/src/main/java/cn/fw/morax/service/biz/salary/SalaryGroupUserBizService.java
... ... @@ -491,7 +491,7 @@ public class SalaryGroupUserBizService {
491 491 * @return
492 492 */
493 493 public List<SalaryGroupUser> fetchRealTimeSalaryGroup(SalaryGroupStaffQueryDTO dto, LocalDate date) {
494   - List<PerformanceStaffDTO> staffs = ehrRpcService.queryKpiStaffByName(dto.getGroupId(), Lists.newArrayList(dto.getPostId()), dto.getShopIds(), dto.getStaffName(), date);
  494 + List<PerformanceStaffDTO> staffs = ehrRpcService.getPointTimeStaffs(dto.getGroupId(), Lists.newArrayList(dto.getPostId()), dto.getShopIds(), dto.getStaffName(), date);
495 495 if (PublicUtil.isEmpty(staffs)) {
496 496 return new ArrayList<>();
497 497 }
... ...