KpiAssessBizService.java 11.5 KB
package cn.fw.morax.service.biz.kpi;

import cn.fw.common.data.mybatis.pagination.PageData;
import cn.fw.common.exception.BusinessException;
import cn.fw.common.page.AppPage;
import cn.fw.ehr.sdk.api.enums.StaffStatusEnum;
import cn.fw.morax.common.utils.MessageFormatUtil;
import cn.fw.morax.common.utils.PublicUtil;
import cn.fw.morax.domain.db.ApprovalRecord;
import cn.fw.morax.domain.db.kpi.*;
import cn.fw.morax.domain.db.kpi.KpiAssess;
import cn.fw.morax.domain.db.salary.SalaryGroupProjectParam;
import cn.fw.morax.domain.dto.kpi.KpiAssessDTO;
import cn.fw.morax.domain.dto.kpi.KpiAssessDetailDTO;
import cn.fw.morax.domain.dto.kpi.KpiAssessStaffDTO;
import cn.fw.morax.domain.dto.query.IndicatorQueryDTO;
import cn.fw.morax.domain.dto.query.KpiAssessQueryDTO;
import cn.fw.morax.domain.enums.ApplicableRoleEnum;
import cn.fw.morax.domain.enums.ApprovalTypeEnum;
import cn.fw.morax.domain.enums.KpiAssessTypeEnum;
import cn.fw.morax.domain.enums.SettingStatusEnum;
import cn.fw.morax.domain.vo.kpi.*;
import cn.fw.morax.rpc.ehr.EhrRpcService;
import cn.fw.morax.rpc.ehr.dto.PerformanceStaffDTO;
import cn.fw.morax.rpc.ehr.dto.StaffBaseInfoDTO;
import cn.fw.morax.rpc.erp.ErpRpcService;
import cn.fw.morax.rpc.erp.dto.RpcUserRoleInfoDTO;
import cn.fw.morax.service.data.kpi.KpiAssessDetailService;
import cn.fw.morax.service.data.kpi.KpiAssessPenaltyService;
import cn.fw.morax.service.data.kpi.KpiAssessService;
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.validation.annotation.Validated;

import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.fw.common.businessvalidator.Validator.BV;

