Skip to main content

automapper_validation/generated/fv2504/
ordchg_conditions_fv2504.rs

1// <auto-generated>
2// Generated by automapper-generator generate-conditions
3// AHB: xml-migs-and-ahbs/FV2504/ORDCHG_AHB_1_0a_20241001.xml
4// Generated: 2026-03-12T10:14:16Z
5// </auto-generated>
6
7#[allow(unused_imports)]
8use crate::eval::format_validators::*;
9use crate::eval::{ConditionEvaluator, ConditionResult, EvaluationContext};
10
11/// Generated condition evaluator for ORDCHG FV2504.
12pub struct OrdchgConditionEvaluatorFV2504 {
13    // External condition IDs that require runtime context.
14    external_conditions: std::collections::HashSet<u32>,
15}
16
17impl Default for OrdchgConditionEvaluatorFV2504 {
18    fn default() -> Self {
19        let mut external_conditions = std::collections::HashSet::new();
20        external_conditions.insert(1);
21        external_conditions.insert(494);
22        Self {
23            external_conditions,
24        }
25    }
26}
27
28impl ConditionEvaluator for OrdchgConditionEvaluatorFV2504 {
29    fn message_type(&self) -> &str {
30        "ORDCHG"
31    }
32
33    fn format_version(&self) -> &str {
34        "FV2504"
35    }
36
37    fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
38        match condition {
39            1 => self.evaluate_1(ctx),
40            2 => self.evaluate_2(ctx),
41            3 => self.evaluate_3(ctx),
42            4 => self.evaluate_4(ctx),
43            5 => self.evaluate_5(ctx),
44            494 => self.evaluate_494(ctx),
45            500 => self.evaluate_500(ctx),
46            501 => self.evaluate_501(ctx),
47            502 => self.evaluate_502(ctx),
48            503 => self.evaluate_503(ctx),
49            931 => self.evaluate_931(ctx),
50            939 => self.evaluate_939(ctx),
51            940 => self.evaluate_940(ctx),
52            _ => ConditionResult::Unknown,
53        }
54    }
55
56    fn is_external(&self, condition: u32) -> bool {
57        self.external_conditions.contains(&condition)
58    }
59    fn is_known(&self, condition: u32) -> bool {
60        matches!(
61            condition,
62            1 | 2 | 3 | 4 | 5 | 494 | 500 | 501 | 502 | 503 | 931 | 939 | 940
63        )
64    }
65}
66
67impl OrdchgConditionEvaluatorFV2504 {
68    /// [1] MP-ID nur aus Sparte Strom
69    /// EXTERNAL: Requires context from outside the message.
70    fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
71        ctx.external.evaluate("mp_id_only_strom")
72    }
73
74    /// [2] Wenn BGM+Z51 (Sperrung) vorhanden
75    fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
76        ctx.has_qualifier("BGM", 0, "Z51")
77    }
78
79    /// [3] Wenn BGM+Z52 (Entsperrung) vorhanden
80    fn evaluate_3(&self, ctx: &EvaluationContext) -> ConditionResult {
81        ctx.has_qualifier("BGM", 0, "Z52")
82    }
83
84    /// [4] wenn im DE3155 in demselben COM der Code EM vorhanden ist
85    fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
86        let coms = ctx.find_segments("COM");
87        ConditionResult::from(coms.iter().any(|com| {
88            com.elements
89                .first()
90                .and_then(|e| e.get(1))
91                .is_some_and(|v| v == "EM")
92        }))
93    }
94
95    /// [5] wenn im DE3155 in demselben COM der Code TE / FX / AJ / AL vorhanden ist
96    fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
97        let coms = ctx.find_segments("COM");
98        ConditionResult::from(coms.iter().any(|com| {
99            com.elements
100                .first()
101                .and_then(|e| e.get(1))
102                .is_some_and(|v| matches!(v.as_str(), "TE" | "FX" | "AJ" | "AL"))
103        }))
104    }
105
106    /// [494] Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.
107    /// EXTERNAL: Requires context from outside the message.
108    // REVIEW: Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt — the date must be the document creation time or earlier. Verifying this requires knowing the actual document creation timestamp at runtime (i.e., 'now' or an authoritative creation time external to the message), which is not derivable from the EDIFACT segments alone. (medium confidence)
109    fn evaluate_494(&self, ctx: &EvaluationContext) -> ConditionResult {
110        ctx.external.evaluate("document_date_not_after_creation")
111    }
112
113    /// [500] Hinweis: Dokumentennummer aus BGM DE1004 der ORDERS
114    fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
115        // Hinweis: Dokumentennummer aus BGM DE1004 der ORDERS — informational note, always applies
116        ConditionResult::True
117    }
118
119    /// [501] Hinweis: Wert aus BGM+Z33 DE1004 der IFTSTA mit der die Information über den Entsperrauftrag übermittelt wurde
120    fn evaluate_501(&self, _ctx: &EvaluationContext) -> ConditionResult {
121        // Hinweis: Wert aus BGM+Z33 DE1004 der IFTSTA mit der die Information über den Entsperrauftrag übermittelt wurde — informational note, always applies
122        ConditionResult::True
123    }
124
125    /// [502] Hinweis: Vorgangsnummer aus CNI DE1490 der IFTSTA mit BGM+Z33 mit der die Information über den Entsperrauftrag übermittelt wurde
126    fn evaluate_502(&self, _ctx: &EvaluationContext) -> ConditionResult {
127        // Hinweis: Vorgangsnummer aus CNI DE1490 der IFTSTA mit BGM+Z33 mit der die Information über den Entsperrauftrag übermittelt wurde — informational note, always applies
128        ConditionResult::True
129    }
130
131    /// [503] Hinweis: Es darf nur eine Information im DE3148 übermittelt werden
132    fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
133        // Hinweis: Es darf nur eine Information im DE3148 übermittelt werden — informational note, always applies
134        ConditionResult::True
135    }
136
137    /// [931] Format: ZZZ = +00
138    // REVIEW: Format constraint: ZZZ (timezone) must be '+00' (UTC). DTM elements[0][1] contains the datetime value including timezone suffix. Checks all DTM segments to ensure their datetime values end with '+00'. Returns Unknown when no DTM segments present, False if any DTM violates the constraint. (medium confidence)
139    fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
140        let dtms = ctx.find_segments("DTM");
141        if dtms.is_empty() {
142            return ConditionResult::Unknown;
143        }
144        for dtm in &dtms {
145            if let Some(value) = dtm.elements.first().and_then(|e| e.get(1)) {
146                if !value.is_empty() && !value.ends_with("+00") {
147                    return ConditionResult::False;
148                }
149            }
150        }
151        ConditionResult::True
152    }
153
154    /// [939] Format: Die Zeichenkette muss die Zeichen @ und . enthalten
155    // REVIEW: Format check: the email address string in COM DE3148 (elements[0][0]) when DE3155 (elements[0][1]) is 'EM' must contain both '@' and '.'. Returns Unknown if no EM-typed COM segment is found. (medium confidence)
156    fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
157        let coms = ctx.find_segments("COM");
158        for com in &coms {
159            let is_email = com
160                .elements
161                .first()
162                .and_then(|e| e.get(1))
163                .is_some_and(|v| v == "EM");
164            if is_email {
165                let value = com
166                    .elements
167                    .first()
168                    .and_then(|e| e.first())
169                    .cloned()
170                    .unwrap_or_default();
171                return ConditionResult::from(value.contains('@') && value.contains('.'));
172            }
173        }
174        ConditionResult::Unknown
175    }
176
177    /// [940] Format: Die Zeichenkette muss mit dem Zeichen + beginnen und danach dürfen nur noch Ziffern folgen
178    // REVIEW: Format check: the phone/fax number string in COM DE3148 (elements[0][0]) when DE3155 (elements[0][1]) is TE/FX/AJ/AL must start with '+' followed by digits only. Returns Unknown if no phone-typed COM segment is found. (medium confidence)
179    fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
180        let coms = ctx.find_segments("COM");
181        for com in &coms {
182            let is_phone = com
183                .elements
184                .first()
185                .and_then(|e| e.get(1))
186                .is_some_and(|v| matches!(v.as_str(), "TE" | "FX" | "AJ" | "AL"));
187            if is_phone {
188                let value = com
189                    .elements
190                    .first()
191                    .and_then(|e| e.first())
192                    .cloned()
193                    .unwrap_or_default();
194                let mut chars = value.chars();
195                let starts_with_plus = chars.next() == Some('+');
196                let rest_all_digits = chars.all(|c| c.is_ascii_digit());
197                return ConditionResult::from(starts_with_plus && rest_all_digits);
198            }
199        }
200        ConditionResult::Unknown
201    }
202}