Skip to main content

automapper_validation/generated/fv2604/
partin_conditions_fv2604.rs

1// <auto-generated>
2// Generated by automapper-generator generate-conditions
3// AHB: xml-migs-and-ahbs/FV2604/PARTIN_AHB_1_0f_Fehlerkorrektur_20251211.xml
4// Generated: 2026-03-12T11:36:50Z
5// </auto-generated>
6
7// LLM-produced bodies aren't idiomatic Rust — silence stylistic lints at
8// file scope so `cargo clippy -D warnings` stays green. Correctness,
9// suspicious, and perf categories stay on so real bugs still surface.
10#![allow(clippy::style, clippy::complexity)]
11
12#[allow(unused_imports)]
13use crate::eval::format_validators::*;
14use crate::eval::{ConditionEvaluator, ConditionResult, EvaluationContext};
15
16/// Generated condition evaluator for PARTIN FV2604.
17pub struct PartinConditionEvaluatorFV2604 {
18    // External condition IDs that require runtime context.
19    external_conditions: std::collections::HashSet<u32>,
20}
21
22impl Default for PartinConditionEvaluatorFV2604 {
23    fn default() -> Self {
24        let mut external_conditions = std::collections::HashSet::new();
25        external_conditions.insert(1);
26        external_conditions.insert(2);
27        external_conditions.insert(4);
28        external_conditions.insert(5);
29        external_conditions.insert(9);
30        external_conditions.insert(17);
31        external_conditions.insert(18);
32        external_conditions.insert(19);
33        external_conditions.insert(20);
34        external_conditions.insert(21);
35        external_conditions.insert(22);
36        external_conditions.insert(23);
37        external_conditions.insert(24);
38        external_conditions.insert(25);
39        external_conditions.insert(26);
40        external_conditions.insert(35);
41        external_conditions.insert(36);
42        external_conditions.insert(41);
43        external_conditions.insert(45);
44        external_conditions.insert(46);
45        external_conditions.insert(49);
46        external_conditions.insert(50);
47        Self {
48            external_conditions,
49        }
50    }
51}
52
53impl ConditionEvaluator for PartinConditionEvaluatorFV2604 {
54    fn message_type(&self) -> &str {
55        "PARTIN"
56    }
57
58    fn format_version(&self) -> &str {
59        "FV2604"
60    }
61
62    fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
63        match condition {
64            1 => self.evaluate_1(ctx),
65            2 => self.evaluate_2(ctx),
66            3 => self.evaluate_3(ctx),
67            4 => self.evaluate_4(ctx),
68            5 => self.evaluate_5(ctx),
69            6 => self.evaluate_6(ctx),
70            7 => self.evaluate_7(ctx),
71            8 => self.evaluate_8(ctx),
72            9 => self.evaluate_9(ctx),
73            10 => self.evaluate_10(ctx),
74            11 => self.evaluate_11(ctx),
75            12 => self.evaluate_12(ctx),
76            13 => self.evaluate_13(ctx),
77            14 => self.evaluate_14(ctx),
78            15 => self.evaluate_15(ctx),
79            16 => self.evaluate_16(ctx),
80            17 => self.evaluate_17(ctx),
81            18 => self.evaluate_18(ctx),
82            19 => self.evaluate_19(ctx),
83            20 => self.evaluate_20(ctx),
84            21 => self.evaluate_21(ctx),
85            22 => self.evaluate_22(ctx),
86            23 => self.evaluate_23(ctx),
87            24 => self.evaluate_24(ctx),
88            25 => self.evaluate_25(ctx),
89            26 => self.evaluate_26(ctx),
90            27 => self.evaluate_27(ctx),
91            28 => self.evaluate_28(ctx),
92            29 => self.evaluate_29(ctx),
93            30 => self.evaluate_30(ctx),
94            31 => self.evaluate_31(ctx),
95            32 => self.evaluate_32(ctx),
96            33 => self.evaluate_33(ctx),
97            34 => self.evaluate_34(ctx),
98            35 => self.evaluate_35(ctx),
99            36 => self.evaluate_36(ctx),
100            41 => self.evaluate_41(ctx),
101            43 => self.evaluate_43(ctx),
102            44 => self.evaluate_44(ctx),
103            45 => self.evaluate_45(ctx),
104            46 => self.evaluate_46(ctx),
105            49 => self.evaluate_49(ctx),
106            50 => self.evaluate_50(ctx),
107            490 => self.evaluate_490(ctx),
108            491 => self.evaluate_491(ctx),
109            494 => self.evaluate_494(ctx),
110            500 => self.evaluate_500(ctx),
111            501 => self.evaluate_501(ctx),
112            502 => self.evaluate_502(ctx),
113            503 => self.evaluate_503(ctx),
114            504 => self.evaluate_504(ctx),
115            505 => self.evaluate_505(ctx),
116            506 => self.evaluate_506(ctx),
117            508 => self.evaluate_508(ctx),
118            908 => self.evaluate_908(ctx),
119            931 => self.evaluate_931(ctx),
120            932 => self.evaluate_932(ctx),
121            933 => self.evaluate_933(ctx),
122            939 => self.evaluate_939(ctx),
123            940 => self.evaluate_940(ctx),
124            _ => ConditionResult::Unknown,
125        }
126    }
127
128    fn is_external(&self, condition: u32) -> bool {
129        self.external_conditions.contains(&condition)
130    }
131    fn is_known(&self, condition: u32) -> bool {
132        matches!(
133            condition,
134            1 | 2
135                | 3
136                | 4
137                | 5
138                | 6
139                | 7
140                | 8
141                | 9
142                | 10
143                | 11
144                | 12
145                | 13
146                | 14
147                | 15
148                | 16
149                | 17
150                | 18
151                | 19
152                | 20
153                | 21
154                | 22
155                | 23
156                | 24
157                | 25
158                | 26
159                | 27
160                | 28
161                | 29
162                | 30
163                | 31
164                | 32
165                | 33
166                | 34
167                | 35
168                | 36
169                | 41
170                | 43
171                | 44
172                | 45
173                | 46
174                | 49
175                | 50
176                | 490
177                | 491
178                | 494
179                | 500
180                | 501
181                | 502
182                | 503
183                | 504
184                | 505
185                | 506
186                | 508
187                | 908
188                | 931
189                | 932
190                | 933
191                | 939
192                | 940
193        )
194    }
195}
196
197impl PartinConditionEvaluatorFV2604 {
198    /// [9] Wenn die Kommunikationsdaten vom Absender nicht mehr aktiv sind.
199    /// EXTERNAL: Requires context from outside the message.
200    fn evaluate_9(&self, ctx: &EvaluationContext) -> ConditionResult {
201        ctx.external.evaluate("sender_communication_inactive")
202    }
203
204    /// [41] Nur MP-ID aus Sparte Gas
205    /// EXTERNAL: Requires context from outside the message.
206    fn evaluate_41(&self, ctx: &EvaluationContext) -> ConditionResult {
207        ctx.external.evaluate("mp_id_is_gas_sector")
208    }
209
210    /// [43] Wenn SG4 NAD+Z71 (Marktgebietsverantwortlicher) DE3207 mit Code „DE“ vorhanden
211    fn evaluate_43(&self, ctx: &EvaluationContext) -> ConditionResult {
212        // NAD+Z71 with DE3207 (elements[8][0]) = "DE"
213        ctx.has_segment_matching("NAD", &[(0, 0, "Z71"), (8, 0, "DE")])
214    }
215
216    /// [44] Wenn SG4 NAD+Z71 (Marktgebietsverantwortlicher) DE3207 mit Code „DE“ nicht vorhanden
217    fn evaluate_44(&self, ctx: &EvaluationContext) -> ConditionResult {
218        // Negation of condition 43: NAD+Z71 with DE3207="DE" NOT present
219        match ctx.has_segment_matching("NAD", &[(0, 0, "Z71"), (8, 0, "DE")]) {
220            ConditionResult::True => ConditionResult::False,
221            ConditionResult::False => ConditionResult::True,
222            ConditionResult::Unknown => ConditionResult::Unknown,
223        }
224    }
225
226    /// [45] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF/NB
227    /// EXTERNAL: Requires context from outside the message.
228    fn evaluate_45(&self, ctx: &EvaluationContext) -> ConditionResult {
229        ctx.external.evaluate("recipient_is_lf_or_nb")
230    }
231
232    /// [46] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF/MSB/MGV
233    /// EXTERNAL: Requires context from outside the message.
234    fn evaluate_46(&self, ctx: &EvaluationContext) -> ConditionResult {
235        ctx.external.evaluate("recipient_is_lf_msb_mgv")
236    }
237
238    /// [49] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF/MGV
239    /// EXTERNAL: Requires context from outside the message.
240    fn evaluate_49(&self, ctx: &EvaluationContext) -> ConditionResult {
241        ctx.external.evaluate("recipient_is_lf_mgv")
242    }
243
244    /// [50] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF/MGV/NB
245    /// EXTERNAL: Requires context from outside the message.
246    fn evaluate_50(&self, ctx: &EvaluationContext) -> ConditionResult {
247        ctx.external.evaluate("recipient_is_lf_mgv_nb")
248    }
249
250    /// [500] Hinweis: Es kann der Firmenname eines Dienstleisters oder die identische Firmenbezeichnung aus SG4 NAD+SU / DDM / DEB / Z31 / Z34 / Z35 / Z36 / Z71 eingetragen werden.
251    fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
252        // Hinweis: Es kann der Firmenname eines Dienstleisters oder die identische Firmenbezeichnung aus SG4 NAD+SU / DDM / DEB / Z31 / Z34 / Z35 / Z36 / Z71 eingetragen werden.
253        ConditionResult::True
254    }
255
256    /// [1] Nur MP-ID aus Sparte Strom
257    /// EXTERNAL: Requires context from outside the message.
258    fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
259        ctx.external.evaluate("mp_id_is_strom")
260    }
261
262    /// [2] Wenn der Code im DE3207 in der "EDI@Energy Codeliste der europäischen Ländercodes" in der Spalte "PLZ vorhanden" ein "X" enthält
263    /// EXTERNAL: Requires context from outside the message.
264    fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
265        ctx.external.evaluate("country_has_postal_code")
266    }
267
268    /// [3] wenn vorhanden
269    fn evaluate_3(&self, _ctx: &EvaluationContext) -> ConditionResult {
270        // Hinweis: wenn vorhanden — informational annotation indicating the element is conditional/optional; always applies when evaluated
271        ConditionResult::True
272    }
273
274    /// [4] Wenn Vorgängerversion vorhanden
275    /// EXTERNAL: Requires context from outside the message.
276    fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
277        ctx.external.evaluate("predecessor_version_exists")
278    }
279
280    /// [5] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF
281    /// EXTERNAL: Requires context from outside the message.
282    fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
283        ctx.external.evaluate("recipient_is_lf")
284    }
285
286    /// [6] wenn im DE3155 im demselben COM der Code EM vorhanden ist
287    fn evaluate_6(&self, ctx: &EvaluationContext) -> ConditionResult {
288        let coms = ctx.find_segments("COM");
289        if coms.is_empty() {
290            return ConditionResult::Unknown;
291        }
292        ConditionResult::from(coms.iter().any(|s| {
293            s.elements
294                .first()
295                .and_then(|e| e.get(1))
296                .is_some_and(|v| v == "EM")
297        }))
298    }
299
300    /// [7] wenn im DE3155 im demselben COM der Code TE / FX / AJ / AL vorhanden ist
301    fn evaluate_7(&self, ctx: &EvaluationContext) -> ConditionResult {
302        let coms = ctx.find_segments("COM");
303        if coms.is_empty() {
304            return ConditionResult::Unknown;
305        }
306        ConditionResult::from(coms.iter().any(|s| {
307            s.elements
308                .first()
309                .and_then(|e| e.get(1))
310                .is_some_and(|v| matches!(v.as_str(), "TE" | "FX" | "AJ" | "AL"))
311        }))
312    }
313
314    /// [8] wenn im DE3155 im demselben COM der Code TE / FX vorhanden ist
315    fn evaluate_8(&self, ctx: &EvaluationContext) -> ConditionResult {
316        let coms = ctx.find_segments("COM");
317        if coms.is_empty() {
318            return ConditionResult::Unknown;
319        }
320        ConditionResult::from(coms.iter().any(|s| {
321            s.elements
322                .first()
323                .and_then(|e| e.get(1))
324                .is_some_and(|v| matches!(v.as_str(), "TE" | "FX"))
325        }))
326    }
327
328    /// [10] Wenn BGM DE1373 = 11 (Dokument nicht verfügbar) nicht vorhanden
329    fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
330        match ctx.find_segment("BGM") {
331            None => ConditionResult::False, // segment absent → condition not applicable
332            Some(bgm) => ConditionResult::from(
333                bgm.elements
334                    .get(4)
335                    .and_then(|e| e.first())
336                    .map(|v| v != "11")
337                    .unwrap_or(true),
338            ),
339        }
340    }
341
342    /// [11] Wenn SG4 NAD+SU (Lieferant) DE3207 mit Code „DE“ vorhanden
343    fn evaluate_11(&self, ctx: &EvaluationContext) -> ConditionResult {
344        let nads = ctx.find_segments_with_qualifier("NAD", 0, "SU");
345        match nads.first() {
346            None => ConditionResult::False, // segment absent → condition not applicable
347            Some(nad) => ConditionResult::from(
348                nad.elements
349                    .get(8)
350                    .and_then(|e| e.first())
351                    .is_some_and(|v| v == "DE"),
352            ),
353        }
354    }
355
356    /// [12] Wenn SG4 NAD+DDM (Netzbetreiber) DE3207 mit Code „DE“ vorhanden
357    fn evaluate_12(&self, ctx: &EvaluationContext) -> ConditionResult {
358        let nads = ctx.find_segments_with_qualifier("NAD", 0, "DDM");
359        match nads.first() {
360            None => ConditionResult::False, // segment absent → condition not applicable
361            Some(nad) => ConditionResult::from(
362                nad.elements
363                    .get(8)
364                    .and_then(|e| e.first())
365                    .is_some_and(|v| v == "DE"),
366            ),
367        }
368    }
369
370    /// [13] Wenn SG4 NAD+DEB (Messstellenbetreiber) DE3207 mit Code „DE“ vorhanden
371    fn evaluate_13(&self, ctx: &EvaluationContext) -> ConditionResult {
372        let nads = ctx.find_segments_with_qualifier("NAD", 0, "DEB");
373        match nads.first() {
374            None => ConditionResult::False, // segment absent → condition not applicable
375            Some(nad) => ConditionResult::from(
376                nad.elements
377                    .get(8)
378                    .and_then(|e| e.first())
379                    .is_some_and(|v| v == "DE"),
380            ),
381        }
382    }
383
384    /// [14] Wenn SG4 NAD+SU (Lieferant) DE3207 der Code „DE“ nicht vorhanden
385    fn evaluate_14(&self, ctx: &EvaluationContext) -> ConditionResult {
386        let nads = ctx.find_segments_with_qualifier("NAD", 0, "SU");
387        match nads.first() {
388            None => ConditionResult::False, // segment absent → condition not applicable
389            Some(nad) => ConditionResult::from(
390                nad.elements
391                    .get(8)
392                    .and_then(|e| e.first())
393                    .map(|v| v != "DE")
394                    .unwrap_or(true),
395            ),
396        }
397    }
398
399    /// [15] Wenn SG4 NAD+DDM (Netzbetreiber) DE3207 der Code „DE“ nicht vorhanden
400    fn evaluate_15(&self, ctx: &EvaluationContext) -> ConditionResult {
401        let nads = ctx.find_segments_with_qualifier("NAD", 0, "DDM");
402        match nads.first() {
403            None => ConditionResult::False, // segment absent → condition not applicable
404            Some(nad) => ConditionResult::from(
405                nad.elements
406                    .get(8)
407                    .and_then(|e| e.first())
408                    .map(|v| v != "DE")
409                    .unwrap_or(true),
410            ),
411        }
412    }
413
414    /// [16] Wenn SG4 NAD+DEB (Messstellenbetreiber) DE3207 der Code „DE“ nicht vorhanden
415    fn evaluate_16(&self, ctx: &EvaluationContext) -> ConditionResult {
416        let nads = ctx.find_segments_with_qualifier("NAD", 0, "DEB");
417        match nads.first() {
418            None => ConditionResult::False, // segment absent → condition not applicable
419            Some(nad) => ConditionResult::from(
420                nad.elements
421                    .get(8)
422                    .and_then(|e| e.first())
423                    .map(|v| v != "DE")
424                    .unwrap_or(true),
425            ),
426        }
427    }
428
429    /// [17] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF/NB/MSB
430    /// EXTERNAL: Requires context from outside the message.
431    fn evaluate_17(&self, ctx: &EvaluationContext) -> ConditionResult {
432        ctx.external.evaluate("recipient_is_lf_nb_msb")
433    }
434
435    /// [18] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF/MSB
436    /// EXTERNAL: Requires context from outside the message.
437    fn evaluate_18(&self, ctx: &EvaluationContext) -> ConditionResult {
438        ctx.external.evaluate("recipient_is_lf_msb")
439    }
440
441    /// [19] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF/MSB/NB/ÜNB
442    /// EXTERNAL: Requires context from outside the message.
443    fn evaluate_19(&self, ctx: &EvaluationContext) -> ConditionResult {
444        ctx.external.evaluate("recipient_is_lf_msb_nb_uenb")
445    }
446
447    /// [20] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF/MSB/ÜNB
448    /// EXTERNAL: Requires context from outside the message.
449    fn evaluate_20(&self, ctx: &EvaluationContext) -> ConditionResult {
450        ctx.external.evaluate("recipient_is_lf_msb_uenb")
451    }
452
453    /// [21] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF/NB/ESA
454    /// EXTERNAL: Requires context from outside the message.
455    fn evaluate_21(&self, ctx: &EvaluationContext) -> ConditionResult {
456        ctx.external.evaluate("recipient_is_lf_nb_esa")
457    }
458
459    /// [22] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle MSB
460    /// EXTERNAL: Requires context from outside the message.
461    fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
462        ctx.external.evaluate("recipient_is_msb")
463    }
464
465    /// [23] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle NB/ÜNB
466    /// EXTERNAL: Requires context from outside the message.
467    fn evaluate_23(&self, ctx: &EvaluationContext) -> ConditionResult {
468        ctx.external.evaluate("recipient_is_nb_uenb")
469    }
470
471    /// [24] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle NB/LF/MSB/ESA
472    /// EXTERNAL: Requires context from outside the message.
473    fn evaluate_24(&self, ctx: &EvaluationContext) -> ConditionResult {
474        ctx.external.evaluate("recipient_is_nb_lf_msb_esa")
475    }
476
477    /// [25] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle NB
478    /// EXTERNAL: Requires context from outside the message.
479    fn evaluate_25(&self, ctx: &EvaluationContext) -> ConditionResult {
480        ctx.external.evaluate("recipient_is_nb")
481    }
482
483    /// [26] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle NB/LF/BKV/BIKO
484    /// EXTERNAL: Requires context from outside the message.
485    fn evaluate_26(&self, ctx: &EvaluationContext) -> ConditionResult {
486        ctx.external.evaluate("recipient_is_nb_lf_bkv_biko")
487    }
488
489    /// [27] Wenn SG4 NAD+Z31 (Übertragungsnetzbetreiber) DE3207 mit Code „DE“ vorhanden
490    fn evaluate_27(&self, ctx: &EvaluationContext) -> ConditionResult {
491        ctx.has_qualified_value("NAD", 0, "Z31", 8, 0, &["DE"])
492    }
493
494    /// [28] Wenn SG4 NAD+Z34 (Bilanzkoordinator) DE3207 mit Code „DE“ vorhanden
495    fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
496        ctx.has_qualified_value("NAD", 0, "Z34", 8, 0, &["DE"])
497    }
498
499    /// [29] Wenn SG4 NAD+Z35 (Bilanzkreisverantwortlicher) DE3207 mit Code „DE“ vorhanden
500    fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
501        ctx.has_qualified_value("NAD", 0, "Z35", 8, 0, &["DE"])
502    }
503
504    /// [30] Wenn SG4 NAD+Z36 (Energieserviceanbieter) DE3207 mit Code „DE“ vorhanden
505    fn evaluate_30(&self, ctx: &EvaluationContext) -> ConditionResult {
506        ctx.has_qualified_value("NAD", 0, "Z36", 8, 0, &["DE"])
507    }
508
509    /// [31] Wenn SG4 NAD+Z31 (Übertragungsnetzbetreiber) DE3207 mit Code „DE“ nicht vorhanden
510    fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
511        match ctx.has_qualified_value("NAD", 0, "Z31", 8, 0, &["DE"]) {
512            ConditionResult::True => ConditionResult::False,
513            ConditionResult::False => ConditionResult::True,
514            ConditionResult::Unknown => ConditionResult::Unknown,
515        }
516    }
517
518    /// [32] Wenn SG4 NAD+Z34 (Bilanzkoordinator) DE3207 mit Code „DE“ nicht vorhanden
519    fn evaluate_32(&self, ctx: &EvaluationContext) -> ConditionResult {
520        let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z34");
521        if nads.is_empty() {
522            return ConditionResult::True;
523        }
524        let has_de = nads.iter().any(|s| {
525            s.elements
526                .get(8)
527                .and_then(|e| e.first())
528                .is_some_and(|v| v == "DE")
529        });
530        ConditionResult::from(!has_de)
531    }
532
533    /// [33] Wenn SG4 NAD+Z35 (Bilanzkreisverantwortlicher) DE3207 mit Code „DE“ nicht vorhanden
534    fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
535        let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z35");
536        if nads.is_empty() {
537            return ConditionResult::True;
538        }
539        let has_de = nads.iter().any(|s| {
540            s.elements
541                .get(8)
542                .and_then(|e| e.first())
543                .is_some_and(|v| v == "DE")
544        });
545        ConditionResult::from(!has_de)
546    }
547
548    /// [34] Wenn SG4 NAD+Z36 (Energieserviceanbieter) DE3207 mit Code „DE“ nicht vorhanden
549    fn evaluate_34(&self, ctx: &EvaluationContext) -> ConditionResult {
550        let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z36");
551        if nads.is_empty() {
552            return ConditionResult::True;
553        }
554        let has_de = nads.iter().any(|s| {
555            s.elements
556                .get(8)
557                .and_then(|e| e.first())
558                .is_some_and(|v| v == "DE")
559        });
560        ConditionResult::from(!has_de)
561    }
562
563    /// [35] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle ÜNB
564    /// EXTERNAL: Requires context from outside the message.
565    fn evaluate_35(&self, ctx: &EvaluationContext) -> ConditionResult {
566        ctx.external.evaluate("recipient_is_uenb")
567    }
568
569    /// [36] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle BKV
570    /// EXTERNAL: Requires context from outside the message.
571    fn evaluate_36(&self, ctx: &EvaluationContext) -> ConditionResult {
572        ctx.external.evaluate("recipient_is_bkv")
573    }
574
575    /// [490] wenn Wert in diesem DE, an der Stelle CCYYMMDD ein Datum aus dem angegeben Zeitraum der Tabelle Kapitel 3.5 „Prozesszeitpunkt bei MESZ mit UTC“ ist
576    fn evaluate_490(&self, ctx: &EvaluationContext) -> ConditionResult {
577        match ctx.resolved_value {
578            Some(val) => is_mesz_utc(val),
579            None => ConditionResult::False,
580        }
581    }
582
583    /// [491] wenn Wert in diesem DE, an der Stelle CCYYMMDD ein Datum aus dem angegeben Zeitraum der Tabelle Kapitel 3.6 „Prozesszeitpunkt bei MEZ mit UTC“ ist
584    fn evaluate_491(&self, ctx: &EvaluationContext) -> ConditionResult {
585        match ctx.resolved_value {
586            Some(val) => is_mez_utc(val),
587            None => ConditionResult::False,
588        }
589    }
590
591    /// [494] Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.
592    // REVIEW: This condition states the referenced date must be the document creation timestamp or earlier. Verifying this would require knowing the actual document creation time as an external reference point, which is not present in the EDIFACT message itself. The phrasing describes a semantic constraint on the field's value origin rather than a checkable boolean predicate from message content. Treated as an always-true informational annotation similar to a Hinweis, since the field by definition carries the value the sender chose as the document date. (medium confidence)
593    fn evaluate_494(&self, _ctx: &EvaluationContext) -> ConditionResult {
594        // Hinweis: Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.
595        // This is a semantic annotation about what the date field must represent (document creation time or earlier).
596        // It cannot be evaluated as a boolean predicate from the EDIFACT message content alone.
597        ConditionResult::True
598    }
599
600    /// [501] Hinweis: Es darf kein Name einer natürlichen Person übermittelt werden, stattdessen ist die organisatorische Einheit im Unternehmen zu nennen.
601    fn evaluate_501(&self, _ctx: &EvaluationContext) -> ConditionResult {
602        // Hinweis: Es darf kein Name einer natürlichen Person übermittelt werden, stattdessen ist die organisatorische Einheit im Unternehmen zu nennen.
603        // Informational note about data privacy — no natural person names, use organisational unit — always applies.
604        ConditionResult::True
605    }
606
607    /// [502] Hinweis: Es darf nur eine Information im DE3148 übermittelt werden
608    fn evaluate_502(&self, _ctx: &EvaluationContext) -> ConditionResult {
609        // Hinweis: Es darf nur eine Information im DE3148 übermittelt werden.
610        // Informational note about cardinality of DE3148 — only one value may be transmitted — always applies.
611        ConditionResult::True
612    }
613
614    /// [503] Hinweis: Angabe erfolgt in gesetzlicher deutscher Zeit
615    fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
616        // Hinweis: Angabe erfolgt in gesetzlicher deutscher Zeit — informational note, always applies
617        ConditionResult::True
618    }
619
620    /// [504] Hinweis: Es ist mindestens die Umsatzsteuer- bzw. Steuernummer zu nennen, die in der INVOIC genutzt wird.
621    fn evaluate_504(&self, _ctx: &EvaluationContext) -> ConditionResult {
622        // Hinweis: Es ist mindestens die Umsatzsteuer- bzw. Steuernummer zu nennen — informational note, always applies
623        ConditionResult::True
624    }
625
626    /// [505] Wenn eine Vorgängerversion (RFF+ACW) angegeben ist, so muss der Wert in diesem DE1056 mindestens um 1 höher sein, als der Wert aus DE1056 der Vorgängerversion (RFF+ACW).
627    // REVIEW: When RFF+ACW (predecessor version) is present, compare DE1056 (elements[0][3]) of RFF+AGK (current version) against DE1056 of RFF+ACW. Condition is True when current version is at least 1 higher than predecessor. Returns False when no ACW present (condition does not apply), Unknown if version numbers cannot be parsed. (medium confidence)
628    fn evaluate_505(&self, ctx: &EvaluationContext) -> ConditionResult {
629        let acw_segments = ctx.find_segments_with_qualifier("RFF", 0, "ACW");
630        if acw_segments.is_empty() {
631            return ConditionResult::False;
632        }
633        let agk_segments = ctx.find_segments_with_qualifier("RFF", 0, "AGK");
634        let current_version = agk_segments
635            .first()
636            .and_then(|s| s.elements.first())
637            .and_then(|e| e.get(3))
638            .and_then(|v| v.parse::<i64>().ok());
639        let predecessor_version = acw_segments
640            .first()
641            .and_then(|s| s.elements.first())
642            .and_then(|e| e.get(3))
643            .and_then(|v| v.parse::<i64>().ok());
644        match (current_version, predecessor_version) {
645            (Some(cur), Some(pred)) => ConditionResult::from(cur >= pred + 1),
646            _ => ConditionResult::Unknown,
647        }
648    }
649
650    /// [506] Hinweis: Das Datenelement ist so zu füllen, dass sein Inhalt den Vorgaben des USt.-Gesetzes genügt, so dass der Empfänger diese Daten in einer INVOIC nutzen kann.
651    fn evaluate_506(&self, _ctx: &EvaluationContext) -> ConditionResult {
652        // Hinweis: Das Datenelement ist so zu füllen, dass sein Inhalt den Vorgaben des USt.-Gesetzes genügt — informational note, always applies
653        ConditionResult::True
654    }
655
656    /// [508] Hinweis: Der LF in seiner Funktion als Grund- und Ersatzversorger muss den NB, in deren Netzgebiet der LF als Grund- und Ersatzversorger ist, einen Bilanzkreis für verbrauchende Marktlokationen ü...
657    fn evaluate_508(&self, _ctx: &EvaluationContext) -> ConditionResult {
658        // Hinweis: Der LF als Grund- und Ersatzversorger muss dem NB einen Bilanzkreis übermitteln — informational note, always applies
659        ConditionResult::True
660    }
661
662    /// [908] Format: Mögliche Werte: 1 bis n
663    fn evaluate_908(&self, _ctx: &EvaluationContext) -> ConditionResult {
664        // Format: Mögliche Werte: 1 bis n — informational cardinality note, always applies
665        ConditionResult::True
666    }
667
668    /// [931] Format: ZZZ = +00
669    fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
670        ctx.format_check("DTM", 0, 1, validate_timezone_utc)
671    }
672
673    /// [932] Format: HHMM = 2200
674    fn evaluate_932(&self, ctx: &EvaluationContext) -> ConditionResult {
675        ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "2200"))
676    }
677
678    /// [933] Format: HHMM = 2300
679    fn evaluate_933(&self, ctx: &EvaluationContext) -> ConditionResult {
680        ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "2300"))
681    }
682
683    /// [939] Format: Die Zeichenkette muss die Zeichen @ und . enthalten
684    fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
685        ctx.format_check("COM", 0, 0, validate_email)
686    }
687
688    /// [940] Format: Die Zeichenkette muss mit dem Zeichen + beginnen und danach dürfen nur noch Ziffern folgen
689    fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
690        ctx.format_check("COM", 0, 0, validate_phone)
691    }
692}