刘光辉
4 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
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
package jnpf.elnService.impl;
 
import jnpf.elnEntity.field.ElnFieldForms;
import jnpf.elnEntity.field.ElnFieldVersionEntity;
import jnpf.elnEntity.runtime.ElnRecordFieldValueEntity;
import jnpf.exception.DataException;
import jnpf.lims.api.model.ElnSourcePropertyRef;
import jnpf.lims.api.model.ElnSourceSnapshot;
 
import java.time.Instant;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
 
/** Shared validation for configured snapshots at creation and explicit synchronization. */
final class ElnConfiguredSourceValues {
    private ElnConfiguredSourceValues() { }
 
    static ElnSourcePropertyRef reference(ElnFieldForms.Read read) {
        if (read.getPropertyRevision() == null || read.getPropertyRevision() < 1
                || read.getProperty() == null || !read.getProperty().matches("[a-zA-Z][a-zA-Z0-9_.-]{0,79}")) {
            throw new DataException("LIMS 来源固定版本无效");
        }
        return new ElnSourcePropertyRef(read.getProperty(), read.getPropertyRevision());
    }
 
    static Map<ElnSourcePropertyRef, ElnSourceSnapshot> index(String itemId,
            List<ElnSourcePropertyRef> requested, List<ElnSourceSnapshot> snapshots) {
        if (snapshots == null) throw new DataException("LIMS 来源快照响应为空");
        Map<ElnSourcePropertyRef, ElnSourceSnapshot> result = new LinkedHashMap<>();
        for (ElnSourceSnapshot snapshot : snapshots) {
            if (snapshot == null || !Objects.equals(itemId, snapshot.getSourceRef())) {
                throw new DataException("LIMS 来源快照检验项不一致");
            }
            ElnSourcePropertyRef ref = new ElnSourcePropertyRef(snapshot.getPropertyCode(), snapshot.getPropertyRevision());
            if (!requested.contains(ref) || result.putIfAbsent(ref, snapshot) != null) {
                throw new DataException("LIMS 来源快照版本不一致或重复");
            }
        }
        if (result.size() != new java.util.HashSet<>(requested).size()) {
            throw new DataException("LIMS 来源快照缺少固定版本结果");
        }
        return result;
    }
 
    static void apply(ElnRecordFieldValueEntity value, ElnFieldVersionEntity version, ElnSourceSnapshot snapshot) {
        if (snapshot == null) throw new DataException("LIMS 来源快照为空");
        boolean missing = "MISSING".equals(snapshot.getOutcomeCode()) || "NOT_APPLICABLE".equals(snapshot.getOutcomeCode());
        if (!"SUCCESS".equals(snapshot.getOutcomeCode()) && !missing) {
            throw new DataException("LIMS 来源取数失败");
        }
        if (missing && Integer.valueOf(1).equals(version.getShifouBitian())) {
            throw new DataException("必填 LIMS 来源缺失或不适用");
        }
        if (!Objects.equals(version.getShujuLeixing(), snapshot.getDataType())
                && !("CHECKBOX".equals(version.getShujuLeixing()) && "BOOLEAN".equals(snapshot.getDataType()))
                && !("TEXT".equals(snapshot.getDataType()) && ("TEXTAREA".equals(version.getShujuLeixing())
                        || "SELECT".equals(version.getShujuLeixing())))) {
            throw new DataException("LIMS 来源类型与固定字段版本不兼容");
        }
        if (!missing && (snapshot.getValue() == null || snapshot.getValue().trim().isEmpty())) {
            throw new DataException("LIMS 来源成功结果不能为空");
        }
        Date acquiredAt;
        try { acquiredAt = Date.from(Instant.parse(snapshot.getAcquiredAt())); }
        catch (RuntimeException invalid) { throw new DataException("LIMS 来源获取时间无效"); }
        if (missing) {
            value.setZhiWenben(null);
            value.setZhiShuzhi(null);
            value.setZhiRiqi(null);
        } else if ("DECIMAL".equals(snapshot.getDataType())) {
            try {
                java.math.BigDecimal number = new java.math.BigDecimal(snapshot.getValue());
                java.math.BigDecimal normalized = number.stripTrailingZeros();
                if (normalized.scale() > 18 || (long) normalized.precision() - normalized.scale() > 20) {
                    throw new DataException("LIMS 来源数值超出快照精度范围,不能舍入保存");
                }
                value.setZhiShuzhi(number);
            }
            catch (NumberFormatException invalid) { throw new DataException("LIMS 来源数值无效"); }
        } else if ("DATE".equals(snapshot.getDataType())) {
            try { value.setZhiRiqi(java.sql.Date.valueOf(java.time.LocalDate.parse(snapshot.getValue()))); }
            catch (RuntimeException invalid) { throw new DataException("LIMS 来源日期无效"); }
        } else if ("DATETIME".equals(snapshot.getDataType())) {
            try {
                java.time.temporal.TemporalAccessor parsed = java.time.format.DateTimeFormatter.ISO_DATE_TIME
                        .parseBest(snapshot.getValue(), java.time.OffsetDateTime::from, java.time.LocalDateTime::from);
                if (parsed.get(java.time.temporal.ChronoField.NANO_OF_SECOND) != 0) {
                    throw new DataException("LIMS 来源时间超出快照秒级精度,不能舍入保存");
                }
                value.setZhiRiqi(parsed instanceof java.time.OffsetDateTime
                        ? Date.from(((java.time.OffsetDateTime) parsed).toInstant())
                        : java.sql.Timestamp.valueOf((java.time.LocalDateTime) parsed));
            }
            catch (DataException invalid) { throw invalid; }
            catch (RuntimeException invalid) { throw new DataException("LIMS 来源时间无效"); }
        } else if ("BOOLEAN".equals(snapshot.getDataType())) {
            if (!"true".equals(snapshot.getValue()) && !"false".equals(snapshot.getValue())) {
                throw new DataException("LIMS 来源布尔值无效");
            }
            value.setZhiWenben(snapshot.getValue());
        } else {
            value.setZhiWenben(snapshot.getValue());
        }
        value.setZhiLaiyuan("LIMS_TASK");
        value.setYuanShuxing(snapshot.getPropertyCode());
        value.setYuanShuxingBanben(snapshot.getPropertyRevision());
        value.setYuanQuzhiZhuangtai(snapshot.getOutcomeCode());
        value.setYuanQuzhiYuanyin(snapshot.getReasonCode());
        value.setYuanXueyuan(snapshot.getLineage());
        value.setYuanYinyongLeixing("LIMS_TASK");
        value.setYuanYinyongId(snapshot.getSourceRef());
        value.setYuanHuoquShijian(acquiredAt);
    }
}