2026-06-26 20b96473f2520590a0dca6b775b81e3ea06a77a0
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
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.mes.service.md.item.MesMdItemService;
import cn.iocoder.yudao.module.mes.service.wm.batch.MesWmBatchService;
 
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 MesMdItemService itemService;
    @MockitoBean
    private MesWmBatchService batchService;
 
    @Test
    public void testUpdateProductSalesLineWhenOqcFinish_pass() {
        // 准备参数
        Long oqcId = randomLongId();
        Integer checkResult = MesQcCheckResultEnum.PASS.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());
    }
 
    @Test
    public void testUpdateProductSalesLineWhenOqcFinish_fail() {
        // 准备参数
        Long oqcId = randomLongId();
        Integer checkResult = MesQcCheckResultEnum.FAIL.getType();
 
        // 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());
    }
 
    @Test
    public void testUpdateProductSalesLineWhenOqcFinish_cancelWhenNg() {
        // 准备数据:同一出库单下 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.FAIL.getType());
 
        // 断言:应该调用 cancelProductSales
        verify(productSalesService).cancelProductSales(eq(salesId));
    }
 
    @Test
    public void testUpdateProductSalesLineWhenOqcFinish_noCancelWhenAllPass() {
        // 准备数据:同一出库单下 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.PASS.getType());
 
        // 断言:不应该调用 cancelProductSales
        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.FAIL.getType());
 
        // 断言:第 2 行不合格 → 应该取消出库单
        verify(productSalesService).cancelProductSales(eq(salesId));
    }
 
}