Skip to main content

automapper_validation/generated/fv2510/
ordrsp_conditions_fv2510.rs

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