package cn.iocoder.yudao.module.mes.api.feedback;
|
|
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.util.StrUtil;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.module.mes.api.feedback.dto.MesProFeedbackWageDetailRespDTO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.feedback.MesProFeedbackDO;
|
import cn.iocoder.yudao.module.mes.dal.dataobject.pro.process.MesProProcessDO;
|
import cn.iocoder.yudao.module.mes.dal.mysql.pro.feedback.MesProFeedbackMapper;
|
import cn.iocoder.yudao.module.mes.service.pro.process.MesProProcessService;
|
import cn.iocoder.yudao.module.mes.service.pro.wage.MesProFeedbackWageBreakdown;
|
import jakarta.annotation.Resource;
|
import org.springframework.stereotype.Service;
|
import org.springframework.validation.annotation.Validated;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.util.*;
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
|
/**
|
* MES 生产报工工资 API 实现类
|
*
|
* @author 超级管理员
|
*/
|
@Service
|
@Validated
|
public class MesProFeedbackWageApiImpl implements MesProFeedbackWageApi {
|
|
@Resource
|
private MesProFeedbackMapper feedbackMapper;
|
@Resource
|
private MesProProcessService processService;
|
|
@Override
|
public Map<Long, BigDecimal> getWageAmountMap(Collection<Long> feedbackUserIds,
|
LocalDateTime beginTime, LocalDateTime endTime) {
|
if (CollUtil.isEmpty(feedbackUserIds)) {
|
return Collections.emptyMap();
|
}
|
List<MesProFeedbackDO> list = feedbackMapper.selectWageListByUserIds(feedbackUserIds, beginTime, endTime);
|
Map<Long, BigDecimal> result = new LinkedHashMap<>();
|
for (MesProFeedbackDO feedback : list) {
|
if (feedback.getFeedbackUserId() == null) {
|
continue;
|
}
|
BigDecimal wage = feedback.getWageAmount() != null ? feedback.getWageAmount() : BigDecimal.ZERO;
|
result.merge(feedback.getFeedbackUserId(), wage, BigDecimal::add);
|
}
|
return result;
|
}
|
|
@Override
|
public List<MesProFeedbackWageDetailRespDTO> getWageDetailList(Long feedbackUserId,
|
LocalDateTime beginTime, LocalDateTime endTime) {
|
if (feedbackUserId == null) {
|
return Collections.emptyList();
|
}
|
List<MesProFeedbackDO> list = feedbackMapper.selectWageListByUserIds(
|
Collections.singleton(feedbackUserId), beginTime, endTime);
|
if (CollUtil.isEmpty(list)) {
|
return Collections.emptyList();
|
}
|
Map<Long, MesProProcessDO> processMap = processService.getProcessMap(
|
convertSet(list, MesProFeedbackDO::getProcessId));
|
List<MesProFeedbackWageDetailRespDTO> result = new ArrayList<>(list.size());
|
for (MesProFeedbackDO feedback : list) {
|
result.add(buildWageDetail(feedback, processMap.get(feedback.getProcessId())));
|
}
|
// 报工时间倒序,最近的报工排在最前
|
result.sort(Comparator.comparing(MesProFeedbackWageDetailRespDTO::getFeedbackTime,
|
Comparator.nullsLast(Comparator.reverseOrder())));
|
return result;
|
}
|
|
private MesProFeedbackWageDetailRespDTO buildWageDetail(MesProFeedbackDO feedback, MesProProcessDO process) {
|
MesProFeedbackWageDetailRespDTO detail = new MesProFeedbackWageDetailRespDTO();
|
detail.setFeedbackId(feedback.getId());
|
detail.setFeedbackNo(feedback.getCode());
|
detail.setProcessId(feedback.getProcessId());
|
detail.setProcessName(process != null ? process.getName() : null);
|
detail.setFeedbackTime(feedback.getFeedbackTime());
|
detail.setStatus(feedback.getStatus());
|
detail.setBillingType(feedback.getBillingType());
|
detail.setWorkHours(feedback.getWorkHours());
|
detail.setFeedbackQuantity(feedback.getFeedbackQuantity());
|
detail.setQualifiedQuantity(feedback.getQualifiedQuantity());
|
|
MesProFeedbackWageBreakdown breakdown = StrUtil.isNotBlank(feedback.getWageBreakdown())
|
? JsonUtils.parseObject(feedback.getWageBreakdown(), MesProFeedbackWageBreakdown.class) : null;
|
BigDecimal mainWage;
|
BigDecimal auxWage;
|
if (breakdown != null) {
|
mainWage = breakdown.getMainWage() != null ? breakdown.getMainWage() : BigDecimal.ZERO;
|
auxWage = breakdown.getAuxWage() != null ? breakdown.getAuxWage()
|
: (feedback.getAuxWageAmount() != null ? feedback.getAuxWageAmount() : BigDecimal.ZERO);
|
} else {
|
// 改造前的历史报工没有工资拆分快照:把报工工资整体视为主工资,
|
// 保证明细中「主工资 + 辅助工资 + 字段调整 + 质量调整 = 最终工资」仍然对得上
|
auxWage = feedback.getAuxWageAmount() != null ? feedback.getAuxWageAmount() : BigDecimal.ZERO;
|
mainWage = feedback.getWageAmount() != null
|
? feedback.getWageAmount().subtract(auxWage).max(BigDecimal.ZERO) : BigDecimal.ZERO;
|
}
|
detail.setMainWage(mainWage);
|
detail.setAuxWage(auxWage);
|
|
// 自定义工资字段明细
|
List<MesProFeedbackWageDetailRespDTO.Field> fields = new ArrayList<>();
|
BigDecimal fieldWage = BigDecimal.ZERO;
|
if (breakdown != null && CollUtil.isNotEmpty(breakdown.getFields())) {
|
for (MesProFeedbackWageBreakdown.FieldSnapshot snapshot : breakdown.getFields()) {
|
MesProFeedbackWageDetailRespDTO.Field field = new MesProFeedbackWageDetailRespDTO.Field();
|
field.setCode(snapshot.getCode());
|
field.setName(snapshot.getName());
|
field.setRole(snapshot.getRole());
|
field.setValue(snapshot.getValue());
|
field.setUnitPrice(snapshot.getUnitPrice());
|
field.setAmount(snapshot.getAmount() != null ? snapshot.getAmount() : BigDecimal.ZERO);
|
fields.add(field);
|
fieldWage = fieldWage.add(field.getAmount());
|
}
|
}
|
detail.setFields(fields);
|
detail.setFieldWage(fieldWage);
|
|
BigDecimal preQualityWage = breakdown != null && breakdown.getPreQualityWage() != null
|
? breakdown.getPreQualityWage() : mainWage.add(auxWage).add(fieldWage);
|
BigDecimal finalWage = feedback.getWageAmount() != null
|
? feedback.getWageAmount()
|
: (breakdown != null && breakdown.getFinalWage() != null ? breakdown.getFinalWage() : preQualityWage);
|
detail.setPreQualityWage(preQualityWage);
|
detail.setFinalWage(finalWage);
|
detail.setQualityAdjustment(finalWage.subtract(preQualityWage));
|
return detail;
|
}
|
|
}
|