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(10);
28        external_conditions.insert(14);
29        external_conditions.insert(31);
30        external_conditions.insert(33);
31        external_conditions.insert(36);
32        external_conditions.insert(37);
33        external_conditions.insert(38);
34        external_conditions.insert(39);
35        external_conditions.insert(40);
36        external_conditions.insert(75);
37        external_conditions.insert(98);
38        external_conditions.insert(99);
39        external_conditions.insert(151);
40        external_conditions.insert(233);
41        external_conditions.insert(241);
42        external_conditions.insert(251);
43        external_conditions.insert(292);
44        external_conditions.insert(314);
45        external_conditions.insert(315);
46        external_conditions.insert(323);
47        external_conditions.insert(326);
48        external_conditions.insert(328);
49        external_conditions.insert(412);
50        external_conditions.insert(425);
51        external_conditions.insert(426);
52        external_conditions.insert(427);
53        external_conditions.insert(428);
54        external_conditions.insert(429);
55        external_conditions.insert(433);
56        external_conditions.insert(435);
57        external_conditions.insert(453);
58        external_conditions.insert(459);
59        external_conditions.insert(460);
60        external_conditions.insert(706);
61        external_conditions.insert(717);
62        Self {
63            external_conditions,
64        }
65    }
66}
67
68impl ConditionEvaluator for UtilmdStromConditionEvaluatorFV2510 {
69    fn message_type(&self) -> &str {
70        "UTILMD_Strom"
71    }
72
73    fn format_version(&self) -> &str {
74        "FV2510"
75    }
76
77    fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
78        match condition {
79            1 => self.evaluate_1(ctx),
80            2 => self.evaluate_2(ctx),
81            3 => self.evaluate_3(ctx),
82            4 => self.evaluate_4(ctx),
83            5 => self.evaluate_5(ctx),
84            6 => self.evaluate_6(ctx),
85            7 => self.evaluate_7(ctx),
86            8 => self.evaluate_8(ctx),
87            9 => self.evaluate_9(ctx),
88            10 => self.evaluate_10(ctx),
89            11 => self.evaluate_11(ctx),
90            12 => self.evaluate_12(ctx),
91            13 => self.evaluate_13(ctx),
92            14 => self.evaluate_14(ctx),
93            15 => self.evaluate_15(ctx),
94            16 => self.evaluate_16(ctx),
95            17 => self.evaluate_17(ctx),
96            18 => self.evaluate_18(ctx),
97            19 => self.evaluate_19(ctx),
98            20 => self.evaluate_20(ctx),
99            21 => self.evaluate_21(ctx),
100            22 => self.evaluate_22(ctx),
101            23 => self.evaluate_23(ctx),
102            24 => self.evaluate_24(ctx),
103            25 => self.evaluate_25(ctx),
104            27 => self.evaluate_27(ctx),
105            28 => self.evaluate_28(ctx),
106            29 => self.evaluate_29(ctx),
107            30 => self.evaluate_30(ctx),
108            31 => self.evaluate_31(ctx),
109            32 => self.evaluate_32(ctx),
110            33 => self.evaluate_33(ctx),
111            34 => self.evaluate_34(ctx),
112            35 => self.evaluate_35(ctx),
113            36 => self.evaluate_36(ctx),
114            37 => self.evaluate_37(ctx),
115            38 => self.evaluate_38(ctx),
116            39 => self.evaluate_39(ctx),
117            40 => self.evaluate_40(ctx),
118            41 => self.evaluate_41(ctx),
119            42 => self.evaluate_42(ctx),
120            43 => self.evaluate_43(ctx),
121            44 => self.evaluate_44(ctx),
122            45 => self.evaluate_45(ctx),
123            46 => self.evaluate_46(ctx),
124            47 => self.evaluate_47(ctx),
125            48 => self.evaluate_48(ctx),
126            49 => self.evaluate_49(ctx),
127            50 => self.evaluate_50(ctx),
128            51 => self.evaluate_51(ctx),
129            52 => self.evaluate_52(ctx),
130            53 => self.evaluate_53(ctx),
131            54 => self.evaluate_54(ctx),
132            55 => self.evaluate_55(ctx),
133            56 => self.evaluate_56(ctx),
134            57 => self.evaluate_57(ctx),
135            58 => self.evaluate_58(ctx),
136            60 => self.evaluate_60(ctx),
137            61 => self.evaluate_61(ctx),
138            62 => self.evaluate_62(ctx),
139            63 => self.evaluate_63(ctx),
140            64 => self.evaluate_64(ctx),
141            65 => self.evaluate_65(ctx),
142            66 => self.evaluate_66(ctx),
143            67 => self.evaluate_67(ctx),
144            68 => self.evaluate_68(ctx),
145            69 => self.evaluate_69(ctx),
146            70 => self.evaluate_70(ctx),
147            71 => self.evaluate_71(ctx),
148            72 => self.evaluate_72(ctx),
149            73 => self.evaluate_73(ctx),
150            74 => self.evaluate_74(ctx),
151            75 => self.evaluate_75(ctx),
152            76 => self.evaluate_76(ctx),
153            77 => self.evaluate_77(ctx),
154            78 => self.evaluate_78(ctx),
155            79 => self.evaluate_79(ctx),
156            83 => self.evaluate_83(ctx),
157            84 => self.evaluate_84(ctx),
158            85 => self.evaluate_85(ctx),
159            86 => self.evaluate_86(ctx),
160            87 => self.evaluate_87(ctx),
161            88 => self.evaluate_88(ctx),
162            89 => self.evaluate_89(ctx),
163            90 => self.evaluate_90(ctx),
164            91 => self.evaluate_91(ctx),
165            92 => self.evaluate_92(ctx),
166            93 => self.evaluate_93(ctx),
167            94 => self.evaluate_94(ctx),
168            95 => self.evaluate_95(ctx),
169            96 => self.evaluate_96(ctx),
170            97 => self.evaluate_97(ctx),
171            98 => self.evaluate_98(ctx),
172            99 => self.evaluate_99(ctx),
173            100 => self.evaluate_100(ctx),
174            101 => self.evaluate_101(ctx),
175            102 => self.evaluate_102(ctx),
176            103 => self.evaluate_103(ctx),
177            104 => self.evaluate_104(ctx),
178            105 => self.evaluate_105(ctx),
179            106 => self.evaluate_106(ctx),
180            107 => self.evaluate_107(ctx),
181            108 => self.evaluate_108(ctx),
182            110 => self.evaluate_110(ctx),
183            111 => self.evaluate_111(ctx),
184            112 => self.evaluate_112(ctx),
185            113 => self.evaluate_113(ctx),
186            114 => self.evaluate_114(ctx),
187            115 => self.evaluate_115(ctx),
188            116 => self.evaluate_116(ctx),
189            117 => self.evaluate_117(ctx),
190            118 => self.evaluate_118(ctx),
191            119 => self.evaluate_119(ctx),
192            120 => self.evaluate_120(ctx),
193            121 => self.evaluate_121(ctx),
194            122 => self.evaluate_122(ctx),
195            123 => self.evaluate_123(ctx),
196            124 => self.evaluate_124(ctx),
197            125 => self.evaluate_125(ctx),
198            126 => self.evaluate_126(ctx),
199            127 => self.evaluate_127(ctx),
200            128 => self.evaluate_128(ctx),
201            129 => self.evaluate_129(ctx),
202            130 => self.evaluate_130(ctx),
203            131 => self.evaluate_131(ctx),
204            132 => self.evaluate_132(ctx),
205            133 => self.evaluate_133(ctx),
206            134 => self.evaluate_134(ctx),
207            135 => self.evaluate_135(ctx),
208            136 => self.evaluate_136(ctx),
209            137 => self.evaluate_137(ctx),
210            138 => self.evaluate_138(ctx),
211            139 => self.evaluate_139(ctx),
212            140 => self.evaluate_140(ctx),
213            141 => self.evaluate_141(ctx),
214            142 => self.evaluate_142(ctx),
215            143 => self.evaluate_143(ctx),
216            144 => self.evaluate_144(ctx),
217            145 => self.evaluate_145(ctx),
218            146 => self.evaluate_146(ctx),
219            147 => self.evaluate_147(ctx),
220            148 => self.evaluate_148(ctx),
221            149 => self.evaluate_149(ctx),
222            150 => self.evaluate_150(ctx),
223            151 => self.evaluate_151(ctx),
224            152 => self.evaluate_152(ctx),
225            153 => self.evaluate_153(ctx),
226            156 => self.evaluate_156(ctx),
227            157 => self.evaluate_157(ctx),
228            161 => self.evaluate_161(ctx),
229            162 => self.evaluate_162(ctx),
230            163 => self.evaluate_163(ctx),
231            164 => self.evaluate_164(ctx),
232            165 => self.evaluate_165(ctx),
233            166 => self.evaluate_166(ctx),
234            167 => self.evaluate_167(ctx),
235            168 => self.evaluate_168(ctx),
236            169 => self.evaluate_169(ctx),
237            170 => self.evaluate_170(ctx),
238            172 => self.evaluate_172(ctx),
239            173 => self.evaluate_173(ctx),
240            174 => self.evaluate_174(ctx),
241            175 => self.evaluate_175(ctx),
242            176 => self.evaluate_176(ctx),
243            177 => self.evaluate_177(ctx),
244            178 => self.evaluate_178(ctx),
245            179 => self.evaluate_179(ctx),
246            180 => self.evaluate_180(ctx),
247            184 => self.evaluate_184(ctx),
248            190 => self.evaluate_190(ctx),
249            191 => self.evaluate_191(ctx),
250            192 => self.evaluate_192(ctx),
251            193 => self.evaluate_193(ctx),
252            194 => self.evaluate_194(ctx),
253            195 => self.evaluate_195(ctx),
254            196 => self.evaluate_196(ctx),
255            197 => self.evaluate_197(ctx),
256            198 => self.evaluate_198(ctx),
257            199 => self.evaluate_199(ctx),
258            201 => self.evaluate_201(ctx),
259            202 => self.evaluate_202(ctx),
260            203 => self.evaluate_203(ctx),
261            204 => self.evaluate_204(ctx),
262            205 => self.evaluate_205(ctx),
263            206 => self.evaluate_206(ctx),
264            209 => self.evaluate_209(ctx),
265            210 => self.evaluate_210(ctx),
266            212 => self.evaluate_212(ctx),
267            213 => self.evaluate_213(ctx),
268            215 => self.evaluate_215(ctx),
269            216 => self.evaluate_216(ctx),
270            217 => self.evaluate_217(ctx),
271            219 => self.evaluate_219(ctx),
272            220 => self.evaluate_220(ctx),
273            221 => self.evaluate_221(ctx),
274            223 => self.evaluate_223(ctx),
275            224 => self.evaluate_224(ctx),
276            227 => self.evaluate_227(ctx),
277            229 => self.evaluate_229(ctx),
278            232 => self.evaluate_232(ctx),
279            233 => self.evaluate_233(ctx),
280            234 => self.evaluate_234(ctx),
281            237 => self.evaluate_237(ctx),
282            238 => self.evaluate_238(ctx),
283            239 => self.evaluate_239(ctx),
284            240 => self.evaluate_240(ctx),
285            241 => self.evaluate_241(ctx),
286            242 => self.evaluate_242(ctx),
287            243 => self.evaluate_243(ctx),
288            244 => self.evaluate_244(ctx),
289            248 => self.evaluate_248(ctx),
290            249 => self.evaluate_249(ctx),
291            251 => self.evaluate_251(ctx),
292            252 => self.evaluate_252(ctx),
293            253 => self.evaluate_253(ctx),
294            254 => self.evaluate_254(ctx),
295            255 => self.evaluate_255(ctx),
296            256 => self.evaluate_256(ctx),
297            257 => self.evaluate_257(ctx),
298            258 => self.evaluate_258(ctx),
299            259 => self.evaluate_259(ctx),
300            261 => self.evaluate_261(ctx),
301            262 => self.evaluate_262(ctx),
302            265 => self.evaluate_265(ctx),
303            266 => self.evaluate_266(ctx),
304            267 => self.evaluate_267(ctx),
305            268 => self.evaluate_268(ctx),
306            269 => self.evaluate_269(ctx),
307            270 => self.evaluate_270(ctx),
308            273 => self.evaluate_273(ctx),
309            279 => self.evaluate_279(ctx),
310            280 => self.evaluate_280(ctx),
311            282 => self.evaluate_282(ctx),
312            284 => self.evaluate_284(ctx),
313            285 => self.evaluate_285(ctx),
314            286 => self.evaluate_286(ctx),
315            287 => self.evaluate_287(ctx),
316            288 => self.evaluate_288(ctx),
317            291 => self.evaluate_291(ctx),
318            292 => self.evaluate_292(ctx),
319            293 => self.evaluate_293(ctx),
320            294 => self.evaluate_294(ctx),
321            295 => self.evaluate_295(ctx),
322            296 => self.evaluate_296(ctx),
323            297 => self.evaluate_297(ctx),
324            298 => self.evaluate_298(ctx),
325            300 => self.evaluate_300(ctx),
326            301 => self.evaluate_301(ctx),
327            302 => self.evaluate_302(ctx),
328            303 => self.evaluate_303(ctx),
329            304 => self.evaluate_304(ctx),
330            305 => self.evaluate_305(ctx),
331            306 => self.evaluate_306(ctx),
332            307 => self.evaluate_307(ctx),
333            309 => self.evaluate_309(ctx),
334            312 => self.evaluate_312(ctx),
335            313 => self.evaluate_313(ctx),
336            314 => self.evaluate_314(ctx),
337            315 => self.evaluate_315(ctx),
338            316 => self.evaluate_316(ctx),
339            317 => self.evaluate_317(ctx),
340            318 => self.evaluate_318(ctx),
341            321 => self.evaluate_321(ctx),
342            322 => self.evaluate_322(ctx),
343            323 => self.evaluate_323(ctx),
344            326 => self.evaluate_326(ctx),
345            327 => self.evaluate_327(ctx),
346            328 => self.evaluate_328(ctx),
347            329 => self.evaluate_329(ctx),
348            332 => self.evaluate_332(ctx),
349            333 => self.evaluate_333(ctx),
350            334 => self.evaluate_334(ctx),
351            335 => self.evaluate_335(ctx),
352            336 => self.evaluate_336(ctx),
353            337 => self.evaluate_337(ctx),
354            338 => self.evaluate_338(ctx),
355            339 => self.evaluate_339(ctx),
356            340 => self.evaluate_340(ctx),
357            341 => self.evaluate_341(ctx),
358            342 => self.evaluate_342(ctx),
359            344 => self.evaluate_344(ctx),
360            345 => self.evaluate_345(ctx),
361            346 => self.evaluate_346(ctx),
362            347 => self.evaluate_347(ctx),
363            348 => self.evaluate_348(ctx),
364            349 => self.evaluate_349(ctx),
365            350 => self.evaluate_350(ctx),
366            351 => self.evaluate_351(ctx),
367            352 => self.evaluate_352(ctx),
368            355 => self.evaluate_355(ctx),
369            356 => self.evaluate_356(ctx),
370            357 => self.evaluate_357(ctx),
371            358 => self.evaluate_358(ctx),
372            359 => self.evaluate_359(ctx),
373            360 => self.evaluate_360(ctx),
374            363 => self.evaluate_363(ctx),
375            365 => self.evaluate_365(ctx),
376            366 => self.evaluate_366(ctx),
377            367 => self.evaluate_367(ctx),
378            368 => self.evaluate_368(ctx),
379            370 => self.evaluate_370(ctx),
380            371 => self.evaluate_371(ctx),
381            372 => self.evaluate_372(ctx),
382            373 => self.evaluate_373(ctx),
383            375 => self.evaluate_375(ctx),
384            376 => self.evaluate_376(ctx),
385            377 => self.evaluate_377(ctx),
386            378 => self.evaluate_378(ctx),
387            379 => self.evaluate_379(ctx),
388            380 => self.evaluate_380(ctx),
389            384 => self.evaluate_384(ctx),
390            386 => self.evaluate_386(ctx),
391            387 => self.evaluate_387(ctx),
392            388 => self.evaluate_388(ctx),
393            391 => self.evaluate_391(ctx),
394            392 => self.evaluate_392(ctx),
395            393 => self.evaluate_393(ctx),
396            394 => self.evaluate_394(ctx),
397            395 => self.evaluate_395(ctx),
398            396 => self.evaluate_396(ctx),
399            397 => self.evaluate_397(ctx),
400            398 => self.evaluate_398(ctx),
401            399 => self.evaluate_399(ctx),
402            401 => self.evaluate_401(ctx),
403            402 => self.evaluate_402(ctx),
404            403 => self.evaluate_403(ctx),
405            404 => self.evaluate_404(ctx),
406            405 => self.evaluate_405(ctx),
407            406 => self.evaluate_406(ctx),
408            407 => self.evaluate_407(ctx),
409            408 => self.evaluate_408(ctx),
410            409 => self.evaluate_409(ctx),
411            410 => self.evaluate_410(ctx),
412            411 => self.evaluate_411(ctx),
413            412 => self.evaluate_412(ctx),
414            413 => self.evaluate_413(ctx),
415            414 => self.evaluate_414(ctx),
416            415 => self.evaluate_415(ctx),
417            416 => self.evaluate_416(ctx),
418            417 => self.evaluate_417(ctx),
419            419 => self.evaluate_419(ctx),
420            420 => self.evaluate_420(ctx),
421            421 => self.evaluate_421(ctx),
422            425 => self.evaluate_425(ctx),
423            426 => self.evaluate_426(ctx),
424            427 => self.evaluate_427(ctx),
425            428 => self.evaluate_428(ctx),
426            429 => self.evaluate_429(ctx),
427            430 => self.evaluate_430(ctx),
428            431 => self.evaluate_431(ctx),
429            432 => self.evaluate_432(ctx),
430            433 => self.evaluate_433(ctx),
431            435 => self.evaluate_435(ctx),
432            436 => self.evaluate_436(ctx),
433            437 => self.evaluate_437(ctx),
434            438 => self.evaluate_438(ctx),
435            440 => self.evaluate_440(ctx),
436            441 => self.evaluate_441(ctx),
437            442 => self.evaluate_442(ctx),
438            444 => self.evaluate_444(ctx),
439            445 => self.evaluate_445(ctx),
440            446 => self.evaluate_446(ctx),
441            447 => self.evaluate_447(ctx),
442            448 => self.evaluate_448(ctx),
443            449 => self.evaluate_449(ctx),
444            450 => self.evaluate_450(ctx),
445            451 => self.evaluate_451(ctx),
446            452 => self.evaluate_452(ctx),
447            453 => self.evaluate_453(ctx),
448            454 => self.evaluate_454(ctx),
449            455 => self.evaluate_455(ctx),
450            456 => self.evaluate_456(ctx),
451            457 => self.evaluate_457(ctx),
452            458 => self.evaluate_458(ctx),
453            459 => self.evaluate_459(ctx),
454            460 => self.evaluate_460(ctx),
455            461 => self.evaluate_461(ctx),
456            462 => self.evaluate_462(ctx),
457            463 => self.evaluate_463(ctx),
458            465 => self.evaluate_465(ctx),
459            466 => self.evaluate_466(ctx),
460            467 => self.evaluate_467(ctx),
461            468 => self.evaluate_468(ctx),
462            469 => self.evaluate_469(ctx),
463            470 => self.evaluate_470(ctx),
464            471 => self.evaluate_471(ctx),
465            472 => self.evaluate_472(ctx),
466            473 => self.evaluate_473(ctx),
467            474 => self.evaluate_474(ctx),
468            475 => self.evaluate_475(ctx),
469            476 => self.evaluate_476(ctx),
470            477 => self.evaluate_477(ctx),
471            478 => self.evaluate_478(ctx),
472            479 => self.evaluate_479(ctx),
473            480 => self.evaluate_480(ctx),
474            481 => self.evaluate_481(ctx),
475            483 => self.evaluate_483(ctx),
476            484 => self.evaluate_484(ctx),
477            487 => self.evaluate_487(ctx),
478            489 => self.evaluate_489(ctx),
479            490 => self.evaluate_490(ctx),
480            491 => self.evaluate_491(ctx),
481            494 => self.evaluate_494(ctx),
482            500 => self.evaluate_500(ctx),
483            501 => self.evaluate_501(ctx),
484            502 => self.evaluate_502(ctx),
485            503 => self.evaluate_503(ctx),
486            504 => self.evaluate_504(ctx),
487            505 => self.evaluate_505(ctx),
488            506 => self.evaluate_506(ctx),
489            507 => self.evaluate_507(ctx),
490            508 => self.evaluate_508(ctx),
491            509 => self.evaluate_509(ctx),
492            510 => self.evaluate_510(ctx),
493            511 => self.evaluate_511(ctx),
494            512 => self.evaluate_512(ctx),
495            513 => self.evaluate_513(ctx),
496            514 => self.evaluate_514(ctx),
497            515 => self.evaluate_515(ctx),
498            516 => self.evaluate_516(ctx),
499            517 => self.evaluate_517(ctx),
500            518 => self.evaluate_518(ctx),
501            519 => self.evaluate_519(ctx),
502            520 => self.evaluate_520(ctx),
503            521 => self.evaluate_521(ctx),
504            522 => self.evaluate_522(ctx),
505            523 => self.evaluate_523(ctx),
506            524 => self.evaluate_524(ctx),
507            525 => self.evaluate_525(ctx),
508            526 => self.evaluate_526(ctx),
509            527 => self.evaluate_527(ctx),
510            528 => self.evaluate_528(ctx),
511            529 => self.evaluate_529(ctx),
512            530 => self.evaluate_530(ctx),
513            531 => self.evaluate_531(ctx),
514            532 => self.evaluate_532(ctx),
515            533 => self.evaluate_533(ctx),
516            534 => self.evaluate_534(ctx),
517            555 => self.evaluate_555(ctx),
518            556 => self.evaluate_556(ctx),
519            557 => self.evaluate_557(ctx),
520            558 => self.evaluate_558(ctx),
521            559 => self.evaluate_559(ctx),
522            560 => self.evaluate_560(ctx),
523            561 => self.evaluate_561(ctx),
524            562 => self.evaluate_562(ctx),
525            563 => self.evaluate_563(ctx),
526            564 => self.evaluate_564(ctx),
527            565 => self.evaluate_565(ctx),
528            566 => self.evaluate_566(ctx),
529            567 => self.evaluate_567(ctx),
530            568 => self.evaluate_568(ctx),
531            569 => self.evaluate_569(ctx),
532            570 => self.evaluate_570(ctx),
533            572 => self.evaluate_572(ctx),
534            576 => self.evaluate_576(ctx),
535            577 => self.evaluate_577(ctx),
536            578 => self.evaluate_578(ctx),
537            579 => self.evaluate_579(ctx),
538            580 => self.evaluate_580(ctx),
539            581 => self.evaluate_581(ctx),
540            586 => self.evaluate_586(ctx),
541            590 => self.evaluate_590(ctx),
542            594 => self.evaluate_594(ctx),
543            599 => self.evaluate_599(ctx),
544            601 => self.evaluate_601(ctx),
545            606 => self.evaluate_606(ctx),
546            609 => self.evaluate_609(ctx),
547            611 => self.evaluate_611(ctx),
548            614 => self.evaluate_614(ctx),
549            617 => self.evaluate_617(ctx),
550            618 => self.evaluate_618(ctx),
551            619 => self.evaluate_619(ctx),
552            621 => self.evaluate_621(ctx),
553            622 => self.evaluate_622(ctx),
554            623 => self.evaluate_623(ctx),
555            630 => self.evaluate_630(ctx),
556            631 => self.evaluate_631(ctx),
557            632 => self.evaluate_632(ctx),
558            637 => self.evaluate_637(ctx),
559            638 => self.evaluate_638(ctx),
560            639 => self.evaluate_639(ctx),
561            640 => self.evaluate_640(ctx),
562            641 => self.evaluate_641(ctx),
563            642 => self.evaluate_642(ctx),
564            643 => self.evaluate_643(ctx),
565            645 => self.evaluate_645(ctx),
566            646 => self.evaluate_646(ctx),
567            647 => self.evaluate_647(ctx),
568            648 => self.evaluate_648(ctx),
569            651 => self.evaluate_651(ctx),
570            653 => self.evaluate_653(ctx),
571            655 => self.evaluate_655(ctx),
572            659 => self.evaluate_659(ctx),
573            660 => self.evaluate_660(ctx),
574            662 => self.evaluate_662(ctx),
575            663 => self.evaluate_663(ctx),
576            664 => self.evaluate_664(ctx),
577            665 => self.evaluate_665(ctx),
578            667 => self.evaluate_667(ctx),
579            668 => self.evaluate_668(ctx),
580            670 => self.evaluate_670(ctx),
581            671 => self.evaluate_671(ctx),
582            672 => self.evaluate_672(ctx),
583            673 => self.evaluate_673(ctx),
584            674 => self.evaluate_674(ctx),
585            675 => self.evaluate_675(ctx),
586            677 => self.evaluate_677(ctx),
587            678 => self.evaluate_678(ctx),
588            679 => self.evaluate_679(ctx),
589            680 => self.evaluate_680(ctx),
590            681 => self.evaluate_681(ctx),
591            682 => self.evaluate_682(ctx),
592            683 => self.evaluate_683(ctx),
593            684 => self.evaluate_684(ctx),
594            685 => self.evaluate_685(ctx),
595            686 => self.evaluate_686(ctx),
596            687 => self.evaluate_687(ctx),
597            688 => self.evaluate_688(ctx),
598            689 => self.evaluate_689(ctx),
599            690 => self.evaluate_690(ctx),
600            693 => self.evaluate_693(ctx),
601            694 => self.evaluate_694(ctx),
602            695 => self.evaluate_695(ctx),
603            696 => self.evaluate_696(ctx),
604            698 => self.evaluate_698(ctx),
605            699 => self.evaluate_699(ctx),
606            700 => self.evaluate_700(ctx),
607            704 => self.evaluate_704(ctx),
608            705 => self.evaluate_705(ctx),
609            706 => self.evaluate_706(ctx),
610            707 => self.evaluate_707(ctx),
611            708 => self.evaluate_708(ctx),
612            709 => self.evaluate_709(ctx),
613            710 => self.evaluate_710(ctx),
614            711 => self.evaluate_711(ctx),
615            712 => self.evaluate_712(ctx),
616            713 => self.evaluate_713(ctx),
617            714 => self.evaluate_714(ctx),
618            715 => self.evaluate_715(ctx),
619            716 => self.evaluate_716(ctx),
620            717 => self.evaluate_717(ctx),
621            718 => self.evaluate_718(ctx),
622            719 => self.evaluate_719(ctx),
623            902 => self.evaluate_902(ctx),
624            910 => self.evaluate_910(ctx),
625            914 => self.evaluate_914(ctx),
626            922 => self.evaluate_922(ctx),
627            926 => self.evaluate_926(ctx),
628            930 => self.evaluate_930(ctx),
629            931 => self.evaluate_931(ctx),
630            932 => self.evaluate_932(ctx),
631            933 => self.evaluate_933(ctx),
632            937 => self.evaluate_937(ctx),
633            938 => self.evaluate_938(ctx),
634            939 => self.evaluate_939(ctx),
635            940 => self.evaluate_940(ctx),
636            942 => self.evaluate_942(ctx),
637            943 => self.evaluate_943(ctx),
638            946 => self.evaluate_946(ctx),
639            948 => self.evaluate_948(ctx),
640            950 => self.evaluate_950(ctx),
641            951 => self.evaluate_951(ctx),
642            952 => self.evaluate_952(ctx),
643            955 => self.evaluate_955(ctx),
644            957 => self.evaluate_957(ctx),
645            960 => self.evaluate_960(ctx),
646            961 => self.evaluate_961(ctx),
647            967 => self.evaluate_967(ctx),
648            2000 => self.evaluate_2000(ctx),
649            2001 => self.evaluate_2001(ctx),
650            2002 => self.evaluate_2002(ctx),
651            2003 => self.evaluate_2003(ctx),
652            2004 => self.evaluate_2004(ctx),
653            2005 => self.evaluate_2005(ctx),
654            2006 => self.evaluate_2006(ctx),
655            2007 => self.evaluate_2007(ctx),
656            2008 => self.evaluate_2008(ctx),
657            2009 => self.evaluate_2009(ctx),
658            2010 => self.evaluate_2010(ctx),
659            2011 => self.evaluate_2011(ctx),
660            2012 => self.evaluate_2012(ctx),
661            2013 => self.evaluate_2013(ctx),
662            2014 => self.evaluate_2014(ctx),
663            2015 => self.evaluate_2015(ctx),
664            2016 => self.evaluate_2016(ctx),
665            2017 => self.evaluate_2017(ctx),
666            2018 => self.evaluate_2018(ctx),
667            2060 => self.evaluate_2060(ctx),
668            2061 => self.evaluate_2061(ctx),
669            2071 => self.evaluate_2071(ctx),
670            2073 => self.evaluate_2073(ctx),
671            2075 => self.evaluate_2075(ctx),
672            2080 => self.evaluate_2080(ctx),
673            2095 => self.evaluate_2095(ctx),
674            2096 => self.evaluate_2096(ctx),
675            2119 => self.evaluate_2119(ctx),
676            2121 => self.evaluate_2121(ctx),
677            2140 => self.evaluate_2140(ctx),
678            2182 => self.evaluate_2182(ctx),
679            2183 => self.evaluate_2183(ctx),
680            2207 => self.evaluate_2207(ctx),
681            2225 => self.evaluate_2225(ctx),
682            2236 => self.evaluate_2236(ctx),
683            2252 => self.evaluate_2252(ctx),
684            2261 => self.evaluate_2261(ctx),
685            2284 => self.evaluate_2284(ctx),
686            2286 => self.evaluate_2286(ctx),
687            2287 => self.evaluate_2287(ctx),
688            2288 => self.evaluate_2288(ctx),
689            2307 => self.evaluate_2307(ctx),
690            2308 => self.evaluate_2308(ctx),
691            2309 => self.evaluate_2309(ctx),
692            2310 => self.evaluate_2310(ctx),
693            2311 => self.evaluate_2311(ctx),
694            2312 => self.evaluate_2312(ctx),
695            2313 => self.evaluate_2313(ctx),
696            2317 => self.evaluate_2317(ctx),
697            2318 => self.evaluate_2318(ctx),
698            2344 => self.evaluate_2344(ctx),
699            2350 => self.evaluate_2350(ctx),
700            2351 => self.evaluate_2351(ctx),
701            2352 => self.evaluate_2352(ctx),
702            2356 => self.evaluate_2356(ctx),
703            2357 => self.evaluate_2357(ctx),
704            2358 => self.evaluate_2358(ctx),
705            2359 => self.evaluate_2359(ctx),
706            2360 => self.evaluate_2360(ctx),
707            2361 => self.evaluate_2361(ctx),
708            _ => ConditionResult::Unknown,
709        }
710    }
711
712    fn is_external(&self, condition: u32) -> bool {
713        self.external_conditions.contains(&condition)
714    }
715    fn is_known(&self, condition: u32) -> bool {
716        matches!(
717            condition,
718            1 | 2
719                | 3
720                | 4
721                | 5
722                | 6
723                | 7
724                | 8
725                | 9
726                | 10
727                | 11
728                | 12
729                | 13
730                | 14
731                | 15
732                | 16
733                | 17
734                | 18
735                | 19
736                | 20
737                | 21
738                | 22
739                | 23
740                | 24
741                | 25
742                | 27
743                | 28
744                | 29
745                | 30
746                | 31
747                | 32
748                | 33
749                | 34
750                | 35
751                | 36
752                | 37
753                | 38
754                | 39
755                | 40
756                | 41
757                | 42
758                | 43
759                | 44
760                | 45
761                | 46
762                | 47
763                | 48
764                | 49
765                | 50
766                | 51
767                | 52
768                | 53
769                | 54
770                | 55
771                | 56
772                | 57
773                | 58
774                | 60
775                | 61
776                | 62
777                | 63
778                | 64
779                | 65
780                | 66
781                | 67
782                | 68
783                | 69
784                | 70
785                | 71
786                | 72
787                | 73
788                | 74
789                | 75
790                | 76
791                | 77
792                | 78
793                | 79
794                | 83
795                | 84
796                | 85
797                | 86
798                | 87
799                | 88
800                | 89
801                | 90
802                | 91
803                | 92
804                | 93
805                | 94
806                | 95
807                | 96
808                | 97
809                | 98
810                | 99
811                | 100
812                | 101
813                | 102
814                | 103
815                | 104
816                | 105
817                | 106
818                | 107
819                | 108
820                | 110
821                | 111
822                | 112
823                | 113
824                | 114
825                | 115
826                | 116
827                | 117
828                | 118
829                | 119
830                | 120
831                | 121
832                | 122
833                | 123
834                | 124
835                | 125
836                | 126
837                | 127
838                | 128
839                | 129
840                | 130
841                | 131
842                | 132
843                | 133
844                | 134
845                | 135
846                | 136
847                | 137
848                | 138
849                | 139
850                | 140
851                | 141
852                | 142
853                | 143
854                | 144
855                | 145
856                | 146
857                | 147
858                | 148
859                | 149
860                | 150
861                | 151
862                | 152
863                | 153
864                | 156
865                | 157
866                | 161
867                | 162
868                | 163
869                | 164
870                | 165
871                | 166
872                | 167
873                | 168
874                | 169
875                | 170
876                | 172
877                | 173
878                | 174
879                | 175
880                | 176
881                | 177
882                | 178
883                | 179
884                | 180
885                | 184
886                | 190
887                | 191
888                | 192
889                | 193
890                | 194
891                | 195
892                | 196
893                | 197
894                | 198
895                | 199
896                | 201
897                | 202
898                | 203
899                | 204
900                | 205
901                | 206
902                | 209
903                | 210
904                | 212
905                | 213
906                | 215
907                | 216
908                | 217
909                | 219
910                | 220
911                | 221
912                | 223
913                | 224
914                | 227
915                | 229
916                | 232
917                | 233
918                | 234
919                | 237
920                | 238
921                | 239
922                | 240
923                | 241
924                | 242
925                | 243
926                | 244
927                | 248
928                | 249
929                | 251
930                | 252
931                | 253
932                | 254
933                | 255
934                | 256
935                | 257
936                | 258
937                | 259
938                | 261
939                | 262
940                | 265
941                | 266
942                | 267
943                | 268
944                | 269
945                | 270
946                | 273
947                | 279
948                | 280
949                | 282
950                | 284
951                | 285
952                | 286
953                | 287
954                | 288
955                | 291
956                | 292
957                | 293
958                | 294
959                | 295
960                | 296
961                | 297
962                | 298
963                | 300
964                | 301
965                | 302
966                | 303
967                | 304
968                | 305
969                | 306
970                | 307
971                | 309
972                | 312
973                | 313
974                | 314
975                | 315
976                | 316
977                | 317
978                | 318
979                | 321
980                | 322
981                | 323
982                | 326
983                | 327
984                | 328
985                | 329
986                | 332
987                | 333
988                | 334
989                | 335
990                | 336
991                | 337
992                | 338
993                | 339
994                | 340
995                | 341
996                | 342
997                | 344
998                | 345
999                | 346
1000                | 347
1001                | 348
1002                | 349
1003                | 350
1004                | 351
1005                | 352
1006                | 355
1007                | 356
1008                | 357
1009                | 358
1010                | 359
1011                | 360
1012                | 363
1013                | 365
1014                | 366
1015                | 367
1016                | 368
1017                | 370
1018                | 371
1019                | 372
1020                | 373
1021                | 375
1022                | 376
1023                | 377
1024                | 378
1025                | 379
1026                | 380
1027                | 384
1028                | 386
1029                | 387
1030                | 388
1031                | 391
1032                | 392
1033                | 393
1034                | 394
1035                | 395
1036                | 396
1037                | 397
1038                | 398
1039                | 399
1040                | 401
1041                | 402
1042                | 403
1043                | 404
1044                | 405
1045                | 406
1046                | 407
1047                | 408
1048                | 409
1049                | 410
1050                | 411
1051                | 412
1052                | 413
1053                | 414
1054                | 415
1055                | 416
1056                | 417
1057                | 419
1058                | 420
1059                | 421
1060                | 425
1061                | 426
1062                | 427
1063                | 428
1064                | 429
1065                | 430
1066                | 431
1067                | 432
1068                | 433
1069                | 435
1070                | 436
1071                | 437
1072                | 438
1073                | 440
1074                | 441
1075                | 442
1076                | 444
1077                | 445
1078                | 446
1079                | 447
1080                | 448
1081                | 449
1082                | 450
1083                | 451
1084                | 452
1085                | 453
1086                | 454
1087                | 455
1088                | 456
1089                | 457
1090                | 458
1091                | 459
1092                | 460
1093                | 461
1094                | 462
1095                | 463
1096                | 465
1097                | 466
1098                | 467
1099                | 468
1100                | 469
1101                | 470
1102                | 471
1103                | 472
1104                | 473
1105                | 474
1106                | 475
1107                | 476
1108                | 477
1109                | 478
1110                | 479
1111                | 480
1112                | 481
1113                | 483
1114                | 484
1115                | 487
1116                | 489
1117                | 490
1118                | 491
1119                | 494
1120                | 500
1121                | 501
1122                | 502
1123                | 503
1124                | 504
1125                | 505
1126                | 506
1127                | 507
1128                | 508
1129                | 509
1130                | 510
1131                | 511
1132                | 512
1133                | 513
1134                | 514
1135                | 515
1136                | 516
1137                | 517
1138                | 518
1139                | 519
1140                | 520
1141                | 521
1142                | 522
1143                | 523
1144                | 524
1145                | 525
1146                | 526
1147                | 527
1148                | 528
1149                | 529
1150                | 530
1151                | 531
1152                | 532
1153                | 533
1154                | 534
1155                | 555
1156                | 556
1157                | 557
1158                | 558
1159                | 559
1160                | 560
1161                | 561
1162                | 562
1163                | 563
1164                | 564
1165                | 565
1166                | 566
1167                | 567
1168                | 568
1169                | 569
1170                | 570
1171                | 572
1172                | 576
1173                | 577
1174                | 578
1175                | 579
1176                | 580
1177                | 581
1178                | 586
1179                | 590
1180                | 594
1181                | 599
1182                | 601
1183                | 606
1184                | 609
1185                | 611
1186                | 614
1187                | 617
1188                | 618
1189                | 619
1190                | 621
1191                | 622
1192                | 623
1193                | 630
1194                | 631
1195                | 632
1196                | 637
1197                | 638
1198                | 639
1199                | 640
1200                | 641
1201                | 642
1202                | 643
1203                | 645
1204                | 646
1205                | 647
1206                | 648
1207                | 651
1208                | 653
1209                | 655
1210                | 659
1211                | 660
1212                | 662
1213                | 663
1214                | 664
1215                | 665
1216                | 667
1217                | 668
1218                | 670
1219                | 671
1220                | 672
1221                | 673
1222                | 674
1223                | 675
1224                | 677
1225                | 678
1226                | 679
1227                | 680
1228                | 681
1229                | 682
1230                | 683
1231                | 684
1232                | 685
1233                | 686
1234                | 687
1235                | 688
1236                | 689
1237                | 690
1238                | 693
1239                | 694
1240                | 695
1241                | 696
1242                | 698
1243                | 699
1244                | 700
1245                | 704
1246                | 705
1247                | 706
1248                | 707
1249                | 708
1250                | 709
1251                | 710
1252                | 711
1253                | 712
1254                | 713
1255                | 714
1256                | 715
1257                | 716
1258                | 717
1259                | 718
1260                | 719
1261                | 902
1262                | 910
1263                | 914
1264                | 922
1265                | 926
1266                | 930
1267                | 931
1268                | 932
1269                | 933
1270                | 937
1271                | 938
1272                | 939
1273                | 940
1274                | 942
1275                | 943
1276                | 946
1277                | 948
1278                | 950
1279                | 951
1280                | 952
1281                | 955
1282                | 957
1283                | 960
1284                | 961
1285                | 967
1286                | 2000
1287                | 2001
1288                | 2002
1289                | 2003
1290                | 2004
1291                | 2005
1292                | 2006
1293                | 2007
1294                | 2008
1295                | 2009
1296                | 2010
1297                | 2011
1298                | 2012
1299                | 2013
1300                | 2014
1301                | 2015
1302                | 2016
1303                | 2017
1304                | 2018
1305                | 2060
1306                | 2061
1307                | 2071
1308                | 2073
1309                | 2075
1310                | 2080
1311                | 2095
1312                | 2096
1313                | 2119
1314                | 2121
1315                | 2140
1316                | 2182
1317                | 2183
1318                | 2207
1319                | 2225
1320                | 2236
1321                | 2252
1322                | 2261
1323                | 2284
1324                | 2286
1325                | 2287
1326                | 2288
1327                | 2307
1328                | 2308
1329                | 2309
1330                | 2310
1331                | 2311
1332                | 2312
1333                | 2313
1334                | 2317
1335                | 2318
1336                | 2344
1337                | 2350
1338                | 2351
1339                | 2352
1340                | 2356
1341                | 2357
1342                | 2358
1343                | 2359
1344                | 2360
1345                | 2361
1346        )
1347    }
1348}
1349
1350impl UtilmdStromConditionEvaluatorFV2510 {
1351    /// [2] Wenn UNH DE0070 (Übermittlungsfolgenummer) mit 1 vorhanden
1352    fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
1353        ctx.has_segment_matching("UNH", &[(3, 0, "1")])
1354    }
1355
1356    /// [3] Bei Aufteilung, in der Nachricht mit der höchsten Übermittlungsfolgenummer
1357    /// EXTERNAL: Requires context from outside the message.
1358    fn evaluate_3(&self, ctx: &EvaluationContext) -> ConditionResult {
1359        ctx.external.evaluate("is_highest_sequence_in_split")
1360    }
1361
1362    /// [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
1363    fn evaluate_20(&self, ctx: &EvaluationContext) -> ConditionResult {
1364        let nav = match ctx.navigator() {
1365            Some(n) => n,
1366            None => return ctx.has_qualified_value("CCI", 0, "Z30", 2, 0, &["Z07"]),
1367        };
1368        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1369        for i in 0..sg8_count {
1370            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1371            let has_z01 = seq_segs.iter().any(|s| {
1372                s.elements
1373                    .first()
1374                    .and_then(|e| e.first())
1375                    .is_some_and(|v| v == "Z01")
1376            });
1377            if !has_z01 {
1378                continue;
1379            }
1380            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
1381            for j in 0..sg10_count {
1382                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
1383                if ccis.iter().any(|s| {
1384                    s.elements
1385                        .first()
1386                        .and_then(|e| e.first())
1387                        .is_some_and(|v| v == "Z30")
1388                        && s.elements
1389                            .get(2)
1390                            .and_then(|e| e.first())
1391                            .is_some_and(|v| v == "Z07")
1392                }) {
1393                    return ConditionResult::True;
1394                }
1395            }
1396        }
1397        ConditionResult::False
1398    }
1399
1400    /// [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
1401    // 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)
1402    fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
1403        let nav = match ctx.navigator() {
1404            Some(n) => n,
1405            None => {
1406                let sts_segs = ctx.find_segments_with_qualifier("STS", 0, "E01");
1407                let found = sts_segs.iter().any(|s| {
1408                    let code = s
1409                        .elements
1410                        .get(2)
1411                        .and_then(|e| e.first())
1412                        .map(|v| v.as_str());
1413                    let list = s.elements.get(2).and_then(|e| e.get(1)).map(|v| v.as_str());
1414                    (code == Some("A04") && list == Some("E_0017"))
1415                        || (code == Some("A03") && list == Some("E_0052"))
1416                });
1417                return ConditionResult::from(!found);
1418            }
1419        };
1420        let sg4_count = nav.group_instance_count(&["SG4"]);
1421        for i in 0..sg4_count {
1422            let ide_segs = nav.find_segments_in_group("IDE", &["SG4"], i);
1423            let has_ide_24 = ide_segs.iter().any(|s| {
1424                s.elements
1425                    .first()
1426                    .and_then(|e| e.first())
1427                    .is_some_and(|v| v == "24")
1428            });
1429            if !has_ide_24 {
1430                continue;
1431            }
1432            let sts_segs = nav.find_segments_in_group("STS", &["SG4"], i);
1433            let found = sts_segs.iter().any(|s| {
1434                let qual = s
1435                    .elements
1436                    .first()
1437                    .and_then(|e| e.first())
1438                    .map(|v| v.as_str());
1439                let code = s
1440                    .elements
1441                    .get(2)
1442                    .and_then(|e| e.first())
1443                    .map(|v| v.as_str());
1444                let list = s.elements.get(2).and_then(|e| e.get(1)).map(|v| v.as_str());
1445                qual == Some("E01")
1446                    && ((code == Some("A04") && list == Some("E_0017"))
1447                        || (code == Some("A03") && list == Some("E_0052")))
1448            });
1449            if !found {
1450                return ConditionResult::True;
1451            }
1452        }
1453        ConditionResult::False
1454    }
1455
1456    /// [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
1457    // 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)
1458    fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
1459        let nav = match ctx.navigator() {
1460            Some(n) => n,
1461            None => {
1462                let sts_segs = ctx.find_segments_with_qualifier("STS", 0, "E01");
1463                let found = sts_segs.iter().any(|s| {
1464                    let code = s
1465                        .elements
1466                        .get(2)
1467                        .and_then(|e| e.first())
1468                        .map(|v| v.as_str());
1469                    let list = s.elements.get(2).and_then(|e| e.get(1)).map(|v| v.as_str());
1470                    (code == Some("A06") && list == Some("E_0017"))
1471                        || (code == Some("A05") && list == Some("E_0052"))
1472                });
1473                return ConditionResult::from(!found);
1474            }
1475        };
1476        let sg4_count = nav.group_instance_count(&["SG4"]);
1477        for i in 0..sg4_count {
1478            let ide_segs = nav.find_segments_in_group("IDE", &["SG4"], i);
1479            let has_ide_24 = ide_segs.iter().any(|s| {
1480                s.elements
1481                    .first()
1482                    .and_then(|e| e.first())
1483                    .is_some_and(|v| v == "24")
1484            });
1485            if !has_ide_24 {
1486                continue;
1487            }
1488            let sts_segs = nav.find_segments_in_group("STS", &["SG4"], i);
1489            let found = sts_segs.iter().any(|s| {
1490                let qual = s
1491                    .elements
1492                    .first()
1493                    .and_then(|e| e.first())
1494                    .map(|v| v.as_str());
1495                let code = s
1496                    .elements
1497                    .get(2)
1498                    .and_then(|e| e.first())
1499                    .map(|v| v.as_str());
1500                let list = s.elements.get(2).and_then(|e| e.get(1)).map(|v| v.as_str());
1501                qual == Some("E01")
1502                    && ((code == Some("A06") && list == Some("E_0017"))
1503                        || (code == Some("A05") && list == Some("E_0052")))
1504            });
1505            if !found {
1506                return ConditionResult::True;
1507            }
1508        }
1509        ConditionResult::False
1510    }
1511
1512    /// [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...
1513    fn evaluate_44(&self, _ctx: &EvaluationContext) -> ConditionResult {
1514        // Hinweis: Die Zeitraum-ID ist vom DE1156 aus einem passenden SG6 RFF+Z49/Z53
1515        // (Verwendungszeitraum der Daten) aus der Anfragenachricht, identifiziert über
1516        // SG6 RFF+TN DE1154 (Referenz Vorgangsnummer), einzutragen. Informelle Befüllungsregel.
1517        ConditionResult::True
1518    }
1519
1520    /// [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...
1521    // 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)
1522    fn evaluate_51(&self, ctx: &EvaluationContext) -> ConditionResult {
1523        let nav = match ctx.navigator() {
1524            Some(n) => n,
1525            None => return ConditionResult::Unknown,
1526        };
1527        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1528
1529        // Step 1: Collect Zeitraum-IDs from Z78 SG8 groups that have RFF+Z31 with the target code
1530        let target_code = "9992000000018";
1531        let mut z78_zeitraum_ids: std::collections::HashSet<String> =
1532            std::collections::HashSet::new();
1533        for i in 0..sg8_count {
1534            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1535            let is_z78 = seq_segs.iter().any(|s| {
1536                s.elements
1537                    .first()
1538                    .and_then(|e| e.first())
1539                    .is_some_and(|v| v == "Z78")
1540            });
1541            if !is_z78 {
1542                continue;
1543            }
1544            let rff_segs = nav.find_segments_in_group("RFF", &["SG4", "SG8"], i);
1545            let has_z31_target = rff_segs.iter().any(|s| {
1546                s.elements
1547                    .first()
1548                    .and_then(|e| e.first())
1549                    .is_some_and(|v| v == "Z31")
1550                    && s.elements
1551                        .first()
1552                        .and_then(|e| e.get(1))
1553                        .is_some_and(|v| v.replace(' ', "") == target_code)
1554            });
1555            if has_z31_target {
1556                for seq in &seq_segs {
1557                    if seq
1558                        .elements
1559                        .first()
1560                        .and_then(|e| e.first())
1561                        .is_some_and(|v| v == "Z78")
1562                    {
1563                        if let Some(zeit_id) = seq.elements.get(1).and_then(|e| e.first()) {
1564                            if !zeit_id.is_empty() {
1565                                z78_zeitraum_ids.insert(zeit_id.clone());
1566                            }
1567                        }
1568                    }
1569                }
1570            }
1571        }
1572
1573        if z78_zeitraum_ids.is_empty() {
1574            // No Z78 with the target code exists — the Z98 group cannot reference it, condition True
1575            return ConditionResult::True;
1576        }
1577
1578        // Step 2: Check if any Z98 SG8 shares a Zeitraum-ID with a target Z78 SG8
1579        for i in 0..sg8_count {
1580            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1581            for seq in &seq_segs {
1582                if seq
1583                    .elements
1584                    .first()
1585                    .and_then(|e| e.first())
1586                    .is_some_and(|v| v == "Z98")
1587                {
1588                    if let Some(zeit_id) = seq.elements.get(1).and_then(|e| e.first()) {
1589                        if z78_zeitraum_ids.contains(zeit_id) {
1590                            // Z98 SG8 references a Z78 with the Pauschal code — condition False
1591                            return ConditionResult::False;
1592                        }
1593                    }
1594                }
1595            }
1596        }
1597        ConditionResult::True
1598    }
1599
1600    /// [79] Wenn SG4 STS+7+++Z33 (Auszug wegen Stilllegung) vorhanden
1601    fn evaluate_79(&self, ctx: &EvaluationContext) -> ConditionResult {
1602        // STS+7+++Z33: elements[0][0]="7" (Statuskategorie), elements[3][0]="Z33" (Transaktionsgrundergänzung: Auszug wegen Stilllegung)
1603        ctx.has_segment_matching("STS", &[(0, 0, "7"), (3, 0, "Z33")])
1604    }
1605
1606    /// [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 ...
1607    // 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)
1608    fn evaluate_134(&self, ctx: &EvaluationContext) -> ConditionResult {
1609        let nav = match ctx.navigator() {
1610            Some(n) => n,
1611            None => return ConditionResult::Unknown,
1612        };
1613        let sg6_count = nav.group_instance_count(&["SG4", "SG6"]);
1614
1615        // Collect (zeitraum_id_numeric, dtm_z25_value, dtm_z26_value) for SG6 groups with RFF+Z48 or RFF+Z55
1616        let mut slices: Vec<(i64, String, String)> = Vec::new();
1617        for i in 0..sg6_count {
1618            let rff_segs = nav.find_segments_in_group("RFF", &["SG4", "SG6"], i);
1619            // DE1156 is elements[0][2] for RFF Verwendungszeitraum
1620            let zeitraum_id = rff_segs.iter().find_map(|s| {
1621                let qual = s.elements.first().and_then(|e| e.first())?;
1622                if qual == "Z48" || qual == "Z55" {
1623                    let id = s.elements.first().and_then(|e| e.get(2))?;
1624                    if !id.is_empty() {
1625                        Some(id.clone())
1626                    } else {
1627                        None
1628                    }
1629                } else {
1630                    None
1631                }
1632            });
1633            let Some(zid_str) = zeitraum_id else { continue };
1634            let Ok(zid_num) = zid_str.parse::<i64>() else {
1635                continue;
1636            };
1637            let dtm_segs = nav.find_segments_in_group("DTM", &["SG4", "SG6"], i);
1638            let z25 = dtm_segs
1639                .iter()
1640                .find_map(|s| {
1641                    if s.elements
1642                        .first()
1643                        .and_then(|e| e.first())
1644                        .is_some_and(|v| v == "Z25")
1645                    {
1646                        s.elements.first().and_then(|e| e.get(1)).cloned()
1647                    } else {
1648                        None
1649                    }
1650                })
1651                .unwrap_or_default();
1652            let z26 = dtm_segs
1653                .iter()
1654                .find_map(|s| {
1655                    if s.elements
1656                        .first()
1657                        .and_then(|e| e.first())
1658                        .is_some_and(|v| v == "Z26")
1659                    {
1660                        s.elements.first().and_then(|e| e.get(1)).cloned()
1661                    } else {
1662                        None
1663                    }
1664                })
1665                .unwrap_or_default();
1666            slices.push((zid_num, z25, z26));
1667        }
1668        if slices.len() < 2 {
1669            return ConditionResult::Unknown;
1670        }
1671        slices.sort_by_key(|s| s.0);
1672        // For each slice with Zeitraum-ID != 1, DTM+Z25 must equal DTM+Z26 of the immediately preceding slice
1673        for idx in 1..slices.len() {
1674            let (id, z25, _) = &slices[idx];
1675            let (_, _, prev_z26) = &slices[idx - 1];
1676            if *id != 1 && !z25.is_empty() && !prev_z26.is_empty() && z25 != prev_z26 {
1677                return ConditionResult::False;
1678            }
1679        }
1680        ConditionResult::True
1681    }
1682
1683    /// [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...
1684    // 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)
1685    fn evaluate_135(&self, ctx: &EvaluationContext) -> ConditionResult {
1686        let nav = match ctx.navigator() {
1687            Some(n) => n,
1688            None => return ConditionResult::Unknown,
1689        };
1690        let sg6_count = nav.group_instance_count(&["SG4", "SG6"]);
1691
1692        // Collect (zeitraum_id_numeric, dtm_z25_value, dtm_z26_value) for SG6 groups with RFF+Z47 or RFF+Z54
1693        let mut slices: Vec<(i64, String, String)> = Vec::new();
1694        for i in 0..sg6_count {
1695            let rff_segs = nav.find_segments_in_group("RFF", &["SG4", "SG6"], i);
1696            // DE1156 is elements[0][2] for RFF Verwendungszeitraum
1697            let zeitraum_id = rff_segs.iter().find_map(|s| {
1698                let qual = s.elements.first().and_then(|e| e.first())?;
1699                if qual == "Z47" || qual == "Z54" {
1700                    let id = s.elements.first().and_then(|e| e.get(2))?;
1701                    if !id.is_empty() {
1702                        Some(id.clone())
1703                    } else {
1704                        None
1705                    }
1706                } else {
1707                    None
1708                }
1709            });
1710            let Some(zid_str) = zeitraum_id else { continue };
1711            let Ok(zid_num) = zid_str.parse::<i64>() else {
1712                continue;
1713            };
1714            let dtm_segs = nav.find_segments_in_group("DTM", &["SG4", "SG6"], i);
1715            let z25 = dtm_segs
1716                .iter()
1717                .find_map(|s| {
1718                    if s.elements
1719                        .first()
1720                        .and_then(|e| e.first())
1721                        .is_some_and(|v| v == "Z25")
1722                    {
1723                        s.elements.first().and_then(|e| e.get(1)).cloned()
1724                    } else {
1725                        None
1726                    }
1727                })
1728                .unwrap_or_default();
1729            let z26 = dtm_segs
1730                .iter()
1731                .find_map(|s| {
1732                    if s.elements
1733                        .first()
1734                        .and_then(|e| e.first())
1735                        .is_some_and(|v| v == "Z26")
1736                    {
1737                        s.elements.first().and_then(|e| e.get(1)).cloned()
1738                    } else {
1739                        None
1740                    }
1741                })
1742                .unwrap_or_default();
1743            slices.push((zid_num, z25, z26));
1744        }
1745        if slices.len() < 2 {
1746            return ConditionResult::Unknown;
1747        }
1748        slices.sort_by_key(|s| s.0);
1749        // For each slice with Zeitraum-ID != 1, DTM+Z25 must equal DTM+Z26 of the immediately preceding slice
1750        for idx in 1..slices.len() {
1751            let (id, z25, _) = &slices[idx];
1752            let (_, _, prev_z26) = &slices[idx - 1];
1753            if *id != 1 && !z25.is_empty() && !prev_z26.is_empty() && z25 != prev_z26 {
1754                return ConditionResult::False;
1755            }
1756        }
1757        ConditionResult::True
1758    }
1759
1760    /// [136] Wenn SG10 CCI+++E13 (Zählertyp) CAV+EHZ (elektronischer Haushaltszähler) in dieser SG8 vorhanden
1761    fn evaluate_136(&self, ctx: &EvaluationContext) -> ConditionResult {
1762        let nav = match ctx.navigator() {
1763            Some(n) => n,
1764            None => return ctx.has_qualified_value("CAV", 0, "EHZ", 0, 0, &["EHZ"]),
1765        };
1766        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1767        for i in 0..sg8_count {
1768            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
1769            for j in 0..sg10_count {
1770                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
1771                let has_cci_e13 = ccis.iter().any(|s| {
1772                    s.elements
1773                        .get(2)
1774                        .and_then(|e| e.first())
1775                        .is_some_and(|v| v == "E13")
1776                });
1777                if has_cci_e13 {
1778                    let cavs =
1779                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
1780                    if cavs.iter().any(|s| {
1781                        s.elements
1782                            .first()
1783                            .and_then(|e| e.first())
1784                            .is_some_and(|v| v == "EHZ")
1785                    }) {
1786                        return ConditionResult::True;
1787                    }
1788                }
1789            }
1790        }
1791        ConditionResult::False
1792    }
1793
1794    /// [139] Wenn SG10 CAV+IVA (Individuelle Abstimmung) in dieser SG8 nicht vorhanden
1795    // 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)
1796    fn evaluate_139(&self, ctx: &EvaluationContext) -> ConditionResult {
1797        let nav = match ctx.navigator() {
1798            Some(n) => n,
1799            None => return ctx.lacks_qualifier("CAV", 0, "IVA"),
1800        };
1801        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1802        for i in 0..sg8_count {
1803            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
1804            for j in 0..sg10_count {
1805                let cavs = nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
1806                if cavs.iter().any(|s| {
1807                    s.elements
1808                        .first()
1809                        .and_then(|e| e.first())
1810                        .is_some_and(|v| v == "IVA")
1811                }) {
1812                    return ConditionResult::False;
1813                }
1814            }
1815        }
1816        ConditionResult::True
1817    }
1818
1819    /// [157] Wenn SG4 STS+7++Z33+ZZB nicht vorhanden
1820    fn evaluate_157(&self, ctx: &EvaluationContext) -> ConditionResult {
1821        let result = ctx.has_segment_matching("STS", &[(0, 0, "7"), (2, 0, "Z33"), (3, 0, "ZZB")]);
1822        match result {
1823            ConditionResult::True => ConditionResult::False,
1824            ConditionResult::False => ConditionResult::True,
1825            ConditionResult::Unknown => ConditionResult::Unknown,
1826        }
1827    }
1828
1829    /// [168] Wenn in dieser SG8 im SG8 PIA+Z02 (Gruppenartikel- ID / Artikel-ID), die Artikel-ID 1-02-0-002/ 003/ 004 vorhanden
1830    fn evaluate_168(&self, ctx: &EvaluationContext) -> ConditionResult {
1831        ctx.any_group_has_qualified_value(
1832            "PIA",
1833            0,
1834            "Z02",
1835            1,
1836            0,
1837            &["1-02-0-002", "1-02-0-003", "1-02-0-004"],
1838            &["SG4", "SG8"],
1839        )
1840    }
1841
1842    /// [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 ...
1843    // 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)
1844    fn evaluate_169(&self, ctx: &EvaluationContext) -> ConditionResult {
1845        let nav = match ctx.navigator() {
1846            Some(n) => n,
1847            None => return ConditionResult::Unknown,
1848        };
1849        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1850        let mut sg8_data: Vec<(String, String)> = Vec::new();
1851        for i in 0..sg8_count {
1852            let seqs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1853            let zeitraum_id = seqs
1854                .iter()
1855                .find(|s| {
1856                    s.elements
1857                        .first()
1858                        .and_then(|e| e.first())
1859                        .is_some_and(|v| v == "Z45")
1860                })
1861                .and_then(|s| s.elements.get(1))
1862                .and_then(|e| e.first())
1863                .filter(|v| !v.is_empty())
1864                .cloned();
1865            if let Some(zid) = zeitraum_id {
1866                let pias = nav.find_segments_in_group("PIA", &["SG4", "SG8"], i);
1867                let article_id = pias
1868                    .iter()
1869                    .find(|s| {
1870                        s.elements
1871                            .first()
1872                            .and_then(|e| e.first())
1873                            .is_some_and(|v| v == "Z02")
1874                    })
1875                    .and_then(|s| s.elements.get(1))
1876                    .and_then(|e| e.first())
1877                    .cloned()
1878                    .unwrap_or_default();
1879                sg8_data.push((zid, article_id));
1880            }
1881        }
1882        for i in 0..sg8_data.len() {
1883            for j in (i + 1)..sg8_data.len() {
1884                if sg8_data[i].0 == sg8_data[j].0 {
1885                    let (id_i, id_j) = (&sg8_data[i].1, &sg8_data[j].1);
1886                    let i_is_002 = id_i == "1-02-0-002";
1887                    let j_is_002 = id_j == "1-02-0-002";
1888                    let i_is_003_004 = id_i == "1-02-0-003" || id_i == "1-02-0-004";
1889                    let j_is_003_004 = id_j == "1-02-0-003" || id_j == "1-02-0-004";
1890                    if (i_is_002 && j_is_003_004) || (j_is_002 && i_is_003_004) {
1891                        return ConditionResult::True;
1892                    }
1893                }
1894            }
1895        }
1896        if sg8_data.is_empty() {
1897            ConditionResult::Unknown
1898        } else {
1899            ConditionResult::False
1900        }
1901    }
1902
1903    /// [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
1904    fn evaluate_206(&self, ctx: &EvaluationContext) -> ConditionResult {
1905        match ctx.has_segment_matching("STS", &[(0, 0, "7"), (2, 0, "ZG5")]) {
1906            ConditionResult::True => ConditionResult::False,
1907            ConditionResult::False => ConditionResult::True,
1908            ConditionResult::Unknown => ConditionResult::Unknown,
1909        }
1910    }
1911
1912    /// [242] Wenn mehr als ein SG8 (Referenz auf die Lokationsbündelstruktur) mit der selben Zeitraum-ID im DE1050 vorhanden
1913    fn evaluate_242(&self, ctx: &EvaluationContext) -> ConditionResult {
1914        let nav = match ctx.navigator() {
1915            Some(n) => n,
1916            None => return ConditionResult::Unknown,
1917        };
1918        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1919        let mut ids: Vec<String> = Vec::new();
1920        for i in 0..sg8_count {
1921            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1922            for seq in &seq_segs {
1923                let qual = seq
1924                    .elements
1925                    .first()
1926                    .and_then(|e| e.first())
1927                    .map(|s| s.as_str());
1928                if matches!(qual, Some("Z78") | Some("ZC7") | Some("ZC8") | Some("ZD5")) {
1929                    if let Some(id) = seq.elements.get(1).and_then(|e| e.first()) {
1930                        if !id.is_empty() {
1931                            ids.push(id.clone());
1932                        }
1933                    }
1934                }
1935            }
1936        }
1937        if ids.is_empty() {
1938            return ConditionResult::Unknown;
1939        }
1940        let mut seen = std::collections::HashSet::new();
1941        ConditionResult::from(ids.iter().any(|id| !seen.insert(id.as_str())))
1942    }
1943
1944    /// [253] Wenn SG4 STS+E01++ZC9 (Ablehnung (keine Zuordnung möglich)) nicht vorhanden
1945    fn evaluate_253(&self, ctx: &EvaluationContext) -> ConditionResult {
1946        match ctx.has_segment_matching("STS", &[(0, 0, "E01"), (2, 0, "ZC9")]) {
1947            ConditionResult::True => ConditionResult::False,
1948            ConditionResult::False => ConditionResult::True,
1949            ConditionResult::Unknown => ConditionResult::Unknown,
1950        }
1951    }
1952
1953    /// [258] Wenn in dieser SG8 SEQ+Z01 (Daten der Marktlokation) SG10 CCI+Z30++Z07 (Verbrauch) vorhanden
1954    fn evaluate_258(&self, ctx: &EvaluationContext) -> ConditionResult {
1955        let nav = match ctx.navigator() {
1956            Some(n) => n,
1957            None => return ctx.has_qualified_value("CCI", 0, "Z30", 2, 0, &["Z07"]),
1958        };
1959        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1960        for i in 0..sg8_count {
1961            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
1962            let has_z01 = seq_segs.iter().any(|s| {
1963                s.elements
1964                    .first()
1965                    .and_then(|e| e.first())
1966                    .is_some_and(|v| v == "Z01")
1967            });
1968            if has_z01 {
1969                let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
1970                for j in 0..sg10_count {
1971                    let ccis =
1972                        nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
1973                    if ccis.iter().any(|s| {
1974                        s.elements
1975                            .first()
1976                            .and_then(|e| e.first())
1977                            .is_some_and(|v| v == "Z30")
1978                            && s.elements
1979                                .get(2)
1980                                .and_then(|e| e.first())
1981                                .is_some_and(|v| v == "Z07")
1982                    }) {
1983                        return ConditionResult::True;
1984                    }
1985                }
1986            }
1987        }
1988        ConditionResult::False
1989    }
1990
1991    /// [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...
1992    // 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)
1993    fn evaluate_297(&self, ctx: &EvaluationContext) -> ConditionResult {
1994        let nav = match ctx.navigator() {
1995            Some(n) => n,
1996            None => return ConditionResult::Unknown,
1997        };
1998        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
1999        // Collect (seq_qualifier, zeitraum_id) tuples from SG8 instances with SEQ+Z02/ZE3 that also have PIA+5
2000        let mut keys: Vec<(String, String)> = Vec::new();
2001        for i in 0..sg8_count {
2002            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2003            for seq in &seq_segs {
2004                let qual = seq
2005                    .elements
2006                    .first()
2007                    .and_then(|e| e.first())
2008                    .map(|s| s.as_str());
2009                if matches!(qual, Some("Z02") | Some("ZE3")) {
2010                    let pia_segs = nav.find_segments_in_group("PIA", &["SG4", "SG8"], i);
2011                    let has_pia5 = pia_segs.iter().any(|s| {
2012                        s.elements
2013                            .first()
2014                            .and_then(|e| e.first())
2015                            .is_some_and(|v| v == "5")
2016                    });
2017                    if has_pia5 {
2018                        let zeitraum_id = seq
2019                            .elements
2020                            .get(1)
2021                            .and_then(|e| e.first())
2022                            .cloned()
2023                            .unwrap_or_default();
2024                        if !zeitraum_id.is_empty() {
2025                            keys.push((qual.unwrap_or_default().to_string(), zeitraum_id));
2026                        }
2027                    }
2028                }
2029            }
2030        }
2031        if keys.is_empty() {
2032            return ConditionResult::Unknown;
2033        }
2034        let mut seen = std::collections::HashSet::new();
2035        ConditionResult::from(keys.iter().any(|k| !seen.insert(k)))
2036    }
2037
2038    /// [312] Wenn DTM+137 (Nachrichtendatum) im DE2380 &lt; 202603312200?+00
2039    fn evaluate_312(&self, ctx: &EvaluationContext) -> ConditionResult {
2040        ctx.dtm_lt("137", "202603312200+00")
2041    }
2042
2043    /// [313] Wenn DTM+137 (Nachrichtendatum) im DE2380 ≥ 202603312200?+00
2044    fn evaluate_313(&self, ctx: &EvaluationContext) -> ConditionResult {
2045        ctx.dtm_ge("137", "202603312200+00")
2046    }
2047
2048    /// [326] Wenn die Marktlokation nicht stillgelegt wird
2049    /// EXTERNAL: Requires context from outside the message.
2050    fn evaluate_326(&self, ctx: &EvaluationContext) -> ConditionResult {
2051        ctx.external.evaluate("market_location_not_decommissioned")
2052    }
2053
2054    /// [328] Wenn die Marktlokation stillgelegt wird
2055    /// EXTERNAL: Requires context from outside the message.
2056    fn evaluate_328(&self, ctx: &EvaluationContext) -> ConditionResult {
2057        ctx.external.evaluate("market_location_decommissioned")
2058    }
2059
2060    /// [346] Wenn SG10 CCI+++E13 (Zählertyp) CAV+MME (mME) in dieser SG8 vorhanden
2061    fn evaluate_346(&self, ctx: &EvaluationContext) -> ConditionResult {
2062        let nav = match ctx.navigator() {
2063            Some(n) => n,
2064            None => {
2065                // Fallback: message-wide check for both CCI+E13 and CAV+MME
2066                let has_cci = ctx.has_qualifier("CCI", 2, "E13");
2067                let has_cav = ctx.has_qualifier("CAV", 0, "MME");
2068                return match (has_cci, has_cav) {
2069                    (ConditionResult::True, ConditionResult::True) => ConditionResult::True,
2070                    (ConditionResult::False, _) | (_, ConditionResult::False) => {
2071                        ConditionResult::False
2072                    }
2073                    _ => ConditionResult::Unknown,
2074                };
2075            }
2076        };
2077        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2078        for i in 0..sg8_count {
2079            let sg10_count = nav.child_group_instance_count(&["SG4", "SG8"], i, "SG10");
2080            for j in 0..sg10_count {
2081                let ccis = nav.find_segments_in_child_group("CCI", &["SG4", "SG8"], i, "SG10", j);
2082                let has_cci_e13 = ccis.iter().any(|s| {
2083                    s.elements
2084                        .get(2)
2085                        .and_then(|e| e.first())
2086                        .is_some_and(|v| v == "E13")
2087                });
2088                if has_cci_e13 {
2089                    let cavs =
2090                        nav.find_segments_in_child_group("CAV", &["SG4", "SG8"], i, "SG10", j);
2091                    if cavs.iter().any(|s| {
2092                        s.elements
2093                            .first()
2094                            .and_then(|e| e.first())
2095                            .is_some_and(|v| v == "MME")
2096                    }) {
2097                        return ConditionResult::True;
2098                    }
2099                }
2100            }
2101        }
2102        ConditionResult::False
2103    }
2104
2105    /// [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...
2106    // 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)
2107    fn evaluate_387(&self, ctx: &EvaluationContext) -> ConditionResult {
2108        let nav = match ctx.navigator() {
2109            Some(n) => n,
2110            None => return ConditionResult::Unknown,
2111        };
2112        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2113        for i in 0..sg8_count {
2114            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2115            let is_obis_malo = seq_segs.iter().any(|s| {
2116                s.elements
2117                    .first()
2118                    .and_then(|e| e.first())
2119                    .is_some_and(|v| matches!(v.as_str(), "Z02" | "ZA1" | "ZA2" | "ZE3"))
2120            });
2121            if !is_obis_malo {
2122                continue;
2123            }
2124            let pia_segs = nav.find_segments_in_group("PIA", &["SG4", "SG8"], i);
2125            for pia in &pia_segs {
2126                if !pia
2127                    .elements
2128                    .first()
2129                    .and_then(|e| e.first())
2130                    .is_some_and(|v| v == "5")
2131                {
2132                    continue;
2133                }
2134                let obis = match pia.elements.get(1).and_then(|e| e.first()) {
2135                    Some(o) => o.as_str(),
2136                    None => continue,
2137                };
2138                // OBIS format: A-B:C.D.E*F — extract E (Tarif/Zählzeit) as split('.')[2] after ':'
2139                let after_colon = obis.find(':').map(|p| &obis[p + 1..]).unwrap_or(obis);
2140                let parts: Vec<&str> = after_colon.split('.').collect();
2141                if parts.len() >= 3 {
2142                    let e_str = parts[2].split('*').next().unwrap_or("");
2143                    if let Ok(e_val) = e_str.parse::<u32>() {
2144                        if e_val >= 1 && e_val <= 62 {
2145                            return ConditionResult::True;
2146                        }
2147                    }
2148                }
2149            }
2150        }
2151        ConditionResult::False
2152    }
2153
2154    /// [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...
2155    fn evaluate_399(&self, _ctx: &EvaluationContext) -> ConditionResult {
2156        // TODO: Condition [399] requires manual implementation
2157        // 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.
2158        ConditionResult::Unknown
2159    }
2160
2161    /// [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/...
2162    fn evaluate_413(&self, _ctx: &EvaluationContext) -> ConditionResult {
2163        // TODO: Condition [413] requires manual implementation
2164        // 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.
2165        ConditionResult::Unknown
2166    }
2167
2168    /// [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...
2169    fn evaluate_414(&self, _ctx: &EvaluationContext) -> ConditionResult {
2170        // TODO: Condition [414] requires manual implementation
2171        // 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.
2172        ConditionResult::Unknown
2173    }
2174
2175    /// [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...
2176    fn evaluate_415(&self, _ctx: &EvaluationContext) -> ConditionResult {
2177        // TODO: Condition [415] requires manual implementation
2178        // 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.
2179        ConditionResult::Unknown
2180    }
2181
2182    /// [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...
2183    fn evaluate_416(&self, _ctx: &EvaluationContext) -> ConditionResult {
2184        // TODO: Condition [416] requires manual implementation
2185        // 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.
2186        ConditionResult::Unknown
2187    }
2188
2189    /// [461] Wenn in derselben SG10 das CCI (Art und Nutzung der Technischen Ressource) im CAV+ZG8 (Technischen Ressource fällt unter § 14a EnWG) vorhanden
2190    fn evaluate_461(&self, ctx: &EvaluationContext) -> ConditionResult {
2191        // Wenn in derselben SG10 das CCI (Art und Nutzung der Technischen Ressource)
2192        // im CAV+ZG8 (Technische Ressource fällt unter § 14a EnWG) vorhanden
2193        // CCI is the SG10 entry segment; condition reduces to: any SG10 has CAV with ZG8
2194        ctx.any_group_has_qualifier("CAV", 0, "ZG8", &["SG4", "SG8", "SG10"])
2195    }
2196
2197    /// [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
2198    fn evaluate_517(&self, _ctx: &EvaluationContext) -> ConditionResult {
2199        // Hinweis: Anzuwenden, wenn einer Marktlokation eine Paket-ID zugeordnet wurde
2200        // und diese wieder gelöscht werden soll, da sie nicht unter den genannten
2201        // NB-Wechsel fällt — informational note, always applies
2202        ConditionResult::True
2203    }
2204
2205    /// [534] Hinweis: Aufgrund der Wiederholbarkeit des SG4 STS Status der Antwort ist die Angabe von max. acht Verwendungszeiträumen möglich
2206    fn evaluate_534(&self, _ctx: &EvaluationContext) -> ConditionResult {
2207        // Hinweis: Aufgrund der Wiederholbarkeit des SG4 STS Status der Antwort ist
2208        // die Angabe von max. acht Verwendungszeiträumen möglich
2209        // — informational note about cardinality, always applies
2210        ConditionResult::True
2211    }
2212
2213    /// [557] Hinweis: Wurden vom Verantwortlichen mehr als acht Verwendungszeiträume gesendet, so werden acht beliebige Verwendungszeiträume beantwortet
2214    fn evaluate_557(&self, _ctx: &EvaluationContext) -> ConditionResult {
2215        // Hinweis: Wurden vom Verantwortlichen mehr als acht Verwendungszeiträume
2216        // gesendet, so werden acht beliebige Verwendungszeiträume beantwortet
2217        // — informational processing note, always applies
2218        ConditionResult::True
2219    }
2220
2221    /// [560] Hinweis: Dies entspricht dem Geschäftsvorfall A
2222    fn evaluate_560(&self, _ctx: &EvaluationContext) -> ConditionResult {
2223        // Hinweis: Dies entspricht dem Geschäftsvorfall A — informational note, always applies
2224        ConditionResult::True
2225    }
2226
2227    /// [561] Hinweis: Dies entspricht dem Geschäftsvorfall B
2228    fn evaluate_561(&self, _ctx: &EvaluationContext) -> ConditionResult {
2229        // Hinweis: Dies entspricht dem Geschäftsvorfall B — informational note, always applies
2230        ConditionResult::True
2231    }
2232
2233    /// [562] Hinweis: Bei Marktlokationen, welche auf Basis von Werten bilanziert werden, wird der erste Tag des Jahres angegeben.
2234    fn evaluate_562(&self, _ctx: &EvaluationContext) -> ConditionResult {
2235        // Hinweis: Bei Marktlokationen, welche auf Basis von Werten bilanziert werden, wird der erste Tag des Jahres angegeben — informational note, always applies
2236        ConditionResult::True
2237    }
2238
2239    /// [564] Hinweis: Das IDE+Z01 (Liste) definiert den Geschäftsvorfall. Alle aufgelisteten IDE+24 sind Bestandteil des Geschäftsvorfalls
2240    fn evaluate_564(&self, _ctx: &EvaluationContext) -> ConditionResult {
2241        // Hinweis: Das IDE+Z01 (Liste) definiert den Geschäftsvorfall. Alle aufgelisteten IDE+24 sind Bestandteil des Geschäftsvorfalls — informational note, always applies
2242        ConditionResult::True
2243    }
2244
2245    /// [565] Hinweis: Das IDE+24 beschreibt einen Bestandteil einer Liste, wenn ein IDE+Z01 vorhanden ist. Es beschreibt nicht den Geschäftsvorfall
2246    fn evaluate_565(&self, _ctx: &EvaluationContext) -> ConditionResult {
2247        // 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
2248        ConditionResult::True
2249    }
2250
2251    /// [578] Hinweis: Dies gilt für den Zeitraum welcher mit Z53 (keine Daten) definiert ist
2252    fn evaluate_578(&self, _ctx: &EvaluationContext) -> ConditionResult {
2253        // Hinweis: Dies gilt für den Zeitraum welcher mit Z53 (keine Daten) definiert ist — informational note, always applies
2254        ConditionResult::True
2255    }
2256
2257    /// [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...
2258    fn evaluate_580(&self, _ctx: &EvaluationContext) -> ConditionResult {
2259        // Hinweis: Ersatzbelieferung context note (Niederspannung non-household / Mittelspannung/Hochspannung) — informational note, always applies
2260        ConditionResult::True
2261    }
2262
2263    /// [681] Hinweis: Übergangsversorgung gibt es nur bei Marktlokationen, die unter § 38a EnWG fallen. Grundlage ist eine bilaterale Vereinbarung
2264    fn evaluate_681(&self, _ctx: &EvaluationContext) -> ConditionResult {
2265        // Hinweis: Übergangsversorgung applies only to Marktlokationen under § 38a EnWG based on bilateral agreement — informational note, always applies
2266        ConditionResult::True
2267    }
2268
2269    /// [686] Hinweis: Zu verwenden bei der Abmeldung der Übergangsversorgung.
2270    fn evaluate_686(&self, _ctx: &EvaluationContext) -> ConditionResult {
2271        // Hinweis: Zu verwenden bei der Abmeldung der Übergangsversorgung — informational note, always applies
2272        ConditionResult::True
2273    }
2274
2275    /// [2000] Je SG5 LOC+Z16 (Marktlokation) ist genau einmal die Segmentgruppe anzugeben
2276    // 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)
2277    fn evaluate_2000(&self, ctx: &EvaluationContext) -> ConditionResult {
2278        // Je SG5 LOC+Z16 (Marktlokation) ist genau einmal die Segmentgruppe anzugeben
2279        // Per SG4 transaction group, exactly one SG5 instance should contain LOC+Z16
2280        let nav = match ctx.navigator() {
2281            Some(n) => n,
2282            None => {
2283                let count = ctx.count_qualified_in_group("LOC", 0, "Z16", &["SG4", "SG5"]);
2284                return ConditionResult::from(count == 1);
2285            }
2286        };
2287        let sg4_count = nav.group_instance_count(&["SG4"]);
2288        if sg4_count == 0 {
2289            return ConditionResult::Unknown;
2290        }
2291        for i in 0..sg4_count {
2292            let sg5_count = nav.child_group_instance_count(&["SG4"], i, "SG5");
2293            let mut loc_z16_count = 0usize;
2294            for j in 0..sg5_count {
2295                let locs = nav.find_segments_in_child_group("LOC", &["SG4"], i, "SG5", j);
2296                for loc in &locs {
2297                    if loc
2298                        .elements
2299                        .first()
2300                        .and_then(|e| e.first())
2301                        .is_some_and(|v| v == "Z16")
2302                    {
2303                        loc_z16_count += 1;
2304                    }
2305                }
2306            }
2307            if loc_z16_count != 1 {
2308                return ConditionResult::False;
2309            }
2310        }
2311        ConditionResult::True
2312    }
2313
2314    /// [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...
2315    // 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)
2316    fn evaluate_2006(&self, ctx: &EvaluationContext) -> ConditionResult {
2317        let nav = match ctx.navigator() {
2318            Some(n) => n,
2319            None => return ConditionResult::Unknown,
2320        };
2321        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2322        let mut qualifying_zeitraum_ids: Vec<String> = Vec::new();
2323        for i in 0..sg8_count {
2324            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2325            let z01_seq = seq_segs.iter().find(|s| {
2326                s.elements
2327                    .first()
2328                    .and_then(|e| e.first())
2329                    .is_some_and(|v| v == "Z01")
2330            });
2331            if let Some(seq) = z01_seq {
2332                if self.evaluate(199, ctx).is_true() {
2333                    if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2334                        if !zeitraum_id.is_empty() {
2335                            qualifying_zeitraum_ids.push(zeitraum_id.clone());
2336                        }
2337                    }
2338                }
2339            }
2340        }
2341        if qualifying_zeitraum_ids.is_empty() {
2342            return ConditionResult::Unknown;
2343        }
2344        // Verify each qualifying Zeitraum-ID appears exactly once across all SG8 SEQ groups
2345        let mut id_counts: std::collections::HashMap<String, usize> =
2346            std::collections::HashMap::new();
2347        for i in 0..sg8_count {
2348            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2349            for seq in &seq_segs {
2350                if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2351                    if !zeitraum_id.is_empty() && qualifying_zeitraum_ids.contains(zeitraum_id) {
2352                        *id_counts.entry(zeitraum_id.clone()).or_insert(0) += 1;
2353                    }
2354                }
2355            }
2356        }
2357        ConditionResult::from(
2358            qualifying_zeitraum_ids
2359                .iter()
2360                .all(|id| id_counts.get(id).copied().unwrap_or(0) == 1),
2361        )
2362    }
2363
2364    /// [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...
2365    // 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)
2366    fn evaluate_2007(&self, ctx: &EvaluationContext) -> ConditionResult {
2367        let nav = match ctx.navigator() {
2368            Some(n) => n,
2369            None => return ConditionResult::Unknown,
2370        };
2371        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2372        let mut qualifying_zeitraum_ids: Vec<String> = Vec::new();
2373        for i in 0..sg8_count {
2374            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2375            let z01_seq = seq_segs.iter().find(|s| {
2376                s.elements
2377                    .first()
2378                    .and_then(|e| e.first())
2379                    .is_some_and(|v| v == "Z01")
2380            });
2381            if let Some(seq) = z01_seq {
2382                if self.evaluate(199, ctx).is_true() {
2383                    if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2384                        if !zeitraum_id.is_empty() {
2385                            qualifying_zeitraum_ids.push(zeitraum_id.clone());
2386                        }
2387                    }
2388                }
2389            }
2390        }
2391        if qualifying_zeitraum_ids.is_empty() {
2392            return ConditionResult::Unknown;
2393        }
2394        let mut id_counts: std::collections::HashMap<String, usize> =
2395            std::collections::HashMap::new();
2396        for i in 0..sg8_count {
2397            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2398            for seq in &seq_segs {
2399                if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2400                    if !zeitraum_id.is_empty() && qualifying_zeitraum_ids.contains(zeitraum_id) {
2401                        *id_counts.entry(zeitraum_id.clone()).or_insert(0) += 1;
2402                    }
2403                }
2404            }
2405        }
2406        ConditionResult::from(
2407            qualifying_zeitraum_ids
2408                .iter()
2409                .all(|id| id_counts.get(id).copied().unwrap_or(0) == 1),
2410        )
2411    }
2412
2413    /// [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...
2414    // 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)
2415    fn evaluate_2008(&self, ctx: &EvaluationContext) -> ConditionResult {
2416        let nav = match ctx.navigator() {
2417            Some(n) => n,
2418            None => return ConditionResult::Unknown,
2419        };
2420        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2421        let mut qualifying_zeitraum_ids: Vec<String> = Vec::new();
2422        for i in 0..sg8_count {
2423            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2424            let z01_seq = seq_segs.iter().find(|s| {
2425                s.elements
2426                    .first()
2427                    .and_then(|e| e.first())
2428                    .is_some_and(|v| v == "Z01")
2429            });
2430            if let Some(seq) = z01_seq {
2431                if self.evaluate(89, ctx).is_true() {
2432                    if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2433                        if !zeitraum_id.is_empty() {
2434                            qualifying_zeitraum_ids.push(zeitraum_id.clone());
2435                        }
2436                    }
2437                }
2438            }
2439        }
2440        if qualifying_zeitraum_ids.is_empty() {
2441            return ConditionResult::Unknown;
2442        }
2443        let mut id_counts: std::collections::HashMap<String, usize> =
2444            std::collections::HashMap::new();
2445        for i in 0..sg8_count {
2446            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2447            for seq in &seq_segs {
2448                if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2449                    if !zeitraum_id.is_empty() && qualifying_zeitraum_ids.contains(zeitraum_id) {
2450                        *id_counts.entry(zeitraum_id.clone()).or_insert(0) += 1;
2451                    }
2452                }
2453            }
2454        }
2455        ConditionResult::from(
2456            qualifying_zeitraum_ids
2457                .iter()
2458                .all(|id| id_counts.get(id).copied().unwrap_or(0) == 1),
2459        )
2460    }
2461
2462    /// [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...
2463    // REVIEW: Condition 2009 is the plural-grammar variant of 2008 ('Bedingungen' vs 'Bedingung'), semantically identical. Same implementation as 2008 referencing condition [89]. (medium confidence)
2464    fn evaluate_2009(&self, ctx: &EvaluationContext) -> ConditionResult {
2465        let nav = match ctx.navigator() {
2466            Some(n) => n,
2467            None => return ConditionResult::Unknown,
2468        };
2469        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2470        let mut qualifying_zeitraum_ids: Vec<String> = Vec::new();
2471        for i in 0..sg8_count {
2472            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2473            let z01_seq = seq_segs.iter().find(|s| {
2474                s.elements
2475                    .first()
2476                    .and_then(|e| e.first())
2477                    .is_some_and(|v| v == "Z01")
2478            });
2479            if let Some(seq) = z01_seq {
2480                if self.evaluate(89, ctx).is_true() {
2481                    if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2482                        if !zeitraum_id.is_empty() {
2483                            qualifying_zeitraum_ids.push(zeitraum_id.clone());
2484                        }
2485                    }
2486                }
2487            }
2488        }
2489        if qualifying_zeitraum_ids.is_empty() {
2490            return ConditionResult::Unknown;
2491        }
2492        let mut id_counts: std::collections::HashMap<String, usize> =
2493            std::collections::HashMap::new();
2494        for i in 0..sg8_count {
2495            let seq_segs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2496            for seq in &seq_segs {
2497                if let Some(zeitraum_id) = seq.elements.get(1).and_then(|e| e.first()) {
2498                    if !zeitraum_id.is_empty() && qualifying_zeitraum_ids.contains(zeitraum_id) {
2499                        *id_counts.entry(zeitraum_id.clone()).or_insert(0) += 1;
2500                    }
2501                }
2502            }
2503        }
2504        ConditionResult::from(
2505            qualifying_zeitraum_ids
2506                .iter()
2507                .all(|id| id_counts.get(id).copied().unwrap_or(0) == 1),
2508        )
2509    }
2510
2511    /// [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 ...
2512    // 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)
2513    fn evaluate_2011(&self, ctx: &EvaluationContext) -> ConditionResult {
2514        let nav = match ctx.navigator() {
2515            Some(n) => n,
2516            None => {
2517                // Fallback: check message-wide RFF+Z49/Z53 for DE1156 Zeitraum-IDs
2518                let rff_segs = ctx.find_segments("RFF");
2519                let has_qualifying = rff_segs.iter().any(|s| {
2520                    let qual = s
2521                        .elements
2522                        .first()
2523                        .and_then(|e| e.first())
2524                        .map(|v| v.as_str());
2525                    matches!(qual, Some("Z49") | Some("Z53"))
2526                        && s.elements
2527                            .first()
2528                            .and_then(|e| e.get(2))
2529                            .is_some_and(|v| !v.is_empty())
2530                });
2531                return if has_qualifying {
2532                    ConditionResult::True
2533                } else {
2534                    ConditionResult::Unknown
2535                };
2536            }
2537        };
2538        let sg6_count = nav.group_instance_count(&["SG4", "SG6"]);
2539        let mut zeitraum_ids: std::collections::HashSet<String> = std::collections::HashSet::new();
2540        for i in 0..sg6_count {
2541            let rff_segs = nav.find_segments_in_group("RFF", &["SG4", "SG6"], i);
2542            for rff in &rff_segs {
2543                let qual = rff
2544                    .elements
2545                    .first()
2546                    .and_then(|e| e.first())
2547                    .map(|s| s.as_str());
2548                if matches!(qual, Some("Z49") | Some("Z53")) {
2549                    // DE1156 is elements[0][2]
2550                    if let Some(zeitraum_id) = rff.elements.first().and_then(|e| e.get(2)) {
2551                        if !zeitraum_id.is_empty() {
2552                            zeitraum_ids.insert(zeitraum_id.clone());
2553                        }
2554                    }
2555                }
2556            }
2557        }
2558        if zeitraum_ids.is_empty() {
2559            return ConditionResult::Unknown;
2560        }
2561        // The segment group should appear exactly once per distinct Zeitraum-ID from SG6 RFF+Z49/Z53
2562        // We verify that qualifying Zeitraum-IDs are present — cardinality enforcement is structural
2563        ConditionResult::True
2564    }
2565
2566    /// [2013] Mindesten einmal anzugeben, wenn kein SG6 RFF+Z54 (Verwendungszeitraum der Daten: Im System keine Daten vorhanden) vorhanden
2567    fn evaluate_2013(&self, ctx: &EvaluationContext) -> ConditionResult {
2568        // Mindestens einmal anzugeben, wenn kein SG6 RFF+Z54 vorhanden
2569        // True when RFF+Z54 (Verwendungszeitraum: Im System keine Daten vorhanden) is absent
2570        ctx.lacks_qualifier("RFF", 0, "Z54")
2571    }
2572
2573    /// [2014] Mindesten einmal anzugeben, wenn kein SG6 RFF+Z47 (Verwendungszeitraum der Daten: Im System vorhandene Daten) vorhanden
2574    fn evaluate_2014(&self, ctx: &EvaluationContext) -> ConditionResult {
2575        // Mindestens einmal anzugeben, wenn kein SG6 RFF+Z47 vorhanden
2576        // True when RFF+Z47 (Verwendungszeitraum: Im System vorhandene Daten) is absent
2577        ctx.lacks_qualifier("RFF", 0, "Z47")
2578    }
2579
2580    /// [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 ...
2581    // 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)
2582    fn evaluate_2016(&self, ctx: &EvaluationContext) -> ConditionResult {
2583        // Segmentgruppe ist mind. einmal für jede Zeitraum-ID aus DE1156 der SG6 RFF+Z49/Z53 anzugeben
2584        // Collect Zeitraum-IDs from SG6 RFF+Z49 and Z53 (DE1156 = elements[0][2])
2585        // Then verify each required Zeitraum-ID is referenced by at least one SG8 SEQ (DE1050 = elements[1][0])
2586        let nav = match ctx.navigator() {
2587            Some(n) => n,
2588            None => return ConditionResult::Unknown,
2589        };
2590        let sg6_count = nav.group_instance_count(&["SG4", "SG6"]);
2591        let mut required_ids: std::collections::HashSet<String> = std::collections::HashSet::new();
2592        for i in 0..sg6_count {
2593            let rffs = nav.find_segments_in_group("RFF", &["SG4", "SG6"], i);
2594            for rff in &rffs {
2595                let qual = rff
2596                    .elements
2597                    .first()
2598                    .and_then(|e| e.first())
2599                    .map(|s| s.as_str());
2600                if matches!(qual, Some("Z49") | Some("Z53")) {
2601                    if let Some(zeitraum_id) = rff.elements.first().and_then(|e| e.get(2)) {
2602                        if !zeitraum_id.is_empty() {
2603                            required_ids.insert(zeitraum_id.clone());
2604                        }
2605                    }
2606                }
2607            }
2608        }
2609        if required_ids.is_empty() {
2610            return ConditionResult::Unknown;
2611        }
2612        // Check that for each required Zeitraum-ID at least one SG8 SEQ references it via DE1050
2613        let sg8_count = nav.group_instance_count(&["SG4", "SG8"]);
2614        let mut found_ids: std::collections::HashSet<String> = std::collections::HashSet::new();
2615        for i in 0..sg8_count {
2616            let seqs = nav.find_segments_in_group("SEQ", &["SG4", "SG8"], i);
2617            for seq in &seqs {
2618                if let Some(ref_id) = seq.elements.get(1).and_then(|e| e.first()) {
2619                    if !ref_id.is_empty() {
2620                        found_ids.insert(ref_id.clone());
2621                    }
2622                }
2623            }
2624        }
2625        ConditionResult::from(required_ids.iter().all(|id| found_ids.contains(id)))
2626    }
2627
2628    /// [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
2629    // 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)
2630    fn evaluate_2121(&self, ctx: &EvaluationContext) -> ConditionResult {
2631        // Segmentgruppe ist genau einmal je SG8 SEQ+Z01/Z80/Z81 anzugeben
2632        // True when at least one SG8 with SEQ+Z01, Z80, or Z81 exists (cardinality trigger)
2633        ctx.any_group_has_any_qualifier("SEQ", 0, &["Z01", "Z80", "Z81"], &["SG4", "SG8"])
2634    }
2635
2636    /// [1] Wenn Aufteilung vorhanden
2637    fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
2638        ctx.external.evaluate("message_splitting")
2639    }
2640
2641    /// [4] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle LF
2642    fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
2643        ctx.external.evaluate("recipient_is_lf")
2644    }
2645
2646    /// [5] Wenn MP-ID in SG2 NAD+MS (Nachrichtenabsender) in der Rolle LF
2647    fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
2648        ctx.external.evaluate("sender_is_lf")
2649    }
2650
2651    /// [6] Wenn MP-ID in SG2 NAD+MR (Nachrichtenempfänger) in der Rolle ÜNB
2652    fn evaluate_6(&self, ctx: &EvaluationContext) -> ConditionResult {
2653        ctx.external.evaluate("recipient_role_check")
2654    }
2655
2656    /// [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
2657    fn evaluate_7(&self, _ctx: &EvaluationContext) -> ConditionResult {
2658        // TODO: implement
2659        ConditionResult::Unknown
2660    }
2661
2662    /// [8] Wenn für Datenclearing erforderlich
2663    fn evaluate_8(&self, ctx: &EvaluationContext) -> ConditionResult {
2664        ctx.external.evaluate("data_clearing_required")
2665    }
2666
2667    /// [9] Wenn MP-ID in SG2 NAD+MS (Nachrichtenabsender) in der Rolle MSB
2668    fn evaluate_9(&self, ctx: &EvaluationContext) -> ConditionResult {
2669        ctx.external.evaluate("sender_role_check")
2670    }
2671
2672    /// [10] Wenn SG4 STS+7++xxx+xxx+E01/E03 (Transaktionsgrund befristete Anmeldung) vorhanden
2673    fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
2674        ctx.external.evaluate("registration_is_time_limited")
2675    }
2676
2677    /// [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
2678    fn evaluate_11(&self, _ctx: &EvaluationContext) -> ConditionResult {
2679        // TODO: implement
2680        ConditionResult::Unknown
2681    }
2682
2683    /// [12] Wenn SG4 DTM+471 (Ende zum nächstmöglichem Termin) nicht vorhanden
2684    fn evaluate_12(&self, _ctx: &EvaluationContext) -> ConditionResult {
2685        // TODO: implement
2686        ConditionResult::Unknown
2687    }
2688
2689    /// [13] Wenn SG4 STS+E01++Z01 (Status der Antwort: Zustimmung mit Terminänderung) nicht vorhanden
2690    fn evaluate_13(&self, _ctx: &EvaluationContext) -> ConditionResult {
2691        // TODO: implement
2692        ConditionResult::Unknown
2693    }
2694
2695    /// [14] Wenn Datum bekannt
2696    fn evaluate_14(&self, ctx: &EvaluationContext) -> ConditionResult {
2697        ctx.external.evaluate("date_known")
2698    }
2699
2700    /// [15] Wenn in derselben SG8 das SEQ+Z98 (Informative Daten der Marktlokation) vorhanden
2701    fn evaluate_15(&self, _ctx: &EvaluationContext) -> ConditionResult {
2702        // TODO: implement
2703        ConditionResult::Unknown
2704    }
2705
2706    /// [16] Wenn SG4 STS+E01++Z12 (Status der Antwort: Ablehnung Vertragsbindung) vorhanden
2707    fn evaluate_16(&self, _ctx: &EvaluationContext) -> ConditionResult {
2708        // TODO: implement
2709        ConditionResult::Unknown
2710    }
2711
2712    /// [17] Wenn in derselben SG8 das SEQ+Z01/Z80/Z81 (Daten der Marktlokation) vorhanden
2713    fn evaluate_17(&self, _ctx: &EvaluationContext) -> ConditionResult {
2714        // TODO: implement
2715        ConditionResult::Unknown
2716    }
2717
2718    /// [18] Wenn SG4 DTM+93 (Ende zum) nicht vorhanden
2719    fn evaluate_18(&self, _ctx: &EvaluationContext) -> ConditionResult {
2720        // TODO: implement
2721        ConditionResult::Unknown
2722    }
2723
2724    /// [19] Wenn SG8 SEQ+Z01/ Z98 (Daten der Marktlokation) SG10 CCI+++ZC0 (Prognose auf Basis von Werten) vorhanden
2725    fn evaluate_19(&self, _ctx: &EvaluationContext) -> ConditionResult {
2726        // TODO: implement
2727        ConditionResult::Unknown
2728    }
2729
2730    /// [21] Wenn SG10 CCI+++ZA6 (Prognose auf Basis von Profilen) in dieser SG8 vorhanden
2731    fn evaluate_21(&self, _ctx: &EvaluationContext) -> ConditionResult {
2732        // TODO: implement
2733        ConditionResult::Unknown
2734    }
2735
2736    /// [22] Es ist die Zeitraum-ID vom DE1156 aus einem passenden SG6 RFF+Z47/ Z48/ Z49 (Verwendungszeitraum der Daten) einzutragen
2737    // 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)
2738    fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
2739        for qual in &["Z47", "Z48", "Z49"] {
2740            if matches!(
2741                ctx.groups_share_qualified_value(
2742                    "RFF",
2743                    0,
2744                    qual,
2745                    0,
2746                    2,
2747                    &["SG4", "SG6"],
2748                    "SEQ",
2749                    1,
2750                    0,
2751                    &["SG4", "SG8"],
2752                ),
2753                ConditionResult::True
2754            ) {
2755                return ConditionResult::True;
2756            }
2757        }
2758        ConditionResult::False
2759    }
2760
2761    /// [23] Wenn in dieser SG4 das STS+E01++A05/A99 (Status der Antwort) vorhanden
2762    fn evaluate_23(&self, _ctx: &EvaluationContext) -> ConditionResult {
2763        // TODO: implement
2764        ConditionResult::Unknown
2765    }
2766
2767    /// [24] Wenn in dieser SG4 das STS+E01++A25/A99 (Status der Antwort) vorhanden
2768    fn evaluate_24(&self, _ctx: &EvaluationContext) -> ConditionResult {
2769        // TODO: implement
2770        ConditionResult::Unknown
2771    }
2772
2773    /// [25] Wenn die Veräußerungsform der erzeugenden Marktlokation der Marktprämie zugeordnet ist
2774    fn evaluate_25(&self, _ctx: &EvaluationContext) -> ConditionResult {
2775        // TODO: implement
2776        ConditionResult::Unknown
2777    }
2778
2779    /// [27] Wenn das DE2380 von SG4 DTM+Z01 (Kündigungsfrist des Vertrags) an vierter Stelle ein T oder R enthält
2780    fn evaluate_27(&self, _ctx: &EvaluationContext) -> ConditionResult {
2781        // TODO: implement
2782        ConditionResult::Unknown
2783    }
2784
2785    /// [30] Wenn Antwort auf Aktivierung übermittelt wird
2786    fn evaluate_30(&self, _ctx: &EvaluationContext) -> ConditionResult {
2787        // TODO: implement
2788        ConditionResult::Unknown
2789    }
2790
2791    /// [31] Wenn eine Korrektur erfolgt
2792    fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
2793        ctx.external.evaluate("correction_in_progress")
2794    }
2795
2796    /// [32] Wenn mehr als ein SG8 (Referenz auf die Lokationsbündelstruktur) vorhanden
2797    fn evaluate_32(&self, _ctx: &EvaluationContext) -> ConditionResult {
2798        // TODO: implement
2799        ConditionResult::Unknown
2800    }
2801
2802    /// [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...
2803    fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
2804        ctx.external.evaluate("code_list_membership_check")
2805    }
2806
2807    /// [34] Wenn Antwort auf Deaktivierung übermittelt wird
2808    fn evaluate_34(&self, _ctx: &EvaluationContext) -> ConditionResult {
2809        // TODO: implement
2810        ConditionResult::Unknown
2811    }
2812
2813    /// [35] Wenn das DE2380 von SG4 DTM+Z01 (Kündigungsfrist des Vertrags) an vierter Stelle T (Termin) enthält
2814    fn evaluate_35(&self, _ctx: &EvaluationContext) -> ConditionResult {
2815        // TODO: implement
2816        ConditionResult::Unknown
2817    }
2818
2819    /// [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...
2820    fn evaluate_36(&self, ctx: &EvaluationContext) -> ConditionResult {
2821        ctx.external.evaluate("code_list_membership_check")
2822    }
2823
2824    /// [37] Wenn Anmeldung/ Änderung befristet
2825    fn evaluate_37(&self, ctx: &EvaluationContext) -> ConditionResult {
2826        ctx.external.evaluate("registration_is_time_limited")
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}