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
package cn.iocoder.yudao.module.mes.service.wm.productissue;
 
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
import cn.iocoder.yudao.module.mes.controller.admin.wm.productissue.vo.detail.MesWmProductIssueDetailSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.md.item.MesMdItemDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDetailDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productissue.MesWmProductIssueLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productissue.MesWmProductIssueDetailMapper;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmProductIssueStatusEnum;
import cn.iocoder.yudao.module.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.wm.materialstock.MesWmMaterialStockService;
import cn.iocoder.yudao.module.mes.service.wm.warehouse.MesWmWarehouseAreaService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
 
import java.util.List;
 
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
 
/**
 * MES 领料出库明细 Service 实现类
 */
@Service
@Validated
public class MesWmProductIssueDetailServiceImpl implements MesWmProductIssueDetailService {
 
    @Resource
    private MesWmProductIssueDetailMapper issueDetailMapper;
 
    @Resource
    @Lazy
    private MesWmProductIssueService issueService;
    @Resource
    @Lazy
    private MesWmProductIssueLineService issueLineService;
    @Resource
    private MesWmWarehouseAreaService warehouseAreaService;
    @Resource
    private MesWmMaterialStockService materialStockService;
    @Resource
    private MesMdItemService mesMdItemService;
 
    @Override
    public Long createProductIssueDetail(MesWmProductIssueDetailSaveReqVO createReqVO) {
        // 校验数据
        validateProductIssueDetailSaveData(createReqVO);
 
        // 插入
        MesWmProductIssueDetailDO detail = BeanUtils.toBean(createReqVO, MesWmProductIssueDetailDO.class);
        issueDetailMapper.insert(detail);
        return detail.getId();
    }
 
    @Override
    public void updateProductIssueDetail(MesWmProductIssueDetailSaveReqVO updateReqVO) {
        // 校验存在
        validateProductIssueDetailExists(updateReqVO.getId());
        // 校验数据
        validateProductIssueDetailSaveData(updateReqVO);
 
        // 更新
        MesWmProductIssueDetailDO updateObj = BeanUtils.toBean(updateReqVO, MesWmProductIssueDetailDO.class);
        issueDetailMapper.updateById(updateObj);
    }
 
    @Override
    public void deleteProductIssueDetail(Long id) {
        // 校验存在
        MesWmProductIssueDetailDO detail = issueDetailMapper.selectById(id);
        if (detail == null) {
            throw exception(WM_PRODUCT_ISSUE_DETAIL_NOT_EXISTS);
        }
        // 校验主单状态为草稿或待拣货(允许在拣货模式删除明细)
        MesWmProductIssueLineDO line = issueLineService.validateProductIssueLineExists(detail.getLineId());
        MesWmProductIssueDO issue = issueService.validateProductIssueExists(line.getIssueId());
        if (!ObjectUtils.equalsAny(issue.getStatus(),
                MesWmProductIssueStatusEnum.PREPARE.getStatus(),
                MesWmProductIssueStatusEnum.APPROVING.getStatus())) {
            throw exception(WM_PRODUCT_ISSUE_STATUS_INVALID);
        }
 
        // 删除
        issueDetailMapper.deleteById(id);
    }
 
    @Override
    public MesWmProductIssueDetailDO getProductIssueDetail(Long id) {
        return issueDetailMapper.selectById(id);
    }
 
    @Override
    public List<MesWmProductIssueDetailDO> getProductIssueDetailListByLineId(Long lineId) {
        return issueDetailMapper.selectListByLineId(lineId);
    }
 
    @Override
    public List<MesWmProductIssueDetailDO> getProductIssueDetailListByIssueId(Long issueId) {
        return issueDetailMapper.selectListByIssueId(issueId);
    }
 
    @Override
    public void deleteProductIssueDetailByIssueId(Long issueId) {
        issueDetailMapper.deleteByIssueId(issueId);
    }
 
    @Override
    public void deleteProductIssueDetailByLineId(Long lineId) {
        issueDetailMapper.deleteByLineId(lineId);
    }
 
    private void validateProductIssueDetailExists(Long id) {
        if (issueDetailMapper.selectById(id) == null) {
            throw exception(WM_PRODUCT_ISSUE_DETAIL_NOT_EXISTS);
        }
    }
 
    /**
     * 校验保存时的关联数据
     */
    private void validateProductIssueDetailSaveData(MesWmProductIssueDetailSaveReqVO reqVO) {
        // 校验父数据存在
        MesWmProductIssueLineDO line = issueLineService.validateProductIssueLineExists(reqVO.getLineId());
        MesMdItemDO item = mesMdItemService.getItem(line.getItemId());
        if (ObjUtil.notEqual(line.getIssueId(), reqVO.getIssueId())) {
            throw exception(WM_PRODUCT_ISSUE_DETAIL_LINE_NOT_MATCH);
        }
        // 校验主单状态为待拣货(只有 APPROVING 状态才允许新增/修改明细)
        MesWmProductIssueDO issue = issueService.validateProductIssueExists(line.getIssueId());
        if (ObjUtil.notEqual(MesWmProductIssueStatusEnum.APPROVING.getStatus(), issue.getStatus())) {
            throw exception(WM_PRODUCT_ISSUE_STATUS_INVALID);
        }
        // 校验物料匹配(明细 itemId 必须与行 itemId 一致)
        validateDetailItemMatch(reqVO.getItemId(), item.getMdmItemId());
        // 校验仓库、库区、库位的关联关系
        warehouseAreaService.validateWarehouseAreaExists(
                reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId());
        // 校验库存记录
        materialStockService.validateSelectedStock(
                reqVO.getMaterialStockId(), reqVO.getItemId(), reqVO.getBatchId(), reqVO.getBatchCode(),
                reqVO.getWarehouseId(), reqVO.getLocationId(), reqVO.getAreaId(), reqVO.getQuantity());
    }
 
    /**
     * 校验明细物料与行物料一致
     */
    private void validateDetailItemMatch(Long detailItemId, Long lineItemId) {
        if (ObjUtil.notEqual(detailItemId, lineItemId)) {
            throw exception(WM_PRODUCT_ISSUE_DETAIL_ITEM_MISMATCH);
        }
    }
 
}