gaoluyang
5 天以前 6b8585fc452ecdcaa82d86fab79a9f27bb442851
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
package cn.iocoder.yudao.module.mes.service.wm.productsales;
 
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.mes.dal.dataobject.wm.productsales.MesWmProductSalesLineDO;
import cn.iocoder.yudao.module.mes.dal.mysql.wm.productsales.MesWmProductSalesLineMapper;
import cn.iocoder.yudao.module.mes.enums.qc.MesQcCheckResultEnum;
import cn.iocoder.yudao.module.mes.enums.wm.MesWmQualityStatusEnum;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
 
import cn.iocoder.yudao.module.erp.api.sale.ErpSaleOrderApi;
import cn.iocoder.yudao.module.mes.service.mdm.MesMdmItemService;
import cn.iocoder.yudao.module.mes.service.qc.oqc.MesQcOqcService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
import cn.iocoder.yudao.module.mes.service.wm.salesnotice.MesWmSalesNoticeLineService;
 
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;
 
/**
 * {@link MesWmProductSalesLineServiceImpl} 的单元测试类
 *
 * @author 超级管理员
 */
@Import(MesWmProductSalesLineServiceImpl.class)
public class MesWmProductSalesLineServiceImplTest extends BaseDbUnitTest {
 
    @Resource
    private MesWmProductSalesLineServiceImpl productSalesLineService;
 
    @Resource
    private MesWmProductSalesLineMapper productSalesLineMapper;
 
    @MockitoBean
    private MesWmProductSalesService productSalesService;
 
    @MockitoBean
    private MesWmProductSalesDetailService productSalesDetailService;
 
    @MockitoBean
    private MesMdmItemService mdmItemService;
    @MockitoBean
    private MesWmBatchService batchService;
    @MockitoBean
    private MesWmSalesNoticeLineService salesNoticeLineService;
    @MockitoBean
    private MesQcOqcService oqcService;
    @MockitoBean
    private ErpSaleOrderApi saleOrderApi;
 
    @Test
    public void testUpdateProductSalesLineWhenOqcFinish_pass() {
        // 准备参数
        Long oqcId = randomLongId();
        Integer checkResult = MesQcCheckResultEnum.QUALIFIED.getType();
 
        // mock 数据
        MesWmProductSalesLineDO lineDO = randomPojo(MesWmProductSalesLineDO.class, o -> {
            o.setOqcCheckFlag(true);         // 需要 OQC 检验
            o.setQualityStatus(null);    // 初始为空
        });
        productSalesLineMapper.insert(lineDO);
 
        // 调用
        productSalesLineService.updateProductSalesLineWhenOqcFinish(lineDO.getId(), oqcId, checkResult);
 
        // 断言:验证行字段更新
        MesWmProductSalesLineDO updateLine = productSalesLineMapper.selectById(lineDO.getId());
        assertEquals(oqcId, updateLine.getOqcId());
        assertEquals(MesWmQualityStatusEnum.PASS.getStatus(), updateLine.getQualityStatus());
        // 断言:全部需检行合格 → 出库单自动流转待拣货
        verify(productSalesService).confirmProductSales(lineDO.getSalesId());
    }
 
    @Test
    public void testUpdateProductSalesLineWhenOqcFinish_fail() {
        // 准备参数:2 表示校验不通过
        Long oqcId = randomLongId();
        Integer checkResult = 2;
 
        // mock 数据
        MesWmProductSalesLineDO lineDO = randomPojo(MesWmProductSalesLineDO.class, o -> {
            o.setOqcCheckFlag(true);
            o.setQualityStatus(null);
        });
        productSalesLineMapper.insert(lineDO);
 
        // 调用
        productSalesLineService.updateProductSalesLineWhenOqcFinish(lineDO.getId(), oqcId, checkResult);
 
        // 断言:验证行字段更新
        MesWmProductSalesLineDO updateLine = productSalesLineMapper.selectById(lineDO.getId());
        assertEquals(oqcId, updateLine.getOqcId());
        assertEquals(MesWmQualityStatusEnum.FAIL.getStatus(), updateLine.getQualityStatus());
        // 断言:存在不合格行时保持待检测,不自动取消整张出库单
        verify(productSalesService, never()).cancelProductSales(anyLong());
        verify(productSalesService, never()).confirmProductSales(anyLong());
    }
 
