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