package cn.fw.morax.service.biz.kpi; import cn.fw.common.exception.BusinessException; import cn.fw.morax.common.constant.Constant; import cn.fw.morax.common.utils.PublicUtil; import cn.fw.morax.domain.db.SettingDraft; import cn.fw.morax.domain.db.kpi.*; import cn.fw.morax.domain.dto.kpi.*; import cn.fw.morax.domain.enums.*; import cn.fw.morax.service.data.SettingDraftService; import cn.fw.morax.service.data.kpi.*; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import java.math.RoundingMode; import java.time.LocalDate; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.stream.Collectors; @RequiredArgsConstructor @Service @Slf4j public class KpiGroupDataService { private final KpiGroupIndicatorLaddersService kpiGroupIndicatorLaddersService; private final KpiGroupIndicatorService kpiGroupIndicatorService; private final KpiStarLaddersService kpiStarLaddersService; private final SettingDraftService settingDraftService; private final KpiGroupService kpiGroupService; private final KpiGroupUserService kpiGroupUserService; private final KpiPoolService kpiPoolService; private final KpiGroupIndicatorPreconditionService kpiGroupIndicatorPreconditionService; private final KpiGroupIndicatorParamService kpiGroupIndicatorParamService; private final KpiGroupIndicatorPreconditionLaddersService kpiGroupIndicatorCondLaddersService; private final IndicatorsService indicatorsService; /** * 保存绩效组 * * @param dto */ public KpiGroup saveKpiGroup(KpiGroupDTO dto) { if (PublicUtil.isNotEmpty(dto.getRevokedScoreRatio())) { dto.setRevokedScoreRatio(dto.getRevokedScoreRatio().divide(Constant.ONE_HUNDRED, 2, RoundingMode.HALF_UP)); } KpiGroup kpiGroup = PublicUtil.copy(dto, KpiGroup.class); kpiGroup.setIndicatorNum(dto.getIndicators().size()); if (PublicUtil.isNotEmpty(dto.getId())) { kpiGroup.setPreId(dto.getId()); kpiGroup.setKgc(dto.getKgc()); } else { kpiGroup.setKgc(PublicUtil.getUUID()); } kpiGroup.setId(null); kpiGroup.setStatus(SettingStatusEnum.EFFECTIVE); kpiGroup.setCreateBy(dto.getUserId()); kpiGroupService.save(kpiGroup); return kpiGroup; } /** * 保存绩效指标、阶梯 * * @param indicators * @param kpiGroup * @return */ @Transactional(rollbackFor = Exception.class) public void saveKpiIndicators(List indicators, KpiGroup kpiGroup) { List indicatorLadders = Lists.newArrayListWithCapacity(30); List params = Lists.newArrayListWithCapacity(30); List preconditionLadders = Lists.newArrayListWithCapacity(30); Long kpiGroupId = kpiGroup.getId(); Long indicatorId = null; KpiGroupIndicator indicator = null; KpiGroupIndicatorLadders indicatorLadder = null; for (KpiGroupIndicatorDTO indicatorDto : indicators) { indicator = PublicUtil.copy(indicatorDto, KpiGroupIndicator.class); indicator.setKpiGroupId(kpiGroupId); kpiGroupIndicatorService.save(indicator); indicatorId = indicator.getId(); //提成参数 if (PublicUtil.isNotEmpty(indicatorDto.getCommissionParams())) { for (KpiGroupIndicatorParamDTO commissionParam : indicatorDto.getCommissionParams()) { KpiGroupIndicatorParam param = PublicUtil.copy(commissionParam, KpiGroupIndicatorParam.class); param.setKpiGroupId(kpiGroupId); param.setKpiGroupIndicatorId(indicatorId); param.setParamType(ParamTypeEnum.COMMISSION); param.setProportion(param.getProportion().divide(Constant.ONE_HUNDRED, 4, RoundingMode.HALF_UP)); if (PublicUtil.isNotEmpty(param.getTargetType()) && TargetTypeEnum.RATIO.equals(param.getTargetType())) { param.setTargetValue(param.getTargetValue().divide(Constant.ONE_HUNDRED, 4, RoundingMode.HALF_UP)); } params.add(param); } } //条件 if (PublicUtil.isNotEmpty(indicatorDto.getConds())) { for (KpiGroupIndicatorPreconditionDTO condDto : indicatorDto.getConds()) { Indicators indicators1 = indicatorsService.queryByCode(condDto.getIndicatorCode(), Boolean.FALSE); KpiGroupIndicatorPrecondition cond = PublicUtil.copy(condDto, KpiGroupIndicatorPrecondition.class); cond.setKpiGroupId(kpiGroupId); cond.setKpiGroupIndicatorId(indicatorId); if (PublicUtil.isNotEmpty(cond.getTargetType()) && TargetTypeEnum.RATIO.equals(cond.getTargetType())) { cond.setTargetValue(cond.getTargetValue().divide(Constant.ONE_HUNDRED, 4, RoundingMode.HALF_UP)); } kpiGroupIndicatorPreconditionService.save(cond); Long kpiGroupIndicatorCondId = cond.getId(); for (KpiGroupIndicatorPreconditionLaddersDTO condLaddersDto : condDto.getCondLadders()) { KpiGroupIndicatorPreconditionLadders condLadder = PublicUtil.copy(condLaddersDto, KpiGroupIndicatorPreconditionLadders.class); condLadder.setPreconditionId(kpiGroupIndicatorCondId); condLadder.dividePercent(cond.getTargetType(), indicators1.getDataType()); if (PublicUtil.isNotEmpty(cond.getTargetType()) && TargetTypeEnum.RATIO.equals(cond.getTargetType())) { cond.setTargetValue(cond.getTargetValue().divide(Constant.ONE_HUNDRED, 4, RoundingMode.HALF_UP)); } preconditionLadders.add(condLadder); } } } //普通得分没有台阶条件 if (ScoreWayEnum.NORMAL.equals(indicator.getScoreWay())) { continue; } if (PublicUtil.isEmpty(indicatorDto.getLadderParams()) || PublicUtil.isEmpty(indicatorDto.getIndicatorLadders())) { throw new BusinessException("台阶参数、台阶不能为空"); } //台阶参数 for (KpiGroupIndicatorParamDTO commissionParam : indicatorDto.getLadderParams()) { KpiGroupIndicatorParam param = PublicUtil.copy(commissionParam, KpiGroupIndicatorParam.class); param.setKpiGroupId(kpiGroupId); param.setKpiGroupIndicatorId(indicatorId); param.setParamType(ParamTypeEnum.LADDER); param.setProportion(param.getProportion().divide(Constant.ONE_HUNDRED, 4, RoundingMode.HALF_UP)); if (PublicUtil.isNotEmpty(param.getTargetType()) && TargetTypeEnum.RATIO.equals(param.getTargetType())) { param.setTargetValue(param.getTargetValue().divide(Constant.ONE_HUNDRED, 4, RoundingMode.HALF_UP)); } params.add(param); } //台阶 for (KpiGroupIndicatorLaddersDTO laddersDto : indicatorDto.getIndicatorLadders()) { indicatorLadder = PublicUtil.copy(laddersDto, KpiGroupIndicatorLadders.class); if (PublicUtil.isNotEmpty(indicator.getLaddersType()) && DataTypeEnum.RATIO.equals(indicator.getLaddersType())) { indicatorLadder.setUpper(indicatorLadder.getUpper().divide(Constant.ONE_HUNDRED, 4, RoundingMode.HALF_UP)); indicatorLadder.setLower(indicatorLadder.getLower().divide(Constant.ONE_HUNDRED, 4, RoundingMode.HALF_UP)); } indicatorLadder.setKpiGroupIndicatorId(indicatorId); indicatorLadders.add(indicatorLadder); } } if (PublicUtil.isNotEmpty(indicatorLadders)) { kpiGroupIndicatorLaddersService.saveBatch(indicatorLadders); } if (PublicUtil.isNotEmpty(params)) { kpiGroupIndicatorParamService.saveBatch(params); } if (PublicUtil.isNotEmpty(preconditionLadders)) { kpiGroupIndicatorCondLaddersService.saveBatch(preconditionLadders); } } /** * 保存绩效星级评定阶梯 * * @param starLaddersDtos * @param kpiGroup * @return */ @Transactional(rollbackFor = Exception.class) public KpiGroup saveKpiStarLadders(List starLaddersDtos, KpiGroup kpiGroup) { List starLadders = Lists.newArrayListWithCapacity(starLaddersDtos.size()); Long kpiGroupId = kpiGroup.getId(); KpiStarLadders starLadder = null; for (KpiStarLaddersDTO starLaddersDto : starLaddersDtos) { starLadder = PublicUtil.copy(starLaddersDto, KpiStarLadders.class); starLadder.setUpper(starLadder.getUpper().divide(Constant.ONE_HUNDRED, 2, RoundingMode.HALF_UP)); starLadder.setLower(starLadder.getLower().divide(Constant.ONE_HUNDRED, 2, RoundingMode.HALF_UP)); starLadder.setKpiGroupId(kpiGroupId); starLadders.add(starLadder); } kpiStarLaddersService.saveBatch(starLadders); return kpiGroup; } /** * 删除绩效组配置(根本没有被使用的绩效组配置会被逻辑删除,如为次月添加3次配置,之前两次根本没有被用,直接删除) * * @param kpiGroups */ @Transactional(rollbackFor = Exception.class) public void delInEffective(List kpiGroups) { if (PublicUtil.isEmpty(kpiGroups)) { return; } List kpiIds = kpiGroups.stream().map(KpiGroup::getId).collect(Collectors.toList()); // kpiGroupService.removeByIds(kpiIds); kpiGroupService.update(Wrappers.lambdaUpdate() .set(KpiGroup::getYn, Boolean.FALSE) .set(KpiGroup::getUpdateTime, new Date()) .in(KpiGroup::getId, kpiIds) ); } /** * 修改多个绩效组状态 * * @param kpiGroups * @param status */ @Transactional(rollbackFor = Exception.class) public void modifyStatusByKpis(List kpiGroups, SettingStatusEnum status) { if (PublicUtil.isEmpty(kpiGroups)) { return; } List kpiIds = kpiGroups.stream().map(KpiGroup::getId).collect(Collectors.toList()); this.modifyStatusByIds(kpiIds, status); } /** * 将绩效组对应的草稿设置为未发布 * * @param kpiGroups */ @Transactional(rollbackFor = Exception.class) public void modifyDraftNoRelease(List kpiGroups) { if (PublicUtil.isEmpty(kpiGroups)) { return; } List kpiIds = kpiGroups.stream().map(KpiGroup::getId).collect(Collectors.toList()); settingDraftService.update(Wrappers.lambdaUpdate() .set(SettingDraft::getUpdateTime, new Date()) .set(SettingDraft::getStatus, SettingDraftStatusEnum.NO_RELEASE) .in(SettingDraft::getUnionId, kpiIds) .eq(SettingDraft::getType, SettingDraftTypeEnum.KPI) .eq(SettingDraft::getYn, Boolean.TRUE) ); } /** * 修改多个绩效组状态 * * @param kpiIds * @param status */ @Transactional(rollbackFor = Exception.class) public void modifyStatusByIds(List kpiIds, SettingStatusEnum status) { if (PublicUtil.isEmpty(kpiIds)) { return; } log.info("修改绩效组配置状态:{},{}", JSON.toJSONString(kpiIds), status.getName()); LocalDate localDate = LocalDate.now(); LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate() .set(KpiGroup::getStatus, status) .in(KpiGroup::getId, kpiIds); switch (status) { case EFFECTIVE: { updateWrapper.set(KpiGroup::getBeginTime, localDate); break; } case INEFFECTIVE: { updateWrapper.set(KpiGroup::getOverTime, PublicUtil.getPreviousDay(localDate)); break; } } kpiGroupService.update(updateWrapper); } /** * 修改绩效组状态 * * @param kpiGroup * @param status */ @Transactional(rollbackFor = Exception.class) public void modifyStatusById(KpiGroup kpiGroup, SettingStatusEnum status) { log.info("修改绩效组配置状态:{},{}", kpiGroup.getId(), status.getName()); LocalDate localDate = LocalDate.now(); LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate() .set(KpiGroup::getStatus, status) .eq(KpiGroup::getId, kpiGroup.getId()); updateWrapper.set(!StringUtils.isEmpty(kpiGroup.getKgc()),KpiGroup::getKgc, kpiGroup.getKgc()); switch (status) { // case BE_EFFECTIVE : { // KpiGroup kpiGroup = kpiGroupService.getById(kpiId); // updateWrapper.set(KpiGroup::getBeginTime, kpiGroup.getBeginTime()); // break; // } case EFFECTIVE: { updateWrapper.set(KpiGroup::getBeginTime, localDate); break; } case INEFFECTIVE: { //之前生效过得配置需要 设置结束时间 if (SettingStatusEnum.EFFECTIVE.equals(kpiGroup.getStatus())) { updateWrapper.set(KpiGroup::getOverTime, PublicUtil.getPreviousDay(localDate)); } break; } } kpiGroupService.update(updateWrapper); } /** * 初始化kgc */ @Transactional(rollbackFor = Exception.class) public void initKgc() { List status = new ArrayList() {{ add(SettingStatusEnum.EFFECTIVE); }}; List kpiGroups = kpiGroupService.list(Wrappers.lambdaQuery() .in(KpiGroup::getStatus, status) .eq(KpiGroup::getYn, Boolean.TRUE) ); for (KpiGroup kpiGroup : kpiGroups) { final Long kpiGroupId = kpiGroup.getId(); final String kgc = PublicUtil.getUUID(); kpiGroupService.update(Wrappers.lambdaUpdate() .set(KpiGroup::getKgc, kgc) .set(KpiGroup::getUpdateTime, new Date()) .eq(KpiGroup::getId, kpiGroupId) ); kpiGroupUserService.update(Wrappers.lambdaUpdate() .set(KpiGroupUser::getKgc, kgc) .set(KpiGroupUser::getUpdateTime, new Date()) .eq(KpiGroupUser::getKpiGroupId, kpiGroupId) ); kpiPoolService.update(Wrappers.lambdaUpdate() // .set(KpiPool::getKgc, kgc) .set(KpiPool::getUpdateTime, new Date()) .eq(KpiPool::getKpiGroupId, kpiGroupId) ); } } }