package cn.iocoder.yudao.module.mes.service.pro.wage;
|
|
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.StrUtil;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.wage.vo.MesProWageQualityRulePageReqVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.wage.vo.MesProWageQualityRuleResolveRespVO;
|
import cn.iocoder.yudao.module.mes.controller.admin.pro.wage.vo.MesProWageQualityRuleSaveReqVO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.wage.MesProWageQualityRuleDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.pro.wage.MesProWageQualityRuleMapper;
|
import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Service;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.math.BigDecimal;
|
import java.util.Comparator;
|
import java.util.List;
|
import java.util.Objects;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
|
|
/**
|
* MES 质量工资规则 Service 实现类
|
*
|
* @author 超级管理员
|
*/
|
@Service
|
@Validated
|
public class MesProWageQualityRuleServiceImpl implements MesProWageQualityRuleService {
|
|
@Resource
|
private MesProWageQualityRuleMapper ruleMapper;
|
@Resource
|
private MesProProcessService processService;
|
|
@Override
|
public PageResult<MesProWageQualityRuleDO> getRulePage(MesProWageQualityRulePageReqVO pageReqVO) {
|
return ruleMapper.selectPage(pageReqVO);
|
}
|
|
@Override
|
public List<MesProWageQualityRuleDO> getRuleListByProcessId(Long processId) {
|
return ruleMapper.selectListByProcessId(processId);
|
}
|
|
@Override
|
public Long createRule(MesProWageQualityRuleSaveReqVO createReqVO) {
|
validateRule(createReqVO);
|
MesProWageQualityRuleDO rule = BeanUtils.toBean(createReqVO, MesProWageQualityRuleDO.class)
|
.setId(null)
|
.setStatus(ObjUtil.defaultIfNull(createReqVO.getStatus(), CommonStatusEnum.ENABLE.getStatus()))
|
.setPriority(ObjUtil.defaultIfNull(createReqVO.getPriority(), 0));
|
ruleMapper.insert(rule);
|
return rule.getId();
|
}
|
|
@Override
|
public void updateRule(MesProWageQualityRuleSaveReqVO updateReqVO) {
|
validateRuleExists(updateReqVO.getId());
|
validateRule(updateReqVO);
|
ruleMapper.updateById(BeanUtils.toBean(updateReqVO, MesProWageQualityRuleDO.class));
|
}
|
|
@Override
|
public void deleteRule(Long id) {
|
validateRuleExists(id);
|
ruleMapper.deleteById(id);
|
}
|
|
@Override
|
public MesProWageQualityRuleResolveRespVO resolve(Long processId, Long routeId, BigDecimal passRate) {
|
MesProWageQualityRuleResolveRespVO resp = new MesProWageQualityRuleResolveRespVO()
|
.setProcessId(processId).setRouteId(routeId).setPassRate(passRate);
|
if (processId == null || passRate == null) {
|
return resp;
|
}
|
MesProWageQualityRuleDO rule = ruleMapper.selectListByProcessId(processId).stream()
|
.filter(item -> Objects.equals(item.getStatus(), CommonStatusEnum.ENABLE.getStatus()))
|
.filter(item -> item.getRouteId() == null || Objects.equals(item.getRouteId(), routeId))
|
.filter(item -> matchRate(item, passRate))
|
.sorted(Comparator
|
// 路线更具体的优先
|
.comparingInt((MesProWageQualityRuleDO item) -> item.getRouteId() != null ? 1 : 0).reversed()
|
.thenComparing(Comparator.comparingInt(
|
(MesProWageQualityRuleDO item) -> ObjUtil.defaultIfNull(item.getPriority(), 0)).reversed())
|
.thenComparing(Comparator.comparing(MesProWageQualityRuleDO::getId).reversed()))
|
.findFirst().orElse(null);
|
if (rule == null) {
|
return resp;
|
}
|
resp.setRuleId(rule.getId()).setRuleType(rule.getRuleType())
|
.setCoefficient(rule.getCoefficient()).setDeductionPerUnit(rule.getDeductionPerUnit());
|
return resp;
|
}
|
|
private static boolean matchRate(MesProWageQualityRuleDO rule, BigDecimal passRate) {
|
if (rule.getMinRate() != null && passRate.compareTo(rule.getMinRate()) < 0) {
|
return false;
|
}
|
return rule.getMaxRate() == null || passRate.compareTo(rule.getMaxRate()) < 0;
|
}
|
|
private MesProWageQualityRuleDO validateRuleExists(Long id) {
|
MesProWageQualityRuleDO rule = ruleMapper.selectById(id);
|
if (rule == null) {
|
throw exception(PRO_WAGE_QUALITY_RULE_NOT_EXISTS);
|
}
|
return rule;
|
}
|
|
private void validateRule(MesProWageQualityRuleSaveReqVO reqVO) {
|
MesProProcessDO process = processService.getProcess(reqVO.getProcessId());
|
if (process == null) {
|
throw exception(PRO_FEEDBACK_PROCESS_NOT_EXISTS, reqVO.getProcessId());
|
}
|
Integer ruleType = reqVO.getRuleType();
|
if (!Objects.equals(ruleType, MesProWageQualityRuleDO.RULE_TYPE_COEFFICIENT)
|
&& !Objects.equals(ruleType, MesProWageQualityRuleDO.RULE_TYPE_DEDUCTION)) {
|
throw new ServiceException(PRO_WAGE_QUALITY_RULE_VALUE_INVALID.getCode(),
|
StrUtil.format("工序[{}]的质量规则类型[{}]不合法;期望 1-合格率系数 / 2-不合格扣款,请重新选择",
|
process.getName(), ruleType));
|
}
|
BigDecimal minRate = reqVO.getMinRate();
|
BigDecimal maxRate = reqVO.getMaxRate();
|
if (minRate == null || maxRate == null) {
|
throw new ServiceException(PRO_WAGE_QUALITY_RULE_RANGE_INVALID.getCode(),
|
StrUtil.format("工序[{}]的质量规则合格率区间不完整:下限[{}],上限[{}];请同时填写下限与上限后重试",
|
process.getName(), minRate, maxRate));
|
}
|
if (minRate.compareTo(maxRate) >= 0) {
|
throw new ServiceException(PRO_WAGE_QUALITY_RULE_RANGE_INVALID.getCode(),
|
StrUtil.format("工序[{}]的质量规则合格率区间不合法:下限[{}%]必须小于上限[{}%];请调整区间后重试",
|
process.getName(), minRate, maxRate));
|
}
|
if (Objects.equals(ruleType, MesProWageQualityRuleDO.RULE_TYPE_COEFFICIENT)) {
|
if (reqVO.getCoefficient() == null || reqVO.getCoefficient().signum() <= 0) {
|
throw new ServiceException(PRO_WAGE_QUALITY_RULE_VALUE_INVALID.getCode(),
|
StrUtil.format("工序[{}]的质量规则为「合格率系数」,期望系数大于 0,实际为[{}];请填写系数后重试",
|
process.getName(), reqVO.getCoefficient()));
|
}
|
} else {
|
if (reqVO.getDeductionPerUnit() == null || reqVO.getDeductionPerUnit().signum() < 0) {
|
throw new ServiceException(PRO_WAGE_QUALITY_RULE_VALUE_INVALID.getCode(),
|
StrUtil.format("工序[{}]的质量规则为「不合格扣款」,期望每件扣款不小于 0,实际为[{}];请填写扣款金额后重试",
|
process.getName(), reqVO.getDeductionPerUnit()));
|
}
|
}
|
}
|
|
}
|