Skip to main content

automapper_validation/generated/fv2504/
ordrsp_conditions_fv2504.rs

1// <auto-generated>
2// Generated by automapper-generator generate-conditions
3// AHB: xml-migs-and-ahbs/FV2504/ORDRSP_AHB_1_0a_Fehlerkorrektur_20250417.xml
4// Generated: 2026-03-12T09:54:30Z
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 ORDRSP FV2504.
12pub struct OrdrspConditionEvaluatorFV2504 {
13    // External condition IDs that require runtime context.
14    external_conditions: std::collections::HashSet<u32>,
15}
16
17impl Default for OrdrspConditionEvaluatorFV2504 {
18    fn default() -> Self {
19        let mut external_conditions = std::collections::HashSet::new();
20        external_conditions.insert(3);
21        external_conditions.insert(4);
22        external_conditions.insert(5);
23        external_conditions.insert(9);
24        external_conditions.insert(10);
25        external_conditions.insert(12);
26        external_conditions.insert(14);
27        external_conditions.insert(15);
28        external_conditions.insert(16);
29        external_conditions.insert(17);
30        external_conditions.insert(18);
31        external_conditions.insert(29);
32        external_conditions.insert(30);
33        external_conditions.insert(31);
34        external_conditions.insert(32);
35        external_conditions.insert(40);
36        external_conditions.insert(49);
37        external_conditions.insert(52);
38        external_conditions.insert(60);
39        external_conditions.insert(70);
40        external_conditions.insert(71);
41        external_conditions.insert(75);
42        external_conditions.insert(492);
43        external_conditions.insert(493);
44        Self {
45            external_conditions,
46        }
47    }
48}
49
50impl ConditionEvaluator for OrdrspConditionEvaluatorFV2504 {
51    fn message_type(&self) -> &str {
52        "ORDRSP"
53    }
54
55    fn format_version(&self) -> &str {
56        "FV2504"
57    }
58
59    fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
60        match condition {
61            1 => self.evaluate_1(ctx),
62            3 => self.evaluate_3(ctx),
63            4 => self.evaluate_4(ctx),
64            5 => self.evaluate_5(ctx),
65            9 => self.evaluate_9(ctx),
66            10 => self.evaluate_10(ctx),
67            11 => self.evaluate_11(ctx),
68            12 => self.evaluate_12(ctx),
69            14 => self.evaluate_14(ctx),
70            15 => self.evaluate_15(ctx),
71            16 => self.evaluate_16(ctx),
72            17 => self.evaluate_17(ctx),
73            18 => self.evaluate_18(ctx),
74            21 => self.evaluate_21(ctx),
75            22 => self.evaluate_22(ctx),
76            23 => self.evaluate_23(ctx),
77            24 => self.evaluate_24(ctx),
78            25 => self.evaluate_25(ctx),
79            27 => self.evaluate_27(ctx),
80            28 => self.evaluate_28(ctx),
81            29 => self.evaluate_29(ctx),
82            30 => self.evaluate_30(ctx),
83            31 => self.evaluate_31(ctx),
84            32 => self.evaluate_32(ctx),
85            33 => self.evaluate_33(ctx),
86            34 => self.evaluate_34(ctx),
87            37 => self.evaluate_37(ctx),
88            38 => self.evaluate_38(ctx),
89            39 => self.evaluate_39(ctx),
90            40 => self.evaluate_40(ctx),
91            41 => self.evaluate_41(ctx),
92            42 => self.evaluate_42(ctx),
93            43 => self.evaluate_43(ctx),
94            44 => self.evaluate_44(ctx),
95            45 => self.evaluate_45(ctx),
96            46 => self.evaluate_46(ctx),
97            47 => self.evaluate_47(ctx),
98            48 => self.evaluate_48(ctx),
99            49 => self.evaluate_49(ctx),
100            50 => self.evaluate_50(ctx),
101            51 => self.evaluate_51(ctx),
102            52 => self.evaluate_52(ctx),
103            53 => self.evaluate_53(ctx),
104            54 => self.evaluate_54(ctx),
105            55 => self.evaluate_55(ctx),
106            56 => self.evaluate_56(ctx),
107            57 => self.evaluate_57(ctx),
108            58 => self.evaluate_58(ctx),
109            59 => self.evaluate_59(ctx),
110            60 => self.evaluate_60(ctx),
111            61 => self.evaluate_61(ctx),
112            62 => self.evaluate_62(ctx),
113            63 => self.evaluate_63(ctx),
114            64 => self.evaluate_64(ctx),
115            65 => self.evaluate_65(ctx),
116            66 => self.evaluate_66(ctx),
117            67 => self.evaluate_67(ctx),
118            68 => self.evaluate_68(ctx),
119            69 => self.evaluate_69(ctx),
120            70 => self.evaluate_70(ctx),
121            71 => self.evaluate_71(ctx),
122            72 => self.evaluate_72(ctx),
123            73 => self.evaluate_73(ctx),
124            74 => self.evaluate_74(ctx),
125            75 => self.evaluate_75(ctx),
126            76 => self.evaluate_76(ctx),
127            77 => self.evaluate_77(ctx),
128            490 => self.evaluate_490(ctx),
129            491 => self.evaluate_491(ctx),
130            492 => self.evaluate_492(ctx),
131            493 => self.evaluate_493(ctx),
132            494 => self.evaluate_494(ctx),
133            500 => self.evaluate_500(ctx),
134            503 => self.evaluate_503(ctx),
135            504 => self.evaluate_504(ctx),
136            513 => self.evaluate_513(ctx),
137            518 => self.evaluate_518(ctx),
138            519 => self.evaluate_519(ctx),
139            520 => self.evaluate_520(ctx),
140            521 => self.evaluate_521(ctx),
141            522 => self.evaluate_522(ctx),
142            523 => self.evaluate_523(ctx),
143            524 => self.evaluate_524(ctx),
144            525 => self.evaluate_525(ctx),
145            526 => self.evaluate_526(ctx),
146            527 => self.evaluate_527(ctx),
147            529 => self.evaluate_529(ctx),
148            530 => self.evaluate_530(ctx),
149            533 => self.evaluate_533(ctx),
150            534 => self.evaluate_534(ctx),
151            535 => self.evaluate_535(ctx),
152            536 => self.evaluate_536(ctx),
153            537 => self.evaluate_537(ctx),
154            538 => self.evaluate_538(ctx),
155            539 => self.evaluate_539(ctx),
156            540 => self.evaluate_540(ctx),
157            542 => self.evaluate_542(ctx),
158            902 => self.evaluate_902(ctx),
159            903 => self.evaluate_903(ctx),
160            930 => self.evaluate_930(ctx),
161            931 => self.evaluate_931(ctx),
162            932 => self.evaluate_932(ctx),
163            933 => self.evaluate_933(ctx),
164            934 => self.evaluate_934(ctx),
165            935 => self.evaluate_935(ctx),
166            939 => self.evaluate_939(ctx),
167            940 => self.evaluate_940(ctx),
168            2036 => self.evaluate_2036(ctx),
169            _ => ConditionResult::Unknown,
170        }
171    }
172
173    fn is_external(&self, condition: u32) -> bool {
174        self.external_conditions.contains(&condition)
175    }
176    fn is_known(&self, condition: u32) -> bool {
177        matches!(
178            condition,
179            1 | 3
180                | 4
181                | 5
182                | 9
183                | 10
184                | 11
185                | 12
186                | 14
187                | 15
188                | 16
189                | 17
190                | 18
191                | 21
192                | 22
193                | 23
194                | 24
195                | 25
196                | 27
197                | 28
198                | 29
199                | 30
200                | 31
201                | 32
202                | 33
203                | 34
204                | 37
205                | 38
206                | 39
207                | 40
208                | 41
209                | 42
210                | 43
211                | 44
212                | 45
213                | 46
214                | 47
215                | 48
216                | 49
217                | 50
218                | 51
219                | 52
220                | 53
221                | 54
222                | 55
223                | 56
224                | 57
225                | 58
226                | 59
227                | 60
228                | 61
229                | 62
230                | 63
231                | 64
232                | 65
233                | 66
234                | 67
235                | 68
236                | 69
237                | 70
238                | 71
239                | 72
240                | 73
241                | 74
242                | 75
243                | 76
244                | 77
245                | 490
246                | 491
247                | 492
248                | 493
249                | 494
250                | 500
251                | 503
252                | 504
253                | 513
254                | 518
255                | 519
256                | 520
257                | 521
258                | 522
259                | 523
260                | 524
261                | 525
262                | 526
263                | 527
264                | 529
265                | 530
266                | 533
267                | 534
268                | 535
269                | 536
270                | 537
271                | 538
272                | 539
273                | 540
274                | 542
275                | 902
276                | 903
277                | 930
278                | 931
279                | 932
280                | 933
281                | 934
282                | 935
283                | 939
284                | 940
285                | 2036
286        )
287    }
288}
289
290impl OrdrspConditionEvaluatorFV2504 {
291    /// [52] wenn es sich bei der Reklamation um die Reklamation der ausgerollten Leistungskurvendefinitionen handelte
292    /// EXTERNAL: Requires context from outside the message.
293    fn evaluate_52(&self, ctx: &EvaluationContext) -> ConditionResult {
294        ctx.external
295            .evaluate("complaint_was_about_rolled_out_power_curve_definitions")
296    }
297
298    /// [60] wenn es sich bei der Reklamation um die Reklamation der Übersicht der Zählzeitdefinitionen handelte
299    /// EXTERNAL: Requires context from outside the message.
300    fn evaluate_60(&self, ctx: &EvaluationContext) -> ConditionResult {
301        ctx.external
302            .evaluate("complaint_was_about_overview_time_of_use_definitions")
303    }
304
305    /// [70] wenn es sich bei der Reklamation um die Reklamation der ausgerollten Zählzeitdefinitionen handelte
306    /// EXTERNAL: Requires context from outside the message.
307    fn evaluate_70(&self, ctx: &EvaluationContext) -> ConditionResult {
308        ctx.external
309            .evaluate("complaint_was_about_rolled_out_time_of_use_definitions")
310    }
311
312    /// [71] wenn es sich bei der Reklamation um die Reklamation der ausgerollten Schaltzeitdefinitionen handelte
313    /// EXTERNAL: Requires context from outside the message.
314    fn evaluate_71(&self, ctx: &EvaluationContext) -> ConditionResult {
315        ctx.external
316            .evaluate("complaint_was_about_rolled_out_switching_time_definitions")
317    }
318
319    /// [75] Wenn es sich um die Antwort auf eine Bestellung handelt in der ein Messprodukt der Codeliste der Konfigurationen aus dem Kapitel 4.6.2 „Werte nach Typ 2 aus SMGW“ bestellt wurde.
320    /// EXTERNAL: Requires context from outside the message.
321    fn evaluate_75(&self, ctx: &EvaluationContext) -> ConditionResult {
322        ctx.external.evaluate("order_contains_smgw_type2_product")
323    }
324
325    /// [490] wenn Wert in diesem DE, an der Stelle CCYYMMDDHHMM ein Zeitpunkt aus dem angegeben Zeitraum der Tabelle Kapitel 3.5 „Übersicht gesetzliche deutsche Sommerzeit (MESZ)“ der Spalten: „Sommerzei...
326    fn evaluate_490(&self, ctx: &EvaluationContext) -> ConditionResult {
327        let dtm_segs = ctx.find_segments("DTM");
328        match dtm_segs
329            .first()
330            .and_then(|s| s.elements.first())
331            .and_then(|e| e.get(1))
332        {
333            Some(val) => is_mesz_utc(val),
334            None => ConditionResult::False, // segment absent → condition not applicable
335        }
336    }
337
338    /// [491] wenn Wert in diesem DE, an der Stelle CCYYMMDDHHMM ein Zeitpunkt aus dem angegeben Zeitraum der Tabelle Kapitel 3.6 „Übersicht gesetzliche deutsche Zeit (MEZ)“ der Spalten: „Winterzeit (MEZ)...
339    fn evaluate_491(&self, ctx: &EvaluationContext) -> ConditionResult {
340        let dtm_segs = ctx.find_segments("DTM");
341        match dtm_segs
342            .first()
343            .and_then(|s| s.elements.first())
344            .and_then(|e| e.get(1))
345        {
346            Some(val) => is_mez_utc(val),
347            None => ConditionResult::False, // segment absent → condition not applicable
348        }
349    }
350
351    /// [1] Wenn BGM+7 vorhanden
352    fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
353        ctx.has_qualifier("BGM", 0, "7")
354    }
355
356    /// [3] Wenn MP-ID in SG3 NAD+MS mit Rolle NB vorhanden
357    /// EXTERNAL: Requires context from outside the message.
358    fn evaluate_3(&self, ctx: &EvaluationContext) -> ConditionResult {
359        ctx.external.evaluate("sender_is_nb")
360    }
361
362    /// [4] Wenn MP-ID in SG3 NAD+MR mit Rolle LF vorhanden
363    /// EXTERNAL: Requires context from outside the message.
364    fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
365        ctx.external.evaluate("recipient_is_lf")
366    }
367
368    /// [5] Wenn MP-ID in SG3 NAD+MS mit Rolle LF vorhanden
369    /// EXTERNAL: Requires context from outside the message.
370    fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
371        ctx.external.evaluate("sender_is_lf")
372    }
373
374    /// [9] Wenn MP-ID in SG3 NAD+MS mit Rolle LF vorhanden
375    /// EXTERNAL: Requires context from outside the message.
376    fn evaluate_9(&self, ctx: &EvaluationContext) -> ConditionResult {
377        ctx.external.evaluate("sender_is_lf")
378    }
379
380    /// [10] Wenn MP-ID in SG3 NAD+MS mit Rolle MSB vorhanden
381    /// EXTERNAL: Requires context from outside the message.
382    fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
383        ctx.external.evaluate("sender_is_msb")
384    }
385
386    /// [11] Wenn AJT+A09+E_0470 vorhanden
387    fn evaluate_11(&self, ctx: &EvaluationContext) -> ConditionResult {
388        ctx.has_qualified_value("AJT", 0, "A09", 1, 0, &["E_0470"])
389    }
390
391    /// [12] Wenn der NB eine unverbindliche Preisinformation angeben kann
392    /// EXTERNAL: Requires context from outside the message.
393    fn evaluate_12(&self, ctx: &EvaluationContext) -> ConditionResult {
394        ctx.external.evaluate("nb_can_provide_price_info")
395    }
396
397    /// [14] Wenn MP-ID in SG3 NAD+MR mit Rolle MSB vorhanden
398    /// EXTERNAL: Requires context from outside the message.
399    fn evaluate_14(&self, ctx: &EvaluationContext) -> ConditionResult {
400        ctx.external.evaluate("recipient_is_msb")
401    }
402
403    /// [15] Wenn MP-ID in SG3 NAD+MR mit Rolle NB vorhanden
404    /// EXTERNAL: Requires context from outside the message.
405    fn evaluate_15(&self, ctx: &EvaluationContext) -> ConditionResult {
406        ctx.external.evaluate("recipient_is_nb")
407    }
408
409    /// [16] Wenn MP-ID in SG3 NAD+MR mit Rolle ÜNB vorhanden
410    /// EXTERNAL: Requires context from outside the message.
411    fn evaluate_16(&self, ctx: &EvaluationContext) -> ConditionResult {
412        ctx.external.evaluate("recipient_is_uenb")
413    }
414
415    /// [17] Der hier angegebene Code des Prüfschritts muss im EBD dem Cluster Zustimmung zugeordnet sein
416    /// EXTERNAL: Requires context from outside the message.
417    fn evaluate_17(&self, ctx: &EvaluationContext) -> ConditionResult {
418        ctx.external.evaluate("pruefschritt_is_zustimmung_cluster")
419    }
420
421    /// [18] Der hier angegebene Code des Prüfschritts muss im EBD dem Cluster Ablehnung zugeordnet sein
422    /// EXTERNAL: Requires context from outside the message.
423    fn evaluate_18(&self, ctx: &EvaluationContext) -> ConditionResult {
424        ctx.external.evaluate("pruefschritt_cluster_ablehnung")
425    }
426
427    /// [21] Wenn IMD++Z01 vorhanden
428    fn evaluate_21(&self, ctx: &EvaluationContext) -> ConditionResult {
429        ctx.has_qualifier("IMD", 1, "Z01")
430    }
431
432    /// [22] Wenn IMD++Z02 vorhanden
433    fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
434        ctx.has_qualifier("IMD", 1, "Z02")
435    }
436
437    /// [23] Wenn IMD++Z03 vorhanden
438    fn evaluate_23(&self, ctx: &EvaluationContext) -> ConditionResult {
439        let segments = ctx.find_segments("IMD");
440        ConditionResult::from(segments.iter().any(|s| {
441            s.elements
442                .get(1)
443                .and_then(|e| e.first())
444                .is_some_and(|v| v == "Z03")
445        }))
446    }
447
448    /// [24] Wenn BGM+Z51 vorhanden
449    fn evaluate_24(&self, ctx: &EvaluationContext) -> ConditionResult {
450        ctx.has_qualifier("BGM", 0, "Z51")
451    }
452
453    /// [25] Wenn BGM+Z52 vorhanden
454    fn evaluate_25(&self, ctx: &EvaluationContext) -> ConditionResult {
455        ctx.has_qualifier("BGM", 0, "Z52")
456    }
457
458    /// [27] Wenn AJT+A05+E_0470 vorhanden
459    fn evaluate_27(&self, ctx: &EvaluationContext) -> ConditionResult {
460        let segments = ctx.find_segments_with_qualifier("AJT", 0, "A05");
461        ConditionResult::from(segments.iter().any(|s| {
462            s.elements
463                .get(1)
464                .and_then(|e| e.first())
465                .is_some_and(|v| v == "E_0470")
466        }))
467    }
468
469    /// [28] Wenn AJT+A99 vorhanden
470    fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
471        ctx.has_qualifier("AJT", 0, "A99")
472    }
473
474    /// [29] MP-ID nur aus Sparte Gas
475    /// EXTERNAL: Requires context from outside the message.
476    fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
477        ctx.external.evaluate("mp_id_is_gas")
478    }
479
480    /// [30] MP-ID nur aus Sparte Strom
481    /// EXTERNAL: Requires context from outside the message.
482    fn evaluate_30(&self, ctx: &EvaluationContext) -> ConditionResult {
483        ctx.external.evaluate("mp_id_is_strom")
484    }
485
486    /// [31] MP-ID mit Rolle MSB
487    /// EXTERNAL: Requires context from outside the message.
488    fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
489        ctx.external.evaluate("mp_id_role_is_msb")
490    }
491
492    /// [32] MP-ID mit Rolle NB
493    /// EXTERNAL: Requires context from outside the message.
494    fn evaluate_32(&self, ctx: &EvaluationContext) -> ConditionResult {
495        ctx.external.evaluate("mp_id_role_is_nb")
496    }
497
498    /// [33] Wenn AJT+A02/A03+E_0488 vorhanden
499    fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
500        let segments = ctx.find_segments("AJT");
501        ConditionResult::from(segments.iter().any(|s| {
502            let qual = s
503                .elements
504                .first()
505                .and_then(|e| e.first())
506                .map(|v| v.as_str());
507            let val = s
508                .elements
509                .get(1)
510                .and_then(|e| e.first())
511                .map(|v| v.as_str());
512            matches!(qual, Some("A02") | Some("A03")) && matches!(val, Some("E_0488"))
513        }))
514    }
515
516    /// [34] wenn vorhanden
517    // REVIEW: 'wenn vorhanden' is a generic conditional-use annotation meaning the element should be included whenever the relevant data is available. As a standalone condition without a specific segment target, it functions as a Hinweis-like unconditional True. (medium confidence)
518    fn evaluate_34(&self, _ctx: &EvaluationContext) -> ConditionResult {
519        // 'wenn vorhanden' — generic availability condition: element is conditional on presence of the data
520        // Without a specific segment reference this acts as an unconditional note
521        ConditionResult::True
522    }
523
524    /// [37] Wenn in dieser Nachricht das SG8 CUX+2 vorhanden
525    fn evaluate_37(&self, ctx: &EvaluationContext) -> ConditionResult {
526        ctx.has_qualifier("CUX", 0, "2")
527    }
528
529    /// [38] Möglicher Wert: ZB4 oder ZB5
530    fn evaluate_38(&self, _ctx: &EvaluationContext) -> ConditionResult {
531        // Hinweis: Möglicher Wert: ZB4 oder ZB5 — informational note documenting permitted values
532        ConditionResult::True
533    }
534
535    /// [39] Möglicher Wert: E17 oder Z07
536    fn evaluate_39(&self, _ctx: &EvaluationContext) -> ConditionResult {
537        // Hinweis: Möglicher Wert: E17 oder Z07 — informational note documenting permitted values
538        ConditionResult::True
539    }
540
541    /// [40] Wenn der Code im DE3207 in der "EDI@Energy Codeliste der europäischen Ländercodes" in der Spalte "PLZ vorhanden" ein "X" enthält
542    /// EXTERNAL: Requires context from outside the message.
543    fn evaluate_40(&self, ctx: &EvaluationContext) -> ConditionResult {
544        ctx.external.evaluate("country_has_postal_code")
545    }
546
547    /// [41] wenn SG2 AJT (Einzelheiten zu einer Anpassung/Änderung) DE4465 mit Wert ZB5 vorhanden
548    fn evaluate_41(&self, ctx: &EvaluationContext) -> ConditionResult {
549        ctx.has_qualifier("AJT", 0, "ZB5")
550    }
551
552    /// [42] Wenn SG2 AJT+Z07 (Antwortkategorie: Ablehnung (Keine Berechtigung)) vorhanden
553    fn evaluate_42(&self, ctx: &EvaluationContext) -> ConditionResult {
554        ctx.has_qualifier("AJT", 0, "Z07")
555    }
556
557    /// [43] Wenn AJT+A02/A03+E_1001 vorhanden
558    fn evaluate_43(&self, ctx: &EvaluationContext) -> ConditionResult {
559        let ajts = ctx.find_segments("AJT");
560        let found = ajts.iter().any(|s| {
561            let code = s
562                .elements
563                .first()
564                .and_then(|e| e.first())
565                .map(|v| v.as_str());
566            let pos = s
567                .elements
568                .get(1)
569                .and_then(|e| e.first())
570                .map(|v| v.as_str());
571            matches!(code, Some("A02") | Some("A03")) && matches!(pos, Some("E_1001"))
572        });
573        ConditionResult::from(found)
574    }
575
576    /// [44] Wenn AJT+A05+E_1000 vorhanden
577    fn evaluate_44(&self, ctx: &EvaluationContext) -> ConditionResult {
578        let ajts = ctx.find_segments("AJT");
579        let found = ajts.iter().any(|s| {
580            let code = s
581                .elements
582                .first()
583                .and_then(|e| e.first())
584                .map(|v| v.as_str());
585            let pos = s
586                .elements
587                .get(1)
588                .and_then(|e| e.first())
589                .map(|v| v.as_str());
590            matches!(code, Some("A05")) && matches!(pos, Some("E_1000"))
591        });
592        ConditionResult::from(found)
593    }
594
595    /// [45] Wenn AJT+A09+E_1000 vorhanden
596    fn evaluate_45(&self, ctx: &EvaluationContext) -> ConditionResult {
597        let ajts = ctx.find_segments("AJT");
598        let found = ajts.iter().any(|s| {
599            let code = s
600                .elements
601                .first()
602                .and_then(|e| e.first())
603                .map(|v| v.as_str());
604            let pos = s
605                .elements
606                .get(1)
607                .and_then(|e| e.first())
608                .map(|v| v.as_str());
609            matches!(code, Some("A09")) && matches!(pos, Some("E_1000"))
610        });
611        ConditionResult::from(found)
612    }
613
614    /// [46] Wenn AJT+A06+E_0552 vorhanden
615    fn evaluate_46(&self, ctx: &EvaluationContext) -> ConditionResult {
616        let ajts = ctx.find_segments("AJT");
617        let found = ajts.iter().any(|s| {
618            let code = s
619                .elements
620                .first()
621                .and_then(|e| e.first())
622                .map(|v| v.as_str());
623            let pos = s
624                .elements
625                .get(1)
626                .and_then(|e| e.first())
627                .map(|v| v.as_str());
628            matches!(code, Some("A06")) && matches!(pos, Some("E_0552"))
629        });
630        ConditionResult::from(found)
631    }
632
633    /// [47] Wenn AJT+A06+E_0553 vorhanden
634    fn evaluate_47(&self, ctx: &EvaluationContext) -> ConditionResult {
635        let ajts = ctx.find_segments("AJT");
636        let found = ajts.iter().any(|s| {
637            let code = s
638                .elements
639                .first()
640                .and_then(|e| e.first())
641                .map(|v| v.as_str());
642            let pos = s
643                .elements
644                .get(1)
645                .and_then(|e| e.first())
646                .map(|v| v.as_str());
647            matches!(code, Some("A06")) && matches!(pos, Some("E_0553"))
648        });
649        ConditionResult::from(found)
650    }
651
652    /// [48] Wenn AJT+A06+E_0554 vorhanden
653    fn evaluate_48(&self, ctx: &EvaluationContext) -> ConditionResult {
654        let ajts = ctx.find_segments("AJT");
655        let found = ajts.iter().any(|s| {
656            let code = s
657                .elements
658                .first()
659                .and_then(|e| e.first())
660                .map(|v| v.as_str());
661            let pos = s
662                .elements
663                .get(1)
664                .and_then(|e| e.first())
665                .map(|v| v.as_str());
666            matches!(code, Some("A06")) && matches!(pos, Some("E_0554"))
667        });
668        ConditionResult::from(found)
669    }
670
671    /// [49] nur, wenn in ursprünglicher Nachricht IMD++Z60 (Abbestellung Messprodukt mit Zählzeitdefinition des LF) vorhanden war
672    /// EXTERNAL: Requires context from outside the message.
673    fn evaluate_49(&self, ctx: &EvaluationContext) -> ConditionResult {
674        ctx.external.evaluate("original_order_had_imd_z60")
675    }
676
677    /// [50] wenn im DE3155 in demselben COM der Code EM vorhanden ist
678    fn evaluate_50(&self, ctx: &EvaluationContext) -> ConditionResult {
679        let coms = ctx.find_segments("COM");
680        ConditionResult::from(coms.iter().any(|s| {
681            s.elements
682                .first()
683                .and_then(|e| e.get(1))
684                .map(|v| v == "EM")
685                .unwrap_or(false)
686        }))
687    }
688
689    /// [51] wenn im DE3155 in demselben COM der Code TE / FX / AJ / AL vorhanden ist
690    fn evaluate_51(&self, ctx: &EvaluationContext) -> ConditionResult {
691        let coms = ctx.find_segments("COM");
692        ConditionResult::from(coms.iter().any(|s| {
693            matches!(
694                s.elements
695                    .first()
696                    .and_then(|e| e.get(1))
697                    .map(|v| v.as_str()),
698                Some("TE") | Some("FX") | Some("AJ") | Some("AL")
699            )
700        }))
701    }
702
703    /// [53] Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z59
704    fn evaluate_53(&self, _ctx: &EvaluationContext) -> ConditionResult {
705        // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z59 — informational note about value origin, always applies
706        ConditionResult::True
707    }
708
709    /// [54] Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z80
710    fn evaluate_54(&self, _ctx: &EvaluationContext) -> ConditionResult {
711        // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z80 — informational note about value origin, always applies
712        ConditionResult::True
713    }
714
715    /// [55] Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z81
716    fn evaluate_55(&self, _ctx: &EvaluationContext) -> ConditionResult {
717        // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z81 — informational note about value origin, always applies
718        ConditionResult::True
719    }
720
721    /// [56] wenn SG2 AJT+A02/A03/A06/A07/A10/A11+E_0548 vorhanden
722    fn evaluate_56(&self, ctx: &EvaluationContext) -> ConditionResult {
723        let ajts = ctx.find_segments("AJT");
724        ConditionResult::from(ajts.iter().any(|s| {
725            let de4465 = s
726                .elements
727                .first()
728                .and_then(|e| e.first())
729                .map(|s| s.as_str());
730            let de1082 = s
731                .elements
732                .get(1)
733                .and_then(|e| e.first())
734                .map(|s| s.as_str());
735            matches!(
736                de4465,
737                Some("A02") | Some("A03") | Some("A06") | Some("A07") | Some("A10") | Some("A11")
738            ) && de1082 == Some("E_0548")
739        }))
740    }
741
742    /// [57] wenn SG2 AJT+A02/A03/A06/A07/A10/A11+E_0549 vorhanden
743    fn evaluate_57(&self, ctx: &EvaluationContext) -> ConditionResult {
744        let ajts = ctx.find_segments("AJT");
745        ConditionResult::from(ajts.iter().any(|s| {
746            let de4465 = s
747                .elements
748                .first()
749                .and_then(|e| e.first())
750                .map(|s| s.as_str());
751            let de1082 = s
752                .elements
753                .get(1)
754                .and_then(|e| e.first())
755                .map(|s| s.as_str());
756            matches!(
757                de4465,
758                Some("A02") | Some("A03") | Some("A06") | Some("A07") | Some("A10") | Some("A11")
759            ) && de1082 == Some("E_0549")
760        }))
761    }
762
763    /// [58] wenn SG2 AJT+A02/A03/A06/A07+E_0550 vorhanden
764    fn evaluate_58(&self, ctx: &EvaluationContext) -> ConditionResult {
765        let ajts = ctx.find_segments("AJT");
766        ConditionResult::from(ajts.iter().any(|s| {
767            let de4465 = s
768                .elements
769                .first()
770                .and_then(|e| e.first())
771                .map(|s| s.as_str());
772            let de1082 = s
773                .elements
774                .get(1)
775                .and_then(|e| e.first())
776                .map(|s| s.as_str());
777            matches!(
778                de4465,
779                Some("A02") | Some("A03") | Some("A06") | Some("A07")
780            ) && de1082 == Some("E_0550")
781        }))
782    }
783
784    /// [59] wenn SG2 AJT+A02/A03/A06/A07/A10/A11+E_0551 vorhanden
785    fn evaluate_59(&self, ctx: &EvaluationContext) -> ConditionResult {
786        let ajts = ctx.find_segments("AJT");
787        ConditionResult::from(ajts.iter().any(|s| {
788            let de4465 = s
789                .elements
790                .first()
791                .and_then(|e| e.first())
792                .map(|s| s.as_str());
793            let de1082 = s
794                .elements
795                .get(1)
796                .and_then(|e| e.first())
797                .map(|s| s.as_str());
798            matches!(
799                de4465,
800                Some("A02") | Some("A03") | Some("A06") | Some("A07") | Some("A10") | Some("A11")
801            ) && de1082 == Some("E_0551")
802        }))
803    }
804
805    /// [61] wenn es sich bei der Reklamation um die Reklamation der Übersicht der Schaltzeitdefinitionen handelte
806    // REVIEW: The condition checks whether the complaint concerned the overview of switching time definitions (Schaltzeitdefinitionen). Condition 63 establishes that BGM+Z60 is the code for Schaltzeitdefinitionen in UTILTS, and the ORDRSP BGM code mirrors this type. Checking BGM elements[0][0] == 'Z60' identifies this complaint type. (medium confidence)
807    fn evaluate_61(&self, ctx: &EvaluationContext) -> ConditionResult {
808        // Reklamation der Übersicht der Schaltzeitdefinitionen → ORDRSP with BGM+Z60
809        ctx.has_qualifier("BGM", 0, "Z60")
810    }
811
812    /// [62] wenn es sich bei der Reklamation um die Reklamation der Übersicht der Leistungskurvendefinitionen handelte
813    // REVIEW: The condition checks whether the complaint concerned the overview of load curve definitions (Leistungskurvendefinitionen). Conditions 64 and 65 establish BGM+Z78 and BGM+Z79 as the two related UTILTS codes for Leistungskurven types, so both are checked. (medium confidence)
814    fn evaluate_62(&self, ctx: &EvaluationContext) -> ConditionResult {
815        // Reklamation der Übersicht der Leistungskurvendefinitionen → BGM+Z78 or BGM+Z79
816        let bgm_segs = ctx.find_segments("BGM");
817        match bgm_segs.first() {
818            Some(s) => {
819                let code = s
820                    .elements
821                    .first()
822                    .and_then(|e| e.first())
823                    .map(|v| v.as_str());
824                ConditionResult::from(matches!(code, Some("Z78") | Some("Z79")))
825            }
826            None => ConditionResult::False, // segment absent → condition not applicable
827        }
828    }
829
830    /// [63] Dokumentennummer aus BGM+Z60 DE1004 der UTILTS
831    fn evaluate_63(&self, _ctx: &EvaluationContext) -> ConditionResult {
832        // Hinweis: Dokumentennummer aus BGM+Z60 DE1004 der UTILTS — informational note, always applies
833        ConditionResult::True
834    }
835
836    /// [64] Dokumentennummer aus BGM+Z78 DE1004 der UTILTS
837    fn evaluate_64(&self, _ctx: &EvaluationContext) -> ConditionResult {
838        // Hinweis: Dokumentennummer aus BGM+Z78 DE1004 der UTILTS — informational note, always applies
839        ConditionResult::True
840    }
841
842    /// [65] Dokumentennummer aus BGM+Z79 DE1004 der UTILTS
843    fn evaluate_65(&self, _ctx: &EvaluationContext) -> ConditionResult {
844        // Hinweis: Dokumentennummer aus BGM+Z79 DE1004 der UTILTS — informational note, always applies
845        ConditionResult::True
846    }
847
848    /// [66] wenn SG2 AJT+A01/A02/A03+E_0544 vorhanden
849    fn evaluate_66(&self, ctx: &EvaluationContext) -> ConditionResult {
850        let ajts = ctx.find_segments("AJT");
851        ConditionResult::from(ajts.iter().any(|s| {
852            let de4465 = s
853                .elements
854                .first()
855                .and_then(|e| e.first())
856                .map(|s| s.as_str());
857            let de1082 = s
858                .elements
859                .get(1)
860                .and_then(|e| e.first())
861                .map(|s| s.as_str());
862            matches!(de4465, Some("A01") | Some("A02") | Some("A03")) && de1082 == Some("E_0544")
863        }))
864    }
865
866    /// [67] wenn SG2 AJT+A01/A02/A03+E_0545 vorhanden
867    fn evaluate_67(&self, ctx: &EvaluationContext) -> ConditionResult {
868        let ajts = ctx.find_segments("AJT");
869        ConditionResult::from(ajts.iter().any(|s| {
870            let de4465 = s
871                .elements
872                .first()
873                .and_then(|e| e.first())
874                .map(|s| s.as_str());
875            let de1082 = s
876                .elements
877                .get(1)
878                .and_then(|e| e.first())
879                .map(|s| s.as_str());
880            matches!(de4465, Some("A01") | Some("A02") | Some("A03")) && de1082 == Some("E_0545")
881        }))
882    }
883
884    /// [68] wenn SG2 AJT+A02/A03+E_0546 vorhanden
885    fn evaluate_68(&self, ctx: &EvaluationContext) -> ConditionResult {
886        let ajts = ctx.find_segments("AJT");
887        ConditionResult::from(ajts.iter().any(|s| {
888            let de4465 = s
889                .elements
890                .first()
891                .and_then(|e| e.first())
892                .map(|s| s.as_str());
893            let de1082 = s
894                .elements
895                .get(1)
896                .and_then(|e| e.first())
897                .map(|s| s.as_str());
898            matches!(de4465, Some("A02") | Some("A03")) && de1082 == Some("E_0546")
899        }))
900    }
901
902    /// [69] wenn SG2 AJT+A01/A02/A03+E_0547 vorhanden
903    fn evaluate_69(&self, ctx: &EvaluationContext) -> ConditionResult {
904        let ajts = ctx.find_segments("AJT");
905        ConditionResult::from(ajts.iter().any(|s| {
906            let de4465 = s
907                .elements
908                .first()
909                .and_then(|e| e.first())
910                .map(|s| s.as_str());
911            let de1082 = s
912                .elements
913                .get(1)
914                .and_then(|e| e.first())
915                .map(|s| s.as_str());
916            matches!(de4465, Some("A01") | Some("A02") | Some("A03")) && de1082 == Some("E_0547")
917        }))
918    }
919
920    /// [72] wenn AJT+A04+E_0552 vorhanden
921    fn evaluate_72(&self, ctx: &EvaluationContext) -> ConditionResult {
922        ctx.has_qualified_value("AJT", 0, "A04", 1, 0, &["E_0552"])
923    }
924
925    /// [73] wenn AJT+A04+E_0553 vorhanden
926    fn evaluate_73(&self, ctx: &EvaluationContext) -> ConditionResult {
927        ctx.has_qualified_value("AJT", 0, "A04", 1, 0, &["E_0553"])
928    }
929
930    /// [74] wenn AJT+A04+E_0554 vorhanden
931    fn evaluate_74(&self, ctx: &EvaluationContext) -> ConditionResult {
932        ctx.has_qualified_value("AJT", 0, "A04", 1, 0, &["E_0554"])
933    }
934
935    /// [76] Wenn FTX+Z27 (IP-Adresse des Absenders) nicht vorhanden
936    fn evaluate_76(&self, ctx: &EvaluationContext) -> ConditionResult {
937        ctx.lacks_qualifier("FTX", 0, "Z27")
938    }
939
940    /// [77] Wenn FTX+Z28 (IP-Range des Absenders) nicht vorhanden
941    fn evaluate_77(&self, ctx: &EvaluationContext) -> ConditionResult {
942        ctx.lacks_qualifier("FTX", 0, "Z28")
943    }
944
945    /// [492] wenn MP-ID in NAD+MR aus Sparte Strom
946    /// EXTERNAL: Requires context from outside the message.
947    fn evaluate_492(&self, ctx: &EvaluationContext) -> ConditionResult {
948        ctx.external.evaluate("recipient_is_strom")
949    }
950
951    /// [493] wenn MP-ID in NAD+MR aus Sparte Gas
952    /// EXTERNAL: Requires context from outside the message.
953    fn evaluate_493(&self, ctx: &EvaluationContext) -> ConditionResult {
954        ctx.external.evaluate("recipient_is_gas")
955    }
956
957    /// [494] Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.
958    // REVIEW: 'Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.' This is a constraint description stating the date must be the document creation time or earlier. It functions as an unconditional validation rule (always applies) rather than a conditional trigger. Without knowing which specific DTM qualifier 'here' refers to in the calling context, and since the constraint itself is always applicable, returning True is appropriate. (medium confidence)
959    fn evaluate_494(&self, _ctx: &EvaluationContext) -> ConditionResult {
960        ConditionResult::True
961    }
962
963    /// [500] Hinweis: Angabe eines technischen Ansprechpartners für die Geräteübernahme
964    fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
965        ConditionResult::True
966    }
967
968    /// [503] Hinweis: Datum, bis zu dem der MSBA zur Fortführung verpflichtet wurde
969    fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
970        ConditionResult::True
971    }
972
973    /// [504] Hinweis: Ggf. korrigiert bei einer Zeitangabe in der ORDERS, die außerhalb des max. möglichen Weiterverpflichtungszeitraums ist. Als Antwort wird dann in SG2 AJT Zustimmung mit Terminänderung an...
974    fn evaluate_504(&self, _ctx: &EvaluationContext) -> ConditionResult {
975        // Hinweis: Ggf. korrigiert bei einer Zeitangabe in der ORDERS, die außerhalb des max. möglichen Weiterverpflichtungszeitraums ist. Als Antwort wird dann in SG2 AJT Zustimmung mit Terminänderung angegeben.
976        ConditionResult::True
977    }
978
979    /// [513] Hinweis: Wert aus BGM+Z12 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
980    fn evaluate_513(&self, _ctx: &EvaluationContext) -> ConditionResult {
981        // Hinweis: Wert aus BGM+Z12 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
982        ConditionResult::True
983    }
984
985    /// [518] Hinweis: Wert aus BGM+Z10 DE1004 der ORDERS, mit der die Bestellung erfolgt ist
986    fn evaluate_518(&self, _ctx: &EvaluationContext) -> ConditionResult {
987        // Hinweis: Wert aus BGM+Z10 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
988        ConditionResult::True
989    }
990
991    /// [519] Hinweis: Wert aus BGM+7 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
992    fn evaluate_519(&self, _ctx: &EvaluationContext) -> ConditionResult {
993        // Hinweis: Wert aus BGM+7 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
994        ConditionResult::True
995    }
996
997    /// [520] Hinweis: Wert aus BGM+Z29 DE1004 der ORDERS, mit der die Anfrage zur Beendigung der Rechnungsabwicklung erfolgt ist.
998    fn evaluate_520(&self, _ctx: &EvaluationContext) -> ConditionResult {
999        // Hinweis: Wert aus BGM+Z29 DE1004 der ORDERS, mit der die Anfrage zur Beendigung der Rechnungsabwicklung erfolgt ist.
1000        ConditionResult::True
1001    }
1002
1003    /// [521] Hinweis: Wert aus BGM+Z14/Z61/Z62 DE1004 der ORDERS, mit der die Anforderung von Stammdaten erfolgt ist
1004    fn evaluate_521(&self, _ctx: &EvaluationContext) -> ConditionResult {
1005        // Hinweis: Wert aus BGM+Z14/Z61/Z62 DE1004 der ORDERS, mit der die Anforderung von Stammdaten erfolgt ist
1006        // Informational note — documents that the BGM DE1004 value originates from the original ORDERS request.
1007        ConditionResult::True
1008    }
1009
1010    /// [522] Hinweis: Wert aus BGM+7/Z28/Z48 DE1004 der ORDERS, mit der die Anforderung von Werten erfolgt ist.
1011    fn evaluate_522(&self, _ctx: &EvaluationContext) -> ConditionResult {
1012        // Hinweis: Wert aus BGM+7/Z28/Z48 DE1004 der ORDERS — informational note, always applies
1013        ConditionResult::True
1014    }
1015
1016    /// [523] Hinweis: Wert aus BGM+7 DE1004 der ORDERS, mit der die Anforderung Anforderung von Brennwert und Zustandszahl erfolgt ist.
1017    fn evaluate_523(&self, _ctx: &EvaluationContext) -> ConditionResult {
1018        // Hinweis: Wert aus BGM+7 DE1004 der ORDERS — informational note, always applies
1019        ConditionResult::True
1020    }
1021
1022    /// [524] Hinweis: Wert aus BGM+Z14 DE1004 der ORDERS, mit der die Anfrage vom MSB Gas erfolgt ist.
1023    fn evaluate_524(&self, _ctx: &EvaluationContext) -> ConditionResult {
1024        // Hinweis: Wert aus BGM+Z14 DE1004 der ORDERS — informational note, always applies
1025        ConditionResult::True
1026    }
1027
1028    /// [525] Hinweis: Wert aus BGM+Z24 DE1004 der ORDERS, mit der die Anforderung Allokationsliste erfolgt ist
1029    fn evaluate_525(&self, _ctx: &EvaluationContext) -> ConditionResult {
1030        // Hinweis: Wert aus BGM+Z24 DE1004 der ORDERS — informational note, always applies
1031        ConditionResult::True
1032    }
1033
1034    /// [526] Hinweis: Wert aus BGM+Z23 DE1004 der ORDERS, mit der die Anforderung bilanzierte Menge erfolgt ist
1035    fn evaluate_526(&self, _ctx: &EvaluationContext) -> ConditionResult {
1036        // Hinweis: Wert aus BGM+Z23 DE1004 der ORDERS — informational note, always applies
1037        ConditionResult::True
1038    }
1039
1040    /// [527] Hinweis: Wert aus BGM+Z34 DE1004 der ORDERS, mit der die Reklamation von Werten erfolgt ist.
1041    fn evaluate_527(&self, _ctx: &EvaluationContext) -> ConditionResult {
1042        // Hinweis: Wert aus BGM+Z34 DE1004 der ORDERS, mit der die Reklamation von Werten erfolgt ist. — informational note, always applies
1043        ConditionResult::True
1044    }
1045
1046    /// [529] Hinweis: Dokumentennummer aus BGM DE1004 der ORDERS
1047    fn evaluate_529(&self, _ctx: &EvaluationContext) -> ConditionResult {
1048        // Hinweis: Dokumentennummer aus BGM DE1004 der ORDERS — informational note, always applies
1049        ConditionResult::True
1050    }
1051
1052    /// [530] Hinweis: Dokumentennummer aus BGM DE1004 der ORDCHG
1053    fn evaluate_530(&self, _ctx: &EvaluationContext) -> ConditionResult {
1054        // Hinweis: Dokumentennummer aus BGM DE1004 der ORDCHG — informational note, always applies
1055        ConditionResult::True
1056    }
1057
1058    /// [533] Hinweis: Wert aus BGM+Z51 DE1004 der ORDCHG
1059    fn evaluate_533(&self, _ctx: &EvaluationContext) -> ConditionResult {
1060        // Hinweis: Wert aus BGM+Z51 DE1004 der ORDCHG — informational note, always applies
1061        ConditionResult::True
1062    }
1063
1064    /// [534] Hinweis: Wert aus BGM+Z52 DE1004 der ORDCHG
1065    fn evaluate_534(&self, _ctx: &EvaluationContext) -> ConditionResult {
1066        // Hinweis: Wert aus BGM+Z52 DE1004 der ORDCHG — informational note, always applies
1067        ConditionResult::True
1068    }
1069
1070    /// [535] Hinweis: Wert aus BGM+Z13 DE1004 der ORDERS, mit der die Ankündigung Gerätewechselabsicht erfolgt ist.
1071    fn evaluate_535(&self, _ctx: &EvaluationContext) -> ConditionResult {
1072        // Hinweis: Wert aus BGM+Z13 DE1004 der ORDERS — informational note, always applies
1073        ConditionResult::True
1074    }
1075
1076    /// [536] Hinweis: Es ist die MP-ID des Eigentümers (MSB) zur bilateralen Klärung anzugeben, wenn der angefragte MSB nicht selber der Eigentümer ist.
1077    fn evaluate_536(&self, _ctx: &EvaluationContext) -> ConditionResult {
1078        // Hinweis: MP-ID des Eigentümers (MSB) angeben — informational note, always applies
1079        ConditionResult::True
1080    }
1081
1082    /// [537] Hinweis: Wert aus BGM+Z72 DE1004 der ORDERS, mit der die Bestellung Beendigung der Konfiguration erfolgt ist.
1083    fn evaluate_537(&self, _ctx: &EvaluationContext) -> ConditionResult {
1084        // Hinweis: Wert aus BGM+Z72 DE1004 der ORDERS — informational note, always applies
1085        ConditionResult::True
1086    }
1087
1088    /// [538] Hinweis: Wert aus BGM+Z76 DE1004 der ORDERS, mit der die Reklamation der Konfiguration erfolgt ist.
1089    fn evaluate_538(&self, _ctx: &EvaluationContext) -> ConditionResult {
1090        // Hinweis: Wert aus BGM+Z76 DE1004 der ORDERS — informational note, always applies
1091        ConditionResult::True
1092    }
1093
1094    /// [539] Hinweis: Wert aus BGM+Z73/Z74 DE1004 der ORDERS, mit der die Bestellung der Konfiguration erfolgt ist.
1095    fn evaluate_539(&self, _ctx: &EvaluationContext) -> ConditionResult {
1096        // Hinweis: Wert aus BGM+Z73/Z74 DE1004 der ORDERS — informational note, always applies
1097        ConditionResult::True
1098    }
1099
1100    /// [540] Hinweis: Es darf nur eine Information im DE3148 übermittelt werden
1101    fn evaluate_540(&self, _ctx: &EvaluationContext) -> ConditionResult {
1102        // Hinweis: Es darf nur eine Information im DE3148 übermittelt werden — informational note, always applies
1103        ConditionResult::True
1104    }
1105
1106    /// [542] Hinweis: Wert aus BGM+Z91 DE1004 der ORDERS, mit der die Bestellung Änderung der Abrechnungsdaten erfolgt ist.
1107    fn evaluate_542(&self, _ctx: &EvaluationContext) -> ConditionResult {
1108        // Hinweis: Wert aus BGM+Z91 DE1004 der ORDERS — informational note about value origin, always applies
1109        ConditionResult::True
1110    }
1111
1112    /// [902] Format: Format: Möglicher Wert: ≥ 0
1113    // REVIEW: Format condition requiring numeric value >= 0. Applied to QTY segment value (elements[0][1]) by convention matching the example pattern. Medium confidence because the exact segment this applies to is not specified in the condition text, but QTY is the standard target for quantity format conditions. (medium confidence)
1114    fn evaluate_902(&self, ctx: &EvaluationContext) -> ConditionResult {
1115        // Format: Möglicher Wert: >= 0
1116        let segs = ctx.find_segments("QTY");
1117        match segs
1118            .first()
1119            .and_then(|s| s.elements.first())
1120            .and_then(|e| e.get(1))
1121        {
1122            Some(val) => validate_numeric(val, ">=", 0.0),
1123            None => ConditionResult::False, // segment absent → condition not applicable
1124        }
1125    }
1126
1127    /// [903] Format: Möglicher Wert: 1
1128    // REVIEW: Format condition requiring the value to equal exactly 1. Applied to QTY segment value (elements[0][1]) by convention. Medium confidence as the exact target segment is not stated, but QTY quantity value is the standard target for this kind of format constraint. (medium confidence)
1129    fn evaluate_903(&self, ctx: &EvaluationContext) -> ConditionResult {
1130        // Format: Möglicher Wert: 1
1131        let segs = ctx.find_segments("QTY");
1132        match segs
1133            .first()
1134            .and_then(|s| s.elements.first())
1135            .and_then(|e| e.get(1))
1136        {
1137            Some(val) => validate_numeric(val, "==", 1.0),
1138            None => ConditionResult::False, // segment absent → condition not applicable
1139        }
1140    }
1141
1142    /// [930] Format: max. 2 Nachkommastellen
1143    // REVIEW: Format condition requiring at most 2 decimal places. Applied to QTY segment value (elements[0][1]) following the standard pattern from example 19. Medium confidence as the exact target segment is not specified in the condition text, but QTY quantity value is the canonical target for decimal place constraints. (medium confidence)
1144    fn evaluate_930(&self, ctx: &EvaluationContext) -> ConditionResult {
1145        // Format: max. 2 Nachkommastellen
1146        let segs = ctx.find_segments("QTY");
1147        match segs
1148            .first()
1149            .and_then(|s| s.elements.first())
1150            .and_then(|e| e.get(1))
1151        {
1152            Some(val) => validate_max_decimal_places(val, 2),
1153            None => ConditionResult::False, // segment absent → condition not applicable
1154        }
1155    }
1156
1157    /// [931] Format: ZZZ = +00
1158    fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
1159        let dtm_segs = ctx.find_segments("DTM");
1160        match dtm_segs
1161            .first()
1162            .and_then(|s| s.elements.first())
1163            .and_then(|e| e.get(1))
1164        {
1165            Some(val) => validate_timezone_utc(val),
1166            None => ConditionResult::False, // segment absent → condition not applicable
1167        }
1168    }
1169
1170    /// [932] Format: HHMM = 2200
1171    fn evaluate_932(&self, ctx: &EvaluationContext) -> ConditionResult {
1172        let dtm_segs = ctx.find_segments("DTM");
1173        match dtm_segs
1174            .first()
1175            .and_then(|s| s.elements.first())
1176            .and_then(|e| e.get(1))
1177        {
1178            Some(val) => validate_hhmm_equals(val, "2200"),
1179            None => ConditionResult::False, // segment absent → condition not applicable
1180        }
1181    }
1182
1183    /// [933] Format: HHMM = 2300
1184    fn evaluate_933(&self, ctx: &EvaluationContext) -> ConditionResult {
1185        let dtm_segs = ctx.find_segments("DTM");
1186        match dtm_segs
1187            .first()
1188            .and_then(|s| s.elements.first())
1189            .and_then(|e| e.get(1))
1190        {
1191            Some(val) => validate_hhmm_equals(val, "2300"),
1192            None => ConditionResult::False, // segment absent → condition not applicable
1193        }
1194    }
1195
1196    /// [934] Format: HHMM = 0400
1197    fn evaluate_934(&self, ctx: &EvaluationContext) -> ConditionResult {
1198        let dtm_segs = ctx.find_segments("DTM");
1199        match dtm_segs
1200            .first()
1201            .and_then(|s| s.elements.first())
1202            .and_then(|e| e.get(1))
1203        {
1204            Some(val) => validate_hhmm_equals(val, "0400"),
1205            None => ConditionResult::False, // segment absent → condition not applicable
1206        }
1207    }
1208
1209    /// [935] Format: HHMM = 0500
1210    fn evaluate_935(&self, ctx: &EvaluationContext) -> ConditionResult {
1211        let dtm_segs = ctx.find_segments("DTM");
1212        match dtm_segs
1213            .first()
1214            .and_then(|s| s.elements.first())
1215            .and_then(|e| e.get(1))
1216        {
1217            Some(val) => validate_hhmm_equals(val, "0500"),
1218            None => ConditionResult::False, // segment absent → condition not applicable
1219        }
1220    }
1221
1222    /// [939] Format: Die Zeichenkette muss die Zeichen @ und . enthalten
1223    // REVIEW: Format condition checking that the string contains '@' and '.' — characteristic of an email address format requirement. Applied to COM segment with EM (Electronic Mail) qualifier where elements[0][0] is the address and elements[0][1] is the communication means type code. Returns Unknown when no COM+EM segment is found (condition not applicable). (medium confidence)
1224    fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
1225        // Format: string must contain '@' and '.' — email address format check
1226        // Applied to COM segment with EM (Electronic Mail) qualifier
1227        // COM+address:qualifier → elements[0] = ["address", "qualifier"]
1228        let com_segs = ctx.find_segments("COM");
1229        for seg in &com_segs {
1230            if let Some(elem0) = seg.elements.first() {
1231                if elem0.get(1).map(|q| q == "EM").unwrap_or(false) {
1232                    let value = elem0.first().map(|s| s.as_str()).unwrap_or("");
1233                    if value.is_empty() {
1234                        return ConditionResult::Unknown;
1235                    }
1236                    return ConditionResult::from(value.contains('@') && value.contains('.'));
1237                }
1238            }
1239        }
1240        ConditionResult::Unknown
1241    }
1242
1243    /// [940] Format: Die Zeichenkette muss mit dem Zeichen + beginnen und danach dürfen nur noch Ziffern folgen
1244    // REVIEW: Format condition checking that the string starts with '+' and contains only digits afterwards — the international phone number format (e.g. +4912345678). Applied to COM segments with phone-type qualifiers (TE=Telephone, FX=Telefax, AH=After Hours). Returns Unknown when no COM segment with a phone qualifier is found. Requires at least one digit after '+' (len > 1) since a bare '+' is not a valid phone number. (medium confidence)
1245    fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
1246        // Format: string must start with '+' and be followed only by digits — international phone number format
1247        // Applied to COM segments with phone-type qualifiers: TE (Telephone), FX (Telefax), AH (After Hours)
1248        // COM+number:qualifier → elements[0] = ["number", "qualifier"]
1249        let com_segs = ctx.find_segments("COM");
1250        for seg in &com_segs {
1251            if let Some(elem0) = seg.elements.first() {
1252                let qualifier = elem0.get(1).map(|s| s.as_str()).unwrap_or("");
1253                if matches!(qualifier, "TE" | "FX" | "AH") {
1254                    let value = elem0.first().map(|s| s.as_str()).unwrap_or("");
1255                    if value.is_empty() {
1256                        return ConditionResult::Unknown;
1257                    }
1258                    return ConditionResult::from(
1259                        value.starts_with('+')
1260                            && value.len() > 1
1261                            && value[1..].chars().all(|c| c.is_ascii_digit()),
1262                    );
1263                }
1264            }
1265        }
1266        ConditionResult::Unknown
1267    }
1268
1269    /// [2036] Pro Nachricht ist die SG27 genau einmal anzugeben
1270    // REVIEW: Cardinality condition requiring SG27 to appear exactly once per message. SG27 is the transaction group (tx_group) in ORDRSP FV2504. Uses the group navigator to count SG27 instances at the top level. Falls back to Unknown when no navigator is available (e.g., when context is used without a pre-assembled tree). This is a structural cardinality rule rather than a content condition. (medium confidence)
1271    fn evaluate_2036(&self, ctx: &EvaluationContext) -> ConditionResult {
1272        // SG27 must appear exactly once per message
1273        // SG27 is the transaction group (tx_group) in ORDRSP
1274        if let Some(nav) = ctx.navigator() {
1275            let count = nav.group_instance_count(&["SG27"]);
1276            ConditionResult::from(count == 1)
1277        } else {
1278            ConditionResult::Unknown
1279        }
1280    }
1281}