Skip to main content

automapper_validation/generated/fv2504/
partin_conditions_fv2504.rs

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