liyong
4 天以前 0f792c9b3b88dc4b1b7b306f89e257d931d2d0bd
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package cn.iocoder.yudao.module.mes.service.wm.returnissue;
 
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
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.wm.returnissue.vo.line.MesWmReturnIssueLinePageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.wm.returnissue.vo.line.MesWmReturnIssueLineSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLineDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.returnissue.MesWmReturnIssueLinePageVO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.returnissue.MesWmReturnIssueLineMapper;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueStatusEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmReturnIssueTypeEnum;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
 
import java.math.BigDecimal;
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.WM_RETURN_ISSUE_LINE_NOT_EXISTS;
 
/**
 * MES 生产退料单行 Service 实现类
 */
@Service
@Validated
public class MesWmReturnIssueLineServiceImpl implements MesWmReturnIssueLineService {
 
    @Resource
    private MesWmReturnIssueLineMapper issueLineMapper;
 
    @Resource
    @Lazy
    private MesWmReturnIssueService issueService;
    @Resource
    private MesMdmItemService mdmItemService;
    @Resource
    @Lazy
    private MesWmReturnIssueDetailService issueDetailService;
 
    @Override
    public Long createReturnIssueLine(MesWmReturnIssueLineSaveReqVO createReqVO) {
        // 校验数据
        MesWmReturnIssueDO issue = validateReturnIssueLineSaveData(createReqVO);
 
        // 插入
        MesWmReturnIssueLineDO line = BeanUtils.toBean(createReqVO, MesWmReturnIssueLineDO.class);
        line.setQualityStatus(calculateQualityStatus(line.getRqcCheckFlag(), issue.getType())); // 质量状态自动赋值
        issueLineMapper.insert(line);
        return line.getId();
    }
 
    @Override
    public void updateReturnIssueLine(MesWmReturnIssueLineSaveReqVO updateReqVO) {
        // 校验存在
        validateReturnIssueLineExists(updateReqVO.getId());
        // 校验数据
        MesWmReturnIssueDO issue = validateReturnIssueLineSaveData(updateReqVO);
 
        // 更新
        MesWmReturnIssueLineDO updateObj = BeanUtils.toBean(updateReqVO, MesWmReturnIssueLineDO.class);
        updateObj.setQualityStatus(calculateQualityStatus(updateObj.getRqcCheckFlag(), issue.getType())); // 质量状态自动赋值
        issueLineMapper.updateById(updateObj);
    }
 
    @Override
    public void deleteReturnIssueLine(Long id) {
        // 校验存在
        MesWmReturnIssueLineDO line = validateReturnIssueLineExists(id);
        // 校验主单为草稿状态才允许删除行
        issueService.validateReturnIssueExistsAndPrepare(line.getIssueId());
        // 级联删除该行的明细
        issueDetailService.deleteReturnIssueDetailByLineId(id);
        // 删除行
        issueLineMapper.deleteById(id);
    }
 
    @Override
    public MesWmReturnIssueLineDO getReturnIssueLine(Long id) {
        return issueLineMapper.selectById(id);
    }
 
    @Override
    public PageResult<MesWmReturnIssueLinePageVO> getReturnIssueLinePage(MesWmReturnIssueLinePageReqVO pageReqVO) {
        return issueLineMapper.selectPage(pageReqVO);
    }
 
    @Override
    public List<MesWmReturnIssueLineDO> getReturnIssueLineListByIssueId(Long issueId) {
        return issueLineMapper.selectListByIssueId(issueId);
    }
 
    @Override
    public void deleteReturnIssueLineByIssueId(Long issueId) {
        issueLineMapper.deleteByIssueId(issueId);
    }
 
    @Override
    public MesWmReturnIssueLineDO validateReturnIssueLineExists(Long id) {
        MesWmReturnIssueLineDO line = issueLineMapper.selectById(id);
        if (line == null) {
            throw exception(WM_RETURN_ISSUE_LINE_NOT_EXISTS);
        }
        return line;
    }
 
    /**
     * 校验保存时的关联数据
     */
    private MesWmReturnIssueDO validateReturnIssueLineSaveData(MesWmReturnIssueLineSaveReqVO reqVO) {
        // 校验父数据存在 + 草稿状态
        MesWmReturnIssueDO issue = issueService.validateReturnIssueExistsAndPrepare(reqVO.getIssueId());
        // 校验物料存在
        mdmItemService.validateItemExistsAndEnable(reqVO.getItemId());
        return issue;
    }
 
