云
20 小时以前 704265308b1227dbada5a36b2027b588c062ded2
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
package cn.iocoder.yudao.module.mes.service.pro.scan;
 
import cn.iocoder.yudao.module.mes.dal.mysql.pro.bagcode.MesProBagCodeMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.pro.batch.MesProBatchMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.pro.pallet.MesProPalletMapper;
import org.apache.ibatis.annotations.Update;
import org.h2.jdbcx.JdbcDataSource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import static org.junit.jupiter.api.Assertions.*;
 
/** 执行 Mapper 中的实际 SQL,验证混扫时状态与袋数的结果。 */
class InboundCompletionSqlTest {
    private JdbcTemplate db;
    private NamedParameterJdbcTemplate named;
    @BeforeEach void setup() {
        JdbcDataSource source = new JdbcDataSource();
        source.setURL("jdbc:h2:mem:" + UUID.randomUUID() + ";MODE=MySQL;DB_CLOSE_DELAY=-1");
        db = new JdbcTemplate(source); named = new NamedParameterJdbcTemplate(source);
        db.execute("CREATE TABLE mes_pro_batch(id BIGINT PRIMARY KEY,status INT,deleted INT DEFAULT 0,inbound_time TIMESTAMP,inbound_event_id BIGINT,inbound_device_code VARCHAR(64),inbound_line_code VARCHAR(64),inbound_bag_quantity INT,update_time TIMESTAMP)");
        db.execute("CREATE TABLE mes_pro_pallet(id BIGINT PRIMARY KEY,batch_id BIGINT,status INT,deleted INT DEFAULT 0,inbound_time TIMESTAMP,inbound_event_id BIGINT,update_time TIMESTAMP)");
        db.execute("CREATE TABLE mes_pro_bag_code(id BIGINT PRIMARY KEY,batch_id BIGINT,pallet_id BIGINT,status INT,deleted INT DEFAULT 0,inbound_time TIMESTAMP,inbound_event_id BIGINT,inbound_device_code VARCHAR(64),inbound_line_code VARCHAR(64),update_time TIMESTAMP)");
        db.update("INSERT INTO mes_pro_batch(id,status) VALUES(1,20)");
        db.update("INSERT INTO mes_pro_pallet(id,batch_id,status) VALUES(1,1,10),(2,1,10)");
        db.update("INSERT INTO mes_pro_bag_code(id,batch_id,pallet_id,status) VALUES(1,1,1,20),(2,1,1,20),(3,1,2,20),(4,1,2,30)");
    }
    private int run(Class<?> mapper, String method, Map<String,Object> values) {
        var target = java.util.Arrays.stream(mapper.getMethods()).filter(m -> m.getName().equals(method)).findFirst().orElseThrow();
        String sql = String.join(" ", target.getAnnotation(Update.class).value()).replaceAll("#\\{(\\w+)\\}", ":$1");
        return named.update(sql, values);
    }
    private Map<String,Object> args(Long id) {
        Map<String,Object> values = new HashMap<>();
        values.put("id",id);values.put("batchId",1L);values.put("palletId",id);
        values.put("eventId",10L);values.put("deviceCode","PDA");values.put("lineCode","L1");
        return values;
    }
    private void refresh() {
        run(MesProPalletMapper.class,"markCompletedInboundByBatchId",args(1L));
        run(MesProBatchMapper.class,"refreshInboundProgress",args(1L));
    }
    private int batchValue(String column) { return db.queryForObject("SELECT " + column + " FROM mes_pro_batch WHERE id=1",Integer.class); }
    @Test void bagThenPalletThenLastBagCompletesOnlyAtTheEnd() {
        run(MesProBagCodeMapper.class,"markInbound",args(1L));refresh();
        assertEquals(20,batchValue("status")); assertEquals(1,batchValue("inbound_bag_quantity"));
        assertNull(db.queryForObject("SELECT inbound_event_id FROM mes_pro_pallet WHERE id=1",Long.class));
        assertEquals(1,run(MesProBagCodeMapper.class,"markInboundByPalletId",args(1L)));
        refresh();assertEquals(20,batchValue("status"));assertEquals(2,batchValue("inbound_bag_quantity"));
        assertEquals(10L,db.queryForObject("SELECT inbound_event_id FROM mes_pro_pallet WHERE id=1",Long.class));
        run(MesProBagCodeMapper.class,"markInbound",args(3L));refresh();
        assertEquals(30,batchValue("status"));assertEquals(3,batchValue("inbound_bag_quantity"));
        assertEquals(10L,db.queryForObject("SELECT inbound_event_id FROM mes_pro_pallet WHERE id=2",Long.class));
        assertNull(db.queryForObject("SELECT inbound_event_id FROM mes_pro_bag_code WHERE id=4",Long.class));
        assertEquals(0,run(MesProBagCodeMapper.class,"markInboundByBatchId",args(1L)));
        refresh();assertEquals(3,batchValue("inbound_bag_quantity"));
    }
    @Test void wholeBatchExcludesCanceledAndDeletedBags() {
        db.update("UPDATE mes_pro_bag_code SET deleted=1 WHERE id=2");
        assertEquals(2,run(MesProBagCodeMapper.class,"markInboundByBatchId",args(1L)));
        refresh();assertEquals(30,batchValue("status"));assertEquals(2,batchValue("inbound_bag_quantity"));
    }
    @Test void emptyBatchDoesNotCompleteAndCanceledBatchDoesNotChange() {
        db.update("DELETE FROM mes_pro_bag_code");refresh();assertEquals(20,batchValue("status"));
        db.update("UPDATE mes_pro_batch SET status=40");refresh();assertEquals(40,batchValue("status"));
    }
}