Skip to main content

automapper_validation/generated/fv2510/
reqote_conditions_fv2510.rs

1// <auto-generated>
2// Generated by automapper-generator generate-conditions
3// AHB: xml-migs-and-ahbs/FV2510/REQOTE_AHB_1_1_20250401.xml
4// Generated: 2026-03-12T10:31:57Z
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 REQOTE FV2510.
12pub struct ReqoteConditionEvaluatorFV2510 {
13    // External condition IDs that require runtime context.
14    external_conditions: std::collections::HashSet<u32>,
15}
16
17impl Default for ReqoteConditionEvaluatorFV2510 {
18    fn default() -> Self {
19        let mut external_conditions = std::collections::HashSet::new();
20        external_conditions.insert(10);
21        external_conditions.insert(24);
22        external_conditions.insert(28);
23        external_conditions.insert(29);
24        external_conditions.insert(30);
25        external_conditions.insert(31);
26        external_conditions.insert(32);
27        external_conditions.insert(33);
28        external_conditions.insert(35);
29        external_conditions.insert(36);
30        external_conditions.insert(37);
31        external_conditions.insert(38);
32        external_conditions.insert(41);
33        external_conditions.insert(42);
34        external_conditions.insert(43);
35        external_conditions.insert(44);
36        external_conditions.insert(45);
37        external_conditions.insert(47);
38        external_conditions.insert(48);
39        external_conditions.insert(49);
40        external_conditions.insert(50);
41        external_conditions.insert(51);
42        external_conditions.insert(53);
43        external_conditions.insert(492);
44        external_conditions.insert(493);
45        external_conditions.insert(2065);
46        external_conditions.insert(2066);
47        Self {
48            external_conditions,
49        }
50    }
51}
52
53impl ConditionEvaluator for ReqoteConditionEvaluatorFV2510 {
54    fn message_type(&self) -> &str {
55        "REQOTE"
56    }
57
58    fn format_version(&self) -> &str {
59        "FV2510"
60    }
61
62    fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
63        match condition {
64            1 => self.evaluate_1(ctx),
65            2 => self.evaluate_2(ctx),
66            10 => self.evaluate_10(ctx),
67            15 => self.evaluate_15(ctx),
68            16 => self.evaluate_16(ctx),
69            17 => self.evaluate_17(ctx),
70            18 => self.evaluate_18(ctx),
71            19 => self.evaluate_19(ctx),
72            20 => self.evaluate_20(ctx),
73            21 => self.evaluate_21(ctx),
74            22 => self.evaluate_22(ctx),
75            23 => self.evaluate_23(ctx),
76            24 => self.evaluate_24(ctx),
77            25 => self.evaluate_25(ctx),
78            26 => self.evaluate_26(ctx),
79            27 => self.evaluate_27(ctx),
80            28 => self.evaluate_28(ctx),
81            29 => self.evaluate_29(ctx),
82            30 => self.evaluate_30(ctx),
83            31 => self.evaluate_31(ctx),
84            32 => self.evaluate_32(ctx),
85            33 => self.evaluate_33(ctx),
86            35 => self.evaluate_35(ctx),
87            36 => self.evaluate_36(ctx),
88            37 => self.evaluate_37(ctx),
89            38 => self.evaluate_38(ctx),
90            39 => self.evaluate_39(ctx),
91            40 => self.evaluate_40(ctx),
92            41 => self.evaluate_41(ctx),
93            42 => self.evaluate_42(ctx),
94            43 => self.evaluate_43(ctx),
95            44 => self.evaluate_44(ctx),
96            45 => self.evaluate_45(ctx),
97            47 => self.evaluate_47(ctx),
98            48 => self.evaluate_48(ctx),
99            49 => self.evaluate_49(ctx),
100            50 => self.evaluate_50(ctx),
101            51 => self.evaluate_51(ctx),
102            52 => self.evaluate_52(ctx),
103            53 => self.evaluate_53(ctx),
104            490 => self.evaluate_490(ctx),
105            491 => self.evaluate_491(ctx),
106            492 => self.evaluate_492(ctx),
107            493 => self.evaluate_493(ctx),
108            494 => self.evaluate_494(ctx),
109            500 => self.evaluate_500(ctx),
110            501 => self.evaluate_501(ctx),
111            502 => self.evaluate_502(ctx),
112            503 => self.evaluate_503(ctx),
113            504 => self.evaluate_504(ctx),
114            507 => self.evaluate_507(ctx),
115            508 => self.evaluate_508(ctx),
116            509 => self.evaluate_509(ctx),
117            510 => self.evaluate_510(ctx),
118            511 => self.evaluate_511(ctx),
119            512 => self.evaluate_512(ctx),
120            514 => self.evaluate_514(ctx),
121            515 => self.evaluate_515(ctx),
122            516 => self.evaluate_516(ctx),
123            517 => self.evaluate_517(ctx),
124            518 => self.evaluate_518(ctx),
125            520 => self.evaluate_520(ctx),
126            521 => self.evaluate_521(ctx),
127            903 => self.evaluate_903(ctx),
128            906 => self.evaluate_906(ctx),
129            911 => self.evaluate_911(ctx),
130            922 => self.evaluate_922(ctx),
131            931 => self.evaluate_931(ctx),
132            932 => self.evaluate_932(ctx),
133            933 => self.evaluate_933(ctx),
134            934 => self.evaluate_934(ctx),
135            935 => self.evaluate_935(ctx),
136            939 => self.evaluate_939(ctx),
137            940 => self.evaluate_940(ctx),
138            950 => self.evaluate_950(ctx),
139            951 => self.evaluate_951(ctx),
140            960 => self.evaluate_960(ctx),
141            961 => self.evaluate_961(ctx),
142            962 => self.evaluate_962(ctx),
143            967 => self.evaluate_967(ctx),
144            2005 => self.evaluate_2005(ctx),
145            2060 => self.evaluate_2060(ctx),
146            2061 => self.evaluate_2061(ctx),
147            2062 => self.evaluate_2062(ctx),
148            2063 => self.evaluate_2063(ctx),
149            2064 => self.evaluate_2064(ctx),
150            2065 => self.evaluate_2065(ctx),
151            2066 => self.evaluate_2066(ctx),
152            2067 => self.evaluate_2067(ctx),
153            2068 => self.evaluate_2068(ctx),
154            _ => ConditionResult::Unknown,
155        }
156    }
157
158    fn is_external(&self, condition: u32) -> bool {
159        self.external_conditions.contains(&condition)
160    }
161    fn is_known(&self, condition: u32) -> bool {
162        matches!(
163            condition,
164            1 | 2
165                | 10
166                | 15
167                | 16
168                | 17
169                | 18
170                | 19
171                | 20
172                | 21
173                | 22
174                | 23
175                | 24
176                | 25
177                | 26
178                | 27
179                | 28
180                | 29
181                | 30
182                | 31
183                | 32
184                | 33
185                | 35
186                | 36
187                | 37
188                | 38
189                | 39
190                | 40
191                | 41
192                | 42
193                | 43
194                | 44
195                | 45
196                | 47
197                | 48
198                | 49
199                | 50
200                | 51
201                | 52
202                | 53
203                | 490
204                | 491
205                | 492
206                | 493
207                | 494
208                | 500
209                | 501
210                | 502
211                | 503
212                | 504
213                | 507
214                | 508
215                | 509
216                | 510
217                | 511
218                | 512
219                | 514
220                | 515
221                | 516
222                | 517
223                | 518
224                | 520
225                | 521
226                | 903
227                | 906
228                | 911
229                | 922
230                | 931
231                | 932
232                | 933
233                | 934
234                | 935
235                | 939
236                | 940
237                | 950
238                | 951
239                | 960
240                | 961
241                | 962
242                | 967
243                | 2005
244                | 2060
245                | 2061
246                | 2062
247                | 2063
248                | 2064
249                | 2065
250                | 2066
251                | 2067
252                | 2068
253        )
254    }
255}
256
257impl ReqoteConditionEvaluatorFV2510 {
258    /// [33] Es sind nur die Messprodukte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.4 „Messprodukte mit Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW“ enthalten sind.
259    /// EXTERNAL: Requires context from outside the message.
260    fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
261        ctx.external
262            .evaluate("messprodukt_in_konfigurationserlaubnis_smgw_list")
263    }
264
265    /// [37] Es sind nur die Messprodukt-Position-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.7 „Art der Werte für Messprodukte nach Typ 2“ enthalten sind.
266    /// EXTERNAL: Requires context from outside the message.
267    fn evaluate_37(&self, ctx: &EvaluationContext) -> ConditionResult {
268        ctx.external
269            .evaluate("messprodukt_position_in_kapitel_4_7_list")
270    }
271
272    /// [38] Wenn innerhalb derselben SG27 LIN im PIA+5 DE7140 (Erforderliches Produkt Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW) ein Produkt angegeben ist, das in der Codeliste der Konfigurationen...
273    /// EXTERNAL: Requires context from outside the message.
274    fn evaluate_38(&self, ctx: &EvaluationContext) -> ConditionResult {
275        ctx.external.evaluate("pia_product_triggers_schwellwert")
276    }
277
278    /// [41] Es sind nur die Messprodukte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.6.1 „Werte nach Typ 2 aus Backend“ enthalten sind.
279    /// EXTERNAL: Requires context from outside the message.
280    fn evaluate_41(&self, ctx: &EvaluationContext) -> ConditionResult {
281        ctx.external
282            .evaluate("messprodukt_in_kapitel_4_6_1_backend_list")
283    }
284
285    /// [42] Es sind nur die Messprodukte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.6.2 „Werte nach Typ 2 aus SMGW“ enthalten sind.
286    /// EXTERNAL: Requires context from outside the message.
287    fn evaluate_42(&self, ctx: &EvaluationContext) -> ConditionResult {
288        ctx.external
289            .evaluate("messprodukt_in_kapitel_4_6_2_smgw_list")
290    }
291
292    /// [43] Wenn innerhalb derselben SG27 LIN im PIA+5 DE7140 (Erforderliches Produkt Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW) ein Produkt angegeben ist, das in der Codeliste der Konfigurationen...
293    /// EXTERNAL: Requires context from outside the message.
294    fn evaluate_43(&self, ctx: &EvaluationContext) -> ConditionResult {
295        ctx.external.evaluate("pia_config_schwellwert_ausloeser")
296    }
297
298    /// [44] Wenn in SG27 LIN (Erforderliches Produkt der Messlokation) das PIA+5 DE7140 mit einem Produkt-Code vorhanden ist der in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer...
299    /// EXTERNAL: Requires context from outside the message.
300    fn evaluate_44(&self, ctx: &EvaluationContext) -> ConditionResult {
301        ctx.external
302            .evaluate("pia_messlokation_weitere_energieflussrichtung")
303    }
304
305    /// [45] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Steuerbaren Ressource angegeben ist.
306    /// EXTERNAL: Requires context from outside the message.
307    fn evaluate_45(&self, ctx: &EvaluationContext) -> ConditionResult {
308        ctx.external.evaluate("loc_172_is_steuerbare_ressource")
309    }
310
311    /// [47] Es sind nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Ebene" mit dem Wert "Mess...
312    /// EXTERNAL: Requires context from outside the message.
313    fn evaluate_47(&self, ctx: &EvaluationContext) -> ConditionResult {
314        ctx.external.evaluate("pia_product_code_messlokation_ebene")
315    }
316
317    /// [48] Es sind weiterhin nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Produkt gegenü...
318    /// EXTERNAL: Requires context from outside the message.
319    fn evaluate_48(&self, ctx: &EvaluationContext) -> ConditionResult {
320        ctx.external.evaluate("pia_product_code_nb_bestellbar")
321    }
322
323    /// [49] Es sind weiterhin nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Produkt gegenü...
324    /// EXTERNAL: Requires context from outside the message.
325    fn evaluate_49(&self, ctx: &EvaluationContext) -> ConditionResult {
326        ctx.external.evaluate("product_code_allowed_for_lf")
327    }
328
329    /// [50] Es sind nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Ebene" mit dem Wert "Netz...
330    /// EXTERNAL: Requires context from outside the message.
331    fn evaluate_50(&self, ctx: &EvaluationContext) -> ConditionResult {
332        ctx.external.evaluate("product_code_level_netzlokation")
333    }
334
335    /// [51] Es sind nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Ebene" mit dem Wert "Steu...
336    /// EXTERNAL: Requires context from outside the message.
337    fn evaluate_51(&self, ctx: &EvaluationContext) -> ConditionResult {
338        ctx.external
339            .evaluate("product_code_level_steuerbare_ressource")
340    }
341
342    /// [52] wenn im DE3155 in demselben COM der Code TE / AL vorhanden ist
343    fn evaluate_52(&self, ctx: &EvaluationContext) -> ConditionResult {
344        // wenn im DE3155 in demselben COM der Code TE / AL vorhanden ist
345        // COM segment: elements[0][0] = D3148 (address), elements[0][1] = D3155 (channel qualifier)
346        let com_segs = ctx.find_segments("COM");
347        if com_segs.is_empty() {
348            return ConditionResult::Unknown;
349        }
350        for seg in &com_segs {
351            if let Some(code) = seg.elements.first().and_then(|e| e.get(1)) {
352                if code == "TE" || code == "AL" {
353                    return ConditionResult::True;
354                }
355            }
356        }
357        ConditionResult::False
358    }
359
360    /// [53] wenn der LF der Marktlokation der genannten Lokation im gewünschten Umsetzungszeitraum nicht zugeordnet ist.
361    /// EXTERNAL: Requires context from outside the message.
362    fn evaluate_53(&self, ctx: &EvaluationContext) -> ConditionResult {
363        ctx.external
364            .evaluate("lf_not_assigned_to_lokation_in_umsetzungszeitraum")
365    }
366
367    /// [494] Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.
368    fn evaluate_494(&self, _ctx: &EvaluationContext) -> ConditionResult {
369        // TODO: Condition [494] requires manual implementation
370        // Reason: Condition states the date must be the document creation time or earlier. This requires knowing which specific DTM qualifier 'the date mentioned here' refers to in the field context, and comparing it against the document creation DTM. Without field-level context in the evaluator (only message-wide segment access), the correct source qualifier is ambiguous. Likely requires comparing a specific DTM against DTM+137 (document creation), but which qualifier is 'das hier genannte Datum' cannot be determined from the condition text alone.
371        ConditionResult::Unknown
372    }
373
374    /// [517] Hinweis: Verwendung der ID der Technischen Ressource
375    fn evaluate_517(&self, _ctx: &EvaluationContext) -> ConditionResult {
376        // Hinweis: Verwendung der ID der Technischen Ressource — informational note, always applies
377        ConditionResult::True
378    }
379
380    /// [518] Hinweis: zur Angabe von Kontaktdaten des Kunden des Lieferanten um die Änderung an der Technik zu vereinfachen.
381    fn evaluate_518(&self, _ctx: &EvaluationContext) -> ConditionResult {
382        // Hinweis: Angabe von Kontaktdaten des Kunden des Lieferanten — informational note, always applies
383        ConditionResult::True
384    }
385
386    /// [520] Hinweis: Angabe des Beginnzeitpunkts des gewünschten Umsetzungstermins aus Sicht des Anfragenden.
387    fn evaluate_520(&self, _ctx: &EvaluationContext) -> ConditionResult {
388        // Hinweis: Angabe des Beginnzeitpunkts des gewünschten Umsetzungstermins — informational note, always applies
389        ConditionResult::True
390    }
391
392    /// [521] Hinweis: Angabe des Endezeitpunkts des gewünschten Umsetzungstermins aus Sicht des Anfragenden.
393    fn evaluate_521(&self, _ctx: &EvaluationContext) -> ConditionResult {
394        // Hinweis: Angabe des Endezeitpunkts des gewünschten Umsetzungstermins — informational note, always applies
395        ConditionResult::True
396    }
397
398    /// [911] Format: Mögliche Werte: 1 bis n, je Nachricht oder Segmentgruppe bei 1 beginnend und fortlaufend aufsteigend
399    fn evaluate_911(&self, _ctx: &EvaluationContext) -> ConditionResult {
400        // TODO: Condition [911] requires manual implementation
401        // Reason: Sequential numbering validation (1..n, monotonically increasing per message or segment group) requires knowing the specific segment and element to inspect, plus iterating across all group instances to verify ordering. The condition description does not specify which segment/element carries the sequence number in this REQOTE SG28 context, and no relevant segment structure is provided. Cannot implement without that information.
402        ConditionResult::Unknown
403    }
404
405    /// [922] Format: TR-ID
406    fn evaluate_922(&self, _ctx: &EvaluationContext) -> ConditionResult {
407        // TODO: Condition [922] requires manual implementation
408        // Reason: Format: TR-ID validation requires knowing which specific segment and element in REQOTE SG28 carries the TR-ID value. The validate_tr_id helper is available, but the segment structure reference provided does not include the segment (e.g., RFF, IDE, or similar) that holds this identifier in SG28. Cannot safely implement without that context.
409        ConditionResult::Unknown
410    }
411
412    /// [967] Format: Zertifikatskörper gemäß X509.1, BSI TR-03109-4
413    fn evaluate_967(&self, _ctx: &EvaluationContext) -> ConditionResult {
414        // TODO: Condition [967] requires manual implementation
415        // Reason: Format: Zertifikatskörper gemäß X509.1, BSI TR-03109-4 requires X.509 certificate body parsing/validation. No helper for certificate format validation exists in the available API (validate_* functions cover numeric, DTM, email, phone, MaLo-ID, TR-ID, etc. — not binary certificate bodies). This would require a cryptographic library integration outside the current EvaluationContext API.
416        ConditionResult::Unknown
417    }
418
419    /// [2065] Diese SG28 ist so oft zu wiederholen, wie zu den unterschiedlichen Messprodukt-Position-Codes zu dem innerhalb derselben SG27 LIN im PIA+5 DE7140 (Erforderliches Produkt Konfigurationserlaubnis fü...
420    /// EXTERNAL: Requires context from outside the message.
421    fn evaluate_2065(&self, ctx: &EvaluationContext) -> ConditionResult {
422        ctx.external
423            .evaluate("sg28_repetition_schwellwert_konfigurationserlaubnis_smgw")
424    }
425
426    /// [2066] Diese SG28 ist so oft zu wiederholen, wie zu den unterschiedlichen Messprodukt-Position-Codes zu dem innerhalb derselben SG27 LIN im PIA+5 DE7140 (Erforderliches Produkt Konfigurationserlaubnis fü...
427    /// EXTERNAL: Requires context from outside the message.
428    fn evaluate_2066(&self, ctx: &EvaluationContext) -> ConditionResult {
429        ctx.external
430            .evaluate("sg28_repetition_schwellwert_werte_typ2_smgw")
431    }
432
433    /// [2067] Die SG12 RFF+Z37 Referenz auf ID der Technischen Ressource ist so oft zu wiederholen, bis alle IDs der Technischen Ressourcen angegeben sind, die der Steuerbaren Ressource in LOC+172 DE3225 (Meldep...
434    fn evaluate_2067(&self, _ctx: &EvaluationContext) -> ConditionResult {
435        // Hinweis: SG12 RFF+Z37 (Referenz auf ID der Technischen Ressource) ist so oft zu wiederholen,
436        // bis alle IDs der Technischen Ressourcen angegeben sind, die der Steuerbaren Ressource in
437        // LOC+172 DE3225 (Meldepunkt) zugeordnet werden sollen — informational repetition cardinality note.
438        ConditionResult::True
439    }
440
441    /// [2068] Diese SG27 ist so oft zu wiederholen, dass alle Produkte zur Lokation die innerhalb des  gewünschten Umsetzungstermins (Zeitintervall aus DTM+469 (Startdatum oder Zeitpunkt) und DTM+472 (Endedatum...
442    fn evaluate_2068(&self, _ctx: &EvaluationContext) -> ConditionResult {
443        // Hinweis: SG27 ist so oft zu wiederholen, dass alle gewünschten Produkte zur Lokation
444        // innerhalb des Umsetzungstermins (DTM+469 bis DTM+472) genannt sind, deren Kombination
445        // gemäß Codeliste Kapitel 7 möglich ist — informational repetition cardinality note.
446        ConditionResult::True
447    }
448
449    /// [1] Wenn DTM+203 (Ausführungsdatum) nicht vorhanden
450    fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
451        ctx.lacks_qualifier("DTM", 0, "203")
452    }
453
454    /// [2] Wenn DTM+469 (Beginn zum (nächstmöglichen Termin)) nicht vorhanden
455    fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
456        ctx.lacks_qualifier("DTM", 0, "469")
457    }
458
459    /// [10] MP-ID nur aus Sparte Strom
460    /// EXTERNAL: Requires context from outside the message.
461    fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
462        ctx.external.evaluate("mp_id_strom_only")
463    }
464
465    /// [15] Wenn DTM+76 (Datum zum geplanten Leistungsbeginn) nicht vorhanden
466    fn evaluate_15(&self, ctx: &EvaluationContext) -> ConditionResult {
467        ctx.lacks_qualifier("DTM", 0, "76")
468    }
469
470    /// [16] Wenn SG1 RFF+Z41 (Referenznummer des Vorgangs der Anmeldung nach WiM) nicht vorhanden
471    fn evaluate_16(&self, ctx: &EvaluationContext) -> ConditionResult {
472        ctx.lacks_qualifier("RFF", 0, "Z41")
473    }
474
475    /// [17] Wenn SG1 RFF+Z41 (Referenznummer des Vorgangs der Anmeldung nach WiM) vorhanden
476    fn evaluate_17(&self, ctx: &EvaluationContext) -> ConditionResult {
477        ctx.has_qualifier("RFF", 0, "Z41")
478    }
479
480    /// [18] Wenn IMD++Z55 (Änderung Konfiguration) vorhanden
481    fn evaluate_18(&self, ctx: &EvaluationContext) -> ConditionResult {
482        ctx.has_qualifier("IMD", 1, "Z55")
483    }
484
485    /// [19] Wenn SG27 LIN++Z64 (Erforderliches Produkt Schaltzeitdefinitionen) vorhanden
486    fn evaluate_19(&self, ctx: &EvaluationContext) -> ConditionResult {
487        ctx.has_qualifier("LIN", 1, "Z64")
488    }
489
490    /// [20] Wenn SG27 LIN++Z65 (Erforderliches Produkt Leistungskurvendefinitionen) vorhanden
491    fn evaluate_20(&self, ctx: &EvaluationContext) -> ConditionResult {
492        ctx.has_qualifier("LIN", 1, "Z65")
493    }
494
495    /// [21] Wenn SG27 LIN++Z66 (Erforderliches Produkt Ad-hoc-Steuerkanal) vorhanden
496    fn evaluate_21(&self, ctx: &EvaluationContext) -> ConditionResult {
497        ctx.has_qualifier("LIN", 1, "Z66")
498    }
499
500    /// [22] Wenn SG27 LIN++Z67 (Erforderliches Messprodukt für Werte nach Typ 2 aus Backend) vorhanden
501    fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
502        ctx.has_qualifier("LIN", 1, "Z67")
503    }
504
505    /// [23] Wenn SG27 LIN++Z68 (Erforderliches Produkt Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW) vorhanden
506    fn evaluate_23(&self, ctx: &EvaluationContext) -> ConditionResult {
507        ctx.has_qualifier("LIN", 1, "Z68")
508    }
509
510    /// [24] Wenn Produkt bestellt werden soll
511    /// EXTERNAL: Requires context from outside the message.
512    // REVIEW: Whether a product should be ordered is a business-intent condition. In a REQOTE context this could theoretically be signalled by presence of PIA+5, but the AHB phrasing 'soll bestellt werden' indicates a business decision or workflow state that cannot be reliably inferred from message structure alone. (medium confidence)
513    fn evaluate_24(&self, ctx: &EvaluationContext) -> ConditionResult {
514        ctx.external.evaluate("product_to_be_ordered")
515    }
516
517    /// [25] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Marktlokation angegeben ist.
518    fn evaluate_25(&self, ctx: &EvaluationContext) -> ConditionResult {
519        // Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Marktlokation angegeben ist.
520        // LOC elements[0][0] == "172" (qualifier), elements[1][0] == DE3225 (Identifikator)
521        // Marktlokation ID: 11 digits with Luhn check digit
522        let segs = ctx.find_segments_with_qualifier("LOC", 0, "172");
523        match segs
524            .first()
525            .and_then(|s| s.elements.get(1))
526            .and_then(|e| e.first())
527        {
528            Some(val) if !val.is_empty() => validate_malo_id(val),
529            _ => ConditionResult::Unknown,
530        }
531    }
532
533    /// [26] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Messlokation angegeben ist.
534    fn evaluate_26(&self, ctx: &EvaluationContext) -> ConditionResult {
535        // Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Messlokation angegeben ist.
536        // LOC elements[0][0] == "172" (qualifier), elements[1][0] == DE3225 (Identifikator)
537        // Messlokation ID: 33 alphanumeric characters (Zählpunkt format)
538        let segs = ctx.find_segments_with_qualifier("LOC", 0, "172");
539        match segs
540            .first()
541            .and_then(|s| s.elements.get(1))
542            .and_then(|e| e.first())
543        {
544            Some(val) if !val.is_empty() => validate_zahlpunkt(val),
545            _ => ConditionResult::Unknown,
546        }
547    }
548
549    /// [27] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Netzlokation angegeben ist.
550    // REVIEW: Checks LOC+172 DE3225 value as a Netzlokation ID by exclusion: it is present but does not match Marktlokation format (11-digit Luhn) nor Messlokation format (33 alphanumeric). Medium confidence because there is no dedicated Netzlokation validator — the logic relies on the three location types being mutually exclusive and exhaustive for this qualifier. (medium confidence)
551    fn evaluate_27(&self, ctx: &EvaluationContext) -> ConditionResult {
552        // Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Netzlokation angegeben ist.
553        // LOC elements[0][0] == "172" (qualifier), elements[1][0] == DE3225 (Identifikator)
554        // Netzlokation ID: neither MaLo (11 digits Luhn) nor MeLo (33 alphanumeric)
555        let segs = ctx.find_segments_with_qualifier("LOC", 0, "172");
556        match segs
557            .first()
558            .and_then(|s| s.elements.get(1))
559            .and_then(|e| e.first())
560        {
561            Some(val) if !val.is_empty() => {
562                let is_malo = matches!(validate_malo_id(val), ConditionResult::True);
563                let is_melo = matches!(validate_zahlpunkt(val), ConditionResult::True);
564                ConditionResult::from(!is_malo && !is_melo)
565            }
566            _ => ConditionResult::Unknown,
567        }
568    }
569
570    /// [28] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Steuerbaren Ressource angegeben ist.
571    /// EXTERNAL: Requires context from outside the message.
572    fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
573        ctx.external.evaluate("loc_172_is_steuerbare_ressource")
574    }
575
576    /// [29] Es sind nur die Konfigurations-Produkte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.1 „Konfigurationsprodukte Schaltzeitdefinition“ enthalten sind.
577    /// EXTERNAL: Requires context from outside the message.
578    fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
579        ctx.external
580            .evaluate("product_in_konfiguration_schaltzeitdefinition")
581    }
582
583    /// [30] Es sind nur die Konfigurations-Produkte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.2 „Konfigurationsprodukte Leistungskurvendefinition“ enthalten sind.
584    /// EXTERNAL: Requires context from outside the message.
585    fn evaluate_30(&self, ctx: &EvaluationContext) -> ConditionResult {
586        ctx.external
587            .evaluate("product_in_konfiguration_leistungskurvendefinition")
588    }
589
590    /// [31] Es sind nur die Konfigurations-Produkte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.3 „Konfigurationsprodukte Ad-Hoc-Steuerkanal“ enthalten sind.
591    /// EXTERNAL: Requires context from outside the message.
592    fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
593        ctx.external
594            .evaluate("product_in_konfiguration_adhoc_steuerkanal")
595    }
596
597    /// [32] Es sind nur die Messprodukte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.5 „Messprodukte für Werte nach Typ 2 aus Backend für LF und NB“ enthalten sind.
598    /// EXTERNAL: Requires context from outside the message.
599    fn evaluate_32(&self, ctx: &EvaluationContext) -> ConditionResult {
600        ctx.external.evaluate("product_in_messprodukte_typ2_lf_nb")
601    }
602
603    /// [35] Wenn MP-ID in SG11 NAD+MS mit Rolle LF vorhanden
604    /// EXTERNAL: Requires context from outside the message.
605    // REVIEW: NAD+MS identifies the sender by MP-ID (elements[0]=MS), but the market role 'LF' (Lieferant) cannot be determined from the NAD segment alone — it requires an external participant role registry lookup. The segment only carries the ID, not the role. (medium confidence)
606    fn evaluate_35(&self, ctx: &EvaluationContext) -> ConditionResult {
607        ctx.external.evaluate("sender_is_lf")
608    }
609
610    /// [36] Wenn MP-ID in SG11 NAD+MS mit Rolle NB vorhanden
611    /// EXTERNAL: Requires context from outside the message.
612    // REVIEW: Same pattern as condition 35: NAD+MS carries the sender MP-ID but the market role 'NB' (Netzbetreiber) cannot be inferred from the EDIFACT segment alone — requires external role registry. (medium confidence)
613    fn evaluate_36(&self, ctx: &EvaluationContext) -> ConditionResult {
614        ctx.external.evaluate("sender_is_nb")
615    }
616
617    /// [39] wenn im DE3155 in demselben COM der Code EM vorhanden ist
618    fn evaluate_39(&self, ctx: &EvaluationContext) -> ConditionResult {
619        // COM segment: C076 composite — elements[0][0]=DE3148 (address), elements[0][1]=DE3155 (qualifier)
620        let coms = ctx.find_segments("COM");
621        if coms.is_empty() {
622            return ConditionResult::False;
623        }
624        ConditionResult::from(coms.iter().any(|s| {
625            s.elements
626                .first()
627                .and_then(|e| e.get(1))
628                .is_some_and(|v| v == "EM")
629        }))
630    }
631
632    /// [40] wenn im DE3155 in demselben COM der Code TE / FX / AJ / AL vorhanden ist
633    fn evaluate_40(&self, ctx: &EvaluationContext) -> ConditionResult {
634        // COM segment: C076 composite — elements[0][0]=DE3148 (address), elements[0][1]=DE3155 (qualifier)
635        // TE=Telephone, FX=Fax, AJ=Unknown, AL=Unknown (telephony-related codes)
636        let coms = ctx.find_segments("COM");
637        if coms.is_empty() {
638            return ConditionResult::False;
639        }
640        ConditionResult::from(coms.iter().any(|s| {
641            s.elements
642                .first()
643                .and_then(|e| e.get(1))
644                .is_some_and(|v| matches!(v.as_str(), "TE" | "FX" | "AJ" | "AL"))
645        }))
646    }
647
648    /// [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...
649    fn evaluate_490(&self, ctx: &EvaluationContext) -> ConditionResult {
650        let dtm_segs = ctx.find_segments("DTM");
651        match dtm_segs
652            .first()
653            .and_then(|s| s.elements.first())
654            .and_then(|e| e.get(1))
655        {
656            Some(val) => is_mesz_utc(val),
657            None => ConditionResult::False, // segment absent → condition not applicable
658        }
659    }
660
661    /// [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)...
662    fn evaluate_491(&self, ctx: &EvaluationContext) -> ConditionResult {
663        let dtm_segs = ctx.find_segments("DTM");
664        match dtm_segs
665            .first()
666            .and_then(|s| s.elements.first())
667            .and_then(|e| e.get(1))
668        {
669            Some(val) => is_mez_utc(val),
670            None => ConditionResult::False, // segment absent → condition not applicable
671        }
672    }
673
674    /// [492] wenn MP-ID in NAD+MR aus Sparte Strom
675    /// EXTERNAL: Requires context from outside the message.
676    // REVIEW: Checks whether the MP-ID in NAD+MR belongs to the electricity sector (Sparte Strom). The sector of a market participant cannot be derived from the EDIFACT message structure — it requires external market participant registry lookup. Delegated to external provider. (medium confidence)
677    fn evaluate_492(&self, ctx: &EvaluationContext) -> ConditionResult {
678        ctx.external.evaluate("recipient_is_electricity_sector")
679    }
680
681    /// [493] wenn MP-ID in NAD+MR aus Sparte Gas
682    /// EXTERNAL: Requires context from outside the message.
683    // REVIEW: Checks whether the MP-ID in NAD+MR belongs to the gas sector (Sparte Gas). Same reasoning as condition 492 — sector membership requires external registry lookup. (medium confidence)
684    fn evaluate_493(&self, ctx: &EvaluationContext) -> ConditionResult {
685        ctx.external.evaluate("recipient_is_gas_sector")
686    }
687
688    /// [500] Hinweis: Angabe eines technischen Ansprechpartners für die Geräteübernahme
689    fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
690        // Hinweis: Angabe eines technischen Ansprechpartners für die Geräteübernahme
691        // Informational note — always applies
692        ConditionResult::True
693    }
694
695    /// [501] Hinweis: Angabe eines Ansprechpartners für die Rechnungsabwicklung
696    fn evaluate_501(&self, _ctx: &EvaluationContext) -> ConditionResult {
697        // Hinweis: Angabe eines Ansprechpartners für die Rechnungsabwicklung
698        // Informational note — always applies
699        ConditionResult::True
700    }
701
702    /// [502] Hinweis: Verwendung der ID der Marktlokation
703    fn evaluate_502(&self, _ctx: &EvaluationContext) -> ConditionResult {
704        // Hinweis: Verwendung der ID der Marktlokation
705        // Informational note — always applies
706        ConditionResult::True
707    }
708
709    /// [503] Hinweis: Verwendung der ID der Messlokation
710    fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
711        // Hinweis: Verwendung der ID der Messlokation
712        // Informational note — always applies
713        ConditionResult::True
714    }
715
716    /// [504] Hinweis: Verwendung der ID der Tranche
717    fn evaluate_504(&self, _ctx: &EvaluationContext) -> ConditionResult {
718        // Hinweis: Verwendung der ID der Tranche — informational note, always applies
719        ConditionResult::True
720    }
721
722    /// [507] Hinweis: Vorgangsnummer aus SG4 IDE+24 DE7402 der UTILMD mit BGM+E01 mit der die Anmeldung des MSB-Wechsels erfolgt ist.
723    fn evaluate_507(&self, _ctx: &EvaluationContext) -> ConditionResult {
724        // Hinweis: Vorgangsnummer aus SG4 IDE+24 DE7402 der UTILMD — informational note, always applies
725        ConditionResult::True
726    }
727
728    /// [508] Hinweis: Wert aus BGM+Z73 DE1004 der IFTSTA mit der die Antwort auf die Bestellung der Konfiguration übermittelt wurde
729    fn evaluate_508(&self, _ctx: &EvaluationContext) -> ConditionResult {
730        // Hinweis: Wert aus BGM+Z73 DE1004 der IFTSTA — informational note, always applies
731        ConditionResult::True
732    }
733
734    /// [509] Hinweis: Vorgangsnummer aus CNI DE1490 der IFTSTA mit BGM+Z73 mit der die Antwort auf die Bestellung der Konfiguration übermittelt wurde
735    fn evaluate_509(&self, _ctx: &EvaluationContext) -> ConditionResult {
736        // Hinweis: Vorgangsnummer aus CNI DE1490 der IFTSTA — informational note, always applies
737        ConditionResult::True
738    }
739
740    /// [510] Hinweis: Verwendung der ID der Netzlokation
741    fn evaluate_510(&self, _ctx: &EvaluationContext) -> ConditionResult {
742        // Hinweis: Verwendung der ID der Netzlokation — informational note, always applies
743        ConditionResult::True
744    }
745
746    /// [511] Hinweis: Verwendung der ID der Steuerbaren Ressource
747    fn evaluate_511(&self, _ctx: &EvaluationContext) -> ConditionResult {
748        ConditionResult::True
749    }
750
751    /// [512] Hinweis: Für den Empfang der Werte nach Typ 2 aus dem SMGW.
752    fn evaluate_512(&self, _ctx: &EvaluationContext) -> ConditionResult {
753        ConditionResult::True
754    }
755
756    /// [514] Hinweis: Es darf nur eine Information im DE3148 übermittelt werden
757    fn evaluate_514(&self, _ctx: &EvaluationContext) -> ConditionResult {
758        ConditionResult::True
759    }
760
761    /// [515] Hinweis: Es ist eine URI IPv4 für die Bereitstellung der Werte anzugeben.
762    fn evaluate_515(&self, _ctx: &EvaluationContext) -> ConditionResult {
763        ConditionResult::True
764    }
765
766    /// [516] Hinweis: Es ist eine URI IPv6 für die Bereitstellung der Werte anzugeben.
767    fn evaluate_516(&self, _ctx: &EvaluationContext) -> ConditionResult {
768        ConditionResult::True
769    }
770
771    /// [903] Format: Möglicher Wert: 1
772    fn evaluate_903(&self, _ctx: &EvaluationContext) -> ConditionResult {
773        ConditionResult::True
774    }
775
776    /// [906] Format: max. 3 Nachkommastellen
777    fn evaluate_906(&self, _ctx: &EvaluationContext) -> ConditionResult {
778        ConditionResult::True
779    }
780
781    /// [931] Format: ZZZ = +00
782    fn evaluate_931(&self, _ctx: &EvaluationContext) -> ConditionResult {
783        ConditionResult::True
784    }
785
786    /// [932] Format: HHMM = 2200
787    fn evaluate_932(&self, _ctx: &EvaluationContext) -> ConditionResult {
788        ConditionResult::True
789    }
790
791    /// [933] Format: HHMM = 2300
792    fn evaluate_933(&self, _ctx: &EvaluationContext) -> ConditionResult {
793        ConditionResult::True
794    }
795
796    /// [934] Format: HHMM = 0400
797    fn evaluate_934(&self, _ctx: &EvaluationContext) -> ConditionResult {
798        ConditionResult::True
799    }
800
801    /// [935] Format: HHMM = 0500
802    fn evaluate_935(&self, _ctx: &EvaluationContext) -> ConditionResult {
803        ConditionResult::True
804    }
805
806    /// [939] Format: Die Zeichenkette muss die Zeichen @ und . enthalten
807    fn evaluate_939(&self, _ctx: &EvaluationContext) -> ConditionResult {
808        ConditionResult::True
809    }
810
811    /// [940] Format: Die Zeichenkette muss mit dem Zeichen + beginnen und danach dürfen nur noch Ziffern folgen
812    fn evaluate_940(&self, _ctx: &EvaluationContext) -> ConditionResult {
813        ConditionResult::True
814    }
815
816    /// [950] Format: Marktlokations-ID
817    fn evaluate_950(&self, _ctx: &EvaluationContext) -> ConditionResult {
818        ConditionResult::True
819    }
820
821    /// [951] Format: Zählpunktbezeichnung
822    fn evaluate_951(&self, ctx: &EvaluationContext) -> ConditionResult {
823        let segs = ctx.find_segments_with_qualifier("LOC", 0, "Z17");
824        match segs
825            .first()
826            .and_then(|s| s.elements.get(1))
827            .and_then(|e| e.first())
828        {
829            Some(val) => validate_zahlpunkt(val),
830            None => ConditionResult::False, // segment absent → condition not applicable
831        }
832    }
833
834    /// [960] Format: Netzlokations-ID
835    // REVIEW: Netzlokations-ID uses the same 11-digit Luhn check digit format as Marktlokations-ID. LOC+Z18 is the standard qualifier for Netzlokation. (medium confidence)
836    fn evaluate_960(&self, ctx: &EvaluationContext) -> ConditionResult {
837        let segs = ctx.find_segments_with_qualifier("LOC", 0, "Z18");
838        match segs
839            .first()
840            .and_then(|s| s.elements.get(1))
841            .and_then(|e| e.first())
842        {
843            Some(val) => validate_malo_id(val),
844            None => ConditionResult::False, // segment absent → condition not applicable
845        }
846    }
847
848    /// [961] Format: SR-ID
849    // REVIEW: SR-ID (SteuerbareRessource-ID) uses the same 11-digit Luhn check digit format as MaLo-ID. LOC+Z19 is the standard qualifier for SteuerbareRessource. (medium confidence)
850    fn evaluate_961(&self, ctx: &EvaluationContext) -> ConditionResult {
851        let segs = ctx.find_segments_with_qualifier("LOC", 0, "Z19");
852        match segs
853            .first()
854            .and_then(|s| s.elements.get(1))
855            .and_then(|e| e.first())
856        {
857            Some(val) => validate_malo_id(val),
858            None => ConditionResult::False, // segment absent → condition not applicable
859        }
860    }
861
862    /// [962] Format: max. 6 Vorkommastellen
863    fn evaluate_962(&self, ctx: &EvaluationContext) -> ConditionResult {
864        let segs = ctx.find_segments("QTY");
865        match segs
866            .first()
867            .and_then(|s| s.elements.first())
868            .and_then(|e| e.get(1))
869        {
870            Some(val) => validate_max_integer_digits(val, 6),
871            None => ConditionResult::False, // segment absent → condition not applicable
872        }
873    }
874
875    /// [2005] Pro Nachricht ist die SG27 genau einmal anzugeben
876    // REVIEW: SG27 must appear exactly once per message. LIN is the entry segment for SG27. Counting all LIN segments gives the SG27 instance count. Returns True when exactly one LIN exists. (medium confidence)
877    fn evaluate_2005(&self, ctx: &EvaluationContext) -> ConditionResult {
878        let lin_count = ctx.find_segments("LIN").len();
879        ConditionResult::from(lin_count == 1)
880    }
881
882    /// [2060] Pro Nachricht ist die SG27 LIN+Z64 (Erforderliches Produkt Schaltzeitdefinitionen) maximal einmal anzugeben
883    // REVIEW: LIN with DE1229=Z64 (Erforderliches Produkt Schaltzeitdefinitionen) must appear at most once. Per segment structure reference, DE1229 (Handlung, Code) is at elements[1][0]. Returns True when 0 or 1 such LIN segments exist. (medium confidence)
884    fn evaluate_2060(&self, ctx: &EvaluationContext) -> ConditionResult {
885        let lins = ctx.find_segments("LIN");
886        let count = lins
887            .iter()
888            .filter(|s| {
889                s.elements
890                    .get(1)
891                    .and_then(|e| e.first())
892                    .is_some_and(|v| v == "Z64")
893            })
894            .count();
895        ConditionResult::from(count <= 1)
896    }
897
898    /// [2061] Pro Nachricht ist die SG27 LIN++Z65 (Erforderliches Produkt Leistungskurvendefinitionen) maximal einmal anzugeben
899    // REVIEW: LIN with DE1229=Z65 (Erforderliches Produkt Leistungskurvendefinitionen) must appear at most once. Per segment structure reference, DE1229 is at elements[1][0]. Returns True when 0 or 1 such LIN segments exist. (medium confidence)
900    fn evaluate_2061(&self, ctx: &EvaluationContext) -> ConditionResult {
901        let lins = ctx.find_segments("LIN");
902        let count = lins
903            .iter()
904            .filter(|s| {
905                s.elements
906                    .get(1)
907                    .and_then(|e| e.first())
908                    .is_some_and(|v| v == "Z65")
909            })
910            .count();
911        ConditionResult::from(count <= 1)
912    }
913
914    /// [2062] Pro Nachricht ist die SG27 LIN++Z66 (Erforderliches Produkt Ad-hoc-Steuerkanal) maximal einmal anzugeben
915    // REVIEW: LIN with DE1229=Z66 (Erforderliches Produkt Ad-hoc-Steuerkanal) must appear at most once. Per segment structure reference, DE1229 is at elements[1][0]. Returns True when 0 or 1 such LIN segments exist. (medium confidence)
916    fn evaluate_2062(&self, ctx: &EvaluationContext) -> ConditionResult {
917        let lins = ctx.find_segments("LIN");
918        let count = lins
919            .iter()
920            .filter(|s| {
921                s.elements
922                    .get(1)
923                    .and_then(|e| e.first())
924                    .is_some_and(|v| v == "Z66")
925            })
926            .count();
927        ConditionResult::from(count <= 1)
928    }
929
930    /// [2063] Pro Nachricht ist die SG27 LIN++Z67 (Erforderliches Messprodukt für Werte nach Typ 2 aus Backend) maximal einmal anzugeben
931    // REVIEW: LIN with DE1229=Z67 (Erforderliches Messprodukt für Werte nach Typ 2 aus Backend) must appear at most once. Per segment structure reference, DE1229 is at elements[1][0]. Returns True when 0 or 1 such LIN segments exist. (medium confidence)
932    fn evaluate_2063(&self, ctx: &EvaluationContext) -> ConditionResult {
933        let lins = ctx.find_segments("LIN");
934        let count = lins
935            .iter()
936            .filter(|s| {
937                s.elements
938                    .get(1)
939                    .and_then(|e| e.first())
940                    .is_some_and(|v| v == "Z67")
941            })
942            .count();
943        ConditionResult::from(count <= 1)
944    }
945
946    /// [2064] Pro Nachricht ist die SG27 LIN++Z68 (Erforderliches Produkt Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW) maximal einmal anzugeben
947    // REVIEW: LIN with DE1229=Z68 (Erforderliches Produkt Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW) must appear at most once. Per segment structure reference, DE1229 is at elements[1][0]. Returns True when 0 or 1 such LIN segments exist. (medium confidence)
948    fn evaluate_2064(&self, ctx: &EvaluationContext) -> ConditionResult {
949        let lins = ctx.find_segments("LIN");
950        let count = lins
951            .iter()
952            .filter(|s| {
953                s.elements
954                    .get(1)
955                    .and_then(|e| e.first())
956                    .is_some_and(|v| v == "Z68")
957            })
958            .count();
959        ConditionResult::from(count <= 1)
960    }
961}