    @Test
    public void testUpdateProductSalesLineWhenOqcFinish_noCancelWhenNg() {
        // 准备数据:同一出库单下 2 行,第 1 行已合格,第 2 行即将变更为不合格
        Long salesId = randomLongId();
        MesWmProductSalesLineDO line1 = randomPojo(MesWmProductSalesLineDO.class, o -> {
            o.setSalesId(salesId);
            o.setOqcCheckFlag(true);
            o.setQualityStatus(MesWmQualityStatusEnum.PASS.getStatus());
        });
        productSalesLineMapper.insert(line1);
 
        MesWmProductSalesLineDO line2 = randomPojo(MesWmProductSalesLineDO.class, o -> {
            o.setSalesId(salesId);
            o.setOqcCheckFlag(true);
            o.setQualityStatus(null); // 待检
        });
        productSalesLineMapper.insert(line2);
 
        // 调用:第 2 行质检不合格
        productSalesLineService.updateProductSalesLineWhenOqcFinish(
                line2.getId(), randomLongId(), 2);
 
        // 断言:不合格行留待后续处置,不能自动取消出库单
        verify(productSalesService, never()).cancelProductSales(anyLong());
        verify(productSalesService, never()).confirmProductSales(anyLong());
    }
 
    @Test
    public void testUpdateProductSalesLineWhenOqcFinish_confirmWhenAllPass() {
        // 准备数据:同一出库单下 2 行,第 1 行已合格,第 2 行即将变更为合格
        Long salesId = randomLongId();
        MesWmProductSalesLineDO line1 = randomPojo(MesWmProductSalesLineDO.class, o -> {
            o.setSalesId(salesId);
            o.setOqcCheckFlag(true);
            o.setQualityStatus(MesWmQualityStatusEnum.PASS.getStatus());
        });
        productSalesLineMapper.insert(line1);
 
        MesWmProductSalesLineDO line2 = randomPojo(MesWmProductSalesLineDO.class, o -> {
            o.setSalesId(salesId);
            o.setOqcCheckFlag(true);
            o.setQualityStatus(null);
        });
        productSalesLineMapper.insert(line2);
 
        // 调用:第 2 行质检合格
        productSalesLineService.updateProductSalesLineWhenOqcFinish(
                line2.getId(), randomLongId(), MesQcCheckResultEnum.QUALIFIED.getType());
 
        // 断言:全部需检行合格 → 流转待拣货,不取消出库单
        verify(productSalesService).confirmProductSales(eq(salesId));
        verify(productSalesService, never()).cancelProductSales(anyLong());
    }
 
    @Test
    public void testUpdateProductSalesLineWhenOqcFinish_skipNonOqcCheckLines() {
        // 准备数据:同一出库单下 2 行,第 1 行不需要 OQC 检验(oqcCheckFlag=false),第 2 行需要检验且不合格
        Long salesId = randomLongId();
        MesWmProductSalesLineDO line1 = randomPojo(MesWmProductSalesLineDO.class, o -> {
            o.setSalesId(salesId);
            o.setOqcCheckFlag(false); // 不需要 OQC 检验
            o.setQualityStatus(null);
        });
        productSalesLineMapper.insert(line1);
 
        MesWmProductSalesLineDO line2 = randomPojo(MesWmProductSalesLineDO.class, o -> {
            o.setSalesId(salesId);
            o.setOqcCheckFlag(true);
            o.setQualityStatus(null);
        });
        productSalesLineMapper.insert(line2);
 
        // 调用:第 2 行质检合格
        productSalesLineService.updateProductSalesLineWhenOqcFinish(
                line2.getId(), randomLongId(), MesQcCheckResultEnum.QUALIFIED.getType());
 
        // 断言:未勾选出货检验的行不参与待检判断 → 全部需检行合格后流转待拣货
        verify(productSalesService).confirmProductSales(eq(salesId));
        verify(productSalesService, never()).cancelProductSales(anyLong());
    }
 
}