KpiGroupDataService.java 15.5 KB
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<KpiGroupIndicatorDTO> indicators, KpiGroup kpiGroup) {

        List<KpiGroupIndicatorLadders> indicatorLadders = Lists.newArrayListWithCapacity(30);
        List<KpiGroupIndicatorParam> params = Lists.newArrayListWithCapacity(30);
        List<KpiGroupIndicatorPreconditionLadders> 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<KpiStarLaddersDTO> starLaddersDtos, KpiGroup kpiGroup) {
        List<KpiStarLadders> 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<KpiGroup> kpiGroups) {
        if (PublicUtil.isEmpty(kpiGroups)) {
            return;
        }
        List<Long> kpiIds = kpiGroups.stream().map(KpiGroup::getId).collect(Collectors.toList());
//        kpiGroupService.removeByIds(kpiIds);
        kpiGroupService.update(Wrappers.<KpiGroup>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<KpiGroup> kpiGroups, SettingStatusEnum status) {
        if (PublicUtil.isEmpty(kpiGroups)) {
            return;
        }
        List<Long> kpiIds = kpiGroups.stream().map(KpiGroup::getId).collect(Collectors.toList());
        this.modifyStatusByIds(kpiIds, status);
    }

    /**
     * 将绩效组对应的草稿设置为未发布
     *
     * @param kpiGroups
     */
    @Transactional(rollbackFor = Exception.class)
    public void modifyDraftNoRelease(List<KpiGroup> kpiGroups) {
        if (PublicUtil.isEmpty(kpiGroups)) {
            return;
        }
        List<Long> kpiIds = kpiGroups.stream().map(KpiGroup::getId).collect(Collectors.toList());

        settingDraftService.update(Wrappers.<SettingDraft>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<Long> kpiIds, SettingStatusEnum status) {
        if (PublicUtil.isEmpty(kpiIds)) {
            return;
        }
        log.info("修改绩效组配置状态:{},{}", JSON.toJSONString(kpiIds), status.getName());
        LocalDate localDate = LocalDate.now();
        LambdaUpdateWrapper<KpiGroup> updateWrapper = Wrappers.<KpiGroup>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<KpiGroup> updateWrapper = Wrappers.<KpiGroup>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<SettingStatusEnum> status = new ArrayList<SettingStatusEnum>() {{
            add(SettingStatusEnum.EFFECTIVE);
        }};
        List<KpiGroup> kpiGroups = kpiGroupService.list(Wrappers.<KpiGroup>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.<KpiGroup>lambdaUpdate()
                    .set(KpiGroup::getKgc, kgc)
                    .set(KpiGroup::getUpdateTime, new Date())
                    .eq(KpiGroup::getId, kpiGroupId)
            );
            kpiGroupUserService.update(Wrappers.<KpiGroupUser>lambdaUpdate()
                    .set(KpiGroupUser::getKgc, kgc)
                    .set(KpiGroupUser::getUpdateTime, new Date())
                    .eq(KpiGroupUser::getKpiGroupId, kpiGroupId)
            );
            kpiPoolService.update(Wrappers.<KpiPool>lambdaUpdate()
//                    .set(KpiPool::getKgc, kgc)
                    .set(KpiPool::getUpdateTime, new Date())
                    .eq(KpiPool::getKpiGroupId, kpiGroupId)
            );

        }
    }

}