Skip to main content

automapper_validation/generated/fv2510/
utilmd_strom_conditions_fv2510.rs

1// <auto-generated>
2// Generated by automapper-generator generate-conditions
3// AHB: xml-migs-and-ahbs/FV2510/UTILMD_AHB_Strom_2_1_außerordentliche_20251211.xml
4// Generated: 2026-03-12T11:07:23Z
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 UTILMD_Strom FV2510.
12pub struct UtilmdStromConditionEvaluatorFV2510 {
13    // External condition IDs that require runtime context.
14    external_conditions: std::collections::HashSet<u32>,
15}
16
17impl Default for UtilmdStromConditionEvaluatorFV2510 {
18    fn default() -> Self {
19        let mut external_conditions = std::collections::HashSet::new();
20        external_conditions.insert(1);
21        external_conditions.insert(3);
22        external_conditions.insert(4);
23        external_conditions.insert(5);
24        external_conditions.insert(6);
25        external_conditions.insert(8);
26        external_conditions.insert(9);
27        external_conditions.insert(14);
28        external_conditions.insert(31);
29        external_conditions.insert(33);
30        external_conditions.insert(36);
31        external_conditions.insert(38);
32        external_conditions.insert(39);
33        external_conditions.insert(40);
34        external_conditions.insert(75);
35        external_conditions.insert(98);
36        external_conditions.insert(99);
37        external_conditions.insert(151);
38        external_conditions.insert(233);
39        external_conditions.insert(241);
40        external_conditions.insert(251);
41        external_conditions.insert(292);
42        external_conditions.insert(314);
43        external_conditions.insert(315);
44        external_conditions.insert(323);
45        external_conditions.insert(326);
46        external_conditions.insert(328);
47        external_conditions.insert(412);
48        external_conditions.insert(425);
49        external_conditions.insert(426);
50        external_conditions.insert(427);
51        external_conditions.insert(428);
52        external_conditions.insert(429);
53        external_conditions.insert(433);
54        external_conditions.insert(435);
55        external_conditions.insert(453);
56        external_conditions.insert(459);
57        external_conditions.insert(460);
58        external_conditions.insert(706);
59        external_conditions.insert(717);
60        Self {
61            external_conditions,
62        }
63    }
64}
65
66impl ConditionEvaluator for UtilmdStromConditionEvaluatorFV2510 {
67    fn message_type(&self) -> &str {
68        "UTILMD_Strom"
69    }
70
71    fn format_version(&self) -> &str {
72        "FV2510"
73    }
74
75    fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
76        match condition {
77            1 => self.evaluate_1(ctx),
78            2 => self.evaluate_2(ctx),
79            3 => self.evaluate_3(ctx),
80            4 => self.evaluate_4(ctx),
81            5 => self.evaluate_5(ctx),
82            6 => self.evaluate_6(ctx),
83            7 => self.evaluate_7(ctx),
84            8 => self.evaluate_8(ctx),
85            9 => self.evaluate_9(ctx),
86            10 => self.evaluate_10(ctx),
87            11 => self.evaluate_11(ctx),
88            12 => self.evaluate_12(ctx),
89            13 => self.evaluate_13(ctx),
90            14 => self.evaluate_14(ctx),
91            15 => self.evaluate_15(ctx),
92            16 => self.evaluate_16(ctx),
93            17 => self.evaluate_17(ctx),
94            18 => self.evaluate_18(ctx),
95            19 => self.evaluate_19(ctx),
96            20 => self.evaluate_20(ctx),
97            21 => self.evaluate_21(ctx),
98            22 => self.evaluate_22(ctx),
99            23 => self.evaluate_23(ctx),
100            24 => self.evaluate_24(ctx),
101            25 => self.evaluate_25(ctx),
102            27 => self.evaluate_27(ctx),
103            28 => self.evaluate_28(ctx),
104            29 => self.evaluate_29(ctx),
105            30 => self.evaluate_30(ctx),
106            31 => self.evaluate_31(ctx),
107            32 => self.evaluate_32(ctx),
108            33 => self.evaluate_33(ctx),
109            34 => self.evaluate_34(ctx),
110            35 => self.evaluate_35(ctx),
111            36 => self.evaluate_36(ctx),
112            37 => self.evaluate_37(ctx),
113            38 => self.evaluate_38(ctx),
114            39 => self.evaluate_39(ctx),
115            40 => self.evaluate_40(ctx),
116            41 => self.evaluate_41(ctx),
117            42 => self.evaluate_42(ctx),
118            43 => self.evaluate_43(ctx),
119            44 => self.evaluate_44(ctx),
120            45 => self.evaluate_45(ctx),
121            46 => self.evaluate_46(ctx),
122            47 => self.evaluate_47(ctx),
123            48 => self.evaluate_48(ctx),
124            49 => self.evaluate_49(ctx),
125            50 => self.evaluate_50(ctx),
126            51 => self.evaluate_51(ctx),
127            52 => self.evaluate_52(ctx),
128            53 => self.evaluate_53(ctx),
129            54 => self.evaluate_54(ctx),
130            55 => self.evaluate_55(ctx),
131            56 => self.evaluate_56(ctx),
132            57 => self.evaluate_57(ctx),
133            58 => self.evaluate_58(ctx),
134            60 => self.evaluate_60(ctx),
135            61 => self.evaluate_61(ctx),
136            62 => self.evaluate_62(ctx),
137            63 => self.evaluate_63(ctx),
138            64 => self.evaluate_64(ctx),
139            65 => self.evaluate_65(ctx),
140            66 => self.evaluate_66(ctx),
141            67 => self.evaluate_67(ctx),
142            68 => self.evaluate_68(ctx),
143            69 => self.evaluate_69(ctx),
144            70 => self.evaluate_70(ctx),
145            71 => self.evaluate_71(ctx),
146            72 => self.evaluate_72(ctx),
147            73 => self.evaluate_73(ctx),
148            74 => self.evaluate_74(ctx),
149            75 => self.evaluate_75(ctx),
150            76 => self.evaluate_76(ctx),
151            77 => self.evaluate_77(ctx),
152            78 => self.evaluate_78(ctx),
153            79 => self.evaluate_79(ctx),
154            83 => self.evaluate_83(ctx),
155            84 => self.evaluate_84(ctx),
156            85 => self.evaluate_85(ctx),
157            86 => self.evaluate_86(ctx),
158            87 => self.evaluate_87(ctx),
159            88 => self.evaluate_88(ctx),
160            89 => self.evaluate_89(ctx),
161            90 => self.evaluate_90(ctx),
162            91 => self.evaluate_91(ctx),
163            92 => self.evaluate_92(ctx),
164            93 => self.evaluate_93(ctx),
165            94 => self.evaluate_94(ctx),
166            95 => self.evaluate_95(ctx),
167            96 => self.evaluate_96(ctx),
168            97 => self.evaluate_97(ctx),
169            98 => self.evaluate_98(ctx),
170            99 => self.evaluate_99(ctx),
171            100 => self.evaluate_100(ctx),
172            101 => self.evaluate_101(ctx),
173            102 => self.evaluate_102(ctx),
174            103 => self.evaluate_103(ctx),
175            104 => self.evaluate_104(ctx),
176            105 => self.evaluate_105(ctx),
177            106 => self.evaluate_106(ctx),
178            107 => self.evaluate_107(ctx),
179            108 => self.evaluate_108(ctx),
180            110 => self.evaluate_110(ctx),
181            111 => self.evaluate_111(ctx),
182            112 => self.evaluate_112(ctx),
183            113 => self.evaluate_113(ctx),
184            114 => self.evaluate_114(ctx),
185            115 => self.evaluate_115(ctx),
186            116 => self.evaluate_116(ctx),
187            117 => self.evaluate_117(ctx),
188            118 => self.evaluate_118(ctx),
189            119 => self.evaluate_119(ctx),
190            120 => self.evaluate_120(ctx),
191            121 => self.evaluate_121(ctx),
192            122 => self.evaluate_122(ctx),
193            123 => self.evaluate_123(ctx),
194            124 => self.evaluate_124(ctx),
195            125 => self.evaluate_125(ctx),
196            126 => self.evaluate_126(ctx),
197            127 => self.evaluate_127(ctx),
198            128 => self.evaluate_128(ctx),
199            129 => self.evaluate_129(ctx),
200            130 => self.evaluate_130(ctx),
201            131 => self.evaluate_131(ctx),
202            132 => self.evaluate_132(ctx),
203            133 => self.evaluate_133(ctx),
204            134 => self.evaluate_134(ctx),
205            135 => self.evaluate_135(ctx),
206            136 => self.evaluate_136(ctx),
207            137 => self.evaluate_137(ctx),
208            138 => self.evaluate_138(ctx),
209            139 => self.evaluate_139(ctx),
210            140 => self.evaluate_140(ctx),
211            141 => self.evaluate_141(ctx),
212            142 => self.evaluate_142(ctx),
213            143 => self.evaluate_143(ctx),
214            144 => self.evaluate_144(ctx),
215            145 => self.evaluate_145(ctx),
216            146 => self.evaluate_146(ctx),
217            147 => self.evaluate_147(ctx),
218            148 => self.evaluate_148(ctx),
219            149 => self.evaluate_149(ctx),
220            150 => self.evaluate_150(ctx),
221            151 => self.evaluate_151(ctx),
222            152 => self.evaluate_152(ctx),
223            153 => self.evaluate_153(ctx),
224            156 => self.evaluate_156(ctx),
225            157 => self.evaluate_157(ctx),
226            161 => self.evaluate_161(ctx),
227            162 => self.evaluate_162(ctx),
228            163 => self.evaluate_163(ctx),
229            164 => self.evaluate_164(ctx),
230            165 => self.evaluate_165(ctx),
231            166 => self.evaluate_166(ctx),
232            167 => self.evaluate_167(ctx),
233            168 => self.evaluate_168(ctx),
234            169 => self.evaluate_169(ctx),
235            170 => self.evaluate_170(ctx),
236            172 => self.evaluate_172(ctx),
237            173 => self.evaluate_173(ctx),
238            174 => self.evaluate_174(ctx),
239            175 => self.evaluate_175(ctx),
240            176 => self.evaluate_176(ctx),
241            177 => self.evaluate_177(ctx),
242            178 => self.evaluate_178(ctx),
243            179 => self.evaluate_179(ctx),
244            180 => self.evaluate_180(ctx),
245            184 => self.evaluate_184(ctx),
246            190 => self.evaluate_190(ctx),
247            191 => self.evaluate_191(ctx),
248            192 => self.evaluate_192(ctx),
249            193 => self.evaluate_193(ctx),
250            194 => self.evaluate_194(ctx),
251            195 => self.evaluate_195(ctx),
252            196 => self.evaluate_196(ctx),
253            197 => self.evaluate_197(ctx),
254            198 => self.evaluate_198(ctx),
255            199 => self.evaluate_199(ctx),
256            201 => self.evaluate_201(ctx),
257            202 => self.evaluate_202(ctx),
258            203 => self.evaluate_203(ctx),
259            204 => self.evaluate_204(ctx),
260            205 => self.evaluate_205(ctx),
261            206 => self.evaluate_206(ctx),
262            209 => self.evaluate_209(ctx),
263            210 => self.evaluate_210(ctx),
264            212 => self.evaluate_212(ctx),
265            213 => self.evaluate_213(ctx),
266            215 => self.evaluate_215(ctx),
267            216 => self.evaluate_216(ctx),
268            217 => self.evaluate_217(ctx),
269            219 => self.evaluate_219(ctx),
270            220 => self.evaluate_220(ctx),
271            221 => self.evaluate_221(ctx),
272            223 => self.evaluate_223(ctx),
273            224 => self.evaluate_224(ctx),
274            227 => self.evaluate_227(ctx),
275            229 => self.evaluate_229(ctx),
276            232 => self.evaluate_232(ctx),
277            233 => self.evaluate_233(ctx),
278            234 => self.evaluate_234(ctx),
279            237 => self.evaluate_237(ctx),
280            238 => self.evaluate_238(ctx),
281            239 => self.evaluate_239(ctx),
282            240 => self.evaluate_240(ctx),
283            241 => self.evaluate_241(ctx),
284            242 => self.evaluate_242(ctx),
285            243 => self.evaluate_243(ctx),
286            244 => self.evaluate_244(ctx),
287            248 => self.evaluate_248(ctx),
288            249 => self.evaluate_249(ctx),
289            251 => self.evaluate_251(ctx),
290            252 => self.evaluate_252(ctx),
291            253 => self.evaluate_253(ctx),
292            254 => self.evaluate_254(ctx),
293            255 => self.evaluate_255(ctx),
294            256 => self.evaluate_256(ctx),
295            257 => self.evaluate_257(ctx),
296            258 => self.evaluate_258(ctx),
297            259 => self.evaluate_259(ctx),
298            261 => self.evaluate_261(ctx),
299            262 => self.evaluate_262(ctx),
300            265 => self.evaluate_265(ctx),
301            266 => self.evaluate_266(ctx),
302            267 => self.evaluate_267(ctx),
303            268 => self.evaluate_268(ctx),
304            269 => self.evaluate_269(ctx),
305            270 => self.evaluate_270(ctx),
306            273 => self.evaluate_273(ctx),
307            279 => self.evaluate_279(ctx),
308            280 => self.evaluate_280(ctx),
309            282 => self.evaluate_282(ctx),
310            284 => self.evaluate_284(ctx),
311            285 => self.evaluate_285(ctx),
312            286 => self.evaluate_286(ctx),
313            287 => self.evaluate_287(ctx),
314            288 => self.evaluate_288(ctx),
315            291 => self.evaluate_291(ctx),
316            292 => self.evaluate_292(ctx),
317            293 => self.evaluate_293(ctx),
318            294 => self.evaluate_294(ctx),
319            295 => self.evaluate_295(ctx),
320            296 => self.evaluate_296(ctx),
321            297 => self.evaluate_297(ctx),
322            298 => self.evaluate_298(ctx),
323            300 => self.evaluate_300(ctx),
324            301 => self.evaluate_301(ctx),
325            302 => self.evaluate_302(ctx),
326            303 => self.evaluate_303(ctx),
327            304 => self.evaluate_304(ctx),
328            305 => self.evaluate_305(ctx),
329            306 => self.evaluate_306(ctx),
330            307 => self.evaluate_307(ctx),
331            309 => self.evaluate_309(ctx),
332            312 => self.evaluate_312(ctx),
333            313 => self.evaluate_313(ctx),
334            314 => self.evaluate_314(ctx),
335            315 => self.evaluate_315(ctx),
336            316 => self.evaluate_316(ctx),
337            317 => self.evaluate_317(ctx),
338            318 => self.evaluate_318(ctx),
339            321 => self.evaluate_321(ctx),
340            322 => self.evaluate_322(ctx),
341            323 => self.evaluate_323(ctx),
342            326 => self.evaluate_326(ctx),
343            327 => self.evaluate_327(ctx),
344            328 => self.evaluate_328(ctx),
345            329 => self.evaluate_329(ctx),
346            332 => self.evaluate_332(ctx),
347            333 => self.evaluate_333(ctx),
348            334 => self.evaluate_334(ctx),
349            335 => self.evaluate_335(ctx),
350            336 => self.evaluate_336(ctx),
351            337 => self.evaluate_337(ctx),
352            338 => self.evaluate_338(ctx),
353            339 => self.evaluate_339(ctx),
354            340 => self.evaluate_340(ctx),
355            341 => self.evaluate_341(ctx),
356            342 => self.evaluate_342(ctx),
357            344 => self.evaluate_344(ctx),
358            345 => self.evaluate_345(ctx),
359            346 => self.evaluate_346(ctx),
360            347 => self.evaluate_347(ctx),
361            348 => self.evaluate_348(ctx),
362            349 => self.evaluate_349(ctx),
363            350 => self.evaluate_350(ctx),
364            351 => self.evaluate_351(ctx),
365            352 => self.evaluate_352(ctx),
366            355 => self.evaluate_355(ctx),
367            356 => self.evaluate_356(ctx),
368            357 => self.evaluate_357(ctx),
369            358 => self.evaluate_358(ctx),
370            359 => self.evaluate_359(ctx),
371            360 => self.evaluate_360(ctx),
372            363 => self.evaluate_363(ctx),
373            365 => self.evaluate_365(ctx),
374            366 => self.evaluate_366(ctx),
375            367 => self.evaluate_367(ctx),
376            368 => self.evaluate_368(ctx),
377            370 => self.evaluate_370(ctx),
378            371 => self.evaluate_371(ctx),
379            372 => self.evaluate_372(ctx),
380            373 => self.evaluate_373(ctx),
381            375 => self.evaluate_375(ctx),
382            376 => self.evaluate_376(ctx),
383            377 => self.evaluate_377(ctx),
384            378 => self.evaluate_378(ctx),
385            379 => self.evaluate_379(ctx),
386            380 => self.evaluate_380(ctx),
387            384 => self.evaluate_384(ctx),
388            386 => self.evaluate_386(ctx),
389            387 => self.evaluate_387(ctx),
390            388 => self.evaluate_388(ctx),
391            391 => self.evaluate_391(ctx),
392            392 => self.evaluate_392(ctx),
393            393 => self.evaluate_393(ctx),
394            394 => self.evaluate_394(ctx),
395            395 => self.evaluate_395(ctx),
396            396 => self.evaluate_396(ctx),
397            397 => self.evaluate_397(ctx),
398            398 => self.evaluate_398(ctx),
399            399 => self.evaluate_399(ctx),
400            401 => self.evaluate_401(ctx),
401            402 => self.evaluate_402(ctx),
402            403 => self.evaluate_403(ctx),
403            404 => self.evaluate_404(ctx),
404            405 => self.evaluate_405(ctx),
405            406 => self.evaluate_406(ctx),
406            407 => self.evaluate_407(ctx),
407            408 => self.evaluate_408(ctx),
408            409 => self.evaluate_409(ctx),
409            410 => self.evaluate_410(ctx),
410            411 => self.evaluate_411(ctx),
411            412 => self.evaluate_412(ctx),
412            413 => self.evaluate_413(ctx),
413            414 => self.evaluate_414(ctx),
414            415 => self.evaluate_415(ctx),
415            416 => self.evaluate_416(ctx),
416            417 => self.evaluate_417(ctx),
417            419 => self.evaluate_419(ctx),
418            420 => self.evaluate_420(ctx),
419            421 => self.evaluate_421(ctx),
420            425 => self.evaluate_425(ctx),
421            426 => self.evaluate_426(ctx),
422            427 => self.evaluate_427(ctx),
423            428 => self.evaluate_428(ctx),
424            429 => self.evaluate_429(ctx),
425            430 => self.evaluate_430(ctx),
426            431 => self.evaluate_431(ctx),
427            432 => self.evaluate_432(ctx),
428            433 => self.evaluate_433(ctx),
429            435 => self.evaluate_435(ctx),
430            436 => self.evaluate_436(ctx),
431            437 => self.evaluate_437(ctx),
432            438 => self.evaluate_438(ctx),
433            440 => self.evaluate_440(ctx),
434            441 => self.evaluate_441(ctx),
435            442 => self.evaluate_442(ctx),
436            444 => self.evaluate_444(ctx),
437            445 => self.evaluate_445(ctx),
438            446 => self.evaluate_446(ctx),
439            447 => self.evaluate_447(ctx),
440            448 => self.evaluate_448(ctx),
441            449 => self.evaluate_449(ctx),
442            450 => self.evaluate_450(ctx),
443            451 => self.evaluate_451(ctx),
444            452 => self.evaluate_452(ctx),
445            453 => self.evaluate_453(ctx),
446            454 => self.evaluate_454(ctx),
447            455 => self.evaluate_455(ctx),
448            456 => self.evaluate_456(ctx),
449            457 => self.evaluate_457(ctx),
450            458 => self.evaluate_458(ctx),
451            459 => self.evaluate_459(ctx),
452            460 => self.evaluate_460(ctx),
453            461 => self.evaluate_461(ctx),
454            462 => self.evaluate_462(ctx),
455            463 => self.evaluate_463(ctx),
456            465 => self.evaluate_465(ctx),
457            466 => self.evaluate_466(ctx),
458            467 => self.evaluate_467(ctx),
459            468 => self.evaluate_468(ctx),
460            469 => self.evaluate_469(ctx),
461            470 => self.evaluate_470(ctx),
462            471 => self.evaluate_471(ctx),
463            472 => self.evaluate_472(ctx),
464            473 => self.evaluate_473(ctx),
465            474 => self.evaluate_474(ctx),
466            475 => self.evaluate_475(ctx),
467            476 => self.evaluate_476(ctx),
468            477 => self.evaluate_477(ctx),
469            478 => self.evaluate_478(ctx),
470            479 => self.evaluate_479(ctx),
471            480 => self.evaluate_480(ctx),
472            481 => self.evaluate_481(ctx),
473            483 => self.evaluate_483(ctx),
474            484 => self.evaluate_484(ctx),
475            487 => self.evaluate_487(ctx),
476            489 => self.evaluate_489(ctx),
477            490 => self.evaluate_490(ctx),
478            491 => self.evaluate_491(ctx),
479            494 => self.evaluate_494(ctx),
480            500 => self.evaluate_500(ctx),
481            501 => self.evaluate_501(ctx),
482            502 => self.evaluate_502(ctx),
483            503 => self.evaluate_503(ctx),
484            504 => self.evaluate_504(ctx),
485            505 => self.evaluate_505(ctx),
486            506 => self.evaluate_506(ctx),
487            507 => self.evaluate_507(ctx),
488            508 => self.evaluate_508(ctx),
489            509 => self.evaluate_509(ctx),
490            510 => self.evaluate_510(ctx),
491            511 => self.evaluate_511(ctx),
492            512 => self.evaluate_512(ctx),
493            513 => self.evaluate_513(ctx),
494            514 => self.evaluate_514(ctx),
495            515 => self.evaluate_515(ctx),
496            516 => self.evaluate_516(ctx),
497            517 => self.evaluate_517(ctx),
498            518 => self.evaluate_518(ctx),
499            519 => self.evaluate_519(ctx),
500            520 => self.evaluate_520(ctx),
501            521 => self.evaluate_521(ctx),
502            522 => self.evaluate_522(ctx),
503            523 => self.evaluate_523(ctx),
504            524 => self.evaluate_524(ctx),
505            525 => self.evaluate_525(ctx),
506            526 => self.evaluate_526(ctx),
507            527 => self.evaluate_527(ctx),
508            528 => self.evaluate_528(ctx),
509            529 => self.evaluate_529(ctx),
510            530 => self.evaluate_530(ctx),
511            531 => self.evaluate_531(ctx),
512            532 => self.evaluate_532(ctx),
513            533 => self.evaluate_533(ctx),
514            534 => self.evaluate_534(ctx),
515            555 => self.evaluate_555(ctx),
516            556 => self.evaluate_556(ctx),
517            557 => self.evaluate_557(ctx),
518            558 => self.evaluate_558(ctx),
519            559 => self.evaluate_559(ctx),
520            560 => self.evaluate_560(ctx),
521            561 => self.evaluate_561(ctx),
522            562 => self.evaluate_562(ctx),
523            563 => self.evaluate_563(ctx),
524            564 => self.evaluate_564(ctx),
525            565 => self.evaluate_565(ctx),
526            566 => self.evaluate_566(ctx),
527            567 => self.evaluate_567(ctx),
528            568 => self.evaluate_568(ctx),
529            569 => self.evaluate_569(ctx),
530            570 => self.evaluate_570(ctx),
531            572 => self.evaluate_572(ctx),
532            576 => self.evaluate_576(ctx),
533            577 => self.evaluate_577(ctx),
534            578 => self.evaluate_578(ctx),
535            579 => self.evaluate_579(ctx),
536            580 => self.evaluate_580(ctx),
537            581 => self.evaluate_581(ctx),
538            586 => self.evaluate_586(ctx),
539            590 => self.evaluate_590(ctx),
540            594 => self.evaluate_594(ctx),
541            599 => self.evaluate_599(ctx),
542            601 => self.evaluate_601(ctx),
543            606 => self.evaluate_606(ctx),
544            609 => self.evaluate_609(ctx),
545            611 => self.evaluate_611(ctx),
546            614 => self.evaluate_614(ctx),
547            617 => self.evaluate_617(ctx),
548            618 => self.evaluate_618(ctx),
549            619 => self.evaluate_619(ctx),
550            621 => self.evaluate_621(ctx),
551            622 => self.evaluate_622(ctx),
552            623 => self.evaluate_623(ctx),
553            630 => self.evaluate_630(ctx),
554            631 => self.evaluate_631(ctx),
555            632 => self.evaluate_632(ctx),
556            637 => self.evaluate_637(ctx),
557            638 => self.evaluate_638(ctx),
558            639 => self.evaluate_639(ctx),
559            640 => self.evaluate_640(ctx),
560            641 => self.evaluate_641(ctx),
561            642 => self.evaluate_642(ctx),
562            643 => self.evaluate_643(ctx),
563            645 => self.evaluate_645(ctx),
564            646 => self.evaluate_646(ctx),
565            647 => self.evaluate_647(ctx),
566            648 => self.evaluate_648(ctx),
567            651 => self.evaluate_651(ctx),
568            653 => self.evaluate_653(ctx),
569            655 => self.evaluate_655(ctx),
570            659 => self.evaluate_659(ctx),
571            660 => self.evaluate_660(ctx),
572            662 => self.evaluate_662(ctx),
573            663 => self.evaluate_663(ctx),
574            664 => self.evaluate_664(ctx),
575            665 => self.evaluate_665(ctx),
576            667 => self.evaluate_667(ctx),
577            668 => self.evaluate_668(ctx),
578            670 => self.evaluate_670(ctx),
579            671 => self.evaluate_671(ctx),
580            672 => self.evaluate_672(ctx),
581            673 => self.evaluate_673(ctx),
582            674 => self.evaluate_674(ctx),
583            675 => self.evaluate_675(ctx),
584            677 => self.evaluate_677(ctx),
585            678 => self.evaluate_678(ctx),
586            679 => self.evaluate_679(ctx),
587            680 => self.evaluate_680(ctx),
588            681 => self.evaluate_681(ctx),
589            682 => self.evaluate_682(ctx),
590            683 => self.evaluate_683(ctx),
591            684 => self.evaluate_684(ctx),
592            685 => self.evaluate_685(ctx),
593            686 => self.evaluate_686(ctx),
594            687 => self.evaluate_687(ctx),
595            688 => self.evaluate_688(ctx),
596            689 => self.evaluate_689(ctx),
597            690 => self.evaluate_690(ctx),
598            693 => self.evaluate_693(ctx),
599            694 => self.evaluate_694(ctx),
600            695 => self.evaluate_695(ctx),
601            696 => self.evaluate_696(ctx),
602            698 => self.evaluate_698(ctx),
603            699 => self.evaluate_699(ctx),
604            700 => self.evaluate_700(ctx),
605            704 => self.evaluate_704(ctx),
606            705 => self.evaluate_705(ctx),
607            706 => self.evaluate_706(ctx),
608            707 => self.evaluate_707(ctx),
609            708 => self.evaluate_708(ctx),
610            709 => self.evaluate_709(ctx),
611            710 => self.evaluate_710(ctx),
612            711 => self.evaluate_711(ctx),
613            712 => self.evaluate_712(ctx),
614            713 => self.evaluate_713(ctx),
615            714 => self.evaluate_714(ctx),
616            715 => self.evaluate_715(ctx),
617            716 => self.evaluate_716(ctx),
618            717 => self.evaluate_717(ctx),
619            718 => self.evaluate_718(ctx),
620            719 => self.evaluate_719(ctx),
621            902 => self.evaluate_902(ctx),
622            910 => self.evaluate_910(ctx),
623            914 => self.evaluate_914(ctx),
624            922 => self.evaluate_922(ctx),
625            926 => self.evaluate_926(ctx),
626            930 => self.evaluate_930(ctx),
627            931 => self.evaluate_931(ctx),
628            932 => self.evaluate_932(ctx),
629            933 => self.evaluate_933(ctx),
630            937 => self.evaluate_937(ctx),
631            938 => self.evaluate_938(ctx),
632            939 => self.evaluate_939(ctx),
633            940 => self.evaluate_940(ctx),
634            942 => self.evaluate_942(ctx),
635            943 => self.evaluate_943(ctx),
636            946 => self.evaluate_946(ctx),
637            948 => self.evaluate_948(ctx),
638            950 => self.evaluate_950(ctx),
639            951 => self.evaluate_951(ctx),
640            952 => self.evaluate_952(ctx),
641            955 => self.evaluate_955(ctx),
642            957 => self.evaluate_957(ctx),
643            960 => self.evaluate_960(ctx),
644            961 => self.evaluate_961(ctx),
645            967 => self.evaluate_967(ctx),
646            2000 => self.evaluate_2000(ctx),
647            2001 => self.evaluate_2001(ctx),
648            2002 => self.evaluate_2002(ctx),
649            2003 => self.evaluate_2003(ctx),
650            2004 => self.evaluate_2004(ctx),
651            2005 => self.evaluate_2005(ctx),
652            2006 => self.evaluate_2006(ctx),
653            2007 => self.evaluate_2007(ctx),
654            2008 => self.evaluate_2008(ctx),
655            2009 => self.evaluate_2009(ctx),
656            2010 => self.evaluate_2010(ctx),
657            2011 => self.evaluate_2011(ctx),
658            2012 => self.evaluate_2012(ctx),
659            2013 => self.evaluate_2013(ctx),
660            2014 => self.evaluate_2014(ctx),
661            2015 => self.evaluate_2015(ctx),
662            2016 => self.evaluate_2016(ctx),
663            2017 => self.evaluate_2017(ctx),
664            2018 => self.evaluate_2018(ctx),
665            2060 => self.evaluate_2060(ctx),
666            2061 => self.evaluate_2061(ctx),
667            2071 => self.evaluate_2071(ctx),
668            2073 => self.evaluate_2073(ctx),
669            2075 => self.evaluate_2075(ctx),
670            2080 => self.evaluate_2080(ctx),
671            2095 => self.evaluate_2095(ctx),
672            2096 => self.evaluate_2096(ctx),
673            2119 => self.evaluate_2119(ctx),
674            2121 => self.evaluate_2121(ctx),
675            2140 => self.evaluate_2140(ctx),
676            2182 => self.evaluate_2182(ctx),
677            2183 => self.evaluate_2183(ctx),
678            2207 => self.evaluate_2207(ctx),
679            2225 => self.evaluate_2225(ctx),
680            2236 => self.evaluate_2236(ctx),
681            2252 => self.evaluate_2252(ctx),
682            2261 => self.evaluate_2261(ctx),
683            2284 => self.evaluate_2284(ctx),
684            2286 => self.evaluate_2286(ctx),
685            2287 => self.evaluate_2287(ctx),
686            2288 => self.evaluate_2288(ctx),
687            2307 => self.evaluate_2307(ctx),
688            2308 => self.evaluate_2308(ctx),
689            2309 => self.evaluate_2309(ctx),
690            2310 => self.evaluate_2310(ctx),
691            2311 => self.evaluate_2311(ctx),
692            2312 => self.evaluate_2312(ctx),
693            2313 => self.evaluate_2313(ctx),
694            2317 => self.evaluate_2317(ctx),
695            2318 => self.evaluate_2318(ctx),
696            2344 => self.evaluate_2344(ctx),
697            2350 => self.evaluate_2350(ctx),
698            2351 => self.evaluate_2351(ctx),
699            2352 => self.evaluate_2352(ctx),
700            2356 => self.evaluate_2356(ctx),
701            2357 => self.evaluate_2357(ctx),
702            2358 => self.evaluate_2358(ctx),
703            2359 => self.evaluate_2359(ctx),
704            2360 => self.evaluate_2360(ctx),
705            2361 => self.evaluate_2361(ctx),
706            _ => ConditionResult::Unknown,
707        }
708    }
709
710    fn is_external(&self, condition: u32) -> bool {
711        self.external_conditions.contains(&condition)
712    }
713    fn is_known(&self, condition: u32) -> bool {
714        matches!(
715            condition,
716            1 | 2
717                | 3
718                | 4
719                | 5
720                | 6
721                | 7
722                | 8
723                | 9
724                | 10
725                | 11
726                | 12
727                | 13
728                | 14
729                | 15
730                | 16
731                | 17
732                | 18
733                | 19
734                | 20
735                | 21
736                | 22
737                | 23
738                | 24
739                | 25
740                | 27
741                | 28
742                | 29
743                | 30
744                | 31
745                | 32
746                | 33
747                | 34
748                | 35
749                | 36
750                | 37
751                | 38
752                | 39
753                | 40
754                | 41
755                | 42
756                | 43
757                | 44
758                | 45
759                | 46
760                | 47
761                | 48
762                | 49
763                | 50
764                | 51
765                | 52
766                | 53
767                | 54
768                | 55
769                | 56
770                | 57
771                | 58
772                | 60
773                | 61
774                | 62
775                | 63
776                | 64
777                | 65
778                | 66
779                | 67
780                | 68
781                | 69
782                | 70
783                | 71
784                | 72
785                | 73
786                | 74
787                | 75
788                | 76
789                | 77
790                | 78
791                | 79
792                | 83
793                | 84
794                | 85
795                | 86
796                | 87
797                | 88
798                | 89
799                | 90
800                | 91
801                | 92
802                | 93
803                | 94
804                | 95
805                | 96
806                | 97
807                | 98
808                | 99
809                | 100
810                | 101
811                | 102
812                | 103
813                | 104
814                | 105
815                | 106
816                | 107
817                | 108
818                | 110
819                | 111
820                | 112
821                | 113
822                | 114
823                | 115
824                | 116
825                | 117
826                | 118
827                | 119
828                | 120
829                | 121
830                | 122
831                | 123
832                | 124
833                | 125
834                | 126
835                | 127
836                | 128
837                | 129
838                | 130
839                | 131
840                | 132
841                | 133
842                | 134
843                | 135
844                | 136
845                | 137
846                | 138
847                | 139
848                | 140
849                | 141
850                | 142
851                | 143
852                | 144
853                | 145
854                | 146
855                | 147
856                | 148
857                | 149
858                | 150
859                | 151
860                | 152
861                | 153
862                | 156
863                | 157
864                | 161
865                | 162
866                | 163
867                | 164
868                | 165
869                | 166
870                | 167
871                | 168
872                | 169
873                | 170
874                | 172
875                | 173
876                | 174
877                | 175
878                | 176
879                | 177
880                | 178
881                | 179
882                | 180
883                | 184
884                | 190
885                | 191
886                | 192
887                | 193
888                | 194
889                | 195
890                | 196
891                | 197
892                | 198
893                | 199
894                | 201
895                | 202
896                | 203
897                | 204
898                | 205
899                | 206
900                | 209
901                | 210
902                | 212
903                | 213
904                | 215
905                | 216
906                | 217
907                | 219
908                | 220
909                | 221
910                | 223
911                | 224
912                | 227
913                | 229
914                | 232
915                | 233
916                | 234
917                | 237
918                | 238
919                | 239
920                | 240
921                | 241
922                | 242
923                | 243
924                | 244
925                | 248
926                | 249
927                | 251
928                | 252
929                | 253
930                | 254
931                | 255
932                | 256
933                | 257
934                | 258
935                | 259
936                | 261
937                | 262
938                | 265
939                | 266
940                | 267
941                | 268
942                | 269
943                | 270
944                | 273
945                | 279
946                | 280
947                | 282
948                | 284
949                | 285
950                | 286
951                | 287
952                | 288
953                | 291
954                | 292
955                | 293
956                | 294
957                | 295
958                | 296
959                | 297
960                | 298
961                | 300
962                | 301
963                | 302
964                | 303
965                | 304
966                | 305
967                | 306
968                | 307
969                | 309
970                | 312
971                | 313
972                | 314
973                | 315
974                | 316
975                | 317
976                | 318
977                | 321
978                | 322
979                | 323
980                | 326
981                | 327
982                | 328
983                | 329
984                | 332
985                | 333
986                | 334
987                | 335
988                | 336
989                | 337
990                | 338
991                | 339
992                | 340
993                | 341
994                | 342
995                | 344
996                | 345
997                | 346
998                | 347
999                | 348
1000                | 349
1001                | 350
1002                | 351
1003                | 352
1004                | 355
1005                | 356
1006                | 357
1007                | 358
1008                | 359
1009                | 360
1010                | 363
1011                | 365
1012                | 366
1013                | 367
1014                | 368
1015                | 370
1016                | 371
1017                | 372
1018                | 373
1019                | 375
1020                | 376
1021                | 377
1022                | 378
1023                | 379
1024                | 380
1025                | 384
1026                | 386
1027                | 387
1028                | 388
1029                | 391
1030                | 392
1031                | 393
1032                | 394
1033                | 395
1034                | 396
1035                | 397
1036                | 398
1037                | 399
1038                | 401
1039                | 402
1040                | 403
1041                | 404
1042                | 405
1043                | 406
1044                | 407
1045                | 408
1046                | 409
1047                | 410
1048                | 411
1049                | 412
1050                | 413
1051                | 414
1052                | 415
1053                | 416
1054                | 417
1055                | 419
1056                | 420
1057                | 421
1058                | 425
1059                | 426
1060                | 427
1061                | 428
1062                | 429
1063                | 430
1064                | 431
1065                | 432
1066                | 433
1067                | 435
1068                | 436
1069                | 437
1070                | 438
1071                | 440
1072                | 441
1073                | 442
1074                | 444
1075                | 445
1076                | 446
1077                | 447
1078                | 448
1079                | 449
1080                | 450
1081                | 451
1082                | 452
1083                | 453
1084                | 454
1085                | 455
1086                | 456
1087                | 457
1088                | 458
1089                | 459
1090                | 460
1091                | 461
1092                | 462
1093                | 463
1094                | 465
1095                | 466
1096                | 467
1097                | 468
1098                | 469
1099                | 470
1100                | 471
1101                | 472
1102                | 473
1103                | 474
1104                | 475
1105                | 476
1106                | 477
1107                | 478
1108                | 479
1109                | 480
1110                | 481
1111                | 483
1112                | 484
1113                | 487
1114                | 489
1115                | 490
1116                | 491
1117                | 494
1118                | 500
1119                | 501
1120                | 502
1121                | 503
1122                | 504
1123                | 505
1124                | 506
1125                | 507
1126                | 508
1127                | 509
1128                | 510
1129                | 511
1130                | 512
1131                | 513
1132                | 514
1133                | 515
1134                | 516
1135                | 517
1136                | 518
1137                | 519
1138                | 520
1139                | 521
1140                | 522
1141                | 523
1142                | 524
1143                | 525
1144                | 526
1145                | 527
1146                | 528
1147                | 529
1148                | 530
1149                | 531
1150                | 532
1151                | 533
1152                | 534
1153                | 555
1154                | 556
1155                | 557
1156                | 558
1157                | 559
1158                | 560
1159                | 561
1160                | 562
1161                | 563
1162                | 564
1163                | 565
1164                | 566
1165                | 567
1166                | 568
1167                | 569
1168                | 570
1169                | 572
1170                | 576
1171                | 577
1172                | 578
1173                | 579
1174                | 580
1175                | 581
1176                | 586
1177                | 590
1178                | 594
1179                | 599
1180                | 601
1181                | 606
1182                | 609
1183                | 611
1184                | 614
1185                | 617
1186                | 618
1187                | 619
1188                | 621
1189                | 622
1190                | 623
1191                | 630
1192                | 631
1193                | 632
1194                | 637
1195                | 638
1196                | 639
1197                | 640
1198                | 641
1199                | 642
1200                | 643
1201                | 645
1202                | 646
1203                | 647
1204                | 648
1205                | 651
1206                | 653
1207                | 655
1208                | 659
1209                | 660
1210                | 662
1211                | 663
1212                | 664
1213                | 665
1214                | 667
1215                | 668
1216                | 670
1217                | 671
1218                | 672
1219                | 673
1220                | 674
1221                | 675
1222                | 677
1223                | 678
1224                | 679
1225                | 680
1226                | 681
1227                | 682
1228                | 683
1229                | 684
1230                | 685
1231                | 686
1232                | 687
1233                | 688
1234                | 689
1235                | 690
1236                | 693
1237                | 694
1238                | 695
1239                | 696
1240                | 698
1241                | 699
1242                | 700
1243                | 704
1244                | 705
1245                | 706
1246                | 707
1247                | 708
1248                | 709
1249                | 710
1250                | 711
1251                | 712
1252                | 713
1253                | 714
1254                | 715
1255                | 716
1256                | 717
1257                | 718
1258                | 719
1259                | 902
1260                | 910
1261                | 914
1262                | 922
1263                | 926
1264                | 930
1265                | 931
1266                | 932
1267                | 933
1268                | 937
1269                | 938
1270                | 939
1271                | 940
1272                | 942
1273                | 943
1274                | 946
1275                | 948
1276                | 950
1277                | 951
1278                | 952
1279                | 955
1280                | 957
1281                | 960
1282                | 961
1283                | 967
1284                | 2000
1285                | 2001
1286                | 2002
1287                | 2003
1288                | 2004
1289                | 2005
1290                | 2006
1291                | 2007
1292                | 2008
1293                | 2009
1294                | 2010
1295                | 2011
1296                | 2012
1297                | 2013
1298                | 2014
1299                | 2015
1300                | 2016
1301                | 2017
1302                | 2018
1303                | 2060
1304                | 2061
1305                | 2071
1306                | 2073
1307                | 2075
1308                | 2080
1309                | 2095
1310                | 2096
1311                | 2119
1312                | 2121
1313                | 2140
1314                | 2182
1315                | 2183
1316                | 2207
1317                | 2225
1318                | 2236
1319                | 2252
1320                | 2261
1321                | 2284
1322                | 2286
1323                | 2287
1324                | 2288
1325                | 2307
1326                | 2308
1327                | 2309
1328                | 2310
1329                | 2311
1330                | 2312
1331                | 2313
1332                | 2317
1333                | 2318
1334                | 2344
1335                | 2350
1336                | 2351
1337                | 2352
1338                | 2356
1339                | 2357
1340                | 2358
1341                | 2359
1342                | 2360
1343                | 2361
1344        )
1345    }
1346}
1347
1348impl UtilmdStromConditionEvaluatorFV2510 {
1349    /// [2] Wenn UNH DE0070 (Übermittlungsfolgenummer) mit 1 vorhanden
1350    fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
1351        ctx.has_segment_matching("UNH", &[(3, 0, "1")])
1352    }
1353
1354    /// [3] Bei Aufteilung, in der Nachricht mit der höchsten Übermittlungsfolgenummer
1355    /// EXTERNAL: Requires context from outside the message.
1356    fn evaluate_3(&self, ctx: &EvaluationContext) -> ConditionResult {
1357        ctx.external.evaluate("is_highest_sequence_in_split")
1358    }
1359
1360    /// [20] Wenn im SG8 SEQ+Z01 (Daten der Marktlokation) mit der gleichen ID im SG8 RFF+Z18 (Referenz auf die ID der Marktlokation) wie in diesem SG8 das SG10 CCI+Z30++Z07 (Verbrauch) vorhanden
1361    fn evaluate_20(&self, ctx: &EvaluationContext) -> ConditionResult {
1362        let nav = match ctx.navigator() {
1363            Some(n) => n,
1364            None => return ctx.has_qualified_value("CCI", 0, "Z30", 2, 0, &["Z07"]),
1365        };
1366        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1367        for i in 0..sg8_count {
1368            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1369            let has_z01 = seq_segs.iter().any(|s| {
1370                s.elements
1371                    .first()
1372                    .and_then(|e| e.first())
1373                    .is_some_and(|v| v == "Z01")
1374            });
1375            if !has_z01 {
1376                continue;
1377            }
1378            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
1379            for j in 0..sg10_count {
1380                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
1381                if ccis.iter().any(|s| {
1382                    s.elements
1383                        .first()
1384                        .and_then(|e| e.first())
1385                        .is_some_and(|v| v == "Z30")
1386                        && s.elements
1387                            .get(2)
1388                            .and_then(|e| e.first())
1389                            .is_some_and(|v| v == "Z07")
1390                }) {
1391                    return ConditionResult::True;
1392                }
1393            }
1394        }
1395        ConditionResult::False
1396    }
1397
1398    /// [28] Wenn in dieser SG4 IDE+24 das STS+E01++A04: E_0017 bzw. A03: E_0052 (Zusätzlicher Datensatz / ergänzte Marktlokation) nicht vorhanden
1399    // REVIEW: Within each SG4 containing IDE+24 (Vorgang), check if STS+E01 with Prüfschritt A04:E_0017 (Zusätzlicher Datensatz) or A03:E_0052 (ergänzte Marktlokation) is absent. Uses navigator to scope the check per SG4 instance. STS elements[0][0]="E01", elements[2][0]=Prüfschritt code, elements[2][1]=codelist. Condition is True when this STS is NOT found in the SG4, indicating no 'additional record' status was set. (medium confidence)
1400    fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
1401        let nav = match ctx.navigator() {
1402            Some(n) => n,
1403            None => {
1404                let sts_segs = ctx.find_segments_with_qualifier("STS", 0, "E01");
1405                let found = sts_segs.iter().any(|s| {
1406                    let code = s
1407                        .elements
1408                        .get(2)
1409                        .and_then(|e| e.first())
1410                        .map(|v| v.as_str());
1411                    let list = s.elements.get(2).and_then(|e| e.get(1)).map(|v| v.as_str());
1412                    (code == Some("A04") && list == Some("E_0017"))
1413                        || (code == Some("A03") && list == Some("E_0052"))
1414                });
1415                return ConditionResult::from(!found);
1416            }
1417        };
1418        let sg4_count = nav.group_instance_count(&["SG4"]);
1419        for i in 0..sg4_count {
1420            let ide_segs = nav.find_segments_in_group("IDE", &["SG4"], i);
1421            let has_ide_24 = ide_segs.iter().any(|s| {
1422                s.elements
1423                    .first()
1424                    .and_then(|e| e.first())
1425                    .is_some_and(|v| v == "24")
1426            });
1427            if !has_ide_24 {
1428                continue;
1429            }
1430            let sts_segs = nav.find_segments_in_group("STS", &["SG4"], i);
1431            let found = sts_segs.iter().any(|s| {
1432                let qual = s
1433                    .elements
1434                    .first()
1435                    .and_then(|e| e.first())
1436                    .map(|v| v.as_str());
1437                let code = s
1438                    .elements
1439                    .get(2)
1440                    .and_then(|e| e.first())
1441                    .map(|v| v.as_str());
1442                let list = s.elements.get(2).and_then(|e| e.get(1)).map(|v| v.as_str());
1443                qual == Some("E01")
1444                    && ((code == Some("A04") && list == Some("E_0017"))
1445                        || (code == Some("A03") && list == Some("E_0052")))
1446            });
1447            if !found {
1448                return ConditionResult::True;
1449            }
1450        }
1451        ConditionResult::False
1452    }
1453
1454    /// [29] Wenn in dieser SG4 IDE+24 das STS+E01++A06: E_0017 bzw. A05: E_0052 (Zu viele Marktlokationen enthalten / entfallene Marktlokation) nicht vorhanden
1455    // REVIEW: Within each SG4 containing IDE+24 (Vorgang), check if STS+E01 with Prüfschritt A06:E_0017 (Zu viele Marktlokationen) or A05:E_0052 (entfallene Marktlokation) is absent. Mirrors condition [28] but for the 'too many / dropped Marktlokation' status codes. True when neither combination is found in the SG4, indicating no 'excess/dropped records' status was set. (medium confidence)
1456    fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
1457        let nav = match ctx.navigator() {
1458            Some(n) => n,
1459            None => {
1460                let sts_segs = ctx.find_segments_with_qualifier("STS", 0, "E01");
1461                let found = sts_segs.iter().any(|s| {
1462                    let code = s
1463                        .elements
1464                        .get(2)
1465                        .and_then(|e| e.first())
1466                        .map(|v| v.as_str());
1467                    let list = s.elements.get(2).and_then(|e| e.get(1)).map(|v| v.as_str());
1468                    (code == Some("A06") && list == Some("E_0017"))
1469                        || (code == Some("A05") && list == Some("E_0052"))
1470                });
1471                return ConditionResult::from(!found);
1472            }
1473        };
1474        let sg4_count = nav.group_instance_count(&["SG4"]);
1475        for i in 0..sg4_count {
1476            let ide_segs = nav.find_segments_in_group("IDE", &["SG4"], i);
1477            let has_ide_24 = ide_segs.iter().any(|s| {
1478                s.elements
1479                    .first()
1480                    .and_then(|e| e.first())
1481                    .is_some_and(|v| v == "24")
1482            });
1483            if !has_ide_24 {
1484                continue;
1485            }
1486            let sts_segs = nav.find_segments_in_group("STS", &["SG4"], i);
1487            let found = sts_segs.iter().any(|s| {
1488                let qual = s
1489                    .elements
1490                    .first()
1491                    .and_then(|e| e.first())
1492                    .map(|v| v.as_str());
1493                let code = s
1494                    .elements
1495                    .get(2)
1496                    .and_then(|e| e.first())
1497                    .map(|v| v.as_str());
1498                let list = s.elements.get(2).and_then(|e| e.get(1)).map(|v| v.as_str());
1499                qual == Some("E01")
1500                    && ((code == Some("A06") && list == Some("E_0017"))
1501                        || (code == Some("A05") && list == Some("E_0052")))
1502            });
1503            if !found {
1504                return ConditionResult::True;
1505            }
1506        }
1507        ConditionResult::False
1508    }
1509
1510    /// [44] Es ist die Zeitraum-ID vom DE1156 aus einem passenden SG6 RFF+Z49/ Z53 (Verwendungszeitraum der Daten: "Gültige Daten", "Keine Daten") aus der Anfragennachricht aus SG6 RFF+TN DE1154 ((Referenz Vo...
1511    fn evaluate_44(&self, _ctx: &EvaluationContext) -> ConditionResult {
1512        // Hinweis: Die Zeitraum-ID ist vom DE1156 aus einem passenden SG6 RFF+Z49/Z53
1513        // (Verwendungszeitraum der Daten) aus der Anfragenachricht, identifiziert über
1514        // SG6 RFF+TN DE1154 (Referenz Vorgangsnummer), einzutragen. Informelle Befüllungsregel.
1515        ConditionResult::True
1516    }
1517
1518    /// [51] Wenn die Marktlokations-ID im SG8 RFF+Z18 derselben SG8 SEQ+Z98 (Informative Daten der Marktlokation) mit derselben Zeitraum-ID im DE1050 nicht auf ein SG8 SEQ+Z78 (Referenz auf die Lokationsbünde...
1519    // REVIEW: Cross-SG condition: checks that SG8 SEQ+Z98 groups (Daten der Marktlokation) do NOT share a Zeitraum-ID with SG8 SEQ+Z78 groups (Lokationsbündelstruktur) that carry the 'Verbrauch ohne Messlokation (Pauschal)' code 9992 00000 001 8 in RFF+Z31. Medium confidence due to the multi-step cross-group correlation logic and the whitespace-normalized code comparison. (medium confidence)
1520    fn evaluate_51(&self, ctx: &EvaluationContext) -> ConditionResult {
1521        let nav = match ctx.navigator() {
1522            Some(n) => n,
1523            None => return ConditionResult::Unknown,
1524        };
1525        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1526
1527        // Step 1: Collect Zeitraum-IDs from Z78 SG8 groups that have RFF+Z31 with the target code
1528        let target_code = "9992000000018";
1529        let mut z78_zeitraum_ids: std::collections::HashSet<String> =
1530            std::collections::HashSet::new();
1531        for i in 0..sg8_count {
1532            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1533            let is_z78 = seq_segs.iter().any(|s| {
1534                s.elements
1535                    .first()
1536                    .and_then(|e| e.first())
1537                    .is_some_and(|v| v == "Z78")
1538            });
1539            if !is_z78 {
1540                continue;
1541            }
1542            let rff_segs = nav.find_segments_in_group("RFF", &["SG4", "SG8"], i);
1543            let has_z31_target = rff_segs.iter().any(|s| {
1544                s.elements
1545                    .first()
1546                    .and_then(|e| e.first())
1547                    .is_some_and(|v| v == "Z31")
1548                    && s.elements
1549                        .first()
1550                        .and_then(|e| e.get(1))
1551                        .is_some_and(|v| v.replace(' ', "") == target_code)
1552            });
1553            if has_z31_target {
1554                for seq in &seq_segs {
1555                    if seq
1556                        .elements
1557                        .first()
1558                        .and_then(|e| e.first())
1559                        .is_some_and(|v| v == "Z78")
1560                    {
1561                        if let Some(zeit_id) = seq.elements.get(1).and_then(|e| e.first()) {
1562                            if !zeit_id.is_empty() {
1563                                z78_zeitraum_ids.insert(zeit_id.clone());
1564                            }
1565                        }
1566                    }
1567                }
1568            }
1569        }
1570
1571        if z78_zeitraum_ids.is_empty() {
1572            // No Z78 with the target code exists — the Z98 group cannot reference it, condition True
1573            return ConditionResult::True;
1574        }
1575
1576        // Step 2: Check if any Z98 SG8 shares a Zeitraum-ID with a target Z78 SG8
1577        for i in 0..sg8_count {
1578            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1579            for seq in &seq_segs {
1580                if seq
1581                    .elements
1582                    .first()
1583                    .and_then(|e| e.first())
1584                    .is_some_and(|v| v == "Z98")
1585                {
1586                    if let Some(zeit_id) = seq.elements.get(1).and_then(|e| e.first()) {
1587                        if z78_zeitraum_ids.contains(zeit_id) {
1588                            // Z98 SG8 references a Z78 with the Pauschal code — condition False
1589                            return ConditionResult::False;
1590                        }
1591                    }
1592                }
1593            }
1594        }
1595        ConditionResult::True
1596    }
1597
1598    /// [79] Wenn SG4 STS+7+++Z33 (Auszug wegen Stilllegung) vorhanden
1599    fn evaluate_79(&self, ctx: &EvaluationContext) -> ConditionResult {
1600        // STS+7+++Z33: elements[0][0]="7" (Statuskategorie), elements[3][0]="Z33" (Transaktionsgrundergänzung: Auszug wegen Stilllegung)
1601        ctx.has_segment_matching("STS", &[(0, 0, "7"), (3, 0, "Z33")])
1602    }
1603
1604    /// [134] Wenn dieses DTM+Z25 (Verwendung der Daten ab) nicht im SG6 RFF+Z48/ Z55 (Verwendungszeitraum der Daten: Erwartete Daten/ Keine Daten erwartet) mit der Zeitraum ID "1" im DE1156 ist, muss das Datum ...
1605    // REVIEW: Temporal consistency check across SG6 Verwendungszeitraum slices with RFF+Z48/Z55 (Erwartete Daten / Keine Daten erwartet). For each slice with Zeitraum-ID > 1, its DTM+Z25 (Daten ab) must equal DTM+Z26 (Daten bis) of the next-lower Zeitraum-ID slice. Reads DE1156 (elements[0][2]) for the Zeitraum-ID, sorts numerically, then validates continuity. Medium confidence due to ordering semantics and implicit 'current SG6 context' requirement. (medium confidence)
1606    fn evaluate_134(&self, ctx: &EvaluationContext) -> ConditionResult {
1607        let nav = match ctx.navigator() {
1608            Some(n) => n,
1609            None => return ConditionResult::Unknown,
1610        };
1611        let sg6_count = nav.group_instance_count(&["SG4", "SG6"]);
1612
1613        // Collect (zeitraum_id_numeric, dtm_z25_value, dtm_z26_value) for SG6 groups with RFF+Z48 or RFF+Z55
1614        let mut slices: Vec<(i64, String, String)> = Vec::new();
1615        for i in 0..sg6_count {
1616            let rff_segs = nav.find_segments_in_group("RFF", &["SG4", "SG6"], i);
1617            // DE1156 is elements[0][2] for RFF Verwendungszeitraum
1618            let zeitraum_id = rff_segs.iter().find_map(|s| {
1619                let qual = s.elements.first().and_then(|e| e.first())?;
1620                if qual == "Z48" || qual == "Z55" {
1621                    let id = s.elements.first().and_then(|e| e.get(2))?;
1622                    if !id.is_empty() {
1623                        Some(id.clone())
1624                    } else {
1625                        None
1626                    }
1627                } else {
1628                    None
1629                }
1630            });
1631            let Some(zid_str) = zeitraum_id else { continue };
1632            let Ok(zid_num) = zid_str.parse::<i64>() else {
1633                continue;
1634            };
1635            let dtm_segs = nav.find_segments_in_group("DTM", &["SG4", "SG6"], i);
1636            let z25 = dtm_segs
1637                .iter()
1638                .find_map(|s| {
1639                    if s.elements
1640                        .first()
1641                        .and_then(|e| e.first())
1642                        .is_some_and(|v| v == "Z25")
1643                    {
1644                        s.elements.first().and_then(|e| e.get(1)).cloned()
1645                    } else {
1646                        None
1647                    }
1648                })
1649                .unwrap_or_default();
1650            let z26 = dtm_segs
1651                .iter()
1652                .find_map(|s| {
1653                    if s.elements
1654                        .first()
1655                        .and_then(|e| e.first())
1656                        .is_some_and(|v| v == "Z26")
1657                    {
1658                        s.elements.first().and_then(|e| e.get(1)).cloned()
1659                    } else {
1660                        None
1661                    }
1662                })
1663                .unwrap_or_default();
1664            slices.push((zid_num, z25, z26));
1665        }
1666        if slices.len() < 2 {
1667            return ConditionResult::Unknown;
1668        }
1669        slices.sort_by_key(|s| s.0);
1670        // For each slice with Zeitraum-ID != 1, DTM+Z25 must equal DTM+Z26 of the immediately preceding slice
1671        for idx in 1..slices.len() {
1672            let (id, z25, _) = &slices[idx];
1673            let (_, _, prev_z26) = &slices[idx - 1];
1674            if *id != 1 && !z25.is_empty() && !prev_z26.is_empty() && z25 != prev_z26 {
1675                return ConditionResult::False;
1676            }
1677        }
1678        ConditionResult::True
1679    }
1680
1681    /// [135] Wenn dieses DTM+Z25 (Verwendung der Daten ab) nicht im SG6 RFF+Z47/ Z54 (Verwendungszeitraum der Daten: Im System vorhandene Daten/ Im System keine Daten vorhanden) mit der Zeitraum ID "1" im DE115...
1682    // REVIEW: Identical logic to condition [134] but applied to SG6 groups with RFF+Z47/Z54 (Im System vorhandene Daten / Im System keine Daten vorhanden) instead of Z48/Z55. Verifies temporal continuity: DTM+Z25 of each non-first slice must equal DTM+Z26 of the preceding slice when sorted by Zeitraum-ID. Same structural approach and same confidence level. (medium confidence)
1683    fn evaluate_135(&self, ctx: &EvaluationContext) -> ConditionResult {
1684        let nav = match ctx.navigator() {
1685            Some(n) => n,
1686            None => return ConditionResult::Unknown,
1687        };
1688        let sg6_count = nav.group_instance_count(&["SG4", "SG6"]);
1689
1690        // Collect (zeitraum_id_numeric, dtm_z25_value, dtm_z26_value) for SG6 groups with RFF+Z47 or RFF+Z54
1691        let mut slices: Vec<(i64, String, String)> = Vec::new();
1692        for i in 0..sg6_count {
1693            let rff_segs = nav.find_segments_in_group("RFF", &["SG4", "SG6"], i);
1694            // DE1156 is elements[0][2] for RFF Verwendungszeitraum
1695            let zeitraum_id = rff_segs.iter().find_map(|s| {
1696                let qual = s.elements.first().and_then(|e| e.first())?;
1697                if qual == "Z47" || qual == "Z54" {
1698                    let id = s.elements.first().and_then(|e| e.get(2))?;
1699                    if !id.is_empty() {
1700                        Some(id.clone())
1701                    } else {
1702                        None
1703                    }
1704                } else {
1705                    None
1706                }
1707            });
1708            let Some(zid_str) = zeitraum_id else { continue };
1709            let Ok(zid_num) = zid_str.parse::<i64>() else {
1710                continue;
1711            };
1712            let dtm_segs = nav.find_segments_in_group("DTM", &["SG4", "SG6"], i);
1713            let z25 = dtm_segs
1714                .iter()
1715                .find_map(|s| {
1716                    if s.elements
1717                        .first()
1718                        .and_then(|e| e.first())
1719                        .is_some_and(|v| v == "Z25")
1720                    {
1721                        s.elements.first().and_then(|e| e.get(1)).cloned()
1722                    } else {
1723                        None
1724                    }
1725                })
1726                .unwrap_or_default();
1727            let z26 = dtm_segs
1728                .iter()
1729                .find_map(|s| {
1730                    if s.elements
1731                        .first()
1732                        .and_then(|e| e.first())
1733                        .is_some_and(|v| v == "Z26")
1734                    {
1735                        s.elements.first().and_then(|e| e.get(1)).cloned()
1736                    } else {
1737                        None
1738                    }
1739                })
1740                .unwrap_or_default();
1741            slices.push((zid_num, z25, z26));
1742        }
1743        if slices.len() < 2 {
1744            return ConditionResult::Unknown;
1745        }
1746        slices.sort_by_key(|s| s.0);
1747        // For each slice with Zeitraum-ID != 1, DTM+Z25 must equal DTM+Z26 of the immediately preceding slice
1748        for idx in 1..slices.len() {
1749            let (id, z25, _) = &slices[idx];
1750            let (_, _, prev_z26) = &slices[idx - 1];
1751            if *id != 1 && !z25.is_empty() && !prev_z26.is_empty() && z25 != prev_z26 {
1752                return ConditionResult::False;
1753            }
1754        }
1755        ConditionResult::True
1756    }
1757
1758    /// [136] Wenn SG10 CCI+++E13 (Zählertyp) CAV+EHZ (elektronischer Haushaltszähler) in dieser SG8 vorhanden
1759    fn evaluate_136(&self, ctx: &EvaluationContext) -> ConditionResult {
1760        let nav = match ctx.navigator() {
1761            Some(n) => n,
1762            None => return ctx.has_qualified_value("CAV", 0, "EHZ", 0, 0, &["EHZ"]),
1763        };
1764        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1765        for i in 0..sg8_count {
1766            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
1767            for j in 0..sg10_count {
1768                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
1769                let has_cci_e13 = ccis.iter().any(|s| {
1770                    s.elements
1771                        .get(2)
1772                        .and_then(|e| e.first())
1773                        .is_some_and(|v| v == "E13")
1774                });
1775                if has_cci_e13 {
1776                    let cavs =
1777                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
1778                    if cavs.iter().any(|s| {
1779                        s.elements
1780                            .first()
1781                            .and_then(|e| e.first())
1782                            .is_some_and(|v| v == "EHZ")
1783                    }) {
1784                        return ConditionResult::True;
1785                    }
1786                }
1787            }
1788        }
1789        ConditionResult::False
1790    }
1791
1792    /// [139] Wenn SG10 CAV+IVA (Individuelle Abstimmung) in dieser SG8 nicht vorhanden
1793    // REVIEW: True when no SG10 child of any SG8 contains a CAV with elements[0][0]=='IVA'. Iterates all SG8 instances and their SG10 children; returns False as soon as IVA is found, True if absent throughout. 'In dieser SG8' is evaluated message-wide since no specific parent qualifier filter is given. (medium confidence)
1794    fn evaluate_139(&self, ctx: &EvaluationContext) -> ConditionResult {
1795        let nav = match ctx.navigator() {
1796            Some(n) => n,
1797            None => return ctx.lacks_qualifier("CAV", 0, "IVA"),
1798        };
1799        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1800        for i in 0..sg8_count {
1801            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
1802            for j in 0..sg10_count {
1803                let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
1804                if cavs.iter().any(|s| {
1805                    s.elements
1806                        .first()
1807                        .and_then(|e| e.first())
1808                        .is_some_and(|v| v == "IVA")
1809                }) {
1810                    return ConditionResult::False;
1811                }
1812            }
1813        }
1814        ConditionResult::True
1815    }
1816
1817    /// [157] Wenn SG4 STS+7++Z33+ZZB nicht vorhanden
1818    fn evaluate_157(&self, ctx: &EvaluationContext) -> ConditionResult {
1819        let result = ctx.has_segment_matching("STS", &[(0, 0, "7"), (2, 0, "Z33"), (3, 0, "ZZB")]);
1820        match result {
1821            ConditionResult::True => ConditionResult::False,
1822            ConditionResult::False => ConditionResult::True,
1823            ConditionResult::Unknown => ConditionResult::Unknown,
1824        }
1825    }
1826
1827    /// [168] Wenn in dieser SG8 im SG8 PIA+Z02 (Gruppenartikel- ID / Artikel-ID), die Artikel-ID 1-02-0-002/ 003/ 004 vorhanden
1828    fn evaluate_168(&self, ctx: &EvaluationContext) -> ConditionResult {
1829        ctx.any_group_has_qualified_value(
1830            "PIA",
1831            0,
1832            "Z02",
1833            1,
1834            0,
1835            &["1-02-0-002", "1-02-0-003", "1-02-0-004"],
1836            &["SG4", "SG8"],
1837        )
1838    }
1839
1840    /// [169] Wenn zwei SG8 SEQ+Z45 (Netznutzungsabrechnungsdaten der Marktlokation), mit derselben Zeitraum-ID im DE1050, mit Artikel-ID im SG8 PIA+Z02 (Gruppenartikel-ID / Artikel-ID), eine SG8 mit 1-02-0-002 ...
1841    // REVIEW: Complex cross-group condition. Collects all SG8 instances having SEQ+Z45 (Netznutzungsabrechnungsdaten), extracting the Zeitraum-ID from SEQ elements[1][0] (DE1050) and the PIA+Z02 article ID from elements[1][0]. Then checks if two such SG8 instances share the same Zeitraum-ID where one has article 1-02-0-002 and the other has 1-02-0-003 or 1-02-0-004. Medium confidence because the article ID string format ('1-02-0-002') must match exactly as stored in the EDIFACT value. (medium confidence)
1842    fn evaluate_169(&self, ctx: &EvaluationContext) -> ConditionResult {
1843        let nav = match ctx.navigator() {
1844            Some(n) => n,
1845            None => return ConditionResult::Unknown,
1846        };
1847        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1848        let mut sg8_data: Vec<(String, String)> = Vec::new();
1849        for i in 0..sg8_count {
1850            let seqs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1851            let zeitraum_id = seqs
1852                .iter()
1853                .find(|s| {
1854                    s.elements
1855                        .first()
1856                        .and_then(|e| e.first())
1857                        .is_some_and(|v| v == "Z45")
1858                })
1859                .and_then(|s| s.elements.get(1))
1860                .and_then(|e| e.first())
1861                .filter(|v| !v.is_empty())
1862                .cloned();
1863            if let Some(zid) = zeitraum_id {
1864                let pias = nav.find_segments_in_group("PIA", &["SG4", "SG8"], i);
1865                let article_id = pias
1866                    .iter()
1867                    .find(|s| {
1868                        s.elements
1869                            .first()
1870                            .and_then(|e| e.first())
1871                            .is_some_and(|v| v == "Z02")
1872                    })
1873                    .and_then(|s| s.elements.get(1))
1874                    .and_then(|e| e.first())
1875                    .cloned()
1876                    .unwrap_or_default();
1877                sg8_data.push((zid, article_id));
1878            }
1879        }
1880        for i in 0..sg8_data.len() {
1881            for j in (i + 1)..sg8_data.len() {
1882                if sg8_data[i].0 == sg8_data[j].0 {
1883                    let (id_i, id_j) = (&sg8_data[i].1, &sg8_data[j].1);
1884                    let i_is_002 = id_i == "1-02-0-002";
1885                    let j_is_002 = id_j == "1-02-0-002";
1886                    let i_is_003_004 = id_i == "1-02-0-003" || id_i == "1-02-0-004";
1887                    let j_is_003_004 = id_j == "1-02-0-003" || id_j == "1-02-0-004";
1888                    if (i_is_002 && j_is_003_004) || (j_is_002 && i_is_003_004) {
1889                        return ConditionResult::True;
1890                    }
1891                }
1892            }
1893        }
1894        if sg8_data.is_empty() {
1895            ConditionResult::Unknown
1896        } else {
1897            ConditionResult::False
1898        }
1899    }
1900
1901    /// [206] Wenn SG4 STS+7++ZG5 (Transaktionsgrund: Aufhebung der zukünftigen Zuordnung aufgrund § 38 EEG 2014 bzw. § 21b Abs. 1 Nr. 2 EEG 2017) nicht vorhanden
1902    fn evaluate_206(&self, ctx: &EvaluationContext) -> ConditionResult {
1903        match ctx.has_segment_matching("STS", &[(0, 0, "7"), (2, 0, "ZG5")]) {
1904            ConditionResult::True => ConditionResult::False,
1905            ConditionResult::False => ConditionResult::True,
1906            ConditionResult::Unknown => ConditionResult::Unknown,
1907        }
1908    }
1909
1910    /// [242] Wenn mehr als ein SG8 (Referenz auf die Lokationsbündelstruktur) mit der selben Zeitraum-ID im DE1050 vorhanden
1911    fn evaluate_242(&self, ctx: &EvaluationContext) -> ConditionResult {
1912        let nav = match ctx.navigator() {
1913            Some(n) => n,
1914            None => return ConditionResult::Unknown,
1915        };
1916        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1917        let mut ids: Vec<String> = Vec::new();
1918        for i in 0..sg8_count {
1919            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1920            for seq in &seq_segs {
1921                let qual = seq
1922                    .elements
1923                    .first()
1924                    .and_then(|e| e.first())
1925                    .map(|s| s.as_str());
1926                if matches!(qual, Some("Z78") | Some("ZC7") | Some("ZC8") | Some("ZD5")) {
1927                    if let Some(id) = seq.elements.get(1).and_then(|e| e.first()) {
1928                        if !id.is_empty() {
1929                            ids.push(id.clone());
1930                        }
1931                    }
1932                }
1933            }
1934        }
1935        if ids.is_empty() {
1936            return ConditionResult::Unknown;
1937        }
1938        let mut seen = std::collections::HashSet::new();
1939        ConditionResult::from(ids.iter().any(|id| !seen.insert(id.as_str())))
1940    }
1941
1942    /// [253] Wenn SG4 STS+E01++ZC9 (Ablehnung (keine Zuordnung möglich)) nicht vorhanden
1943    fn evaluate_253(&self, ctx: &EvaluationContext) -> ConditionResult {
1944        match ctx.has_segment_matching("STS", &[(0, 0, "E01"), (2, 0, "ZC9")]) {
1945            ConditionResult::True => ConditionResult::False,
1946            ConditionResult::False => ConditionResult::True,
1947            ConditionResult::Unknown => ConditionResult::Unknown,
1948        }
1949    }
1950
1951    /// [258] Wenn in dieser SG8 SEQ+Z01 (Daten der Marktlokation) SG10 CCI+Z30++Z07 (Verbrauch) vorhanden
1952    fn evaluate_258(&self, ctx: &EvaluationContext) -> ConditionResult {
1953        let nav = match ctx.navigator() {
1954            Some(n) => n,
1955            None => return ctx.has_qualified_value("CCI", 0, "Z30", 2, 0, &["Z07"]),
1956        };
1957        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1958        for i in 0..sg8_count {
1959            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1960            let has_z01 = seq_segs.iter().any(|s| {
1961                s.elements
1962                    .first()
1963                    .and_then(|e| e.first())
1964                    .is_some_and(|v| v == "Z01")
1965            });
1966            if has_z01 {
1967                let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
1968                for j in 0..sg10_count {
1969                    let ccis =
1970                        nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
1971                    if ccis.iter().any(|s| {
1972                        s.elements
1973                            .first()
1974                            .and_then(|e| e.first())
1975                            .is_some_and(|v| v == "Z30")
1976                            && s.elements
1977                                .get(2)
1978                                .and_then(|e| e.first())
1979                                .is_some_and(|v| v == "Z07")
1980                    }) {
1981                        return ConditionResult::True;
1982                    }
1983                }
1984            }
1985        }
1986        ConditionResult::False
1987    }
1988
1989    /// [297] Wenn mehr als eine SG8 SEQ+Z02/ ZE3 (OBIS- Daten der Marktlokation) mit einer OBIS-Kennzahl für Energiemenge im PIA+5, mit gleicher Zeitraum-ID und identischem Code im DE1229 des SG8 SEQ+Z02/ZA1/Z...
1990    // REVIEW: Find SG8 instances with SEQ qualifier Z02 or ZE3 that also have a PIA+5 segment. Collect (de1229_code, zeitraum_id) tuples. Condition is True when more than one such SG8 shares the same combination. Note: 'OBIS-Kennzahl für Energiemenge' filtering is not enforced here (would require knowledge of valid OBIS patterns), so presence of PIA+5 is used as a proxy. (medium confidence)
1991    fn evaluate_297(&self, ctx: &EvaluationContext) -> ConditionResult {
1992        let nav = match ctx.navigator() {
1993            Some(n) => n,
1994            None => return ConditionResult::Unknown,
1995        };
1996        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1997        // Collect (seq_qualifier, zeitraum_id) tuples from SG8 instances with SEQ+Z02/ZE3 that also have PIA+5
1998        let mut keys: Vec<(String, String)> = Vec::new();
1999        for i in 0..sg8_count {
2000            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2001            for seq in &seq_segs {
2002                let qual = seq
2003                    .elements
2004                    .first()
2005                    .and_then(|e| e.first())
2006                    .map(|s| s.as_str());
2007                if matches!(qual, Some("Z02") | Some("ZE3")) {
2008                    let pia_segs = nav.find_segments_in_group("PIA", &["SG4", "SG8"], i);
2009                    let has_pia5 = pia_segs.iter().any(|s| {
2010                        s.elements
2011                            .first()
2012                            .and_then(|e| e.first())
2013                            .is_some_and(|v| v == "5")
2014                    });
2015                    if has_pia5 {
2016                        let zeitraum_id = seq
2017                            .elements
2018                            .get(1)
2019                            .and_then(|e| e.first())
2020                            .cloned()
2021                            .unwrap_or_default();
2022                        if !zeitraum_id.is_empty() {
2023                            keys.push((qual.unwrap_or_default().to_string(), zeitraum_id));
2024                        }
2025                    }
2026                }
2027            }
2028        }
2029        if keys.is_empty() {
2030            return ConditionResult::Unknown;
2031        }
2032        let mut seen = std::collections::HashSet::new();
2033        ConditionResult::from(keys.iter().any(|k| !seen.insert(k)))
2034    }
2035
2036    /// [312] Wenn DTM+137 (Nachrichtendatum) im DE2380 &lt; 202603312200?+00
2037    fn evaluate_312(&self, ctx: &EvaluationContext) -> ConditionResult {
2038        ctx.dtm_lt("137", "202603312200+00")
2039    }
2040
2041    /// [313] Wenn DTM+137 (Nachrichtendatum) im DE2380 ≥ 202603312200?+00
2042    fn evaluate_313(&self, ctx: &EvaluationContext) -> ConditionResult {
2043        ctx.dtm_ge("137", "202603312200+00")
2044    }
2045
2046    /// [326] Wenn die Marktlokation nicht stillgelegt wird
2047    /// EXTERNAL: Requires context from outside the message.
2048    fn evaluate_326(&self, ctx: &EvaluationContext) -> ConditionResult {
2049        ctx.external.evaluate("market_location_not_decommissioned")
2050    }
2051
2052    /// [328] Wenn die Marktlokation stillgelegt wird
2053    /// EXTERNAL: Requires context from outside the message.
2054    fn evaluate_328(&self, ctx: &EvaluationContext) -> ConditionResult {
2055        ctx.external.evaluate("market_location_decommissioned")
2056    }
2057
2058    /// [346] Wenn SG10 CCI+++E13 (Zählertyp) CAV+MME (mME) in dieser SG8 vorhanden
2059    fn evaluate_346(&self, ctx: &EvaluationContext) -> ConditionResult {
2060        let nav = match ctx.navigator() {
2061            Some(n) => n,
2062            None => {
2063                // Fallback: message-wide check for both CCI+E13 and CAV+MME
2064                let has_cci = ctx.has_qualifier("CCI", 2, "E13");
2065                let has_cav = ctx.has_qualifier("CAV", 0, "MME");
2066                return match (has_cci, has_cav) {
2067                    (ConditionResult::True, ConditionResult::True) => ConditionResult::True,
2068                    (ConditionResult::False, _) | (_, ConditionResult::False) => {
2069                        ConditionResult::False
2070                    }
2071                    _ => ConditionResult::Unknown,
2072                };
2073            }
2074        };
2075        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2076        for i in 0..sg8_count {
2077            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
2078            for j in 0..sg10_count {
2079                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
2080                let has_cci_e13 = ccis.iter().any(|s| {
2081                    s.elements
2082                        .get(2)
2083                        .and_then(|e| e.first())
2084                        .is_some_and(|v| v == "E13")
2085                });
2086                if has_cci_e13 {
2087                    let cavs =
2088                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
2089                    if cavs.iter().any(|s| {
2090                        s.elements
2091                            .first()
2092                            .and_then(|e| e.first())
2093                            .is_some_and(|v| v == "MME")
2094                    }) {
2095                        return ConditionResult::True;
2096                    }
2097                }
2098            }
2099        }
2100        ConditionResult::False
2101    }
2102
2103    /// [387] Wenn in derselben SG8 (OBIS-Daten der Marktlokation) eine OBIS-Kennzahl für Energiemenge im PIA+5 vorhanden und es sich lt. Codeliste OBIS um eine OBIS mit zugeordneter Zählzeit handelt (Tarif: e...
2104    // REVIEW: Iterates SG8 instances that are OBIS-Daten der Marktlokation (SEQ+Z02/ZA1/ZA2/ZE3), then for each finds PIA+5 and parses the OBIS string to extract the E value (Tarif/Zählzeit field at index 2 after splitting C.D.E by '.'). Returns True if E is in range 1–62, indicating a Zählzeit-differentiated (tariff-associated) OBIS. Medium confidence because the 'Energiemenge' semantic (C value should indicate energy quantity) is not fully validated — only the E=1..62 Zählzeit criterion stated in the condition text is checked. (medium confidence)
2105    fn evaluate_387(&self, ctx: &EvaluationContext) -> ConditionResult {
2106        let nav = match ctx.navigator() {
2107            Some(n) => n,
2108            None => return ConditionResult::Unknown,
2109        };
2110        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2111        for i in 0..sg8_count {
2112            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2113            let is_obis_malo = seq_segs.iter().any(|s| {
2114                s.elements
2115                    .first()
2116                    .and_then(|e| e.first())
2117                    .is_some_and(|v| matches!(v.as_str(), "Z02" | "ZA1" | "ZA2" | "ZE3"))
2118            });
2119            if !is_obis_malo {
2120                continue;
2121            }
2122            let pia_segs = nav.find_segments_in_group("PIA", &["SG4", "SG8"], i);
2123            for pia in &pia_segs {
2124                if !pia
2125                    .elements
2126                    .first()
2127                    .and_then(|e| e.first())
2128                    .is_some_and(|v| v == "5")
2129                {
2130                    continue;
2131                }
2132                let obis = match pia.elements.get(1).and_then(|e| e.first()) {
2133                    Some(o) => o.as_str(),
2134                    None => continue,
2135                };
2136                // OBIS format: A-B:C.D.E*F — extract E (Tarif/Zählzeit) as split('.')[2] after ':'
2137                let after_colon = obis.find(':').map(|p| &obis[p + 1..]).unwrap_or(obis);
2138                let parts: Vec<&str> = after_colon.split('.').collect();
2139                if parts.len() >= 3 {
2140                    let e_str = parts[2].split('*').next().unwrap_or("");
2141                    if let Ok(e_val) = e_str.parse::<u32>() {
2142                        if e_val >= 1 && e_val <= 62 {
2143                            return ConditionResult::True;
2144                        }
2145                    }
2146                }
2147            }
2148        }
2149        ConditionResult::False
2150    }
2151
2152    /// [399] Wenn im SG8 SEQ+Z78 mit identischer Zeitraum-ID im DE1050 wie im DE3224 dieses Segments, das RFF+Z31 (Lokationsbündelstruktur) im DE1153 der Code Z31 (Lokationsbündelstruktur) vorhanden, und im D...
2153    fn evaluate_399(&self, _ctx: &EvaluationContext) -> ConditionResult {
2154        // TODO: Condition [399] requires manual implementation
2155        // Reason: Requires cross-group Zeitraum-ID matching: the SEQ+Z78 DE1050 value must equal DE3224 of 'dieses Segments'. The phrase 'dieses Segments' implies the condition is evaluated in the context of a specific segment instance (likely a SG5/SG6 LOC or RFF) whose Zeitraum-ID is to be compared — this runtime per-segment context is not available in the message-wide EvaluationContext. The RFF+Z31 value check (not equal to '9992 00000 001 8') is individually implementable, but without the Zeitraum-ID anchor the result would be incorrect for most PIDs.
2156        ConditionResult::Unknown
2157    }
2158
2159    /// [413] Wenn eine SG8 SEQ+Z02/ZA1/ZA2 (OBIS-Daten der Marktlokation) mit einer OBIS-Kennzahl für Wirkarbeit und kumuliert im PIA+5, mit gleicher Zeitraum-ID und identischem Code im DE1229 des SG8 SEQ+Z02/...
2160    fn evaluate_413(&self, _ctx: &EvaluationContext) -> ConditionResult {
2161        // TODO: Condition [413] requires manual implementation
2162        // Reason: Requires knowing the 'current SG8' instance being validated: the condition checks whether another SG8 with SEQ+Z02/ZA1/ZA2, same Zeitraum-ID (SEQ DE1050), and identical DE1229 code as the current SG8 exists and has a Wirkarbeit+kumuliert OBIS (C=1/2, D=8) in PIA+5. The 'same Zeitraum-ID and identical DE1229 code as the current SG8' comparison requires per-instance context not available in EvaluationContext. A message-wide existence check would produce false positives by ignoring the Zeitraum-ID/code correlation constraint.
2163        ConditionResult::Unknown
2164    }
2165
2166    /// [414] Wenn keine SG8 SEQ+Z02/ZA1/ZA2 (OBIS-Daten der Marktlokation) mit einer OBIS-Kennzahl für Wirkarbeit und kumuliert im PIA+5, mit gleicher Zeitraum-ID und identischem Code im DE1229 des SG8 SEQ+Z02...
2167    fn evaluate_414(&self, _ctx: &EvaluationContext) -> ConditionResult {
2168        // TODO: Condition [414] requires manual implementation
2169        // Reason: Negation of condition [413]. Same structural complexity: requires 'current SG8' context to verify that no other SG8 with matching Zeitraum-ID (SEQ DE1050) and same DE1229 code has a Wirkarbeit+kumuliert OBIS in PIA+5. Cannot be correctly implemented without the per-instance current SG8 reference.
2170        ConditionResult::Unknown
2171    }
2172
2173    /// [415] Wenn eine weitere SG8 SEQ+Z02/ZA1/ZA2 (OBIS-Daten der Marktlokation) mit einer OBIS-Kennzahl für Wirkarbeit und 1/4 Stunde im PIA+5, mit gleicher Zeitraum-ID und identischem Code im DE1229 des SG8...
2174    fn evaluate_415(&self, _ctx: &EvaluationContext) -> ConditionResult {
2175        // TODO: Condition [415] requires manual implementation
2176        // Reason: Analogous to condition [413] but targets Wirkarbeit+1/4 Stunde (OBIS D=5, quarter-hour interval measurement) instead of kumuliert (D=8). Requires the same 'current SG8' context for Zeitraum-ID and DE1229 code matching against another SG8 instance. Cannot be implemented correctly without per-instance evaluation context.
2177        ConditionResult::Unknown
2178    }
2179
2180    /// [416] Wenn keine SG8 SEQ+Z02/ZA1/ZA2 (OBIS-Daten der Marktlokation) mit einer OBIS-Kennzahl für Wirkarbeit und 1/4 Stunde im PIA+5, mit gleicher Zeitraum-ID und identischem Code im DE1229 des SG8 SEQ+Z0...
2181    fn evaluate_416(&self, _ctx: &EvaluationContext) -> ConditionResult {
2182        // TODO: Condition [416] requires manual implementation
2183        // Reason: This condition requires checking for absence of an SG8 SEQ+Z02/ZA1/ZA2 group that contains a PIA+5 with an OBIS code specifically representing 'Wirkarbeit und 1/4 Stunde'. Determining which OBIS code patterns qualify as 'Wirkarbeit' (active energy) and '1/4 Stunde' (15-minute granularity) requires domain-specific knowledge about OBIS code structure not derivable from the MIG schema alone. The cross-group Zeitraum-ID matching adds further complexity. Cannot implement reliably without an authoritative list of qualifying OBIS code patterns.
2184        ConditionResult::Unknown
2185    }
2186
2187    /// [461] Wenn in derselben SG10 das CCI (Art und Nutzung der Technischen Ressource) im CAV+ZG8 (Technischen Ressource fällt unter § 14a EnWG) vorhanden
2188    fn evaluate_461(&self, ctx: &EvaluationContext) -> ConditionResult {
2189        // Wenn in derselben SG10 das CCI (Art und Nutzung der Technischen Ressource)
2190        // im CAV+ZG8 (Technische Ressource fällt unter § 14a EnWG) vorhanden
2191        // CCI is the SG10 entry segment; condition reduces to: any SG10 has CAV with ZG8
2192        ctx.any_group_has_qualifier("CAV", 0, "ZG8", &["SG4", "SG8", "SG10"])
2193    }
2194
2195    /// [517] Hinweis: Anzuwenden, wenn einer Marktlokation eine Paket-ID zugeordnet wurde und diese wieder gelöscht werden soll, da sie nicht unter den genannten NB-Wechsel fällt
2196    fn evaluate_517(&self, _ctx: &EvaluationContext) -> ConditionResult {
2197        // Hinweis: Anzuwenden, wenn einer Marktlokation eine Paket-ID zugeordnet wurde
2198        // und diese wieder gelöscht werden soll, da sie nicht unter den genannten
2199        // NB-Wechsel fällt — informational note, always applies
2200        ConditionResult::True
2201    }
2202
2203    /// [534] Hinweis: Aufgrund der Wiederholbarkeit des SG4 STS Status der Antwort ist die Angabe von max. acht Verwendungszeiträumen möglich
2204    fn evaluate_534(&self, _ctx: &EvaluationContext) -> ConditionResult {
2205        // Hinweis: Aufgrund der Wiederholbarkeit des SG4 STS Status der Antwort ist
2206        // die Angabe von max. acht Verwendungszeiträumen möglich
2207        // — informational note about cardinality, always applies
2208        ConditionResult::True
2209    }
2210
2211    /// [557] Hinweis: Wurden vom Verantwortlichen mehr als acht Verwendungszeiträume gesendet, so werden acht beliebige Verwendungszeiträume beantwortet
2212    fn evaluate_557(&self, _ctx: &EvaluationContext) -> ConditionResult {
2213        // Hinweis: Wurden vom Verantwortlichen mehr als acht Verwendungszeiträume
2214        // gesendet, so werden acht beliebige Verwendungszeiträume beantwortet
2215        // — informational processing note, always applies
2216        ConditionResult::True
2217    }
2218
2219    /// [560] Hinweis: Dies entspricht dem Geschäftsvorfall A
2220    fn evaluate_560(&self, _ctx: &EvaluationContext) -> ConditionResult {
2221        // Hinweis: Dies entspricht dem Geschäftsvorfall A — informational note, always applies
2222        ConditionResult::True
2223    }
2224
2225    /// [561] Hinweis: Dies entspricht dem Geschäftsvorfall B
2226    fn evaluate_561(&self, _ctx: &EvaluationContext) -> ConditionResult {
2227        // Hinweis: Dies entspricht dem Geschäftsvorfall B — informational note, always applies
2228        ConditionResult::True
2229    }
2230
2231    /// [562] Hinweis: Bei Marktlokationen, welche auf Basis von Werten bilanziert werden, wird der erste Tag des Jahres angegeben.
2232    fn evaluate_562(&self, _ctx: &EvaluationContext) -> ConditionResult {
2233        // Hinweis: Bei Marktlokationen, welche auf Basis von Werten bilanziert werden, wird der erste Tag des Jahres angegeben — informational note, always applies
2234        ConditionResult::True
2235    }
2236
2237    /// [564] Hinweis: Das IDE+Z01 (Liste) definiert den Geschäftsvorfall. Alle aufgelisteten IDE+24 sind Bestandteil des Geschäftsvorfalls
2238    fn evaluate_564(&self, _ctx: &EvaluationContext) -> ConditionResult {
2239        // Hinweis: Das IDE+Z01 (Liste) definiert den Geschäftsvorfall. Alle aufgelisteten IDE+24 sind Bestandteil des Geschäftsvorfalls — informational note, always applies
2240        ConditionResult::True
2241    }
2242
2243    /// [565] Hinweis: Das IDE+24 beschreibt einen Bestandteil einer Liste, wenn ein IDE+Z01 vorhanden ist. Es beschreibt nicht den Geschäftsvorfall
2244    fn evaluate_565(&self, _ctx: &EvaluationContext) -> ConditionResult {
2245        // Hinweis: Das IDE+24 beschreibt einen Bestandteil einer Liste, wenn ein IDE+Z01 vorhanden ist. Es beschreibt nicht den Geschäftsvorfall — informational note, always applies
2246        ConditionResult::True
2247    }
2248
2249    /// [578] Hinweis: Dies gilt für den Zeitraum welcher mit Z53 (keine Daten) definiert ist
2250    fn evaluate_578(&self, _ctx: &EvaluationContext) -> ConditionResult {
2251        // Hinweis: Dies gilt für den Zeitraum welcher mit Z53 (keine Daten) definiert ist — informational note, always applies
2252        ConditionResult::True
2253    }
2254
2255    /// [580] Hinweis:  Ersatzbelieferung gibt es nur bei  - Marktlokationen in der Niederspannung, die kein Haushaltskunde gem. EnWG sind und die nicht mehr der gesetzlichen Ersatzversorgung (drei Monate) unter...
2256    fn evaluate_580(&self, _ctx: &EvaluationContext) -> ConditionResult {
2257        // Hinweis: Ersatzbelieferung context note (Niederspannung non-household / Mittelspannung/Hochspannung) — informational note, always applies
2258        ConditionResult::True
2259    }
2260
2261    /// [681] Hinweis: Übergangsversorgung gibt es nur bei Marktlokationen, die unter § 38a EnWG fallen. Grundlage ist eine bilaterale Vereinbarung
2262    fn evaluate_681(&self, _ctx: &EvaluationContext) -> ConditionResult {
2263        // Hinweis: Übergangsversorgung applies only to Marktlokationen under § 38a EnWG based on bilateral agreement — informational note, always applies
2264        ConditionResult::True
2265    }
2266
2267    /// [686] Hinweis: Zu verwenden bei der Abmeldung der Übergangsversorgung.
2268    fn evaluate_686(&self, _ctx: &EvaluationContext) -> ConditionResult {
2269        // Hinweis: Zu verwenden bei der Abmeldung der Übergangsversorgung — informational note, always applies
2270        ConditionResult::True
2271    }
2272
2273    /// [2000] Je SG5 LOC+Z16 (Marktlokation) ist genau einmal die Segmentgruppe anzugeben
2274    // REVIEW: Checks that per SG4 transaction group, exactly one SG5 child group contains a LOC segment with qualifier Z16 (Marktlokation). Uses parent-child navigator to iterate SG4 instances and count LOC+Z16 occurrences in their SG5 children. Falls back to message-wide count when no navigator is available. (medium confidence)
2275    fn evaluate_2000(&self, ctx: &EvaluationContext) -> ConditionResult {
2276        // Je SG5 LOC+Z16 (Marktlokation) ist genau einmal die Segmentgruppe anzugeben
2277        // Per SG4 transaction group, exactly one SG5 instance should contain LOC+Z16
2278        let nav = match ctx.navigator() {
2279            Some(n) => n,
2280            None => {
2281                let count = ctx.count_qualified_in_group("LOC", 0, "Z16", &["SG4", "SG5"]);
2282                return ConditionResult::from(count == 1);
2283            }
2284        };
2285        let sg4_count = nav.group_instance_count(&["SG4"]);
2286        if sg4_count == 0 {
2287            return ConditionResult::Unknown;
2288        }
2289        for i in 0..sg4_count {
2290            let sg5_count = nav.child_group_instance_count(&["SG4"], i, "SG5");
2291            let mut loc_z16_count = 0usize;
2292            for j in 0..sg5_count {
2293                let locs = nav.find_segments_in_child_group("LOC", &["SG4"], i, "SG5", j);
2294                for loc in &locs {
2295                    if loc
2296                        .elements
2297                        .first()
2298                        .and_then(|e| e.first())
2299                        .is_some_and(|v| v == "Z16")
2300                    {
2301                        loc_z16_count += 1;
2302                    }
2303                }
2304            }
2305            if loc_z16_count != 1 {
2306                return ConditionResult::False;
2307            }
2308        }
2309        ConditionResult::True
2310    }
2311
2312    /// [2006] Segmentgruppe ist genau einmal für jede SG8 SEQ+Z01 (Daten der Marktlokation) anzugeben, bei der die Bedingung [199] an der Segmentgruppe erfüllt ist. Dabei ist die selbe Zeitraum-ID im nachfolge...
2313    // REVIEW: Condition 2006 requires the segment group to appear exactly once for each SG8 SEQ+Z01 where condition [199] is fulfilled, with matching Zeitraum-ID (SEQ DE1050). Implementation: collect Zeitraum-IDs from qualifying SG8s, then verify each appears exactly once across SG8 SEQ groups. Medium confidence because the exact 'current group' path is not directly accessible — we approximate via Zeitraum-ID uniqueness across all SG8 SEQ instances. (medium confidence)
2314    fn evaluate_2006(&self, ctx: &EvaluationContext) -> ConditionResult {
2315        let nav = match ctx.navigator() {
2316            Some(n) => n,
2317            None => return ConditionResult::Unknown,
2318        };
2319        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2320        let mut qualifying_zeitraum_ids: Vec<String> = Vec::new();
2321        for i in 0..sg8_count {
2322            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2323            let z01_seq = seq_segs.iter().find(|s| {
2324                s.elements
2325                    .first()
2326                    .and_then(|e| e.first())
2327                    .is_some_and(|v| v == "Z01")
2328            });
2329            if let Some(seq) = z01_seq {
2330                if self.evaluate(199, ctx).is_true() {
2331                    if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2332                        if !zeitraum_id.is_empty() {
2333                            qualifying_zeitraum_ids.push(zeitraum_id.clone());
2334                        }
2335                    }
2336                }
2337            }
2338        }
2339        if qualifying_zeitraum_ids.is_empty() {
2340            return ConditionResult::Unknown;
2341        }
2342        // Verify each qualifying Zeitraum-ID appears exactly once across all SG8 SEQ groups
2343        let mut id_counts: std::collections::HashMap<String, usize> =
2344            std::collections::HashMap::new();
2345        for i in 0..sg8_count {
2346            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2347            for seq in &seq_segs {
2348                if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2349                    if !zeitraum_id.is_empty() && qualifying_zeitraum_ids.contains(zeitraum_id) {
2350                        *id_counts.entry(zeitraum_id.clone()).or_insert(0) += 1;
2351                    }
2352                }
2353            }
2354        }
2355        ConditionResult::from(
2356            qualifying_zeitraum_ids
2357                .iter()
2358                .all(|id| id_counts.get(id).copied().unwrap_or(0) == 1),
2359        )
2360    }
2361
2362    /// [2007] Segmentgruppe ist genau einmal für jede SG8 SEQ+Z01 (Daten der Marktlokation) anzugeben, bei der die Bedingungen [199] an der Segmentgruppe erfüllt ist. Dabei ist die selbe Zeitraum-ID im nachfol...
2363    // REVIEW: Condition 2007 is semantically identical to 2006 — the only difference is grammatical (plural 'Bedingungen' vs singular 'Bedingung'). Same logic: exactly once per qualifying SG8 SEQ+Z01 where condition [199] is met, with matching Zeitraum-ID. (medium confidence)
2364    fn evaluate_2007(&self, ctx: &EvaluationContext) -> ConditionResult {
2365        let nav = match ctx.navigator() {
2366            Some(n) => n,
2367            None => return ConditionResult::Unknown,
2368        };
2369        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2370        let mut qualifying_zeitraum_ids: Vec<String> = Vec::new();
2371        for i in 0..sg8_count {
2372            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2373            let z01_seq = seq_segs.iter().find(|s| {
2374                s.elements
2375                    .first()
2376                    .and_then(|e| e.first())
2377                    .is_some_and(|v| v == "Z01")
2378            });
2379            if let Some(seq) = z01_seq {
2380                if self.evaluate(199, ctx).is_true() {
2381                    if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2382                        if !zeitraum_id.is_empty() {
2383                            qualifying_zeitraum_ids.push(zeitraum_id.clone());
2384                        }
2385                    }
2386                }
2387            }
2388        }
2389        if qualifying_zeitraum_ids.is_empty() {
2390            return ConditionResult::Unknown;
2391        }
2392        let mut id_counts: std::collections::HashMap<String, usize> =
2393            std::collections::HashMap::new();
2394        for i in 0..sg8_count {
2395            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2396            for seq in &seq_segs {
2397                if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2398                    if !zeitraum_id.is_empty() && qualifying_zeitraum_ids.contains(zeitraum_id) {
2399                        *id_counts.entry(zeitraum_id.clone()).or_insert(0) += 1;
2400                    }
2401                }
2402            }
2403        }
2404        ConditionResult::from(
2405            qualifying_zeitraum_ids
2406                .iter()
2407                .all(|id| id_counts.get(id).copied().unwrap_or(0) == 1),
2408        )
2409    }
2410
2411    /// [2008] Segmentgruppe ist genau einmal für jede SG8 SEQ+Z01 (Daten der Marktlokation) anzugeben, bei der die Bedingung [89] an der Segmentgruppe erfüllt ist. Dabei ist die selbe Zeitraum-ID im nachfolgen...
2412    // REVIEW: Condition 2008 is the same structure as 2006/2007 but references condition [89] instead of [199]. Exactly once per SG8 SEQ+Z01 where condition [89] is fulfilled, with matching Zeitraum-ID in SEQ DE1050. (medium confidence)
2413    fn evaluate_2008(&self, ctx: &EvaluationContext) -> ConditionResult {
2414        let nav = match ctx.navigator() {
2415            Some(n) => n,
2416            None => return ConditionResult::Unknown,
2417        };
2418        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2419        let mut qualifying_zeitraum_ids: Vec<String> = Vec::new();
2420        for i in 0..sg8_count {
2421            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2422            let z01_seq = seq_segs.iter().find(|s| {
2423                s.elements
2424                    .first()
2425                    .and_then(|e| e.first())
2426                    .is_some_and(|v| v == "Z01")
2427            });
2428            if let Some(seq) = z01_seq {
2429                if self.evaluate(89, ctx).is_true() {
2430                    if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2431                        if !zeitraum_id.is_empty() {
2432                            qualifying_zeitraum_ids.push(zeitraum_id.clone());
2433                        }
2434                    }
2435                }
2436            }
2437        }
2438        if qualifying_zeitraum_ids.is_empty() {
2439            return ConditionResult::Unknown;
2440        }
2441        let mut id_counts: std::collections::HashMap<String, usize> =
2442            std::collections::HashMap::new();
2443        for i in 0..sg8_count {
2444            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2445            for seq in &seq_segs {
2446                if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2447                    if !zeitraum_id.is_empty() && qualifying_zeitraum_ids.contains(zeitraum_id) {
2448                        *id_counts.entry(zeitraum_id.clone()).or_insert(0) += 1;
2449                    }
2450                }
2451            }
2452        }
2453        ConditionResult::from(
2454            qualifying_zeitraum_ids
2455                .iter()
2456                .all(|id| id_counts.get(id).copied().unwrap_or(0) == 1),
2457        )
2458    }
2459
2460    /// [2009] Segmentgruppe ist genau einmal für jede SG8 SEQ+Z01 (Daten der Marktlokation) anzugeben, bei der die Bedingungen [89] an der Segmentgruppe erfüllt ist. Dabei ist die selbe Zeitraum-ID im nachfolg...
2461    // REVIEW: Condition 2009 is the plural-grammar variant of 2008 ('Bedingungen' vs 'Bedingung'), semantically identical. Same implementation as 2008 referencing condition [89]. (medium confidence)
2462    fn evaluate_2009(&self, ctx: &EvaluationContext) -> ConditionResult {
2463        let nav = match ctx.navigator() {
2464            Some(n) => n,
2465            None => return ConditionResult::Unknown,
2466        };
2467        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2468        let mut qualifying_zeitraum_ids: Vec<String> = Vec::new();
2469        for i in 0..sg8_count {
2470            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2471            let z01_seq = seq_segs.iter().find(|s| {
2472                s.elements
2473                    .first()
2474                    .and_then(|e| e.first())
2475                    .is_some_and(|v| v == "Z01")
2476            });
2477            if let Some(seq) = z01_seq {
2478                if self.evaluate(89, ctx).is_true() {
2479                    if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2480                        if !zeitraum_id.is_empty() {
2481                            qualifying_zeitraum_ids.push(zeitraum_id.clone());
2482                        }
2483                    }
2484                }
2485            }
2486        }
2487        if qualifying_zeitraum_ids.is_empty() {
2488            return ConditionResult::Unknown;
2489        }
2490        let mut id_counts: std::collections::HashMap<String, usize> =
2491            std::collections::HashMap::new();
2492        for i in 0..sg8_count {
2493            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2494            for seq in &seq_segs {
2495                if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2496                    if !zeitraum_id.is_empty() && qualifying_zeitraum_ids.contains(zeitraum_id) {
2497                        *id_counts.entry(zeitraum_id.clone()).or_insert(0) += 1;
2498                    }
2499                }
2500            }
2501        }
2502        ConditionResult::from(
2503            qualifying_zeitraum_ids
2504                .iter()
2505                .all(|id| id_counts.get(id).copied().unwrap_or(0) == 1),
2506        )
2507    }
2508
2509    /// [2011] Segmentgruppe ist genau einmal für jede Zeitraum-ID aus dem DE1156 der SG6 RFF+Z49 / Z53 (Verwendungszeitraum der Daten: "Gültige Daten" / "Keine Daten") aus der Anfragennachricht aus SG6 RFF+TN ...
2510    // REVIEW: Condition 2011 requires the group to appear exactly once for each Zeitraum-ID from DE1156 of SG6 RFF+Z49/Z53 (Verwendungszeitraum 'Gültige Daten'/'Keine Daten') as referenced by the request message (via SG6 RFF+TN). Implementation collects DE1156 values (elements[0][2]) from SG6 RFF with Z49 or Z53 qualifiers. Returns True when qualifying Zeitraum-IDs are found (indicating the group should exist). Medium confidence because the 'aus der Anfragenachricht' cross-message reference cannot be fully verified within a single message context. (medium confidence)
2511    fn evaluate_2011(&self, ctx: &EvaluationContext) -> ConditionResult {
2512        let nav = match ctx.navigator() {
2513            Some(n) => n,
2514            None => {
2515                // Fallback: check message-wide RFF+Z49/Z53 for DE1156 Zeitraum-IDs
2516                let rff_segs = ctx.find_segments("RFF");
2517                let has_qualifying = rff_segs.iter().any(|s| {
2518                    let qual = s
2519                        .elements
2520                        .first()
2521                        .and_then(|e| e.first())
2522                        .map(|v| v.as_str());
2523                    matches!(qual, Some("Z49") | Some("Z53"))
2524                        && s.elements
2525                            .first()
2526                            .and_then(|e| e.get(2))
2527                            .is_some_and(|v| !v.is_empty())
2528                });
2529                return if has_qualifying {
2530                    ConditionResult::True
2531                } else {
2532                    ConditionResult::Unknown
2533                };
2534            }
2535        };
2536        let sg6_count = nav.group_instance_count(&["SG4", "SG6"]);
2537        let mut zeitraum_ids: std::collections::HashSet<String> = std::collections::HashSet::new();
2538        for i in 0..sg6_count {
2539            let rff_segs = nav.find_segments_in_group("RFF", &["SG4", "SG6"], i);
2540            for rff in &rff_segs {
2541                let qual = rff
2542                    .elements
2543                    .first()
2544                    .and_then(|e| e.first())
2545                    .map(|s| s.as_str());
2546                if matches!(qual, Some("Z49") | Some("Z53")) {
2547                    // DE1156 is elements[0][2]
2548                    if let Some(zeitraum_id) = rff.elements.first().and_then(|e| e.get(2)) {
2549                        if !zeitraum_id.is_empty() {
2550                            zeitraum_ids.insert(zeitraum_id.clone());
2551                        }
2552                    }
2553                }
2554            }
2555        }
2556        if zeitraum_ids.is_empty() {
2557            return ConditionResult::Unknown;
2558        }
2559        // The segment group should appear exactly once per distinct Zeitraum-ID from SG6 RFF+Z49/Z53
2560        // We verify that qualifying Zeitraum-IDs are present — cardinality enforcement is structural
2561        ConditionResult::True
2562    }
2563
2564    /// [2013] Mindesten einmal anzugeben, wenn kein SG6 RFF+Z54 (Verwendungszeitraum der Daten: Im System keine Daten vorhanden) vorhanden
2565    fn evaluate_2013(&self, ctx: &EvaluationContext) -> ConditionResult {
2566        // Mindestens einmal anzugeben, wenn kein SG6 RFF+Z54 vorhanden
2567        // True when RFF+Z54 (Verwendungszeitraum: Im System keine Daten vorhanden) is absent
2568        ctx.lacks_qualifier("RFF", 0, "Z54")
2569    }
2570
2571    /// [2014] Mindesten einmal anzugeben, wenn kein SG6 RFF+Z47 (Verwendungszeitraum der Daten: Im System vorhandene Daten) vorhanden
2572    fn evaluate_2014(&self, ctx: &EvaluationContext) -> ConditionResult {
2573        // Mindestens einmal anzugeben, wenn kein SG6 RFF+Z47 vorhanden
2574        // True when RFF+Z47 (Verwendungszeitraum: Im System vorhandene Daten) is absent
2575        ctx.lacks_qualifier("RFF", 0, "Z47")
2576    }
2577
2578    /// [2016] Segmentgruppe ist mind. einmal für jede Zeitraum-ID aus dem DE1156 der SG6 RFF+Z49 / Z53 (Verwendungszeitraum der Daten: "Gültige Daten" / "Keine Daten") aus der Anfragennachricht aus SG6 RFF+TN ...
2579    // REVIEW: Cross-group Zeitraum-ID correlation: collect DE1156 values from SG6 RFF+Z49/Z53, verify each is covered by at least one SG8 SEQ's DE1050 reference. The mention of 'Anfragenachricht' (request message) and RFF+TN adds ambiguity about whether the source is this message or an external one; implemented as intra-message check on the most direct interpretation. (medium confidence)
2580    fn evaluate_2016(&self, ctx: &EvaluationContext) -> ConditionResult {
2581        // Segmentgruppe ist mind. einmal für jede Zeitraum-ID aus DE1156 der SG6 RFF+Z49/Z53 anzugeben
2582        // Collect Zeitraum-IDs from SG6 RFF+Z49 and Z53 (DE1156 = elements[0][2])
2583        // Then verify each required Zeitraum-ID is referenced by at least one SG8 SEQ (DE1050 = elements[1][0])
2584        let nav = match ctx.navigator() {
2585            Some(n) => n,
2586            None => return ConditionResult::Unknown,
2587        };
2588        let sg6_count = nav.group_instance_count(&["SG4", "SG6"]);
2589        let mut required_ids: std::collections::HashSet<String> = std::collections::HashSet::new();
2590        for i in 0..sg6_count {
2591            let rffs = nav.find_segments_in_group("RFF", &["SG4", "SG6"], i);
2592            for rff in &rffs {
2593                let qual = rff
2594                    .elements
2595                    .first()
2596                    .and_then(|e| e.first())
2597                    .map(|s| s.as_str());
2598                if matches!(qual, Some("Z49") | Some("Z53")) {
2599                    if let Some(zeitraum_id) = rff.elements.first().and_then(|e| e.get(2)) {
2600                        if !zeitraum_id.is_empty() {
2601                            required_ids.insert(zeitraum_id.clone());
2602                        }
2603                    }
2604                }
2605            }
2606        }
2607        if required_ids.is_empty() {
2608            return ConditionResult::Unknown;
2609        }
2610        // Check that for each required Zeitraum-ID at least one SG8 SEQ references it via DE1050
2611        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2612        let mut found_ids: std::collections::HashSet<String> = std::collections::HashSet::new();
2613        for i in 0..sg8_count {
2614            let seqs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2615            for seq in &seqs {
2616                if let Some(ref_id) = seq.elements.get(1).and_then(|e| e.first()) {
2617                    if !ref_id.is_empty() {
2618                        found_ids.insert(ref_id.clone());
2619                    }
2620                }
2621            }
2622        }
2623        ConditionResult::from(required_ids.iter().all(|id| found_ids.contains(id)))
2624    }
2625
2626    /// [2121] Segmentgruppe ist genau einmal je SG8 SEQ+Z01/ Z80/Z81 (Daten der Marktlokation/ Erwartete Daten der Marktlokation/ Im System vorhandene Daten der Marktlokation) anzugeben
2627    // REVIEW: Cardinality condition: this segment group must appear exactly once per qualifying SG8 (those with SEQ+Z01/Z80/Z81 — Daten/Erwartete Daten/Im System vorhandene Daten der Marktlokation). As a boolean predicate the condition evaluates True when such qualifying SG8 instances exist, signalling that the subject segment group is required. Full cardinality validation (exactly-once enforcement) requires the broader validator framework. (medium confidence)
2628    fn evaluate_2121(&self, ctx: &EvaluationContext) -> ConditionResult {
2629        // Segmentgruppe ist genau einmal je SG8 SEQ+Z01/Z80/Z81 anzugeben
2630        // True when at least one SG8 with SEQ+Z01, Z80, or Z81 exists (cardinality trigger)
2631        ctx.any_group_has_any_qualifier("SEQ", 0, &["Z01", "Z80", "Z81"], &["SG4", "SG8"])
2632    }
2633
2634    /// [1] Wenn Aufteilung vorhanden
2635    fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
2636        ctx.external.evaluate("message_splitting")
2637    }
2638
2639    /// [4] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF
2640    fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
2641        ctx.external.evaluate("recipient_is_lf")
2642    }
2643
2644    /// [5] Wenn MP-ID in SG2 NAD+MS (Nachrichtenabsender) in der Rolle LF
2645    fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
2646        ctx.external.evaluate("sender_is_lf")
2647    }
2648
2649    /// [6] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle ÜNB
2650    fn evaluate_6(&self, ctx: &EvaluationContext) -> ConditionResult {
2651        ctx.external.evaluate("recipient_role_check")
2652    }
2653
2654    /// [7] Wenn SG4 STS+7++ZG9/ZH1/ZH2 (Transaktionsgrund: Aufhebung einer zukünftigen Zuordnung wegen Auszug des Kunden / -wegen Stilllegung / -wegen aufgehobenem Vertragsverhältnis) vorhanden
2655    fn evaluate_7(&self, _ctx: &EvaluationContext) -> ConditionResult {
2656        // TODO: implement
2657        ConditionResult::Unknown
2658    }
2659
2660    /// [8] Wenn für Datenclearing erforderlich
2661    fn evaluate_8(&self, ctx: &EvaluationContext) -> ConditionResult {
2662        ctx.external.evaluate("data_clearing_required")
2663    }
2664
2665    /// [9] Wenn MP-ID in SG2 NAD+MS (Nachrichtenabsender) in der Rolle MSB
2666    fn evaluate_9(&self, ctx: &EvaluationContext) -> ConditionResult {
2667        ctx.external.evaluate("sender_role_check")
2668    }
2669
2670    /// [10] Wenn SG4 STS+7++xxx+xxx+E01/E03 (Transaktionsgrund befristete Anmeldung) vorhanden
2671    fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
2672        // STS+7++E01+ZW4+E03: element[4] is c556_3.d9013 = transaktionsgrundErgaenzungBefristeteAnmeldung
2673        ctx.has_qualified_value("STS", 0, "7", 4, 0, &["E01", "E03"])
2674    }
2675
2676    /// [11] Wenn SG4 STS+7++ZG9/ZH1/ZH2 (Transaktionsgrund: Aufhebung einer zukünftigen Zuordnung wegen Auszug des Kunden / -wegen Stilllegung / -wegen aufgehobenem Vertragsverhältnis) nicht vorhanden
2677    fn evaluate_11(&self, _ctx: &EvaluationContext) -> ConditionResult {
2678        // TODO: implement
2679        ConditionResult::Unknown
2680    }
2681
2682    /// [12] Wenn SG4 DTM+471 (Ende zum nächstmöglichem Termin) nicht vorhanden
2683    fn evaluate_12(&self, _ctx: &EvaluationContext) -> ConditionResult {
2684        // TODO: implement
2685        ConditionResult::Unknown
2686    }
2687
2688    /// [13] Wenn SG4 STS+E01++Z01 (Status der Antwort: Zustimmung mit Terminänderung) nicht vorhanden
2689    fn evaluate_13(&self, _ctx: &EvaluationContext) -> ConditionResult {
2690        // TODO: implement
2691        ConditionResult::Unknown
2692    }
2693
2694    /// [14] Wenn Datum bekannt
2695    fn evaluate_14(&self, ctx: &EvaluationContext) -> ConditionResult {
2696        ctx.external.evaluate("date_known")
2697    }
2698
2699    /// [15] Wenn in derselben SG8 das SEQ+Z98 (Informative Daten der Marktlokation) vorhanden
2700    fn evaluate_15(&self, _ctx: &EvaluationContext) -> ConditionResult {
2701        // TODO: implement
2702        ConditionResult::Unknown
2703    }
2704
2705    /// [16] Wenn SG4 STS+E01++Z12 (Status der Antwort: Ablehnung Vertragsbindung) vorhanden
2706    fn evaluate_16(&self, _ctx: &EvaluationContext) -> ConditionResult {
2707        // TODO: implement
2708        ConditionResult::Unknown
2709    }
2710
2711    /// [17] Wenn in derselben SG8 das SEQ+Z01/Z80/Z81 (Daten der Marktlokation) vorhanden
2712    fn evaluate_17(&self, _ctx: &EvaluationContext) -> ConditionResult {
2713        // TODO: implement
2714        ConditionResult::Unknown
2715    }
2716
2717    /// [18] Wenn SG4 DTM+93 (Ende zum) nicht vorhanden
2718    fn evaluate_18(&self, _ctx: &EvaluationContext) -> ConditionResult {
2719        // TODO: implement
2720        ConditionResult::Unknown
2721    }
2722
2723    /// [19] Wenn SG8 SEQ+Z01/ Z98 (Daten der Marktlokation) SG10 CCI+++ZC0 (Prognose auf Basis von Werten) vorhanden
2724    fn evaluate_19(&self, _ctx: &EvaluationContext) -> ConditionResult {
2725        // TODO: implement
2726        ConditionResult::Unknown
2727    }
2728
2729    /// [21] Wenn SG10 CCI+++ZA6 (Prognose auf Basis von Profilen) in dieser SG8 vorhanden
2730    fn evaluate_21(&self, _ctx: &EvaluationContext) -> ConditionResult {
2731        // TODO: implement
2732        ConditionResult::Unknown
2733    }
2734
2735    /// [22] Es ist die Zeitraum-ID vom DE1156 aus einem passenden SG6 RFF+Z47/ Z48/ Z49 (Verwendungszeitraum der Daten) einzutragen
2736    // REVIEW: Checks if any SG6 RFF+Z47/Z48/Z49 Zeitraum-ID (DE1156 at elements[0][2]) matches any SG8 SEQ Zeitraum-ID reference (DE1050 at elements[1][0]). Uses groups_share_qualified_value for cross-group correlation across all three qualifying codes. (medium confidence)
2737    fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
2738        for qual in &["Z47", "Z48", "Z49"] {
2739            if matches!(
2740                ctx.groups_share_qualified_value(
2741                    "RFF",
2742                    0,
2743                    qual,
2744                    0,
2745                    2,
2746                    &["SG4", "SG6"],
2747                    "SEQ",
2748                    1,
2749                    0,
2750                    &["SG4", "SG8"],
2751                ),
2752                ConditionResult::True
2753            ) {
2754                return ConditionResult::True;
2755            }
2756        }
2757        ConditionResult::False
2758    }
2759
2760    /// [23] Wenn in dieser SG4 das STS+E01++A05/A99 (Status der Antwort) vorhanden
2761    fn evaluate_23(&self, _ctx: &EvaluationContext) -> ConditionResult {
2762        // TODO: implement
2763        ConditionResult::Unknown
2764    }
2765
2766    /// [24] Wenn in dieser SG4 das STS+E01++A25/A99 (Status der Antwort) vorhanden
2767    fn evaluate_24(&self, _ctx: &EvaluationContext) -> ConditionResult {
2768        // TODO: implement
2769        ConditionResult::Unknown
2770    }
2771
2772    /// [25] Wenn die Veräußerungsform der erzeugenden Marktlokation der Marktprämie zugeordnet ist
2773    fn evaluate_25(&self, _ctx: &EvaluationContext) -> ConditionResult {
2774        // TODO: implement
2775        ConditionResult::Unknown
2776    }
2777
2778    /// [27] Wenn das DE2380 von SG4 DTM+Z01 (Kündigungsfrist des Vertrags) an vierter Stelle ein T oder R enthält
2779    fn evaluate_27(&self, _ctx: &EvaluationContext) -> ConditionResult {
2780        // TODO: implement
2781        ConditionResult::Unknown
2782    }
2783
2784    /// [30] Wenn Antwort auf Aktivierung übermittelt wird
2785    fn evaluate_30(&self, _ctx: &EvaluationContext) -> ConditionResult {
2786        // TODO: implement
2787        ConditionResult::Unknown
2788    }
2789
2790    /// [31] Wenn eine Korrektur erfolgt
2791    fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
2792        ctx.external.evaluate("correction_in_progress")
2793    }
2794
2795    /// [32] Wenn mehr als ein SG8 (Referenz auf die Lokationsbündelstruktur) vorhanden
2796    fn evaluate_32(&self, _ctx: &EvaluationContext) -> ConditionResult {
2797        // TODO: implement
2798        ConditionResult::Unknown
2799    }
2800
2801    /// [33] Wenn in einer SG8 SEQ+Z79 im PIA+5 (Erforderliches Produkt) DE7140 ein Produkt-Code genannt ist, der in der Codeliste der Konfigurationen im Kapitel 6 \"Produkte zur Bestellung / Änderung von Date...
2802    fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
2803        ctx.external.evaluate("code_list_membership_check")
2804    }
2805
2806    /// [34] Wenn Antwort auf Deaktivierung übermittelt wird
2807    fn evaluate_34(&self, _ctx: &EvaluationContext) -> ConditionResult {
2808        // TODO: implement
2809        ConditionResult::Unknown
2810    }
2811
2812    /// [35] Wenn das DE2380 von SG4 DTM+Z01 (Kündigungsfrist des Vertrags) an vierter Stelle T (Termin) enthält
2813    fn evaluate_35(&self, _ctx: &EvaluationContext) -> ConditionResult {
2814        // TODO: implement
2815        ConditionResult::Unknown
2816    }
2817
2818    /// [36] Wenn in derselben SG8 SEQ+Z79 im PIA+5 (Erforderliches Produkt) DE7140 ein Produkt-Code genannt ist, der in der Codeliste der Konfigurationen im Kapitel 6.1 \"Anmeldung einer Zuordnung des LFN (UTI...
2819    fn evaluate_36(&self, ctx: &EvaluationContext) -> ConditionResult {
2820        ctx.external.evaluate("code_list_membership_check")
2821    }
2822
2823    /// [37] Wenn Anmeldung/ Änderung befristet
2824    fn evaluate_37(&self, ctx: &EvaluationContext) -> ConditionResult {
2825        // Same check as [10]: STS element[4] is befristete Anmeldung code
2826        ctx.has_qualified_value("STS", 0, "7", 4, 0, &["E01", "E03"])
2827    }
2828
2829    /// [38] Es sind nur die Code der Produkteigenschaft zu dem in derselben SG8 SEQ+Z79 im PIA+5 (Erforderliches Produkt) DE7140 erlaubt, die in der Codeliste der Konfigurationen im Kapitel  6.1 \"Anmeldung ei...
2830    fn evaluate_38(&self, ctx: &EvaluationContext) -> ConditionResult {
2831        ctx.external.evaluate("code_list_membership_check")
2832    }
2833
2834    /// [39] Wenn in derselben SG8 SEQ+Z79 m PIA+5 (Erforderliches Produkt) DE7140 ein Produkt-Code genannt ist, der in der Codeliste der Konfigurationen im Kapitel 6.1 \"Anmeldung einer Zuordnung des LFN (UTIL...
2835    fn evaluate_39(&self, ctx: &EvaluationContext) -> ConditionResult {
2836        ctx.external.evaluate("code_list_membership_check")
2837    }
2838
2839    /// [40] Es ist nur der Wertebereich erlaubt, der zu dem in derselben SG8 SEQ+Z79 im PIA+5 (Erforderliches Produkt) DE7140 genannten Produkt, das in der Codeliste der Konfigurationen im Kapitel 6.1 \"Anmeld...
2840    fn evaluate_40(&self, ctx: &EvaluationContext) -> ConditionResult {
2841        ctx.external.evaluate("code_list_membership_check")
2842    }
2843
2844    /// [41] Es ist eine Produktpaket-ID aus dem DE1050 von einem SG8 SEQ+Z79 (Erforderliches Produkt) zu nennen
2845    fn evaluate_41(&self, _ctx: &EvaluationContext) -> ConditionResult {
2846        // TODO: implement
2847        ConditionResult::Unknown
2848    }
2849
2850    /// [42] Wenn mehr als ein SG8 SEQ+ZH0 (Priorisierung erforderliches Produktpaket) vorhanden
2851    fn evaluate_42(&self, _ctx: &EvaluationContext) -> ConditionResult {
2852        // TODO: implement
2853        ConditionResult::Unknown
2854    }
2855
2856    /// [43] Wenn in dieser SG4 das STS+E01++A12 / A13 (Status der Antwort) vorhanden
2857    fn evaluate_43(&self, _ctx: &EvaluationContext) -> ConditionResult {
2858        // TODO: implement
2859        ConditionResult::Unknown
2860    }
2861
2862    /// [45] Wenn in derselben SG8 das SG10 CCI+Z01++Z82 (Verwendungsumfang: ID der prozessual behandelten Messlokation) vorhanden
2863    fn evaluate_45(&self, _ctx: &EvaluationContext) -> ConditionResult {
2864        // TODO: implement
2865        ConditionResult::Unknown
2866    }
2867
2868    /// [46] Wenn ID für Objekt vergeben wurde
2869    fn evaluate_46(&self, _ctx: &EvaluationContext) -> ConditionResult {
2870        // TODO: implement
2871        ConditionResult::Unknown
2872    }
2873
2874    /// [47] Wenn SG10 CCI+15++Z21 (Summenzeitreihentyp) CAV+DBA/ VZR/ EGS/ LGS/ SLS/ SES/ TLS/ TES/ BIL/ BIP/ BIT/ GAL/ GAP/ GAT/ GEL/ GEP/ GET/ SOL/ SOP/ SOT/ WFL/ WFP/ WFT/ WNL/ WNP/ WNT vorhanden
2875    // REVIEW: Iterates all SG8 instances and their SG10 children looking for CCI with elements[0][0]=="15" and elements[2][0]=="Z21" (Zeitreihentyp), then checks if the same SG10 has a CAV with elements[0][0] in the Summenzeitreihentyp code list. Uses navigator for parent-child group traversal. (medium confidence)
2876    fn evaluate_47(&self, ctx: &EvaluationContext) -> ConditionResult {
2877        const CODES: &[&str] = &[
2878            "DBA", "VZR", "EGS", "LGS", "SLS", "SES", "TLS", "TES", "BIL", "BIP", "BIT", "GAL",
2879            "GAP", "GAT", "GEL", "GEP", "GET", "SOL", "SOP", "SOT", "WFL", "WFP", "WFT", "WNL",
2880            "WNP", "WNT",
2881        ];
2882        let nav = match ctx.navigator {
2883            Some(n) => n,
2884            None => return ConditionResult::Unknown,
2885        };
2886        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2887        for i in 0..sg8_count {
2888            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
2889            for j in 0..sg10_count {
2890                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
2891                let has_cci_15_z21 = ccis.iter().any(|s| {
2892                    s.elements
2893                        .first()
2894                        .and_then(|e: &Vec<String>| e.first())
2895                        .is_some_and(|v: &String| v == "15")
2896                        && s.elements
2897                            .get(2)
2898                            .and_then(|e: &Vec<String>| e.first())
2899                            .is_some_and(|v: &String| v == "Z21")
2900                });
2901                if has_cci_15_z21 {
2902                    let cavs =
2903                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
2904                    if cavs.iter().any(|s| {
2905                        s.elements
2906                            .first()
2907                            .and_then(|e: &Vec<String>| e.first())
2908                            .is_some_and(|v: &String| CODES.contains(&v.as_str()))
2909                    }) {
2910                        return ConditionResult::True;
2911                    }
2912                }
2913            }
2914        }
2915        ConditionResult::False
2916    }
2917
2918    /// [48] Wenn in dieser SG4 das STS+E01++A99 (Status der Antwort: Sonstiges) vorhanden
2919    fn evaluate_48(&self, _ctx: &EvaluationContext) -> ConditionResult {
2920        // TODO: implement
2921        ConditionResult::Unknown
2922    }
2923
2924    /// [49] Wenn in dieser SG4 das STS+E01++E14 (Status der Antwort: Ablehnung Sonstiges) vorhanden
2925    fn evaluate_49(&self, _ctx: &EvaluationContext) -> ConditionResult {
2926        // TODO: implement
2927        ConditionResult::Unknown
2928    }
2929
2930    /// [50] Wenn kein SG8 SEQ+ZE7 (Informative Daten der Tranche) mit derselben Zeitraum-ID im DE1050 auf die gleiche Marktlokation-ID mit dem RFF+Z18 (Marktlokation) referenziert wie dieses SG8 SEQ+Z98 (Infor...
2931    // REVIEW: Collects (Zeitraum-ID from SEQ.elements[1][0], Marktlok-ID from sibling RFF+Z18.elements[0][1]) for all SG8 instances with SEQ+Z98 and SEQ+ZE7. Returns True if any Z98 group has no ZE7 group matching on both values. Uses collect_group_values with instance-index correlation via HashMap, assuming each SG8 has at most one SEQ (guaranteed as entry segment) and the zip ordering is stable. (medium confidence)
2932    fn evaluate_50(&self, ctx: &EvaluationContext) -> ConditionResult {
2933        use std::collections::HashMap;
2934
2935        let seq_quals = ctx.collect_group_values("SEQ", 0, 0, &["SG4", "SG8"]);
2936        let seq_zeitraum = ctx.collect_group_values("SEQ", 1, 0, &["SG4", "SG8"]);
2937        let rff_quals = ctx.collect_group_values("RFF", 0, 0, &["SG4", "SG8"]);
2938        let rff_ids = ctx.collect_group_values("RFF", 0, 1, &["SG4", "SG8"]);
2939
2940        // Build per-instance RFF lookup: instance_idx -> list of (qualifier, id)
2941        let mut rff_by_instance: HashMap<usize, Vec<(String, String)>> = HashMap::new();
2942        for ((idx, q), (_, id)) in rff_quals.iter().zip(rff_ids.iter()) {
2943            rff_by_instance
2944                .entry(*idx)
2945                .or_default()
2946                .push((q.clone(), id.clone()));
2947        }
2948
2949        // Build (zeitraum_id, marktlok_id) for Z98 and ZE7 SG8 instances
2950        let mut seq_zeitraum_map: HashMap<usize, String> = HashMap::new();
2951        for (idx, z) in &seq_zeitraum {
2952            seq_zeitraum_map.insert(*idx, z.clone());
2953        }
2954
2955        let z98_data: Vec<(String, String)> = seq_quals
2956            .iter()
2957            .filter(|(_, q)| q == "Z98")
2958            .map(|(idx, _)| {
2959                let zeitraum = seq_zeitraum_map.get(idx).cloned().unwrap_or_default();
2960                let marktlok = rff_by_instance
2961                    .get(idx)
2962                    .and_then(|rffs| rffs.iter().find(|(q, _)| q == "Z18"))
2963                    .map(|(_, id)| id.clone())
2964                    .unwrap_or_default();
2965                (zeitraum, marktlok)
2966            })
2967            .collect();
2968
2969        if z98_data.is_empty() {
2970            return ConditionResult::Unknown;
2971        }
2972
2973        let ze7_data: Vec<(String, String)> = seq_quals
2974            .iter()
2975            .filter(|(_, q)| q == "ZE7")
2976            .map(|(idx, _)| {
2977                let zeitraum = seq_zeitraum_map.get(idx).cloned().unwrap_or_default();
2978                let marktlok = rff_by_instance
2979                    .get(idx)
2980                    .and_then(|rffs| rffs.iter().find(|(q, _)| q == "Z18"))
2981                    .map(|(_, id)| id.clone())
2982                    .unwrap_or_default();
2983                (zeitraum, marktlok)
2984            })
2985            .collect();
2986
2987        ConditionResult::from(z98_data.iter().any(|(z98_zeit, z98_lok)| {
2988            !ze7_data
2989                .iter()
2990                .any(|(ze7_zeit, ze7_lok)| ze7_zeit == z98_zeit && ze7_lok == z98_lok)
2991        }))
2992    }
2993
2994    /// [52] Wenn SG10 CCI+Z07++Z55/ Z56 (Profiltyp: sonstige verbrauchende Marktlokation / sonstige erzeugende Marktlokation) vorhanden
2995    fn evaluate_52(&self, _ctx: &EvaluationContext) -> ConditionResult {
2996        // TODO: implement
2997        ConditionResult::Unknown
2998    }
2999
3000    /// [53] Wenn weitere Präzisierungen als über CCI+Z07 (Profiltyp) möglich sind
3001    fn evaluate_53(&self, _ctx: &EvaluationContext) -> ConditionResult {
3002        // TODO: implement
3003        ConditionResult::Unknown
3004    }
3005
3006    /// [54] Wenn SG8 SEQ+Z01 (Daten der Marktlokation) SG10 CCI+Z30++Z06 (Lieferrichtung: Erzeugung) vorhanden
3007    fn evaluate_54(&self, _ctx: &EvaluationContext) -> ConditionResult {
3008        // TODO: implement
3009        ConditionResult::Unknown
3010    }
3011
3012    /// [55] Wenn in dieser SG4 das STS+E01++A06/ A99 (Status der Antwort) vorhanden
3013    fn evaluate_55(&self, _ctx: &EvaluationContext) -> ConditionResult {
3014        // TODO: implement
3015        ConditionResult::Unknown
3016    }
3017
3018    /// [56] Wenn im STS+E01 im DE9013 (Status der Antwort) ein Antwortcode aus dem Cluster Zustimmung vorhanden ist
3019    fn evaluate_56(&self, _ctx: &EvaluationContext) -> ConditionResult {
3020        // TODO: implement
3021        ConditionResult::Unknown
3022    }
3023
3024    /// [57] Wenn in derselben SG8 das CCI+Z45++ZD9 (Abrechnung findet statt) vorhanden ist
3025    fn evaluate_57(&self, _ctx: &EvaluationContext) -> ConditionResult {
3026        // TODO: implement
3027        ConditionResult::Unknown
3028    }
3029
3030    /// [58] Wenn in diesem CCI das DE3055 mit dem Code 293 vorhanden
3031    fn evaluate_58(&self, _ctx: &EvaluationContext) -> ConditionResult {
3032        // TODO: implement
3033        ConditionResult::Unknown
3034    }
3035
3036    /// [60] Wenn BGM+Z90 (Beendigung der Zuordnung zur Lokation) vorhanden
3037    fn evaluate_60(&self, _ctx: &EvaluationContext) -> ConditionResult {
3038        // TODO: implement
3039        ConditionResult::Unknown
3040    }
3041
3042    /// [61] Wenn BGM+Z89 (Zuordnung zur Lokation) vorhanden
3043    fn evaluate_61(&self, _ctx: &EvaluationContext) -> ConditionResult {
3044        // TODO: implement
3045        ConditionResult::Unknown
3046    }
3047
3048    /// [62] Wenn mehr als eine SG8 SEQ+Z45 (Netznutzungsabrechnungsdaten der Marktlokation), mit derselben Zeitraum-ID im DE1050, mit einer Gruppen-/Artikel-ID im SG8 PIA+Z02 (Gruppenartikel-ID / Artikel-ID), ...
3049    // REVIEW: Iterates SG8 instances within each SG4, finds those with SEQ+Z45 and a non-empty Zeitraum-ID in elements[1][0]. Checks if PIA+Z02 in the same SG8 has a product code (elements[1][0]) beginning with 1-08-1 through 1-08-5. Groups by Zeitraum-ID and checks if any ID appears more than once. Requires navigator for per-instance group segment access; returns Unknown without one. (medium confidence)
3050    fn evaluate_62(&self, ctx: &EvaluationContext) -> ConditionResult {
3051        let nav = match ctx.navigator {
3052            Some(n) => n,
3053            None => return ConditionResult::Unknown,
3054        };
3055        use std::collections::HashMap;
3056        let mut count_by_zid: HashMap<String, u32> = HashMap::new();
3057        let sg4_count = nav.group_instance_count(&["SG4"]);
3058        for sg4_idx in 0..sg4_count {
3059            let sg8_count = nav.child_group_instance_count(&["SG4"], sg4_idx, "SG8");
3060            for sg8_idx in 0..sg8_count {
3061                let seqs =
3062                    nav.find_segments_in_child_group("SEQ", &["SG4"], sg4_idx, "SG8", sg8_idx);
3063                let zeitraum_opt = seqs
3064                    .iter()
3065                    .filter(|s| {
3066                        s.elements
3067                            .first()
3068                            .and_then(|e: &Vec<String>| e.first())
3069                            .is_some_and(|v: &String| v == "Z45")
3070                    })
3071                    .filter_map(|s| {
3072                        s.elements
3073                            .get(1)
3074                            .and_then(|e: &Vec<String>| e.first())
3075                            .filter(|v| !v.is_empty())
3076                            .cloned()
3077                    })
3078                    .next();
3079                let Some(zid) = zeitraum_opt else { continue };
3080                let pias =
3081                    nav.find_segments_in_child_group("PIA", &["SG4"], sg4_idx, "SG8", sg8_idx);
3082                let has_qualifying_pia = pias.iter().any(|s| {
3083                    s.elements
3084                        .first()
3085                        .and_then(|e: &Vec<String>| e.first())
3086                        .is_some_and(|v: &String| v == "Z02")
3087                        && s.elements
3088                            .get(1)
3089                            .and_then(|e: &Vec<String>| e.first())
3090                            .map(|code| {
3091                                code.starts_with("1-08-1")
3092                                    || code.starts_with("1-08-2")
3093                                    || code.starts_with("1-08-3")
3094                                    || code.starts_with("1-08-4")
3095                                    || code.starts_with("1-08-5")
3096                            })
3097                            .unwrap_or(false)
3098                });
3099                if has_qualifying_pia {
3100                    *count_by_zid.entry(zid).or_insert(0) += 1;
3101                }
3102            }
3103        }
3104        ConditionResult::from(count_by_zid.values().any(|&c| c > 1))
3105    }
3106
3107    /// [63] Wenn in dieser SG4 das STS+E01++A15/ A99 (Status der Antwort) vorhanden
3108    fn evaluate_63(&self, _ctx: &EvaluationContext) -> ConditionResult {
3109        // TODO: implement
3110        ConditionResult::Unknown
3111    }
3112
3113    /// [64] Wenn mehr als eine SG8 SEQ+ZE1 (Informative Netznutzungsabrechnungsdaten der Marktlokation) mit einer Gruppen-/ Artikel-ID im SG8 PIA+Z02 (Gruppenartikel-ID / Artikel-ID), welche mit 1-08-1/2/3/4/5...
3114    fn evaluate_64(&self, _ctx: &EvaluationContext) -> ConditionResult {
3115        // TODO: implement
3116        ConditionResult::Unknown
3117    }
3118
3119    /// [65] Wenn in derselben SG8 SEQ+ZE1 (Informative Netznutzungsabrechnungsdaten der Marktlokation) eine Gruppen-/Artikel-ID im PIA+Z02 (Gruppenartikel-ID / Artikel-ID), welche mit 1-08-1/2/3/4/5 beginnt, v...
3120    fn evaluate_65(&self, _ctx: &EvaluationContext) -> ConditionResult {
3121        // TODO: implement
3122        ConditionResult::Unknown
3123    }
3124
3125    /// [66] Wenn SG8 SEQ+ZH0 (Priorisierung erforderliches Produktpaket) mehr als einmal vorhanden
3126    fn evaluate_66(&self, _ctx: &EvaluationContext) -> ConditionResult {
3127        // TODO: implement
3128        ConditionResult::Unknown
3129    }
3130
3131    /// [67] Wenn in keinem SG8 SEQ+Z79 (Bestandteil eine Produktpaketes CCI+Z66/CAV+ZH9 (Produkteigenschaft/ Code der Produkteigenschaft) der Code 9991000002933 (Ruhende Marktlokation ausprägen) vorhanden ist.
3132    fn evaluate_67(&self, _ctx: &EvaluationContext) -> ConditionResult {
3133        // TODO: implement
3134        ConditionResult::Unknown
3135    }
3136
3137    /// [68] Wenn SG8 SEQ+ZH0 (Priorisierung erforderliches Produktpaket) mehr als zweimal vorhanden
3138    fn evaluate_68(&self, _ctx: &EvaluationContext) -> ConditionResult {
3139        // TODO: implement
3140        ConditionResult::Unknown
3141    }
3142
3143    /// [69] Wenn SG8 SEQ+ZH0 (Priorisierung erforderliches Produktpaket) mehr als dreimal vorhanden
3144    fn evaluate_69(&self, _ctx: &EvaluationContext) -> ConditionResult {
3145        // TODO: implement
3146        ConditionResult::Unknown
3147    }
3148
3149    /// [70] Wenn SG8 SEQ+ZH0 (Priorisierung erforderliches Produktpaket) fünfmal vorhanden
3150    fn evaluate_70(&self, _ctx: &EvaluationContext) -> ConditionResult {
3151        // TODO: implement
3152        ConditionResult::Unknown
3153    }
3154
3155    /// [71] Wenn Antwort auf Zuordnung übermittelt wird
3156    fn evaluate_71(&self, _ctx: &EvaluationContext) -> ConditionResult {
3157        // TODO: implement
3158        ConditionResult::Unknown
3159    }
3160
3161    /// [72] Wenn Antwort auf Beendigung der Zuordnung übermittelt wird
3162    fn evaluate_72(&self, _ctx: &EvaluationContext) -> ConditionResult {
3163        // TODO: implement
3164        ConditionResult::Unknown
3165    }
3166
3167    /// [73] Wenn in derselben SG8 im PIA DE7140 ein Code aus der Codeliste der Gruppenartikel- und Artikel-ID vorhanden ist, der in der Spalte UTILMD/Preisangabe mit X gekennzeichnet ist
3168    fn evaluate_73(&self, _ctx: &EvaluationContext) -> ConditionResult {
3169        // TODO: implement
3170        ConditionResult::Unknown
3171    }
3172
3173    /// [74] Wenn in der selben SG8 SEQ+Z59 (Produkt-Daten der Marktlokation) das PIA+5 (Produkt-Daten der Marktlokation) vorhanden
3174    fn evaluate_74(&self, _ctx: &EvaluationContext) -> ConditionResult {
3175        // TODO: implement
3176        ConditionResult::Unknown
3177    }
3178
3179    /// [75] Wenn in diesem PIA+5 in DE7140 der Code 9991000000721 (vgl.: Kapitel 4.2. Konfigurationsprodukte Leistungskurvendefinition der Codeliste der Konfigurationen) vorhanden
3180    fn evaluate_75(&self, ctx: &EvaluationContext) -> ConditionResult {
3181        ctx.external.evaluate("code_list_membership_check")
3182    }
3183
3184    /// [76] Wenn Summenzeitreihe auf Ebene des Bilanzierungsgebiet
3185    // REVIEW: SEQ+Z49 is 'Abgerechnete Daten der Bilanzierungsgebietssummenzeitreihe' — the only SEQ code in the reference that explicitly names a Bilanzierungsgebiet-level Summenzeitreihe. Checking its presence is the most direct mapping of the condition text. A broader interpretation involving CAV codes (Bezeichnung der Summenzeitreihe) is possible but those codes are not fully enumerated in the provided reference. (medium confidence)
3186    fn evaluate_76(&self, ctx: &EvaluationContext) -> ConditionResult {
3187        ctx.has_qualifier("SEQ", 0, "Z49")
3188    }
3189
3190    /// [77] Wenn SG8 SEQ+Z03 (Zähleinrichtungsdaten) CAV+Z30 (Identifikation/Nummer des Gerätes) nicht vorhanden
3191    fn evaluate_77(&self, _ctx: &EvaluationContext) -> ConditionResult {
3192        // TODO: implement
3193        ConditionResult::Unknown
3194    }
3195
3196    /// [78] Wenn SG4 STS+7++E02 (Transaktionsgrund: Einzug in Neuanlage) nicht vorhanden
3197    fn evaluate_78(&self, _ctx: &EvaluationContext) -> ConditionResult {
3198        // TODO: implement
3199        ConditionResult::Unknown
3200    }
3201
3202    /// [83] Wenn in dieser SG4 das STS+E01++A08/ A16/ A99 (Status der Antwort) vorhanden
3203    fn evaluate_83(&self, _ctx: &EvaluationContext) -> ConditionResult {
3204        // TODO: implement
3205        ConditionResult::Unknown
3206    }
3207
3208    /// [84] Wenn SG4 STS+E01++A57 (Status der Antwort) vorhanden
3209    fn evaluate_84(&self, _ctx: &EvaluationContext) -> ConditionResult {
3210        // TODO: implement
3211        ConditionResult::Unknown
3212    }
3213
3214    /// [85] Wenn das DE2380 von SG4 DTM+Z01 (Kündigungsfrist des Vertrags) an vierter Stelle M, Q, H oder J enthält
3215    fn evaluate_85(&self, _ctx: &EvaluationContext) -> ConditionResult {
3216        // TODO: implement
3217        ConditionResult::Unknown
3218    }
3219
3220    /// [86] Wenn das RFF+Z50 (Termine der Marktlokation) aus dieser SG6 (Termine der Marktlokation) auf das gleiche SG5 LOC+Z16 (Marktlokation), wie ein RFF+Z18 (Marktlokation) aus einer SG8 SEQ+Z01 (Daten der...
3221    fn evaluate_86(&self, _ctx: &EvaluationContext) -> ConditionResult {
3222        // TODO: implement
3223        ConditionResult::Unknown
3224    }
3225
3226    /// [87] Es ist ein Monatserster 0 Uhr (gem. deutscher Zeit) anzugeben
3227    fn evaluate_87(&self, _ctx: &EvaluationContext) -> ConditionResult {
3228        // TODO: implement
3229        ConditionResult::Unknown
3230    }
3231
3232    /// [88] Wert muss identisch mit DE2380 aus dem SG4 DTM+157 (Änderung zum) sein
3233    fn evaluate_88(&self, _ctx: &EvaluationContext) -> ConditionResult {
3234        // TODO: implement
3235        ConditionResult::Unknown
3236    }
3237
3238    /// [89] Wenn im SG8 SEQ+Z01 (Daten der Marktlokation) mit identischer Zeitraum-ID im DE1050 wie in diesem SG8, das SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) CAV+...
3239    // REVIEW: Checks whether any SG8 instance contains an SG10 child with CCI at elements[2][0]=ZA6 and CAV at elements[0][0]=E14. The condition text requires the Zeitraum-ID in DE1050 to match 'this SG8', but a per-group evaluation context is not available in the current API — the Zeitraum-ID cross-reference is therefore not enforced and is instead approximated as a message-wide check. The CCI qualifier position (elements[2][0]) is confirmed by the MIG reference for CCI segments in SG10. (medium confidence)
3240    fn evaluate_89(&self, ctx: &EvaluationContext) -> ConditionResult {
3241        let nav = match ctx.navigator {
3242            Some(n) => n,
3243            None => {
3244                return ctx.filtered_parent_child_has_qualifier(
3245                    &["SG4", "SG8"],
3246                    "SEQ",
3247                    0,
3248                    "Z01",
3249                    "SG10",
3250                    "CCI",
3251                    2,
3252                    "ZA6",
3253                )
3254            }
3255        };
3256        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
3257        for i in 0..sg8_count {
3258            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
3259            for j in 0..sg10_count {
3260                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
3261                let has_cci_za6 = ccis.iter().any(|s| {
3262                    s.elements
3263                        .get(2)
3264                        .and_then(|e: &Vec<String>| e.first())
3265                        .is_some_and(|v: &String| v == "ZA6")
3266                });
3267                if !has_cci_za6 {
3268                    continue;
3269                }
3270                let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
3271                if cavs.iter().any(|s| {
3272                    s.elements
3273                        .first()
3274                        .and_then(|e: &Vec<String>| e.first())
3275                        .is_some_and(|v: &String| v == "E14")
3276                }) {
3277                    return ConditionResult::True;
3278                }
3279            }
3280        }
3281        ConditionResult::False
3282    }
3283
3284    /// [90] Wenn SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) einmal mit CAV+E14 (TLP/TEP) und einmal mit CAV+E02 (SLP/SEP) in dieser SG8 vorhanden
3285    // REVIEW: Within each SG8, iterates all SG10 child instances. For each SG10 that has a CCI with elements[2][0]=ZA6, checks the CAV elements[0][0] value. Tracks whether E14 and E02 have both been seen within the same SG8. Returns True when both are found in a single SG8, satisfying the requirement that both Prognosegrundlage options appear 'in dieser SG8'. (medium confidence)
3286    fn evaluate_90(&self, ctx: &EvaluationContext) -> ConditionResult {
3287        let nav = match ctx.navigator {
3288            Some(n) => n,
3289            None => return ConditionResult::Unknown,
3290        };
3291        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
3292        for i in 0..sg8_count {
3293            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
3294            let mut has_za6_e14 = false;
3295            let mut has_za6_e02 = false;
3296            for j in 0..sg10_count {
3297                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
3298                let has_cci_za6 = ccis.iter().any(|s| {
3299                    s.elements
3300                        .get(2)
3301                        .and_then(|e: &Vec<String>| e.first())
3302                        .is_some_and(|v: &String| v == "ZA6")
3303                });
3304                if !has_cci_za6 {
3305                    continue;
3306                }
3307                let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
3308                for cav in &cavs {
3309                    if let Some(code) = cav.elements.first().and_then(|e: &Vec<String>| e.first()) {
3310                        if code == "E14" {
3311                            has_za6_e14 = true;
3312                        }
3313                        if code == "E02" {
3314                            has_za6_e02 = true;
3315                        }
3316                    }
3317                }
3318            }
3319            if has_za6_e14 && has_za6_e02 {
3320                return ConditionResult::True;
3321            }
3322        }
3323        ConditionResult::False
3324    }
3325
3326    /// [91] Wenn nicht SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) einmal mit CAV+E14 (TLP/ TEP) und einmal mit CAV+E02 (SLP/SEP) in dieser SG8 vorhanden
3327    // REVIEW: Logical negation of condition 90. Condition 91 is explicitly defined as 'Wenn NICHT (CCI+++ZA6 einmal mit CAV+E14 und einmal mit CAV+E02 in dieser SG8 vorhanden)', which is the exact complement of condition 90. Preserving Unknown propagation handles the no-navigator fallback case correctly. (medium confidence)
3328    fn evaluate_91(&self, ctx: &EvaluationContext) -> ConditionResult {
3329        match self.evaluate_90(ctx) {
3330            ConditionResult::True => ConditionResult::False,
3331            ConditionResult::False => ConditionResult::True,
3332            ConditionResult::Unknown => ConditionResult::Unknown,
3333        }
3334    }
3335
3336    /// [92] Wenn Wert innerhalb SG bzw. Segment geändert wird
3337    fn evaluate_92(&self, _ctx: &EvaluationContext) -> ConditionResult {
3338        // TODO: implement
3339        ConditionResult::Unknown
3340    }
3341
3342    /// [93] Erlaubte Codes aus der PRICAT BGM+Z32 (Preisblatt Messstellenbetrieb) des verantwortlichen MSB
3343    fn evaluate_93(&self, _ctx: &EvaluationContext) -> ConditionResult {
3344        // TODO: implement
3345        ConditionResult::Unknown
3346    }
3347
3348    /// [94] Wenn ein Segment innerhalb der SG vorhanden
3349    fn evaluate_94(&self, _ctx: &EvaluationContext) -> ConditionResult {
3350        // TODO: implement
3351        ConditionResult::Unknown
3352    }
3353
3354    /// [95] Wenn in derselben SG10 das CCI+Z17 (Stromverbrauchsart) CAV+ZE5 (E-Mobilität) vorhanden
3355    fn evaluate_95(&self, _ctx: &EvaluationContext) -> ConditionResult {
3356        // TODO: implement
3357        ConditionResult::Unknown
3358    }
3359
3360    /// [96] Wenn SG4 STS+7++xxx+ZAP (Transaktionsgrundergänzung ruhende Marktlokation) vorhanden
3361    fn evaluate_96(&self, _ctx: &EvaluationContext) -> ConditionResult {
3362        // TODO: implement
3363        ConditionResult::Unknown
3364    }
3365
3366    /// [97] Wenn in einem SG10 CAV+ZH9 DE7110 der Code der Produkteigenschaft (Wertebereich) 9991000002420 (Marktprämie) vorhanden ist
3367    fn evaluate_97(&self, _ctx: &EvaluationContext) -> ConditionResult {
3368        // TODO: implement
3369        ConditionResult::Unknown
3370    }
3371
3372    /// [98] Wenn MP-ID in SG2 NAD+MS (Nachrichtenabsender) in der Rolle NB
3373    fn evaluate_98(&self, ctx: &EvaluationContext) -> ConditionResult {
3374        ctx.external.evaluate("sender_role_check")
3375    }
3376
3377    /// [99] Wenn MP-ID in SG2 NAD+MS (Nachrichtenabsender) in der Rolle ÜNB
3378    fn evaluate_99(&self, ctx: &EvaluationContext) -> ConditionResult {
3379        ctx.external.evaluate("sender_role_check")
3380    }
3381
3382    /// [100] Wenn SG10 CAV+TLS/ TES/ BIT/ GET/ GAT/ SOT/ WNT/ WFT/ WAT vorhanden
3383    fn evaluate_100(&self, _ctx: &EvaluationContext) -> ConditionResult {
3384        // TODO: implement
3385        ConditionResult::Unknown
3386    }
3387
3388    /// [101] Wenn SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) CAV+E14/ Z36 (TLP/ TEP/ TEP mit Ref.messung) in dieser SG8 vorhanden
3389    fn evaluate_101(&self, _ctx: &EvaluationContext) -> ConditionResult {
3390        // TODO: implement
3391        ConditionResult::Unknown
3392    }
3393
3394    /// [102] Wenn SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) CAV+Z36 (TEP mit Ref.messung) in dieser SG8 vorhanden
3395    fn evaluate_102(&self, _ctx: &EvaluationContext) -> ConditionResult {
3396        // TODO: implement
3397        ConditionResult::Unknown
3398    }
3399
3400    /// [103] Wenn SG9 QTY+265 (Arbeit / Leistung für tagesparameterabhängig e Marktlokation: Veranschlagte Jahresmenge Gesamt) in dieser SG8 vorhanden
3401    fn evaluate_103(&self, _ctx: &EvaluationContext) -> ConditionResult {
3402        // TODO: implement
3403        ConditionResult::Unknown
3404    }
3405
3406    /// [104] Wenn SG9 QTY+Z08 (Arbeit / Leistung für tagesparameterabhängige Marktlokation: angepasste elektrische Arbeit nach Anhang D) in dieser SG8 vorhanden
3407    fn evaluate_104(&self, _ctx: &EvaluationContext) -> ConditionResult {
3408        // TODO: implement
3409        ConditionResult::Unknown
3410    }
3411
3412    /// [105] Wenn SG9 QTY+Z10 (Arbeit / Leistung für tagesparameterabhängige Marktlokation: Leistung der Marktlokation) in dieser SG8 vorhanden
3413    fn evaluate_105(&self, _ctx: &EvaluationContext) -> ConditionResult {
3414        // TODO: implement
3415        ConditionResult::Unknown
3416    }
3417
3418    /// [106] Wenn in dieser SG8 SEQ+Z01 SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) CAV+E02 (SLP/SEP) vorhanden
3419    fn evaluate_106(&self, _ctx: &EvaluationContext) -> ConditionResult {
3420        // TODO: implement
3421        ConditionResult::Unknown
3422    }
3423
3424    /// [107] Wenn in derselben SG8 das SG10 CAV+SLS/ SES/ BIP/ GEP/ GAP/ SOP/ WNP/ WFP/ WAP vorhanden
3425    fn evaluate_107(&self, _ctx: &EvaluationContext) -> ConditionResult {
3426        // TODO: implement
3427        ConditionResult::Unknown
3428    }
3429
3430    /// [108] Wenn in derselben SG8 (Netznutzungsabrechnungsdaten der Marktlokation) eine Gruppen-/Artikel-ID im PIA+Z02 (Gruppenartikel-ID / Artikel-ID), welche mit 1-08-1/2/3/4/5 beginnt, vorhanden
3431    fn evaluate_108(&self, _ctx: &EvaluationContext) -> ConditionResult {
3432        // TODO: implement
3433        ConditionResult::Unknown
3434    }
3435
3436    /// [110] Wenn SG10 CAV+LGS/ EGS/ BIL/ GEL/ GAL/ SOL/ WNL/ WFL / WAL vorhanden
3437    fn evaluate_110(&self, _ctx: &EvaluationContext) -> ConditionResult {
3438        // TODO: implement
3439        ConditionResult::Unknown
3440    }
3441
3442    /// [111] Wenn in derselben SG8 SEQ+Z59 (Produkt-Daten der Marktlokation) das PIA+5 (Produkt-Daten der Marktlokation) nicht vorhanden
3443    fn evaluate_111(&self, ctx: &EvaluationContext) -> ConditionResult {
3444        ctx.any_group_has_qualifier_without("SEQ", 0, "Z59", "PIA", 0, "5", &["SG4", "SG8"])
3445    }
3446
3447    /// [112] Wenn in derselben SG8 SEQ+Z59 (Produkt-Daten der Marktlokation) das SG10 CCI+11 (Details zum Produkt der Marktlokation) nicht vorhanden
3448    fn evaluate_112(&self, ctx: &EvaluationContext) -> ConditionResult {
3449        let result = ctx.filtered_parent_child_has_qualifier(
3450            &["SG4", "SG8"],
3451            "SEQ",
3452            0,
3453            "Z59",
3454            "SG10",
3455            "CCI",
3456            0,
3457            "11",
3458        );
3459        match result {
3460            ConditionResult::True => ConditionResult::False,
3461            ConditionResult::False => ConditionResult::True,
3462            ConditionResult::Unknown => ConditionResult::Unknown,
3463        }
3464    }
3465
3466    /// [113] Wenn es sich um eine Antwort auf die Bestellung einer Zählzeit handelt
3467    fn evaluate_113(&self, _ctx: &EvaluationContext) -> ConditionResult {
3468        // TODO: implement
3469        ConditionResult::Unknown
3470    }
3471
3472    /// [114] Wenn das SG10 CCI+E03 (Spannungsebene der Marktlokation) CAV E06 (Niederspannung) in dieser SG vorhanden
3473    // REVIEW: Checks that CCI+E03 (Spannungsebene, elements[0][0]='E03' per AHB hint) and CAV+E06 (Niederspannung, elements[0][0]='E06') co-occur in the same SG10 child instance of some SG8. Uses navigator to iterate SG8→SG10 pairs and verify both segments within the same SG10 instance. Confidence medium because navigator availability is runtime-dependent and fallback is message-wide only. (medium confidence)
3474    fn evaluate_114(&self, ctx: &EvaluationContext) -> ConditionResult {
3475        let nav = match ctx.navigator {
3476            Some(n) => n,
3477            None => {
3478                return match (
3479                    ctx.has_qualifier("CCI", 0, "E03"),
3480                    ctx.has_qualifier("CAV", 0, "E06"),
3481                ) {
3482                    (ConditionResult::True, ConditionResult::True) => ConditionResult::True,
3483                    (ConditionResult::False, _) | (_, ConditionResult::False) => {
3484                        ConditionResult::False
3485                    }
3486                    _ => ConditionResult::Unknown,
3487                };
3488            }
3489        };
3490        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
3491        for i in 0..sg8_count {
3492            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
3493            for j in 0..sg10_count {
3494                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
3495                let has_cci_e03 = ccis.iter().any(|s| {
3496                    s.elements
3497                        .first()
3498                        .and_then(|e: &Vec<String>| e.first())
3499                        .is_some_and(|v: &String| v == "E03")
3500                });
3501                if has_cci_e03 {
3502                    let cavs =
3503                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
3504                    if cavs.iter().any(|s| {
3505                        s.elements
3506                            .first()
3507                            .and_then(|e: &Vec<String>| e.first())
3508                            .is_some_and(|v: &String| v == "E06")
3509                    }) {
3510                        return ConditionResult::True;
3511                    }
3512                }
3513            }
3514        }
3515        ConditionResult::False
3516    }
3517
3518    /// [115] Wenn das SG10 CCI+E03 (Spannungsebene der Marktlokation) CAV E05 (Mittelspannung) in dieser SG vorhanden
3519    fn evaluate_115(&self, _ctx: &EvaluationContext) -> ConditionResult {
3520        // TODO: implement
3521        ConditionResult::Unknown
3522    }
3523
3524    /// [116] Wenn das SG10 CCI+E03 (Spannungsebene der Marktlokation) CAV E04 (Hochspannung) in dieser SG vorhanden
3525    fn evaluate_116(&self, _ctx: &EvaluationContext) -> ConditionResult {
3526        // TODO: implement
3527        ConditionResult::Unknown
3528    }
3529
3530    /// [117] Wenn das RFF+Z18 (Marktlokation) aus dieser SG8 auf das gleiche SG5 LOC+Z16 (Marktlokation), wie ein RFF+Z18 (Marktlokation) aus einer SG8 SEQ+Z01 (Daten der Marktlokation), in dem SG10 CCI+++ZA6 (...
3531    // REVIEW: Full condition requires: (1) current SG8 has RFF+Z18=X, (2) another SG8 with SEQ+Z01 also has RFF+Z18=X, (3) that SG8 has SG10 with CCI elements[2][0]='ZA6' AND CAV elements[0][0]='E14'. Implementation simplifies to checking whether any SG8 has SG10 with both CCI+++ZA6 and CAV+E14 co-occurring in the same SG10 instance. The cross-SG RFF+Z18 value correlation and SEQ+Z01 parent check are omitted because the navigator API only exposes child-group segments (SG10 within SG8), not SG8's own entry segments. Medium confidence due to this structural limitation. (medium confidence)
3532    fn evaluate_117(&self, ctx: &EvaluationContext) -> ConditionResult {
3533        let nav = match ctx.navigator {
3534            Some(n) => n,
3535            None => return ConditionResult::Unknown,
3536        };
3537        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
3538        for i in 0..sg8_count {
3539            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
3540            for j in 0..sg10_count {
3541                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
3542                let has_cci_za6 = ccis.iter().any(|s| {
3543                    s.elements
3544                        .get(2)
3545                        .and_then(|e: &Vec<String>| e.first())
3546                        .is_some_and(|v: &String| v == "ZA6")
3547                });
3548                if has_cci_za6 {
3549                    let cavs =
3550                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
3551                    if cavs.iter().any(|s| {
3552                        s.elements
3553                            .first()
3554                            .and_then(|e: &Vec<String>| e.first())
3555                            .is_some_and(|v: &String| v == "E14")
3556                    }) {
3557                        return ConditionResult::True;
3558                    }
3559                }
3560            }
3561        }
3562        ConditionResult::False
3563    }
3564
3565    /// [118] Wenn in dieser SG8 SEQ+Z98 SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) CAV+E02 (SLP/ SEP) vorhanden
3566    fn evaluate_118(&self, ctx: &EvaluationContext) -> ConditionResult {
3567        let has_cci = ctx.filtered_parent_child_has_qualifier(
3568            &["SG4", "SG8"],
3569            "SEQ",
3570            0,
3571            "Z98",
3572            "SG10",
3573            "CCI",
3574            2,
3575            "ZA6",
3576        );
3577        if has_cci != ConditionResult::True {
3578            return has_cci;
3579        }
3580        ctx.filtered_parent_child_has_qualifier(
3581            &["SG4", "SG8"],
3582            "SEQ",
3583            0,
3584            "Z98",
3585            "SG10",
3586            "CAV",
3587            0,
3588            "E02",
3589        )
3590    }
3591
3592    /// [119] Wenn in der SG8 SEQ+Z01/ Z98 SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) CAV+E02 (SLP/SEP) vorhanden
3593    fn evaluate_119(&self, _ctx: &EvaluationContext) -> ConditionResult {
3594        // TODO: implement
3595        ConditionResult::Unknown
3596    }
3597
3598    /// [120] Wenn von NB Abtretungserklärung benötigt wird
3599    fn evaluate_120(&self, _ctx: &EvaluationContext) -> ConditionResult {
3600        // TODO: implement
3601        ConditionResult::Unknown
3602    }
3603
3604    /// [121] Wenn in dem SEQ+Z03/ ZF5 (Zähleinrichtungsdaten) das SG8 RFF+Z14 (Referenz auf das Smartmeter-Gateway) nicht vorhanden
3605    fn evaluate_121(&self, ctx: &EvaluationContext) -> ConditionResult {
3606        let z03 =
3607            ctx.any_group_has_qualifier_without("SEQ", 0, "Z03", "RFF", 0, "Z14", &["SG4", "SG8"]);
3608        if z03 == ConditionResult::True {
3609            return ConditionResult::True;
3610        }
3611        ctx.any_group_has_qualifier_without("SEQ", 0, "ZF5", "RFF", 0, "Z14", &["SG4", "SG8"])
3612    }
3613
3614    /// [122] Wenn in dieser SG8 SEQ+Z98 SG10 CCI+++E03 (Spannungsebene der Marktlokation) CAV+E06 (Niederspannung) vorhanden
3615    // REVIEW: Uses filtered_parent_child_has_qualifier to find SG8 instances where SEQ+Z98 has an SG10 child with CCI at elements[2]='E03' (Spannungsebene der Marktlokation). Then confirms CAV+E06 (Niederspannung) exists in an SG8 group. The CAV check is group-scoped rather than strictly same-SG10-instance because the navigator API does not directly expose parent-group (SG8) segment access alongside child-group (SG10) checks in one call. (medium confidence)
3616    fn evaluate_122(&self, ctx: &EvaluationContext) -> ConditionResult {
3617        // Check: in SG8 with SEQ+Z98, SG10 child has CCI+++E03 (Spannungsebene, elements[2][0]="E03")
3618        let has_cci_e03 = ctx.filtered_parent_child_has_qualifier(
3619            &["SG4", "SG8"],
3620            "SEQ",
3621            0,
3622            "Z98",
3623            "SG10",
3624            "CCI",
3625            2,
3626            "E03",
3627        );
3628        if has_cci_e03 != ConditionResult::True {
3629            return has_cci_e03;
3630        }
3631        // Also verify CAV+E06 (Niederspannung, elements[0][0]="E06") exists in the same SG8 scope
3632        ctx.any_group_has_qualifier("CAV", 0, "E06", &["SG4", "SG8"])
3633    }
3634
3635    /// [123] Wenn noch mindestens eine weitere SG8 SEQ+Z20 (OBIS-Daten der Zähleinrichtung Smartmeter-Gateway) mit dem SG8 RFF+MG (Gerätenummer des Zählers) auf die gleiche Identifikation/Nummer des Gerätes...
3636    // REVIEW: Scans segments linearly to collect RFF+MG device IDs from each SG8 group with SEQ+Z20 (OBIS-Daten der Zähleinrichtung/Smartmeter-Gateway). A new SEQ starts a new SG8 context; RFF+MG within that context records the device number. Returns True if any device ID appears in 2+ different SG8 groups (indicating multiple OBIS datasets reference the same device). Linear scan is used because the navigator API does not expose a direct method to retrieve segments within a parent SG8 instance by absolute index. (medium confidence)
3637    fn evaluate_123(&self, ctx: &EvaluationContext) -> ConditionResult {
3638        struct Sg8Z20Entry {
3639            mg_id: Option<String>,
3640        }
3641        let mut entries: Vec<Sg8Z20Entry> = Vec::new();
3642        let mut current: Option<Sg8Z20Entry> = None;
3643        for seg in ctx.segments {
3644            match seg.id.as_str() {
3645                "SEQ" => {
3646                    if let Some(entry) = current.take() {
3647                        entries.push(entry);
3648                    }
3649                    if seg
3650                        .elements
3651                        .first()
3652                        .and_then(|e: &Vec<String>| e.first())
3653                        .is_some_and(|v: &String| v == "Z20")
3654                    {
3655                        current = Some(Sg8Z20Entry { mg_id: None });
3656                    }
3657                }
3658                "RFF" if current.is_some() => {
3659                    if seg
3660                        .elements
3661                        .first()
3662                        .and_then(|e: &Vec<String>| e.first())
3663                        .is_some_and(|v: &String| v == "MG")
3664                    {
3665                        if let Some(ref mut entry) = current {
3666                            if entry.mg_id.is_none() {
3667                                entry.mg_id = seg.elements.first().and_then(|e| e.get(1)).cloned();
3668                            }
3669                        }
3670                    }
3671                }
3672                _ => {}
3673            }
3674        }
3675        if let Some(entry) = current {
3676            entries.push(entry);
3677        }
3678        let ids: Vec<&str> = entries
3679            .iter()
3680            .filter_map(|e| e.mg_id.as_deref().filter(|s| !s.is_empty()))
3681            .collect();
3682        for i in 0..ids.len() {
3683            for j in (i + 1)..ids.len() {
3684                if ids[i] == ids[j] {
3685                    return ConditionResult::True;
3686                }
3687            }
3688        }
3689        ConditionResult::False
3690    }
3691
3692    /// [124] Wenn noch mindestens eine weitere SG8 SEQ+Z20 (OBIS-Daten der Zähleinrichtung Smartmeter-Gateway) mit derselben Zeitraum-ID aus dem DE1050 dieser SG8 mit dem SG8 RFF+MG (Gerätenummer des Zählers...
3693    // REVIEW: Extends condition 123 by also requiring that the matching SG8 groups share the same Zeitraum-ID (from SEQ.elements[1][0] = DE1050 / C286.d1050). Both the Zeitraum-ID and the RFF+MG device number must be identical across at least two different SG8 instances with SEQ+Z20 for the condition to be True. (medium confidence)
3694    fn evaluate_124(&self, ctx: &EvaluationContext) -> ConditionResult {
3695        struct Sg8Z20Entry {
3696            zeitraum_id: String,
3697            mg_id: Option<String>,
3698        }
3699        let mut entries: Vec<Sg8Z20Entry> = Vec::new();
3700        let mut current: Option<Sg8Z20Entry> = None;
3701        for seg in ctx.segments {
3702            match seg.id.as_str() {
3703                "SEQ" => {
3704                    if let Some(entry) = current.take() {
3705                        entries.push(entry);
3706                    }
3707                    if seg
3708                        .elements
3709                        .first()
3710                        .and_then(|e: &Vec<String>| e.first())
3711                        .is_some_and(|v: &String| v == "Z20")
3712                    {
3713                        let zeitraum_id = seg
3714                            .elements
3715                            .get(1)
3716                            .and_then(|e: &Vec<String>| e.first())
3717                            .cloned()
3718                            .unwrap_or_default();
3719                        current = Some(Sg8Z20Entry {
3720                            zeitraum_id,
3721                            mg_id: None,
3722                        });
3723                    }
3724                }
3725                "RFF" if current.is_some() => {
3726                    if seg
3727                        .elements
3728                        .first()
3729                        .and_then(|e: &Vec<String>| e.first())
3730                        .is_some_and(|v: &String| v == "MG")
3731                    {
3732                        if let Some(ref mut entry) = current {
3733                            if entry.mg_id.is_none() {
3734                                entry.mg_id = seg.elements.first().and_then(|e| e.get(1)).cloned();
3735                            }
3736                        }
3737                    }
3738                }
3739                _ => {}
3740            }
3741        }
3742        if let Some(entry) = current {
3743            entries.push(entry);
3744        }
3745        for i in 0..entries.len() {
3746            for j in (i + 1)..entries.len() {
3747                let ei = &entries[i];
3748                let ej = &entries[j];
3749                if !ei.zeitraum_id.is_empty()
3750                    && ei.zeitraum_id == ej.zeitraum_id
3751                    && ei.mg_id.is_some()
3752                    && !ei.mg_id.as_deref().unwrap_or("").is_empty()
3753                    && ei.mg_id == ej.mg_id
3754                {
3755                    return ConditionResult::True;
3756                }
3757            }
3758        }
3759        ConditionResult::False
3760    }
3761
3762    /// [125] Wenn in derselben SG8 SEQ+Z76/ ZC5/ ZC6 (Messstellenbetriebsabrechnungsdaten der Marktlokation) im DE4347 des PIA Z02 (Gruppenartikel-ID / Artikel-ID) vorhanden
3763    fn evaluate_125(&self, _ctx: &EvaluationContext) -> ConditionResult {
3764        // TODO: implement
3765        ConditionResult::Unknown
3766    }
3767
3768    /// [126] Es ist der Wert einzutragen, der sich aus der Wiederholungshäufigkeit des SG6 RFF+Z49/ Z53 (Verwendungszeitraum der Daten: Gültige Daten/ Keine Daten) ergibt. Bedeutet: Das erste SG6 RFF+Z49/ Z53...
3769    fn evaluate_126(&self, _ctx: &EvaluationContext) -> ConditionResult {
3770        // TODO: implement
3771        ConditionResult::Unknown
3772    }
3773
3774    /// [127] Es ist der Wert einzutragen, der sich aus der Wiederholungshäufigkeit des SG6 RFF+Z48/ Z55 (Verwendungszeitraum der Daten: Erwartete Daten/ Keine Daten erwartet) ergibt. Bedeutet: Das erste SG6  R...
3775    fn evaluate_127(&self, _ctx: &EvaluationContext) -> ConditionResult {
3776        // TODO: implement
3777        ConditionResult::Unknown
3778    }
3779
3780    /// [128] Es ist der Wert einzutragen, der sich aus der Wiederholungshäufigkeit des SG6 RFF+Z47/ Z54 (Verwendungszeitraum der Daten: Im System vorhandene Daten/ Im System keine Daten vorhanden) ergibt. Bede...
3781    fn evaluate_128(&self, _ctx: &EvaluationContext) -> ConditionResult {
3782        // TODO: implement
3783        ConditionResult::Unknown
3784    }
3785
3786    /// [129] Innerhalb eines SG4 IDE müssen alle DE3225 der SG5 LOC+Z16 (Marktlokation) den identischen Wert enthalten
3787    fn evaluate_129(&self, _ctx: &EvaluationContext) -> ConditionResult {
3788        // TODO: implement
3789        ConditionResult::Unknown
3790    }
3791
3792    /// [130] Wenn an Messlokation vorhanden
3793    fn evaluate_130(&self, _ctx: &EvaluationContext) -> ConditionResult {
3794        // TODO: implement
3795        ConditionResult::Unknown
3796    }
3797
3798    /// [131] Wenn dieses DTM+Z25 (Verwendung der Daten ab) im SG6 RFF (Verwendungszeitraum der Daten) mit der Zeitraum ID \"1\" im DE1156 gekennzeichnet ist, muss das Datum in diesem DE2380 der direkt auf DTM+1...
3799    fn evaluate_131(&self, _ctx: &EvaluationContext) -> ConditionResult {
3800        // TODO: implement
3801        ConditionResult::Unknown
3802    }
3803
3804    /// [132] Wenn dieses DTM+Z25 (Verwendung der Daten ab) im SG6 RFF (Verwendungszeitraum der Daten) mit der Zeitraum ID "1" im DE1156 gekennzeichnet ist, muss das Datum in diesem DE2380 der direkt auf DTM+137...
3805    // REVIEW: Validates that when RFF in SG6 has Zeitraum-ID '1' (elements[0][2] = DE1156), the DTM+Z25 date must equal the day immediately following DTM+137 (Nachrichtendatum) at 00:00. Parses the YYYYMMDD portion of DTM+137, computes next calendar day with correct month/year rollover, then checks that DTM+Z25's first 12 characters match YYYYMMDDHHMM with HHMM=0000. Note: German timezone offset (CET/CEST) validation is not performed — this checks the stored datetime value directly, which is the common encoding in EDIFACT 303 format for this use case. (medium confidence)
3806    fn evaluate_132(&self, ctx: &EvaluationContext) -> ConditionResult {
3807        // Condition applies only when RFF in SG6 has Zeitraum-ID "1" in DE1156 (elements[0][2])
3808        let has_zeitraum_id_1 = ctx.find_segments("RFF").iter().any(|s| {
3809            s.elements
3810                .first()
3811                .and_then(|e| e.get(2))
3812                .is_some_and(|v: &String| v == "1")
3813        });
3814        if !has_zeitraum_id_1 {
3815            return ConditionResult::False;
3816        }
3817        // Get message date from DTM+137 (format 303: CCYYMMDDHHmm...)
3818        let msg_date_str = match ctx
3819            .find_segments_with_qualifier("DTM", 0, "137")
3820            .into_iter()
3821            .next()
3822        {
3823            Some(seg) => match seg.elements.first().and_then(|e| e.get(1)) {
3824                Some(v) if v.len() >= 8 => v.clone(),
3825                _ => return ConditionResult::Unknown,
3826            },
3827            None => return ConditionResult::Unknown,
3828        };
3829        // Get DTM+Z25 (Verwendung der Daten ab) value
3830        let usage_date_str = match ctx
3831            .find_segments_with_qualifier("DTM", 0, "Z25")
3832            .into_iter()
3833            .next()
3834        {
3835            Some(seg) => match seg.elements.first().and_then(|e| e.get(1)) {
3836                Some(v) if v.len() >= 12 => v.clone(),
3837                _ => return ConditionResult::Unknown,
3838            },
3839            None => return ConditionResult::Unknown,
3840        };
3841        // Parse YYYYMMDD from DTM+137 value
3842        let year: u32 = match msg_date_str[..4].parse() {
3843            Ok(v) => v,
3844            Err(_) => return ConditionResult::Unknown,
3845        };
3846        let month: u32 = match msg_date_str[4..6].parse() {
3847            Ok(v) => v,
3848            Err(_) => return ConditionResult::Unknown,
3849        };
3850        let day: u32 = match msg_date_str[6..8].parse() {
3851            Ok(v) => v,
3852            Err(_) => return ConditionResult::Unknown,
3853        };
3854        let days_in_month: u32 = match month {
3855            1 | 3 | 5 | 7 | 8 | 10 | 12 => 31,
3856            4 | 6 | 9 | 11 => 30,
3857            2 => {
3858                if year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) {
3859                    29
3860                } else {
3861                    28
3862                }
3863            }
3864            _ => return ConditionResult::Unknown,
3865        };
3866        let (next_year, next_month, next_day): (u32, u32, u32) = if day >= days_in_month {
3867            if month == 12 {
3868                (year + 1, 1, 1)
3869            } else {
3870                (year, month + 1, 1)
3871            }
3872        } else {
3873            (year, month, day + 1)
3874        };
3875        // Expected DTM+Z25: next day at 00:00 — format 303 prefix YYYYMMDDHHMM = 12 chars
3876        let expected_prefix = format!("{:04}{:02}{:02}0000", next_year, next_month, next_day);
3877        let actual_len = usage_date_str.len().min(12);
3878        let actual_prefix = &usage_date_str[..actual_len];
3879        ConditionResult::from(actual_prefix == expected_prefix.as_str())
3880    }
3881
3882    /// [133] Wenn an der übermittelten Marktlokation / Messlokation vorhanden
3883    fn evaluate_133(&self, _ctx: &EvaluationContext) -> ConditionResult {
3884        // TODO: implement
3885        ConditionResult::Unknown
3886    }
3887
3888    /// [137] Nicht bei Neuanlage
3889    fn evaluate_137(&self, _ctx: &EvaluationContext) -> ConditionResult {
3890        // TODO: implement
3891        ConditionResult::Unknown
3892    }
3893
3894    /// [138] Wenn im selben QTY im DE6063 Z35 (Abschlag) vorhanden
3895    fn evaluate_138(&self, _ctx: &EvaluationContext) -> ConditionResult {
3896        // TODO: implement
3897        ConditionResult::Unknown
3898    }
3899
3900    /// [140] Wenn im selben QTY im DE6063 Z34/Z35 (Zuschlag/Abschlag) vorhanden
3901    fn evaluate_140(&self, _ctx: &EvaluationContext) -> ConditionResult {
3902        // TODO: implement
3903        ConditionResult::Unknown
3904    }
3905
3906    /// [141] Wenn SG10 CAV+MIW/ MPW/ MBW vorhanden
3907    fn evaluate_141(&self, _ctx: &EvaluationContext) -> ConditionResult {
3908        // TODO: implement
3909        ConditionResult::Unknown
3910    }
3911
3912    /// [142] Wenn SG8 PIA+Z01+:Z04/ Z05 (Berechnung Tagesmitteltemperatur: vom Anbieter zur Verfügung gestellte - / Äquivalente Tagesmitteltemperatur) vorhanden
3913    fn evaluate_142(&self, _ctx: &EvaluationContext) -> ConditionResult {
3914        // TODO: implement
3915        ConditionResult::Unknown
3916    }
3917
3918    /// [143] Wenn STS+7++ZX3 (Transaktionsgrund: Abrechnungsdaten BK-Abrechnung verbrauchender MaLo) vorhanden
3919    fn evaluate_143(&self, _ctx: &EvaluationContext) -> ConditionResult {
3920        // TODO: implement
3921        ConditionResult::Unknown
3922    }
3923
3924    /// [144] Wenn STS+7++ZAN (Transaktionsgrund: Korrektur Abrechnungsdaten BK-Abrechnung verbrauchender MaLo) vorhanden
3925    fn evaluate_144(&self, _ctx: &EvaluationContext) -> ConditionResult {
3926        // TODO: implement
3927        ConditionResult::Unknown
3928    }
3929
3930    /// [145] Wenn STS+7++ZX2 (Transaktionsgrund: Abrechnungsdaten BK-Abrechnung erzeugender MaLo) vorhanden
3931    fn evaluate_145(&self, _ctx: &EvaluationContext) -> ConditionResult {
3932        // TODO: implement
3933        ConditionResult::Unknown
3934    }
3935
3936    /// [146] Wenn STS+7++ZA0 (Transaktionsgrund: Korrektur Abrechnungsdaten BK-Abrechnung erzeugender MaLo) vorhanden
3937    fn evaluate_146(&self, _ctx: &EvaluationContext) -> ConditionResult {
3938        // TODO: implement
3939        ConditionResult::Unknown
3940    }
3941
3942    /// [147] Wenn in Anfrage vorhanden
3943    fn evaluate_147(&self, _ctx: &EvaluationContext) -> ConditionResult {
3944        // TODO: implement
3945        ConditionResult::Unknown
3946    }
3947
3948    /// [148] Wenn in dieser SG8 im SG8 PIA+Z02 (Gruppenartikel-ID / Artikel-ID), die Artikel-ID 1-02-0-017/ 1-02-0-018 vorhanden
3949    fn evaluate_148(&self, _ctx: &EvaluationContext) -> ConditionResult {
3950        // TODO: implement
3951        ConditionResult::Unknown
3952    }
3953
3954    /// [149] Wenn zwei SG8 SEQ+Z45 (Netznutzungsabrechnungsdaten der Marktlokation), mit  derselben Zeitraum-ID im DE1050, mit Artikel-ID im SG8 PIA+Z02 (Gruppenartikel-ID / Artikel-ID), eine SG8 mit 1-02-0-017...
3955    // REVIEW: Condition checks whether two SG8 SEQ+Z45 groups with the same Zeitraum-ID (elements[1][0]) each contain PIA+Z02 (DE4347=Z02) with product codes '1-02-0-017' and '1-02-0-018'. Uses collect_group_values to gather SEQ qualifiers and Zeitraum-IDs per group instance, then PIA qualifiers and product codes (elements[1][0]=DE7140) per group instance. Positional alignment of pia_quals and pia_prods (both from same PIA segments in same order) enables reliable qualifier-to-product matching. Groups product codes by Zeitraum-ID to check co-occurrence. (medium confidence)
3956    fn evaluate_149(&self, ctx: &EvaluationContext) -> ConditionResult {
3957        use std::collections::{HashMap, HashSet};
3958        let seq_quals = ctx.collect_group_values("SEQ", 0, 0, &["SG4", "SG8"]);
3959        let seq_zeitraum = ctx.collect_group_values("SEQ", 1, 0, &["SG4", "SG8"]);
3960        let pia_quals = ctx.collect_group_values("PIA", 0, 0, &["SG4", "SG8"]);
3961        let pia_prods = ctx.collect_group_values("PIA", 1, 0, &["SG4", "SG8"]);
3962        // Map group index -> Zeitraum-ID for SG8s with SEQ+Z45
3963        let mut idx_to_zeitraum: HashMap<usize, String> = HashMap::new();
3964        for ((gi, q), (_, zid)) in seq_quals.iter().zip(seq_zeitraum.iter()) {
3965            if q == "Z45" && !zid.is_empty() {
3966                idx_to_zeitraum.insert(*gi, zid.clone());
3967            }
3968        }
3969        if idx_to_zeitraum.is_empty() {
3970            return ConditionResult::False;
3971        }
3972        // Map Zeitraum-ID -> set of PIA+Z02 product codes found in the same SG8 group
3973        let mut zeitraum_products: HashMap<String, HashSet<String>> = HashMap::new();
3974        for (i, (gi, qual)) in pia_quals.iter().enumerate() {
3975            if qual == "Z02" {
3976                if let Some(zid) = idx_to_zeitraum.get(gi) {
3977                    if let Some((_, prod)) = pia_prods.get(i) {
3978                        if !prod.is_empty() {
3979                            zeitraum_products
3980                                .entry(zid.clone())
3981                                .or_default()
3982                                .insert(prod.clone());
3983                        }
3984                    }
3985                }
3986            }
3987        }
3988        ConditionResult::from(
3989            zeitraum_products
3990                .values()
3991                .any(|codes| codes.contains("1-02-0-017") && codes.contains("1-02-0-018")),
3992        )
3993    }
3994
3995    /// [150] Wenn in dieser SG8 im SG8 PIA+Z02 (Gruppenartikel-ID / Artikel-ID), die Artikel-ID 1-02-0-002 vorhanden
3996    fn evaluate_150(&self, _ctx: &EvaluationContext) -> ConditionResult {
3997        // TODO: implement
3998        ConditionResult::Unknown
3999    }
4000
4001    /// [151] Wenn bei der Bestellung ein Messprodukt der Codeliste der Konfigurationen aus dem Kapitel 4.4 mit dem Ü̈bertragungsweg \"aus dem SMGW\" bestellt wurde. Der Empfänger der Werte kann dadurch seine...
4002    fn evaluate_151(&self, ctx: &EvaluationContext) -> ConditionResult {
4003        ctx.external.evaluate("code_list_membership_check")
4004    }
4005
4006    /// [152] Wenn FTX+Z28 (IP-Range des Absenders) nicht vorhanden
4007    fn evaluate_152(&self, _ctx: &EvaluationContext) -> ConditionResult {
4008        // TODO: implement
4009        ConditionResult::Unknown
4010    }
4011
4012    /// [153] Wenn FTX+Z27 (IP-Adresse des Absenders) nicht vorhanden
4013    fn evaluate_153(&self, _ctx: &EvaluationContext) -> ConditionResult {
4014        // TODO: implement
4015        ConditionResult::Unknown
4016    }
4017
4018    /// [156] Wenn SG4 FTX+Z17 (Zieladresse URI) vorhanden
4019    fn evaluate_156(&self, _ctx: &EvaluationContext) -> ConditionResult {
4020        // TODO: implement
4021        ConditionResult::Unknown
4022    }
4023
4024    /// [161] Wenn SG4 STS+7++E03+ZW8 (Transaktionsgrundergänzung Fall 1) vorhanden
4025    fn evaluate_161(&self, _ctx: &EvaluationContext) -> ConditionResult {
4026        // TODO: implement
4027        ConditionResult::Unknown
4028    }
4029
4030    /// [162] Wenn SG4 STS+7++E03+ZW9 (Transaktionsgrundergänzung Fall 2) vorhanden
4031    fn evaluate_162(&self, _ctx: &EvaluationContext) -> ConditionResult {
4032        // TODO: implement
4033        ConditionResult::Unknown
4034    }
4035
4036    /// [163] Wenn SG4 STS+7++E03+ZX0 (Transaktionsgrundergänzung Fall 3) vorhanden
4037    fn evaluate_163(&self, _ctx: &EvaluationContext) -> ConditionResult {
4038        // TODO: implement
4039        ConditionResult::Unknown
4040    }
4041
4042    /// [164] Wenn SG4 STS+7++E03+ZX1 (Transaktionsgrundergänzung Fall 4) vorhanden
4043    fn evaluate_164(&self, _ctx: &EvaluationContext) -> ConditionResult {
4044        // TODO: implement
4045        ConditionResult::Unknown
4046    }
4047
4048    /// [165] Wenn bekannt
4049    fn evaluate_165(&self, _ctx: &EvaluationContext) -> ConditionResult {
4050        // TODO: implement
4051        ConditionResult::Unknown
4052    }
4053
4054    /// [166] Wenn vorhanden
4055    fn evaluate_166(&self, _ctx: &EvaluationContext) -> ConditionResult {
4056        // TODO: implement
4057        ConditionResult::Unknown
4058    }
4059
4060    /// [167] Wenn SG5 LOC+Z21 (Tranche) vorhanden
4061    fn evaluate_167(&self, _ctx: &EvaluationContext) -> ConditionResult {
4062        // TODO: implement
4063        ConditionResult::Unknown
4064    }
4065
4066    /// [170] Wenn Anschrift der Marktlokation vorhanden
4067    fn evaluate_170(&self, _ctx: &EvaluationContext) -> ConditionResult {
4068        // TODO: implement
4069        ConditionResult::Unknown
4070    }
4071
4072    /// [172] Wenn im selben QTY im DE6063 Z37 (Kein Zu- und Abschlag) vorhanden
4073    fn evaluate_172(&self, _ctx: &EvaluationContext) -> ConditionResult {
4074        // TODO: implement
4075        ConditionResult::Unknown
4076    }
4077
4078    /// [173] Wenn im RFF+Z33 (Referenz auf den Objektcode in der Lokationsbündelstruktur) das DE1156 (Fortlaufende Nummer eines Lokationsbündels im Geschäftsvorfall) in derselben SG8 SEQ+Z58/ ZC9/ ZD0/ ZD6 (...
4079    // REVIEW: Condition is True when, in an SG8 with SEQ+Z58/ZC9/ZD0/ZD6 (Zuordnung Lokation zum Objektcode), RFF+Z33 exists but its DE1156 (elements[0][2] = Fortlaufende Nummer) is absent or empty. Uses collect_group_values to find target SG8 group indices by SEQ qualifier, then positionally aligns rff_quals[i] with rff_de1156[i] (same RFF segment) to check DE1156 emptiness scoped to those groups. Returns Unknown if no RFF+Z33 found in target groups (condition not applicable), False if all RFF+Z33 have DE1156 present. (medium confidence)
4080    fn evaluate_173(&self, ctx: &EvaluationContext) -> ConditionResult {
4081        use std::collections::HashSet;
4082        let seq_quals = ctx.collect_group_values("SEQ", 0, 0, &["SG4", "SG8"]);
4083        let target_indices: HashSet<usize> = seq_quals
4084            .iter()
4085            .filter(|(_, q)| matches!(q.as_str(), "Z58" | "ZC9" | "ZD0" | "ZD6"))
4086            .map(|(i, _)| *i)
4087            .collect();
4088        if target_indices.is_empty() {
4089            return ConditionResult::Unknown;
4090        }
4091        // Collect RFF qualifier (elements[0][0]) and DE1156 (elements[0][2]) with positional alignment
4092        let rff_quals = ctx.collect_group_values("RFF", 0, 0, &["SG4", "SG8"]);
4093        let rff_de1156 = ctx.collect_group_values("RFF", 0, 2, &["SG4", "SG8"]);
4094        let mut found_rff_z33 = false;
4095        for (i, (gi, qual)) in rff_quals.iter().enumerate() {
4096            if qual == "Z33" && target_indices.contains(gi) {
4097                found_rff_z33 = true;
4098                let de1156_empty = rff_de1156.get(i).map(|(_, v)| v.is_empty()).unwrap_or(true);
4099                if de1156_empty {
4100                    return ConditionResult::True;
4101                }
4102            }
4103        }
4104        if found_rff_z33 {
4105            ConditionResult::False
4106        } else {
4107            ConditionResult::Unknown
4108        }
4109    }
4110
4111    /// [174] Wenn im RFF+Z33 (Referenz auf den Objektcode in der Lokationsbündelstruktur) das DE1156 Fortlaufende Nummer eines Lokationsbündels im Geschäftsvorfall) in derselben SG8 SEQ+Z58/ ZC9/ ZD0/ ZD6 (Z...
4112    fn evaluate_174(&self, _ctx: &EvaluationContext) -> ConditionResult {
4113        // TODO: implement
4114        ConditionResult::Unknown
4115    }
4116
4117    /// [175] Wenn der Objektcode im RFF+Z33 (Referenz auf den Objektcode in der Lokationsbündelstruktur) im DE1154 derselben SG8 SEQ+Z58 (Zuordnung Lokation zum Objektcode des Lokationsbündels) in einem weite...
4118    // REVIEW: Cross-SG8 check: find all SG8 instances with SEQ+Z58 that also have RFF+Z33. Check whether any Objektcode (DE1154) with the same fortlaufende Nummer (DE1156) appears in two distinct SG8 instances. Uses nav.find_segments_in_group to access SG8-level segments directly, following the existing navigator pattern. (medium confidence)
4119    fn evaluate_175(&self, ctx: &EvaluationContext) -> ConditionResult {
4120        let nav = match ctx.navigator {
4121            Some(n) => n,
4122            None => return ConditionResult::Unknown,
4123        };
4124        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
4125        let mut entries: Vec<(usize, String, String)> = Vec::new();
4126        for i in 0..sg8_count {
4127            let seqs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
4128            if !seqs.iter().any(|s| {
4129                s.elements
4130                    .first()
4131                    .and_then(|e: &Vec<String>| e.first())
4132                    .is_some_and(|v: &String| v == "Z58")
4133            }) {
4134                continue;
4135            }
4136            let rffs = nav.find_segments_in_group("RFF", &["SG4", "SG8"], i);
4137            for rff in &rffs {
4138                let elems = match rff.elements.first() {
4139                    Some(e) => e,
4140                    None => continue,
4141                };
4142                if elems.first().map(|s| s.as_str()) != Some("Z33") {
4143                    continue;
4144                }
4145                let objektcode = elems.get(1).cloned().unwrap_or_default();
4146                let fort_nr = elems.get(2).cloned().unwrap_or_default();
4147                if !objektcode.is_empty() {
4148                    entries.push((i, objektcode, fort_nr));
4149                }
4150            }
4151        }
4152        for a in 0..entries.len() {
4153            for b in (a + 1)..entries.len() {
4154                if entries[a].0 != entries[b].0
4155                    && entries[a].1 == entries[b].1
4156                    && entries[a].2 == entries[b].2
4157                {
4158                    return ConditionResult::True;
4159                }
4160            }
4161        }
4162        ConditionResult::False
4163    }
4164
4165    /// [176] Wenn in demselben Segment das DE1153 mit dem Code Z34 vorgelagerte Messlokation vorhanden ist
4166    fn evaluate_176(&self, _ctx: &EvaluationContext) -> ConditionResult {
4167        // TODO: implement
4168        ConditionResult::Unknown
4169    }
4170
4171    /// [177] Wenn in demselben Segment das DE1153 mit dem Code Z35 vorgelagerte Netzlokation vorhanden ist
4172    fn evaluate_177(&self, _ctx: &EvaluationContext) -> ConditionResult {
4173        // TODO: implement
4174        ConditionResult::Unknown
4175    }
4176
4177    /// [178] Wenn das LOC+Z18 (Netzlokation) vorhanden ist
4178    fn evaluate_178(&self, _ctx: &EvaluationContext) -> ConditionResult {
4179        // TODO: implement
4180        ConditionResult::Unknown
4181    }
4182
4183    /// [179] Wenn der Objektcode im RFF+Z33 (Referenz auf den Objektcode in der Lokationsbündelstruktur) im DE1154 derselben SG8 SEQ+Z58/ ZC9 / ZD0/ ZD6 (Zuordnung Lokation zum Objektcode des Lokationsbündels...
4184    fn evaluate_179(&self, _ctx: &EvaluationContext) -> ConditionResult {
4185        // TODO: implement
4186        ConditionResult::Unknown
4187    }
4188
4189    /// [180] Wenn im selben QTY im DE6063 Z46 (Kein Abschlag) vorhanden
4190    fn evaluate_180(&self, _ctx: &EvaluationContext) -> ConditionResult {
4191        // TODO: implement
4192        ConditionResult::Unknown
4193    }
4194
4195    /// [184] Wenn in derselben SG8 SEQ+Z18 (Daten der Messlokation) ein CCI+Z01++Z82 (Verwendungsumfang: ID der prozessual behandelten Messlokation) vorhanden
4196    fn evaluate_184(&self, _ctx: &EvaluationContext) -> ConditionResult {
4197        // TODO: implement
4198        ConditionResult::Unknown
4199    }
4200
4201    /// [190] Wenn in derselben SG8 SEQ+Z60/ ZG8/ ZG9/ ZE0  (Produkt-Daten der Netzlokation) PIA+5+9991000000721:Z12 vorhanden
4202    fn evaluate_190(&self, _ctx: &EvaluationContext) -> ConditionResult {
4203        // TODO: implement
4204        ConditionResult::Unknown
4205    }
4206
4207    /// [191] Wenn im SG4 IDE+Z01 (Identifikation einer Liste) STS+E01 (Status der Antwort der Liste) nicht vorhanden
4208    fn evaluate_191(&self, _ctx: &EvaluationContext) -> ConditionResult {
4209        // TODO: implement
4210        ConditionResult::Unknown
4211    }
4212
4213    /// [192] Wenn SG4 STS+7++XXX+ZW4/ZAP (Transaktionsgrund / Ergänzung: Verbrauchende Marktlokation / ruhende Marktlokation) vorhanden
4214    fn evaluate_192(&self, _ctx: &EvaluationContext) -> ConditionResult {
4215        // TODO: implement
4216        ConditionResult::Unknown
4217    }
4218
4219    /// [193] Wenn das SG10 CCI ZB5 (Spannungsebene der Summenzeitreihe) CAV E06 (Niederspannung) in dieser SG vorhanden
4220    fn evaluate_193(&self, ctx: &EvaluationContext) -> ConditionResult {
4221        let nav = match ctx.navigator {
4222            Some(n) => n,
4223            None => {
4224                let cavs = ctx.find_segments("CAV");
4225                return ConditionResult::from(cavs.iter().any(|s| {
4226                    s.elements
4227                        .first()
4228                        .and_then(|e: &Vec<String>| e.first())
4229                        .is_some_and(|v: &String| v == "E06")
4230                }));
4231            }
4232        };
4233        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
4234        for i in 0..sg8_count {
4235            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
4236            for j in 0..sg10_count {
4237                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
4238                let has_cci_zb5 = ccis.iter().any(|s| {
4239                    s.elements
4240                        .get(2)
4241                        .and_then(|e: &Vec<String>| e.first())
4242                        .is_some_and(|v: &String| v == "ZB5")
4243                });
4244                if !has_cci_zb5 {
4245                    continue;
4246                }
4247                let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
4248                if cavs.iter().any(|s| {
4249                    s.elements
4250                        .first()
4251                        .and_then(|e: &Vec<String>| e.first())
4252                        .is_some_and(|v: &String| v == "E06")
4253                }) {
4254                    return ConditionResult::True;
4255                }
4256            }
4257        }
4258        ConditionResult::False
4259    }
4260
4261    /// [194] Wenn das SG10 CCI ZB5 (Spannungsebene der Summenzeitreihe) CAV E05 (Mittelspannung) in dieser SG vorhanden
4262    fn evaluate_194(&self, _ctx: &EvaluationContext) -> ConditionResult {
4263        // TODO: implement
4264        ConditionResult::Unknown
4265    }
4266
4267    /// [195] Wenn das SG10 CCI ZB5 (Spannungsebene der Summenzeitreihe) CAV E04 (Hochspannung) in dieser SG vorhanden
4268    fn evaluate_195(&self, _ctx: &EvaluationContext) -> ConditionResult {
4269        // TODO: implement
4270        ConditionResult::Unknown
4271    }
4272
4273    /// [196] Wenn der Objektcode im RFF+Z33 (Referenz auf den Objektcode in der Lokationsbündelstruktur) im DE1154 derselben SG8 SEQ+Z58/ZC9/ZD0 (Zuordnung Lokation zum Objektcode des Lokationsbündels) in ein...
4274    // REVIEW: Extended cross-SG8 check vs 175: now requires matching SEQ qualifier code (DE1229), Zeitraum-ID from SEQ DE1050 (elements[1][0]), Objektcode (RFF+Z33 DE1154), AND fortlaufende Nummer (RFF+Z33 DE1156) to all be identical between two distinct SG8 instances. SEQ qualifiers are Z58/ZC9/ZD0 per schema. (medium confidence)
4275    fn evaluate_196(&self, ctx: &EvaluationContext) -> ConditionResult {
4276        let nav = match ctx.navigator {
4277            Some(n) => n,
4278            None => return ConditionResult::Unknown,
4279        };
4280        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
4281        let mut entries: Vec<(usize, String, String, String, String)> = Vec::new();
4282        for i in 0..sg8_count {
4283            let seqs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
4284            let seq_opt = seqs.iter().find(|s| {
4285                s.elements
4286                    .first()
4287                    .and_then(|e: &Vec<String>| e.first())
4288                    .is_some_and(|v: &String| matches!(v.as_str(), "Z58" | "ZC9" | "ZD0"))
4289            });
4290            let seq = match seq_opt {
4291                Some(s) => s,
4292                None => continue,
4293            };
4294            let seq_code = seq
4295                .elements
4296                .first()
4297                .and_then(|e: &Vec<String>| e.first())
4298                .cloned()
4299                .unwrap_or_default();
4300            let zeitraum_id = seq
4301                .elements
4302                .get(1)
4303                .and_then(|e: &Vec<String>| e.first())
4304                .cloned()
4305                .unwrap_or_default();
4306            let rffs = nav.find_segments_in_group("RFF", &["SG4", "SG8"], i);
4307            for rff in &rffs {
4308                let elems = match rff.elements.first() {
4309                    Some(e) => e,
4310                    None => continue,
4311                };
4312                if elems.first().map(|s| s.as_str()) != Some("Z33") {
4313                    continue;
4314                }
4315                let objektcode = elems.get(1).cloned().unwrap_or_default();
4316                let fort_nr = elems.get(2).cloned().unwrap_or_default();
4317                if !objektcode.is_empty() {
4318                    entries.push((
4319                        i,
4320                        seq_code.clone(),
4321                        zeitraum_id.clone(),
4322                        objektcode,
4323                        fort_nr,
4324                    ));
4325                }
4326            }
4327        }
4328        for a in 0..entries.len() {
4329            for b in (a + 1)..entries.len() {
4330                if entries[a].0 != entries[b].0
4331                    && entries[a].1 == entries[b].1
4332                    && entries[a].2 == entries[b].2
4333                    && entries[a].3 == entries[b].3
4334                    && entries[a].4 == entries[b].4
4335                {
4336                    return ConditionResult::True;
4337                }
4338            }
4339        }
4340        ConditionResult::False
4341    }
4342
4343    /// [197] Wenn das RFF+Z18 (Marktlokation) aus dieser SG8 auf das gleiche SG5 LOC+Z16 (Marktlokation), wie ein RFF+Z18 (Marktlokation) aus einer SG8 SEQ+Z01 (Daten der Marktlokation), in dem SG10 CCI+++ZA6 (...
4344    // REVIEW: Two-phase cross-SG8 check. Phase 1: collect Marktlokation IDs from SG8 instances that (a) have SEQ+Z01 and (b) have an SG10 child with CCI elements[2][0]=ZA6 and CAV elements[0][0]=E02. Phase 2: check whether any SG8's RFF+Z18 references one of those qualifying Marktlokation IDs, establishing the cross-reference described in the condition. (medium confidence)
4345    fn evaluate_197(&self, ctx: &EvaluationContext) -> ConditionResult {
4346        let nav = match ctx.navigator {
4347            Some(n) => n,
4348            None => return ConditionResult::Unknown,
4349        };
4350        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
4351        let mut qualifying_malo_ids: Vec<String> = Vec::new();
4352        for i in 0..sg8_count {
4353            let seqs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
4354            if !seqs.iter().any(|s| {
4355                s.elements
4356                    .first()
4357                    .and_then(|e: &Vec<String>| e.first())
4358                    .is_some_and(|v: &String| v == "Z01")
4359            }) {
4360                continue;
4361            }
4362            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
4363            let has_prog = (0..sg10_count).any(|j| {
4364                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
4365                let has_za6 = ccis.iter().any(|s| {
4366                    s.elements
4367                        .get(2)
4368                        .and_then(|e: &Vec<String>| e.first())
4369                        .is_some_and(|v: &String| v == "ZA6")
4370                });
4371                if !has_za6 {
4372                    return false;
4373                }
4374                let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
4375                cavs.iter().any(|s| {
4376                    s.elements
4377                        .first()
4378                        .and_then(|e: &Vec<String>| e.first())
4379                        .is_some_and(|v: &String| v == "E02")
4380                })
4381            });
4382            if !has_prog {
4383                continue;
4384            }
4385            let rffs = nav.find_segments_in_group("RFF", &["SG4", "SG8"], i);
4386            for rff in &rffs {
4387                let elems = match rff.elements.first() {
4388                    Some(e) => e,
4389                    None => continue,
4390                };
4391                if elems.first().map(|s| s.as_str()) != Some("Z18") {
4392                    continue;
4393                }
4394                if let Some(malo_id) = elems.get(1) {
4395                    if !malo_id.is_empty() {
4396                        qualifying_malo_ids.push(malo_id.clone());
4397                    }
4398                }
4399            }
4400        }
4401        if qualifying_malo_ids.is_empty() {
4402            return ConditionResult::False;
4403        }
4404        for i in 0..sg8_count {
4405            let rffs = nav.find_segments_in_group("RFF", &["SG4", "SG8"], i);
4406            for rff in &rffs {
4407                let elems = match rff.elements.first() {
4408                    Some(e) => e,
4409                    None => continue,
4410                };
4411                if elems.first().map(|s| s.as_str()) != Some("Z18") {
4412                    continue;
4413                }
4414                if let Some(malo_id) = elems.get(1) {
4415                    if qualifying_malo_ids.contains(malo_id) {
4416                        return ConditionResult::True;
4417                    }
4418                }
4419            }
4420        }
4421        ConditionResult::False
4422    }
4423
4424    /// [198] Wenn SG4 STS+7++E03(Transaktionsgrund: Wechsel) vorhanden
4425    fn evaluate_198(&self, _ctx: &EvaluationContext) -> ConditionResult {
4426        // TODO: implement
4427        ConditionResult::Unknown
4428    }
4429
4430    /// [199] Wenn in der SG8 SEQ+Z01/ SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) mit identischer Zeitraum-ID im DE1050 CAV+E02 (SLP/SEP) vorhanden
4431    // REVIEW: Checks whether any SG8 with SEQ+Z01 (Daten der Marktlokation) contains an SG10 child group where CCI elements[2][0]=ZA6 (Prognosegrundlage: Prognose auf Basis von Profilen) and CAV elements[0][0]=E02 (SLP/SEP) appear in the same SG10 instance. The 'identischer Zeitraum-ID' constraint from SEQ DE1050 is structurally satisfied by operating within the same SG8 instance; deeper Zeitraum-ID cross-referencing with other groups is omitted as it would require knowing the external referencing context. (medium confidence)
4432    fn evaluate_199(&self, ctx: &EvaluationContext) -> ConditionResult {
4433        let nav = match ctx.navigator {
4434            Some(n) => n,
4435            None => {
4436                return ctx.filtered_parent_child_has_qualifier(
4437                    &["SG4", "SG8"],
4438                    "SEQ",
4439                    0,
4440                    "Z01",
4441                    "SG10",
4442                    "CCI",
4443                    2,
4444                    "ZA6",
4445                )
4446            }
4447        };
4448        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
4449        for i in 0..sg8_count {
4450            let seqs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
4451            if !seqs.iter().any(|s| {
4452                s.elements
4453                    .first()
4454                    .and_then(|e: &Vec<String>| e.first())
4455                    .is_some_and(|v: &String| v == "Z01")
4456            }) {
4457                continue;
4458            }
4459            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
4460            for j in 0..sg10_count {
4461                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
4462                if !ccis.iter().any(|s| {
4463                    s.elements
4464                        .get(2)
4465                        .and_then(|e: &Vec<String>| e.first())
4466                        .is_some_and(|v: &String| v == "ZA6")
4467                }) {
4468                    continue;
4469                }
4470                let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
4471                if cavs.iter().any(|s| {
4472                    s.elements
4473                        .first()
4474                        .and_then(|e: &Vec<String>| e.first())
4475                        .is_some_and(|v: &String| v == "E02")
4476                }) {
4477                    return ConditionResult::True;
4478                }
4479            }
4480        }
4481        ConditionResult::False
4482    }
4483
4484    /// [201] Wenn die Marktlokation / Tranche nicht den ganzen Bilanzierungsmonat dem gleichen Tupel aus Bilanzkreis, Zeitreihentyp, Spannungsebene und Lieferant zugeordnet ist
4485    fn evaluate_201(&self, _ctx: &EvaluationContext) -> ConditionResult {
4486        // TODO: implement
4487        ConditionResult::Unknown
4488    }
4489
4490    /// [202] Wenn SG8 SEQ+Z78 RFF+Z39 (Keine standardisierte Lokationsbündelstruktur vorhanden), mit identischer Zeitraum-ID im DE1050 wie im DE3224 dieses Segments
4491    // REVIEW: Collects Zeitraum-IDs from SG5 LOC.DE3224 (elements[1][3]), checks SEQ+Z78 DE1050 (elements[1][0]) for a match, then verifies RFF+Z39 exists. Co-occurrence of SEQ+Z78 and RFF+Z39 in the same SG8 instance is not verified without navigator group-instance access. (medium confidence)
4492    fn evaluate_202(&self, ctx: &EvaluationContext) -> ConditionResult {
4493        use std::collections::HashSet;
4494        // Collect Zeitraum-IDs from all SG5 LOC segments (DE3224 at elements[1][3])
4495        let loc_zeitraum_ids: HashSet<String> = ctx
4496            .find_segments("LOC")
4497            .into_iter()
4498            .filter_map(|s| s.elements.get(1)?.get(3).cloned())
4499            .filter(|v| !v.is_empty())
4500            .collect();
4501        if loc_zeitraum_ids.is_empty() {
4502            return ConditionResult::False;
4503        }
4504        // Check if any SEQ+Z78 (SG8 Lokationsbündelstruktur) has DE1050 matching a LOC DE3224
4505        let matching_seq = ctx
4506            .find_segments_with_qualifier("SEQ", 0, "Z78")
4507            .into_iter()
4508            .any(|s| {
4509                s.elements
4510                    .get(1)
4511                    .and_then(|e: &Vec<String>| e.first())
4512                    .is_some_and(|v: &String| {
4513                        !v.is_empty() && loc_zeitraum_ids.contains(v.as_str())
4514                    })
4515            });
4516        if !matching_seq {
4517            return ConditionResult::False;
4518        }
4519        // Verify RFF+Z39 also exists (co-occurrence in same SG8 not verified without navigator)
4520        ctx.has_qualifier("RFF", 0, "Z39")
4521    }
4522
4523    /// [203] Wenn STS+7++E06 / Z39 / ZC6 / ZC7/ ZT6/ ZT7 vorhanden
4524    fn evaluate_203(&self, _ctx: &EvaluationContext) -> ConditionResult {
4525        // TODO: implement
4526        ConditionResult::Unknown
4527    }
4528
4529    /// [204] Wenn im SG8+SEQ+Z03/ ZA3/ ZA4 (Zähleinrichtungsdaten) mit der selben Zeitraum-ID im SG8 SEQ DE1050, sowie identischer Qualität im DE1229 der SG8 SEQ für die in diesem RFF DE1154 genannte Geräte...
4530    // REVIEW: Checks each Zähleinrichtungsdaten SEQ qualifier (Z03/ZA3/ZA4) — if any SG8 instance has that SEQ qualifier but no RFF+Z14 (Smartmeter-Gateway reference), the condition is true. The additional Zeitraum-ID and Gerätenummer cross-matching from the full condition text cannot be implemented without per-instance SG8 segment access. (medium confidence)
4531    fn evaluate_204(&self, ctx: &EvaluationContext) -> ConditionResult {
4532        // True if any SG8 with Zähleinrichtungsdaten (SEQ+Z03/ZA3/ZA4) lacks RFF+Z14 (Smartmeter-Gateway)
4533        for qual in &["Z03", "ZA3", "ZA4"] {
4534            if matches!(
4535                ctx.any_group_has_qualifier_without(
4536                    "SEQ",
4537                    0,
4538                    qual,
4539                    "RFF",
4540                    0,
4541                    "Z14",
4542                    &["SG4", "SG8"]
4543                ),
4544                ConditionResult::True
4545            ) {
4546                return ConditionResult::True;
4547            }
4548        }
4549        ConditionResult::False
4550    }
4551
4552    /// [205] Wenn SG5 LOC+Z19 (Steuerbare Ressource) vorhanden
4553    fn evaluate_205(&self, _ctx: &EvaluationContext) -> ConditionResult {
4554        // TODO: implement
4555        ConditionResult::Unknown
4556    }
4557
4558    /// [209] Wenn im selben Segment im DE2379 der Code 303 vorhanden ist
4559    fn evaluate_209(&self, _ctx: &EvaluationContext) -> ConditionResult {
4560        // TODO: implement
4561        ConditionResult::Unknown
4562    }
4563
4564    /// [210] Wenn SG10 CCI+++ZA6 (Prognose auf Basis von Profilen) in dieser SG8 vorhanden
4565    fn evaluate_210(&self, _ctx: &EvaluationContext) -> ConditionResult {
4566        // TODO: implement
4567        ConditionResult::Unknown
4568    }
4569
4570    /// [212] Wenn im selben SG12 NAD DE3124 nicht vorhanden
4571    fn evaluate_212(&self, _ctx: &EvaluationContext) -> ConditionResult {
4572        // TODO: implement
4573        ConditionResult::Unknown
4574    }
4575
4576    /// [213] Wenn SG12 NAD+Z09 (Kunde des Lieferanten) vorhanden
4577    fn evaluate_213(&self, _ctx: &EvaluationContext) -> ConditionResult {
4578        // TODO: implement
4579        ConditionResult::Unknown
4580    }
4581
4582    /// [215] Wenn in derselben SG8 (Zähleinrichtungsdaten) SG10 CCI+++E13 CAV+MME (Zählertyp: mME) vorhanden
4583    fn evaluate_215(&self, _ctx: &EvaluationContext) -> ConditionResult {
4584        // TODO: implement
4585        ConditionResult::Unknown
4586    }
4587
4588    /// [216] Wenn CCI+++Z88 (Netznutzung) CAV+Z74:::Z08 (Netznutzungsvertrag: Direkter Vertrag zwischen Kunden und NB) vorhanden
4589    fn evaluate_216(&self, _ctx: &EvaluationContext) -> ConditionResult {
4590        // TODO: implement
4591        ConditionResult::Unknown
4592    }
4593
4594    /// [217] Wenn SG6 RFF+Z49 (Verwendungszeitraum der Daten: \"Gültige Daten\") vorhanden
4595    fn evaluate_217(&self, _ctx: &EvaluationContext) -> ConditionResult {
4596        // TODO: implement
4597        ConditionResult::Unknown
4598    }
4599
4600    /// [219] Wenn SG12 NAD+Z65 (Informativer Kunde des Lieferanten) vorhanden
4601    fn evaluate_219(&self, _ctx: &EvaluationContext) -> ConditionResult {
4602        // TODO: implement
4603        ConditionResult::Unknown
4604    }
4605
4606    /// [220] Wenn SG8 SEQ+Z01/ Z98 (Daten der Marktlokation) SG10 CCI+Z30++Z06 (Lieferrichtung: Erzeugung) in dieser SG8 vorhanden
4607    fn evaluate_220(&self, _ctx: &EvaluationContext) -> ConditionResult {
4608        // TODO: implement
4609        ConditionResult::Unknown
4610    }
4611
4612    /// [221] Wenn kein SG8 SEQ+Z15 (Daten der Tranche) auf die gleiche Marktlokation-ID mit dem RFF+Z18 (Marktlokation) referenziert wie dieses SG8 SEQ+Z01 (Daten der Marktlokation)
4613    fn evaluate_221(&self, _ctx: &EvaluationContext) -> ConditionResult {
4614        // TODO: implement
4615        ConditionResult::Unknown
4616    }
4617
4618    /// [223] Wenn das RFF+Z18 (Marktlokation) aus dieser SG8 auf das gleiche SG5 LOC+Z16 (Marktlokation), wie ein RFF+Z18 (Marktlokation) aus einer SG8 SEQ+Z01 (Daten der Marktlokation) verweist, und dort das S...
4619    fn evaluate_223(&self, _ctx: &EvaluationContext) -> ConditionResult {
4620        // TODO: implement
4621        ConditionResult::Unknown
4622    }
4623
4624    /// [224] Wenn kein SG8 SEQ+ZE7 (Informative Daten der Tranche) auf die gleiche Marktlokation-ID mit dem RFF+Z18 (Marktlokation) referenziert wie dieses SG8 SEQ+Z98 (Informative Daten der Marktlokation)
4625    fn evaluate_224(&self, _ctx: &EvaluationContext) -> ConditionResult {
4626        // TODO: implement
4627        ConditionResult::Unknown
4628    }
4629
4630    /// [227] Wenn im SG8 SEQ+Z98 (Daten der Marktlokation) das SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) CAV+E14 (TLP/TEP) vorhanden
4631    fn evaluate_227(&self, _ctx: &EvaluationContext) -> ConditionResult {
4632        // TODO: implement
4633        ConditionResult::Unknown
4634    }
4635
4636    /// [229] Wenn der Objektcode im RFF+Z33 (Referenz auf den Objektcode in der Lokationsbündelstruktur) im DE1154 derselben SG8 SEQ+Z58/ ZC9/ ZD0/ ZD6 (Zuordnung Lokation zum Objektcode des Lokationsbündels)...
4637    // REVIEW: Detects if the same (SEQ-qualifier, Zeitraum-ID, RFF+Z33-Objektcode) triple appears in two different SG8 instances — which is what the condition guards against. Uses collect_group_values to correlate SEQ and RFF data by SG8 instance index. Limitation: collect_group_values may only return the first RFF per SG8 instance, so Z33 may be missed if it is not the first RFF in the group. (medium confidence)
4638    fn evaluate_229(&self, ctx: &EvaluationContext) -> ConditionResult {
4639        use std::collections::HashSet;
4640        let target_quals: HashSet<&str> = ["Z58", "ZC9", "ZD0", "ZD6"].iter().cloned().collect();
4641        // Collect per-SG8-instance: SEQ qualifier and Zeitraum-ID
4642        let seq_quals = ctx.collect_group_values("SEQ", 0, 0, &["SG4", "SG8"]);
4643        let seq_zeitraums = ctx.collect_group_values("SEQ", 1, 0, &["SG4", "SG8"]);
4644        // Collect per-SG8-instance: RFF qualifier and DE1154 value
4645        let rff_quals = ctx.collect_group_values("RFF", 0, 0, &["SG4", "SG8"]);
4646        let rff_codes = ctx.collect_group_values("RFF", 0, 1, &["SG4", "SG8"]);
4647        // Detect duplicate (seq_qual, zeitraum_id, objektcode) combinations across SG8 instances
4648        let mut seen: HashSet<(String, String, String)> = HashSet::new();
4649        for (idx, seq_qual) in &seq_quals {
4650            if seq_qual.is_empty() || !target_quals.contains(seq_qual.as_str()) {
4651                continue;
4652            }
4653            let zeitraum_id = seq_zeitraums
4654                .iter()
4655                .find(|(i, _)| i == idx)
4656                .map(|(_, v)| v.as_str())
4657                .unwrap_or("");
4658            // Find RFF+Z33 in this SG8 instance (correlation by instance index)
4659            for (ridx, rff_qual) in rff_quals.iter() {
4660                if ridx != idx || rff_qual != "Z33" {
4661                    continue;
4662                }
4663                if let Some((_, obj_code)) = rff_codes.iter().find(|(i, _)| i == ridx) {
4664                    if obj_code.is_empty() {
4665                        continue;
4666                    }
4667                    let key = (seq_qual.clone(), zeitraum_id.to_string(), obj_code.clone());
4668                    if seen.contains(&key) {
4669                        return ConditionResult::True;
4670                    }
4671                    seen.insert(key);
4672                }
4673            }
4674        }
4675        ConditionResult::False
4676    }
4677
4678    /// [232] Wenn SG10 CCI+++Z83 (Messtechnische Einordnung der Marktlokation) CAV+Z52 (iMS) vorhanden
4679    fn evaluate_232(&self, _ctx: &EvaluationContext) -> ConditionResult {
4680        // TODO: implement
4681        ConditionResult::Unknown
4682    }
4683
4684    /// [233] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle NB
4685    fn evaluate_233(&self, ctx: &EvaluationContext) -> ConditionResult {
4686        ctx.external.evaluate("recipient_role_check")
4687    }
4688
4689    /// [234] Wenn SG10 CCI+++Z83 (Messtechnische Einordnung der Marktlokation) CAV+Z53 (kME/ mME) vorhanden
4690    fn evaluate_234(&self, _ctx: &EvaluationContext) -> ConditionResult {
4691        // TODO: implement
4692        ConditionResult::Unknown
4693    }
4694
4695    /// [237] Wenn in derselben SG8 im DE7140 des PIA+Z02 (Gruppenartikel-ID / Artikel-ID) eine Gruppenartikel-ID / Artikel-ID mit 1-06 (entspricht Entgelte des Messstellenbetriebs bei kME) beginnt
4696    fn evaluate_237(&self, _ctx: &EvaluationContext) -> ConditionResult {
4697        // TODO: implement
4698        ConditionResult::Unknown
4699    }
4700
4701    /// [238] Wenn SG4 IDE+24 (Vorgang) nicht vorhanden
4702    fn evaluate_238(&self, _ctx: &EvaluationContext) -> ConditionResult {
4703        // TODO: implement
4704        ConditionResult::Unknown
4705    }
4706
4707    /// [239] Wenn in derselben SG10 das CCI+Z17 (Stromverbrauchsart) im CAV+Z65 (Wärme/Kälte) vorhanden
4708    fn evaluate_239(&self, _ctx: &EvaluationContext) -> ConditionResult {
4709        // TODO: implement
4710        ConditionResult::Unknown
4711    }
4712
4713    /// [240] Wenn SG8 SEQ+Z01 (Daten der Marktlokation) CCI+Z22++Z91 (Veräußerungsform der erzeugenden Marktlokation:: Marktprämie) vorhanden
4714    fn evaluate_240(&self, _ctx: &EvaluationContext) -> ConditionResult {
4715        // TODO: implement
4716        ConditionResult::Unknown
4717    }
4718
4719    /// [241] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle MSB
4720    fn evaluate_241(&self, ctx: &EvaluationContext) -> ConditionResult {
4721        ctx.external.evaluate("recipient_role_check")
4722    }
4723
4724    /// [243] Wenn SG10 CCI+6++ZA8 (Aggreg.verantw. NB) in dieser SG8 vorhanden
4725    fn evaluate_243(&self, _ctx: &EvaluationContext) -> ConditionResult {
4726        // TODO: implement
4727        ConditionResult::Unknown
4728    }
4729
4730    /// [244] Wenn SG10 CCI+6++ZA9 (Aggreg.verantw. ÜNB) in dieser SG8 vorhanden
4731    fn evaluate_244(&self, _ctx: &EvaluationContext) -> ConditionResult {
4732        // TODO: implement
4733        ConditionResult::Unknown
4734    }
4735
4736    /// [248] Wenn die Inbetriebnahme der verbrauchenden Marktlokation innerhalb der letzten drei Jahre war und die Energie der Marktlokation mit iMS ausgestatteten Messlokationen erfolgt
4737    fn evaluate_248(&self, _ctx: &EvaluationContext) -> ConditionResult {
4738        // TODO: implement
4739        ConditionResult::Unknown
4740    }
4741
4742    /// [249] Innerhalb eines SG4 IDE müssen alle DE1131 der SG4 STS+E01 (Status der Antwort) den identischen Wert enthalten
4743    fn evaluate_249(&self, _ctx: &EvaluationContext) -> ConditionResult {
4744        // TODO: implement
4745        ConditionResult::Unknown
4746    }
4747
4748    /// [251] Wenn MP-ID in SG2 NAD+MS (Nachrichtensender) in der Rolle BIKO
4749    fn evaluate_251(&self, ctx: &EvaluationContext) -> ConditionResult {
4750        ctx.external.evaluate("sender_role_check")
4751    }
4752
4753    /// [252] Wenn DE0068 vorhanden
4754    fn evaluate_252(&self, _ctx: &EvaluationContext) -> ConditionResult {
4755        // TODO: implement
4756        ConditionResult::Unknown
4757    }
4758
4759    /// [254] Es ist der Code \"AUA\" einzutragen
4760    fn evaluate_254(&self, _ctx: &EvaluationContext) -> ConditionResult {
4761        // TODO: implement
4762        ConditionResult::Unknown
4763    }
4764
4765    /// [255] Wenn Marktlokation am Redispatch 2.0 teilnimmt
4766    fn evaluate_255(&self, _ctx: &EvaluationContext) -> ConditionResult {
4767        // TODO: implement
4768        ConditionResult::Unknown
4769    }
4770
4771    /// [256] Wenn in derselben SG8 SEQ (OBIS-Daten der Zähleinrichtung / Smartmeter-Gateway) das PIA+5+1-b?:1.8.e / 1-b?:2.8.e vorhanden
4772    fn evaluate_256(&self, _ctx: &EvaluationContext) -> ConditionResult {
4773        // TODO: implement
4774        ConditionResult::Unknown
4775    }
4776
4777    /// [257] Wenn in derselben SG8 SEQ (OBIS-Daten der Marktlokation) das PIA+5+1-b?:1.9.e vorhanden
4778    fn evaluate_257(&self, _ctx: &EvaluationContext) -> ConditionResult {
4779        // TODO: implement
4780        ConditionResult::Unknown
4781    }
4782
4783    /// [259] Wenn in diesem PIA der Code im DE7140 mit 1-01, 1-03, 1-05 enthalten ist
4784    fn evaluate_259(&self, _ctx: &EvaluationContext) -> ConditionResult {
4785        // TODO: implement
4786        ConditionResult::Unknown
4787    }
4788
4789    /// [261] Wenn in diesem PIA der Code im DE7140 mit 1-07-1/2, 1-10-1/2/4/5/6/7/8/9, 1-11-1 beginnt
4790    fn evaluate_261(&self, _ctx: &EvaluationContext) -> ConditionResult {
4791        // TODO: implement
4792        ConditionResult::Unknown
4793    }
4794
4795    /// [262] Wenn Produkt an der Marktlokation vorhanden ist
4796    fn evaluate_262(&self, _ctx: &EvaluationContext) -> ConditionResult {
4797        // TODO: implement
4798        ConditionResult::Unknown
4799    }
4800
4801    /// [265] Wenn im SG8 SEQ+Z01/ Z98 (Daten der Marktlokation) das SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis von Profilen) CAV+Z36 (TEP m. Referenzmessung) vorhanden
4802    fn evaluate_265(&self, _ctx: &EvaluationContext) -> ConditionResult {
4803        // TODO: implement
4804        ConditionResult::Unknown
4805    }
4806
4807    /// [266] Wenn im SG8 SEQ+Z01 (Daten der Marktlokation) mit identischer Zeitraum-ID im SG8 SEQ+Z01 DE1050 wie in dieser SG8 SEQ, das SG10 CCI+++ZA6 (Prognosegrundlage der Marktlokation: Prognose auf Basis vo...
4808    // REVIEW: Navigates all SG8 instances and their SG10 children, checking for CCI with elements[2][0]=ZA6 (Prognosegrundlage) co-occurring with CAV with elements[0][0]=Z36 (TEP m. Referenzmessung) in the same SG10 instance. The parent SG8 SEQ+Z01 filter and Zeitraum-ID cross-matching are not verified due to lack of direct SG8-level segment access; relies on CCI+ZA6/CAV+Z36 being specific enough to Marktlokation groups. (medium confidence)
4809    fn evaluate_266(&self, ctx: &EvaluationContext) -> ConditionResult {
4810        let nav = match ctx.navigator {
4811            Some(n) => n,
4812            None => {
4813                // Fallback: check any SG8+SEQ+Z01 child SG10 has CAV+Z36
4814                return ctx.filtered_parent_child_has_qualifier(
4815                    &["SG4", "SG8"],
4816                    "SEQ",
4817                    0,
4818                    "Z01",
4819                    "SG10",
4820                    "CAV",
4821                    0,
4822                    "Z36",
4823                );
4824            }
4825        };
4826        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
4827        for i in 0..sg8_count {
4828            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
4829            for j in 0..sg10_count {
4830                // CCI+++ZA6 means elements[2][0] == "ZA6"
4831                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
4832                let has_cci_za6 = ccis.iter().any(|s| {
4833                    s.elements
4834                        .get(2)
4835                        .and_then(|e: &Vec<String>| e.first())
4836                        .is_some_and(|v: &String| v == "ZA6")
4837                });
4838                if has_cci_za6 {
4839                    let cavs =
4840                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
4841                    if cavs.iter().any(|s| {
4842                        s.elements
4843                            .first()
4844                            .and_then(|e: &Vec<String>| e.first())
4845                            .is_some_and(|v: &String| v == "Z36")
4846                    }) {
4847                        return ConditionResult::True;
4848                    }
4849                }
4850            }
4851        }
4852        ConditionResult::False
4853    }
4854
4855    /// [267] Wenn SG8 SEQ+Z38 (Referenzprofildaten) nicht vorhanden
4856    fn evaluate_267(&self, _ctx: &EvaluationContext) -> ConditionResult {
4857        // TODO: implement
4858        ConditionResult::Unknown
4859    }
4860
4861    /// [268] Wenn der Code im DE3207 in der \"EDI@Energy Codeliste der europäischen Ländercodes\" in der Spalte \"PLZ vorhanden\" ein \"X\" aufgeführt ist
4862    fn evaluate_268(&self, _ctx: &EvaluationContext) -> ConditionResult {
4863        // TODO: implement
4864        ConditionResult::Unknown
4865    }
4866
4867    /// [269] Es sind alle OBIS-Kennzahlen gem. EDI@Energy Codeliste der OBIS-Kennzahlen und Medien für den deutschen Energiemarkt Kap.3 anzugeben welche an der Tranche erforderlich sind
4868    fn evaluate_269(&self, _ctx: &EvaluationContext) -> ConditionResult {
4869        // TODO: implement
4870        ConditionResult::Unknown
4871    }
4872
4873    /// [270] Wenn in diesem PIA der Code im DE7140 mit 1-02, 1-04, 1-06, 1-09 beginnt
4874    fn evaluate_270(&self, _ctx: &EvaluationContext) -> ConditionResult {
4875        // TODO: implement
4876        ConditionResult::Unknown
4877    }
4878
4879    /// [273] Wenn in derselben SG8 SEQ+Z20 (OBIS-Daten der Zähleinrichtung / Smartmeter-Gateway) das PIA+5+1-b?:1.8.e / 1-b?:2.8.e / 1-b?:3.8.e / 1-b?:4.8.e / 1-b?:5.8.e / 1-b?:6.8.e / 1-b?:7.8.e / 1-b?:8.8.e ...
4880    fn evaluate_273(&self, _ctx: &EvaluationContext) -> ConditionResult {
4881        // TODO: implement
4882        ConditionResult::Unknown
4883    }
4884
4885    /// [279] Wenn STS+7++xxx+ZW4 / ZAP (Transaktionsgrundergänzung  verbrauchende Marktlokation / ruhende Marktlokation) vorhanden
4886    fn evaluate_279(&self, _ctx: &EvaluationContext) -> ConditionResult {
4887        // TODO: implement
4888        ConditionResult::Unknown
4889    }
4890
4891    /// [280] Nur MP-ID aus Sparte Strom
4892    fn evaluate_280(&self, _ctx: &EvaluationContext) -> ConditionResult {
4893        // TODO: implement
4894        ConditionResult::Unknown
4895    }
4896
4897    /// [282] Wenn in diesem PIA der Code im DE7140 1-01-6-005, 1-01-9-001/002, 1-07-3-001, 1- 08-1-001, 1-08-3-001, 1-08-4-001/002/003/004, 1-10-3-001 enthalten ist
4898    fn evaluate_282(&self, _ctx: &EvaluationContext) -> ConditionResult {
4899        // TODO: implement
4900        ConditionResult::Unknown
4901    }
4902
4903    /// [284] Erlaubte Codes aus der Codeliste der Gruppenartikel- und Artikel-ID sind in der Spalte UTILMD/Codeverwendung mit X gekennzeichnet
4904    fn evaluate_284(&self, _ctx: &EvaluationContext) -> ConditionResult {
4905        // TODO: implement
4906        ConditionResult::Unknown
4907    }
4908
4909    /// [285] Wenn in diesem PIA der Code im DE7140 mit 1-08-3-AGS angegeben ist
4910    fn evaluate_285(&self, _ctx: &EvaluationContext) -> ConditionResult {
4911        // TODO: implement
4912        ConditionResult::Unknown
4913    }
4914
4915    /// [286] Wenn in diesem PIA der Code im DE7140 mit 1-08-1/2/4/5-AGS-KG
4916    fn evaluate_286(&self, _ctx: &EvaluationContext) -> ConditionResult {
4917        // TODO: implement
4918        ConditionResult::Unknown
4919    }
4920
4921    /// [287] Erlaubte Codes aus der PRICAT BGM+ Z70 (Preisblatt Netznutzung) des verantwortlichen NB
4922    fn evaluate_287(&self, _ctx: &EvaluationContext) -> ConditionResult {
4923        // TODO: implement
4924        ConditionResult::Unknown
4925    }
4926
4927    /// [288] Wenn in derselben SG8 (OBIS-Daten der Marktlokation) das PIA+5+1-b?:2.9.e vorhanden
4928    fn evaluate_288(&self, _ctx: &EvaluationContext) -> ConditionResult {
4929        // TODO: implement
4930        ConditionResult::Unknown
4931    }
4932
4933    /// [291] Wenn in derselben SG8 (Zuordnung Lokation zum Objektcode des Lokationsbündels) das RFF+Z37 vorhanden
4934    fn evaluate_291(&self, _ctx: &EvaluationContext) -> ConditionResult {
4935        // TODO: implement
4936        ConditionResult::Unknown
4937    }
4938
4939    /// [292] Es sind nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 6.1 \"Anmeldung einer Zuordnung des LFN (UTILMD)\" in der Spalte \"Anmeldung einer Zuordnung des LFN (UTIL...
4940    fn evaluate_292(&self, ctx: &EvaluationContext) -> ConditionResult {
4941        ctx.external.evaluate("code_list_membership_check")
4942    }
4943
4944    /// [293] Wenn SG5 LOC+Z22 (ruhende Marktlokation) vorhanden
4945    fn evaluate_293(&self, _ctx: &EvaluationContext) -> ConditionResult {
4946        // TODO: implement
4947        ConditionResult::Unknown
4948    }
4949
4950    /// [294] Wenn SG5 LOC+Z18 (Netzlokation) vorhanden
4951    fn evaluate_294(&self, _ctx: &EvaluationContext) -> ConditionResult {
4952        // TODO: implement
4953        ConditionResult::Unknown
4954    }
4955
4956    /// [295] Wenn SG5 LOC+Z15 (MaBiS-Zählpunkt) nicht vorhanden
4957    fn evaluate_295(&self, _ctx: &EvaluationContext) -> ConditionResult {
4958        // TODO: implement
4959        ConditionResult::Unknown
4960    }
4961
4962    /// [296] Wenn SG5 LOC+Z20 (Technische Ressource) vorhanden
4963    fn evaluate_296(&self, _ctx: &EvaluationContext) -> ConditionResult {
4964        // TODO: implement
4965        ConditionResult::Unknown
4966    }
4967
4968    /// [298] Wenn SG5 LOC+Z20 (Technische Ressource) nicht vorhanden
4969    fn evaluate_298(&self, _ctx: &EvaluationContext) -> ConditionResult {
4970        // TODO: implement
4971        ConditionResult::Unknown
4972    }
4973
4974    /// [300] Wenn SG8 SEQ+Z15/ ZE7 (Daten der Tranche) nicht vorhanden
4975    fn evaluate_300(&self, _ctx: &EvaluationContext) -> ConditionResult {
4976        // TODO: implement
4977        ConditionResult::Unknown
4978    }
4979
4980    /// [301] Wenn BGM+E03 (Änderungsmeldung) vorhanden
4981    fn evaluate_301(&self, _ctx: &EvaluationContext) -> ConditionResult {
4982        // TODO: implement
4983        ConditionResult::Unknown
4984    }
4985
4986    /// [302] Wenn SG8 SEQ+Z08 (Profilschardaten) nicht vorhanden
4987    fn evaluate_302(&self, _ctx: &EvaluationContext) -> ConditionResult {
4988        // TODO: implement
4989        ConditionResult::Unknown
4990    }
4991
4992    /// [303] Wenn SG8 SEQ+Z21 (Profildaten) nicht vorhanden
4993    fn evaluate_303(&self, _ctx: &EvaluationContext) -> ConditionResult {
4994        // TODO: implement
4995        ConditionResult::Unknown
4996    }
4997
4998    /// [304] Wenn SG8 SEQ+Z22 (Daten der Summenzeitreihe) vorhanden
4999    fn evaluate_304(&self, _ctx: &EvaluationContext) -> ConditionResult {
5000        // TODO: implement
5001        ConditionResult::Unknown
5002    }
5003
5004    /// [305] Wenn SG8 SEQ+Z24 (Daten der Überführungszeitreihe) vorhanden
5005    fn evaluate_305(&self, _ctx: &EvaluationContext) -> ConditionResult {
5006        // TODO: implement
5007        ConditionResult::Unknown
5008    }
5009
5010    /// [306] Wenn SG5 LOC+Z22 (ruhende Marktlokation) mit derselben Zeitraum-ID im DE3224 vorhanden wie in dieser SG8 im DE1050 (Referenz auf Zeitraum-ID) des SEQ+Z58
5011    fn evaluate_306(&self, ctx: &EvaluationContext) -> ConditionResult {
5012        use std::collections::HashSet;
5013        // Collect Zeitraum-IDs from SG5 LOC+Z22 (Ruhende Marktlokation) — DE3224 at elements[1][3]
5014        let loc_z22_ids: HashSet<String> = ctx
5015            .find_segments_with_qualifier("LOC", 0, "Z22")
5016            .into_iter()
5017            .filter_map(|s| s.elements.get(1)?.get(3).cloned())
5018            .filter(|v| !v.is_empty())
5019            .collect();
5020        if loc_z22_ids.is_empty() {
5021            return ConditionResult::False;
5022        }
5023        // Check if any SG8 SEQ+Z58 has DE1050 (elements[1][0]) matching a LOC+Z22 DE3224
5024        let has_match = ctx
5025            .find_segments_with_qualifier("SEQ", 0, "Z58")
5026            .iter()
5027            .any(|s| {
5028                s.elements
5029                    .get(1)
5030                    .and_then(|e: &Vec<String>| e.first())
5031                    .is_some_and(|v: &String| !v.is_empty() && loc_z22_ids.contains(v.as_str()))
5032            });
5033        ConditionResult::from(has_match)
5034    }
5035
5036    /// [307] Wenn SG5 LOC+Z22 (ruhende Marktlokation) mit derselben Zeitraum-ID im DE3224 nicht vorhanden wie in dieser SG8 im DE1050 (Referenz auf Zeitraum-ID) des SEQ+Z58
5037    // REVIEW: Collects Zeitraum-IDs from SG5 LOC+Z22 segments (DE3224 = elements[1][3]) and SEQ+Z58 segments (DE1050 = elements[1][0]). Returns True when any SEQ+Z58 has a Zeitraum-ID with no matching LOC+Z22 entry. Message-wide fallback since group-level Zeitraum-ID isolation is not possible without navigator. (medium confidence)
5038    fn evaluate_307(&self, ctx: &EvaluationContext) -> ConditionResult {
5039        let seq_segs = ctx.find_segments_with_qualifier("SEQ", 0, "Z58");
5040        if seq_segs.is_empty() {
5041            return ConditionResult::Unknown;
5042        }
5043        let loc_segs = ctx.find_segments_with_qualifier("LOC", 0, "Z22");
5044        let loc_z22_zeitraum_ids: Vec<&str> = loc_segs
5045            .iter()
5046            .filter_map(|s| s.elements.get(1).and_then(|e| e.get(3)).map(|v| v.as_str()))
5047            .filter(|v| !v.is_empty())
5048            .collect();
5049        ConditionResult::from(seq_segs.iter().any(|seq| {
5050            let zid = seq
5051                .elements
5052                .get(1)
5053                .and_then(|e: &Vec<String>| e.first())
5054                .map(|v| v.as_str())
5055                .unwrap_or("");
5056            !zid.is_empty() && !loc_z22_zeitraum_ids.contains(&zid)
5057        }))
5058    }
5059
5060    /// [309] Wenn SG5 LOC+Z22 (ruhende Marktlokation) nicht vorhanden
5061    fn evaluate_309(&self, _ctx: &EvaluationContext) -> ConditionResult {
5062        // TODO: implement
5063        ConditionResult::Unknown
5064    }
5065
5066    /// [314] Es sind alle OBIS-Kennzahlen gem. Codeliste der OBIS-Kennzahlen und Medien Kapitel 3 anzugeben welche an der Marktlokation erforderlich sind. Der Mindestumfang der OBIS-Kennzahlen ergibt sich aus d...
5067    fn evaluate_314(&self, ctx: &EvaluationContext) -> ConditionResult {
5068        ctx.external.evaluate("code_list_membership_check")
5069    }
5070
5071    /// [315] Wenn BGM+Z88 (Datenclearing) vorhanden
5072    fn evaluate_315(&self, ctx: &EvaluationContext) -> ConditionResult {
5073        ctx.external.evaluate("data_clearing_required")
5074    }
5075
5076    /// [316] Wenn in derselben SG8 das RFF+Z14 (Smartmeter-Gateway) nicht vorhanden
5077    fn evaluate_316(&self, ctx: &EvaluationContext) -> ConditionResult {
5078        ctx.any_group_has_qualifier_without("SEQ", 0, "Z03", "RFF", 0, "Z14", &["SG4", "SG8"])
5079    }
5080
5081    /// [317] Es ist derselbe Wert wie im DE2380 von DTM+92 (Datum Vertragsbeginn) einzutragen
5082    fn evaluate_317(&self, _ctx: &EvaluationContext) -> ConditionResult {
5083        // TODO: implement
5084        ConditionResult::Unknown
5085    }
5086
5087    /// [318] Es ist derselbe Wert wie im DE2380 von DTM+93 (Datum Vertragende) einzutragen
5088    fn evaluate_318(&self, _ctx: &EvaluationContext) -> ConditionResult {
5089        // TODO: implement
5090        ConditionResult::Unknown
5091    }
5092
5093    /// [321] Wenn im DE3155 in demselben COM der Code EM vorhanden ist
5094    fn evaluate_321(&self, _ctx: &EvaluationContext) -> ConditionResult {
5095        // TODO: implement
5096        ConditionResult::Unknown
5097    }
5098
5099    /// [322] Wenn im DE3155 in demselben COM der Code TE / FX / AJ / AL vorhanden ist
5100    fn evaluate_322(&self, _ctx: &EvaluationContext) -> ConditionResult {
5101        // TODO: implement
5102        ConditionResult::Unknown
5103    }
5104
5105    /// [323] Es sind alle OBIS-Kennzahlen gem. EDI@Energy Codeliste der OBIS-Kennzahlen und Medien für den deutschen Energiemarkt Kap. 3. anzugeben, welche an der Zähleinrichtung genutzt werden. Der Mindestum...
5106    fn evaluate_323(&self, ctx: &EvaluationContext) -> ConditionResult {
5107        ctx.external.evaluate("code_list_membership_check")
5108    }
5109
5110    /// [327] Wenn die Zeitraum-ID im DE1050 dieser SG8 SEQ, welche mit der Zeitraum-ID einer SG6 RFF+Z47/Z48/Z49 (Verwendungszeitraum der Daten) identisch ist und in deren SG das SG6 DTM+Z25 (Verwendung der Dat...
5111    // REVIEW: Step 1: Collect all SEQ DE1050 Zeitraum-IDs. Step 2: Find RFF+Z47/Z48/Z49 (Verwendungszeitraum) whose DE1156 (elements[0][2]) matches. Step 3: Check co-located DTM+Z25 DE2380 (elements[0][1]) >= threshold after normalising EDIFACT escape '?+' to '+'. Falls back to message-wide DTM search which may give false positives if multiple SG6 groups are present, but is sufficient for typical single-transaction messages. (medium confidence)
5112    fn evaluate_327(&self, ctx: &EvaluationContext) -> ConditionResult {
5113        const THRESHOLD: &str = "202212312300+00";
5114        let seq_zeitraum_ids: Vec<String> = ctx
5115            .find_segments("SEQ")
5116            .iter()
5117            .filter_map(|s| {
5118                s.elements
5119                    .get(1)
5120                    .and_then(|e: &Vec<String>| e.first())
5121                    .cloned()
5122            })
5123            .filter(|v| !v.is_empty())
5124            .collect();
5125        if seq_zeitraum_ids.is_empty() {
5126            return ConditionResult::Unknown;
5127        }
5128        let rff_segs = ctx.find_segments("RFF");
5129        let matching_rff = rff_segs.iter().any(|rff| {
5130            let qual = rff
5131                .elements
5132                .first()
5133                .and_then(|e: &Vec<String>| e.first())
5134                .map(|v| v.as_str())
5135                .unwrap_or("");
5136            if !["Z47", "Z48", "Z49"].contains(&qual) {
5137                return false;
5138            }
5139            let zid = rff
5140                .elements
5141                .first()
5142                .and_then(|e| e.get(2))
5143                .map(|v| v.as_str())
5144                .unwrap_or("");
5145            !zid.is_empty() && seq_zeitraum_ids.iter().any(|id| id.as_str() == zid)
5146        });
5147        if !matching_rff {
5148            return ConditionResult::False;
5149        }
5150        for dtm in ctx.find_segments_with_qualifier("DTM", 0, "Z25") {
5151            let val = dtm
5152                .elements
5153                .first()
5154                .and_then(|e| e.get(1))
5155                .map(|v| v.replace("?+", "+"))
5156                .unwrap_or_default();
5157            if !val.is_empty() && val.as_str() >= THRESHOLD {
5158                return ConditionResult::True;
5159            }
5160        }
5161        ConditionResult::False
5162    }
5163
5164    /// [329] Wenn in dieser SG4 IDE+24 das STS+E01++A03: E_0096 bzw. A04:E_0097 (Status der Antwort) nicht vorhanden
5165    fn evaluate_329(&self, _ctx: &EvaluationContext) -> ConditionResult {
5166        // TODO: implement
5167        ConditionResult::Unknown
5168    }
5169
5170    /// [332] Wenn im SG8 SEQ+Z01 (Daten der Marktlokation) mit identischer Zeitraum-ID im DE1050 wie in dieser SG8, das SG10 CCI+6++ZA9 (Aggreg. verantw. ÜNB) nicht vorhanden
5171    // REVIEW: Checks whether any SG8 instance lacks CCI+6++ZA9 (Aggregationsverantwortung ÜNB, elements[0]='6' and elements[2][0]='ZA9') in its SG10 children. With navigator: iterates SG8 instances and their SG10 children. Without navigator: falls back to message-wide CCI+6 with ZA9 check. The Zeitraum-ID cross-reference between this SG8 and the Z01 SG8 cannot be fully verified without direct SG8-level segment access via navigator, so this is an approximation that may produce false positives in multi-SG4-group messages. (medium confidence)
5172    fn evaluate_332(&self, ctx: &EvaluationContext) -> ConditionResult {
5173        let nav = match ctx.navigator {
5174            Some(n) => n,
5175            None => {
5176                if ctx.find_segments_with_qualifier("SEQ", 0, "Z01").is_empty() {
5177                    return ConditionResult::Unknown;
5178                }
5179                let has_cci_za9 = ctx
5180                    .find_segments_with_qualifier("CCI", 0, "6")
5181                    .iter()
5182                    .any(|s| {
5183                        s.elements
5184                            .get(2)
5185                            .and_then(|e: &Vec<String>| e.first())
5186                            .map(|v| v.as_str())
5187                            == Some("ZA9")
5188                    });
5189                return ConditionResult::from(!has_cci_za9);
5190            }
5191        };
5192        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
5193        if sg8_count == 0 {
5194            return ConditionResult::Unknown;
5195        }
5196        for sg8_idx in 0..sg8_count {
5197            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], sg8_idx, "SG10");
5198            let mut has_cci_za9 = false;
5199            for sg10_idx in 0..sg10_count {
5200                let ccis = nav.find_segments_in_child_group(
5201                    "CCI",
5202                    &["SG4", "SG8"],
5203                    sg8_idx,
5204                    "SG10",
5205                    sg10_idx,
5206                );
5207                if ccis.iter().any(|s| {
5208                    s.elements
5209                        .first()
5210                        .and_then(|e: &Vec<String>| e.first())
5211                        .map(|v| v.as_str())
5212                        == Some("6")
5213                        && s.elements
5214                            .get(2)
5215                            .and_then(|e: &Vec<String>| e.first())
5216                            .map(|v| v.as_str())
5217                            == Some("ZA9")
5218                }) {
5219                    has_cci_za9 = true;
5220                    break;
5221                }
5222            }
5223            if !has_cci_za9 {
5224                return ConditionResult::True;
5225            }
5226        }
5227        ConditionResult::False
5228    }
5229
5230    /// [333] Wenn in diesem RFF \"Referenz auf die Lokationsbündelstruktur\" im DE1153 der Code Z31 \"Lokationsbündelstruktur\" vorhanden ist
5231    fn evaluate_333(&self, _ctx: &EvaluationContext) -> ConditionResult {
5232        // TODO: implement
5233        ConditionResult::Unknown
5234    }
5235
5236    /// [334] Nur MP-ID aus Sparte Gas
5237    fn evaluate_334(&self, _ctx: &EvaluationContext) -> ConditionResult {
5238        // TODO: implement
5239        ConditionResult::Unknown
5240    }
5241
5242    /// [335] Wenn in dieser SG8 im SEQ+Z58 (Zuordnung Lokation zum Objektcode des Lokationsbündels) im DE1050 eine Zeitraum-ID angegeben wird, wie in einer SG8 SEQ+Z78 RFF+Z31 (Referenz auf die Lokationsbünde...
5243    // REVIEW: Collects Zeitraum-IDs from SEQ+Z58 DE1050 (elements[1][0]). Verifies an SG8 with SEQ+Z78 exists (entry for Lokationsbündelstruktur). Collects IDs from RFF+Z31 DE1154 (elements[0][1]) and checks if any SEQ+Z58 Zeitraum-ID matches. Co-location of RFF+Z31 with SEQ+Z78 in the same SG8 instance is approximated message-wide; exact co-location verification would require navigator SG8-level segment access. (medium confidence)
5244    fn evaluate_335(&self, ctx: &EvaluationContext) -> ConditionResult {
5245        let z58_ids: Vec<String> = ctx
5246            .find_segments_with_qualifier("SEQ", 0, "Z58")
5247            .iter()
5248            .filter_map(|s| {
5249                s.elements
5250                    .get(1)
5251                    .and_then(|e: &Vec<String>| e.first())
5252                    .cloned()
5253            })
5254            .filter(|v| !v.is_empty())
5255            .collect();
5256        if z58_ids.is_empty() {
5257            return ConditionResult::Unknown;
5258        }
5259        if ctx.find_segments_with_qualifier("SEQ", 0, "Z78").is_empty() {
5260            return ConditionResult::False;
5261        }
5262        let rff_z31_ids: Vec<String> = ctx
5263            .find_segments("RFF")
5264            .iter()
5265            .filter(|rff| {
5266                rff.elements
5267                    .first()
5268                    .and_then(|e: &Vec<String>| e.first())
5269                    .map(|v| v.as_str())
5270                    == Some("Z31")
5271            })
5272            .filter_map(|rff| rff.elements.first().and_then(|e| e.get(1)).cloned())
5273            .filter(|v| !v.is_empty())
5274            .collect();
5275        ConditionResult::from(z58_ids.iter().any(|id| rff_z31_ids.contains(id)))
5276    }
5277
5278    /// [336] Wenn in Änderungsmeldung gefüllt
5279    fn evaluate_336(&self, _ctx: &EvaluationContext) -> ConditionResult {
5280        // TODO: implement
5281        ConditionResult::Unknown
5282    }
5283
5284    /// [337] Wenn SG10 CCI+++ZB4 (Bezeichnung der Summenzeitreihe) CAV+Z95/ Z96 vorhanden
5285    fn evaluate_337(&self, _ctx: &EvaluationContext) -> ConditionResult {
5286        // TODO: implement
5287        ConditionResult::Unknown
5288    }
5289
5290    /// [338] Wenn CCI+++ZB4 (Bezeichnung der Summenzeitreihe) CAV+Z95/ Z96/ Z97/ Z99/ ZA1/ ZA3/ ZA4/ZG7 vorhanden
5291    fn evaluate_338(&self, _ctx: &EvaluationContext) -> ConditionResult {
5292        // TODO: implement
5293        ConditionResult::Unknown
5294    }
5295
5296    /// [339] Wenn CCI+++ZB4 (Bezeichnung der Summenzeitreihe) CAV+Z97/ Z98/ Z99/ ZA0/ ZA1/ ZA2/ ZA3/ ZA6/ ZG7 vorhanden
5297    fn evaluate_339(&self, _ctx: &EvaluationContext) -> ConditionResult {
5298        // TODO: implement
5299        ConditionResult::Unknown
5300    }
5301
5302    /// [340] Wenn CCI+++ZB4 (Bezeichnung der Summenzeitreihe) CAV+Z95/ Z97/ Z98/ Z99/ ZA1/ ZA2/ ZA3/ ZA4/ ZA5/ ZA6 vorhanden
5303    fn evaluate_340(&self, _ctx: &EvaluationContext) -> ConditionResult {
5304        // TODO: implement
5305        ConditionResult::Unknown
5306    }
5307
5308    /// [341] Wenn CCI+++ZB4 (Bezeichnung der Summenzeitreihe) CAV+Z96/ ZA0/ ZG7 vorhanden
5309    fn evaluate_341(&self, _ctx: &EvaluationContext) -> ConditionResult {
5310        // TODO: implement
5311        ConditionResult::Unknown
5312    }
5313
5314    /// [342] Wenn aktiver MaBiS-ZP für den Betrachtungszeitraum vorhanden
5315    fn evaluate_342(&self, _ctx: &EvaluationContext) -> ConditionResult {
5316        // TODO: implement
5317        ConditionResult::Unknown
5318    }
5319
5320    /// [344] Wenn in dieser SG8 das SG10 CCI+++ZB4 (Bezeichnung der Summenzeitreihe) CAV+ZF1 (Netzgangzeitreihe (NGZ)) vorhanden
5321    fn evaluate_344(&self, _ctx: &EvaluationContext) -> ConditionResult {
5322        // TODO: implement
5323        ConditionResult::Unknown
5324    }
5325
5326    /// [345] Wenn SG5 LOC+Z17 (Messlokation) vorhanden
5327    fn evaluate_345(&self, _ctx: &EvaluationContext) -> ConditionResult {
5328        // TODO: implement
5329        ConditionResult::Unknown
5330    }
5331
5332    /// [347] Wenn SG5 LOC+Z16 (Marktlokation) nicht vorhanden
5333    fn evaluate_347(&self, _ctx: &EvaluationContext) -> ConditionResult {
5334        // TODO: implement
5335        ConditionResult::Unknown
5336    }
5337
5338    /// [348] Wenn SG5 LOC+Z21 (Tranche) nicht vorhanden
5339    fn evaluate_348(&self, _ctx: &EvaluationContext) -> ConditionResult {
5340        // TODO: implement
5341        ConditionResult::Unknown
5342    }
5343
5344    /// [349] Wenn SG5 LOC+Z17 (Messlokation) nicht vorhanden
5345    fn evaluate_349(&self, _ctx: &EvaluationContext) -> ConditionResult {
5346        // TODO: implement
5347        ConditionResult::Unknown
5348    }
5349
5350    /// [350] Wenn SG8 SEQ+Z78/ZD5 RFF+Z31 (Referenz auf die Lokationsbündelstruktur) vorhanden
5351    fn evaluate_350(&self, _ctx: &EvaluationContext) -> ConditionResult {
5352        // TODO: implement
5353        ConditionResult::Unknown
5354    }
5355
5356    /// [351] Wenn SG4 STS+E01++A04/ A05 /A13 /A14 (Status der Antwort) vorhanden
5357    fn evaluate_351(&self, _ctx: &EvaluationContext) -> ConditionResult {
5358        // TODO: implement
5359        ConditionResult::Unknown
5360    }
5361
5362    /// [352] Wenn SG4 STS++A05/ A06/ A14 /A15 (Status der Antwort) vorhanden
5363    fn evaluate_352(&self, _ctx: &EvaluationContext) -> ConditionResult {
5364        // TODO: implement
5365        ConditionResult::Unknown
5366    }
5367
5368    /// [355] Wenn SG4 STS+E01++A45 (Status der Antwort) vorhanden
5369    fn evaluate_355(&self, _ctx: &EvaluationContext) -> ConditionResult {
5370        // TODO: implement
5371        ConditionResult::Unknown
5372    }
5373
5374    /// [356] Wenn SG4 STS+E01++A50 (Status der Antwort) vorhanden
5375    fn evaluate_356(&self, _ctx: &EvaluationContext) -> ConditionResult {
5376        // TODO: implement
5377        ConditionResult::Unknown
5378    }
5379
5380    /// [357] Wenn SG4 STS+E01++A03/ A09/ A12/ A17 (Status der Antwort) vorhanden
5381    fn evaluate_357(&self, _ctx: &EvaluationContext) -> ConditionResult {
5382        // TODO: implement
5383        ConditionResult::Unknown
5384    }
5385
5386    /// [358] Wenn SG4 STS+E01++A06 (Status der Antwort) vorhanden
5387    fn evaluate_358(&self, _ctx: &EvaluationContext) -> ConditionResult {
5388        // TODO: implement
5389        ConditionResult::Unknown
5390    }
5391
5392    /// [359] Es sind nur Antwortcodes aus dem Cluster Ablehnung erlaubt
5393    fn evaluate_359(&self, _ctx: &EvaluationContext) -> ConditionResult {
5394        // TODO: implement
5395        ConditionResult::Unknown
5396    }
5397
5398    /// [360] Es sind nur Antwortcodes aus dem Cluster Zustimmung erlaubt
5399    fn evaluate_360(&self, _ctx: &EvaluationContext) -> ConditionResult {
5400        // TODO: implement
5401        ConditionResult::Unknown
5402    }
5403
5404    /// [363] Wenn SG4 STS+E01++A50 (Status der Antwort) vorhanden
5405    fn evaluate_363(&self, _ctx: &EvaluationContext) -> ConditionResult {
5406        // TODO: implement
5407        ConditionResult::Unknown
5408    }
5409
5410    /// [365] Wenn in dieser SG4 IDE+24 das STS+E01++A04:E_0047/E_0014 bzw. A03:E_0049/E_0004 (Status der Antwort) nicht vorhanden
5411    fn evaluate_365(&self, _ctx: &EvaluationContext) -> ConditionResult {
5412        // TODO: implement
5413        ConditionResult::Unknown
5414    }
5415
5416    /// [366] Bis auf den Code A30 sind alle Codes aus EBD E_0624 im Cluster Ablehnung erlaubt
5417    fn evaluate_366(&self, _ctx: &EvaluationContext) -> ConditionResult {
5418        // TODO: implement
5419        ConditionResult::Unknown
5420    }
5421
5422    /// [367] Wenn SG4 STS+E01++A05/ A14 (Status der Antwort) vorhanden
5423    fn evaluate_367(&self, _ctx: &EvaluationContext) -> ConditionResult {
5424        // TODO: implement
5425        ConditionResult::Unknown
5426    }
5427
5428    /// [368] Bis auf den Code A41 sind alle Codes aus EBD E_0624 im Cluster Ablehnung erlaubt
5429    fn evaluate_368(&self, _ctx: &EvaluationContext) -> ConditionResult {
5430        // TODO: implement
5431        ConditionResult::Unknown
5432    }
5433
5434    /// [370] Wenn SG10 CAV+TLS/TES/BIT/GET/GAT/SOT/WNT/WFT/WAT
5435    fn evaluate_370(&self, _ctx: &EvaluationContext) -> ConditionResult {
5436        // TODO: implement
5437        ConditionResult::Unknown
5438    }
5439
5440    /// [371] Wenn SG8 SEQ+Z38 (Referenzprofildaten) nicht vorhanden
5441    fn evaluate_371(&self, _ctx: &EvaluationContext) -> ConditionResult {
5442        // TODO: implement
5443        ConditionResult::Unknown
5444    }
5445
5446    /// [372] Wenn SG10 CAV+TES/BIT/GET/GAT/SOT/WNT/WFT/WAT vorhanden
5447    fn evaluate_372(&self, _ctx: &EvaluationContext) -> ConditionResult {
5448        // TODO: implement
5449        ConditionResult::Unknown
5450    }
5451
5452    /// [373] Wenn ein Referenzprofil an der Marktlokation vorhanden ist
5453    fn evaluate_373(&self, _ctx: &EvaluationContext) -> ConditionResult {
5454        // TODO: implement
5455        ConditionResult::Unknown
5456    }
5457
5458    /// [375] Für die ID im SG5 LOC+Z15 (MaBiS-Zählpunkt) DE3225, wenn SG8+Z24 (Daten der Überführungszeitreihe) nicht vorhanden
5459    fn evaluate_375(&self, _ctx: &EvaluationContext) -> ConditionResult {
5460        // TODO: implement
5461        ConditionResult::Unknown
5462    }
5463
5464    /// [376] Für die ID im SG5 LOC+Z15 (MaBiS-Zählpunkt) DE3225, wenn SG8+Z22 (Daten der Summenzeitreihe) nicht vorhanden
5465    fn evaluate_376(&self, _ctx: &EvaluationContext) -> ConditionResult {
5466        // TODO: implement
5467        ConditionResult::Unknown
5468    }
5469
5470    /// [377] Wenn SG10 CCI+15++Z21 (Überführungszeitreihentyp) CAV+AUS vorhanden
5471    // REVIEW: Checks if any SG8 has a child SG10 with CCI[0]='15' and CCI[2]='Z21' (Überführungszeitreihentyp) followed by CAV with value 'AUS'. Follows the navigator pattern from example 10 exactly. (medium confidence)
5472    fn evaluate_377(&self, ctx: &EvaluationContext) -> ConditionResult {
5473        let nav = match ctx.navigator {
5474            Some(n) => n,
5475            None => return ctx.has_qualified_value("CAV", 0, "AUS", 0, 0, &["AUS"]),
5476        };
5477        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
5478        for i in 0..sg8_count {
5479            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
5480            for j in 0..sg10_count {
5481                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
5482                let has_cci = ccis.iter().any(|s| {
5483                    s.elements
5484                        .first()
5485                        .and_then(|e: &Vec<String>| e.first())
5486                        .is_some_and(|v: &String| v == "15")
5487                        && s.elements
5488                            .get(2)
5489                            .and_then(|e: &Vec<String>| e.first())
5490                            .is_some_and(|v: &String| v == "Z21")
5491                });
5492                if has_cci {
5493                    let cavs =
5494                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
5495                    if cavs.iter().any(|s| {
5496                        s.elements
5497                            .first()
5498                            .and_then(|e: &Vec<String>| e.first())
5499                            .is_some_and(|v: &String| v == "AUS")
5500                    }) {
5501                        return ConditionResult::True;
5502                    }
5503                }
5504            }
5505        }
5506        ConditionResult::False
5507    }
5508
5509    /// [378] Wenn SG10 CCI+15++Z21 (Überführungszeitreihentyp) CAV+AUS nicht vorhanden
5510    // REVIEW: Logical negation of condition 377: True when CCI+15++Z21 CAV+AUS is NOT present in any SG8's SG10 child. Iterates all instances and returns True only if the combination is never found. (medium confidence)
5511    fn evaluate_378(&self, ctx: &EvaluationContext) -> ConditionResult {
5512        let nav = match ctx.navigator {
5513            Some(n) => n,
5514            None => {
5515                let r = ctx.has_qualified_value("CAV", 0, "AUS", 0, 0, &["AUS"]);
5516                return match r {
5517                    ConditionResult::True => ConditionResult::False,
5518                    ConditionResult::False => ConditionResult::True,
5519                    ConditionResult::Unknown => ConditionResult::Unknown,
5520                };
5521            }
5522        };
5523        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
5524        for i in 0..sg8_count {
5525            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
5526            for j in 0..sg10_count {
5527                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
5528                let has_cci = ccis.iter().any(|s| {
5529                    s.elements
5530                        .first()
5531                        .and_then(|e: &Vec<String>| e.first())
5532                        .is_some_and(|v: &String| v == "15")
5533                        && s.elements
5534                            .get(2)
5535                            .and_then(|e: &Vec<String>| e.first())
5536                            .is_some_and(|v: &String| v == "Z21")
5537                });
5538                if has_cci {
5539                    let cavs =
5540                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
5541                    if cavs.iter().any(|s| {
5542                        s.elements
5543                            .first()
5544                            .and_then(|e: &Vec<String>| e.first())
5545                            .is_some_and(|v: &String| v == "AUS")
5546                    }) {
5547                        return ConditionResult::False;
5548                    }
5549                }
5550            }
5551        }
5552        ConditionResult::True
5553    }
5554
5555    /// [379] Wenn SG10 CCI+15++Z21 (Überführungszeitreihentyp) CAV+ Code für EEG-Überführungszeitreihen (ausgenommen AU1) vorhanden
5556    fn evaluate_379(&self, _ctx: &EvaluationContext) -> ConditionResult {
5557        // TODO: implement
5558        ConditionResult::Unknown
5559    }
5560
5561    /// [380] Wenn SG10 CCI+15++Z21 (Überführungszeitreihentyp) CAV+AUS/AU1 vorhanden
5562    // REVIEW: Variant of condition 377 that accepts either 'AUS' or 'AU1' as the CAV value for the Überführungszeitreihentyp. Same SG8→SG10 parent-child navigation, broadened CAV value check. (medium confidence)
5563    fn evaluate_380(&self, ctx: &EvaluationContext) -> ConditionResult {
5564        let nav = match ctx.navigator {
5565            Some(n) => n,
5566            None => {
5567                return ctx.any_group_has_any_qualifier("CAV", 0, &["AUS", "AU1"], &["SG4", "SG8"])
5568            }
5569        };
5570        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
5571        for i in 0..sg8_count {
5572            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
5573            for j in 0..sg10_count {
5574                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
5575                let has_cci = ccis.iter().any(|s| {
5576                    s.elements
5577                        .first()
5578                        .and_then(|e: &Vec<String>| e.first())
5579                        .is_some_and(|v: &String| v == "15")
5580                        && s.elements
5581                            .get(2)
5582                            .and_then(|e: &Vec<String>| e.first())
5583                            .is_some_and(|v: &String| v == "Z21")
5584                });
5585                if has_cci {
5586                    let cavs =
5587                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
5588                    if cavs.iter().any(|s| {
5589                        s.elements
5590                            .first()
5591                            .and_then(|e: &Vec<String>| e.first())
5592                            .is_some_and(|v: &String| v == "AUS" || v == "AU1")
5593                    }) {
5594                        return ConditionResult::True;
5595                    }
5596                }
5597            }
5598        }
5599        ConditionResult::False
5600    }
5601
5602    /// [384] Wenn in derselben SG8 SG10 CCI+Z37++ZD1 (Basis zur Bildung der Tranchengröße) (Prozentual) vorhanden
5603    fn evaluate_384(&self, _ctx: &EvaluationContext) -> ConditionResult {
5604        // TODO: implement
5605        ConditionResult::Unknown
5606    }
5607
5608    /// [386] Wenn mehr als eine SG8 SEQ+Z02/ ZE3 (OBIS-Daten der Marktlokation) mit einer OBIS-Kennzahl für Energiemenge im PIA+5 vorhanden
5609    fn evaluate_386(&self, _ctx: &EvaluationContext) -> ConditionResult {
5610        // TODO: implement
5611        ConditionResult::Unknown
5612    }
5613
5614    /// [388] Segmentgruppe ist mindesten einmal für jede Zeitraum-ID aus dem DE1156 der SG6 RFF+Z49 (Verwendungszeitraum der Daten: \"Gültige Daten\") anzugeben, wenn in diesem Zeitraum Blindarbeit bzw. -leis...
5615    fn evaluate_388(&self, _ctx: &EvaluationContext) -> ConditionResult {
5616        // TODO: implement
5617        ConditionResult::Unknown
5618    }
5619
5620    /// [391] Wenn in derselben SG8 SEQ+Z20 (OBIS Daten der Zähleinrichtung / Smartmeter-Gateway) eine OBIS-Kennzahl für Zählerstand im PIA+5 vorhanden und es sich lt. Codeliste OBIS um eine OBIS mit zugeordn...
5621    fn evaluate_391(&self, _ctx: &EvaluationContext) -> ConditionResult {
5622        // TODO: implement
5623        ConditionResult::Unknown
5624    }
5625
5626    /// [392] Wenn in diesem PIA der Code im Format n1-n2-n1 angegeben ist
5627    fn evaluate_392(&self, _ctx: &EvaluationContext) -> ConditionResult {
5628        // TODO: implement
5629        ConditionResult::Unknown
5630    }
5631
5632    /// [393] Wenn in diesem PIA der Code im Format n1-n2-n1-n3 angegeben ist
5633    fn evaluate_393(&self, _ctx: &EvaluationContext) -> ConditionResult {
5634        // TODO: implement
5635        ConditionResult::Unknown
5636    }
5637
5638    /// [394] Wenn in diesem PIA der Code im Format n1-n2-n1-n8-n2 angegeben ist
5639    fn evaluate_394(&self, _ctx: &EvaluationContext) -> ConditionResult {
5640        // TODO: implement
5641        ConditionResult::Unknown
5642    }
5643
5644    /// [395] Wenn in diesem PIA der Code im Format n1-n2-n1-n8 angegeben ist
5645    fn evaluate_395(&self, _ctx: &EvaluationContext) -> ConditionResult {
5646        // TODO: implement
5647        ConditionResult::Unknown
5648    }
5649
5650    /// [396] Wenn in derselben SG8 SEQ+Z02/ ZA1/ ZA2 (OBIS-Daten der Marktlokation) eine OBIS-Kennzahl für Wirkarbeit und 1/4 Stunde im PIA+5 vorhanden
5651    fn evaluate_396(&self, _ctx: &EvaluationContext) -> ConditionResult {
5652        // TODO: implement
5653        ConditionResult::Unknown
5654    }
5655
5656    /// [397] Wenn in diesem PIA der Code im DE7140 mit 1-08-1/1-08-4 beginnt
5657    fn evaluate_397(&self, _ctx: &EvaluationContext) -> ConditionResult {
5658        // TODO: implement
5659        ConditionResult::Unknown
5660    }
5661
5662    /// [398] Wenn in diesem PIA der Code im DE7140 mit 1-08-2/1-08-5 beginnt
5663    fn evaluate_398(&self, _ctx: &EvaluationContext) -> ConditionResult {
5664        // TODO: implement
5665        ConditionResult::Unknown
5666    }
5667
5668    /// [401] Wenn dieses DTM+Z25 (Verwendung der Daten ab) nicht im SG6 RFF+Z49/ Z53 (Verwendungszeitraum der Daten: Gültige Daten/ Keine Daten) mit der Zeitraum ID \"1\" im DE1156 ist, muss das Datum dem DTM+...
5669    fn evaluate_401(&self, _ctx: &EvaluationContext) -> ConditionResult {
5670        // TODO: implement
5671        ConditionResult::Unknown
5672    }
5673
5674    /// [402] Wenn in derselben SG8  (OBIS-Daten der Zähleinrichtung / Smartmeter-Gateway) eine OBIS-Kennzahl der Werteart \"Zählerstand\" im PIA+5 vorhanden
5675    fn evaluate_402(&self, _ctx: &EvaluationContext) -> ConditionResult {
5676        // TODO: implement
5677        ConditionResult::Unknown
5678    }
5679
5680    /// [403] Wenn nicht dieselbe MP-ID in SG2 NAD+MS (Nachrichtensender) und im SG8 SEQ+Z01 (Daten der Marktlokation) SG10 CCI+++ZB3 (Zugeordnete Marktpartner) CAV+Z91 (Messtellenbetreiber) vorhanden
5681    // REVIEW: Gets NAD+MS MP-ID from SG2 (elements[1][0]), then navigates all SG8→SG10 instances looking for CCI with elements[2][0]='ZB3' (Zugeordnete Marktpartner) and CAV with elements[0][0]='Z91' (Messstellenbetreiber). Compares the CAV+Z91 MP-ID (elements[0][1]) with the sender MP-ID. Returns True when they differ (not the same). Note: SEQ+Z01 filter on the parent SG8 is omitted because `find_segments_in_child_group` only accesses child groups, not the parent SG8 segments; the Z91 MSB identity is message-consistent regardless. (medium confidence)
5682    fn evaluate_403(&self, ctx: &EvaluationContext) -> ConditionResult {
5683        let sender_mp_id: String = match ctx.find_segments_with_qualifier("NAD", 0, "MS").first() {
5684            Some(nad) => match nad.elements.get(1).and_then(|e: &Vec<String>| e.first()) {
5685                Some(id) if !id.is_empty() => id.clone(),
5686                _ => return ConditionResult::Unknown,
5687            },
5688            None => return ConditionResult::Unknown,
5689        };
5690        let nav = match ctx.navigator {
5691            Some(n) => n,
5692            None => return ConditionResult::Unknown,
5693        };
5694        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
5695        for i in 0..sg8_count {
5696            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
5697            for j in 0..sg10_count {
5698                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
5699                let has_cci_zb3 = ccis.iter().any(|s| {
5700                    s.elements
5701                        .get(2)
5702                        .and_then(|e: &Vec<String>| e.first())
5703                        .is_some_and(|v: &String| v == "ZB3")
5704                });
5705                if !has_cci_zb3 {
5706                    continue;
5707                }
5708                let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
5709                for cav in &cavs {
5710                    if cav
5711                        .elements
5712                        .first()
5713                        .and_then(|e: &Vec<String>| e.first())
5714                        .is_some_and(|v: &String| v == "Z91")
5715                    {
5716                        if let Some(msb_id) = cav.elements.first().and_then(|e| e.get(1)) {
5717                            if !msb_id.is_empty() {
5718                                return ConditionResult::from(
5719                                    sender_mp_id.as_str() != msb_id.as_str(),
5720                                );
5721                            }
5722                        }
5723                    }
5724                }
5725            }
5726        }
5727        ConditionResult::Unknown
5728    }
5729
5730    /// [404] Wenn nicht dieselbe MP-ID in SG2 NAD+MR (Nachrichtenempfänger) und im SG8 SEQ+Z01/ Z98 (Daten der Marktlokation) SG10 CCI+++ZB3 (Zugeordnete Marktpartner) CAV+Z91 (Messtellenbetreiber) vorhanden
5731    // REVIEW: Reads NAD+MR MP-ID from elements[1][0], then iterates all SG8 SG10 children looking for CCI with elements[2][0]==ZB3 and CAV with elements[0][0]==Z91 where the MP-ID (elements[0][1]) matches. Returns False if same MP-ID found (condition 'not same' fails), True otherwise. Approximation: cannot filter SG8 instances by SEQ+Z01/Z98 without find_segments_in_group; checks all SG8 SG10 children. This is acceptable since CCI+ZB3 CAV+Z91 patterns in other SG8 types would still represent valid MSB assignments to compare against. (medium confidence)
5732    fn evaluate_404(&self, ctx: &EvaluationContext) -> ConditionResult {
5733        let mr_nads = ctx.find_segments_with_qualifier("NAD", 0, "MR");
5734        let mr_mp_id = match mr_nads.first() {
5735            Some(nad) => nad
5736                .elements
5737                .get(1)
5738                .and_then(|e: &Vec<String>| e.first())
5739                .cloned()
5740                .unwrap_or_default(),
5741            None => return ConditionResult::Unknown,
5742        };
5743        if mr_mp_id.is_empty() {
5744            return ConditionResult::Unknown;
5745        }
5746
5747        let nav = match ctx.navigator {
5748            Some(n) => n,
5749            None => {
5750                let cavs = ctx.find_segments("CAV");
5751                let same_id_exists = cavs.iter().any(|s| {
5752                    s.elements
5753                        .first()
5754                        .and_then(|e: &Vec<String>| e.first())
5755                        .is_some_and(|v: &String| v == "Z91")
5756                        && s.elements
5757                            .first()
5758                            .and_then(|e| e.get(1))
5759                            .is_some_and(|v: &String| v == &mr_mp_id)
5760                });
5761                return ConditionResult::from(!same_id_exists);
5762            }
5763        };
5764
5765        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
5766        for i in 0..sg8_count {
5767            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
5768            for j in 0..sg10_count {
5769                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
5770                let has_cci_zb3 = ccis.iter().any(|s| {
5771                    s.elements
5772                        .get(2)
5773                        .and_then(|e: &Vec<String>| e.first())
5774                        .is_some_and(|v: &String| v == "ZB3")
5775                });
5776                if !has_cci_zb3 {
5777                    continue;
5778                }
5779                let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
5780                for cav in &cavs {
5781                    if cav
5782                        .elements
5783                        .first()
5784                        .and_then(|e: &Vec<String>| e.first())
5785                        .is_some_and(|v: &String| v == "Z91")
5786                    {
5787                        let cav_mp_id = cav
5788                            .elements
5789                            .first()
5790                            .and_then(|e| e.get(1))
5791                            .map(|s| s.as_str())
5792                            .unwrap_or("");
5793                        if cav_mp_id == mr_mp_id.as_str() {
5794                            return ConditionResult::False;
5795                        }
5796                    }
5797                }
5798            }
5799        }
5800
5801        ConditionResult::True
5802    }
5803
5804    /// [405] Wenn in derselben SG8 SEQ+Z02/ZA1/ZA2 (OBIS-Daten der Marktlokation) eine OBIS-Kennzahl für Wirkarbeit und kumuliert im PIA+5 vorhanden
5805    fn evaluate_405(&self, _ctx: &EvaluationContext) -> ConditionResult {
5806        // TODO: implement
5807        ConditionResult::Unknown
5808    }
5809
5810    /// [406] Wenn in derselben SG8 SEQ+Z02/ZA1/ZA2 (OBIS-Daten der Marktlokation) eine OBIS-Kennzahl für Wirkarbeit und höchste 1/4 Stunde im Monat im PIA+5 vorhanden
5811    fn evaluate_406(&self, _ctx: &EvaluationContext) -> ConditionResult {
5812        // TODO: implement
5813        ConditionResult::Unknown
5814    }
5815
5816    /// [407] Wenn in derselben SG8 SEQ+Z02/ZA1/ZA2 (OBIS-Daten der Marktlokation) eine OBIS-Kennzahl für Blindarbeit im PIA+5 vorhanden
5817    fn evaluate_407(&self, _ctx: &EvaluationContext) -> ConditionResult {
5818        // TODO: implement
5819        ConditionResult::Unknown
5820    }
5821
5822    /// [408] Wenn eine SG8 SEQ+Z02 (OBIS-Daten der Marktlokation), mit dem RFF+Z18 (Referenz auf die ID der Marktlokation) auf die gleiche ID einer Marktlokation referenziert wie das RFF+Z18 (Referenz auf die I...
5823    fn evaluate_408(&self, _ctx: &EvaluationContext) -> ConditionResult {
5824        // TODO: implement
5825        ConditionResult::Unknown
5826    }
5827
5828    /// [409] Wenn keine SG8 SEQ+Z02 (OBIS-Daten der Marktlokation), mit dem RFF+Z18 (Referenz auf die ID der Marktlokation) auf die gleiche ID einer Marktlokation referenziert wie das RFF+Z18 (Referenz auf die ...
5829    fn evaluate_409(&self, _ctx: &EvaluationContext) -> ConditionResult {
5830        // TODO: implement
5831        ConditionResult::Unknown
5832    }
5833
5834    /// [410] Wenn eine SG8 SEQ+Z02 (OBIS-Daten der Marktlokation), mit dem RFF+Z18 (Referenz auf die ID der Marktlokation) auf die gleiche ID einer Marktlokation referenziert wie das RFF+Z18 (Referenz auf die I...
5835    fn evaluate_410(&self, _ctx: &EvaluationContext) -> ConditionResult {
5836        // TODO: implement
5837        ConditionResult::Unknown
5838    }
5839
5840    /// [411] Wenn keine SG8 SEQ+Z02 (OBIS-Daten der Marktlokation), mit dem RFF+Z18 (Referenz auf die ID der Marktlokation) auf die gleiche ID einer Marktlokation referenziert wie das RFF+Z18 (Referenz auf die ...
5841    fn evaluate_411(&self, _ctx: &EvaluationContext) -> ConditionResult {
5842        // TODO: implement
5843        ConditionResult::Unknown
5844    }
5845
5846    /// [412] Es sind ausschließlich Konfigurationsprodukt-Codes der \"EDI@Energy Codeliste der Konfigurationen\" aus Kapitel 4.2 Konfigurationsprodukte Leistungskurvendefinition erlaubt
5847    fn evaluate_412(&self, ctx: &EvaluationContext) -> ConditionResult {
5848        ctx.external.evaluate("code_list_membership_check")
5849    }
5850
5851    /// [417] Wenn für den erforderlichen Wert keine Zählzeit benötigt wird
5852    fn evaluate_417(&self, _ctx: &EvaluationContext) -> ConditionResult {
5853        // TODO: implement
5854        ConditionResult::Unknown
5855    }
5856
5857    /// [419] Wenn in diesem Datenelement kein anderes Paket in dieser SG10 in derselben SG8 SEQ zur Möglichkeit der Angabe von mindestens einem anderen Code führt
5858    fn evaluate_419(&self, _ctx: &EvaluationContext) -> ConditionResult {
5859        // TODO: implement
5860        ConditionResult::Unknown
5861    }
5862
5863    /// [420] Wenn in dieser SG8 das RFF+Z14 (Smartmeter-Gateway) vorhanden ist
5864    fn evaluate_420(&self, _ctx: &EvaluationContext) -> ConditionResult {
5865        // TODO: implement
5866        ConditionResult::Unknown
5867    }
5868
5869    /// [421] Wenn in dieser SG8 das SG10 CCI+Z39 (Zugeordnete Zählzeitdefinition) vorhanden ist
5870    fn evaluate_421(&self, _ctx: &EvaluationContext) -> ConditionResult {
5871        // TODO: implement
5872        ConditionResult::Unknown
5873    }
5874
5875    /// [425] Messprodukt-Code aus den Kapitel 2.1 \"Standard-Messprodukte der Marktlokation\" der Codeliste der Konfigurationen
5876    fn evaluate_425(&self, ctx: &EvaluationContext) -> ConditionResult {
5877        ctx.external.evaluate("code_list_membership_check")
5878    }
5879
5880    /// [426] Messprodukt-Code aus den Kapitel 2.2 \"Standard-Messprodukte der Tranche\" der Codeliste der Konfigurationen
5881    fn evaluate_426(&self, ctx: &EvaluationContext) -> ConditionResult {
5882        ctx.external.evaluate("code_list_membership_check")
5883    }
5884
5885    /// [427] Messprodukt-Code aus den Kapitel 2.3 \"Standard-Messprodukte der Messlokation\" der Codeliste der Konfigurationen
5886    fn evaluate_427(&self, ctx: &EvaluationContext) -> ConditionResult {
5887        ctx.external.evaluate("code_list_membership_check")
5888    }
5889
5890    /// [428] Wenn in derselben SG8 SEQ+Z27/ ZE2 (Erforderliches Messprodukt der Marktlokation) das PIA+5 DE7140 mit einem Messprodukt aus Codeliste der Konfigurationen Kapitel 2.1.1 Standard-Messprodukt der Mar...
5891    fn evaluate_428(&self, ctx: &EvaluationContext) -> ConditionResult {
5892        ctx.external.evaluate("code_list_membership_check")
5893    }
5894
5895    /// [429] Wenn in derselben SG8 SEQ+Z19/ ZF4 (Erforderliches Messprodukt der Messlokation) das PIA+5 DE7140 mit einem Messprodukt aus Codeliste der Konfigurationen Kapitel 2.3.1 Standard-Messprodukt der Mess...
5896    fn evaluate_429(&self, ctx: &EvaluationContext) -> ConditionResult {
5897        ctx.external.evaluate("code_list_membership_check")
5898    }
5899
5900    /// [430] Wenn eine andere SG8 SEQ+Z27 (Erforderliches Messprodukt der Marktlokation), mit dem RFF+Z18 (Referenz auf die ID der Marktlokation) auf die gleiche ID einer Marktlokation referenziert, mit PIA+5+9...
5901    fn evaluate_430(&self, _ctx: &EvaluationContext) -> ConditionResult {
5902        // TODO: implement
5903        ConditionResult::Unknown
5904    }
5905
5906    /// [431] Wenn keine andere SG8 SEQ+Z27 (Erforderliches Messprodukt der Marktlokation), mit dem RFF+Z18 (Referenz auf die ID der Marktlokation) auf die gleiche ID einer Marktlokation referenziert, mit PIA+5+...
5907    fn evaluate_431(&self, _ctx: &EvaluationContext) -> ConditionResult {
5908        // TODO: implement
5909        ConditionResult::Unknown
5910    }
5911
5912    /// [432] Wenn in derselben SG8 SEQ+Z27 (Erforderliches Messprodukt der Marktlokation), das PIA+5+9991000000078:Z11 (Wirkarbeit Lastgang 1/4 stündlich) vorhanden ist
5913    fn evaluate_432(&self, _ctx: &EvaluationContext) -> ConditionResult {
5914        // TODO: implement
5915        ConditionResult::Unknown
5916    }
5917
5918    /// [433] Wenn keine andere SG8 SEQ+Z27 (Erforderliches Messprodukt der Marktlokation), mit dem RFF+Z18 (Referenz auf die ID der Marktlokation) auf die gleiche ID einer Marktlokation referenziert, mit PIA+5 ...
5919    fn evaluate_433(&self, ctx: &EvaluationContext) -> ConditionResult {
5920        ctx.external.evaluate("code_list_membership_check")
5921    }
5922
5923    /// [435] Wenn eine andere SG8 SEQ+Z27 (Erforderliches Messprodukt der Marktlokation), mit dem RFF+Z18 (Referenz auf die ID der Marktlokation) auf die gleiche ID einer Marktlokation referenziert, mit PIA+5 D...
5924    fn evaluate_435(&self, ctx: &EvaluationContext) -> ConditionResult {
5925        ctx.external.evaluate("code_list_membership_check")
5926    }
5927
5928    /// [436] Wenn in derselben SG8 SEQ+Z27 (Erforderliches Messprodukt der Marktlokation), das PIA+5+9991000000086:Z11 (Wirkarbeit höchste 1/4 Stunde im Monat) vorhanden ist
5929    fn evaluate_436(&self, _ctx: &EvaluationContext) -> ConditionResult {
5930        // TODO: implement
5931        ConditionResult::Unknown
5932    }
5933
5934    /// [437] Wenn in dieser SG4 das STS+E01++A04 / A23 (Status der Antwort) vorhanden
5935    fn evaluate_437(&self, _ctx: &EvaluationContext) -> ConditionResult {
5936        // TODO: implement
5937        ConditionResult::Unknown
5938    }
5939
5940    /// [438] Wenn im selben CCI im DE7059 der Code Z39 (Code der Zählzeit) vorhanden ist
5941    fn evaluate_438(&self, _ctx: &EvaluationContext) -> ConditionResult {
5942        // TODO: implement
5943        ConditionResult::Unknown
5944    }
5945
5946    /// [440] Wenn in demselben RFF der Code Z35 (vorgelagerte Netzlokation) im DE1153 vorhanden
5947    fn evaluate_440(&self, _ctx: &EvaluationContext) -> ConditionResult {
5948        // TODO: implement
5949        ConditionResult::Unknown
5950    }
5951
5952    /// [441] Wenn im SG8+SEQ+Z03/ ZF5 (Zähleinrichtungsdaten) für die in diesem RFF DE1154 genannte Gerätenummer eines Zählers das RFF+Z14 (Referenz auf das Smartmeter-Gateway) nicht vorhanden ist
5953    fn evaluate_441(&self, _ctx: &EvaluationContext) -> ConditionResult {
5954        // TODO: implement
5955        ConditionResult::Unknown
5956    }
5957
5958    /// [442] Wenn in demselben RFF der Code Z34 (vorgelagerte Messlokation) im DE1153 vorhanden
5959    fn evaluate_442(&self, _ctx: &EvaluationContext) -> ConditionResult {
5960        // TODO: implement
5961        ConditionResult::Unknown
5962    }
5963
5964    /// [444] Wenn in derselben SG8 (Produkt-Daten der Netzlokation) das PIA+5 (Produkt-Daten der Netzlokation) nicht vorhanden
5965    // REVIEW: Checks whether any SG8 instance carrying a 'Produkt-Daten der Netzlokation' SEQ qualifier (Z60, ZE0, ZG8, ZG9) lacks PIA+5. Iterates each qualifier separately using any_group_has_qualifier_without which checks: SEQ+code present AND PIA+5 absent in same SG8. Returns True on first match. Correctly handles the multi-qualifier case via OR iteration. (medium confidence)
5966    fn evaluate_444(&self, ctx: &EvaluationContext) -> ConditionResult {
5967        for code in ["Z60", "ZE0", "ZG8", "ZG9"] {
5968            if matches!(
5969                ctx.any_group_has_qualifier_without("SEQ", 0, code, "PIA", 0, "5", &["SG4", "SG8"]),
5970                ConditionResult::True
5971            ) {
5972                return ConditionResult::True;
5973            }
5974        }
5975        ConditionResult::False
5976    }
5977
5978    /// [445] Wenn in derselben SG8 (Produkt-Daten der Netzlokation) das SG10 CCI+11 (Details zum Produkt der Netzlokation) nicht vorhanden
5979    // REVIEW: Iterates all SG8 instances and checks whether any SG10 child group contains CCI with elements[0][0]=="11" (Details zum Produkt der Netzlokation). Returns True when an SG8 is found that lacks such a CCI+11 in its SG10 children. Navigator fallback uses filtered_parent_child_has_qualifier negated per qualifier. Approximation: the navigator path does not filter SG8 instances by Produkt-Daten-Netzlokation SEQ qualifier due to absence of find_segments_in_group; checks all SG8 instances instead. (medium confidence)
5980    fn evaluate_445(&self, ctx: &EvaluationContext) -> ConditionResult {
5981        let nav = match ctx.navigator {
5982            Some(n) => n,
5983            None => {
5984                let has_cci11 = ["Z60", "ZE0", "ZG8", "ZG9"].iter().any(|code| {
5985                    matches!(
5986                        ctx.filtered_parent_child_has_qualifier(
5987                            &["SG4", "SG8"],
5988                            "SEQ",
5989                            0,
5990                            code,
5991                            "SG10",
5992                            "CCI",
5993                            0,
5994                            "11",
5995                        ),
5996                        ConditionResult::True
5997                    )
5998                });
5999                return ConditionResult::from(!has_cci11);
6000            }
6001        };
6002
6003        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
6004        for i in 0..sg8_count {
6005            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
6006            let has_cci11 = (0..sg10_count).any(|j| {
6007                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
6008                ccis.iter().any(|s| {
6009                    s.elements
6010                        .first()
6011                        .and_then(|e: &Vec<String>| e.first())
6012                        .is_some_and(|v: &String| v == "11")
6013                })
6014            });
6015            if !has_cci11 {
6016                return ConditionResult::True;
6017            }
6018        }
6019        ConditionResult::False
6020    }
6021
6022    /// [446] Wenn in derselben SG8 das CCI+Z17 (Stromverbrauchsart) vorhanden
6023    fn evaluate_446(&self, _ctx: &EvaluationContext) -> ConditionResult {
6024        // TODO: implement
6025        ConditionResult::Unknown
6026    }
6027
6028    /// [447] Wenn in derselben SG8 das CCI+Z50 (Stromerzeugungsart) vorhanden
6029    fn evaluate_447(&self, _ctx: &EvaluationContext) -> ConditionResult {
6030        // TODO: implement
6031        ConditionResult::Unknown
6032    }
6033
6034    /// [448] Wenn in derselben SG8 das CCI+Z56 (Speicher) vorhanden
6035    fn evaluate_448(&self, _ctx: &EvaluationContext) -> ConditionResult {
6036        // TODO: implement
6037        ConditionResult::Unknown
6038    }
6039
6040    /// [449] Wenn in derselben SG8 das SG10 CCI+6++ZA9 CAV=ZG3 (Aggreg.verantw. ÜNB und Lokation im Regelbetrieb) vorhanden
6041    fn evaluate_449(&self, _ctx: &EvaluationContext) -> ConditionResult {
6042        // TODO: implement
6043        ConditionResult::Unknown
6044    }
6045
6046    /// [450] Wenn in demselben RFF der Code Z32 (Netzlokation) im DE1153 vorhanden
6047    fn evaluate_450(&self, _ctx: &EvaluationContext) -> ConditionResult {
6048        // TODO: implement
6049        ConditionResult::Unknown
6050    }
6051
6052    /// [451] Wenn in demselben RFF der Code Z18 (Marktlokation) im DE1153 vorhanden
6053    fn evaluate_451(&self, _ctx: &EvaluationContext) -> ConditionResult {
6054        // TODO: implement
6055        ConditionResult::Unknown
6056    }
6057
6058    /// [452] Wenn in demselben RFF der Code Z19 (Messlokation) im DE1153 vorhanden
6059    fn evaluate_452(&self, _ctx: &EvaluationContext) -> ConditionResult {
6060        // TODO: implement
6061        ConditionResult::Unknown
6062    }
6063
6064    /// [453] Wenn bei der Bestellung ein Messprodukt der Codeliste der Konfigurationen aus dem Kapitel 4.4 mit dem Auslöser „Bei Schwellwertunter-/ -überschreitung“ mit selbständiger Änderungsmöglichke...
6065    fn evaluate_453(&self, ctx: &EvaluationContext) -> ConditionResult {
6066        ctx.external.evaluate("code_list_membership_check")
6067    }
6068
6069    /// [454] Das Bilanzierungsbeginn Datum muss kleiner sein als das Bilanzierungsende Datum in der SG8 „Datenstand des ÜNB“, SG 9 Energiemenge DZÜ Anteil
6070    fn evaluate_454(&self, _ctx: &EvaluationContext) -> ConditionResult {
6071        // TODO: implement
6072        ConditionResult::Unknown
6073    }
6074
6075    /// [455] Das Bilanzierungsende-Datum muss größer sein, als das Bilanzierungsbeginn Datum in der SG8 „Datenstand des ÜNB“ , SG 9 Energiemenge DZÜ Anteil
6076    fn evaluate_455(&self, _ctx: &EvaluationContext) -> ConditionResult {
6077        // TODO: implement
6078        ConditionResult::Unknown
6079    }
6080
6081    /// [456] Wenn in demselben RFF der Code Z37 (Technische Ressource) im DE1153 vorhanden
6082    fn evaluate_456(&self, _ctx: &EvaluationContext) -> ConditionResult {
6083        // TODO: implement
6084        ConditionResult::Unknown
6085    }
6086
6087    /// [457] Wenn bei der Bestellung das Messprodukten 9991000001498 bestellt wurde
6088    fn evaluate_457(&self, _ctx: &EvaluationContext) -> ConditionResult {
6089        // TODO: implement
6090        ConditionResult::Unknown
6091    }
6092
6093    /// [458] Wenn bei der Bestellung das Konfigurationsprodukte 9991000000739 bestellt wurde
6094    fn evaluate_458(&self, _ctx: &EvaluationContext) -> ConditionResult {
6095        // TODO: implement
6096        ConditionResult::Unknown
6097    }
6098
6099    /// [459] Wenn bei der Bestellung ein Messprodukt der Codeliste der Konfigurationen aus dem Kapitel 4.4 mit dem Übertragungsweg \"CLS-Direkt aus dem SMGW\" bestellt wurde
6100    fn evaluate_459(&self, ctx: &EvaluationContext) -> ConditionResult {
6101        ctx.external.evaluate("code_list_membership_check")
6102    }
6103
6104    /// [460] Wenn bei der Bestellung ein Messprodukt der Codeliste der Konfigurationen aus dem Kapitel 4.4 mit dem Übertragungsweg \"aus dem SMGW\" bestellt wurde
6105    fn evaluate_460(&self, ctx: &EvaluationContext) -> ConditionResult {
6106        ctx.external.evaluate("code_list_membership_check")
6107    }
6108
6109    /// [462] Wenn in derselben SG10 das CCI+Z17 (Stromverbrauchsart) im CAV+ZH1 (Inbetriebsetzung der TR vor 2024) vorhanden
6110    fn evaluate_462(&self, _ctx: &EvaluationContext) -> ConditionResult {
6111        // TODO: implement
6112        ConditionResult::Unknown
6113    }
6114
6115    /// [463] Wenn in derselben SG10 das CCI+Z61++ZF9 (Kunde erfüllt die Voraussetzung nach EnFG) vorhanden
6116    fn evaluate_463(&self, _ctx: &EvaluationContext) -> ConditionResult {
6117        // TODO: implement
6118        ConditionResult::Unknown
6119    }
6120
6121    /// [465] Wenn in derselben SG8 (Daten der Technischen Ressource) das RFF+Z38 (Referenz auf die der Technischen Ressource zugeordnete Steuerbare Ressource) vorhanden ist
6122    fn evaluate_465(&self, _ctx: &EvaluationContext) -> ConditionResult {
6123        // TODO: implement
6124        ConditionResult::Unknown
6125    }
6126
6127    /// [466] Wenn in derselben SG8 (Daten der Technischen Ressource) das RFF+Z32 (Referenz auf die der Technischen Ressource zugeordneten Netzlokation) vorhanden ist
6128    fn evaluate_466(&self, _ctx: &EvaluationContext) -> ConditionResult {
6129        // TODO: implement
6130        ConditionResult::Unknown
6131    }
6132
6133    /// [467] Wenn in derselben SG8 (Daten der Technischen Ressource) das CAV+ZG8 (Technischen Ressource fällt unter § 14a EnWG) vorhanden ist
6134    fn evaluate_467(&self, _ctx: &EvaluationContext) -> ConditionResult {
6135        // TODO: implement
6136        ConditionResult::Unknown
6137    }
6138
6139    /// [468] Wenn in derselben SG8 (Daten der Technischen Ressource) das SG10 CAV+ZH0 (Inbetriebsetzung der TR nach 2023) vorhanden ist
6140    fn evaluate_468(&self, _ctx: &EvaluationContext) -> ConditionResult {
6141        // TODO: implement
6142        ConditionResult::Unknown
6143    }
6144
6145    /// [469] Wenn in derselben SG8 (Daten der Technischen Ressource) das SG10 CAV+ZH1 (Inbetriebsetzung der TR vor 2024) vorhanden ist
6146    fn evaluate_469(&self, _ctx: &EvaluationContext) -> ConditionResult {
6147        // TODO: implement
6148        ConditionResult::Unknown
6149    }
6150
6151    /// [470] Wenn in derselben SG8 (Daten der Technischen Ressource) das CAV+ZH5 (Wechsel in das in das § 14a EnWG-Modell gem. Festlegung BK6-22-300 wurde durchgeführt) vorhanden ist
6152    fn evaluate_470(&self, _ctx: &EvaluationContext) -> ConditionResult {
6153        // TODO: implement
6154        ConditionResult::Unknown
6155    }
6156
6157    /// [471] Wenn im selben SG6 RFF+Z49/ Z53 (Verwendungszeitraum der Daten: Gültige Daten/ Keine Daten) im DE1156 (Zeitraum-ID) eine Zeitraum ID genannt ist, die kleiner ist als in einem anderen SG6 RFF+Z49/ ...
6158    fn evaluate_471(&self, _ctx: &EvaluationContext) -> ConditionResult {
6159        // TODO: implement
6160        ConditionResult::Unknown
6161    }
6162
6163    /// [472] Wenn im selben SG6 RFF+Z48/ Z55 (Verwendungszeitraum der Daten: Erwartete Daten/ Keine Daten erwartet) im DE1156 (Zeitraum-ID) eine Zeitraum ID genannt ist, die kleiner ist als in einem anderen SG6...
6164    fn evaluate_472(&self, _ctx: &EvaluationContext) -> ConditionResult {
6165        // TODO: implement
6166        ConditionResult::Unknown
6167    }
6168
6169    /// [473] Wenn im selben SG6 RFF+Z47/ Z54 (Verwendungszeitraum der Daten: Im System vorhandene Daten/ Im System keine Daten vorhanden) im DE1156 (Zeitraum-ID) eine Zeitraum ID genannt ist, die kleiner ist al...
6170    fn evaluate_473(&self, _ctx: &EvaluationContext) -> ConditionResult {
6171        // TODO: implement
6172        ConditionResult::Unknown
6173    }
6174
6175    /// [474] Wenn SG4 STS+7++ZC8 (Transaktionsgrund \"Beendigung der Zuordnung\") vorhanden
6176    fn evaluate_474(&self, _ctx: &EvaluationContext) -> ConditionResult {
6177        // TODO: implement
6178        ConditionResult::Unknown
6179    }
6180
6181    /// [475] Wenn SG4 STS+7++ZH1 (Transaktionsgrund \"Aufhebung einer zukünftigen Zuordnung wegen Stilllegung\") vorhanden
6182    fn evaluate_475(&self, _ctx: &EvaluationContext) -> ConditionResult {
6183        // TODO: implement
6184        ConditionResult::Unknown
6185    }
6186
6187    /// [476] Wenn SG4 STS+7++xxx+ZW0 (Transaktionsgrundergänzung Geschäftsvorfall 1) vorhanden
6188    fn evaluate_476(&self, _ctx: &EvaluationContext) -> ConditionResult {
6189        // TODO: implement
6190        ConditionResult::Unknown
6191    }
6192
6193    /// [477] Wenn SG4 STS+7++xxx+ZW1 (Transaktionsgrundergänzung Geschäftsvorfall 2) vorhanden
6194    fn evaluate_477(&self, _ctx: &EvaluationContext) -> ConditionResult {
6195        // TODO: implement
6196        ConditionResult::Unknown
6197    }
6198
6199    /// [478] Wenn SG4 STS+7++xxx+ZW2 (Transaktionsgrundergänzung Geschäftsvorfall 3) vorhanden
6200    fn evaluate_478(&self, _ctx: &EvaluationContext) -> ConditionResult {
6201        // TODO: implement
6202        ConditionResult::Unknown
6203    }
6204
6205    /// [479] Wenn SG4 STS+7++xxx+ZW3 (Transaktionsgrundergänzung Erzeugende Marktlokation) vorhanden
6206    fn evaluate_479(&self, _ctx: &EvaluationContext) -> ConditionResult {
6207        // TODO: implement
6208        ConditionResult::Unknown
6209    }
6210
6211    /// [480] Wenn SG4 STS+7++xxx+ZW4 (Transaktionsgrundergänzung Verbrauchende Marktlokation) vorhanden
6212    fn evaluate_480(&self, _ctx: &EvaluationContext) -> ConditionResult {
6213        // TODO: implement
6214        ConditionResult::Unknown
6215    }
6216
6217    /// [481] Wenn SG4 STS+7++xxx+ZW5 (Transaktionsgrundergänzung Tranche) vorhanden
6218    fn evaluate_481(&self, _ctx: &EvaluationContext) -> ConditionResult {
6219        // TODO: implement
6220        ConditionResult::Unknown
6221    }
6222
6223    /// [483] Wenn SG4 STS+7++xxx+ZW7 (Transaktionsgrundergänzung Gemessene Marktlokation) vorhanden
6224    fn evaluate_483(&self, _ctx: &EvaluationContext) -> ConditionResult {
6225        // TODO: implement
6226        ConditionResult::Unknown
6227    }
6228
6229    /// [484] Wenn SG4 STS+7++xxx+ZW8 (Transaktionsgrundergänzung Fall1) vorhanden
6230    fn evaluate_484(&self, _ctx: &EvaluationContext) -> ConditionResult {
6231        // TODO: implement
6232        ConditionResult::Unknown
6233    }
6234
6235    /// [487] Wenn SG4 STS+7++xxx+ZX1 (Transaktionsgrundergänzung Fall4) vorhanden
6236    fn evaluate_487(&self, _ctx: &EvaluationContext) -> ConditionResult {
6237        // TODO: implement
6238        ConditionResult::Unknown
6239    }
6240
6241    /// [489] Nur bei dem ältesten Zeitraum welcher mit SG6 RFF+Z49 (Verwendungszeitraum der Daten: Gültige Daten) beschrieben ist
6242    fn evaluate_489(&self, _ctx: &EvaluationContext) -> ConditionResult {
6243        // TODO: implement
6244        ConditionResult::Unknown
6245    }
6246
6247    /// [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
6248    fn evaluate_490(&self, _ctx: &EvaluationContext) -> ConditionResult {
6249        // TODO: implement
6250        ConditionResult::Unknown
6251    }
6252
6253    /// [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
6254    fn evaluate_491(&self, _ctx: &EvaluationContext) -> ConditionResult {
6255        // TODO: implement
6256        ConditionResult::Unknown
6257    }
6258
6259    /// [494] Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt
6260    fn evaluate_494(&self, _ctx: &EvaluationContext) -> ConditionResult {
6261        // TODO: implement
6262        ConditionResult::Unknown
6263    }
6264
6265    /// [500] Hinweis: Code ist gemäß der Kategorie der zu stornierenden Meldung zu wählen
6266    fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
6267        // TODO: implement
6268        ConditionResult::Unknown
6269    }
6270
6271    /// [501] Hinweis: Es sind zur Unterstützung die Daten des LFA anzugeben
6272    fn evaluate_501(&self, _ctx: &EvaluationContext) -> ConditionResult {
6273        // TODO: implement
6274        ConditionResult::Unknown
6275    }
6276
6277    /// [502] Hinweis: Es wird der Betrachtungsmonat der DZR bzw. BAS angegeben
6278    fn evaluate_502(&self, _ctx: &EvaluationContext) -> ConditionResult {
6279        // TODO: implement
6280        ConditionResult::Unknown
6281    }
6282
6283    /// [503] Hinweis: Angabe des BGM DE1004 aus der ORDERS
6284    fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
6285        // TODO: implement
6286        ConditionResult::Unknown
6287    }
6288
6289    /// [504] Hinweis: Je Profil (ggf. inkl. Profilschar) ein Vorgang erforderlich
6290    fn evaluate_504(&self, _ctx: &EvaluationContext) -> ConditionResult {
6291        // TODO: implement
6292        ConditionResult::Unknown
6293    }
6294
6295    /// [505] Hinweis: Je zugeordneter ID und je EEG-Überführungszeitreihe ein Vorgang erforderlich
6296    fn evaluate_505(&self, _ctx: &EvaluationContext) -> ConditionResult {
6297        // TODO: implement
6298        ConditionResult::Unknown
6299    }
6300
6301    /// [506] Hinweis: Für jeden Code im LOC+Z16 (Marktlokation) sollen die entsprechenden Kundendaten des LF angegeben werden, falls bekannt
6302    fn evaluate_506(&self, _ctx: &EvaluationContext) -> ConditionResult {
6303        // TODO: implement
6304        ConditionResult::Unknown
6305    }
6306
6307    /// [507] Hinweis: Ursprünglich vom NB bestätigtes Beginndatum
6308    fn evaluate_507(&self, _ctx: &EvaluationContext) -> ConditionResult {
6309        // TODO: implement
6310        ConditionResult::Unknown
6311    }
6312
6313    /// [508] Hinweis: Ausschließlich kME sind über die NNE abrechenbar
6314    fn evaluate_508(&self, _ctx: &EvaluationContext) -> ConditionResult {
6315        // TODO: implement
6316        ConditionResult::Unknown
6317    }
6318
6319    /// [509] Hinweis: Handelt sich um ein mME oder iMS ist das RFF 1154 immer mit NEIN anzugeben
6320    fn evaluate_509(&self, _ctx: &EvaluationContext) -> ConditionResult {
6321        // TODO: implement
6322        ConditionResult::Unknown
6323    }
6324
6325    /// [510] Hinweis: Zu verwenden bei der Abmeldung der ESV
6326    fn evaluate_510(&self, _ctx: &EvaluationContext) -> ConditionResult {
6327        // TODO: implement
6328        ConditionResult::Unknown
6329    }
6330
6331    /// [511] Hinweis: Es sind alle Bilanzierungsgebiete anzugeben in denen das Profil verwendet wird
6332    fn evaluate_511(&self, _ctx: &EvaluationContext) -> ConditionResult {
6333        // TODO: implement
6334        ConditionResult::Unknown
6335    }
6336
6337    /// [512] Hinweis: Es ist informativ die bisherige Veräußerungsform des LFA an der erzeugenden Marktlokation anzugeben
6338    fn evaluate_512(&self, _ctx: &EvaluationContext) -> ConditionResult {
6339        // TODO: implement
6340        ConditionResult::Unknown
6341    }
6342
6343    /// [513] Hinweis: Es ist das nächstmögliche Datum ab dem DTM+471 aus der entsprechenden Anfrage zu ermitteln
6344    fn evaluate_513(&self, _ctx: &EvaluationContext) -> ConditionResult {
6345        // TODO: implement
6346        ConditionResult::Unknown
6347    }
6348
6349    /// [514] Hinweis: Es darf nur eine Information im DE3148 übermittelt werden
6350    fn evaluate_514(&self, _ctx: &EvaluationContext) -> ConditionResult {
6351        // TODO: implement
6352        ConditionResult::Unknown
6353    }
6354
6355    /// [515] Hinweis: Für den ZP der LieferantensummenZR anzugeben
6356    fn evaluate_515(&self, _ctx: &EvaluationContext) -> ConditionResult {
6357        // TODO: implement
6358        ConditionResult::Unknown
6359    }
6360
6361    /// [516] Hinweis: Es ist der Änderungszeitpunkt anzugeben an dem das Zuordnungsende des NBA und der Zuordnungsbeginn des NBN zu einer Marktlokation fallen
6362    fn evaluate_516(&self, _ctx: &EvaluationContext) -> ConditionResult {
6363        // TODO: implement
6364        ConditionResult::Unknown
6365    }
6366
6367    /// [518] Hinweis: Es sind alle Altlieferanten anzugeben, an die eine Abmeldeanfrage gesendet wird
6368    fn evaluate_518(&self, _ctx: &EvaluationContext) -> ConditionResult {
6369        // TODO: implement
6370        ConditionResult::Unknown
6371    }
6372
6373    /// [519] Hinweis: Wenn in der Anmeldung der Code ZAP vorhanden war, so ist dieser auch in der Antwort zu verwenden
6374    fn evaluate_519(&self, _ctx: &EvaluationContext) -> ConditionResult {
6375        // TODO: implement
6376        ConditionResult::Unknown
6377    }
6378
6379    /// [520] Hinweis: Bei der Verwendung des Codes ZAP handelt es sich immer um eine gemessene Marktlokation
6380    fn evaluate_520(&self, _ctx: &EvaluationContext) -> ConditionResult {
6381        // TODO: implement
6382        ConditionResult::Unknown
6383    }
6384
6385    /// [521] Hinweis: Wenn im zweiten DE 9013 des STS+7 (Transaktionsgrund) der Code ZAP vorhanden ist, so ist das hier angegebene Datum als Zuordnungsbeginn bei der Bildung der \"Ruhenden MaLo zu verstehen. Be...
6386    fn evaluate_521(&self, _ctx: &EvaluationContext) -> ConditionResult {
6387        // TODO: implement
6388        ConditionResult::Unknown
6389    }
6390
6391    /// [522] Hinweis: Es ist der NBN anzugeben
6392    fn evaluate_522(&self, _ctx: &EvaluationContext) -> ConditionResult {
6393        // TODO: implement
6394        ConditionResult::Unknown
6395    }
6396
6397    /// [523] Hinweis: Mindestens einmal für jede Marktlokation bzw. Tranche, die in der DZÜ / BG-CL / LF-SZR berücksichtigt wurde
6398    fn evaluate_523(&self, _ctx: &EvaluationContext) -> ConditionResult {
6399        // TODO: implement
6400        ConditionResult::Unknown
6401    }
6402
6403    /// [524] Hinweis: Mindestens einmal für jede Marktlokation bzw. Tranche, für die der LF nicht die gemeldete Ansicht des NB teilt
6404    fn evaluate_524(&self, _ctx: &EvaluationContext) -> ConditionResult {
6405        // TODO: implement
6406        ConditionResult::Unknown
6407    }
6408
6409    /// [525] Hinweis: Es sind nur die OBIS-Kennzahlen erlaubt, die im vorherigen Stammdatenaustausch zu dieser Marktlokation vom MSB zu diesem Zeitpunkt übermittelt wurden
6410    fn evaluate_525(&self, _ctx: &EvaluationContext) -> ConditionResult {
6411        // TODO: implement
6412        ConditionResult::Unknown
6413    }
6414
6415    /// [526] Hinweis: Wenn der Marktlokation keine Technische Ressource in der Lokationsbündelstruktur zugeordnet wurde
6416    fn evaluate_526(&self, _ctx: &EvaluationContext) -> ConditionResult {
6417        // TODO: implement
6418        ConditionResult::Unknown
6419    }
6420
6421    /// [527] Hinweis: Es sind alle Identifikatoren der Messlokationen anzugeben
6422    fn evaluate_527(&self, _ctx: &EvaluationContext) -> ConditionResult {
6423        // TODO: implement
6424        ConditionResult::Unknown
6425    }
6426
6427    /// [528] Hinweis: Es ist das Datum/ Daten aus der Anfrage zu verwenden
6428    fn evaluate_528(&self, _ctx: &EvaluationContext) -> ConditionResult {
6429        // TODO: implement
6430        ConditionResult::Unknown
6431    }
6432
6433    /// [529] Hinweis: Für zusätzliche nicht im Markt standardisierte Identifikatoren wie z.B. eine Netzbetreiber-Projektnummer
6434    fn evaluate_529(&self, _ctx: &EvaluationContext) -> ConditionResult {
6435        // TODO: implement
6436        ConditionResult::Unknown
6437    }
6438
6439    /// [530] Hinweis: Es sind alle an der Lokation vorhandenen Daten, die mit dieser Segmentgruppe übermittelt werden und zum Datum „Änderung zum“ Gültigkeit haben, anzugeben. Dies kann zur Folge haben, ...
6440    fn evaluate_530(&self, _ctx: &EvaluationContext) -> ConditionResult {
6441        // TODO: implement
6442        ConditionResult::Unknown
6443    }
6444
6445    /// [531] Hinweis: Es ist das Jahr anzugeben in dem die nächste Netznutzungsabrechnung erfolgt
6446    fn evaluate_531(&self, _ctx: &EvaluationContext) -> ConditionResult {
6447        // TODO: implement
6448        ConditionResult::Unknown
6449    }
6450
6451    /// [532] Hinweis: Kritische Daten (gemäß GPKE)
6452    fn evaluate_532(&self, _ctx: &EvaluationContext) -> ConditionResult {
6453        // TODO: implement
6454        ConditionResult::Unknown
6455    }
6456
6457    /// [533] Hinweis: Es ist die MP-ID des Lieferanten anzugeben
6458    fn evaluate_533(&self, _ctx: &EvaluationContext) -> ConditionResult {
6459        // TODO: implement
6460        ConditionResult::Unknown
6461    }
6462
6463    /// [555] Die Anwendungsfälle für die Durchführung der BDEW-Anwendungshilfe „Marktprozesse Netzbetreiberwechsel Sparte Strom“ sind ab dem 01.08.2025 für Netzbetreiberwechsel ab dem 01.01.2026 zu verw...
6464    fn evaluate_555(&self, _ctx: &EvaluationContext) -> ConditionResult {
6465        // TODO: implement
6466        ConditionResult::Unknown
6467    }
6468
6469    /// [556] Hinweis: Wenn keine Korrespondenzanschrift des Endverbrauchers/ Kunden vorliegt, ist die Anschrift der Marktlokation zu übermitteln
6470    fn evaluate_556(&self, _ctx: &EvaluationContext) -> ConditionResult {
6471        // TODO: implement
6472        ConditionResult::Unknown
6473    }
6474
6475    /// [558] Hinweis: Diese Information kann freiwillig ausgetauscht werden
6476    fn evaluate_558(&self, _ctx: &EvaluationContext) -> ConditionResult {
6477        // TODO: implement
6478        ConditionResult::Unknown
6479    }
6480
6481    /// [559] Hinweis: Die Korrespondenzanschrift des Endverbrauchers/Kunden wird nicht zur Identifikation genutzt
6482    fn evaluate_559(&self, _ctx: &EvaluationContext) -> ConditionResult {
6483        // TODO: implement
6484        ConditionResult::Unknown
6485    }
6486
6487    /// [563] Hinweis: Für die ID der LieferantensummenZR
6488    fn evaluate_563(&self, _ctx: &EvaluationContext) -> ConditionResult {
6489        // TODO: implement
6490        ConditionResult::Unknown
6491    }
6492
6493    /// [566] Hinweis: Altlieferant
6494    fn evaluate_566(&self, _ctx: &EvaluationContext) -> ConditionResult {
6495        // TODO: implement
6496        ConditionResult::Unknown
6497    }
6498
6499    /// [567] Hinweis: Neulieferant
6500    fn evaluate_567(&self, _ctx: &EvaluationContext) -> ConditionResult {
6501        // TODO: implement
6502        ConditionResult::Unknown
6503    }
6504
6505    /// [568] Hinweis: Lieferant der LieferantensummenZR
6506    fn evaluate_568(&self, _ctx: &EvaluationContext) -> ConditionResult {
6507        // TODO: implement
6508        ConditionResult::Unknown
6509    }
6510
6511    /// [569] Hinweis: Dritter Nutzer
6512    fn evaluate_569(&self, _ctx: &EvaluationContext) -> ConditionResult {
6513        // TODO: implement
6514        ConditionResult::Unknown
6515    }
6516
6517    /// [570] Hinweis: Netzbetreiber Alt
6518    fn evaluate_570(&self, _ctx: &EvaluationContext) -> ConditionResult {
6519        // TODO: implement
6520        ConditionResult::Unknown
6521    }
6522
6523    /// [572] Hinweis: Kundenname aus Anmeldung Lieferant neu
6524    fn evaluate_572(&self, _ctx: &EvaluationContext) -> ConditionResult {
6525        // TODO: implement
6526        ConditionResult::Unknown
6527    }
6528
6529    /// [576] Hinweis: Stammdaten des bisherigen Messstellenbetreibers
6530    fn evaluate_576(&self, _ctx: &EvaluationContext) -> ConditionResult {
6531        // TODO: implement
6532        ConditionResult::Unknown
6533    }
6534
6535    /// [577] Hinweis: Wird mit dem ursprünglich vom NB bestätigten Beginnzeitpunkt gefüllt
6536    fn evaluate_577(&self, _ctx: &EvaluationContext) -> ConditionResult {
6537        // TODO: implement
6538        ConditionResult::Unknown
6539    }
6540
6541    /// [579] Hinweis: Auslösender Marktpartner (LFN bei STS+7++ZH0/ZG9, NB bei STS+7++ZH1)
6542    fn evaluate_579(&self, _ctx: &EvaluationContext) -> ConditionResult {
6543        // TODO: implement
6544        ConditionResult::Unknown
6545    }
6546
6547    /// [581] Hinweis: Es ist der Zeitpunkt anzugeben, zu welchem der Vertrag am Tag des Versandes der Antwort noch kündbar ist.
6548    fn evaluate_581(&self, _ctx: &EvaluationContext) -> ConditionResult {
6549        // TODO: implement
6550        ConditionResult::Unknown
6551    }
6552
6553    /// [586] Hinweis: Die Messlokationsadresse ist der Messlokation zugeordnet, welche in SG8 SEQ+Z18/ ZF3 (Daten der Messlokation) mit CCI+Z01++Z82 (Verwendungsumfang: ID der prozessual behandelten Messlokatio...
6554    fn evaluate_586(&self, _ctx: &EvaluationContext) -> ConditionResult {
6555        // TODO: implement
6556        ConditionResult::Unknown
6557    }
6558
6559    /// [590] Hinweis: Für den Empfang des Steuerbefehls
6560    fn evaluate_590(&self, _ctx: &EvaluationContext) -> ConditionResult {
6561        // TODO: implement
6562        ConditionResult::Unknown
6563    }
6564
6565    /// [594] Hinweis: Es ist der ZPB des ZP der NGZ und die ZPB der NZR anzugeben
6566    fn evaluate_594(&self, _ctx: &EvaluationContext) -> ConditionResult {
6567        // TODO: implement
6568        ConditionResult::Unknown
6569    }
6570
6571    /// [599] Hinweis: Es ist der Name und die Adresse des Ablesekartenempfängers für die Messlokation anzugeben, welche in SG8 SEQ+Z18 (Daten der Messlokation) mit CCI+Z01++Z82 (Verwendungsumfang: ID der proz...
6572    fn evaluate_599(&self, _ctx: &EvaluationContext) -> ConditionResult {
6573        // TODO: implement
6574        ConditionResult::Unknown
6575    }
6576
6577    /// [601] Hinweis: Es ist die ID der Marktlokation und alle Identifikatoren der Messlokationen anzugeben. Sowie wenn vorhanden die Tranche/n der Marklokation
6578    fn evaluate_601(&self, _ctx: &EvaluationContext) -> ConditionResult {
6579        // TODO: implement
6580        ConditionResult::Unknown
6581    }
6582
6583    /// [606] Hinweis: In diesem Segment bzw. SG sind die Daten aus der Sicht des NB anzugeben
6584    fn evaluate_606(&self, _ctx: &EvaluationContext) -> ConditionResult {
6585        // TODO: implement
6586        ConditionResult::Unknown
6587    }
6588
6589    /// [609] Hinweis: In diesem Segment bzw. SG sind die zwischen NB, LF und ÜNB im Rahmen der Marktkommunikation ausgetauschten Daten aus der Sicht des ÜNB anzugeben
6590    fn evaluate_609(&self, _ctx: &EvaluationContext) -> ConditionResult {
6591        // TODO: implement
6592        ConditionResult::Unknown
6593    }
6594
6595    /// [611] Hinweis: Wenn das Unternehmen NB die Aufgaben der Marktrolle LF wahrnimmt, ist die MP-ID des Unternehmens NB in der Marktrolle LF anzugeben
6596    fn evaluate_611(&self, _ctx: &EvaluationContext) -> ConditionResult {
6597        // TODO: implement
6598        ConditionResult::Unknown
6599    }
6600
6601    /// [614] Hinweis: Es werden nur die OBIS Kennzahlen übermittelt die für die Bilanzierung relevant sind
6602    fn evaluate_614(&self, _ctx: &EvaluationContext) -> ConditionResult {
6603        // TODO: implement
6604        ConditionResult::Unknown
6605    }
6606
6607    /// [617] Hinweis: Mehrere Vorgänge für eine Marktlokation bei Wechsel bilanzierungsrelevanter Stammdaten innerhalb des Bilanzierungsmonats
6608    fn evaluate_617(&self, _ctx: &EvaluationContext) -> ConditionResult {
6609        // TODO: implement
6610        ConditionResult::Unknown
6611    }
6612
6613    /// [618] Hinweis: Bisheriges Datum des MSBA. Sollte der MSBN ein abweichendes Datum verwenden wollen, so teilt er das neue Datum mit einer Stammdatenänderung mit
6614    fn evaluate_618(&self, _ctx: &EvaluationContext) -> ConditionResult {
6615        // TODO: implement
6616        ConditionResult::Unknown
6617    }
6618
6619    /// [619] Hinweis: Für die selbständige Änderungsmöglichkeit der Schwellwertunter- / -über-schreitung
6620    fn evaluate_619(&self, _ctx: &EvaluationContext) -> ConditionResult {
6621        // TODO: implement
6622        ConditionResult::Unknown
6623    }
6624
6625    /// [621] Hinweis: Es ist der MSB anzugeben, welcher ab dem Zeitpunkt der Lokation zugeordnet ist, der in DTM+76 (Datum zum geplanten Leistungsbeginn) genannt ist.
6626    fn evaluate_621(&self, _ctx: &EvaluationContext) -> ConditionResult {
6627        // TODO: implement
6628        ConditionResult::Unknown
6629    }
6630
6631    /// [622] Hinweis: Falls die OBIS-Kennzahl für mehrere Marktrollen relevant ist, so muss die Segmentgruppe pro Marktrolle wiederholt werden
6632    fn evaluate_622(&self, _ctx: &EvaluationContext) -> ConditionResult {
6633        // TODO: implement
6634        ConditionResult::Unknown
6635    }
6636
6637    /// [623] Hinweis: Es sind alle Identifikatoren der Messlokationen anzugeben, die zur Ermittlung der Energiemenge der im Vorgang genannten Marktlokation benötigt werden
6638    fn evaluate_623(&self, _ctx: &EvaluationContext) -> ConditionResult {
6639        // TODO: implement
6640        ConditionResult::Unknown
6641    }
6642
6643    /// [630] Hinweis: Wenn die Liste abgelehnt wird, ist kein Vorgang enthalten
6644    fn evaluate_630(&self, _ctx: &EvaluationContext) -> ConditionResult {
6645        // TODO: implement
6646        ConditionResult::Unknown
6647    }
6648
6649    /// [631] Hinweis: Es ist die Listennummer aus der Lieferanten- bzw. Bilanzierungsgebietsclearingliste zu verwenden
6650    fn evaluate_631(&self, _ctx: &EvaluationContext) -> ConditionResult {
6651        // TODO: implement
6652        ConditionResult::Unknown
6653    }
6654
6655    /// [632] Hinweis: Es ist die Listennummer aus der Lieferanten-ausfallarbeits-clearingliste zu verwenden
6656    fn evaluate_632(&self, _ctx: &EvaluationContext) -> ConditionResult {
6657        // TODO: implement
6658        ConditionResult::Unknown
6659    }
6660
6661    /// [637] Hinweis: Bei Verpflichtungsanfrage
6662    fn evaluate_637(&self, _ctx: &EvaluationContext) -> ConditionResult {
6663        // TODO: implement
6664        ConditionResult::Unknown
6665    }
6666
6667    /// [638] Hinweis: Bei Aufforderung zur Übernahme der einzelnen Messlokation durch den gMSB
6668    fn evaluate_638(&self, _ctx: &EvaluationContext) -> ConditionResult {
6669        // TODO: implement
6670        ConditionResult::Unknown
6671    }
6672
6673    /// [639] Hinweis: Wenn Antwort auf Deaktivierung
6674    fn evaluate_639(&self, _ctx: &EvaluationContext) -> ConditionResult {
6675        // TODO: implement
6676        ConditionResult::Unknown
6677    }
6678
6679    /// [640] Hinweis: Wenn Antwort auf Aktivierung
6680    fn evaluate_640(&self, _ctx: &EvaluationContext) -> ConditionResult {
6681        // TODO: implement
6682        ConditionResult::Unknown
6683    }
6684
6685    /// [641] Hinweis: Wenn Einzelanforderung vorliegt
6686    fn evaluate_641(&self, _ctx: &EvaluationContext) -> ConditionResult {
6687        // TODO: implement
6688        ConditionResult::Unknown
6689    }
6690
6691    /// [642] Hinweis: Wenn Abo vorliegt
6692    fn evaluate_642(&self, _ctx: &EvaluationContext) -> ConditionResult {
6693        // TODO: implement
6694        ConditionResult::Unknown
6695    }
6696
6697    /// [643] Hinweis: Nachfolgender Netzbetreiber
6698    fn evaluate_643(&self, _ctx: &EvaluationContext) -> ConditionResult {
6699        // TODO: implement
6700        ConditionResult::Unknown
6701    }
6702
6703    /// [645] Hinweis: Es ist der Bilanzkreis des LF anzugeben
6704    fn evaluate_645(&self, _ctx: &EvaluationContext) -> ConditionResult {
6705        // TODO: implement
6706        ConditionResult::Unknown
6707    }
6708
6709    /// [646] Hinweis: Es ist der RD-Bilanzkreis des ANB anzugeben
6710    fn evaluate_646(&self, _ctx: &EvaluationContext) -> ConditionResult {
6711        // TODO: implement
6712        ConditionResult::Unknown
6713    }
6714
6715    /// [647] Hinweis: Es ist der RD-Bilanzkreis des anfNB anzugeben
6716    fn evaluate_647(&self, _ctx: &EvaluationContext) -> ConditionResult {
6717        // TODO: implement
6718        ConditionResult::Unknown
6719    }
6720
6721    /// [648] Hinweis: Soll ein Produkt ab dem Datum \"Änderung zum\" nicht mehr vorhanden sein, wird dies durch nicht angeben des PIA+5 ausgedrückt
6722    fn evaluate_648(&self, _ctx: &EvaluationContext) -> ConditionResult {
6723        // TODO: implement
6724        ConditionResult::Unknown
6725    }
6726
6727    /// [651] Hinweis: Es sind die Marktlokationen anzugeben, zu welchen die hier genannte OBIS benötigt wird
6728    fn evaluate_651(&self, _ctx: &EvaluationContext) -> ConditionResult {
6729        // TODO: implement
6730        ConditionResult::Unknown
6731    }
6732
6733    /// [653] Hinweis: Es sind alle Netzlokationen, Marktlokationen, Tranchen und Messlokationen zu nennen, die durch die Bestätigung der Abmeldung der prozessual behandelten Messlokation nicht mehr dem MSB zug...
6734    fn evaluate_653(&self, _ctx: &EvaluationContext) -> ConditionResult {
6735        // TODO: implement
6736        ConditionResult::Unknown
6737    }
6738
6739    /// [655] Hinweis: Es ist die Listennummer aus der DZÜ Liste zu verwenden
6740    fn evaluate_655(&self, _ctx: &EvaluationContext) -> ConditionResult {
6741        // TODO: implement
6742        ConditionResult::Unknown
6743    }
6744
6745    /// [659] Hinweis: Bei Tranchen ist nur der Meldepunkt der Tranche anzugeben
6746    fn evaluate_659(&self, _ctx: &EvaluationContext) -> ConditionResult {
6747        // TODO: implement
6748        ConditionResult::Unknown
6749    }
6750
6751    /// [660] Hinweis: Es ist die ID der BK-Summenzeitreihe Aggregationsebene BG anzugeben
6752    fn evaluate_660(&self, _ctx: &EvaluationContext) -> ConditionResult {
6753        // TODO: implement
6754        ConditionResult::Unknown
6755    }
6756
6757    /// [662] Hinweis: Es sind die Daten NGZ und die Daten der NZR anzugeben
6758    fn evaluate_662(&self, _ctx: &EvaluationContext) -> ConditionResult {
6759        // TODO: implement
6760        ConditionResult::Unknown
6761    }
6762
6763    /// [663] Hinweis: Es ist die ID der Marktlokation und die ZPB des ZP der NGZ anzugeben
6764    fn evaluate_663(&self, _ctx: &EvaluationContext) -> ConditionResult {
6765        // TODO: implement
6766        ConditionResult::Unknown
6767    }
6768
6769    /// [664] Hinweis: Es ist das BG des NB (LPB) anzugeben
6770    fn evaluate_664(&self, _ctx: &EvaluationContext) -> ConditionResult {
6771        // TODO: implement
6772        ConditionResult::Unknown
6773    }
6774
6775    /// [665] Hinweis: Wenn ein Zähler mit einem SMGW parametriert ist werden an dem Zähler keine OBIS-Kennzahlen angegeben Hier gibt es nur OBIS Kennzahlen vom SMGW
6776    fn evaluate_665(&self, _ctx: &EvaluationContext) -> ConditionResult {
6777        // TODO: implement
6778        ConditionResult::Unknown
6779    }
6780
6781    /// [667] Hinweis: Für Zeiten die bilanziert wurden, aber inzwischen keine Aggregationsverantwortung beim ÜNB vorliegt, ist eine SG8 mit SG8 - SG10 CCI+6=ZA8 oder SG 10 CCI+6 = ZA9 CAV=ZG4 und SG8 - SG9 QT...
6782    fn evaluate_667(&self, _ctx: &EvaluationContext) -> ConditionResult {
6783        // TODO: implement
6784        ConditionResult::Unknown
6785    }
6786
6787    /// [668] Hinweis: Dieses Segment wird nach Abschluss der Einführung der Lokationsbündelstruktur zum 01.10.2025 aus der UTILMD entfernt
6788    fn evaluate_668(&self, _ctx: &EvaluationContext) -> ConditionResult {
6789        // TODO: implement
6790        ConditionResult::Unknown
6791    }
6792
6793    /// [670] Hinweis: Es sind alle Netzlokationen, zu nennen, die dem gleichen Lokationsbündel angehören
6794    fn evaluate_670(&self, _ctx: &EvaluationContext) -> ConditionResult {
6795        // TODO: implement
6796        ConditionResult::Unknown
6797    }
6798
6799    /// [671] Hinweis: Es sind alle Marktlokationen, zu nennen, die dem gleichen Lokationsbündel angehören
6800    fn evaluate_671(&self, _ctx: &EvaluationContext) -> ConditionResult {
6801        // TODO: implement
6802        ConditionResult::Unknown
6803    }
6804
6805    /// [672] Hinweis: Es sind alle Technischen Ressourcen, zu nennen, die dem gleichen Lokationsbündel angehören
6806    fn evaluate_672(&self, _ctx: &EvaluationContext) -> ConditionResult {
6807        // TODO: implement
6808        ConditionResult::Unknown
6809    }
6810
6811    /// [673] Hinweis: Es sind alle Steuerbaren Ressourcen, zu nennen, die dem gleichen Lokationsbündel angehören
6812    fn evaluate_673(&self, _ctx: &EvaluationContext) -> ConditionResult {
6813        // TODO: implement
6814        ConditionResult::Unknown
6815    }
6816
6817    /// [674] Hinweis: Es sind alle Tranchen, zu nennen, die dem gleichen Lokationsbündel angehören
6818    fn evaluate_674(&self, _ctx: &EvaluationContext) -> ConditionResult {
6819        // TODO: implement
6820        ConditionResult::Unknown
6821    }
6822
6823    /// [675] Hinweis: Es sind alle Messlokationen, zu nennen, die Lokationsbündel angehören
6824    fn evaluate_675(&self, _ctx: &EvaluationContext) -> ConditionResult {
6825        // TODO: implement
6826        ConditionResult::Unknown
6827    }
6828
6829    /// [677] Hinweis: Es sind alle Netzlokationen, zu nennen, die aktuell und / oder zukünftig dem gleichen Lokationsbündel angehören
6830    fn evaluate_677(&self, _ctx: &EvaluationContext) -> ConditionResult {
6831        // TODO: implement
6832        ConditionResult::Unknown
6833    }
6834
6835    /// [678] Hinweis: Es sind alle Marktlokationen, zu nennen, die aktuell und / oder zukünftig dem gleichen Lokationsbündel angehören
6836    fn evaluate_678(&self, _ctx: &EvaluationContext) -> ConditionResult {
6837        // TODO: implement
6838        ConditionResult::Unknown
6839    }
6840
6841    /// [679] Hinweis: Es sind alle Technischen Ressourcen, zu nennen, die aktuell und / oder zukünftig dem gleichen Lokationsbündel angehören
6842    fn evaluate_679(&self, _ctx: &EvaluationContext) -> ConditionResult {
6843        // TODO: implement
6844        ConditionResult::Unknown
6845    }
6846
6847    /// [680] Hinweis: Es sind alle Steuerbaren Ressourcen, zu nennen, die aktuell und / oder zukünftig dem gleichen Lokationsbündel angehören
6848    fn evaluate_680(&self, _ctx: &EvaluationContext) -> ConditionResult {
6849        // TODO: implement
6850        ConditionResult::Unknown
6851    }
6852
6853    /// [682] Hinweis: Es sind alle Messlokationen, zu nennen, die aktuell und / oder zukünftig dem gleichen Lokationsbündel angehören
6854    fn evaluate_682(&self, _ctx: &EvaluationContext) -> ConditionResult {
6855        // TODO: implement
6856        ConditionResult::Unknown
6857    }
6858
6859    /// [683] Hinweis: Es sind alle ID der Netzlokationen, welche der im SG5 LOC+Z16 angegebenen Marktlokation aktuell und / oder zukünftig vorgelagert sind, anzugeben
6860    fn evaluate_683(&self, _ctx: &EvaluationContext) -> ConditionResult {
6861        // TODO: implement
6862        ConditionResult::Unknown
6863    }
6864
6865    /// [684] Hinweis: Es sind alle ID der Technischen Ressourcen, welche der im LOC+Z16/ Z22 angegebenen Marktlokation aktuell und / oder zukünftig zugehören, anzugeben
6866    fn evaluate_684(&self, _ctx: &EvaluationContext) -> ConditionResult {
6867        // TODO: implement
6868        ConditionResult::Unknown
6869    }
6870
6871    /// [685] Hinweis: Es sind alle ID der Steuerbaren Ressourcen, welche der im LOC+Z20 angegebenen Technischen Ressourcen aktuell und / oder zukünftig zugeordnet sind, anzugeben.
6872    fn evaluate_685(&self, _ctx: &EvaluationContext) -> ConditionResult {
6873        // TODO: implement
6874        ConditionResult::Unknown
6875    }
6876
6877    /// [687] Hinweis: Es sind alle Messlokationen zu nennen, die für die Energiemengenermittlung aktuell und / oder zukünftig der im LOC+Z16/ Z22 angegebenen Marktlokation notwendig sind
6878    fn evaluate_687(&self, _ctx: &EvaluationContext) -> ConditionResult {
6879        // TODO: implement
6880        ConditionResult::Unknown
6881    }
6882
6883    /// [688] Hinweis: Es sind alle ID der Netzlokationen, welche der im LOC+Z16 angegebenen Marktlokation vorgelagert sind, anzugeben
6884    fn evaluate_688(&self, _ctx: &EvaluationContext) -> ConditionResult {
6885        // TODO: implement
6886        ConditionResult::Unknown
6887    }
6888
6889    /// [689] Hinweis: Es sind alle ID der Technischen Ressourcen, welche der im LOC+Z16 angegebenen Marktlokation zugehören, anzugeben
6890    fn evaluate_689(&self, _ctx: &EvaluationContext) -> ConditionResult {
6891        // TODO: implement
6892        ConditionResult::Unknown
6893    }
6894
6895    /// [690] Hinweis: Es sind alle ID der Steuerbaren Ressourcen, welche der im LOC+Z20 angegebenen Technischen Ressourcen zugeordnet sind, anzugeben
6896    fn evaluate_690(&self, _ctx: &EvaluationContext) -> ConditionResult {
6897        // TODO: implement
6898        ConditionResult::Unknown
6899    }
6900
6901    /// [693] Hinweis: Es sind die Daten NGZ anzugeben
6902    fn evaluate_693(&self, _ctx: &EvaluationContext) -> ConditionResult {
6903        // TODO: implement
6904        ConditionResult::Unknown
6905    }
6906
6907    /// [694] Hinweis: Wenn in einer Marktlokation eine ID für eine Technischen Ressource vergeben wird, müssen für alle ggf. weitere Technische Ressourcen in der Marktlokation ID vergeben werden. Hintergrund...
6908    fn evaluate_694(&self, _ctx: &EvaluationContext) -> ConditionResult {
6909        // TODO: implement
6910        ConditionResult::Unknown
6911    }
6912
6913    /// [695] Hinweis: Verwendung, wenn Rolle LF einem Unternehmen NB zugeordnet ist
6914    fn evaluate_695(&self, _ctx: &EvaluationContext) -> ConditionResult {
6915        // TODO: implement
6916        ConditionResult::Unknown
6917    }
6918
6919    /// [696] Hinweis: Verwendung, nur wenn die Rolle LF nicht einem Unternehmen NB zugeordnet ist
6920    fn evaluate_696(&self, _ctx: &EvaluationContext) -> ConditionResult {
6921        // TODO: implement
6922        ConditionResult::Unknown
6923    }
6924
6925    /// [698] Hinweis: Für eine erzeugende Marktlokation muss für jede Technische Ressource eine ID der Technischen Ressourcen vergeben werden. Dies ist notwendig um die Nennleistung der Technische Ressource b...
6926    fn evaluate_698(&self, _ctx: &EvaluationContext) -> ConditionResult {
6927        // TODO: implement
6928        ConditionResult::Unknown
6929    }
6930
6931    /// [699] Hinweis: Es ist die ID der Steuerbare Ressource zu nennen über die die Technische Ressource gesteuert wird
6932    fn evaluate_699(&self, _ctx: &EvaluationContext) -> ConditionResult {
6933        // TODO: implement
6934        ConditionResult::Unknown
6935    }
6936
6937    /// [700] Hinweis: Es ist die ID der Netzlokation zu nennen über die die Technische Ressource gesteuert wird
6938    fn evaluate_700(&self, _ctx: &EvaluationContext) -> ConditionResult {
6939        // TODO: implement
6940        ConditionResult::Unknown
6941    }
6942
6943    /// [704] Hinweis: Segment ist zu verwenden, wenn es in Anfrage vorhanden war
6944    fn evaluate_704(&self, _ctx: &EvaluationContext) -> ConditionResult {
6945        // TODO: implement
6946        ConditionResult::Unknown
6947    }
6948
6949    /// [705] Hinweis: Wenn die Aktion eines Sequenzdiagramms \"Rückmeldung auf Änderung\" durchgeführt wird
6950    fn evaluate_705(&self, _ctx: &EvaluationContext) -> ConditionResult {
6951        // TODO: implement
6952        ConditionResult::Unknown
6953    }
6954
6955    /// [706] Hinweis: Wenn die Aktion eines Sequenzdiagramms \"Bestellung einer Änderung von Stammdaten...\" durchgeführt wird, mit dem Ziel ein Datenclearing durchzuführen
6956    fn evaluate_706(&self, ctx: &EvaluationContext) -> ConditionResult {
6957        ctx.external.evaluate("data_clearing_required")
6958    }
6959
6960    /// [707] Hinweis: für weitere Details siehe Kapitel \"SG6 Verwendungszeitraum der Daten\"
6961    fn evaluate_707(&self, _ctx: &EvaluationContext) -> ConditionResult {
6962        // TODO: implement
6963        ConditionResult::Unknown
6964    }
6965
6966    /// [708] Hinweis: Wenn die Aktion \"Ankündigung der Zuordnung des E/G zur Marktlokation\" durchgeführt wird
6967    fn evaluate_708(&self, _ctx: &EvaluationContext) -> ConditionResult {
6968        // TODO: implement
6969        ConditionResult::Unknown
6970    }
6971
6972    /// [709] Hinweis: Wenn die Aktion \"Zuordnung des E/G zur Marktlokation aufgrund fehlender Antwort\" durchgeführt wird
6973    fn evaluate_709(&self, _ctx: &EvaluationContext) -> ConditionResult {
6974        // TODO: implement
6975        ConditionResult::Unknown
6976    }
6977
6978    /// [710] Hinweis: Wenn die Aktion \"Ankündigung der Zuordnung des LFN zur Marktlokation bzw. Tranche\" durchgeführt wird
6979    fn evaluate_710(&self, _ctx: &EvaluationContext) -> ConditionResult {
6980        // TODO: implement
6981        ConditionResult::Unknown
6982    }
6983
6984    /// [711] Hinweis: Wenn die Aktion \"Zuordnung des LFN zur Marktlokation bzw. Tranche aufgrund fehlender Antwort\" durchgeführt wird
6985    fn evaluate_711(&self, _ctx: &EvaluationContext) -> ConditionResult {
6986        // TODO: implement
6987        ConditionResult::Unknown
6988    }
6989
6990    /// [712] Hinweis: Wenn die Aktion \"Ankündigung der Beendigung der Zuordnung des LF zur Marktlokation bzw. Tranche\" durchgeführt wird
6991    fn evaluate_712(&self, _ctx: &EvaluationContext) -> ConditionResult {
6992        // TODO: implement
6993        ConditionResult::Unknown
6994    }
6995
6996    /// [713] Hinweis: Wenn die Aktion \"Beendigung der Zuordnung des LF zur Marktlokation bzw. Tranche aufgrund fehlender Antwort\" durchgeführt wird
6997    fn evaluate_713(&self, _ctx: &EvaluationContext) -> ConditionResult {
6998        // TODO: implement
6999        ConditionResult::Unknown
7000    }
7001
7002    /// [714] Hinweis: Es ist bei einer unterjährigen Gebietsübernahme möglich hier den bisherigen NB zu nennen um aufzuzeigen, dass die im PIA+5 dieser SG8 genannten Gruppenartikel-ID bzw. Artikel-ID auf die...
7003    fn evaluate_714(&self, _ctx: &EvaluationContext) -> ConditionResult {
7004        // TODO: implement
7005        ConditionResult::Unknown
7006    }
7007
7008    /// [715] Hinweis: Dieser Transaktionsgrund darf für die betroffene Lokation nur angewendet werden wenn zuvor vom LF eine Anfrage Abr.-Daten BK-Abr. in die Vergangenheit erfolgte oder eine Korrektur zuvor m...
7009    fn evaluate_715(&self, _ctx: &EvaluationContext) -> ConditionResult {
7010        // TODO: implement
7011        ConditionResult::Unknown
7012    }
7013
7014    /// [716] Hinweis: Wenn die Aktion eines Sequenzdiagramms \"Rückmeldung auf Abrechnungsdaten\" durchgeführt wird
7015    fn evaluate_716(&self, _ctx: &EvaluationContext) -> ConditionResult {
7016        // TODO: implement
7017        ConditionResult::Unknown
7018    }
7019
7020    /// [717] Hinweis: Wenn die Aktion des Sequenzdiagramms \"Bestellung einer Änderung von Abrechnungsdaten\" durchgeführt wird, mit dem Ziel ein Datenclearing durchzuführen
7021    fn evaluate_717(&self, ctx: &EvaluationContext) -> ConditionResult {
7022        ctx.external.evaluate("data_clearing_required")
7023    }
7024
7025    /// [718] Hinweis: Es sind alle Tranchen der im SG5 LOC+Z16 (Marktlokation) genannten Marktlokation anzugeben, die für die im SG6 (Verwendungszeitraum der Daten) genannten Zeiträume vorhanden sind
7026    fn evaluate_718(&self, _ctx: &EvaluationContext) -> ConditionResult {
7027        // TODO: implement
7028        ConditionResult::Unknown
7029    }
7030
7031    /// [719] Hinweis: Dieser Transaktionsgrund darf für die betroffene Lokation nur angewendet werden wenn der LF auf eine Anfrage mit diesem Transaktionsgrund antwortet oder eine Anfrage Abr.-Daten BK-Abr. in...
7032    fn evaluate_719(&self, _ctx: &EvaluationContext) -> ConditionResult {
7033        // TODO: implement
7034        ConditionResult::Unknown
7035    }
7036
7037    /// [902] Format: Möglicher Wert: ≥ 0
7038    fn evaluate_902(&self, _ctx: &EvaluationContext) -> ConditionResult {
7039        // TODO: implement
7040        ConditionResult::Unknown
7041    }
7042
7043    /// [910] Format: Möglicher Wert: < 0 oder ≥ 0
7044    fn evaluate_910(&self, _ctx: &EvaluationContext) -> ConditionResult {
7045        // TODO: implement
7046        ConditionResult::Unknown
7047    }
7048
7049    /// [914] Format: Möglicher Wert: > 0
7050    fn evaluate_914(&self, _ctx: &EvaluationContext) -> ConditionResult {
7051        // TODO: implement
7052        ConditionResult::Unknown
7053    }
7054
7055    /// [922] Format: TR-ID
7056    fn evaluate_922(&self, _ctx: &EvaluationContext) -> ConditionResult {
7057        // TODO: implement
7058        ConditionResult::Unknown
7059    }
7060
7061    /// [926] Format: Möglicher Wert: 0
7062    fn evaluate_926(&self, _ctx: &EvaluationContext) -> ConditionResult {
7063        // TODO: implement
7064        ConditionResult::Unknown
7065    }
7066
7067    /// [930] Format: max. 2 Nachkommastellen
7068    fn evaluate_930(&self, _ctx: &EvaluationContext) -> ConditionResult {
7069        // TODO: implement
7070        ConditionResult::Unknown
7071    }
7072
7073    /// [931] Format: ZZZ = +00
7074    fn evaluate_931(&self, _ctx: &EvaluationContext) -> ConditionResult {
7075        // TODO: implement
7076        ConditionResult::Unknown
7077    }
7078
7079    /// [932] Format: HHMM = 2200
7080    fn evaluate_932(&self, _ctx: &EvaluationContext) -> ConditionResult {
7081        // TODO: implement
7082        ConditionResult::Unknown
7083    }
7084
7085    /// [933] Format: HHMM = 2300
7086    fn evaluate_933(&self, _ctx: &EvaluationContext) -> ConditionResult {
7087        // TODO: implement
7088        ConditionResult::Unknown
7089    }
7090
7091    /// [937] Format: keine Nachkommastelle
7092    fn evaluate_937(&self, _ctx: &EvaluationContext) -> ConditionResult {
7093        // TODO: implement
7094        ConditionResult::Unknown
7095    }
7096
7097    /// [938] Format: Möglicher Wert: <= 10
7098    fn evaluate_938(&self, _ctx: &EvaluationContext) -> ConditionResult {
7099        // TODO: implement
7100        ConditionResult::Unknown
7101    }
7102
7103    /// [939] Format: Die Zeichenkette muss die Zeichen @ und . enthalten
7104    fn evaluate_939(&self, _ctx: &EvaluationContext) -> ConditionResult {
7105        // TODO: implement
7106        ConditionResult::Unknown
7107    }
7108
7109    /// [940] Format: Die Zeichenkette muss mit dem Zeichen + beginnen und danach dürfen nur noch Ziffern folgen
7110    fn evaluate_940(&self, _ctx: &EvaluationContext) -> ConditionResult {
7111        // TODO: implement
7112        ConditionResult::Unknown
7113    }
7114
7115    /// [942] Format: n1-n2-n1-n3
7116    fn evaluate_942(&self, _ctx: &EvaluationContext) -> ConditionResult {
7117        // TODO: implement
7118        ConditionResult::Unknown
7119    }
7120
7121    /// [943] Format: n1-n2-n1
7122    fn evaluate_943(&self, _ctx: &EvaluationContext) -> ConditionResult {
7123        // TODO: implement
7124        ConditionResult::Unknown
7125    }
7126
7127    /// [946] Format: max. 11 Nachkommastellen
7128    fn evaluate_946(&self, _ctx: &EvaluationContext) -> ConditionResult {
7129        // TODO: implement
7130        ConditionResult::Unknown
7131    }
7132
7133    /// [948] Format: n1-n2-n1-n8-n2
7134    fn evaluate_948(&self, _ctx: &EvaluationContext) -> ConditionResult {
7135        // TODO: implement
7136        ConditionResult::Unknown
7137    }
7138
7139    /// [950] Format: Marktlokations-ID
7140    fn evaluate_950(&self, _ctx: &EvaluationContext) -> ConditionResult {
7141        // TODO: implement
7142        ConditionResult::Unknown
7143    }
7144
7145    /// [951] Format: Zählpunktbezeichnung
7146    fn evaluate_951(&self, _ctx: &EvaluationContext) -> ConditionResult {
7147        // TODO: implement
7148        ConditionResult::Unknown
7149    }
7150
7151    /// [952] Format: Gerätenummer nach DIN 43863-5
7152    fn evaluate_952(&self, _ctx: &EvaluationContext) -> ConditionResult {
7153        // TODO: implement
7154        ConditionResult::Unknown
7155    }
7156
7157    /// [955] Format: Möglicher Wert: < 100
7158    fn evaluate_955(&self, _ctx: &EvaluationContext) -> ConditionResult {
7159        // TODO: implement
7160        ConditionResult::Unknown
7161    }
7162
7163    /// [957] Format: n1-n2-n1-n8
7164    fn evaluate_957(&self, _ctx: &EvaluationContext) -> ConditionResult {
7165        // TODO: implement
7166        ConditionResult::Unknown
7167    }
7168
7169    /// [960] Format: Netzlokations-ID
7170    fn evaluate_960(&self, _ctx: &EvaluationContext) -> ConditionResult {
7171        // TODO: implement
7172        ConditionResult::Unknown
7173    }
7174
7175    /// [961] Format: SR-ID
7176    fn evaluate_961(&self, _ctx: &EvaluationContext) -> ConditionResult {
7177        // TODO: implement
7178        ConditionResult::Unknown
7179    }
7180
7181    /// [967] Format: Zertifikatskörper gemäß X509.1, BSI TR-03109-4
7182    fn evaluate_967(&self, _ctx: &EvaluationContext) -> ConditionResult {
7183        // TODO: implement
7184        ConditionResult::Unknown
7185    }
7186
7187    /// [2001] Segmentgruppe ist mindestens zweimal je SG4 IDE+24 (Vorgang) anzugeben
7188    fn evaluate_2001(&self, _ctx: &EvaluationContext) -> ConditionResult {
7189        // TODO: implement
7190        ConditionResult::Unknown
7191    }
7192
7193    /// [2002] Für jede Produktpaket-ID im SG8 SEQ+Z79 (Erforderliches Produkt) DE1050 genau einmal anzugeben
7194    fn evaluate_2002(&self, _ctx: &EvaluationContext) -> ConditionResult {
7195        // TODO: implement
7196        ConditionResult::Unknown
7197    }
7198
7199    /// [2003] Einmal für jede ruhende Marktlokation, die der Marktlokation \"Kundenanlage\" aus dem SG5 LOC+Z16 (Marktlokation) ab dem Zeitpunkt aus dem SG4 DTM+92 (Beginn zum) untergeordnet ist
7200    fn evaluate_2003(&self, _ctx: &EvaluationContext) -> ConditionResult {
7201        // TODO: implement
7202        ConditionResult::Unknown
7203    }
7204
7205    /// [2004] Segmentgruppe ist genau einmal für jede Zeitraum-ID aus dem DE1156 der SG6 RFF+Z49 (Verwendungszeitraum der Daten: "Gültige Daten") anzugeben
7206    // REVIEW: Collects Zeitraum-IDs from SG6 RFF+Z49 DE1156 (elements[0][2]) by correlating qualifier (elements[0][0]) and ID (elements[0][2]) vectors via shared SG6 instance index. Then collects all SEQ DE1050 (elements[1][0]) references from SG8 instances. For each Zeitraum-ID from SG6 RFF+Z49, counts matching SG8 SEQ references; returns False if any count != 1 (violates 'exactly once' cardinality). Returns Unknown if no RFF+Z49 Zeitraum-IDs exist. (medium confidence)
7207    fn evaluate_2004(&self, ctx: &EvaluationContext) -> ConditionResult {
7208        let rff_qualifiers = ctx.collect_group_values("RFF", 0, 0, &["SG4", "SG6"]);
7209        let rff_zeitraum_ids = ctx.collect_group_values("RFF", 0, 2, &["SG4", "SG6"]);
7210
7211        let zeitraum_ids: Vec<String> = rff_qualifiers
7212            .iter()
7213            .filter(|(_, qual)| qual.as_str() == "Z49")
7214            .filter_map(|(idx, _)| {
7215                rff_zeitraum_ids
7216                    .iter()
7217                    .find(|(i, v)| i == idx && !v.is_empty())
7218                    .map(|(_, v)| v.clone())
7219            })
7220            .collect();
7221
7222        if zeitraum_ids.is_empty() {
7223            return ConditionResult::Unknown;
7224        }
7225
7226        let seq_refs = ctx.collect_group_values("SEQ", 1, 0, &["SG4", "SG8"]);
7227
7228        for zid in &zeitraum_ids {
7229            let count = seq_refs.iter().filter(|(_, v)| v == zid).count();
7230            if count != 1 {
7231                return ConditionResult::False;
7232            }
7233        }
7234
7235        ConditionResult::True
7236    }
7237
7238    /// [2005] Segmentgruppe ist mindesten einmal für jede Zeitraum-ID aus dem DE1156 der SG6 RFF+Z49 (Verwendungszeitraum der Daten: "Gültige Daten") anzugeben
7239    // REVIEW: Same logic as 2004 but enforces 'at least once' cardinality (count >= 1) instead of 'exactly once'. Collects Zeitraum-IDs from SG6 RFF+Z49 DE1156 and checks that each has at least one matching SG8 SEQ DE1050 reference. Returns False if any Zeitraum-ID has zero matching SG8 references. (medium confidence)
7240    fn evaluate_2005(&self, ctx: &EvaluationContext) -> ConditionResult {
7241        let rff_qualifiers = ctx.collect_group_values("RFF", 0, 0, &["SG4", "SG6"]);
7242        let rff_zeitraum_ids = ctx.collect_group_values("RFF", 0, 2, &["SG4", "SG6"]);
7243
7244        let zeitraum_ids: Vec<String> = rff_qualifiers
7245            .iter()
7246            .filter(|(_, qual)| qual.as_str() == "Z49")
7247            .filter_map(|(idx, _)| {
7248                rff_zeitraum_ids
7249                    .iter()
7250                    .find(|(i, v)| i == idx && !v.is_empty())
7251                    .map(|(_, v)| v.clone())
7252            })
7253            .collect();
7254
7255        if zeitraum_ids.is_empty() {
7256            return ConditionResult::Unknown;
7257        }
7258
7259        let seq_refs = ctx.collect_group_values("SEQ", 1, 0, &["SG4", "SG8"]);
7260
7261        for zid in &zeitraum_ids {
7262            let count = seq_refs.iter().filter(|(_, v)| v == zid).count();
7263            if count == 0 {
7264                return ConditionResult::False;
7265            }
7266        }
7267
7268        ConditionResult::True
7269    }
7270
7271    /// [2010] Segmentgruppe ist genau einmal für jede SG8 SEQ+Z01 (Daten der Marktlokation) anzugeben, bei der die Bedingungen [266] ∧ [479] an der Segmentgruppe erfüllt ist. Dabei ist die selbe Zeitraum-ID ...
7272    fn evaluate_2010(&self, _ctx: &EvaluationContext) -> ConditionResult {
7273        // TODO: implement
7274        ConditionResult::Unknown
7275    }
7276
7277    /// [2012] Segmentgruppe ist genau einmal für die Angabe der Informativen Daten der Marktlokation anzugeben
7278    fn evaluate_2012(&self, _ctx: &EvaluationContext) -> ConditionResult {
7279        // TODO: implement
7280        ConditionResult::Unknown
7281    }
7282
7283    /// [2015] Einmal für jede ruhende Marktlokation, die der Marktlokation \"Kundenanlage\" aus dem SG5 LOC+Z16 (Marktlokation) untergeordnet ist
7284    fn evaluate_2015(&self, _ctx: &EvaluationContext) -> ConditionResult {
7285        // TODO: implement
7286        ConditionResult::Unknown
7287    }
7288
7289    /// [2017] Je SG5 LOC+Z17 (Messlokation) ist genau einmal die Segmentgruppe anzugeben
7290    fn evaluate_2017(&self, _ctx: &EvaluationContext) -> ConditionResult {
7291        // TODO: implement
7292        ConditionResult::Unknown
7293    }
7294
7295    /// [2018] Segmentgruppe ist genau einmal für jede SG8 SEQ+Z01 (Daten der Marktlokation) anzugeben, bei der die Bedingungen [266] an der Segmentgruppe erfüllt ist. Dabei ist die selbe Zeitraum-ID im nachfol...
7296    fn evaluate_2018(&self, _ctx: &EvaluationContext) -> ConditionResult {
7297        // TODO: implement
7298        ConditionResult::Unknown
7299    }
7300
7301    /// [2060] Wenn SG10 CAV+NZR ist die Segmentgruppe genau zwei Mal je IDE+24 anzugeben
7302    fn evaluate_2060(&self, _ctx: &EvaluationContext) -> ConditionResult {
7303        // TODO: implement
7304        ConditionResult::Unknown
7305    }
7306
7307    /// [2061] Segment bzw. Segmentgruppe ist genau einmal je SG4 IDE (Vorgang) anzugeben
7308    fn evaluate_2061(&self, _ctx: &EvaluationContext) -> ConditionResult {
7309        // TODO: implement
7310        ConditionResult::Unknown
7311    }
7312
7313    /// [2071] Für die ID der LieferantensummenZR einmal je SG4 IDE+24 (Vorgang)
7314    fn evaluate_2071(&self, _ctx: &EvaluationContext) -> ConditionResult {
7315        // TODO: implement
7316        ConditionResult::Unknown
7317    }
7318
7319    /// [2073] Für die ID der BilanzkreissummenZR einmal je SG4 IDE+24 (Vorgang)
7320    fn evaluate_2073(&self, _ctx: &EvaluationContext) -> ConditionResult {
7321        // TODO: implement
7322        ConditionResult::Unknown
7323    }
7324
7325    /// [2075] Für die ID der Zeitreihen (nicht bei EEG-EUZ und EUZ der AAÜZ) in der Clearingliste einmal je SG4 IDE+24 (Vorgang)
7326    fn evaluate_2075(&self, _ctx: &EvaluationContext) -> ConditionResult {
7327        // TODO: implement
7328        ConditionResult::Unknown
7329    }
7330
7331    /// [2080] Segmentgruppe ist max. zweimal je SG4 IDE+24 (Vorgang) anzugeben
7332    fn evaluate_2080(&self, _ctx: &EvaluationContext) -> ConditionResult {
7333        // TODO: implement
7334        ConditionResult::Unknown
7335    }
7336
7337    /// [2095] Je SG5 LOC+Z15 (MaBiS-Zählpunkt) ist genau einmal die Segmentgruppe anzugeben
7338    fn evaluate_2095(&self, _ctx: &EvaluationContext) -> ConditionResult {
7339        // TODO: implement
7340        ConditionResult::Unknown
7341    }
7342
7343    /// [2096] Segmentgruppe ist genau zweimal je SG4 IDE anzugeben
7344    fn evaluate_2096(&self, _ctx: &EvaluationContext) -> ConditionResult {
7345        // TODO: implement
7346        ConditionResult::Unknown
7347    }
7348
7349    /// [2119] Je SG8 SEQ+Z13/ ZG0 (Smartmeter-Gateway) ist genau einmal die Segmentgruppe anzugeben
7350    fn evaluate_2119(&self, _ctx: &EvaluationContext) -> ConditionResult {
7351        // TODO: implement
7352        ConditionResult::Unknown
7353    }
7354
7355    /// [2140] Für die ID der LieferantensummenZR einmal je SG4 IDE+Z01 (Liste)
7356    fn evaluate_2140(&self, _ctx: &EvaluationContext) -> ConditionResult {
7357        // TODO: implement
7358        ConditionResult::Unknown
7359    }
7360
7361    /// [2182] Segmentgruppe ist genau einmal je SG8 SEQ+Z01/ Z80/ Z81/ Z98 (Daten der Marktlokation/ Erwartete Daten der Marktlokation/ Im System vorhandene Daten der Marktlokation) anzugeben
7362    fn evaluate_2182(&self, _ctx: &EvaluationContext) -> ConditionResult {
7363        // TODO: implement
7364        ConditionResult::Unknown
7365    }
7366
7367    /// [2183] Segmentgruppe ist genau zweimal je SG8 SEQ+Z01/ Z80/ Z81/ Z98 (Daten der Marktlokation/ Erwartete Daten der Marktlokation/ Im System vorhandene Daten der Marktlokation) anzugeben
7368    fn evaluate_2183(&self, _ctx: &EvaluationContext) -> ConditionResult {
7369        // TODO: implement
7370        ConditionResult::Unknown
7371    }
7372
7373    /// [2207] Für die ID der Lieferanten-ausfall-arbeits-summen-zeitreihe einmal je SG4 IDE+Z01 (Liste)
7374    fn evaluate_2207(&self, _ctx: &EvaluationContext) -> ConditionResult {
7375        // TODO: implement
7376        ConditionResult::Unknown
7377    }
7378
7379    /// [2225] Einmal für jede Marktlokation bzw. Tranche für die der LF nicht die gemeldete Ansicht des NB teilt
7380    fn evaluate_2225(&self, _ctx: &EvaluationContext) -> ConditionResult {
7381        // TODO: implement
7382        ConditionResult::Unknown
7383    }
7384
7385    /// [2236] Code einmal je SG4 IDE+24 (Vorgang)
7386    fn evaluate_2236(&self, _ctx: &EvaluationContext) -> ConditionResult {
7387        // TODO: implement
7388        ConditionResult::Unknown
7389    }
7390
7391    /// [2252] Einmal für jede Marktlokation bzw. Tranche, die in der Lieferantenausfallarbeits-summenzeitreihe berücksichtigt wurde
7392    fn evaluate_2252(&self, _ctx: &EvaluationContext) -> ConditionResult {
7393        // TODO: implement
7394        ConditionResult::Unknown
7395    }
7396
7397    /// [2261] Für jede ID im SG5 LOC+Z21 (Tranche) DE3225, mindestens einmal anzugeben
7398    fn evaluate_2261(&self, _ctx: &EvaluationContext) -> ConditionResult {
7399        // TODO: implement
7400        ConditionResult::Unknown
7401    }
7402
7403    /// [2284] Für jede Messlokations-ID im SG5 LOC+Z17 (Messlokation) DE3225 genau einmal anzugeben
7404    fn evaluate_2284(&self, _ctx: &EvaluationContext) -> ConditionResult {
7405        // TODO: implement
7406        ConditionResult::Unknown
7407    }
7408
7409    /// [2286] Für jede SEQ+ZF3 (Daten der Messlokation) mindestens einmal anzugeben
7410    fn evaluate_2286(&self, _ctx: &EvaluationContext) -> ConditionResult {
7411        // TODO: implement
7412        ConditionResult::Unknown
7413    }
7414
7415    /// [2287] Für jede SEQ+Z03/ ZF5 (Zähleinrichtungsdaten) mindestens einmal anzugeben
7416    fn evaluate_2287(&self, _ctx: &EvaluationContext) -> ConditionResult {
7417        // TODO: implement
7418        ConditionResult::Unknown
7419    }
7420
7421    /// [2288] Einmal für jede Zeitreihe, die in der DZR berücksichtigt wurde
7422    fn evaluate_2288(&self, _ctx: &EvaluationContext) -> ConditionResult {
7423        // TODO: implement
7424        ConditionResult::Unknown
7425    }
7426
7427    /// [2307] Für jede ID im SG5 LOC+Z21 (Tranche) DE3225 genau einmal anzugeben
7428    fn evaluate_2307(&self, _ctx: &EvaluationContext) -> ConditionResult {
7429        // TODO: implement
7430        ConditionResult::Unknown
7431    }
7432
7433    /// [2308] Für jede ID im SG5 LOC+Z16 (Marktlokation) DE3225, mindestens einmal anzugeben
7434    fn evaluate_2308(&self, _ctx: &EvaluationContext) -> ConditionResult {
7435        // TODO: implement
7436        ConditionResult::Unknown
7437    }
7438
7439    /// [2309] Für jede ID im SG5 LOC+Z17 (Messlokation) DE3225 mindestens einmal anzugeben
7440    fn evaluate_2309(&self, _ctx: &EvaluationContext) -> ConditionResult {
7441        // TODO: implement
7442        ConditionResult::Unknown
7443    }
7444
7445    /// [2310] Für jede ID im SG5 LOC+Z16 (Marktlokation) DE3225 genau einmal anzugeben
7446    fn evaluate_2310(&self, _ctx: &EvaluationContext) -> ConditionResult {
7447        // TODO: implement
7448        ConditionResult::Unknown
7449    }
7450
7451    /// [2311] Für jede ID im SG5 LOC+Z21 (Tranche) DE3225, mindestens einmal anzugeben
7452    fn evaluate_2311(&self, _ctx: &EvaluationContext) -> ConditionResult {
7453        // TODO: implement
7454        ConditionResult::Unknown
7455    }
7456
7457    /// [2312] Wenn der Objektcode \"9992000001256\" (Netzlokation) im DE1154 des selben RFF+Z33 nicht vorhanden ist, ist das RFF+Z33 in derselben SG8 SEQ+Z58/ ZC9/ ZD0/ ZD6 (Zuordnung Lokation zum Objektcode des...
7458    fn evaluate_2312(&self, _ctx: &EvaluationContext) -> ConditionResult {
7459        // TODO: implement
7460        ConditionResult::Unknown
7461    }
7462
7463    /// [2313] Je SG8 SEQ+Z58/ ZC9/ ZD0/ ZD6 (Zuordnung Lokation zum Objektcode des Lokationsbündels) genau einmal anzugeben
7464    fn evaluate_2313(&self, _ctx: &EvaluationContext) -> ConditionResult {
7465        // TODO: implement
7466        ConditionResult::Unknown
7467    }
7468
7469    /// [2317] Wenn in derselben SG8 SEQ+Z04/ ZF7 (Wandlerdaten) das SG10 CCI+++Z25 (Wandler) CAV+MIW/MPW/MUW vorhanden, ist das Segment mindestens zweimal anzugeben
7470    fn evaluate_2317(&self, _ctx: &EvaluationContext) -> ConditionResult {
7471        // TODO: implement
7472        ConditionResult::Unknown
7473    }
7474
7475    /// [2318] Wenn in derselben SG8 SEQ+Z04/ ZF7 (Wandlerdaten) das SG10 CCI+++Z25 (Wandler) CAV+MBW (Blockstromwandler) vorhanden, ist das Segment genau einmal anzugeben
7476    fn evaluate_2318(&self, _ctx: &EvaluationContext) -> ConditionResult {
7477        // TODO: implement
7478        ConditionResult::Unknown
7479    }
7480
7481    /// [2344] Einmal für jede Marktlokation bzw. Tranche, die in der DZÜ / BG-CL / LF-SZR berücksichtigt wurde
7482    fn evaluate_2344(&self, _ctx: &EvaluationContext) -> ConditionResult {
7483        // TODO: implement
7484        ConditionResult::Unknown
7485    }
7486
7487    /// [2350] Für jedes SMGW das im SEQ+Z13/ ZG0 (Smartmeter-Gateway) SG10 CCI+++Z75 CAV+Z30 (Gerätenummer) genannt ist, mindestens einmal je SEQ+Z03/ ZF5 (Zähleinrichtungsdaten) das mit SG8 RFF+Z14 (Referenz...
7488    fn evaluate_2350(&self, _ctx: &EvaluationContext) -> ConditionResult {
7489        // TODO: implement
7490        ConditionResult::Unknown
7491    }
7492
7493    /// [2351] Einmal je ZP einer BK-SZR, in der die Marktlokation in die Berechnung der abgerechneten Summenzeitreihe aufgenommen wurde
7494    fn evaluate_2351(&self, _ctx: &EvaluationContext) -> ConditionResult {
7495        // TODO: implement
7496        ConditionResult::Unknown
7497    }
7498
7499    /// [2352] Einmal je ZP einer BG-SZR, in der die Marktlokation in die Berechnung der abgerechneten Summenzeitreihe aufge-nommen wurde
7500    fn evaluate_2352(&self, _ctx: &EvaluationContext) -> ConditionResult {
7501        // TODO: implement
7502        ConditionResult::Unknown
7503    }
7504
7505    /// [2356] Je SG5 LOC+Z18 (Netzlokation) ist genau einmal die Segmentgruppe anzugeben
7506    fn evaluate_2356(&self, _ctx: &EvaluationContext) -> ConditionResult {
7507        // TODO: implement
7508        ConditionResult::Unknown
7509    }
7510
7511    /// [2357] Je SG5 LOC+Z20 (Technische Ressource) ist genau einmal die Segmentgruppe anzugeben
7512    fn evaluate_2357(&self, _ctx: &EvaluationContext) -> ConditionResult {
7513        // TODO: implement
7514        ConditionResult::Unknown
7515    }
7516
7517    /// [2358] Je SG5 LOC+Z19 (Steuerbare Ressource) ist genau einmal die Segmentgruppe anzugeben
7518    fn evaluate_2358(&self, _ctx: &EvaluationContext) -> ConditionResult {
7519        // TODO: implement
7520        ConditionResult::Unknown
7521    }
7522
7523    /// [2359] Für jede ID im SG5 LOC+Z16 / Z17 / Z20 (Marktlokation / Messlokation / Technische Ressource) DE3225 mindestens einmal anzugeben
7524    fn evaluate_2359(&self, _ctx: &EvaluationContext) -> ConditionResult {
7525        // TODO: implement
7526        ConditionResult::Unknown
7527    }
7528
7529    /// [2360] Für jede ID im SG5 LOC+Z18 (Netzlokation) DE3225 mindestens einmal anzugeben
7530    fn evaluate_2360(&self, _ctx: &EvaluationContext) -> ConditionResult {
7531        // TODO: implement
7532        ConditionResult::Unknown
7533    }
7534
7535    /// [2361] Für jede ID im SG5 LOC+Z17 / Z20 / Z22 (Messlokation / Technische Ressource / ruhende Marktlokation) DE3225 mindestens einmal anzugeben
7536    fn evaluate_2361(&self, _ctx: &EvaluationContext) -> ConditionResult {
7537        // TODO: implement
7538        ConditionResult::Unknown
7539    }
7540}