gaoluyang
昨天 8c65f898ed6e5b0c7a94c792c4562f6ec831dccd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
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;
    }
 
}