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