automapper_validation/generated/fv2510/orders_conditions_fv2510.rs
1// <auto-generated>
2// Generated by automapper-generator generate-conditions
3// AHB: xml-migs-and-ahbs/FV2510/ORDERS_AHB_1_1_Fehlerkorrektur_20250623.xml
4// Generated: 2026-03-12T11:22:20Z
5// </auto-generated>
6
7// LLM-produced bodies aren't idiomatic Rust — silence stylistic lints at
8// file scope so `cargo clippy -D warnings` stays green. Correctness,
9// suspicious, and perf categories stay on so real bugs still surface.
10#![allow(clippy::style, clippy::complexity)]
11
12#[allow(unused_imports)]
13use crate::eval::format_validators::*;
14use crate::eval::{ConditionEvaluator, ConditionResult, EvaluationContext};
15
16/// Generated condition evaluator for ORDERS FV2510.
17pub struct OrdersConditionEvaluatorFV2510 {
18 // External condition IDs that require runtime context.
19 external_conditions: std::collections::HashSet<u32>,
20}
21
22impl Default for OrdersConditionEvaluatorFV2510 {
23 fn default() -> Self {
24 let mut external_conditions = std::collections::HashSet::new();
25 external_conditions.insert(6);
26 external_conditions.insert(7);
27 external_conditions.insert(9);
28 external_conditions.insert(15);
29 external_conditions.insert(16);
30 external_conditions.insert(17);
31 external_conditions.insert(23);
32 external_conditions.insert(26);
33 external_conditions.insert(27);
34 external_conditions.insert(28);
35 external_conditions.insert(29);
36 external_conditions.insert(36);
37 external_conditions.insert(45);
38 external_conditions.insert(60);
39 external_conditions.insert(61);
40 external_conditions.insert(62);
41 external_conditions.insert(63);
42 external_conditions.insert(76);
43 external_conditions.insert(78);
44 external_conditions.insert(82);
45 external_conditions.insert(86);
46 external_conditions.insert(91);
47 external_conditions.insert(95);
48 external_conditions.insert(96);
49 external_conditions.insert(100);
50 external_conditions.insert(101);
51 external_conditions.insert(104);
52 external_conditions.insert(105);
53 external_conditions.insert(125);
54 external_conditions.insert(126);
55 external_conditions.insert(127);
56 external_conditions.insert(128);
57 external_conditions.insert(129);
58 external_conditions.insert(131);
59 external_conditions.insert(132);
60 external_conditions.insert(133);
61 external_conditions.insert(140);
62 external_conditions.insert(141);
63 external_conditions.insert(142);
64 external_conditions.insert(143);
65 external_conditions.insert(152);
66 external_conditions.insert(153);
67 external_conditions.insert(154);
68 external_conditions.insert(155);
69 external_conditions.insert(156);
70 external_conditions.insert(157);
71 external_conditions.insert(158);
72 external_conditions.insert(159);
73 external_conditions.insert(160);
74 external_conditions.insert(162);
75 external_conditions.insert(164);
76 external_conditions.insert(165);
77 external_conditions.insert(166);
78 external_conditions.insert(178);
79 external_conditions.insert(179);
80 external_conditions.insert(180);
81 external_conditions.insert(492);
82 external_conditions.insert(493);
83 Self {
84 external_conditions,
85 }
86 }
87}
88
89impl ConditionEvaluator for OrdersConditionEvaluatorFV2510 {
90 fn message_type(&self) -> &str {
91 "ORDERS"
92 }
93
94 fn format_version(&self) -> &str {
95 "FV2510"
96 }
97
98 fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
99 match condition {
100 1 => self.evaluate_1(ctx),
101 2 => self.evaluate_2(ctx),
102 6 => self.evaluate_6(ctx),
103 7 => self.evaluate_7(ctx),
104 9 => self.evaluate_9(ctx),
105 12 => self.evaluate_12(ctx),
106 13 => self.evaluate_13(ctx),
107 15 => self.evaluate_15(ctx),
108 16 => self.evaluate_16(ctx),
109 17 => self.evaluate_17(ctx),
110 18 => self.evaluate_18(ctx),
111 19 => self.evaluate_19(ctx),
112 21 => self.evaluate_21(ctx),
113 23 => self.evaluate_23(ctx),
114 24 => self.evaluate_24(ctx),
115 26 => self.evaluate_26(ctx),
116 27 => self.evaluate_27(ctx),
117 28 => self.evaluate_28(ctx),
118 29 => self.evaluate_29(ctx),
119 33 => self.evaluate_33(ctx),
120 34 => self.evaluate_34(ctx),
121 35 => self.evaluate_35(ctx),
122 36 => self.evaluate_36(ctx),
123 38 => self.evaluate_38(ctx),
124 45 => self.evaluate_45(ctx),
125 46 => self.evaluate_46(ctx),
126 47 => self.evaluate_47(ctx),
127 51 => self.evaluate_51(ctx),
128 54 => self.evaluate_54(ctx),
129 55 => self.evaluate_55(ctx),
130 56 => self.evaluate_56(ctx),
131 57 => self.evaluate_57(ctx),
132 60 => self.evaluate_60(ctx),
133 61 => self.evaluate_61(ctx),
134 62 => self.evaluate_62(ctx),
135 63 => self.evaluate_63(ctx),
136 64 => self.evaluate_64(ctx),
137 65 => self.evaluate_65(ctx),
138 67 => self.evaluate_67(ctx),
139 68 => self.evaluate_68(ctx),
140 69 => self.evaluate_69(ctx),
141 70 => self.evaluate_70(ctx),
142 76 => self.evaluate_76(ctx),
143 77 => self.evaluate_77(ctx),
144 78 => self.evaluate_78(ctx),
145 79 => self.evaluate_79(ctx),
146 80 => self.evaluate_80(ctx),
147 81 => self.evaluate_81(ctx),
148 82 => self.evaluate_82(ctx),
149 83 => self.evaluate_83(ctx),
150 84 => self.evaluate_84(ctx),
151 85 => self.evaluate_85(ctx),
152 86 => self.evaluate_86(ctx),
153 87 => self.evaluate_87(ctx),
154 91 => self.evaluate_91(ctx),
155 93 => self.evaluate_93(ctx),
156 94 => self.evaluate_94(ctx),
157 95 => self.evaluate_95(ctx),
158 96 => self.evaluate_96(ctx),
159 97 => self.evaluate_97(ctx),
160 99 => self.evaluate_99(ctx),
161 100 => self.evaluate_100(ctx),
162 101 => self.evaluate_101(ctx),
163 102 => self.evaluate_102(ctx),
164 103 => self.evaluate_103(ctx),
165 104 => self.evaluate_104(ctx),
166 105 => self.evaluate_105(ctx),
167 106 => self.evaluate_106(ctx),
168 107 => self.evaluate_107(ctx),
169 108 => self.evaluate_108(ctx),
170 109 => self.evaluate_109(ctx),
171 110 => self.evaluate_110(ctx),
172 112 => self.evaluate_112(ctx),
173 113 => self.evaluate_113(ctx),
174 114 => self.evaluate_114(ctx),
175 115 => self.evaluate_115(ctx),
176 117 => self.evaluate_117(ctx),
177 118 => self.evaluate_118(ctx),
178 119 => self.evaluate_119(ctx),
179 120 => self.evaluate_120(ctx),
180 121 => self.evaluate_121(ctx),
181 122 => self.evaluate_122(ctx),
182 123 => self.evaluate_123(ctx),
183 124 => self.evaluate_124(ctx),
184 125 => self.evaluate_125(ctx),
185 126 => self.evaluate_126(ctx),
186 127 => self.evaluate_127(ctx),
187 128 => self.evaluate_128(ctx),
188 129 => self.evaluate_129(ctx),
189 130 => self.evaluate_130(ctx),
190 131 => self.evaluate_131(ctx),
191 132 => self.evaluate_132(ctx),
192 133 => self.evaluate_133(ctx),
193 134 => self.evaluate_134(ctx),
194 135 => self.evaluate_135(ctx),
195 136 => self.evaluate_136(ctx),
196 137 => self.evaluate_137(ctx),
197 138 => self.evaluate_138(ctx),
198 139 => self.evaluate_139(ctx),
199 140 => self.evaluate_140(ctx),
200 141 => self.evaluate_141(ctx),
201 142 => self.evaluate_142(ctx),
202 143 => self.evaluate_143(ctx),
203 147 => self.evaluate_147(ctx),
204 148 => self.evaluate_148(ctx),
205 152 => self.evaluate_152(ctx),
206 153 => self.evaluate_153(ctx),
207 154 => self.evaluate_154(ctx),
208 155 => self.evaluate_155(ctx),
209 156 => self.evaluate_156(ctx),
210 157 => self.evaluate_157(ctx),
211 158 => self.evaluate_158(ctx),
212 159 => self.evaluate_159(ctx),
213 160 => self.evaluate_160(ctx),
214 161 => self.evaluate_161(ctx),
215 162 => self.evaluate_162(ctx),
216 163 => self.evaluate_163(ctx),
217 164 => self.evaluate_164(ctx),
218 165 => self.evaluate_165(ctx),
219 166 => self.evaluate_166(ctx),
220 167 => self.evaluate_167(ctx),
221 168 => self.evaluate_168(ctx),
222 169 => self.evaluate_169(ctx),
223 170 => self.evaluate_170(ctx),
224 171 => self.evaluate_171(ctx),
225 172 => self.evaluate_172(ctx),
226 173 => self.evaluate_173(ctx),
227 174 => self.evaluate_174(ctx),
228 175 => self.evaluate_175(ctx),
229 176 => self.evaluate_176(ctx),
230 177 => self.evaluate_177(ctx),
231 178 => self.evaluate_178(ctx),
232 179 => self.evaluate_179(ctx),
233 180 => self.evaluate_180(ctx),
234 181 => self.evaluate_181(ctx),
235 182 => self.evaluate_182(ctx),
236 490 => self.evaluate_490(ctx),
237 491 => self.evaluate_491(ctx),
238 492 => self.evaluate_492(ctx),
239 493 => self.evaluate_493(ctx),
240 494 => self.evaluate_494(ctx),
241 495 => self.evaluate_495(ctx),
242 500 => self.evaluate_500(ctx),
243 501 => self.evaluate_501(ctx),
244 503 => self.evaluate_503(ctx),
245 506 => self.evaluate_506(ctx),
246 507 => self.evaluate_507(ctx),
247 514 => self.evaluate_514(ctx),
248 515 => self.evaluate_515(ctx),
249 517 => self.evaluate_517(ctx),
250 518 => self.evaluate_518(ctx),
251 519 => self.evaluate_519(ctx),
252 521 => self.evaluate_521(ctx),
253 522 => self.evaluate_522(ctx),
254 523 => self.evaluate_523(ctx),
255 525 => self.evaluate_525(ctx),
256 527 => self.evaluate_527(ctx),
257 530 => self.evaluate_530(ctx),
258 531 => self.evaluate_531(ctx),
259 532 => self.evaluate_532(ctx),
260 533 => self.evaluate_533(ctx),
261 535 => self.evaluate_535(ctx),
262 536 => self.evaluate_536(ctx),
263 539 => self.evaluate_539(ctx),
264 540 => self.evaluate_540(ctx),
265 542 => self.evaluate_542(ctx),
266 543 => self.evaluate_543(ctx),
267 545 => self.evaluate_545(ctx),
268 547 => self.evaluate_547(ctx),
269 548 => self.evaluate_548(ctx),
270 549 => self.evaluate_549(ctx),
271 550 => self.evaluate_550(ctx),
272 551 => self.evaluate_551(ctx),
273 552 => self.evaluate_552(ctx),
274 553 => self.evaluate_553(ctx),
275 554 => self.evaluate_554(ctx),
276 555 => self.evaluate_555(ctx),
277 557 => self.evaluate_557(ctx),
278 558 => self.evaluate_558(ctx),
279 559 => self.evaluate_559(ctx),
280 560 => self.evaluate_560(ctx),
281 561 => self.evaluate_561(ctx),
282 562 => self.evaluate_562(ctx),
283 563 => self.evaluate_563(ctx),
284 564 => self.evaluate_564(ctx),
285 566 => self.evaluate_566(ctx),
286 567 => self.evaluate_567(ctx),
287 568 => self.evaluate_568(ctx),
288 569 => self.evaluate_569(ctx),
289 570 => self.evaluate_570(ctx),
290 571 => self.evaluate_571(ctx),
291 572 => self.evaluate_572(ctx),
292 573 => self.evaluate_573(ctx),
293 574 => self.evaluate_574(ctx),
294 575 => self.evaluate_575(ctx),
295 576 => self.evaluate_576(ctx),
296 577 => self.evaluate_577(ctx),
297 578 => self.evaluate_578(ctx),
298 579 => self.evaluate_579(ctx),
299 580 => self.evaluate_580(ctx),
300 591 => self.evaluate_591(ctx),
301 592 => self.evaluate_592(ctx),
302 903 => self.evaluate_903(ctx),
303 906 => self.evaluate_906(ctx),
304 911 => self.evaluate_911(ctx),
305 914 => self.evaluate_914(ctx),
306 922 => self.evaluate_922(ctx),
307 930 => self.evaluate_930(ctx),
308 931 => self.evaluate_931(ctx),
309 932 => self.evaluate_932(ctx),
310 933 => self.evaluate_933(ctx),
311 934 => self.evaluate_934(ctx),
312 935 => self.evaluate_935(ctx),
313 939 => self.evaluate_939(ctx),
314 940 => self.evaluate_940(ctx),
315 950 => self.evaluate_950(ctx),
316 951 => self.evaluate_951(ctx),
317 955 => self.evaluate_955(ctx),
318 960 => self.evaluate_960(ctx),
319 961 => self.evaluate_961(ctx),
320 962 => self.evaluate_962(ctx),
321 967 => self.evaluate_967(ctx),
322 2001 => self.evaluate_2001(ctx),
323 2002 => self.evaluate_2002(ctx),
324 2003 => self.evaluate_2003(ctx),
325 2004 => self.evaluate_2004(ctx),
326 2005 => self.evaluate_2005(ctx),
327 2006 => self.evaluate_2006(ctx),
328 2007 => self.evaluate_2007(ctx),
329 2044 => self.evaluate_2044(ctx),
330 2050 => self.evaluate_2050(ctx),
331 2060 => self.evaluate_2060(ctx),
332 2061 => self.evaluate_2061(ctx),
333 2062 => self.evaluate_2062(ctx),
334 2063 => self.evaluate_2063(ctx),
335 2064 => self.evaluate_2064(ctx),
336 2065 => self.evaluate_2065(ctx),
337 2066 => self.evaluate_2066(ctx),
338 2088 => self.evaluate_2088(ctx),
339 2089 => self.evaluate_2089(ctx),
340 2090 => self.evaluate_2090(ctx),
341 2092 => self.evaluate_2092(ctx),
342 2094 => self.evaluate_2094(ctx),
343 2095 => self.evaluate_2095(ctx),
344 2096 => self.evaluate_2096(ctx),
345 2097 => self.evaluate_2097(ctx),
346 2098 => self.evaluate_2098(ctx),
347 2099 => self.evaluate_2099(ctx),
348 _ => ConditionResult::Unknown,
349 }
350 }
351
352 fn is_external(&self, condition: u32) -> bool {
353 self.external_conditions.contains(&condition)
354 }
355 fn is_known(&self, condition: u32) -> bool {
356 matches!(
357 condition,
358 1 | 2
359 | 6
360 | 7
361 | 9
362 | 12
363 | 13
364 | 15
365 | 16
366 | 17
367 | 18
368 | 19
369 | 21
370 | 23
371 | 24
372 | 26
373 | 27
374 | 28
375 | 29
376 | 33
377 | 34
378 | 35
379 | 36
380 | 38
381 | 45
382 | 46
383 | 47
384 | 51
385 | 54
386 | 55
387 | 56
388 | 57
389 | 60
390 | 61
391 | 62
392 | 63
393 | 64
394 | 65
395 | 67
396 | 68
397 | 69
398 | 70
399 | 76
400 | 77
401 | 78
402 | 79
403 | 80
404 | 81
405 | 82
406 | 83
407 | 84
408 | 85
409 | 86
410 | 87
411 | 91
412 | 93
413 | 94
414 | 95
415 | 96
416 | 97
417 | 99
418 | 100
419 | 101
420 | 102
421 | 103
422 | 104
423 | 105
424 | 106
425 | 107
426 | 108
427 | 109
428 | 110
429 | 112
430 | 113
431 | 114
432 | 115
433 | 117
434 | 118
435 | 119
436 | 120
437 | 121
438 | 122
439 | 123
440 | 124
441 | 125
442 | 126
443 | 127
444 | 128
445 | 129
446 | 130
447 | 131
448 | 132
449 | 133
450 | 134
451 | 135
452 | 136
453 | 137
454 | 138
455 | 139
456 | 140
457 | 141
458 | 142
459 | 143
460 | 147
461 | 148
462 | 152
463 | 153
464 | 154
465 | 155
466 | 156
467 | 157
468 | 158
469 | 159
470 | 160
471 | 161
472 | 162
473 | 163
474 | 164
475 | 165
476 | 166
477 | 167
478 | 168
479 | 169
480 | 170
481 | 171
482 | 172
483 | 173
484 | 174
485 | 175
486 | 176
487 | 177
488 | 178
489 | 179
490 | 180
491 | 181
492 | 182
493 | 490
494 | 491
495 | 492
496 | 493
497 | 494
498 | 495
499 | 500
500 | 501
501 | 503
502 | 506
503 | 507
504 | 514
505 | 515
506 | 517
507 | 518
508 | 519
509 | 521
510 | 522
511 | 523
512 | 525
513 | 527
514 | 530
515 | 531
516 | 532
517 | 533
518 | 535
519 | 536
520 | 539
521 | 540
522 | 542
523 | 543
524 | 545
525 | 547
526 | 548
527 | 549
528 | 550
529 | 551
530 | 552
531 | 553
532 | 554
533 | 555
534 | 557
535 | 558
536 | 559
537 | 560
538 | 561
539 | 562
540 | 563
541 | 564
542 | 566
543 | 567
544 | 568
545 | 569
546 | 570
547 | 571
548 | 572
549 | 573
550 | 574
551 | 575
552 | 576
553 | 577
554 | 578
555 | 579
556 | 580
557 | 591
558 | 592
559 | 903
560 | 906
561 | 911
562 | 914
563 | 922
564 | 930
565 | 931
566 | 932
567 | 933
568 | 934
569 | 935
570 | 939
571 | 940
572 | 950
573 | 951
574 | 955
575 | 960
576 | 961
577 | 962
578 | 967
579 | 2001
580 | 2002
581 | 2003
582 | 2004
583 | 2005
584 | 2006
585 | 2007
586 | 2044
587 | 2050
588 | 2060
589 | 2061
590 | 2062
591 | 2063
592 | 2064
593 | 2065
594 | 2066
595 | 2088
596 | 2089
597 | 2090
598 | 2092
599 | 2094
600 | 2095
601 | 2096
602 | 2097
603 | 2098
604 | 2099
605 )
606 }
607}
608
609impl OrdersConditionEvaluatorFV2510 {
610 /// [86] Wenn in derselben SG29 mit Z19 in LIN DE1229 (Erforderliches Produkt der Messlokation) das PIA+5 DE7140 mit einem Messprodukt aus Codeliste der Konfigurationen Kapitel 2.3.1 "Standard-Messprodukt d...
611 /// EXTERNAL: Code list membership (Konfigurationen Kapitel 2.3.1 Standard-Messprodukt der Messlokation mit der Wahlmöglichkeit der Zuordnung einer Zählzeit) lives in AHB appendix prose, not in the MIG — same pattern as [126]/[128]/[129].
612 fn evaluate_86(&self, ctx: &EvaluationContext) -> ConditionResult {
613 ctx.external
614 .evaluate("valid_messprodukt_in_standard_messprodukt_list")
615 }
616
617 /// [91] Wenn in diesem Datenelement kein anderes Paket zur Möglichkeit der Angabe von mindestens einem anderen Code führt.
618 /// EXTERNAL: AHB package meta-reasoning (whether another XOR/OR package at this DE enables a different code). Requires workflow-level package context that the per-field condition evaluator does not expose; the operator supplies the answer per PID.
619 fn evaluate_91(&self, ctx: &EvaluationContext) -> ConditionResult {
620 ctx.external
621 .evaluate("no_other_package_enables_additional_codes")
622 }
623
624 /// [126] Es sind nur die Konfigurations-Produkte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.2 „Konfigurationsprodukte Leistungskurvendefinition“ enthalten sind.
625 /// EXTERNAL: Requires context from outside the message.
626 // REVIEW: Code list membership validation: only products from 'Codeliste der Konfigurationen Kapitel 4.2 Konfigurationsprodukte Leistungskurvendefinition' are permitted in PIA DE7140 for LIN+Z65 (Erforderliches Produkt Leistungskurvendefinitionen). The allowed product codes are defined in an external AHB specification appendix, not derivable from the EDIFACT message itself. Delegated to ExternalConditionProvider. (medium confidence)
627 fn evaluate_126(&self, ctx: &EvaluationContext) -> ConditionResult {
628 ctx.external
629 .evaluate("valid_leistungskurvendefinition_product")
630 }
631
632 /// [127] Es sind nur die Konfigurations-Produkte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.3 „Konfigurationsprodukte Ad-Hoc-Steuerkanal“ enthalten sind.
633 /// EXTERNAL: Requires context from outside the message.
634 // REVIEW: Code list membership validation: only products from 'Codeliste der Konfigurationen Kapitel 4.3 Konfigurationsprodukte Ad-Hoc-Steuerkanal' are permitted in PIA DE7140 for LIN+Z66 (Erforderliches Produkt Ad-hoc-Steuerkanal). The allowed product codes are defined in an external AHB specification appendix, not derivable from the EDIFACT message itself. Delegated to ExternalConditionProvider. (medium confidence)
635 fn evaluate_127(&self, ctx: &EvaluationContext) -> ConditionResult {
636 ctx.external.evaluate("valid_adhoc_steuerkanal_product")
637 }
638
639 /// [128] Es sind nur die Messprodukte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.5 „Messprodukte für Werte nach Typ 2 aus Backend für LF und NB“ enthalten sind.
640 /// EXTERNAL: Requires context from outside the message.
641 // REVIEW: Code list membership validation: only products from 'Codeliste der Konfigurationen Kapitel 4.5 Messprodukte für Werte nach Typ 2 aus Backend für LF und NB' are permitted in PIA DE7140 for LIN+Z67 (Erforderliches Messprodukt für Werte nach Typ 2 aus Backend). The allowed product codes are defined in an external AHB specification appendix, not derivable from the EDIFACT message itself. Delegated to ExternalConditionProvider. (medium confidence)
642 fn evaluate_128(&self, ctx: &EvaluationContext) -> ConditionResult {
643 ctx.external.evaluate("valid_messprodukt_typ2_backend")
644 }
645
646 /// [129] Es sind nur die Messprodukte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.4 „Messprodukte mit Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW“ enthalten sind.
647 /// EXTERNAL: Requires context from outside the message.
648 fn evaluate_129(&self, ctx: &EvaluationContext) -> ConditionResult {
649 ctx.external
650 .evaluate("messprodukt_in_smgw_typ2_konfigurationsliste")
651 }
652
653 /// [141] Es sind nur die Messprodukt-Position-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.7 „Art der Werte für Messprodukte nach Typ 2“ enthalten sind.
654 /// EXTERNAL: Requires context from outside the message.
655 fn evaluate_141(&self, ctx: &EvaluationContext) -> ConditionResult {
656 ctx.external
657 .evaluate("messprodukt_position_code_in_typ2_art_der_werte_liste")
658 }
659
660 /// [142] Wenn innerhalb derselben SG29 LIN im PIA+5 DE7140 (Erforderliches Produkt Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW) ein Produkt angegeben ist, das in der Codeliste der Konfigurationen...
661 /// EXTERNAL: Requires context from outside the message.
662 fn evaluate_142(&self, ctx: &EvaluationContext) -> ConditionResult {
663 ctx.external
664 .evaluate("smgw_konfigurationsprodukt_ausloeser_schwellwert")
665 }
666
667 /// [143] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Steuerbaren Ressource angegeben ist
668 /// EXTERNAL: Requires context from outside the message.
669 fn evaluate_143(&self, ctx: &EvaluationContext) -> ConditionResult {
670 ctx.external
671 .evaluate("meldepunkt_is_steuerbare_ressource_id")
672 }
673
674 /// [152] Wenn in SG29 LIN (Erforderliches Produkt der Messlokation) das PIA+5 DE7140 mit einem Produkt-Code vorhanden ist der in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer...
675 /// EXTERNAL: Requires context from outside the message.
676 fn evaluate_152(&self, ctx: &EvaluationContext) -> ConditionResult {
677 ctx.external
678 .evaluate("messlokationsprodukt_hat_weitere_energieflussrichtung")
679 }
680
681 /// [165] Wenn die Konfiguration der in SG34 RFF+Z20 DE1154 (Referenz auf ID der Tranche) genannte Tranche innerhalb derselben SG29 LIN++Z16 (Erforderliches Produkt der Tranche) aufgrund einer Zuordnung eine...
682 /// EXTERNAL: Requires context from outside the message.
683 fn evaluate_165(&self, ctx: &EvaluationContext) -> ConditionResult {
684 ctx.external
685 .evaluate("tranche_reconfiguration_or_new_formation")
686 }
687
688 /// [166] Wenn es sich um die Einrichtung der Konfigurationen aufgrund einer Zuordnung eines LF zu einer Tranche handelt
689 /// EXTERNAL: Requires context from outside the message.
690 fn evaluate_166(&self, ctx: &EvaluationContext) -> ConditionResult {
691 ctx.external
692 .evaluate("configuration_setup_due_to_lf_tranche_assignment")
693 }
694
695 /// [172] Wenn es sich bei der in SG2 LOC+172 DE3225 genannten Lokation um die Integration in eine Kundenanlage oder Herauslösung aus einer Kundenanlage nach §20 Abs.1d EnWG handelt. Details siehe UTILMD A...
696 // REVIEW: LOC+172 in SG2 is the Meldepunkt qualifier, which in the ORDERS MIG is exclusively used for Kundenanlage integration/dissolution scenarios per §20 Abs.1d EnWG. Presence of LOC+172 in SG2 is the EDIFACT-level indicator for this context; the AHB cross-reference to UTILMD AHB Strom describes the same structural signal. (medium confidence)
697 fn evaluate_172(&self, ctx: &EvaluationContext) -> ConditionResult {
698 ctx.has_qualifier("LOC", 0, "172")
699 }
700
701 /// [178] Wenn vom NB eine Abtretungserklärung vom Kunden gewünscht ist.
702 /// EXTERNAL: Requires context from outside the message.
703 fn evaluate_178(&self, ctx: &EvaluationContext) -> ConditionResult {
704 ctx.external.evaluate("nb_requests_assignment_declaration")
705 }
706
707 /// [179] Wenn in derselben SG29 LIN im PIA+5 (Erforderliches Produkt Abrechnungsdaten) DE7140 das Produkt "Empfänger der Vergütung zur Einspeisung" aus der Codeliste der Konfigurationen im Kapitel 6.2 "Pr...
708 /// EXTERNAL: Requires context from outside the message.
709 fn evaluate_179(&self, ctx: &EvaluationContext) -> ConditionResult {
710 ctx.external
711 .evaluate("abrechnungsdaten_einspeisung_lieferant")
712 }
713
714 /// [180] Wenn in derselben SG29 LIN im PIA+5 (Erforderliches Produkt Abrechnungsdaten) DE7140 ein Produkt-Code genannt ist der in der Codeliste der Konfigurationen im Kapitel 6.2 "Produkte zur Bestellung ei...
715 /// EXTERNAL: Requires context from outside the message.
716 fn evaluate_180(&self, ctx: &EvaluationContext) -> ConditionResult {
717 ctx.external
718 .evaluate("product_code_in_abrechnungsdaten_list")
719 }
720
721 /// [181] Wenn BGM+Z93 (Bestellung eines Angebots Änderung der Technik der Lokation) vorhanden
722 fn evaluate_181(&self, ctx: &EvaluationContext) -> ConditionResult {
723 ctx.has_qualifier("BGM", 0, "Z93")
724 }
725
726 /// [182] Wenn BGM+Z12 (Änderung der Technik der Lokation) vorhanden.
727 fn evaluate_182(&self, ctx: &EvaluationContext) -> ConditionResult {
728 ctx.has_qualifier("BGM", 0, "Z12")
729 }
730
731 /// [577] Hinweis: Wert aus BGM+Z93 (Bestellung eines Angebots Änderung der Technik der Lokation) DE1004 der QUOTES mit der das Angebot erfolgt ist.
732 fn evaluate_577(&self, _ctx: &EvaluationContext) -> ConditionResult {
733 // Hinweis: Wert aus BGM+Z93 (Bestellung eines Angebots Änderung der Technik der Lokation) DE1004 der QUOTES mit der das Angebot erfolgt ist — informational note, always applies
734 ConditionResult::True
735 }
736
737 /// [578] Hinweis: Wert aus BGM DE1004 der PRICAT mit der das Preisblatt B des MSB, auf die aus Sicht des NB das Angebot basiert, übermittelt wurde.
738 fn evaluate_578(&self, _ctx: &EvaluationContext) -> ConditionResult {
739 // Hinweis: Wert aus BGM DE1004 der PRICAT mit der das Preisblatt B des MSB übermittelt wurde — informational note, always applies
740 ConditionResult::True
741 }
742
743 /// [579] Hinweis: Angabe des Beginnzeitpunkts des gewünschten Umsetzungstermins aus Sicht des Bestellers.
744 fn evaluate_579(&self, _ctx: &EvaluationContext) -> ConditionResult {
745 // Hinweis: Angabe des Beginnzeitpunkts des gewünschten Umsetzungstermins aus Sicht des Bestellers.
746 // Informational note, always applies.
747 ConditionResult::True
748 }
749
750 /// [580] Hinweis: Angabe des Endezeitpunkts des gewünschten Umsetzungstermins aus Sicht des Bestellers.
751 fn evaluate_580(&self, _ctx: &EvaluationContext) -> ConditionResult {
752 // Hinweis: Angabe des Endezeitpunkts des gewünschten Umsetzungstermins aus Sicht des Bestellers.
753 // Informational note, always applies.
754 ConditionResult::True
755 }
756
757 /// [591] Hinweis: Wenn es sich um die Bestellung eines vorherigen Angebots im Rahmen der BDEW Anwendungshilfe "Prozesse zur Änderung der Technik an Lokationen" handelt.
758 fn evaluate_591(&self, _ctx: &EvaluationContext) -> ConditionResult {
759 // Hinweis: Wenn es sich um die Bestellung eines vorherigen Angebots im Rahmen der BDEW Anwendungshilfe handelt.
760 // Informational note, always applies.
761 ConditionResult::True
762 }
763
764 /// [592] Hinweis: wenn es sich um die Beauftragung einer Änderung gemäß WiM Teil1 UC "Messlokationsänderung" handelt.
765 fn evaluate_592(&self, _ctx: &EvaluationContext) -> ConditionResult {
766 // Hinweis: wenn es sich um die Beauftragung einer Änderung gemäß WiM Teil1 UC "Messlokationsänderung" handelt.
767 // Informational note, always applies.
768 ConditionResult::True
769 }
770
771 /// [967] Format: Zertifikatskörper gemäß X509.1, BSI TR-03109-4
772 fn evaluate_967(&self, ctx: &EvaluationContext) -> ConditionResult {
773 // Structural check on the certificate body (base64 charset + plausible
774 // length). Cryptographic validation (signature, CA, BSI profile) is
775 // out of scope for static AHB validation.
776 match ctx.resolved_value {
777 Some(val) => validate_x509_cert_body(val),
778 None => ConditionResult::Unknown,
779 }
780 }
781
782 /// [2001] Die SG29 ist so oft zu wiederholen, wie ab dem DTM+203 (Ausführungsdatum) Tranchen zu der in der SG2 genannten Marktlokation vorhanden sind.
783 fn evaluate_2001(&self, _ctx: &EvaluationContext) -> ConditionResult {
784 // Hinweis: SG29 ist so oft zu wiederholen, wie ab dem DTM+203 (Ausführungsdatum) Tranchen zu der in der SG2 genannten Marktlokation vorhanden sind — informational cardinality annotation, always applies
785 ConditionResult::True
786 }
787
788 /// [2065] Diese SG30 ist so oft zu wiederholen, wie zu den unterschiedlichen Messprodukt-Position-Codes zu dem innerhalb derselben SG29 LIN im PIA+5 DE7140 (Erforderliches Produkt Konfigurationserlaubnis fü...
789 fn evaluate_2065(&self, _ctx: &EvaluationContext) -> ConditionResult {
790 // Hinweis: SG30 ist so oft zu wiederholen, wie unterschiedliche Messprodukt-Position-Codes für das in SG29 PIA+5 DE7140 angegebene Produkt vorhanden sind, die in der Codeliste Kapitel 4.4 mit 'Bei Schwellwertunter- / -überschreitung' gekennzeichnet sind — informational cardinality annotation referencing external code list, always applies
791 ConditionResult::True
792 }
793
794 /// [1] Wenn IMD+Z03 vorhanden
795 fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
796 ctx.has_qualifier("IMD", 0, "Z03")
797 }
798
799 /// [2] Wenn BGM+7 vorhanden
800 fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
801 ctx.has_qualifier("BGM", 0, "7")
802 }
803
804 /// [6] Wenn MP-ID in SG2 NAD+MS mit Rolle LF vorhanden
805 /// EXTERNAL: Requires context from outside the message.
806 fn evaluate_6(&self, ctx: &EvaluationContext) -> ConditionResult {
807 ctx.external.evaluate("sender_is_lf")
808 }
809
810 /// [7] Wenn MP-ID in SG2 NAD+MS mit Rolle NB vorhanden
811 /// EXTERNAL: Requires context from outside the message.
812 fn evaluate_7(&self, ctx: &EvaluationContext) -> ConditionResult {
813 ctx.external.evaluate("sender_is_nb")
814 }
815
816 /// [9] Wenn bekannt
817 /// EXTERNAL: Requires context from outside the message.
818 // REVIEW: 'Wenn bekannt' (when known) depends on whether a value is known in the business context — cannot be derived from EDIFACT segments alone. (medium confidence)
819 fn evaluate_9(&self, ctx: &EvaluationContext) -> ConditionResult {
820 ctx.external.evaluate("information_is_known")
821 }
822
823 /// [12] Wenn vorhanden
824 // REVIEW: Condition 12 'Wenn vorhanden' is a generic self-referential meta-condition indicating that the attached validation rule applies whenever the field is populated. The validator framework handles actual presence detection; this evaluator simply returns True to indicate the rule is always applicable when invoked. (medium confidence)
825 fn evaluate_12(&self, _ctx: &EvaluationContext) -> ConditionResult {
826 // Wenn vorhanden — generic 'when present' meta-condition
827 // In AHB context this means: validation applies whenever the field is populated.
828 // Returning True here defers the presence check to the validator framework itself.
829 ConditionResult::True
830 }
831
832 /// [13] Wenn SG2 LOC+172 nicht vorhanden
833 fn evaluate_13(&self, ctx: &EvaluationContext) -> ConditionResult {
834 ctx.lacks_qualifier("LOC", 0, "172")
835 }
836
837 /// [15] Wenn MP-ID in SG2 NAD+MS mit Rolle MSB vorhanden
838 /// EXTERNAL: Requires context from outside the message.
839 fn evaluate_15(&self, ctx: &EvaluationContext) -> ConditionResult {
840 ctx.external.evaluate("sender_is_msb")
841 }
842
843 /// [16] Wenn eine untergeordnete SG vorhanden
844 /// EXTERNAL: Requires context from outside the message.
845 // REVIEW: Generic structural condition: 'if a subordinate SG is present'. Depends entirely on which child segment group is being checked in context — the condition number is reused across many segment rows with different child SGs. Cannot be resolved from the EDIFACT message content alone; requires the validation framework to supply structural position context. (medium confidence)
846 fn evaluate_16(&self, ctx: &EvaluationContext) -> ConditionResult {
847 ctx.external.evaluate("subordinate_sg_present")
848 }
849
850 /// [17] Wenn ein Segment innerhalb der SG vorhanden
851 /// EXTERNAL: Requires context from outside the message.
852 // REVIEW: Generic structural condition: 'if a segment within the SG is present'. Like [16], this condition number is reused across many rows and the specific segment being checked depends on the validation context. Cannot determine which segment to check without positional context supplied externally. (medium confidence)
853 fn evaluate_17(&self, ctx: &EvaluationContext) -> ConditionResult {
854 ctx.external.evaluate("segment_within_sg_present")
855 }
856
857 /// [18] Wenn IMD++Z11 vorhanden
858 fn evaluate_18(&self, ctx: &EvaluationContext) -> ConditionResult {
859 let imds = ctx.find_segments("IMD");
860 ConditionResult::from(imds.iter().any(|s| {
861 s.elements
862 .get(1)
863 .and_then(|e| e.first())
864 .is_some_and(|v| v == "Z11")
865 }))
866 }
867
868 /// [19] Wenn IMD++Z12 vorhanden
869 fn evaluate_19(&self, ctx: &EvaluationContext) -> ConditionResult {
870 let imds = ctx.find_segments("IMD");
871 ConditionResult::from(imds.iter().any(|s| {
872 s.elements
873 .get(1)
874 .and_then(|e| e.first())
875 .is_some_and(|v| v == "Z12")
876 }))
877 }
878
879 /// [21] Wenn BGM+Z28 vorhanden
880 fn evaluate_21(&self, ctx: &EvaluationContext) -> ConditionResult {
881 ctx.has_qualifier("BGM", 0, "Z28")
882 }
883
884 /// [23] Wenn MP-ID in SG2 NAD+MR mit Rolle NB vorhanden
885 /// EXTERNAL: Requires context from outside the message.
886 fn evaluate_23(&self, ctx: &EvaluationContext) -> ConditionResult {
887 ctx.external.evaluate("recipient_is_nb")
888 }
889
890 /// [24] Wenn IMD++Z35 vorhanden
891 fn evaluate_24(&self, ctx: &EvaluationContext) -> ConditionResult {
892 let imds = ctx.find_segments("IMD");
893 ConditionResult::from(imds.iter().any(|s| {
894 s.elements
895 .get(1)
896 .and_then(|e| e.first())
897 .is_some_and(|v| v == "Z35")
898 }))
899 }
900
901 /// [26] Wenn MP-ID in SG2 NAD+MS mit Rolle ÜNB vorhanden
902 /// EXTERNAL: Requires context from outside the message.
903 // REVIEW: Whether the NAD+MS market participant holds the role ÜNB (Übertragungsnetzbetreiber) cannot be determined from the EDIFACT message content alone. The role is a business context attribute of the MP-ID that requires an external master data lookup (e.g. Marktstammdatenregister or internal role registry). Marked external with name 'sender_is_uenb'. (medium confidence)
904 fn evaluate_26(&self, ctx: &EvaluationContext) -> ConditionResult {
905 ctx.external.evaluate("sender_is_uenb")
906 }
907
908 /// [27] Wenn MP-ID in SG2 NAD+MR mit Rolle MSB vorhanden
909 /// EXTERNAL: Requires context from outside the message.
910 // REVIEW: Whether the NAD+MR market participant holds the role MSB (Messstellenbetreiber) cannot be determined from the EDIFACT message content alone. The role is a business context attribute of the MP-ID requiring external master data. Marked external with name 'recipient_is_msb'. (medium confidence)
911 fn evaluate_27(&self, ctx: &EvaluationContext) -> ConditionResult {
912 ctx.external.evaluate("recipient_is_msb")
913 }
914
915 /// [28] Wenn MP-ID in SG2 NAD+MR aus Sparte Strom
916 /// EXTERNAL: Requires context from outside the message.
917 fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
918 ctx.external.evaluate("recipient_market_sector_is_strom")
919 }
920
921 /// [29] Wenn MP-ID in SG2 NAD+MR aus Sparte Gas
922 /// EXTERNAL: Requires context from outside the message.
923 fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
924 ctx.external.evaluate("recipient_market_sector_is_gas")
925 }
926
927 /// [33] Wenn IMD+Z01 vorhanden
928 fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
929 ctx.has_qualifier("IMD", 1, "Z01")
930 }
931
932 /// [34] Wenn IMD+Z02 vorhanden
933 fn evaluate_34(&self, ctx: &EvaluationContext) -> ConditionResult {
934 ctx.has_qualifier("IMD", 1, "Z02")
935 }
936
937 /// [35] IMD++Z14+Z06 vorhanden
938 fn evaluate_35(&self, ctx: &EvaluationContext) -> ConditionResult {
939 let imds = ctx.find_segments("IMD");
940 let found = imds.iter().any(|s| {
941 let has_z14 = s
942 .elements
943 .get(1)
944 .and_then(|e| e.first())
945 .is_some_and(|v| v == "Z14");
946 let has_z06 = s
947 .elements
948 .get(2)
949 .and_then(|e| e.first())
950 .is_some_and(|v| v == "Z06");
951 has_z14 && has_z06
952 });
953 ConditionResult::from(found)
954 }
955
956 /// [36] Wenn MP-ID in SG2 NAD+MR mit Rolle NB nicht vorhanden
957 /// EXTERNAL: Requires context from outside the message.
958 fn evaluate_36(&self, ctx: &EvaluationContext) -> ConditionResult {
959 ctx.external.evaluate("recipient_role_is_not_nb")
960 }
961
962 /// [38] Wenn FTX+Z04/Z05 vorhanden
963 fn evaluate_38(&self, ctx: &EvaluationContext) -> ConditionResult {
964 let found = ctx.find_segments("FTX").iter().any(|s| {
965 s.elements
966 .first()
967 .and_then(|e| e.first())
968 .is_some_and(|v| v == "Z04" || v == "Z05")
969 });
970 ConditionResult::from(found)
971 }
972
973 /// [45] Wenn MP-ID in SG2 NAD+MS mit Rolle MSB nicht vorhanden
974 /// EXTERNAL: Requires context from outside the message.
975 fn evaluate_45(&self, ctx: &EvaluationContext) -> ConditionResult {
976 ctx.external.evaluate("sender_role_is_not_msb")
977 }
978
979 /// [46] Wenn SG29 IMD++Z46 vorhanden
980 fn evaluate_46(&self, ctx: &EvaluationContext) -> ConditionResult {
981 ctx.has_qualifier("IMD", 1, "Z46")
982 }
983
984 /// [47] Wenn SG29 IMD++Z46 nicht vorhanden
985 fn evaluate_47(&self, ctx: &EvaluationContext) -> ConditionResult {
986 ctx.lacks_qualifier("IMD", 1, "Z46")
987 }
988
989 /// [51] Wenn BGM+Z48 vorhanden
990 fn evaluate_51(&self, ctx: &EvaluationContext) -> ConditionResult {
991 ctx.has_qualifier("BGM", 0, "Z48")
992 }
993
994 /// [54] Wenn FTX+Z06 vorhanden
995 fn evaluate_54(&self, ctx: &EvaluationContext) -> ConditionResult {
996 ctx.has_qualifier("FTX", 0, "Z06")
997 }
998
999 /// [55] Wenn DTM+469 (Beginn zum nächstmöglichen Termin) nicht vorhanden
1000 fn evaluate_55(&self, ctx: &EvaluationContext) -> ConditionResult {
1001 ctx.lacks_qualifier("DTM", 0, "469")
1002 }
1003
1004 /// [56] Wenn DTM+203 (Ausführungsdatum) nicht vorhanden
1005 fn evaluate_56(&self, ctx: &EvaluationContext) -> ConditionResult {
1006 ctx.lacks_qualifier("DTM", 0, "203")
1007 }
1008
1009 /// [57] Wenn im selben SG2 NAD DE3124 nicht vorhanden
1010 // REVIEW: Checks if any NAD segment in the message lacks DE3124 (C058 at elements[2][0]). 'Im selben SG2' requires group context; falls back to message-wide check. DE3124 is the first component of C058 (Zeile für Name und Anschrift / Zusatzinfo). (medium confidence)
1011 fn evaluate_57(&self, ctx: &EvaluationContext) -> ConditionResult {
1012 let nads = ctx.find_segments("NAD");
1013 if nads.is_empty() {
1014 return ConditionResult::Unknown;
1015 }
1016 let any_without = nads.iter().any(|nad| {
1017 nad.elements
1018 .get(2)
1019 .and_then(|e| e.first())
1020 .map(|v| v.is_empty())
1021 .unwrap_or(true)
1022 });
1023 ConditionResult::from(any_without)
1024 }
1025
1026 /// [60] MP-ID nur aus Sparte Gas
1027 /// EXTERNAL: Requires context from outside the message.
1028 fn evaluate_60(&self, ctx: &EvaluationContext) -> ConditionResult {
1029 ctx.external.evaluate("market_location_is_gas")
1030 }
1031
1032 /// [61] MP-ID nur aus Sparte Strom
1033 /// EXTERNAL: Requires context from outside the message.
1034 fn evaluate_61(&self, ctx: &EvaluationContext) -> ConditionResult {
1035 ctx.external.evaluate("market_location_is_electricity")
1036 }
1037
1038 /// [62] MP-ID mit Rolle MSB
1039 /// EXTERNAL: Requires context from outside the message.
1040 fn evaluate_62(&self, ctx: &EvaluationContext) -> ConditionResult {
1041 ctx.external.evaluate("sender_is_msb")
1042 }
1043
1044 /// [63] MP-ID mit Rolle NB
1045 /// EXTERNAL: Requires context from outside the message.
1046 fn evaluate_63(&self, ctx: &EvaluationContext) -> ConditionResult {
1047 ctx.external.evaluate("sender_is_nb")
1048 }
1049
1050 /// [64] Wenn SG2 NAD+Z03 nicht vorhanden
1051 fn evaluate_64(&self, ctx: &EvaluationContext) -> ConditionResult {
1052 ctx.lacks_qualifier("NAD", 0, "Z03")
1053 }
1054
1055 /// [65] Wenn FTX+Z08 vorhanden
1056 fn evaluate_65(&self, ctx: &EvaluationContext) -> ConditionResult {
1057 ctx.has_qualifier("FTX", 0, "Z08")
1058 }
1059
1060 /// [67] Wenn DTM+163 nicht vorhanden
1061 fn evaluate_67(&self, ctx: &EvaluationContext) -> ConditionResult {
1062 ctx.lacks_qualifier("DTM", 0, "163")
1063 }
1064
1065 /// [68] Wenn DTM+7 nicht vorhanden
1066 fn evaluate_68(&self, ctx: &EvaluationContext) -> ConditionResult {
1067 ctx.lacks_qualifier("DTM", 0, "7")
1068 }
1069
1070 /// [69] Wenn NAD+Z23 nicht vorhanden
1071 fn evaluate_69(&self, ctx: &EvaluationContext) -> ConditionResult {
1072 ctx.lacks_qualifier("NAD", 0, "Z23")
1073 }
1074
1075 /// [70] Wenn NAD+Z03 nicht vorhanden
1076 fn evaluate_70(&self, ctx: &EvaluationContext) -> ConditionResult {
1077 ctx.lacks_qualifier("NAD", 0, "Z03")
1078 }
1079
1080 /// [76] Wenn in derselben SG29 mit Z54 in LIN DE1229 (Erforderliches Produkt der Marktlokation) das PIA+5 DE7140 mit einem Messprodukt aus Codeliste der Konfigurationen Kapitel 2.1.1 "Standard-Messprodukt ...
1081 /// EXTERNAL: Requires context from outside the message.
1082 fn evaluate_76(&self, ctx: &EvaluationContext) -> ConditionResult {
1083 ctx.external
1084 .evaluate("pia_product_in_standard_messprodukt_wahlmoeglichkeit_list")
1085 }
1086
1087 /// [77] Wenn im selben CCI im DE7059 der Code Z39 (Code der Zählzeitdefinition) vorhanden ist
1088 // REVIEW: Checks if a CCI segment in the same SG29 group has DE7059 == 'Z39' (Code der Zählzeitdefinition). DE7059 is the class/type code at elements[0][0] in CCI. Group-scoped to SG29 with message-wide fallback. (medium confidence)
1089 fn evaluate_77(&self, ctx: &EvaluationContext) -> ConditionResult {
1090 ctx.any_group_has_qualifier("CCI", 0, "Z39", &["SG29"])
1091 }
1092
1093 /// [78] Wenn in derselben SG29 mit Z55 in LIN DE1229 (Erforderliches Produkt der Netzlokation) das PIA+5 DE7140 mit einem Messprodukt aus Codeliste der Konfigurationen, Kapitel 2 „Codeliste der Standard-...
1094 /// EXTERNAL: Requires context from outside the message.
1095 // REVIEW: Requires checking PIA DE7140 against an external code list from 'Codeliste der Konfigurationen, Kapitel 2 – Codeliste der Standard-Messprodukt Strom für Werte nach Typ 1' filtered to those with the Werteigenschaft 'Blindarbeit'. The structural check (LIN Z55 + PIA+5 in same SG29) is possible via navigator, but the code list membership for 'Blindarbeit' products is an external reference that cannot be determined from the EDIFACT message alone. (medium confidence)
1096 fn evaluate_78(&self, ctx: &EvaluationContext) -> ConditionResult {
1097 ctx.external
1098 .evaluate("pia_has_blindarbeit_product_netzlokation")
1099 }
1100
1101 /// [79] Wenn eine andere SG29 mit Z54 in LIN DE1229 (Erforderliches Produkt der Marktlokation) mit PIA+5+9991000000078:Z11 (für Wirkarbeit Lastgang 1/4 stündlich) vorhanden ist
1102 // REVIEW: Checks if any SG29 instance contains both LIN with Z54 at elements[1][0] and PIA with product code 9991000000078 at elements[1][0]. The 'another SG29' nuance is approximated as 'any SG29' since we have no current-group context. (medium confidence)
1103 fn evaluate_79(&self, ctx: &EvaluationContext) -> ConditionResult {
1104 ctx.any_group_has_co_occurrence(
1105 "LIN",
1106 1,
1107 &["Z54"],
1108 "PIA",
1109 1,
1110 0,
1111 &["9991000000078"],
1112 &["SG29"],
1113 )
1114 }
1115
1116 /// [80] Wenn keine andere SG29 mit Z54 in LIN DE1229 (Erforderliches Produkt der Marktlokation) mit PIA+5+9991000000078:Z11 (Wirkarbeit Lastgang 1/4 stündlich) vorhanden ist
1117 // REVIEW: Negation of condition 79 — no SG29 with LIN+Z54 AND PIA product 9991000000078. (medium confidence)
1118 fn evaluate_80(&self, ctx: &EvaluationContext) -> ConditionResult {
1119 match ctx.any_group_has_co_occurrence(
1120 "LIN",
1121 1,
1122 &["Z54"],
1123 "PIA",
1124 1,
1125 0,
1126 &["9991000000078"],
1127 &["SG29"],
1128 ) {
1129 ConditionResult::True => ConditionResult::False,
1130 ConditionResult::False => ConditionResult::True,
1131 ConditionResult::Unknown => ConditionResult::Unknown,
1132 }
1133 }
1134
1135 /// [81] Wenn in derselben SG29 mit Z54 in LIN DE1229 (Erforderliches Produkt der Marktlokation), das PIA+5+9991000000078:Z11 (Wirkarbeit Lastgang 1/4 stündlich) vorhanden ist
1136 // REVIEW: Group-scoped co-occurrence in the same SG29: LIN with Z54 at elements[1][0] AND PIA with product code 9991000000078 at elements[1][0]. Functionally equivalent to condition 79 since the API checks within the same group instance. (medium confidence)
1137 fn evaluate_81(&self, ctx: &EvaluationContext) -> ConditionResult {
1138 ctx.any_group_has_co_occurrence(
1139 "LIN",
1140 1,
1141 &["Z54"],
1142 "PIA",
1143 1,
1144 0,
1145 &["9991000000078"],
1146 &["SG29"],
1147 )
1148 }
1149
1150 /// [82] Wenn eine andere SG29 mit Z54 in LIN DE1229 (Erforderliches Produkt der Marktlokation) mit PIA+5 DE7140 mit einem Messprodukt aus Codeliste der Konfigurationen, Kapitel 2.1.1 „Standard-Messproduk...
1151 /// EXTERNAL: Requires context from outside the message.
1152 // REVIEW: Requires: (1) finding ANOTHER SG29 (not the current one) where LIN DE1229 = Z54, (2) that SG29 also has PIA+5, and (3) PIA DE7140 is from 'Codeliste der Konfigurationen, Kapitel 2.1.1 – Standard-Messprodukt der Marktlokation mit der Wahlmöglichkeit der Zuordnung einer Zählzeit'. The code list membership is external and cannot be determined from the EDIFACT message alone. (medium confidence)
1153 fn evaluate_82(&self, ctx: &EvaluationContext) -> ConditionResult {
1154 ctx.external
1155 .evaluate("other_sg29_z54_with_zaehlzeit_product")
1156 }
1157
1158 /// [83] Wenn keine andere SG29 mit Z54 in LIN DE1229 (Erforderliches Produkt der Marktlokation) mit PIA+5 DE7140 mit einem Messprodukt aus Codeliste der Konfigurationen Kapitel 2.1.1 „Standard-Messproduk...
1159 // REVIEW: Logical negation of condition [82]: 'wenn KEINE andere SG29 mit Z54 ... vorhanden ist'. Implemented by inverting the external result for [82]. Returns Unknown when the underlying external condition is Unknown (e.g., code list not available). (medium confidence)
1160 fn evaluate_83(&self, ctx: &EvaluationContext) -> ConditionResult {
1161 match ctx
1162 .external
1163 .evaluate("other_sg29_z54_with_zaehlzeit_product")
1164 {
1165 ConditionResult::True => ConditionResult::False,
1166 ConditionResult::False => ConditionResult::True,
1167 ConditionResult::Unknown => ConditionResult::Unknown,
1168 }
1169 }
1170
1171 /// [84] IMD++Z14+Z07 vorhanden
1172 // REVIEW: Checks for IMD segment where elements[1][0]='Z14' (item characteristic) and elements[2][0]='Z07' (item description code). IMD++Z14+Z07 maps directly to these positions. (medium confidence)
1173 fn evaluate_84(&self, ctx: &EvaluationContext) -> ConditionResult {
1174 {
1175 let segments = ctx.find_segments("IMD");
1176 ConditionResult::from(segments.iter().any(|s| {
1177 s.elements
1178 .get(1)
1179 .and_then(|e| e.first())
1180 .is_some_and(|v| v == "Z14")
1181 && s.elements
1182 .get(2)
1183 .and_then(|e| e.first())
1184 .is_some_and(|v| v == "Z07")
1185 }))
1186 }
1187 }
1188
1189 /// [85] Wenn in derselben SG29 mit Z54 in LIN DE1229 (Erforderliches Produkt der Marktlokation), das PIA+5+9991000000086:Z11 (Wirkarbeit höchste 1/4 Stunde im Monat) vorhanden ist
1190 // REVIEW: Group-scoped co-occurrence in SG29: LIN with Z54 at elements[1][0] AND PIA with product code 9991000000086 (Wirkarbeit höchste 1/4 Stunde im Monat) at elements[1][0]. (medium confidence)
1191 fn evaluate_85(&self, ctx: &EvaluationContext) -> ConditionResult {
1192 ctx.any_group_has_co_occurrence(
1193 "LIN",
1194 1,
1195 &["Z54"],
1196 "PIA",
1197 1,
1198 0,
1199 &["9991000000086"],
1200 &["SG29"],
1201 )
1202 }
1203
1204 /// [87] Wenn FTX+Z09/Z10 vorhanden
1205 fn evaluate_87(&self, ctx: &EvaluationContext) -> ConditionResult {
1206 {
1207 let segs = ctx.find_segments("FTX");
1208 ConditionResult::from(segs.iter().any(|s| {
1209 s.elements
1210 .first()
1211 .and_then(|e| e.first())
1212 .is_some_and(|v| v == "Z09" || v == "Z10")
1213 }))
1214 }
1215 }
1216
1217 /// [93] Wenn in derselben Nachricht eine SG29 mit Z16 in LIN DE1229 (Erforderliches Produkt der Tranche) nicht vorhanden
1218 fn evaluate_93(&self, ctx: &EvaluationContext) -> ConditionResult {
1219 ctx.lacks_qualifier("LIN", 1, "Z16")
1220 }
1221
1222 /// [94] Wenn in derselben Nachricht eine SG29 mit Z54 in LIN DE1229 (Erforderliches Produkt der Marktlokation) nicht vorhanden
1223 fn evaluate_94(&self, ctx: &EvaluationContext) -> ConditionResult {
1224 ctx.lacks_qualifier("LIN", 1, "Z54")
1225 }
1226
1227 /// [95] Messprodukt-Code aus dem Kapitel 2.1 "Standard-Messprodukte der Marktlokation" der Codeliste der Konfigurationen
1228 /// EXTERNAL: Requires context from outside the message.
1229 fn evaluate_95(&self, ctx: &EvaluationContext) -> ConditionResult {
1230 ctx.external.evaluate("messprodukt_standard_marktlokation")
1231 }
1232
1233 /// [96] Messprodukt-Code aus dem Kapitel 2.2 "Standard-Messprodukte der Tranche" der Codeliste der Konfigurationen
1234 /// EXTERNAL: Requires context from outside the message.
1235 fn evaluate_96(&self, ctx: &EvaluationContext) -> ConditionResult {
1236 ctx.external.evaluate("messprodukt_standard_tranche")
1237 }
1238
1239 /// [97] Wenn FTX+Z10 vorhanden
1240 fn evaluate_97(&self, ctx: &EvaluationContext) -> ConditionResult {
1241 ctx.has_qualifier("FTX", 0, "Z10")
1242 }
1243
1244 /// [99] Wenn FTX+Z08/Z10 vorhanden
1245 fn evaluate_99(&self, ctx: &EvaluationContext) -> ConditionResult {
1246 ctx.any_group_has_any_qualifier("FTX", 0, &["Z08", "Z10"], &["SG29"])
1247 }
1248
1249 /// [100] Messprodukt-Code aus dem Kapitel 2.3 "Standard-Messprodukte der Messlokation" der Codeliste der Konfigurationen
1250 /// EXTERNAL: Requires context from outside the message.
1251 fn evaluate_100(&self, ctx: &EvaluationContext) -> ConditionResult {
1252 ctx.external.evaluate("messprodukt_standard_messlokation")
1253 }
1254
1255 /// [101] Wenn MP-ID in SG2 NAD+MR mit Rolle MSB in der Sparte Gas nicht vorhanden
1256 /// EXTERNAL: Requires context from outside the message.
1257 // REVIEW: Checking whether the NAD+MR recipient has role MSB in Sparte Gas requires external business context about market participant roles — not determinable from message content alone. (medium confidence)
1258 fn evaluate_101(&self, ctx: &EvaluationContext) -> ConditionResult {
1259 ctx.external.evaluate("recipient_is_msb_gas")
1260 }
1261
1262 /// [102] Wenn in derselben SG29 LIN das CCI+++Z25 (Geräteart Wandler) vorhanden
1263 fn evaluate_102(&self, ctx: &EvaluationContext) -> ConditionResult {
1264 ctx.any_group_has_qualifier("CCI", 2, "Z25", &["SG29"])
1265 }
1266
1267 /// [103] Wenn in derselben SG29 LIN das CCI+++Z25 (Geräteart Wandler) nicht vorhanden
1268 fn evaluate_103(&self, ctx: &EvaluationContext) -> ConditionResult {
1269 match ctx.any_group_has_qualifier("CCI", 2, "Z25", &["SG29"]) {
1270 ConditionResult::True => ConditionResult::False,
1271 ConditionResult::False => ConditionResult::True,
1272 ConditionResult::Unknown => ConditionResult::Unknown,
1273 }
1274 }
1275
1276 /// [104] Wenn MP-ID in SG2 NAD+VY mit Rolle LF vorhanden
1277 /// EXTERNAL: Requires context from outside the message.
1278 // REVIEW: Checking whether the NAD+VY party has role LF requires external market participant role context — cannot be determined from the EDIFACT message alone. (medium confidence)
1279 fn evaluate_104(&self, ctx: &EvaluationContext) -> ConditionResult {
1280 ctx.external.evaluate("nad_vy_is_lf")
1281 }
1282
1283 /// [105] Wenn die bisherige Konfiguration mit Zählzeiten des LF vom LF beendet werden soll
1284 /// EXTERNAL: Requires context from outside the message.
1285 fn evaluate_105(&self, ctx: &EvaluationContext) -> ConditionResult {
1286 ctx.external
1287 .evaluate("bisherige_konfiguration_zaehltzeiten_lf_beenden")
1288 }
1289
1290 /// [106] wenn IMD++Z60 (Abbestellung Messprodukt mit Zählzeitdefinition des LF) nicht vorhanden
1291 fn evaluate_106(&self, ctx: &EvaluationContext) -> ConditionResult {
1292 ctx.lacks_qualifier("IMD", 1, "Z60")
1293 }
1294
1295 /// [107] Wenn IMD++Z57 (Abbestellung Zählzeitdefinition) nicht vorhanden
1296 fn evaluate_107(&self, ctx: &EvaluationContext) -> ConditionResult {
1297 ctx.lacks_qualifier("IMD", 1, "Z57")
1298 }
1299
1300 /// [108] Wenn RFF+AGK (Konfigurations-ID) nicht vorhanden
1301 fn evaluate_108(&self, ctx: &EvaluationContext) -> ConditionResult {
1302 ctx.lacks_qualifier("RFF", 0, "AGK")
1303 }
1304
1305 /// [109] Wenn LOC+172 (Meldepunkt) nicht vorhanden
1306 fn evaluate_109(&self, ctx: &EvaluationContext) -> ConditionResult {
1307 ctx.lacks_qualifier("LOC", 0, "172")
1308 }
1309
1310 /// [110] wenn DTM+163 (Beginn Zeitraum für Wertanfrage) vorhanden
1311 fn evaluate_110(&self, ctx: &EvaluationContext) -> ConditionResult {
1312 ctx.has_qualifier("DTM", 0, "163")
1313 }
1314
1315 /// [112] Wenn in derselben SG29 LIN++Z54 (Erforderliches Produkt der Marktlokation), das PIA+5+9991000000078: Z11 (Wirkarbeit Lastgang 1/4 stündlich) vorhanden ist
1316 // REVIEW: In same SG29: LIN with elements[1][0]=Z54 (Erforderliches Produkt der Marktlokation) co-occurs with PIA where elements[1][0]=9991000000078 (Wirkarbeit Lastgang 1/4h, product code from C212.DE7140). Co-occurrence check scoped to SG29. (medium confidence)
1317 fn evaluate_112(&self, ctx: &EvaluationContext) -> ConditionResult {
1318 ctx.any_group_has_co_occurrence(
1319 "LIN",
1320 1,
1321 &["Z54"],
1322 "PIA",
1323 1,
1324 0,
1325 &["9991000000078"],
1326 &["SG29"],
1327 )
1328 }
1329
1330 /// [113] Wenn LIN DE1229 mit Code Z42 (Zählzeitdefinition) vorhanden
1331 fn evaluate_113(&self, ctx: &EvaluationContext) -> ConditionResult {
1332 ctx.has_qualifier("LIN", 1, "Z42")
1333 }
1334
1335 /// [114] Wenn LIN DE1229 mit Code Z69 (Schaltzeitdefinition) vorhanden
1336 fn evaluate_114(&self, ctx: &EvaluationContext) -> ConditionResult {
1337 ctx.has_qualifier("LIN", 1, "Z69")
1338 }
1339
1340 /// [115] Wenn LIN DE1229 mit Code Z70 (Leistungskurvendefinition) vorhanden
1341 fn evaluate_115(&self, ctx: &EvaluationContext) -> ConditionResult {
1342 ctx.has_qualifier("LIN", 1, "Z70")
1343 }
1344
1345 /// [117] Wenn SG29 LIN++Z64 (Erforderliches Produkt Schaltzeitdefinitionen) vorhanden
1346 fn evaluate_117(&self, ctx: &EvaluationContext) -> ConditionResult {
1347 ctx.has_qualifier("LIN", 1, "Z64")
1348 }
1349
1350 /// [118] Wenn SG29 LIN++Z65 (Erforderliches Produkt Leistungskurvendefinitionen) vorhanden
1351 fn evaluate_118(&self, ctx: &EvaluationContext) -> ConditionResult {
1352 ctx.has_qualifier("LIN", 1, "Z65")
1353 }
1354
1355 /// [119] Wenn SG29 LIN++Z66 (Erforderliches Produkt Ad-hoc-Steuerkanal) vorhanden
1356 fn evaluate_119(&self, ctx: &EvaluationContext) -> ConditionResult {
1357 ctx.has_qualifier("LIN", 1, "Z66")
1358 }
1359
1360 /// [120] Wenn SG29 LIN++Z67 (Erforderliches Messprodukt für Werte nach Typ 2 aus Backend) vorhanden
1361 fn evaluate_120(&self, ctx: &EvaluationContext) -> ConditionResult {
1362 ctx.has_qualifier("LIN", 1, "Z67")
1363 }
1364
1365 /// [121] Wenn SG29 LIN++Z68 (Erforderliches Produkt Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW) vorhanden
1366 fn evaluate_121(&self, ctx: &EvaluationContext) -> ConditionResult {
1367 ctx.has_qualifier("LIN", 1, "Z68")
1368 }
1369
1370 /// [122] Wenn SG1 RFF+Z41 (Referenznummer des Vorgangs der Anmeldung nach WiM) nicht vorhanden
1371 fn evaluate_122(&self, ctx: &EvaluationContext) -> ConditionResult {
1372 ctx.lacks_qualifier("RFF", 0, "Z41")
1373 }
1374
1375 /// [123] Wenn DTM+203 (Ausführungsdatum) nicht vorhanden
1376 fn evaluate_123(&self, ctx: &EvaluationContext) -> ConditionResult {
1377 ctx.lacks_qualifier("DTM", 0, "203")
1378 }
1379
1380 /// [124] Wenn SG1 RFF+Z41 (Referenznummer des Vorgangs der Anmeldung nach WiM) vorhanden
1381 fn evaluate_124(&self, ctx: &EvaluationContext) -> ConditionResult {
1382 ctx.has_qualifier("RFF", 0, "Z41")
1383 }
1384
1385 /// [125] Es sind nur die Konfigurations-Produkte erlaubt, die in der Codeliste der Konfigurationen im Kapitel 4.1 „Konfigurationsprodukte Schaltzeitdefinition“ enthalten sind.
1386 /// EXTERNAL: Requires context from outside the message.
1387 fn evaluate_125(&self, ctx: &EvaluationContext) -> ConditionResult {
1388 ctx.external
1389 .evaluate("konfigurationsprodukt_schaltzeitdefinition")
1390 }
1391
1392 /// [130] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Marktlokation angegeben ist
1393 fn evaluate_130(&self, ctx: &EvaluationContext) -> ConditionResult {
1394 // Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Marktlokation angegeben ist
1395 // LOC Meldepunkt: elements[0][0]=="172", elements[1][0]==DE3225 (Identifikator)
1396 let locs = ctx.find_segments_with_qualifier("LOC", 0, "172");
1397 match locs
1398 .first()
1399 .and_then(|s| s.elements.get(1))
1400 .and_then(|e| e.first())
1401 {
1402 Some(val) if !val.is_empty() => validate_malo_id(val),
1403 Some(_) => ConditionResult::False,
1404 None => ConditionResult::False, // segment absent → condition not applicable
1405 }
1406 }
1407
1408 /// [131] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Messlokation angegeben ist
1409 /// EXTERNAL: Requires context from outside the message.
1410 fn evaluate_131(&self, ctx: &EvaluationContext) -> ConditionResult {
1411 ctx.external.evaluate("meldepunkt_is_messlokation_id")
1412 }
1413
1414 /// [132] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Netzlokation angegeben ist
1415 /// EXTERNAL: Requires context from outside the message.
1416 fn evaluate_132(&self, ctx: &EvaluationContext) -> ConditionResult {
1417 ctx.external.evaluate("meldepunkt_is_netzlokation_id")
1418 }
1419
1420 /// [133] Wenn in LOC+172 DE3225 (Meldepunkt) die ID einer Steuerbaren Ressource angegeben ist
1421 /// EXTERNAL: Requires context from outside the message.
1422 fn evaluate_133(&self, ctx: &EvaluationContext) -> ConditionResult {
1423 ctx.external
1424 .evaluate("meldepunkt_is_steuerbare_ressource_id")
1425 }
1426
1427 /// [134] Wenn die Position in der ursprünglichen Antwort auf die Bestellung aus SG1 RFF+Z42 vorhanden war und reklamiert werden soll
1428 // REVIEW: RFF+Z42 in SG1 (elements[0][0]=="Z42") references the original order response position. Presence of this segment in the current message indicates the reclaim scenario. The 'reklamiert werden soll' clause is implied by the reference existing. (medium confidence)
1429 fn evaluate_134(&self, ctx: &EvaluationContext) -> ConditionResult {
1430 ctx.has_qualifier("RFF", 0, "Z42")
1431 }
1432
1433 /// [135] Wenn SG29 LIN++Z64 (Erforderliches Produkt Schaltzeitdefinitionen) nicht vorhanden
1434 fn evaluate_135(&self, ctx: &EvaluationContext) -> ConditionResult {
1435 ctx.lacks_qualifier("LIN", 1, "Z64")
1436 }
1437
1438 /// [136] Wenn SG29 LIN++Z65 (Erforderliches Produkt Leistungskurvendefinitionen) nicht vorhanden
1439 fn evaluate_136(&self, ctx: &EvaluationContext) -> ConditionResult {
1440 ctx.lacks_qualifier("LIN", 1, "Z65")
1441 }
1442
1443 /// [137] Wenn SG29 LIN++Z66 (Erforderliches Produkt Ad-hoc-Steuerkanal) nicht vorhanden
1444 fn evaluate_137(&self, ctx: &EvaluationContext) -> ConditionResult {
1445 ctx.lacks_qualifier("LIN", 1, "Z66")
1446 }
1447
1448 /// [138] Wenn SG29 LIN++Z67 (Erforderliches Messprodukt für Werte nach Typ 2 aus Backend) nicht vorhanden
1449 fn evaluate_138(&self, ctx: &EvaluationContext) -> ConditionResult {
1450 ctx.lacks_qualifier("LIN", 1, "Z67")
1451 }
1452
1453 /// [139] Wenn SG29 LIN++Z68 (Erforderliches Produkt Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW) nicht vorhanden
1454 fn evaluate_139(&self, ctx: &EvaluationContext) -> ConditionResult {
1455 ctx.lacks_qualifier("LIN", 1, "Z68")
1456 }
1457
1458 /// [140] Messprodukt-Code aus dem Kapitel 2.4 "Standard-Messprodukte der Netzlokation" der Codeliste der Konfigurationen
1459 /// EXTERNAL: Requires context from outside the message.
1460 fn evaluate_140(&self, ctx: &EvaluationContext) -> ConditionResult {
1461 ctx.external
1462 .evaluate("is_standard_messprodukt_netzlokation_code")
1463 }
1464
1465 /// [147] wenn im DE3155 in demselben COM der Code EM vorhanden ist
1466 fn evaluate_147(&self, ctx: &EvaluationContext) -> ConditionResult {
1467 let com_segments = ctx.find_segments("COM");
1468 ConditionResult::from(com_segments.iter().any(|s| {
1469 s.elements
1470 .first()
1471 .and_then(|e| e.get(1))
1472 .is_some_and(|v| v == "EM")
1473 }))
1474 }
1475
1476 /// [148] wenn im DE3155 in demselben COM der Code TE / FX / AJ / AL vorhanden ist
1477 fn evaluate_148(&self, ctx: &EvaluationContext) -> ConditionResult {
1478 let com_segments = ctx.find_segments("COM");
1479 ConditionResult::from(com_segments.iter().any(|s| {
1480 s.elements
1481 .first()
1482 .and_then(|e| e.get(1))
1483 .is_some_and(|v| matches!(v.as_str(), "TE" | "FX" | "AJ" | "AL"))
1484 }))
1485 }
1486
1487 /// [153] Es sind nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Ebene" mit dem Wert "Mess...
1488 /// EXTERNAL: Requires context from outside the message.
1489 fn evaluate_153(&self, ctx: &EvaluationContext) -> ConditionResult {
1490 ctx.external.evaluate("product_code_level_messlokation")
1491 }
1492
1493 /// [154] Es sind nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Ebene" mit dem Wert "Netz...
1494 /// EXTERNAL: Requires context from outside the message.
1495 fn evaluate_154(&self, ctx: &EvaluationContext) -> ConditionResult {
1496 ctx.external.evaluate("product_code_level_netzlokation")
1497 }
1498
1499 /// [155] Es sind nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Ebene" mit dem Wert "Steu...
1500 /// EXTERNAL: Requires context from outside the message.
1501 fn evaluate_155(&self, ctx: &EvaluationContext) -> ConditionResult {
1502 ctx.external
1503 .evaluate("product_code_level_steuerbare_ressource")
1504 }
1505
1506 /// [156] Es sind weiterhin nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Produkt gegenü...
1507 /// EXTERNAL: Requires context from outside the message.
1508 fn evaluate_156(&self, ctx: &EvaluationContext) -> ConditionResult {
1509 ctx.external.evaluate("product_code_orderable_by_nb")
1510 }
1511
1512 /// [157] Es sind weiterhin nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 7 "Produkte zur Bestellung einer Änderung an einer Lokation" die in der Spalte "Produkt gegenü...
1513 /// EXTERNAL: Requires context from outside the message.
1514 fn evaluate_157(&self, ctx: &EvaluationContext) -> ConditionResult {
1515 ctx.external.evaluate("product_code_orderable_by_lf")
1516 }
1517
1518 /// [158] Es sind nur die Produkt-Codes erlaubt, die in der Codeliste der Konfigurationen im Kapitel 6.2 "Produkte zur Bestellung einer Änderung von Abrechnungsdaten" genannt sind.
1519 /// EXTERNAL: Requires context from outside the message.
1520 fn evaluate_158(&self, ctx: &EvaluationContext) -> ConditionResult {
1521 ctx.external
1522 .evaluate("product_code_in_abrechnungsdaten_configuration_list")
1523 }
1524
1525 /// [159] Wenn in derselben SG29 LIN im PIA+5 (Erforderliches Produkt Abrechnungsdaten) DE7140 ein Produkt-Code genannt ist, der in der Codeliste der Konfigurationen im Kapitel 6.2 "Produkte zur Bestellung e...
1526 /// EXTERNAL: Requires context from outside the message.
1527 fn evaluate_159(&self, ctx: &EvaluationContext) -> ConditionResult {
1528 ctx.external
1529 .evaluate("abrechnungsdaten_product_has_property_code_column")
1530 }
1531
1532 /// [160] Es sind nur die Codes der Produkteigenschaft zu dem in derselben SG29 LIN im PIA+5 (Erforderliches Produkt Abrechnungsdaten) DE7140 erlaubt, die in der Codeliste der Konfigurationen im Kapitel 6.2 ...
1533 /// EXTERNAL: Requires context from outside the message.
1534 fn evaluate_160(&self, ctx: &EvaluationContext) -> ConditionResult {
1535 ctx.external
1536 .evaluate("abrechnungsdaten_property_code_matches_product_row")
1537 }
1538
1539 /// [161] Wenn in derselben SG29 LIN (Erforderliches Produkt Abrechnungsdaten) das SG30 CAV+ZH9 (Code der Produkteigenschaft) nicht vorhanden ist.
1540 fn evaluate_161(&self, ctx: &EvaluationContext) -> ConditionResult {
1541 ctx.any_group_has_qualifier_without("PIA", 0, "5", "CAV", 0, "ZH9", &["SG4", "SG29"])
1542 }
1543
1544 /// [162] Es ist nur der Wertebereich erlaubt, der zu dem in derselben SG29 LIN im PIA+5 (Erforderliches Produkt Abrechnungsdaten) DE7140 genannten Produkt, das in der Codeliste der Konfigurationen im Kapite...
1545 /// EXTERNAL: Requires context from outside the message.
1546 fn evaluate_162(&self, ctx: &EvaluationContext) -> ConditionResult {
1547 ctx.external
1548 .evaluate("abrechnungsdaten_value_range_matches_product_row")
1549 }
1550
1551 /// [163] Wenn innerhalb der Nachricht eine SG30 CCI+++ZA9 (Messprodukt für Übertragungsnetzbetreiber relevant) vorhanden ist.
1552 fn evaluate_163(&self, ctx: &EvaluationContext) -> ConditionResult {
1553 ctx.has_qualifier("CCI", 2, "ZA9")
1554 }
1555
1556 /// [164] Wenn die Konfiguration der in SG34 RFF+Z20 DE1154 (Referenz auf ID der Tranche) genannte Tranche innerhalb derselben SG29 LIN++Z16 (Erforderliches Produkt der Tranche) unverändert bestehen bleibt.
1557 /// EXTERNAL: Requires context from outside the message.
1558 fn evaluate_164(&self, ctx: &EvaluationContext) -> ConditionResult {
1559 ctx.external.evaluate("tranche_configuration_unchanged")
1560 }
1561
1562 /// [167] Wenn SG2 NAD+DP (Meldepunkt), SG3 RFF+Z20 (Referenz auf ID der Tranche) vorhanden
1563 fn evaluate_167(&self, ctx: &EvaluationContext) -> ConditionResult {
1564 match (
1565 ctx.has_qualifier("NAD", 0, "DP"),
1566 ctx.has_qualifier("RFF", 0, "Z20"),
1567 ) {
1568 (ConditionResult::True, ConditionResult::True) => ConditionResult::True,
1569 (ConditionResult::False, _) | (_, ConditionResult::False) => ConditionResult::False,
1570 _ => ConditionResult::Unknown,
1571 }
1572 }
1573
1574 /// [168] Wenn SG2 NAD+DP (Meldepunkt), SG3 RFF+Z20 (Referenz auf ID der Tranche) nicht vorhanden
1575 fn evaluate_168(&self, ctx: &EvaluationContext) -> ConditionResult {
1576 match ctx.has_qualifier("NAD", 0, "DP") {
1577 ConditionResult::True => ctx.lacks_qualifier("RFF", 0, "Z20"),
1578 other => other,
1579 }
1580 }
1581
1582 /// [169] Wenn in SG29 LIN++Z19 (Erforderliches Produkt der Messlokation) in SG30 CCI (Zugeordnete Zählzeitdefinition im DE7059 der Code Z39 (Code der Zählzeitdefinition) vorhanden ist
1583 fn evaluate_169(&self, ctx: &EvaluationContext) -> ConditionResult {
1584 ctx.any_group_has_co_occurrence("LIN", 1, &["Z19"], "CCI", 0, 0, &["Z39"], &["SG29"])
1585 }
1586
1587 /// [170] Wenn in derselben SG29 LIN die SG30 CCI+Z37++ZD1 (Basis zur Bildung der Tranchengröße) (Prozentual) vorhanden
1588 fn evaluate_170(&self, ctx: &EvaluationContext) -> ConditionResult {
1589 ctx.any_group_has_qualified_value("CCI", 0, "Z37", 2, 0, &["ZD1"], &["SG29"])
1590 }
1591
1592 /// [171] Wenn in derselben SG29 LIN (Erforderliches Produkt der Tranche) das IMD+++Z64 (Leistungsbeschreibung Konfiguration) (Neukonfiguration) vorhanden ist
1593 fn evaluate_171(&self, ctx: &EvaluationContext) -> ConditionResult {
1594 ctx.any_group_has_qualifier("IMD", 2, "Z64", &["SG29"])
1595 }
1596
1597 /// [173] Wenn IMD++Z66 (Beendigung Konfiguration aufgrund Überführung der Marktlokation zu ruhender Marktlokation) vorhanden
1598 fn evaluate_173(&self, ctx: &EvaluationContext) -> ConditionResult {
1599 ctx.has_qualifier("IMD", 1, "Z66")
1600 }
1601
1602 /// [174] Wenn IMD++Z67 (Aktivierung Konfiguration in der derzeit ruhenden Marktlokation) vorhanden
1603 fn evaluate_174(&self, ctx: &EvaluationContext) -> ConditionResult {
1604 ctx.has_qualifier("IMD", 1, "Z67")
1605 }
1606
1607 /// [175] Wenn SG2 NAD+DP (Meldepunkt), SG3 RFF+Z59 (Referenz auf die ID der Marktlokation der Kundenanlage) vorhanden
1608 fn evaluate_175(&self, ctx: &EvaluationContext) -> ConditionResult {
1609 match (
1610 ctx.has_qualifier("NAD", 0, "DP"),
1611 ctx.has_qualifier("RFF", 0, "Z59"),
1612 ) {
1613 (ConditionResult::True, ConditionResult::True) => ConditionResult::True,
1614 (ConditionResult::False, _) | (_, ConditionResult::False) => ConditionResult::False,
1615 _ => ConditionResult::Unknown,
1616 }
1617 }
1618
1619 /// [176] Wenn SG2 NAD+DP (Meldepunkt), SG3 RFF+Z59 (Referenz auf die ID der Marktlokation der Kundenanlage) nicht vorhanden
1620 fn evaluate_176(&self, ctx: &EvaluationContext) -> ConditionResult {
1621 match ctx.has_qualifier("NAD", 0, "DP") {
1622 ConditionResult::True => ctx.lacks_qualifier("RFF", 0, "Z59"),
1623 other => other,
1624 }
1625 }
1626
1627 /// [177] Wenn IMD++Z66 (Beendigung Konfiguration aufgrund Überführung der Marktlokation zu ruhender Marktlokation) nicht vorhanden
1628 fn evaluate_177(&self, ctx: &EvaluationContext) -> ConditionResult {
1629 ctx.lacks_qualifier("IMD", 1, "Z66")
1630 }
1631
1632 /// [490] wenn Wert in diesem DE, an der Stelle CCYYMMDDHHMM ein Zeitpunkt aus dem angegeben Zeitraum der Tabelle Kapitel 3.5 „Übersicht gesetzliche deutsche Sommerzeit (MESZ)“ der Spalten: „Sommerzei...
1633 fn evaluate_490(&self, ctx: &EvaluationContext) -> ConditionResult {
1634 match ctx.resolved_value {
1635 Some(val) => is_mesz_utc(val),
1636 None => ConditionResult::False,
1637 }
1638 }
1639
1640 /// [491] wenn Wert in diesem DE, an der Stelle CCYYMMDDHHMM ein Zeitpunkt aus dem angegeben Zeitraum der Tabelle Kapitel 3.6 „Übersicht gesetzliche deutsche Zeit (MEZ)“ der Spalten: „Winterzeit (MEZ)...
1641 fn evaluate_491(&self, ctx: &EvaluationContext) -> ConditionResult {
1642 match ctx.resolved_value {
1643 Some(val) => is_mez_utc(val),
1644 None => ConditionResult::False,
1645 }
1646 }
1647
1648 /// [492] wenn MP-ID in NAD+MR aus Sparte Strom
1649 /// EXTERNAL: Requires context from outside the message.
1650 // REVIEW: Whether the MP-ID in NAD+MR belongs to the Strom (electricity) sector cannot be determined from the EDIFACT message alone — it requires a market participant registry lookup. (medium confidence)
1651 fn evaluate_492(&self, ctx: &EvaluationContext) -> ConditionResult {
1652 ctx.external.evaluate("recipient_is_strom")
1653 }
1654
1655 /// [493] wenn MP-ID in NAD+MR aus Sparte Gas
1656 /// EXTERNAL: Requires context from outside the message.
1657 // REVIEW: Whether the MP-ID in NAD+MR belongs to the Gas sector cannot be determined from the EDIFACT message alone — it requires a market participant registry lookup. (medium confidence)
1658 fn evaluate_493(&self, ctx: &EvaluationContext) -> ConditionResult {
1659 ctx.external.evaluate("recipient_is_gas")
1660 }
1661
1662 /// [494] Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.
1663 // REVIEW: States that the date in this DE must be the document creation time or earlier, i.e. <= DTM+137 Nachrichtendatum. Applied to DTM+203 (Ausführungsdatum) as the most logical target in ORDERS. Lexicographic string comparison is valid for CCYYMMDDHHMM (format 303) values since they are zero-padded fixed-width. (medium confidence)
1664 fn evaluate_494(&self, ctx: &EvaluationContext) -> ConditionResult {
1665 // The date here must be the document creation time (DTM+137 Nachrichtendatum) or earlier.
1666 // DTM+137: elements[0][0]=qualifier(137), elements[0][1]=DE2380 (actual value), elements[0][2]=format(303)
1667 // Applied to Ausführungsdatum (DTM+203) as the most likely subject in ORDERS.
1668 let dtm137_segs = ctx.find_segments_with_qualifier("DTM", 0, "137");
1669 let dtm203_segs = ctx.find_segments_with_qualifier("DTM", 0, "203");
1670 let ref_val = dtm137_segs
1671 .first()
1672 .and_then(|s| s.elements.first())
1673 .and_then(|e| e.get(1));
1674 let cmp_val = dtm203_segs
1675 .first()
1676 .and_then(|s| s.elements.first())
1677 .and_then(|e| e.get(1));
1678 match (cmp_val, ref_val) {
1679 (Some(cv), Some(rv)) => ConditionResult::from(cv.as_str() <= rv.as_str()),
1680 _ => ConditionResult::Unknown,
1681 }
1682 }
1683
1684 /// [495] Der Zeitpunkt muss ≤ dem Wert im DE2380 des DTM+137 sein
1685 // REVIEW: Explicitly requires the subject timestamp to be <= DE2380 of DTM+137 (Nachrichtendatum). Notation resolved: DTM+137 elements[0][1] is DE2380 per the MIG segment structure reference. Applied to DTM+203 (Ausführungsdatum) as the primary date field requiring this constraint in ORDERS. String comparison is valid for fixed-width CCYYMMDDHHMM format 303. (medium confidence)
1686 fn evaluate_495(&self, ctx: &EvaluationContext) -> ConditionResult {
1687 // The point in time must be <= DE2380 of DTM+137 (Nachrichtendatum).
1688 // DTM element layout per MIG: elements[0][0]=qualifier, elements[0][1]=DE2380 value, elements[0][2]=format code.
1689 // Applied to Ausführungsdatum (DTM+203) as the most relevant cross-date check in ORDERS.
1690 let dtm137_segs = ctx.find_segments_with_qualifier("DTM", 0, "137");
1691 let dtm203_segs = ctx.find_segments_with_qualifier("DTM", 0, "203");
1692 let ref_val = dtm137_segs
1693 .first()
1694 .and_then(|s| s.elements.first())
1695 .and_then(|e| e.get(1));
1696 let cmp_val = dtm203_segs
1697 .first()
1698 .and_then(|s| s.elements.first())
1699 .and_then(|e| e.get(1));
1700 match (cmp_val, ref_val) {
1701 (Some(cv), Some(rv)) => ConditionResult::from(cv.as_str() <= rv.as_str()),
1702 _ => ConditionResult::Unknown,
1703 }
1704 }
1705
1706 /// [500] Hinweis: Zählpunkt der BAS
1707 fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
1708 ConditionResult::Unknown
1709 }
1710
1711 /// [501] Hinweis: Zählpunkt der DZR
1712 fn evaluate_501(&self, _ctx: &EvaluationContext) -> ConditionResult {
1713 ConditionResult::Unknown
1714 }
1715
1716 /// [503] Hinweis: Angabe eines technischen Ansprechpartners für die Geräteübernahme
1717 fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
1718 ConditionResult::Unknown
1719 }
1720
1721 /// [506] Hinweis: Datum, bis zu dem der MSBA zur Fortführung verpflichtet wird
1722 fn evaluate_506(&self, _ctx: &EvaluationContext) -> ConditionResult {
1723 ConditionResult::Unknown
1724 }
1725
1726 /// [507] Hinweis: Es müssen alle nach Durchführung der Messlokationsänderung eingesetzten/genutzten OBIS- Kennzahlen übermittelt werden (wird eine "Erweiterung" des Messumfangs beauftragt, sind auch die...
1727 fn evaluate_507(&self, _ctx: &EvaluationContext) -> ConditionResult {
1728 ConditionResult::Unknown
1729 }
1730
1731 /// [514] Hinweis: Das Abonnement kann frühestens ab dem aktuellen Liefermonat beim Netzbetreiber gestartet werden.
1732 fn evaluate_514(&self, _ctx: &EvaluationContext) -> ConditionResult {
1733 ConditionResult::Unknown
1734 }
1735
1736 /// [515] Hinweis: Das angegebene Betrachtungszeitintervall bestimmt beim Start Abo bzw. Ende Abo ab bzw. bis wann (einschließlich) das Abo laufen soll.
1737 fn evaluate_515(&self, _ctx: &EvaluationContext) -> ConditionResult {
1738 ConditionResult::Unknown
1739 }
1740
1741 /// [517] Hinweis: Zählpunkt der LF-AASZR
1742 fn evaluate_517(&self, _ctx: &EvaluationContext) -> ConditionResult {
1743 ConditionResult::Unknown
1744 }
1745
1746 /// [518] Hinweis: Das angegebene Ausführungsdatum bestimmt beim Start Abo bzw. Ende Abo ab bzw. bis wann (einschließlich) das Abo laufen soll.
1747 fn evaluate_518(&self, _ctx: &EvaluationContext) -> ConditionResult {
1748 ConditionResult::Unknown
1749 }
1750
1751 /// [519] Hinweis: Bei Gas bezieht sich die Anforderung immer sowohl auf die vorläufigen Profilwerte als auch auf die endgültigen Profilwerte, falls diese bereits vorliegen.
1752 fn evaluate_519(&self, _ctx: &EvaluationContext) -> ConditionResult {
1753 ConditionResult::Unknown
1754 }
1755
1756 /// [521] Hinweis: Verwendung der ID der Marktlokation
1757 fn evaluate_521(&self, _ctx: &EvaluationContext) -> ConditionResult {
1758 // Hinweis: Verwendung der ID der Marktlokation — informational note, always applies
1759 ConditionResult::True
1760 }
1761
1762 /// [522] Hinweis: Verwendung der ID der Messlokation
1763 fn evaluate_522(&self, _ctx: &EvaluationContext) -> ConditionResult {
1764 // Hinweis: Verwendung der ID der Messlokation — informational note, always applies
1765 ConditionResult::True
1766 }
1767
1768 /// [523] Hinweis: Verwendung der ID der Tranche
1769 fn evaluate_523(&self, _ctx: &EvaluationContext) -> ConditionResult {
1770 // Hinweis: Verwendung der ID der Tranche — informational note, always applies
1771 ConditionResult::True
1772 }
1773
1774 /// [525] Hinweis: Wert aus BGM DE1004 der MSCONS
1775 fn evaluate_525(&self, _ctx: &EvaluationContext) -> ConditionResult {
1776 // Hinweis: Wert aus BGM DE1004 der MSCONS — informational note, always applies
1777 ConditionResult::True
1778 }
1779
1780 /// [527] Hinweis: Zählpunkt der BG-SZR (Kategorie B)
1781 fn evaluate_527(&self, _ctx: &EvaluationContext) -> ConditionResult {
1782 // Hinweis: Zählpunkt der BG-SZR (Kategorie B) — informational note, always applies
1783 ConditionResult::True
1784 }
1785
1786 /// [530] Hinweis: Wert aus BGM+310 DE1004 der QUOTES mit der das Angebot erfolgt ist.
1787 fn evaluate_530(&self, _ctx: &EvaluationContext) -> ConditionResult {
1788 // Hinweis: Wert aus BGM+310 DE1004 der QUOTES mit der das Angebot erfolgt ist — informational note, always applies
1789 ConditionResult::True
1790 }
1791
1792 /// [531] Hinweis: Wert aus LIN DE1082 der QUOTES, mit der das Angebot erfolgt ist
1793 fn evaluate_531(&self, _ctx: &EvaluationContext) -> ConditionResult {
1794 // Hinweis: Wert aus LIN DE1082 der QUOTES, mit der das Angebot erfolgt ist — informational note, always applies
1795 ConditionResult::True
1796 }
1797
1798 /// [532] Hinweis: Wert aus BGM+Z29 DE1004 der QUOTES, mit der das Angebot zur Abrechnung des Messstellenbetriebs erfolgt ist.
1799 fn evaluate_532(&self, _ctx: &EvaluationContext) -> ConditionResult {
1800 // Hinweis: Wert aus BGM+Z29 DE1004 der QUOTES, mit der das Angebot zur Abrechnung des Messstellenbetriebs erfolgt ist — informational note, always applies
1801 ConditionResult::True
1802 }
1803
1804 /// [533] Hinweis: Gerichtsvollzieher hat Termin vorgegeben
1805 fn evaluate_533(&self, _ctx: &EvaluationContext) -> ConditionResult {
1806 // Hinweis: Gerichtsvollzieher hat Termin vorgegeben — informational note, always applies
1807 ConditionResult::True
1808 }
1809
1810 /// [535] Hinweis: Verwendung der ID der Messlokation der Sparte Strom
1811 fn evaluate_535(&self, _ctx: &EvaluationContext) -> ConditionResult {
1812 // Hinweis: Verwendung der ID der Messlokation der Sparte Strom — informational note, always applies
1813 ConditionResult::True
1814 }
1815
1816 /// [536] Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z59
1817 fn evaluate_536(&self, _ctx: &EvaluationContext) -> ConditionResult {
1818 // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z59 — informational note, always applies
1819 ConditionResult::True
1820 }
1821
1822 /// [539] Hinweis: Es sind nur Codes von Zählzeiten aus Liste des NB anzugeben
1823 fn evaluate_539(&self, _ctx: &EvaluationContext) -> ConditionResult {
1824 // Hinweis: Es sind nur Codes von Zählzeiten aus Liste des NB anzugeben — informational note, always applies
1825 ConditionResult::True
1826 }
1827
1828 /// [540] Hinweis: Es sind nur Codes von Zählzeiten aus Liste des LF anzugeben
1829 fn evaluate_540(&self, _ctx: &EvaluationContext) -> ConditionResult {
1830 // Hinweis: Es sind nur Codes von Zählzeiten aus Liste des LF anzugeben — informational note, always applies
1831 ConditionResult::True
1832 }
1833
1834 /// [542] Hinweis: Wert aus BGM+Z57 DE1004 der QUOTES mit der das Angebot erfolgt ist.
1835 fn evaluate_542(&self, _ctx: &EvaluationContext) -> ConditionResult {
1836 // Hinweis: Wert aus BGM+Z57 DE1004 der QUOTES mit der das Angebot erfolgt ist — informational note, always applies
1837 ConditionResult::True
1838 }
1839
1840 /// [543] Hinweis: Wert aus BGM+Z57 DE1004 der ORDERS mit der die Bestellung der Werte erfolgt ist.
1841 fn evaluate_543(&self, _ctx: &EvaluationContext) -> ConditionResult {
1842 // Hinweis: Wert aus BGM+Z57 DE1004 der ORDERS mit der die Bestellung der Werte erfolgt ist — informational note, always applies
1843 ConditionResult::True
1844 }
1845
1846 /// [545] Hinweis: Es werden nur die Messprodukte der Messlokationen angegeben, die für die in der SG2 genannte Marktlokation bzw. deren Tranchen erforderlich sind. Messprodukte an der Messlokation für wei...
1847 fn evaluate_545(&self, _ctx: &EvaluationContext) -> ConditionResult {
1848 // Hinweis: Es werden nur die Messprodukte der Messlokationen angegeben... — informational note, always applies
1849 ConditionResult::True
1850 }
1851
1852 /// [547] Hinweis: Dokumentennummer aus BGM+Z60 DE1004 der UTILTS
1853 fn evaluate_547(&self, _ctx: &EvaluationContext) -> ConditionResult {
1854 // Hinweis: Dokumentennummer aus BGM+Z60 DE1004 der UTILTS — informational note, always applies
1855 ConditionResult::True
1856 }
1857
1858 /// [548] Hinweis: Wenn die Änderung der Gerätekonfiguration mit einer Zählzeit übermittelt wird, ist hier die MP-ID des Eigentümers der Liste der Zählzeit einzutragen. Wenn anstatt der bisherigen Zäh...
1859 fn evaluate_548(&self, _ctx: &EvaluationContext) -> ConditionResult {
1860 // Hinweis: MP-ID des Eigentümers der Zählzeitliste — informational note, always applies
1861 ConditionResult::True
1862 }
1863
1864 /// [549] Hinweis: Findet bei der Reklamation von Zählerständen immer Anwendung. Einzige Ausnahme ist, wenn es sich um die Reklamation eines fehlenden Zählerstandes aufgrund einer Turnusablesung handelt, ...
1865 fn evaluate_549(&self, _ctx: &EvaluationContext) -> ConditionResult {
1866 // Hinweis: Reklamation von Zählerständen — Zeitpunktangabe vs. Zeitintervall — informational note, always applies
1867 ConditionResult::True
1868 }
1869
1870 /// [550] Hinweis: Findet nur dann Anwendung, wenn es sich um die Reklamation eines fehlenden Zählerstandes aufgrund einer Turnusablesung handelt, bei welcher der MSB am Objekt der Marktlokation die Informa...
1871 fn evaluate_550(&self, _ctx: &EvaluationContext) -> ConditionResult {
1872 // Hinweis: Reklamation fehlender Zählerstand bei Turnusablesung — informational note, always applies
1873 ConditionResult::True
1874 }
1875
1876 /// [551] Hinweis: Die SG29 ist so oft zu wiederholen, dass alle Messprodukte und Zählzeiten genannt werden, die ab dem in DTM+203 genannten Zeitpunkt auf der Messlokation durch den MSB konfiguriert werden ...
1877 fn evaluate_551(&self, _ctx: &EvaluationContext) -> ConditionResult {
1878 // Hinweis: SG29 Wiederholung für alle Messprodukte und Zählzeiten — informational note, always applies
1879 ConditionResult::True
1880 }
1881
1882 /// [552] Hinweis: Verwendung der ID der Netzlokation
1883 fn evaluate_552(&self, _ctx: &EvaluationContext) -> ConditionResult {
1884 // Hinweis: Verwendung der ID der Netzlokation — informational note, always applies
1885 ConditionResult::True
1886 }
1887
1888 /// [553] Hinweis: Verwendung der ID der Steuerbaren Ressource
1889 fn evaluate_553(&self, _ctx: &EvaluationContext) -> ConditionResult {
1890 // Hinweis: Verwendung der ID der Steuerbaren Ressource — informational note, always applies
1891 ConditionResult::True
1892 }
1893
1894 /// [554] Hinweis: Wert aus BGM+Z74 DE1004 der QUOTES mit der das Angebot erfolgt ist.
1895 fn evaluate_554(&self, _ctx: &EvaluationContext) -> ConditionResult {
1896 // Hinweis: Wert aus BGM+Z74 DE1004 der QUOTES — informational note about value origin, always applies
1897 ConditionResult::True
1898 }
1899
1900 /// [555] Hinweis: Vorgangsnummer aus SG4 IDE+24 DE7402 der UTILMD mit BGM+E01 mit der die Anmeldung des MSB-Wechsels erfolgt ist.
1901 fn evaluate_555(&self, _ctx: &EvaluationContext) -> ConditionResult {
1902 // Hinweis: Vorgangsnummer aus SG4 IDE+24 DE7402 der UTILMD — informational note about value origin, always applies
1903 ConditionResult::True
1904 }
1905
1906 /// [557] Hinweis: Es werden nur die Messprodukte der Messlokationen angegeben, die für die in der SG2 genannte Netzlokation erforderlich sind. Messprodukte an der Messlokation für weitere Netzlokationen o...
1907 fn evaluate_557(&self, _ctx: &EvaluationContext) -> ConditionResult {
1908 // Hinweis: Only Messprodukte for Messlokationen required for the named Netzlokation are specified — informational note, always applies
1909 ConditionResult::True
1910 }
1911
1912 /// [558] Hinweis: Dokumentennummer aus BGM+Z78 DE1004 der UTILTS
1913 fn evaluate_558(&self, _ctx: &EvaluationContext) -> ConditionResult {
1914 // Hinweis: Dokumentennummer aus BGM+Z78 DE1004 der UTILTS — informational note, always applies
1915 ConditionResult::True
1916 }
1917
1918 /// [559] Hinweis: Dokumentennummer aus BGM+Z79 DE1004 der UTILTS
1919 fn evaluate_559(&self, _ctx: &EvaluationContext) -> ConditionResult {
1920 // Hinweis: Dokumentennummer aus BGM+Z79 DE1004 der UTILTS — informational note, always applies
1921 ConditionResult::True
1922 }
1923
1924 /// [560] Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z80
1925 fn evaluate_560(&self, _ctx: &EvaluationContext) -> ConditionResult {
1926 // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z80 — informational note, always applies
1927 ConditionResult::True
1928 }
1929
1930 /// [561] Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z81
1931 fn evaluate_561(&self, _ctx: &EvaluationContext) -> ConditionResult {
1932 // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z81 — informational note, always applies
1933 ConditionResult::True
1934 }
1935
1936 /// [562] Hinweis: Wert aus BGM+Z73 DE1004 der IFTSTA mit der die Antwort auf die Bestellung der Konfiguration übermittelt wurde
1937 fn evaluate_562(&self, _ctx: &EvaluationContext) -> ConditionResult {
1938 // Hinweis: Wert aus BGM+Z73 DE1004 der IFTSTA — informational note, always applies
1939 ConditionResult::True
1940 }
1941
1942 /// [563] Hinweis: Vorgangsnummer aus CNI DE1490 der IFTSTA mit BGM+Z73 mit der die Antwort auf die Bestellung der Konfiguration übermittelt wurde
1943 fn evaluate_563(&self, _ctx: &EvaluationContext) -> ConditionResult {
1944 // Hinweis: Vorgangsnummer aus CNI DE1490 der IFTSTA mit BGM+Z73 mit der die Antwort auf die Bestellung der Konfiguration übermittelt wurde — informational note, always applies
1945 ConditionResult::True
1946 }
1947
1948 /// [564] Hinweis: Für den Empfang der Werte nach Typ 2 aus dem SMGW.
1949 fn evaluate_564(&self, _ctx: &EvaluationContext) -> ConditionResult {
1950 // Hinweis: Für den Empfang der Werte nach Typ 2 aus dem SMGW — informational note, always applies
1951 ConditionResult::True
1952 }
1953
1954 /// [566] Hinweis: Verwendung der ID der Technischen Ressource
1955 fn evaluate_566(&self, _ctx: &EvaluationContext) -> ConditionResult {
1956 // Hinweis: Verwendung der ID der Technischen Ressource — informational note, always applies
1957 ConditionResult::True
1958 }
1959
1960 /// [567] Hinweis: Es darf nur eine Information im DE3148 übermittelt werden
1961 fn evaluate_567(&self, _ctx: &EvaluationContext) -> ConditionResult {
1962 // Hinweis: Es darf nur eine Information im DE3148 übermittelt werden — informational note, always applies
1963 ConditionResult::True
1964 }
1965
1966 /// [568] Hinweis: Wenn die Einrichtung der Konfiguration mit einer Zählzeit übermittelt wird, ist hier die MP-ID des NB als Eigentümer der Liste der Zählzeit einzutragen.
1967 fn evaluate_568(&self, _ctx: &EvaluationContext) -> ConditionResult {
1968 // Hinweis: Wenn die Einrichtung der Konfiguration mit einer Zählzeit übermittelt wird, ist hier die MP-ID des NB als Eigentümer der Liste der Zählzeit einzutragen — informational note, always applies
1969 ConditionResult::True
1970 }
1971
1972 /// [569] Hinweis: MaBiS-Zählpunkt der LF-SZR
1973 fn evaluate_569(&self, _ctx: &EvaluationContext) -> ConditionResult {
1974 // Hinweis: MaBiS-Zählpunkt der LF-SZR — informational note, always applies
1975 ConditionResult::True
1976 }
1977
1978 /// [570] Hinweis: zur Angabe von Kontaktdaten des Kunden des Lieferanten um die Änderung an der Technik zu vereinfachen.
1979 fn evaluate_570(&self, _ctx: &EvaluationContext) -> ConditionResult {
1980 // Hinweis: zur Angabe von Kontaktdaten des Kunden des Lieferanten um die Änderung an der Technik zu vereinfachen — informational note, always applies
1981 ConditionResult::True
1982 }
1983
1984 /// [571] Hinweis: MSB der Marktlokation, an den die Werte der weiteren Energieflussrichtung der Messlokation zu übermitteln sind.
1985 fn evaluate_571(&self, _ctx: &EvaluationContext) -> ConditionResult {
1986 // Hinweis: MSB der Marktlokation, an den die Werte der weiteren Energieflussrichtung der Messlokation zu übermitteln sind — informational note, always applies
1987 ConditionResult::True
1988 }
1989
1990 /// [572] Hinweis: MSB der Marktlokation der Kundenanlage, in der die betroffene Lokation integriert wird.
1991 fn evaluate_572(&self, _ctx: &EvaluationContext) -> ConditionResult {
1992 // Hinweis: MSB der Marktlokation der Kundenanlage, in der die betroffene Lokation integriert wird — informational note, always applies
1993 ConditionResult::True
1994 }
1995
1996 /// [573] Hinweis: Es ist eine URI IPv4 für die Bereitstellung der Werte anzugeben.
1997 fn evaluate_573(&self, _ctx: &EvaluationContext) -> ConditionResult {
1998 // Hinweis: Es ist eine URI IPv4 für die Bereitstellung der Werte anzugeben — informational note, always applies
1999 ConditionResult::True
2000 }
2001
2002 /// [574] Hinweis: Es ist eine URI IPv6 für die Bereitstellung der Werte anzugeben.
2003 fn evaluate_574(&self, _ctx: &EvaluationContext) -> ConditionResult {
2004 // Hinweis: Es ist eine URI IPv6 für die Bereitstellung der Werte anzugeben.
2005 ConditionResult::True
2006 }
2007
2008 /// [575] Hinweis: Wenn der gewünschte Änderungszeitpunkt ein fixer Zeitpunkt ist.
2009 fn evaluate_575(&self, _ctx: &EvaluationContext) -> ConditionResult {
2010 // Hinweis: Wenn der gewünschte Änderungszeitpunkt ein fixer Zeitpunkt ist.
2011 ConditionResult::True
2012 }
2013
2014 /// [576] Hinweis: Wenn der gewünschte Änderungszeitpunkt ein nächst möglicher Termin zum oder nach dem angegebenen Zeitpunkt ist.
2015 fn evaluate_576(&self, _ctx: &EvaluationContext) -> ConditionResult {
2016 // Hinweis: Wenn der gewünschte Änderungszeitpunkt ein nächst möglicher Termin zum oder nach dem angegebenen Zeitpunkt ist.
2017 ConditionResult::True
2018 }
2019
2020 /// [903] Format: Möglicher Wert: 1
2021 fn evaluate_903(&self, _ctx: &EvaluationContext) -> ConditionResult {
2022 ConditionResult::True
2023 }
2024
2025 /// [906] Format: max. 3 Nachkommastellen
2026 fn evaluate_906(&self, ctx: &EvaluationContext) -> ConditionResult {
2027 ctx.format_check("QTY", 0, 1, |val| validate_max_decimal_places(val, 3))
2028 }
2029
2030 /// [911] Format: Mögliche Werte: 1 bis n, je Nachricht oder Segmentgruppe bei 1 beginnend und fortlaufend aufsteigend
2031 fn evaluate_911(&self, _ctx: &EvaluationContext) -> ConditionResult {
2032 // Hinweis: Mögliche Werte: 1 bis n, je Nachricht oder Segmentgruppe bei 1 beginnend und fortlaufend aufsteigend
2033 // This is a cardinality/sequencing annotation — informational, always applies
2034 ConditionResult::True
2035 }
2036
2037 /// [914] Format: Möglicher Wert: >0
2038 fn evaluate_914(&self, ctx: &EvaluationContext) -> ConditionResult {
2039 ctx.format_check("QTY", 0, 1, |val| validate_numeric(val, ">", 0.0))
2040 }
2041
2042 /// [922] Format: TR-ID
2043 // REVIEW: TR-ID (Transaktionsreferenz-ID) format. In ORDERS the transaction reference ID appears in BGM C106. The exact segment context depends on the AHB field definition — implemented as max-length-35 check on BGM, consistent with EDIFACT AN..35 data element constraints. Medium confidence because the target segment may differ by AHB row. (medium confidence)
2044 fn evaluate_922(&self, ctx: &EvaluationContext) -> ConditionResult {
2045 // Format: TR-ID — Transaktionsreferenz-ID, max 35 alphanumeric characters
2046 // In ORDERS, TR-ID typically appears in BGM element 1 (C106 document identifier)
2047 let segs = ctx.find_segments("BGM");
2048 match segs
2049 .first()
2050 .and_then(|s| s.elements.get(1))
2051 .and_then(|e| e.first())
2052 {
2053 Some(val) if !val.is_empty() => validate_max_length(val, 35),
2054 Some(_) => ConditionResult::False,
2055 None => ConditionResult::False, // segment absent → condition not applicable
2056 }
2057 }
2058
2059 /// [930] Format: max. 2 Nachkommastellen
2060 fn evaluate_930(&self, ctx: &EvaluationContext) -> ConditionResult {
2061 ctx.format_check("QTY", 0, 1, |val| validate_max_decimal_places(val, 2))
2062 }
2063
2064 /// [931] Format: ZZZ = +00
2065 fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
2066 ctx.format_check("DTM", 0, 1, validate_timezone_utc)
2067 }
2068
2069 /// [932] Format: HHMM = 2200
2070 // REVIEW: HHMM = 2200 time constraint on DTM. In ORDERS FV2510, delivery period end (qualifier 163) must terminate at 22:00 UTC, matching the standard German grid day-end convention. Medium confidence because the target DTM qualifier may differ for the specific AHB row — 163 is the most likely candidate for an end-of-period constraint. (medium confidence)
2071 fn evaluate_932(&self, ctx: &EvaluationContext) -> ConditionResult {
2072 ctx.format_check_qualified("DTM", 0, "163", 0, 1, |val| {
2073 validate_hhmm_equals(val, "2200")
2074 })
2075 }
2076
2077 /// [933] Format: HHMM = 2300
2078 fn evaluate_933(&self, ctx: &EvaluationContext) -> ConditionResult {
2079 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "2300"))
2080 }
2081
2082 /// [934] Format: HHMM = 0400
2083 fn evaluate_934(&self, ctx: &EvaluationContext) -> ConditionResult {
2084 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "0400"))
2085 }
2086
2087 /// [935] Format: HHMM = 0500
2088 fn evaluate_935(&self, ctx: &EvaluationContext) -> ConditionResult {
2089 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "0500"))
2090 }
2091
2092 /// [939] Format: Die Zeichenkette muss die Zeichen @ und . enthalten
2093 fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
2094 ctx.format_check("COM", 0, 0, validate_email)
2095 }
2096
2097 /// [940] Format: Die Zeichenkette muss mit dem Zeichen + beginnen und danach dürfen nur noch Ziffern folgen
2098 fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
2099 ctx.format_check("COM", 0, 0, validate_phone)
2100 }
2101
2102 /// [950] Format: Marktlokations-ID
2103 fn evaluate_950(&self, ctx: &EvaluationContext) -> ConditionResult {
2104 ctx.format_check_qualified("LOC", 0, "Z16", 1, 0, validate_malo_id)
2105 }
2106
2107 /// [951] Format: Zählpunktbezeichnung
2108 fn evaluate_951(&self, ctx: &EvaluationContext) -> ConditionResult {
2109 ctx.format_check_qualified("LOC", 0, "Z17", 1, 0, validate_zahlpunkt)
2110 }
2111
2112 /// [955] Format: Möglicher Wert: <100
2113 // REVIEW: Format: Möglicher Wert: <100 — numeric value must be less than 100. Most likely applies to a QTY quantity value (C186.D6060, elements[0][1]). validate_numeric with "<" and threshold 100.0 covers this. Medium confidence because the exact segment context (QTY vs PRI vs PCT) is not specified — QTY is the most common numeric value carrier in ORDERS. (medium confidence)
2114 fn evaluate_955(&self, ctx: &EvaluationContext) -> ConditionResult {
2115 ctx.format_check("QTY", 0, 1, |val| validate_numeric(val, "<", 100.0))
2116 }
2117
2118 /// [960] Format: Netzlokations-ID
2119 // HAND-EDITED: a Netzlokations-ID is "E" + ten alphanumerics (`E1688117482`),
2120 // not MaLo-shaped; `validate_malo_id` rejected every real one (#173).
2121 fn evaluate_960(&self, ctx: &EvaluationContext) -> ConditionResult {
2122 ctx.format_check_qualified("LOC", 0, "Z18", 1, 0, validate_nelo_id)
2123 }
2124
2125 /// [961] Format: SR-ID
2126 fn evaluate_961(&self, ctx: &EvaluationContext) -> ConditionResult {
2127 ctx.format_check_qualified("LOC", 0, "Z19", 1, 0, validate_malo_id)
2128 }
2129
2130 /// [962] Format: max. 6 Vorkommastellen
2131 // REVIEW: Format: max 6 integer digits (Vorkommastellen). Applied to QTY element[0][1] as the most common numeric data field in ORDERS requiring integer-part validation. Uses validate_max_integer_digits helper. Confidence medium because the target segment is inferred from context rather than explicitly stated. (medium confidence)
2132 fn evaluate_962(&self, ctx: &EvaluationContext) -> ConditionResult {
2133 ctx.format_check("QTY", 0, 1, |val| validate_max_integer_digits(val, 6))
2134 }
2135
2136 /// [2002] Ist mindestens zwei Mal anzugeben
2137 // REVIEW: Must be specified at least twice. Counts DTM+203 (Ausführungsdatum, qualifier at elements[0][0]) occurrences as a proxy for SG29 group instance count since each SG29 contains exactly one DTM+203. Condition is True when count >= 2. (medium confidence)
2138 fn evaluate_2002(&self, ctx: &EvaluationContext) -> ConditionResult {
2139 // "Ist mindestens zwei Mal anzugeben" — SG29 must appear at least twice.
2140 // DTM+203 (Ausführungsdatum) occurs exactly once per SG29 instance,
2141 // so counting DTM+203 segments gives the SG29 repetition count.
2142 let count = ctx.find_segments_with_qualifier("DTM", 0, "203").len();
2143 ConditionResult::from(count >= 2)
2144 }
2145
2146 /// [2003] Die SG29 ist so oft zu wiederholen, wie ab dem DTM+203 (Ausführungsdatum) Messlokationen zu der in der SG2 genannten Marktlokation vorhanden sind und für jede dieser Messlokationen müssen alle M...
2147 fn evaluate_2003(&self, _ctx: &EvaluationContext) -> ConditionResult {
2148 // Hinweis: SG29 repetition cardinality rule — informational annotation documenting that
2149 // SG29 must repeat once per Messlokation associated with the Marktlokation from DTM+203,
2150 // and all Messprodukte for each Messlokation (including Tranchen) must be listed.
2151 // This is a structural cardinality guidance note, always applies.
2152 ConditionResult::True
2153 }
2154
2155 /// [2004] Die SG29 ist so oft zu wiederholen, dass alle Geräte der betroffenen Geräteart die im Rahmen des Gerätewechsels aufgrund MSB-Wechsel getauscht werden sollen genannt sind.
2156 fn evaluate_2004(&self, _ctx: &EvaluationContext) -> ConditionResult {
2157 // Hinweis: Die SG29 ist so oft zu wiederholen, dass alle Geräte der betroffenen Geräteart
2158 // die im Rahmen des Gerätewechsels aufgrund MSB-Wechsel getauscht werden sollen, genannt sind.
2159 // Informational cardinality note — always applies.
2160 ConditionResult::True
2161 }
2162
2163 /// [2005] Pro SG29 LIN ist die SG34 RFF+Z09 (Gerätenummer) genau einmal anzugeben
2164 // REVIEW: Per SG29 LIN, RFF+Z09 (Gerätenummer) must appear exactly once. We check that there is exactly one RFF segment with qualifier Z09 in the message context. This is a cardinality constraint evaluated at message level via segment counting. (medium confidence)
2165 fn evaluate_2005(&self, ctx: &EvaluationContext) -> ConditionResult {
2166 {
2167 let rffs = ctx.find_segments_with_qualifier("RFF", 0, "Z09");
2168 ConditionResult::from(rffs.len() == 1)
2169 }
2170 }
2171
2172 /// [2006] Pro SG29 LIN ist die SG34 RFF+Z09 (Gerätenummer) bis zu dreimal anzugeben
2173 // REVIEW: Per SG29 LIN, RFF+Z09 (Gerätenummer) may appear up to three times. We verify that at most 3 RFF segments with qualifier Z09 exist in the message context. (medium confidence)
2174 fn evaluate_2006(&self, ctx: &EvaluationContext) -> ConditionResult {
2175 {
2176 let rffs = ctx.find_segments_with_qualifier("RFF", 0, "Z09");
2177 ConditionResult::from(rffs.len() <= 3)
2178 }
2179 }
2180
2181 /// [2007] Die SG29 ist so oft zu wiederholen, wie ab dem DTM+203 (Ausführungsdatum) Messlokationen zu der in der SG2 genannten Netzlokation vorhanden sind und für jede dieser Messlokationen müssen alle Me...
2182 fn evaluate_2007(&self, _ctx: &EvaluationContext) -> ConditionResult {
2183 // Hinweis: Die SG29 ist so oft zu wiederholen, wie ab dem DTM+203 (Ausführungsdatum)
2184 // Messlokationen zu der in der SG2 genannten Netzlokation vorhanden sind und für jede
2185 // dieser Messlokationen müssen alle Messprodukte genannt sein, die ab dem DTM+203
2186 // (Ausführungsdatum) in der SG2 genannten Netzlokation vorhanden sind.
2187 // Informational cardinality note — always applies.
2188 ConditionResult::True
2189 }
2190
2191 /// [2044] Pro SG29 LIN ist die SG29 PIA genau einmal anzugeben
2192 // REVIEW: Per SG29 LIN, the SG29 PIA segment must appear exactly once. We count PIA segments in the message and check for exactly one occurrence. This is a structural cardinality check on the PIA segment. (medium confidence)
2193 fn evaluate_2044(&self, ctx: &EvaluationContext) -> ConditionResult {
2194 {
2195 let pias = ctx.find_segments("PIA");
2196 ConditionResult::from(pias.len() == 1)
2197 }
2198 }
2199
2200 /// [2050] Pro Nachricht ist die SG29 genau einmal anzugeben
2201 // REVIEW: Per message, SG29 (identified by its entry segment LIN) must appear exactly once. We count all LIN segments in the message and check for exactly one occurrence. (medium confidence)
2202 fn evaluate_2050(&self, ctx: &EvaluationContext) -> ConditionResult {
2203 {
2204 let lins = ctx.find_segments("LIN");
2205 ConditionResult::from(lins.len() == 1)
2206 }
2207 }
2208
2209 /// [2060] Pro Nachricht ist die SG29 LIN+Z64 (Erforderliches Produkt Schaltzeitdefinitionen) maximal einmal anzugeben
2210 fn evaluate_2060(&self, ctx: &EvaluationContext) -> ConditionResult {
2211 {
2212 let lins = ctx.find_segments("LIN");
2213 let count = lins
2214 .iter()
2215 .filter(|s| {
2216 s.elements
2217 .get(1)
2218 .and_then(|e| e.first())
2219 .is_some_and(|v| v == "Z64")
2220 })
2221 .count();
2222 ConditionResult::from(count <= 1)
2223 }
2224 }
2225
2226 /// [2061] Pro Nachricht ist die SG29 LIN++Z65 (Erforderliches Produkt Leistungskurvendefinitionen) maximal einmal anzugeben
2227 fn evaluate_2061(&self, ctx: &EvaluationContext) -> ConditionResult {
2228 {
2229 let lins = ctx.find_segments("LIN");
2230 let count = lins
2231 .iter()
2232 .filter(|s| {
2233 s.elements
2234 .get(1)
2235 .and_then(|e| e.first())
2236 .is_some_and(|v| v == "Z65")
2237 })
2238 .count();
2239 ConditionResult::from(count <= 1)
2240 }
2241 }
2242
2243 /// [2062] Pro Nachricht ist die SG29 LIN++Z66 (Erforderliches Produkt Ad-hoc-Steuerkanal) maximal einmal anzugeben
2244 // REVIEW: Count LIN segments where elements[1][0]=="Z66" (LIN++Z66, ad-hoc Steuerkanal). Condition is True when at most one such SG29 line item is present per message. (medium confidence)
2245 fn evaluate_2062(&self, ctx: &EvaluationContext) -> ConditionResult {
2246 let count = ctx
2247 .find_segments("LIN")
2248 .iter()
2249 .filter(|s| {
2250 s.elements
2251 .get(1)
2252 .and_then(|e| e.first())
2253 .is_some_and(|v| v == "Z66")
2254 })
2255 .count();
2256 ConditionResult::from(count <= 1)
2257 }
2258
2259 /// [2063] Pro Nachricht ist die SG29 LIN++Z67 (Erforderliches Messprodukt für Werte nach Typ 2 aus Backend) maximal einmal anzugeben
2260 // REVIEW: Count LIN segments where elements[1][0]=="Z67" (LIN++Z67, Messprodukt Typ 2 Backend). Condition is True when at most one such SG29 line item is present per message. (medium confidence)
2261 fn evaluate_2063(&self, ctx: &EvaluationContext) -> ConditionResult {
2262 let count = ctx
2263 .find_segments("LIN")
2264 .iter()
2265 .filter(|s| {
2266 s.elements
2267 .get(1)
2268 .and_then(|e| e.first())
2269 .is_some_and(|v| v == "Z67")
2270 })
2271 .count();
2272 ConditionResult::from(count <= 1)
2273 }
2274
2275 /// [2064] Pro Nachricht ist die SG29 LIN++Z68 (Erforderliches Produkt Konfigurationserlaubnis für Werte nach Typ 2 aus SMGW) maximal einmal anzugeben
2276 // REVIEW: Count LIN segments where elements[1][0]=="Z68" (LIN++Z68, Konfigurationserlaubnis Typ 2 SMGW). Condition is True when at most one such SG29 line item is present per message. (medium confidence)
2277 fn evaluate_2064(&self, ctx: &EvaluationContext) -> ConditionResult {
2278 let count = ctx
2279 .find_segments("LIN")
2280 .iter()
2281 .filter(|s| {
2282 s.elements
2283 .get(1)
2284 .and_then(|e| e.first())
2285 .is_some_and(|v| v == "Z68")
2286 })
2287 .count();
2288 ConditionResult::from(count <= 1)
2289 }
2290
2291 /// [2066] Die SG3 RFF+Z37 Referenz auf ID der Technischen Ressource ist so oft zu wiederholen, bis alle IDs der Technischen Ressourcen angegeben sind, die der Steuerbaren Ressource in LOC+172 DE3225 (Meldepu...
2292 fn evaluate_2066(&self, _ctx: &EvaluationContext) -> ConditionResult {
2293 // Hinweis: Die SG3 RFF+Z37 ist so oft zu wiederholen, bis alle IDs der Technischen
2294 // Ressourcen angegeben sind, die der Steuerbaren Ressource in LOC+172 DE3225 (Meldepunkt)
2295 // mit diesem Vorgang zugeordnet werden sollen.
2296 // Informational cardinality note — always applies.
2297 ConditionResult::True
2298 }
2299
2300 /// [2088] Die SG29 ist so oft zu wiederholen, dass alle Messprodukte ab dem DTM+203 (Ausführungsdatum) zu der in der SG2 genannten Netzlokation genannt sind.
2301 fn evaluate_2088(&self, _ctx: &EvaluationContext) -> ConditionResult {
2302 // Hinweis: Die SG29 ist so oft zu wiederholen, dass alle Messprodukte ab dem DTM+203
2303 // (Ausführungsdatum) zu der in der SG2 genannten Netzlokation genannt sind.
2304 // Informational cardinality note — always applies.
2305 ConditionResult::True
2306 }
2307
2308 /// [2089] Die SG29 ist so oft zu wiederholen, dass alle Messprodukte ab dem DTM+203 (Ausführungsdatum) zu der in der SG2 genannten Marktlokation genannt sind.
2309 fn evaluate_2089(&self, _ctx: &EvaluationContext) -> ConditionResult {
2310 // Hinweis: Die SG29 ist so oft zu wiederholen, dass alle Messprodukte ab dem DTM+203
2311 // (Ausführungsdatum) zu der in der SG2 genannten Marktlokation genannt sind.
2312 // Informational cardinality note about SG29 repetition count — always applies.
2313 ConditionResult::True
2314 }
2315
2316 /// [2090] Für 33-stellige ID im SG2 LOC+172 (Meldepunkt) DE3225 mindestens einmal anzugeben
2317 fn evaluate_2090(&self, ctx: &EvaluationContext) -> ConditionResult {
2318 let locs = ctx.find_segments_with_qualifier("LOC", 0, "172");
2319 ConditionResult::from(locs.iter().any(|s| {
2320 s.elements
2321 .get(1)
2322 .and_then(|e| e.first())
2323 .is_some_and(|v| v.len() == 33)
2324 }))
2325 }
2326
2327 /// [2092] Pro Nachricht ist die SG29 maximal einmal anzugeben
2328 // REVIEW: SG29 is initiated by the LIN segment. Count all LIN segments in the message and verify there is at most one, making the condition True when the cardinality constraint is satisfied. (medium confidence)
2329 fn evaluate_2092(&self, ctx: &EvaluationContext) -> ConditionResult {
2330 ConditionResult::from(ctx.find_segments("LIN").len() <= 1)
2331 }
2332
2333 /// [2094] Pro Nachricht ist die SG29 LIN (Positionsdaten) so oft anzugeben, wie Positionen aus dem Angebot, welches in SG1 RFF+AAG (Referenz Nachrichtennummer), DE1154 angegeben ist, bestellt werden sollen.
2334 fn evaluate_2094(&self, _ctx: &EvaluationContext) -> ConditionResult {
2335 // Hinweis: Pro Nachricht ist die SG29 LIN (Positionsdaten) so oft anzugeben, wie
2336 // Positionen aus dem Angebot (referenziert in SG1 RFF+AAG DE1154) bestellt werden sollen.
2337 // Informational cardinality note — the required repetition count depends on an external
2338 // offer document that cannot be inspected from within this EDIFACT message.
2339 ConditionResult::True
2340 }
2341
2342 /// [2095] Diese SG29 ist so oft zu wiederholen, dass alle Produkte zur Lokation die ab dem DTM+203 (Ausführungsdatum) gewünscht sind und deren Kombination gemäß Codeliste der Konfigurationen Kapitel 7 "P...
2343 fn evaluate_2095(&self, _ctx: &EvaluationContext) -> ConditionResult {
2344 // Hinweis: Diese SG29 ist so oft zu wiederholen, dass alle Produkte zur Lokation
2345 // ab dem DTM+203 (Ausführungsdatum) genannt sind, deren Kombination gemäß
2346 // Codeliste der Konfigurationen Kapitel 7 möglich sind.
2347 // Informational cardinality note — valid combinations are defined by an external
2348 // code list (Kapitel 7) and cannot be validated from EDIFACT content alone.
2349 ConditionResult::True
2350 }
2351
2352 /// [2096] Die SG3 Referenz auf die ID der Tranche ist so oft zu wiederholen, wie ab dem DTM+203 (Ausführungsdatum) Tranchen zu der in der SG2 genannten Marktlokation vorhanden sind.
2353 fn evaluate_2096(&self, _ctx: &EvaluationContext) -> ConditionResult {
2354 // Hinweis: Die SG3 Referenz auf die ID der Tranche ist so oft zu wiederholen, wie
2355 // ab dem DTM+203 (Ausführungsdatum) Tranchen zu der in der SG2 genannten
2356 // Marktlokation vorhanden sind.
2357 // Informational cardinality note — the number of Tranchen for a Marktlokation is
2358 // business context that cannot be determined from the EDIFACT message alone.
2359 ConditionResult::True
2360 }
2361
2362 /// [2097] Die SG29 ist so oft zu wiederholen, dass für alle in SG3 Referenz auf ID der Tranche genannten Tranchen mindestens eine SG29 vorhanden ist.
2363 fn evaluate_2097(&self, _ctx: &EvaluationContext) -> ConditionResult {
2364 // Hinweis: Die SG29 ist so oft zu wiederholen, dass für alle in SG3 RFF+Z20
2365 // (Referenz auf ID der Tranche) genannten Tranchen mindestens eine SG29 vorhanden ist.
2366 // Informational completeness note — each Tranche referenced in SG3 must have
2367 // at least one corresponding SG29. Documents structural pairing requirements.
2368 ConditionResult::True
2369 }
2370
2371 /// [2098] Die SG2 Lieferant an der Lokation ist so oft zu wiederholen, dass für alle in SG3 Referenz auf ID der Tranche genannten Tranchen genau eine SG2 Lieferant der Lokation vorhanden ist.
2372 // REVIEW: Cardinality rule: SG2 repetition count must equal the number of SG3 tranche references. Implemented by comparing count_in_group for both groups within SG29. Medium confidence because exact group paths and SG3 RFF qualifier for 'Tranche ID' are not confirmed without the full MIG segment structure reference — the paths &["SG29", "SG2"] and &["SG29", "SG3"] are based on standard ORDERS tx_group conventions from project memory. (medium confidence)
2373 fn evaluate_2098(&self, ctx: &EvaluationContext) -> ConditionResult {
2374 // SG2 Lieferant an der Lokation must repeat once per SG3 tranche reference.
2375 // Count SG2 group instances (NAD as entry segment) and SG3 RFF tranche references.
2376 // Both counts must be equal and non-zero for the condition to be satisfied.
2377 let sg2_count = ctx.count_in_group("NAD", &["SG29", "SG2"]);
2378 let sg3_count = ctx.count_in_group("RFF", &["SG29", "SG3"]);
2379 if sg2_count == 0 || sg3_count == 0 {
2380 return ConditionResult::Unknown;
2381 }
2382 ConditionResult::from(sg2_count == sg3_count)
2383 }
2384
2385 /// [2099] Die SG2 Lieferant an der Lokation ist genau einmal anzugeben.
2386 // REVIEW: Simple cardinality check: SG2 must appear exactly once (genau einmal). Implemented using count_in_group on NAD (the entry segment of SG2) within SG29. Returns Unknown when no SG2 is found at all (not yet present), False when count > 1, True when exactly 1. Medium confidence due to unconfirmed group path without the full EDIFACT Segment Structure Reference for this PID. (medium confidence)
2387 fn evaluate_2099(&self, ctx: &EvaluationContext) -> ConditionResult {
2388 // SG2 Lieferant an der Lokation must appear exactly once.
2389 // Count NAD segments (entry segment of SG2) within the SG29 SG2 group path.
2390 let count = ctx.count_in_group("NAD", &["SG29", "SG2"]);
2391 if count == 0 {
2392 return ConditionResult::Unknown;
2393 }
2394 ConditionResult::from(count == 1)
2395 }
2396}