    @Override
    public void updateReturnIssueQualityStatusByIssueId(Long issueId, Integer issueType) {
        List<MesWmReturnIssueLineDO> lines = issueLineMapper.selectListByIssueId(issueId);
        for (MesWmReturnIssueLineDO line : lines) {
            Integer newStatus = calculateQualityStatus(line.getRqcCheckFlag(), issueType);
            if (ObjUtil.notEqual(newStatus, line.getQualityStatus())) {
                issueLineMapper.updateById(new MesWmReturnIssueLineDO()
                        .setId(line.getId()).setQualityStatus(newStatus));
            }
        }
    }
 
    /**
     * 根据 rqcCheckFlag 和退料类型,计算质量状态
     *
     * @param rqcCheckFlag 是否需要质检
     * @param issueType 退料类型
     * @return 质量状态
     */
    private Integer calculateQualityStatus(Boolean rqcCheckFlag, Integer issueType) {
        if (Boolean.TRUE.equals(rqcCheckFlag)) {
            return MesWmQualityStatusEnum.PENDING.getStatus(); // 待检
        }
        if (MesWmReturnIssueTypeEnum.REMAINDER.getType().equals(issueType)) {
            return MesWmQualityStatusEnum.PASS.getStatus(); // 合格(余料退回直接合格)
        }
        return MesWmQualityStatusEnum.FAIL.getStatus(); // 不合格
    }
 
    @Override
    public void updateReturnIssueLineWhenRqcFinish(Long sourceLineId, Long sourceDocId, Integer checkResult,
                                                    BigDecimal qualifiedQuantity, BigDecimal unqualifiedQuantity) {
        MesWmReturnIssueLineDO sourceLine = validateReturnIssueLineExists(sourceLineId);
        boolean hasUnqualified = unqualifiedQuantity != null && unqualifiedQuantity.compareTo(BigDecimal.ZERO) > 0;
        boolean hasQualified = qualifiedQuantity != null && qualifiedQuantity.compareTo(BigDecimal.ZERO) > 0;
 
        // 1. 根据合格/不合格品数量,更新退料单行的质量状态
        if (!hasUnqualified) {
            // 1.A 情况一:全部合格
            issueLineMapper.updateById(new MesWmReturnIssueLineDO()
                    .setId(sourceLineId).setQualityStatus(MesWmQualityStatusEnum.PASS.getStatus()));
        } else if (!hasQualified) {
            // 1.B 情况二:全部不合格
            issueLineMapper.updateById(new MesWmReturnIssueLineDO()
                    .setId(sourceLineId).setQualityStatus(MesWmQualityStatusEnum.FAIL.getStatus()));
        } else {
            // 1.C 情况三:部分合格部分不合格 → 拆分行
            // 1.C.1 新增一行不合格品
            MesWmReturnIssueLineDO unqualifiedLine = new MesWmReturnIssueLineDO()
                    .setIssueId(sourceLine.getIssueId())
                    .setMaterialStockId(sourceLine.getMaterialStockId())
                    .setItemId(sourceLine.getItemId())
                    .setQuantity(unqualifiedQuantity)
                    .setBatchId(sourceLine.getBatchId())
                    .setRqcId(sourceLine.getRqcId())
                    .setRqcCheckFlag(sourceLine.getRqcCheckFlag())
                    .setQualityStatus(MesWmQualityStatusEnum.FAIL.getStatus())
                    .setRemark(sourceLine.getRemark());
            issueLineMapper.insert(unqualifiedLine);
            // 1.C.2 更新原行为合格品(数量调整为合格数量)
            issueLineMapper.updateById(new MesWmReturnIssueLineDO()
                    .setId(sourceLineId)
                    .setQuantity(qualifiedQuantity)
                    .setQualityStatus(MesWmQualityStatusEnum.PASS.getStatus()));
        }
 
        // 2. 检查退料单下是否还有待检验的行,若全检完则将退料单状态设为"待上架"
        if (sourceDocId != null) {
            List<MesWmReturnIssueLineDO> allLines = issueLineMapper.selectListByIssueId(sourceDocId);
            boolean allInspected = !CollUtil.contains(allLines,
                    line -> Objects.equals(line.getQualityStatus(), MesWmQualityStatusEnum.PENDING.getStatus()));
            if (allInspected) {
                issueService.updateReturnIssueStatus(sourceDocId, MesWmReturnIssueStatusEnum.APPROVING.getStatus());
            }
        }
    }
 
}