/**
 * @author jiangchao
 * @des: 人员质量评测
 * @date 2023/3/17 16:01
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class KpiAssessBizService {

    private final ErpRpcService erpRpcService;
    private final EhrRpcService ehrRpcService;
    private final KpiAssessService kpiAssessService;
    private final KpiAssessDetailService kpiAssessDetailService;
    private final KpiAssessPenaltyService kpiAssessPenaltyService;

    /**
     * 分页查询
     *
     * @param dto
     * @return
     */
    public AppPage<KpiAssessVO> kpiAssessPage(KpiAssessQueryDTO dto) {
        PageData<KpiAssess> pageData = kpiAssessService.page(new PageData<>(dto.getCurrent(), dto.getPageSize()),
                Wrappers.<KpiAssess>lambdaQuery()
                        .eq(KpiAssess::getBackup, Boolean.FALSE)
                        .eq(KpiAssess::getGroupId, dto.getGroupId())
                        .eq(PublicUtil.isNotEmpty(dto.getPostId()), KpiAssess::getPostId, dto.getPostId())
                        .eq(KpiAssess::getYn, Boolean.TRUE)
        );

        return PublicUtil.toPage(pageData, kpiAssess -> {
            KpiAssessVO kpiAssessVO = PublicUtil.copy(kpiAssess, KpiAssessVO.class);
            return kpiAssessVO;
        });
    }

    public KpiAssessVO kpiAssessDetail(Long id) {
        KpiAssess kpiAssess = kpiAssessService.getById(id);
        BV.notNull(kpiAssess, "配置不存在,请重试");
        KpiAssessVO kpiAssessVO = PublicUtil.copy(kpiAssess, KpiAssessVO.class);
        List<KpiAssessDetail> kpiAssessDetails = kpiAssessDetailService.list(Wrappers.<KpiAssessDetail>lambdaQuery()
                .eq(KpiAssessDetail::getKpiAssessId, id)
                .eq(KpiAssessDetail::getYn, Boolean.TRUE)
        );
        if (PublicUtil.isEmpty(kpiAssessDetails)) {
            return kpiAssessVO;
        }
        List<KpiAssessDetailVO> kpiAssessDetailVos = PublicUtil.copyList(kpiAssessDetails, KpiAssessDetailVO.class);
        kpiAssessVO.setDetails(kpiAssessDetailVos);
        return kpiAssessVO;
    }

    @Transactional(rollbackFor = Exception.class)
    public void saveKpiAssess(KpiAssessDTO dto) {
        checkAssess(dto);

        KpiAssess kpiAssess = convertDB(dto);
        kpiAssessService.saveOrUpdate(kpiAssess);
        final Long kpiAssessId = kpiAssess.getId();

        kpiAssessDetailService.update(Wrappers.<KpiAssessDetail>lambdaUpdate()
                .eq(KpiAssessDetail::getKpiAssessId, kpiAssessId)
                .set(KpiAssessDetail::getYn, Boolean.FALSE)
        );
        List<KpiAssessDetail> kpiAssessDetails = PublicUtil.copyList(dto.getDetails(), KpiAssessDetail.class);
        kpiAssessDetails.forEach(kpiAssessDetail -> kpiAssessDetail.setKpiAssessId(kpiAssessId));
        kpiAssessDetailService.saveBatch(kpiAssessDetails);
    }

    public void checkAssess(KpiAssessDTO dto) {
        List<KpiAssess> kpiAssesses = kpiAssessService.getConfigs(dto.getId(), dto.getType(), dto.getGroupId(), dto.getPostId(), dto.getShopIds());
        BV.isTrue(PublicUtil.isEmpty(kpiAssesses), "岗位、门店存在重复配置,请重试");

        if (KpiAssessTypeEnum.TURN_POSITIVE_AFTER.equals(dto.getType())) {
            List<KpiAssessDetailDTO> errorDetails = dto.getDetails().stream()
                    .filter(detail ->
                            PublicUtil.isEmpty(detail.getCapPersonPenaltyScore()) ||
                            PublicUtil.isEmpty(detail.getCapPersonPenaltyMoney()) ||
                            PublicUtil.isEmpty(detail.getAwardScore()) ||
                            PublicUtil.isEmpty(detail.getCapPersonAwardScore()) ||
                            PublicUtil.isEmpty(detail.getCapAwardScore()) ||
                            PublicUtil.isEmpty(detail.getAwardMoney()) ||
                            PublicUtil.isEmpty(detail.getCapPersonAwardMoney()) ||
                            PublicUtil.isEmpty(detail.getCapAwardMoney())
                    )
                    .collect(Collectors.toList());
            BV.isTrue(PublicUtil.isEmpty(errorDetails), "转正后保护期员工需要设置封顶单人惩罚分、奖励,请重试");
        }

        Set<String> roleCodes = new HashSet<>();
        dto.getDetails().stream().forEach(detail -> detail.getRoleCodes().stream().forEach(roleCode -> {
            if (! roleCodes.add(roleCode)) {
                throw new BusinessException("角色重复配置,请重试");
            }
        }));
    }

    @Transactional(rollbackFor = Exception.class)
    public void removeById(Long id) {
        kpiAssessService.removeById(id);
        kpiAssessDetailService.update(Wrappers.<KpiAssessDetail>lambdaUpdate()
                .eq(KpiAssessDetail::getKpiAssessId, id)
                .set(KpiAssessDetail::getYn, Boolean.FALSE)
        );
    }

    /**
     * 转正保护期员工
     *
     * @param postId
     * @param shopIds
     * @param localDate
     * @return
     */
    public List<KpiGroupUserVO> kpiRegularProtectionStaffs(Long postId, List<Long> shopIds, LocalDate localDate) {
        List<PerformanceStaffDTO> staffs = ehrRpcService.queryKpiStaff(postId, new ArrayList<>(shopIds));
        if (PublicUtil.isEmpty(staffs)) {
            return new ArrayList<>();
        }
        List<KpiGroupUserVO> regularProtectionStaffs = new ArrayList<>();
        LocalDate currentTime = LocalDate.now();

        for (PerformanceStaffDTO staff : staffs) {
            //转正两个月内不计算绩效  绩效开始时间为转正的两个月后
            if (StaffStatusEnum.REGULAR.getValue().equals(staff.getStaffStatus())) {
                LocalDate regularDate = PublicUtil.isNotEmpty(staff.getRegularDate()) ? staff.getRegularDate() : staff.getEntryDate();
                LocalDate startKpiDate = PublicUtil.getKpiDateOfRegularStaff(regularDate);
                //开始计算考评日期在 当前时间之前
                if (startKpiDate.isBefore(currentTime)) {
                    KpiGroupUserVO kpiUser = this.convertToGroupUser(staff, localDate);
                    regularProtectionStaffs.add(kpiUser);
                }
            }
        }
        return regularProtectionStaffs;
    }

    /**
     * 转正保护期员工
     *
     * @return
     */
    public List<KpiGroupUserVO> queryAssessStaffs(KpiAssessStaffDTO dto) {
        List<KpiGroupUserVO> users = new ArrayList<>();
        Set<Long> staffIds = new HashSet<>();
        final List<Long> shopIds = dto.getShopIds();
        for (String roleCode : dto.getRoleCodes()) {
            List<RpcUserRoleInfoDTO> userRoleInfos = this.getUserEnableRoleInfos(roleCode, new ArrayList<>(shopIds));
            if (PublicUtil.isNotEmpty(userRoleInfos)) {
                staffIds.addAll(userRoleInfos.stream().map(RpcUserRoleInfoDTO::getUserId).collect(Collectors.toSet()));
            }
        }
        if (PublicUtil.isEmpty(staffIds)) {
            return new ArrayList<>();
        }
        List<StaffBaseInfoDTO> staffDtos = ehrRpcService.queryStaffBaseInfo(new ArrayList<>(staffIds));
        staffDtos.stream().forEach(staffDto -> users.add(convertToGroupUser(staffDto)));
        return users;
    }

    /**
     * 对查询的人员去重
     *
     * @param roleCode
     * @param shopIds
     * @return
     */
    public List<RpcUserRoleInfoDTO> getUserEnableRoleInfos(String roleCode, List<Long> shopIds) {
        List<RpcUserRoleInfoDTO> userRoleInfos = erpRpcService.getUserEnableRoleInfos(roleCode, shopIds);
        if (PublicUtil.isEmpty(userRoleInfos)) {
            return new ArrayList<>();
        }
        Set<Long> staffIds = new HashSet<>();
        List<RpcUserRoleInfoDTO> repeatUserRoleInfos = Lists.newArrayListWithCapacity(userRoleInfos.size());
        for (RpcUserRoleInfoDTO rpcUserRoleInfoDTO : userRoleInfos) {
            if (staffIds.add(rpcUserRoleInfoDTO.getUserId())) {
                repeatUserRoleInfos.add(rpcUserRoleInfoDTO);
            }
        }
        return repeatUserRoleInfos;
    }

    /**
     * 转换员工基础信息
     *
     * @param staff
     * @return
     */
    private KpiGroupUserVO convertToGroupUser(StaffBaseInfoDTO staff){
        KpiGroupUserVO kpiUser = KpiGroupUserVO.builder()
                .userId(staff.getId())
                .userName(staff.getName())
                .postId(staff.getPostId())
                .postName(staff.getPostName())
                .shopId(staff.getShopId())
                .shopName(staff.getShopName())
                .groupId(staff.getGroupId())
                .build();
        return kpiUser;
    }

    /**
     * 转换员工基础信息
     *
     * @param staff
     * @return
     */
    private KpiGroupUserVO convertToGroupUser(PerformanceStaffDTO staff, LocalDate now){
        KpiGroupUserVO kpiUser = KpiGroupUserVO.builder()
                .userId(staff.getId())
                .userName(staff.getName())
                .postId(staff.getPostId())
                .postName(staff.getPostName())
                .shopId(staff.getShopId())
                .shopName(staff.getShopName())
                .groupId(staff.getGroupId())
                .dataDate(now)
                .build();
        return kpiUser;
    }

    public KpiAssess convertDB(KpiAssessDTO dto) {
        KpiAssess kpiAssess = new KpiAssess();
        if (PublicUtil.isNotEmpty(dto.getId())) {
            kpiAssess.setId(dto.getId());
        }
        kpiAssess.setType(dto.getType());
        kpiAssess.setPostId(dto.getPostId());
        kpiAssess.setPostName(dto.getPostName());
        kpiAssess.setShopIds(dto.getShopIds());
        kpiAssess.setShopNames(dto.getShopNames());
        kpiAssess.setRank(dto.getRank());
        kpiAssess.setGroupId(dto.getGroupId());
        kpiAssess.setYn(Boolean.TRUE);
        return kpiAssess;
    }


}