automapper_validation/generated/fv2510/ordrsp_conditions_fv2510.rs
1// <auto-generated>
2// Generated by automapper-generator generate-conditions
3// AHB: xml-migs-and-ahbs/FV2510/ORDRSP_AHB_1_1_Fehlerkorrektur_20250417.xml
4// Generated: 2026-03-12T10:41:52Z
5// </auto-generated>
6
7// LLM-produced bodies aren't idiomatic Rust — silence stylistic lints at
8// file scope so `cargo clippy -D warnings` stays green. Correctness,
9// suspicious, and perf categories stay on so real bugs still surface.
10#![allow(clippy::style, clippy::complexity)]
11
12#[allow(unused_imports)]
13use crate::eval::format_validators::*;
14use crate::eval::{Cluster, ConditionEvaluator, ConditionResult, EvaluationContext};
15// HAND-EDITED: shared cluster helpers for conditions [17]/[18].
16// Preserve across regeneration — see CLAUDE.md "Codelist Providers".
17use crate::eval::ebd_cluster::resolved_sts_code_in_cluster;
18
19/// Generated condition evaluator for ORDRSP FV2510.
20pub struct OrdrspConditionEvaluatorFV2510 {
21 // External condition IDs that require runtime context.
22 external_conditions: std::collections::HashSet<u32>,
23}
24
25impl Default for OrdrspConditionEvaluatorFV2510 {
26 fn default() -> Self {
27 let mut external_conditions = std::collections::HashSet::new();
28 external_conditions.insert(3);
29 external_conditions.insert(4);
30 external_conditions.insert(5);
31 external_conditions.insert(7);
32 external_conditions.insert(9);
33 external_conditions.insert(10);
34 external_conditions.insert(12);
35 external_conditions.insert(13);
36 external_conditions.insert(14);
37 external_conditions.insert(15);
38 external_conditions.insert(16);
39 // HAND-EDITED: [17]/[18] are no longer external — they now read
40 // the EBD cluster lookup directly. See FV2504 counterpart.
41 // external_conditions.insert(17);
42 // external_conditions.insert(18);
43 external_conditions.insert(29);
44 external_conditions.insert(30);
45 external_conditions.insert(31);
46 external_conditions.insert(32);
47 external_conditions.insert(40);
48 external_conditions.insert(49);
49 external_conditions.insert(52);
50 external_conditions.insert(60);
51 external_conditions.insert(70);
52 external_conditions.insert(71);
53 external_conditions.insert(75);
54 external_conditions.insert(492);
55 external_conditions.insert(493);
56 Self {
57 external_conditions,
58 }
59 }
60}
61
62impl ConditionEvaluator for OrdrspConditionEvaluatorFV2510 {
63 fn message_type(&self) -> &str {
64 "ORDRSP"
65 }
66
67 fn format_version(&self) -> &str {
68 "FV2510"
69 }
70
71 fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
72 match condition {
73 1 => self.evaluate_1(ctx),
74 3 => self.evaluate_3(ctx),
75 4 => self.evaluate_4(ctx),
76 5 => self.evaluate_5(ctx),
77 7 => self.evaluate_7(ctx),
78 9 => self.evaluate_9(ctx),
79 10 => self.evaluate_10(ctx),
80 11 => self.evaluate_11(ctx),
81 12 => self.evaluate_12(ctx),
82 13 => self.evaluate_13(ctx),
83 14 => self.evaluate_14(ctx),
84 15 => self.evaluate_15(ctx),
85 16 => self.evaluate_16(ctx),
86 17 => self.evaluate_17(ctx),
87 18 => self.evaluate_18(ctx),
88 21 => self.evaluate_21(ctx),
89 22 => self.evaluate_22(ctx),
90 23 => self.evaluate_23(ctx),
91 24 => self.evaluate_24(ctx),
92 25 => self.evaluate_25(ctx),
93 27 => self.evaluate_27(ctx),
94 28 => self.evaluate_28(ctx),
95 29 => self.evaluate_29(ctx),
96 30 => self.evaluate_30(ctx),
97 31 => self.evaluate_31(ctx),
98 32 => self.evaluate_32(ctx),
99 33 => self.evaluate_33(ctx),
100 34 => self.evaluate_34(ctx),
101 37 => self.evaluate_37(ctx),
102 38 => self.evaluate_38(ctx),
103 39 => self.evaluate_39(ctx),
104 40 => self.evaluate_40(ctx),
105 41 => self.evaluate_41(ctx),
106 42 => self.evaluate_42(ctx),
107 43 => self.evaluate_43(ctx),
108 44 => self.evaluate_44(ctx),
109 45 => self.evaluate_45(ctx),
110 46 => self.evaluate_46(ctx),
111 47 => self.evaluate_47(ctx),
112 48 => self.evaluate_48(ctx),
113 49 => self.evaluate_49(ctx),
114 50 => self.evaluate_50(ctx),
115 51 => self.evaluate_51(ctx),
116 52 => self.evaluate_52(ctx),
117 53 => self.evaluate_53(ctx),
118 54 => self.evaluate_54(ctx),
119 55 => self.evaluate_55(ctx),
120 56 => self.evaluate_56(ctx),
121 57 => self.evaluate_57(ctx),
122 58 => self.evaluate_58(ctx),
123 59 => self.evaluate_59(ctx),
124 60 => self.evaluate_60(ctx),
125 61 => self.evaluate_61(ctx),
126 62 => self.evaluate_62(ctx),
127 63 => self.evaluate_63(ctx),
128 64 => self.evaluate_64(ctx),
129 65 => self.evaluate_65(ctx),
130 66 => self.evaluate_66(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 71 => self.evaluate_71(ctx),
136 72 => self.evaluate_72(ctx),
137 73 => self.evaluate_73(ctx),
138 74 => self.evaluate_74(ctx),
139 75 => self.evaluate_75(ctx),
140 76 => self.evaluate_76(ctx),
141 77 => self.evaluate_77(ctx),
142 78 => self.evaluate_78(ctx),
143 79 => self.evaluate_79(ctx),
144 80 => self.evaluate_80(ctx),
145 81 => self.evaluate_81(ctx),
146 82 => self.evaluate_82(ctx),
147 83 => self.evaluate_83(ctx),
148 490 => self.evaluate_490(ctx),
149 491 => self.evaluate_491(ctx),
150 492 => self.evaluate_492(ctx),
151 493 => self.evaluate_493(ctx),
152 494 => self.evaluate_494(ctx),
153 500 => self.evaluate_500(ctx),
154 503 => self.evaluate_503(ctx),
155 504 => self.evaluate_504(ctx),
156 513 => self.evaluate_513(ctx),
157 518 => self.evaluate_518(ctx),
158 519 => self.evaluate_519(ctx),
159 520 => self.evaluate_520(ctx),
160 521 => self.evaluate_521(ctx),
161 522 => self.evaluate_522(ctx),
162 523 => self.evaluate_523(ctx),
163 524 => self.evaluate_524(ctx),
164 525 => self.evaluate_525(ctx),
165 526 => self.evaluate_526(ctx),
166 527 => self.evaluate_527(ctx),
167 529 => self.evaluate_529(ctx),
168 530 => self.evaluate_530(ctx),
169 533 => self.evaluate_533(ctx),
170 534 => self.evaluate_534(ctx),
171 535 => self.evaluate_535(ctx),
172 536 => self.evaluate_536(ctx),
173 537 => self.evaluate_537(ctx),
174 538 => self.evaluate_538(ctx),
175 539 => self.evaluate_539(ctx),
176 540 => self.evaluate_540(ctx),
177 542 => self.evaluate_542(ctx),
178 543 => self.evaluate_543(ctx),
179 544 => self.evaluate_544(ctx),
180 545 => self.evaluate_545(ctx),
181 546 => self.evaluate_546(ctx),
182 547 => self.evaluate_547(ctx),
183 548 => self.evaluate_548(ctx),
184 902 => self.evaluate_902(ctx),
185 903 => self.evaluate_903(ctx),
186 930 => self.evaluate_930(ctx),
187 931 => self.evaluate_931(ctx),
188 932 => self.evaluate_932(ctx),
189 933 => self.evaluate_933(ctx),
190 934 => self.evaluate_934(ctx),
191 935 => self.evaluate_935(ctx),
192 939 => self.evaluate_939(ctx),
193 940 => self.evaluate_940(ctx),
194 2036 => self.evaluate_2036(ctx),
195 _ => ConditionResult::Unknown,
196 }
197 }
198
199 fn is_external(&self, condition: u32) -> bool {
200 self.external_conditions.contains(&condition)
201 }
202 fn is_known(&self, condition: u32) -> bool {
203 matches!(
204 condition,
205 1 | 3
206 | 4
207 | 5
208 | 7
209 | 9
210 | 10
211 | 11
212 | 12
213 | 13
214 | 14
215 | 15
216 | 16
217 | 17
218 | 18
219 | 21
220 | 22
221 | 23
222 | 24
223 | 25
224 | 27
225 | 28
226 | 29
227 | 30
228 | 31
229 | 32
230 | 33
231 | 34
232 | 37
233 | 38
234 | 39
235 | 40
236 | 41
237 | 42
238 | 43
239 | 44
240 | 45
241 | 46
242 | 47
243 | 48
244 | 49
245 | 50
246 | 51
247 | 52
248 | 53
249 | 54
250 | 55
251 | 56
252 | 57
253 | 58
254 | 59
255 | 60
256 | 61
257 | 62
258 | 63
259 | 64
260 | 65
261 | 66
262 | 67
263 | 68
264 | 69
265 | 70
266 | 71
267 | 72
268 | 73
269 | 74
270 | 75
271 | 76
272 | 77
273 | 78
274 | 79
275 | 80
276 | 81
277 | 82
278 | 83
279 | 490
280 | 491
281 | 492
282 | 493
283 | 494
284 | 500
285 | 503
286 | 504
287 | 513
288 | 518
289 | 519
290 | 520
291 | 521
292 | 522
293 | 523
294 | 524
295 | 525
296 | 526
297 | 527
298 | 529
299 | 530
300 | 533
301 | 534
302 | 535
303 | 536
304 | 537
305 | 538
306 | 539
307 | 540
308 | 542
309 | 543
310 | 544
311 | 545
312 | 546
313 | 547
314 | 548
315 | 902
316 | 903
317 | 930
318 | 931
319 | 932
320 | 933
321 | 934
322 | 935
323 | 939
324 | 940
325 | 2036
326 )
327 }
328}
329
330impl OrdrspConditionEvaluatorFV2510 {
331 /// [7] Wenn MP-ID in SG3 NAD+MR aus Sparte Strom
332 /// EXTERNAL: Requires context from outside the message.
333 fn evaluate_7(&self, ctx: &EvaluationContext) -> ConditionResult {
334 ctx.external.evaluate("recipient_is_strom")
335 }
336
337 /// [13] Wenn MP-ID in SG3 NAD+MR aus Sparte Gas
338 /// EXTERNAL: Requires context from outside the message.
339 fn evaluate_13(&self, ctx: &EvaluationContext) -> ConditionResult {
340 ctx.external.evaluate("recipient_is_gas")
341 }
342
343 /// [52] wenn es sich bei der Reklamation um die Reklamation der ausgerollten Leistungskurvendefinitionen handelte
344 /// EXTERNAL: Requires context from outside the message.
345 fn evaluate_52(&self, ctx: &EvaluationContext) -> ConditionResult {
346 ctx.external
347 .evaluate("reklamation_ausgerollte_leistungskurvendefinitionen")
348 }
349
350 /// [60] wenn es sich bei der Reklamation um die Reklamation der Übersicht der Zählzeitdefinitionen handelte
351 /// EXTERNAL: Requires context from outside the message.
352 fn evaluate_60(&self, ctx: &EvaluationContext) -> ConditionResult {
353 ctx.external
354 .evaluate("reklamation_uebersicht_zaehlzeitdefinitionen")
355 }
356
357 /// [70] wenn es sich bei der Reklamation um die Reklamation der ausgerollten Zählzeitdefinitionen handelte
358 /// EXTERNAL: Requires context from outside the message.
359 fn evaluate_70(&self, ctx: &EvaluationContext) -> ConditionResult {
360 ctx.external
361 .evaluate("reklamation_ausgerollte_zaehlzeitdefinitionen")
362 }
363
364 /// [71] wenn es sich bei der Reklamation um die Reklamation der ausgerollten Schaltzeitdefinitionen handelte
365 /// EXTERNAL: Requires context from outside the message.
366 fn evaluate_71(&self, ctx: &EvaluationContext) -> ConditionResult {
367 ctx.external
368 .evaluate("complaint_is_about_rolled_out_switch_time_definitions")
369 }
370
371 /// [75] Wenn es sich um die Antwort auf eine Bestellung handelt in der ein Messprodukt der Codeliste der Konfigurationen aus dem Kapitel 4.6.2 „Werte nach Typ 2 aus SMGW“ bestellt wurde.
372 /// EXTERNAL: Requires context from outside the message.
373 fn evaluate_75(&self, ctx: &EvaluationContext) -> ConditionResult {
374 ctx.external
375 .evaluate("order_contains_smgw_type2_messprodukt")
376 }
377
378 /// [78] Wenn AJT+A04+E_0279 vorhanden
379 fn evaluate_78(&self, ctx: &EvaluationContext) -> ConditionResult {
380 ctx.has_segment_matching("AJT", &[(0, 0, "A04"), (1, 0, "E_0279")])
381 }
382
383 /// [79] Wenn AJT+A04+E_0283 vorhanden
384 fn evaluate_79(&self, ctx: &EvaluationContext) -> ConditionResult {
385 ctx.has_segment_matching("AJT", &[(0, 0, "A04"), (1, 0, "E_0283")])
386 }
387
388 /// [80] Wenn AJT+A05+E_0279 vorhanden
389 fn evaluate_80(&self, ctx: &EvaluationContext) -> ConditionResult {
390 ctx.has_segment_matching("AJT", &[(0, 0, "A05"), (1, 0, "E_0279")])
391 }
392
393 /// [81] Wenn AJT+A05+E_0283 vorhanden
394 fn evaluate_81(&self, ctx: &EvaluationContext) -> ConditionResult {
395 ctx.has_segment_matching("AJT", &[(0, 0, "A05"), (1, 0, "E_0283")])
396 }
397
398 /// [82] Wenn BGM+Z93 (Bestellung eines Angebots Änderung der Technik der Lokation) vorhanden
399 fn evaluate_82(&self, ctx: &EvaluationContext) -> ConditionResult {
400 ctx.has_qualifier("BGM", 0, "Z93")
401 }
402
403 /// [83] Wenn BGM+Z12 (Änderung der Technik der Lokation) vorhanden
404 fn evaluate_83(&self, ctx: &EvaluationContext) -> ConditionResult {
405 ctx.has_qualifier("BGM", 0, "Z12")
406 }
407
408 /// [513] Hinweis: Wert aus BGM+Z12 (Änderung der Technik der Lokation) DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
409 fn evaluate_513(&self, _ctx: &EvaluationContext) -> ConditionResult {
410 // Hinweis: Wert aus BGM+Z12 (Änderung der Technik der Lokation) DE1004 der ORDERS — informational note, always applies
411 ConditionResult::True
412 }
413
414 /// [543] Hinweis: Wert aus BGM+Z93 (Bestellung eines Angebots Änderung der Technik der Lokation) DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
415 fn evaluate_543(&self, _ctx: &EvaluationContext) -> ConditionResult {
416 // Hinweis: Wert aus BGM+Z93 (Bestellung eines Angebots Änderung der Technik der Lokation) DE1004 der ORDERS — informational note, always applies
417 ConditionResult::True
418 }
419
420 /// [544] Hinweis: Wert aus BGM DE1004 der PRICAT mit der das Preisblatt B des MSB, auf die aus Sicht des MSB das Angebot basiert, übermittelt wurde.
421 fn evaluate_544(&self, _ctx: &EvaluationContext) -> ConditionResult {
422 // Hinweis: Wert aus BGM DE1004 der PRICAT mit der das Preisblatt B des MSB — informational note, always applies
423 ConditionResult::True
424 }
425
426 /// [545] Hinweis: Angabe des Beginnzeitpunkts des realistisch möglichen Umsetzungstermins der zum Zeitpunkt der Ablehnung ermittelt werden kann.
427 fn evaluate_545(&self, _ctx: &EvaluationContext) -> ConditionResult {
428 // Hinweis: Angabe des Beginnzeitpunkts des realistisch möglichen Umsetzungstermins — informational note, always applies
429 ConditionResult::True
430 }
431
432 /// [546] Hinweis: Angabe des Endezeitpunkts des realistisch möglichen Umsetzungstermins der zum Zeitpunkt der Ablehnung ermittelt werden kann.
433 fn evaluate_546(&self, _ctx: &EvaluationContext) -> ConditionResult {
434 // Hinweis: Angabe des Endezeitpunkts des realistisch möglichen Umsetzungstermins — informational note, always applies
435 ConditionResult::True
436 }
437
438 /// [547] Hinweis: Wenn es sich um die Bestellung eines vorherigen Angebots im Rahmen der BDEW Anwendungshilfe "Prozesse zur Änderung der Technik an Lokationen" handelt.
439 fn evaluate_547(&self, _ctx: &EvaluationContext) -> ConditionResult {
440 // Hinweis: Bestellung eines vorherigen Angebots im Rahmen der BDEW Anwendungshilfe 'Prozesse zur Änderung der Technik an Lokationen' — informational note, always applies
441 ConditionResult::True
442 }
443
444 /// [548] Hinweis: Hinweis: wenn es sich um die Beauftragung einer Änderung gemäß WiM Teil1 UC "Messlokationsänderung" handelt.
445 fn evaluate_548(&self, _ctx: &EvaluationContext) -> ConditionResult {
446 // Hinweis: Beauftragung einer Änderung gemäß WiM Teil1 UC 'Messlokationsänderung' — informational note, always applies
447 ConditionResult::True
448 }
449
450 /// [1] Wenn BGM+7 vorhanden
451 fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
452 ctx.has_qualifier("BGM", 0, "7")
453 }
454
455 /// [3] Wenn MP-ID in SG3 NAD+MS mit Rolle NB vorhanden
456 /// EXTERNAL: Requires context from outside the message.
457 fn evaluate_3(&self, ctx: &EvaluationContext) -> ConditionResult {
458 ctx.external.evaluate("sender_is_nb")
459 }
460
461 /// [4] Wenn MP-ID in SG3 NAD+MR mit Rolle LF vorhanden
462 /// EXTERNAL: Requires context from outside the message.
463 fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
464 ctx.external.evaluate("recipient_is_lf")
465 }
466
467 /// [5] Wenn MP-ID in SG3 NAD+MS mit Rolle LF vorhanden
468 /// EXTERNAL: Requires context from outside the message.
469 fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
470 ctx.external.evaluate("sender_is_lf")
471 }
472
473 /// [9] Wenn MP-ID in SG3 NAD+MS mit Rolle LF vorhanden
474 /// EXTERNAL: Requires context from outside the message.
475 fn evaluate_9(&self, ctx: &EvaluationContext) -> ConditionResult {
476 ctx.external.evaluate("sender_is_lf")
477 }
478
479 /// [10] Wenn MP-ID in SG3 NAD+MS mit Rolle MSB vorhanden
480 /// EXTERNAL: Requires context from outside the message.
481 fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
482 ctx.external.evaluate("sender_is_msb")
483 }
484
485 /// [11] Wenn AJT+A09+E_0470 vorhanden
486 fn evaluate_11(&self, ctx: &EvaluationContext) -> ConditionResult {
487 ctx.has_qualified_value("AJT", 0, "A09", 1, 0, &["E_0470"])
488 }
489
490 /// [12] Wenn der NB eine unverbindliche Preisinformation angeben kann
491 /// EXTERNAL: Requires context from outside the message.
492 fn evaluate_12(&self, ctx: &EvaluationContext) -> ConditionResult {
493 ctx.external.evaluate("nb_can_provide_price_info")
494 }
495
496 /// [14] Wenn MP-ID in SG3 NAD+MR mit Rolle MSB vorhanden
497 /// EXTERNAL: Requires context from outside the message.
498 fn evaluate_14(&self, ctx: &EvaluationContext) -> ConditionResult {
499 ctx.external.evaluate("recipient_is_msb")
500 }
501
502 /// [15] Wenn MP-ID in SG3 NAD+MR mit Rolle NB vorhanden
503 /// EXTERNAL: Requires context from outside the message.
504 fn evaluate_15(&self, ctx: &EvaluationContext) -> ConditionResult {
505 ctx.external.evaluate("recipient_is_nb")
506 }
507
508 /// [16] Wenn MP-ID in SG3 NAD+MR mit Rolle ÜNB vorhanden
509 /// EXTERNAL: Requires context from outside the message.
510 fn evaluate_16(&self, ctx: &EvaluationContext) -> ConditionResult {
511 ctx.external.evaluate("recipient_is_uenb")
512 }
513
514 /// [17] Der hier angegebene Code des Prüfschritts muss im EBD dem Cluster Zustimmung zugeordnet sein
515 // HAND-EDITED: driven by per-EBD cluster data (mako_prozesse).
516 fn evaluate_17(&self, ctx: &EvaluationContext) -> ConditionResult {
517 resolved_sts_code_in_cluster(ctx, Cluster::is_zustimmung)
518 }
519
520 /// [18] Der hier angegebene Code des Prüfschritts muss im EBD dem Cluster Ablehnung zugeordnet sein
521 // HAND-EDITED: driven by per-EBD cluster data (mako_prozesse).
522 fn evaluate_18(&self, ctx: &EvaluationContext) -> ConditionResult {
523 resolved_sts_code_in_cluster(ctx, Cluster::is_ablehnung)
524 }
525
526 /// [21] Wenn IMD++Z01 vorhanden
527 fn evaluate_21(&self, ctx: &EvaluationContext) -> ConditionResult {
528 ctx.has_qualifier("IMD", 1, "Z01")
529 }
530
531 /// [22] Wenn IMD++Z02 vorhanden
532 fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
533 ctx.has_qualifier("IMD", 1, "Z02")
534 }
535
536 /// [23] Wenn IMD++Z03 vorhanden
537 fn evaluate_23(&self, ctx: &EvaluationContext) -> ConditionResult {
538 let segments = ctx.find_segments("IMD");
539 ConditionResult::from(segments.iter().any(|s| {
540 s.elements
541 .get(1)
542 .and_then(|e| e.first())
543 .is_some_and(|v| v == "Z03")
544 }))
545 }
546
547 /// [24] Wenn BGM+Z51 vorhanden
548 fn evaluate_24(&self, ctx: &EvaluationContext) -> ConditionResult {
549 ctx.has_qualifier("BGM", 0, "Z51")
550 }
551
552 /// [25] Wenn BGM+Z52 vorhanden
553 fn evaluate_25(&self, ctx: &EvaluationContext) -> ConditionResult {
554 ctx.has_qualifier("BGM", 0, "Z52")
555 }
556
557 /// [27] Wenn AJT+A05+E_0470 vorhanden
558 fn evaluate_27(&self, ctx: &EvaluationContext) -> ConditionResult {
559 let segments = ctx.find_segments_with_qualifier("AJT", 0, "A05");
560 ConditionResult::from(segments.iter().any(|s| {
561 s.elements
562 .get(1)
563 .and_then(|e| e.first())
564 .is_some_and(|v| v == "E_0470")
565 }))
566 }
567
568 /// [28] Wenn AJT+A99 vorhanden
569 fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
570 ctx.has_qualifier("AJT", 0, "A99")
571 }
572
573 /// [29] MP-ID nur aus Sparte Gas
574 /// EXTERNAL: Requires context from outside the message.
575 fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
576 ctx.external.evaluate("mp_id_is_gas")
577 }
578
579 /// [30] MP-ID nur aus Sparte Strom
580 /// EXTERNAL: Requires context from outside the message.
581 fn evaluate_30(&self, ctx: &EvaluationContext) -> ConditionResult {
582 ctx.external.evaluate("mp_id_is_strom")
583 }
584
585 /// [31] MP-ID mit Rolle MSB
586 /// EXTERNAL: Requires context from outside the message.
587 fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
588 ctx.external.evaluate("mp_id_role_is_msb")
589 }
590
591 /// [32] MP-ID mit Rolle NB
592 /// EXTERNAL: Requires context from outside the message.
593 fn evaluate_32(&self, ctx: &EvaluationContext) -> ConditionResult {
594 ctx.external.evaluate("mp_id_role_is_nb")
595 }
596
597 /// [33] Wenn AJT+A02/A03+E_0488 vorhanden
598 fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
599 let segments = ctx.find_segments("AJT");
600 ConditionResult::from(segments.iter().any(|s| {
601 let qual = s
602 .elements
603 .first()
604 .and_then(|e| e.first())
605 .map(|v| v.as_str());
606 let val = s
607 .elements
608 .get(1)
609 .and_then(|e| e.first())
610 .map(|v| v.as_str());
611 matches!(qual, Some("A02") | Some("A03")) && matches!(val, Some("E_0488"))
612 }))
613 }
614
615 /// [34] wenn vorhanden
616 // REVIEW: 'wenn vorhanden' is a generic conditional-use annotation meaning the element should be included whenever the relevant data is available. As a standalone condition without a specific segment target, it functions as a Hinweis-like unconditional True. (medium confidence)
617 fn evaluate_34(&self, _ctx: &EvaluationContext) -> ConditionResult {
618 // 'wenn vorhanden' — generic availability condition: element is conditional on presence of the data
619 // Without a specific segment reference this acts as an unconditional note
620 ConditionResult::True
621 }
622
623 /// [37] Wenn in dieser Nachricht das SG8 CUX+2 vorhanden
624 fn evaluate_37(&self, ctx: &EvaluationContext) -> ConditionResult {
625 ctx.has_qualifier("CUX", 0, "2")
626 }
627
628 /// [38] Möglicher Wert: ZB4 oder ZB5
629 fn evaluate_38(&self, _ctx: &EvaluationContext) -> ConditionResult {
630 // Hinweis: Möglicher Wert: ZB4 oder ZB5 — informational note documenting permitted values
631 ConditionResult::True
632 }
633
634 /// [39] Möglicher Wert: E17 oder Z07
635 fn evaluate_39(&self, _ctx: &EvaluationContext) -> ConditionResult {
636 // Hinweis: Möglicher Wert: E17 oder Z07 — informational note documenting permitted values
637 ConditionResult::True
638 }
639
640 /// [40] Wenn der Code im DE3207 in der "EDI@Energy Codeliste der europäischen Ländercodes" in der Spalte "PLZ vorhanden" ein "X" enthält
641 /// EXTERNAL: Requires context from outside the message.
642 fn evaluate_40(&self, ctx: &EvaluationContext) -> ConditionResult {
643 ctx.external.evaluate("country_has_postal_code")
644 }
645
646 /// [41] wenn SG2 AJT (Einzelheiten zu einer Anpassung/Änderung) DE4465 mit Wert ZB5 vorhanden
647 fn evaluate_41(&self, ctx: &EvaluationContext) -> ConditionResult {
648 ctx.has_qualifier("AJT", 0, "ZB5")
649 }
650
651 /// [42] Wenn SG2 AJT+Z07 (Antwortkategorie: Ablehnung (Keine Berechtigung)) vorhanden
652 fn evaluate_42(&self, ctx: &EvaluationContext) -> ConditionResult {
653 ctx.has_qualifier("AJT", 0, "Z07")
654 }
655
656 /// [43] Wenn AJT+A02/A03+E_1001 vorhanden
657 fn evaluate_43(&self, ctx: &EvaluationContext) -> ConditionResult {
658 let ajts = ctx.find_segments("AJT");
659 let found = ajts.iter().any(|s| {
660 let code = s
661 .elements
662 .first()
663 .and_then(|e| e.first())
664 .map(|v| v.as_str());
665 let pos = s
666 .elements
667 .get(1)
668 .and_then(|e| e.first())
669 .map(|v| v.as_str());
670 matches!(code, Some("A02") | Some("A03")) && matches!(pos, Some("E_1001"))
671 });
672 ConditionResult::from(found)
673 }
674
675 /// [44] Wenn AJT+A05+E_1000 vorhanden
676 fn evaluate_44(&self, ctx: &EvaluationContext) -> ConditionResult {
677 let ajts = ctx.find_segments("AJT");
678 let found = ajts.iter().any(|s| {
679 let code = s
680 .elements
681 .first()
682 .and_then(|e| e.first())
683 .map(|v| v.as_str());
684 let pos = s
685 .elements
686 .get(1)
687 .and_then(|e| e.first())
688 .map(|v| v.as_str());
689 matches!(code, Some("A05")) && matches!(pos, Some("E_1000"))
690 });
691 ConditionResult::from(found)
692 }
693
694 /// [45] Wenn AJT+A09+E_1000 vorhanden
695 fn evaluate_45(&self, ctx: &EvaluationContext) -> ConditionResult {
696 let ajts = ctx.find_segments("AJT");
697 let found = ajts.iter().any(|s| {
698 let code = s
699 .elements
700 .first()
701 .and_then(|e| e.first())
702 .map(|v| v.as_str());
703 let pos = s
704 .elements
705 .get(1)
706 .and_then(|e| e.first())
707 .map(|v| v.as_str());
708 matches!(code, Some("A09")) && matches!(pos, Some("E_1000"))
709 });
710 ConditionResult::from(found)
711 }
712
713 /// [46] Wenn AJT+A06+E_0552 vorhanden
714 fn evaluate_46(&self, ctx: &EvaluationContext) -> ConditionResult {
715 let ajts = ctx.find_segments("AJT");
716 let found = ajts.iter().any(|s| {
717 let code = s
718 .elements
719 .first()
720 .and_then(|e| e.first())
721 .map(|v| v.as_str());
722 let pos = s
723 .elements
724 .get(1)
725 .and_then(|e| e.first())
726 .map(|v| v.as_str());
727 matches!(code, Some("A06")) && matches!(pos, Some("E_0552"))
728 });
729 ConditionResult::from(found)
730 }
731
732 /// [47] Wenn AJT+A06+E_0553 vorhanden
733 fn evaluate_47(&self, ctx: &EvaluationContext) -> ConditionResult {
734 let ajts = ctx.find_segments("AJT");
735 let found = ajts.iter().any(|s| {
736 let code = s
737 .elements
738 .first()
739 .and_then(|e| e.first())
740 .map(|v| v.as_str());
741 let pos = s
742 .elements
743 .get(1)
744 .and_then(|e| e.first())
745 .map(|v| v.as_str());
746 matches!(code, Some("A06")) && matches!(pos, Some("E_0553"))
747 });
748 ConditionResult::from(found)
749 }
750
751 /// [48] Wenn AJT+A06+E_0554 vorhanden
752 fn evaluate_48(&self, ctx: &EvaluationContext) -> ConditionResult {
753 let ajts = ctx.find_segments("AJT");
754 let found = ajts.iter().any(|s| {
755 let code = s
756 .elements
757 .first()
758 .and_then(|e| e.first())
759 .map(|v| v.as_str());
760 let pos = s
761 .elements
762 .get(1)
763 .and_then(|e| e.first())
764 .map(|v| v.as_str());
765 matches!(code, Some("A06")) && matches!(pos, Some("E_0554"))
766 });
767 ConditionResult::from(found)
768 }
769
770 /// [49] nur, wenn in ursprünglicher Nachricht IMD++Z60 (Abbestellung Messprodukt mit Zählzeitdefinition des LF) vorhanden war
771 /// EXTERNAL: Requires context from outside the message.
772 fn evaluate_49(&self, ctx: &EvaluationContext) -> ConditionResult {
773 ctx.external.evaluate("original_order_had_imd_z60")
774 }
775
776 /// [50] wenn im DE3155 in demselben COM der Code EM vorhanden ist
777 fn evaluate_50(&self, ctx: &EvaluationContext) -> ConditionResult {
778 let coms = ctx.find_segments("COM");
779 ConditionResult::from(coms.iter().any(|s| {
780 s.elements
781 .first()
782 .and_then(|e| e.get(1))
783 .map(|v| v == "EM")
784 .unwrap_or(false)
785 }))
786 }
787
788 /// [51] wenn im DE3155 in demselben COM der Code TE / FX / AJ / AL vorhanden ist
789 fn evaluate_51(&self, ctx: &EvaluationContext) -> ConditionResult {
790 let coms = ctx.find_segments("COM");
791 ConditionResult::from(coms.iter().any(|s| {
792 matches!(
793 s.elements
794 .first()
795 .and_then(|e| e.get(1))
796 .map(|v| v.as_str()),
797 Some("TE") | Some("FX") | Some("AJ") | Some("AL")
798 )
799 }))
800 }
801
802 /// [53] Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z59
803 fn evaluate_53(&self, _ctx: &EvaluationContext) -> ConditionResult {
804 // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z59 — informational note about value origin, always applies
805 ConditionResult::True
806 }
807
808 /// [54] Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z80
809 fn evaluate_54(&self, _ctx: &EvaluationContext) -> ConditionResult {
810 // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z80 — informational note about value origin, always applies
811 ConditionResult::True
812 }
813
814 /// [55] Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z81
815 fn evaluate_55(&self, _ctx: &EvaluationContext) -> ConditionResult {
816 // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z81 — informational note about value origin, always applies
817 ConditionResult::True
818 }
819
820 /// [56] wenn SG2 AJT+A02/A03/A06/A07/A10/A11+E_0548 vorhanden
821 fn evaluate_56(&self, ctx: &EvaluationContext) -> ConditionResult {
822 let ajts = ctx.find_segments("AJT");
823 ConditionResult::from(ajts.iter().any(|s| {
824 let de4465 = s
825 .elements
826 .first()
827 .and_then(|e| e.first())
828 .map(|s| s.as_str());
829 let de1082 = s
830 .elements
831 .get(1)
832 .and_then(|e| e.first())
833 .map(|s| s.as_str());
834 matches!(
835 de4465,
836 Some("A02") | Some("A03") | Some("A06") | Some("A07") | Some("A10") | Some("A11")
837 ) && de1082 == Some("E_0548")
838 }))
839 }
840
841 /// [57] wenn SG2 AJT+A02/A03/A06/A07/A10/A11+E_0549 vorhanden
842 fn evaluate_57(&self, ctx: &EvaluationContext) -> ConditionResult {
843 let ajts = ctx.find_segments("AJT");
844 ConditionResult::from(ajts.iter().any(|s| {
845 let de4465 = s
846 .elements
847 .first()
848 .and_then(|e| e.first())
849 .map(|s| s.as_str());
850 let de1082 = s
851 .elements
852 .get(1)
853 .and_then(|e| e.first())
854 .map(|s| s.as_str());
855 matches!(
856 de4465,
857 Some("A02") | Some("A03") | Some("A06") | Some("A07") | Some("A10") | Some("A11")
858 ) && de1082 == Some("E_0549")
859 }))
860 }
861
862 /// [58] wenn SG2 AJT+A02/A03/A06/A07+E_0550 vorhanden
863 fn evaluate_58(&self, ctx: &EvaluationContext) -> ConditionResult {
864 let ajts = ctx.find_segments("AJT");
865 ConditionResult::from(ajts.iter().any(|s| {
866 let de4465 = s
867 .elements
868 .first()
869 .and_then(|e| e.first())
870 .map(|s| s.as_str());
871 let de1082 = s
872 .elements
873 .get(1)
874 .and_then(|e| e.first())
875 .map(|s| s.as_str());
876 matches!(
877 de4465,
878 Some("A02") | Some("A03") | Some("A06") | Some("A07")
879 ) && de1082 == Some("E_0550")
880 }))
881 }
882
883 /// [59] wenn SG2 AJT+A02/A03/A06/A07/A10/A11+E_0551 vorhanden
884 fn evaluate_59(&self, ctx: &EvaluationContext) -> ConditionResult {
885 let ajts = ctx.find_segments("AJT");
886 ConditionResult::from(ajts.iter().any(|s| {
887 let de4465 = s
888 .elements
889 .first()
890 .and_then(|e| e.first())
891 .map(|s| s.as_str());
892 let de1082 = s
893 .elements
894 .get(1)
895 .and_then(|e| e.first())
896 .map(|s| s.as_str());
897 matches!(
898 de4465,
899 Some("A02") | Some("A03") | Some("A06") | Some("A07") | Some("A10") | Some("A11")
900 ) && de1082 == Some("E_0551")
901 }))
902 }
903
904 /// [61] wenn es sich bei der Reklamation um die Reklamation der Übersicht der Schaltzeitdefinitionen handelte
905 // REVIEW: The condition checks whether the complaint concerned the overview of switching time definitions (Schaltzeitdefinitionen). Condition 63 establishes that BGM+Z60 is the code for Schaltzeitdefinitionen in UTILTS, and the ORDRSP BGM code mirrors this type. Checking BGM elements[0][0] == 'Z60' identifies this complaint type. (medium confidence)
906 fn evaluate_61(&self, ctx: &EvaluationContext) -> ConditionResult {
907 // Reklamation der Übersicht der Schaltzeitdefinitionen → ORDRSP with BGM+Z60
908 ctx.has_qualifier("BGM", 0, "Z60")
909 }
910
911 /// [62] wenn es sich bei der Reklamation um die Reklamation der Übersicht der Leistungskurvendefinitionen handelte
912 // REVIEW: The condition checks whether the complaint concerned the overview of load curve definitions (Leistungskurvendefinitionen). Conditions 64 and 65 establish BGM+Z78 and BGM+Z79 as the two related UTILTS codes for Leistungskurven types, so both are checked. (medium confidence)
913 fn evaluate_62(&self, ctx: &EvaluationContext) -> ConditionResult {
914 // Reklamation der Übersicht der Leistungskurvendefinitionen → BGM+Z78 or BGM+Z79
915 let bgm_segs = ctx.find_segments("BGM");
916 match bgm_segs.first() {
917 Some(s) => {
918 let code = s
919 .elements
920 .first()
921 .and_then(|e| e.first())
922 .map(|v| v.as_str());
923 ConditionResult::from(matches!(code, Some("Z78") | Some("Z79")))
924 }
925 None => ConditionResult::False, // segment absent → condition not applicable
926 }
927 }
928
929 /// [63] Dokumentennummer aus BGM+Z60 DE1004 der UTILTS
930 fn evaluate_63(&self, _ctx: &EvaluationContext) -> ConditionResult {
931 // Hinweis: Dokumentennummer aus BGM+Z60 DE1004 der UTILTS — informational note, always applies
932 ConditionResult::True
933 }
934
935 /// [64] Dokumentennummer aus BGM+Z78 DE1004 der UTILTS
936 fn evaluate_64(&self, _ctx: &EvaluationContext) -> ConditionResult {
937 // Hinweis: Dokumentennummer aus BGM+Z78 DE1004 der UTILTS — informational note, always applies
938 ConditionResult::True
939 }
940
941 /// [65] Dokumentennummer aus BGM+Z79 DE1004 der UTILTS
942 fn evaluate_65(&self, _ctx: &EvaluationContext) -> ConditionResult {
943 // Hinweis: Dokumentennummer aus BGM+Z79 DE1004 der UTILTS — informational note, always applies
944 ConditionResult::True
945 }
946
947 /// [66] wenn SG2 AJT+A01/A02/A03+E_0544 vorhanden
948 fn evaluate_66(&self, ctx: &EvaluationContext) -> ConditionResult {
949 let ajts = ctx.find_segments("AJT");
950 ConditionResult::from(ajts.iter().any(|s| {
951 let de4465 = s
952 .elements
953 .first()
954 .and_then(|e| e.first())
955 .map(|s| s.as_str());
956 let de1082 = s
957 .elements
958 .get(1)
959 .and_then(|e| e.first())
960 .map(|s| s.as_str());
961 matches!(de4465, Some("A01") | Some("A02") | Some("A03")) && de1082 == Some("E_0544")
962 }))
963 }
964
965 /// [67] wenn SG2 AJT+A01/A02/A03+E_0545 vorhanden
966 fn evaluate_67(&self, ctx: &EvaluationContext) -> ConditionResult {
967 let ajts = ctx.find_segments("AJT");
968 ConditionResult::from(ajts.iter().any(|s| {
969 let de4465 = s
970 .elements
971 .first()
972 .and_then(|e| e.first())
973 .map(|s| s.as_str());
974 let de1082 = s
975 .elements
976 .get(1)
977 .and_then(|e| e.first())
978 .map(|s| s.as_str());
979 matches!(de4465, Some("A01") | Some("A02") | Some("A03")) && de1082 == Some("E_0545")
980 }))
981 }
982
983 /// [68] wenn SG2 AJT+A02/A03+E_0546 vorhanden
984 fn evaluate_68(&self, ctx: &EvaluationContext) -> ConditionResult {
985 let ajts = ctx.find_segments("AJT");
986 ConditionResult::from(ajts.iter().any(|s| {
987 let de4465 = s
988 .elements
989 .first()
990 .and_then(|e| e.first())
991 .map(|s| s.as_str());
992 let de1082 = s
993 .elements
994 .get(1)
995 .and_then(|e| e.first())
996 .map(|s| s.as_str());
997 matches!(de4465, Some("A02") | Some("A03")) && de1082 == Some("E_0546")
998 }))
999 }
1000
1001 /// [69] wenn SG2 AJT+A01/A02/A03+E_0547 vorhanden
1002 fn evaluate_69(&self, ctx: &EvaluationContext) -> ConditionResult {
1003 let ajts = ctx.find_segments("AJT");
1004 ConditionResult::from(ajts.iter().any(|s| {
1005 let de4465 = s
1006 .elements
1007 .first()
1008 .and_then(|e| e.first())
1009 .map(|s| s.as_str());
1010 let de1082 = s
1011 .elements
1012 .get(1)
1013 .and_then(|e| e.first())
1014 .map(|s| s.as_str());
1015 matches!(de4465, Some("A01") | Some("A02") | Some("A03")) && de1082 == Some("E_0547")
1016 }))
1017 }
1018
1019 /// [72] wenn AJT+A04+E_0552 vorhanden
1020 fn evaluate_72(&self, ctx: &EvaluationContext) -> ConditionResult {
1021 ctx.has_qualified_value("AJT", 0, "A04", 1, 0, &["E_0552"])
1022 }
1023
1024 /// [73] wenn AJT+A04+E_0553 vorhanden
1025 fn evaluate_73(&self, ctx: &EvaluationContext) -> ConditionResult {
1026 ctx.has_qualified_value("AJT", 0, "A04", 1, 0, &["E_0553"])
1027 }
1028
1029 /// [74] wenn AJT+A04+E_0554 vorhanden
1030 fn evaluate_74(&self, ctx: &EvaluationContext) -> ConditionResult {
1031 ctx.has_qualified_value("AJT", 0, "A04", 1, 0, &["E_0554"])
1032 }
1033
1034 /// [76] Wenn FTX+Z27 (IP-Adresse des Absenders) nicht vorhanden
1035 fn evaluate_76(&self, ctx: &EvaluationContext) -> ConditionResult {
1036 ctx.lacks_qualifier("FTX", 0, "Z27")
1037 }
1038
1039 /// [77] Wenn FTX+Z28 (IP-Range des Absenders) nicht vorhanden
1040 fn evaluate_77(&self, ctx: &EvaluationContext) -> ConditionResult {
1041 ctx.lacks_qualifier("FTX", 0, "Z28")
1042 }
1043
1044 /// [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...
1045 fn evaluate_490(&self, ctx: &EvaluationContext) -> ConditionResult {
1046 match ctx.resolved_value {
1047 Some(val) => is_mesz_utc(val),
1048 None => ConditionResult::False,
1049 }
1050 }
1051
1052 /// [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)...
1053 fn evaluate_491(&self, ctx: &EvaluationContext) -> ConditionResult {
1054 match ctx.resolved_value {
1055 Some(val) => is_mez_utc(val),
1056 None => ConditionResult::False,
1057 }
1058 }
1059
1060 /// [492] wenn MP-ID in NAD+MR aus Sparte Strom
1061 /// EXTERNAL: Requires context from outside the message.
1062 fn evaluate_492(&self, ctx: &EvaluationContext) -> ConditionResult {
1063 ctx.external.evaluate("recipient_is_strom")
1064 }
1065
1066 /// [493] wenn MP-ID in NAD+MR aus Sparte Gas
1067 /// EXTERNAL: Requires context from outside the message.
1068 fn evaluate_493(&self, ctx: &EvaluationContext) -> ConditionResult {
1069 ctx.external.evaluate("recipient_is_gas")
1070 }
1071
1072 /// [494] Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.
1073 // REVIEW: 'Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.' This is a constraint description stating the date must be the document creation time or earlier. It functions as an unconditional validation rule (always applies) rather than a conditional trigger. Without knowing which specific DTM qualifier 'here' refers to in the calling context, and since the constraint itself is always applicable, returning True is appropriate. (medium confidence)
1074 fn evaluate_494(&self, _ctx: &EvaluationContext) -> ConditionResult {
1075 ConditionResult::True
1076 }
1077
1078 /// [500] Hinweis: Angabe eines technischen Ansprechpartners für die Geräteübernahme
1079 fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
1080 ConditionResult::True
1081 }
1082
1083 /// [503] Hinweis: Datum, bis zu dem der MSBA zur Fortführung verpflichtet wurde
1084 fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
1085 ConditionResult::True
1086 }
1087
1088 /// [504] Hinweis: Ggf. korrigiert bei einer Zeitangabe in der ORDERS, die außerhalb des max. möglichen Weiterverpflichtungszeitraums ist. Als Antwort wird dann in SG2 AJT Zustimmung mit Terminänderung an...
1089 fn evaluate_504(&self, _ctx: &EvaluationContext) -> ConditionResult {
1090 // Hinweis: Ggf. korrigiert bei einer Zeitangabe in der ORDERS, die außerhalb des max. möglichen Weiterverpflichtungszeitraums ist. Als Antwort wird dann in SG2 AJT Zustimmung mit Terminänderung angegeben.
1091 ConditionResult::True
1092 }
1093
1094 /// [518] Hinweis: Wert aus BGM+Z10 DE1004 der ORDERS, mit der die Bestellung erfolgt ist
1095 fn evaluate_518(&self, _ctx: &EvaluationContext) -> ConditionResult {
1096 // Hinweis: Wert aus BGM+Z10 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
1097 ConditionResult::True
1098 }
1099
1100 /// [519] Hinweis: Wert aus BGM+7 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
1101 fn evaluate_519(&self, _ctx: &EvaluationContext) -> ConditionResult {
1102 // Hinweis: Wert aus BGM+7 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
1103 ConditionResult::True
1104 }
1105
1106 /// [520] Hinweis: Wert aus BGM+Z29 DE1004 der ORDERS, mit der die Anfrage zur Beendigung der Rechnungsabwicklung erfolgt ist.
1107 fn evaluate_520(&self, _ctx: &EvaluationContext) -> ConditionResult {
1108 // Hinweis: Wert aus BGM+Z29 DE1004 der ORDERS, mit der die Anfrage zur Beendigung der Rechnungsabwicklung erfolgt ist.
1109 ConditionResult::True
1110 }
1111
1112 /// [521] Hinweis: Wert aus BGM+Z14/Z61/Z62 DE1004 der ORDERS, mit der die Anforderung von Stammdaten erfolgt ist
1113 fn evaluate_521(&self, _ctx: &EvaluationContext) -> ConditionResult {
1114 // Hinweis: Wert aus BGM+Z14/Z61/Z62 DE1004 der ORDERS, mit der die Anforderung von Stammdaten erfolgt ist
1115 // Informational note — documents that the BGM DE1004 value originates from the original ORDERS request.
1116 ConditionResult::True
1117 }
1118
1119 /// [522] Hinweis: Wert aus BGM+7/Z28/Z48 DE1004 der ORDERS, mit der die Anforderung von Werten erfolgt ist.
1120 fn evaluate_522(&self, _ctx: &EvaluationContext) -> ConditionResult {
1121 // Hinweis: Wert aus BGM+7/Z28/Z48 DE1004 der ORDERS — informational note, always applies
1122 ConditionResult::True
1123 }
1124
1125 /// [523] Hinweis: Wert aus BGM+7 DE1004 der ORDERS, mit der die Anforderung Anforderung von Brennwert und Zustandszahl erfolgt ist.
1126 fn evaluate_523(&self, _ctx: &EvaluationContext) -> ConditionResult {
1127 // Hinweis: Wert aus BGM+7 DE1004 der ORDERS — informational note, always applies
1128 ConditionResult::True
1129 }
1130
1131 /// [524] Hinweis: Wert aus BGM+Z14 DE1004 der ORDERS, mit der die Anfrage vom MSB Gas erfolgt ist.
1132 fn evaluate_524(&self, _ctx: &EvaluationContext) -> ConditionResult {
1133 // Hinweis: Wert aus BGM+Z14 DE1004 der ORDERS — informational note, always applies
1134 ConditionResult::True
1135 }
1136
1137 /// [525] Hinweis: Wert aus BGM+Z24 DE1004 der ORDERS, mit der die Anforderung Allokationsliste erfolgt ist
1138 fn evaluate_525(&self, _ctx: &EvaluationContext) -> ConditionResult {
1139 // Hinweis: Wert aus BGM+Z24 DE1004 der ORDERS — informational note, always applies
1140 ConditionResult::True
1141 }
1142
1143 /// [526] Hinweis: Wert aus BGM+Z23 DE1004 der ORDERS, mit der die Anforderung bilanzierte Menge erfolgt ist
1144 fn evaluate_526(&self, _ctx: &EvaluationContext) -> ConditionResult {
1145 // Hinweis: Wert aus BGM+Z23 DE1004 der ORDERS — informational note, always applies
1146 ConditionResult::True
1147 }
1148
1149 /// [527] Hinweis: Wert aus BGM+Z34 DE1004 der ORDERS, mit der die Reklamation von Werten erfolgt ist.
1150 fn evaluate_527(&self, _ctx: &EvaluationContext) -> ConditionResult {
1151 // Hinweis: Wert aus BGM+Z34 DE1004 der ORDERS, mit der die Reklamation von Werten erfolgt ist. — informational note, always applies
1152 ConditionResult::True
1153 }
1154
1155 /// [529] Hinweis: Dokumentennummer aus BGM DE1004 der ORDERS
1156 fn evaluate_529(&self, _ctx: &EvaluationContext) -> ConditionResult {
1157 // Hinweis: Dokumentennummer aus BGM DE1004 der ORDERS — informational note, always applies
1158 ConditionResult::True
1159 }
1160
1161 /// [530] Hinweis: Dokumentennummer aus BGM DE1004 der ORDCHG
1162 fn evaluate_530(&self, _ctx: &EvaluationContext) -> ConditionResult {
1163 // Hinweis: Dokumentennummer aus BGM DE1004 der ORDCHG — informational note, always applies
1164 ConditionResult::True
1165 }
1166
1167 /// [533] Hinweis: Wert aus BGM+Z51 DE1004 der ORDCHG
1168 fn evaluate_533(&self, _ctx: &EvaluationContext) -> ConditionResult {
1169 // Hinweis: Wert aus BGM+Z51 DE1004 der ORDCHG — informational note, always applies
1170 ConditionResult::True
1171 }
1172
1173 /// [534] Hinweis: Wert aus BGM+Z52 DE1004 der ORDCHG
1174 fn evaluate_534(&self, _ctx: &EvaluationContext) -> ConditionResult {
1175 // Hinweis: Wert aus BGM+Z52 DE1004 der ORDCHG — informational note, always applies
1176 ConditionResult::True
1177 }
1178
1179 /// [535] Hinweis: Wert aus BGM+Z13 DE1004 der ORDERS, mit der die Ankündigung Gerätewechselabsicht erfolgt ist.
1180 fn evaluate_535(&self, _ctx: &EvaluationContext) -> ConditionResult {
1181 // Hinweis: Wert aus BGM+Z13 DE1004 der ORDERS — informational note, always applies
1182 ConditionResult::True
1183 }
1184
1185 /// [536] Hinweis: Es ist die MP-ID des Eigentümers (MSB) zur bilateralen Klärung anzugeben, wenn der angefragte MSB nicht selber der Eigentümer ist.
1186 fn evaluate_536(&self, _ctx: &EvaluationContext) -> ConditionResult {
1187 // Hinweis: MP-ID des Eigentümers (MSB) angeben — informational note, always applies
1188 ConditionResult::True
1189 }
1190
1191 /// [537] Hinweis: Wert aus BGM+Z72 DE1004 der ORDERS, mit der die Bestellung Beendigung der Konfiguration erfolgt ist.
1192 fn evaluate_537(&self, _ctx: &EvaluationContext) -> ConditionResult {
1193 // Hinweis: Wert aus BGM+Z72 DE1004 der ORDERS — informational note, always applies
1194 ConditionResult::True
1195 }
1196
1197 /// [538] Hinweis: Wert aus BGM+Z76 DE1004 der ORDERS, mit der die Reklamation der Konfiguration erfolgt ist.
1198 fn evaluate_538(&self, _ctx: &EvaluationContext) -> ConditionResult {
1199 // Hinweis: Wert aus BGM+Z76 DE1004 der ORDERS — informational note, always applies
1200 ConditionResult::True
1201 }
1202
1203 /// [539] Hinweis: Wert aus BGM+Z73/Z74 DE1004 der ORDERS, mit der die Bestellung der Konfiguration erfolgt ist.
1204 fn evaluate_539(&self, _ctx: &EvaluationContext) -> ConditionResult {
1205 // Hinweis: Wert aus BGM+Z73/Z74 DE1004 der ORDERS — informational note, always applies
1206 ConditionResult::True
1207 }
1208
1209 /// [540] Hinweis: Es darf nur eine Information im DE3148 übermittelt werden
1210 fn evaluate_540(&self, _ctx: &EvaluationContext) -> ConditionResult {
1211 // Hinweis: Es darf nur eine Information im DE3148 übermittelt werden — informational note, always applies
1212 ConditionResult::True
1213 }
1214
1215 /// [542] Hinweis: Wert aus BGM+Z91 DE1004 der ORDERS, mit der die Bestellung Änderung der Abrechnungsdaten erfolgt ist.
1216 fn evaluate_542(&self, _ctx: &EvaluationContext) -> ConditionResult {
1217 // Hinweis: Wert aus BGM+Z91 DE1004 der ORDERS — informational note about value origin, always applies
1218 ConditionResult::True
1219 }
1220
1221 /// [902] Format: Format: Möglicher Wert: ≥ 0
1222 // REVIEW: Format condition requiring numeric value >= 0. Applied to QTY segment value (elements[0][1]) by convention matching the example pattern. Medium confidence because the exact segment this applies to is not specified in the condition text, but QTY is the standard target for quantity format conditions. (medium confidence)
1223 fn evaluate_902(&self, ctx: &EvaluationContext) -> ConditionResult {
1224 ctx.format_check("QTY", 0, 1, |val| validate_numeric(val, ">=", 0.0))
1225 }
1226
1227 /// [903] Format: Möglicher Wert: 1
1228 // REVIEW: Format condition requiring the value to equal exactly 1. Applied to QTY segment value (elements[0][1]) by convention. Medium confidence as the exact target segment is not stated, but QTY quantity value is the standard target for this kind of format constraint. (medium confidence)
1229 fn evaluate_903(&self, ctx: &EvaluationContext) -> ConditionResult {
1230 ctx.format_check("QTY", 0, 1, |val| validate_numeric(val, "==", 1.0))
1231 }
1232
1233 /// [930] Format: max. 2 Nachkommastellen
1234 // REVIEW: Format condition requiring at most 2 decimal places. Applied to QTY segment value (elements[0][1]) following the standard pattern from example 19. Medium confidence as the exact target segment is not specified in the condition text, but QTY quantity value is the canonical target for decimal place constraints. (medium confidence)
1235 fn evaluate_930(&self, ctx: &EvaluationContext) -> ConditionResult {
1236 ctx.format_check("QTY", 0, 1, |val| validate_max_decimal_places(val, 2))
1237 }
1238
1239 /// [931] Format: ZZZ = +00
1240 fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
1241 ctx.format_check("DTM", 0, 1, validate_timezone_utc)
1242 }
1243
1244 /// [932] Format: HHMM = 2200
1245 fn evaluate_932(&self, ctx: &EvaluationContext) -> ConditionResult {
1246 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "2200"))
1247 }
1248
1249 /// [933] Format: HHMM = 2300
1250 fn evaluate_933(&self, ctx: &EvaluationContext) -> ConditionResult {
1251 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "2300"))
1252 }
1253
1254 /// [934] Format: HHMM = 0400
1255 fn evaluate_934(&self, ctx: &EvaluationContext) -> ConditionResult {
1256 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "0400"))
1257 }
1258
1259 /// [935] Format: HHMM = 0500
1260 fn evaluate_935(&self, ctx: &EvaluationContext) -> ConditionResult {
1261 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "0500"))
1262 }
1263
1264 /// [939] Format: Die Zeichenkette muss die Zeichen @ und . enthalten
1265 // REVIEW: Format condition checking that the string contains '@' and '.' — characteristic of an email address format requirement. Applied to COM segment with EM (Electronic Mail) qualifier where elements[0][0] is the address and elements[0][1] is the communication means type code. Returns Unknown when no COM+EM segment is found (condition not applicable). (medium confidence)
1266 fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
1267 // Format: string must contain '@' and '.' — email address format check
1268 // Applied to COM segment with EM (Electronic Mail) qualifier
1269 // COM+address:qualifier → elements[0] = ["address", "qualifier"]
1270 let com_segs = ctx.find_segments("COM");
1271 for seg in &com_segs {
1272 if let Some(elem0) = seg.elements.first() {
1273 if elem0.get(1).map(|q| q == "EM").unwrap_or(false) {
1274 let value = elem0.first().map(|s| s.as_str()).unwrap_or("");
1275 if value.is_empty() {
1276 return ConditionResult::Unknown;
1277 }
1278 return ConditionResult::from(value.contains('@') && value.contains('.'));
1279 }
1280 }
1281 }
1282 ConditionResult::Unknown
1283 }
1284
1285 /// [940] Format: Die Zeichenkette muss mit dem Zeichen + beginnen und danach dürfen nur noch Ziffern folgen
1286 // REVIEW: Format condition checking that the string starts with '+' and contains only digits afterwards — the international phone number format (e.g. +4912345678). Applied to COM segments with phone-type qualifiers (TE=Telephone, FX=Telefax, AH=After Hours). Returns Unknown when no COM segment with a phone qualifier is found. Requires at least one digit after '+' (len > 1) since a bare '+' is not a valid phone number. (medium confidence)
1287 fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
1288 // Format: string must start with '+' and be followed only by digits — international phone number format
1289 // Applied to COM segments with phone-type qualifiers: TE (Telephone), FX (Telefax), AH (After Hours)
1290 // COM+number:qualifier → elements[0] = ["number", "qualifier"]
1291 let com_segs = ctx.find_segments("COM");
1292 for seg in &com_segs {
1293 if let Some(elem0) = seg.elements.first() {
1294 let qualifier = elem0.get(1).map(|s| s.as_str()).unwrap_or("");
1295 if matches!(qualifier, "TE" | "FX" | "AH") {
1296 let value = elem0.first().map(|s| s.as_str()).unwrap_or("");
1297 if value.is_empty() {
1298 return ConditionResult::Unknown;
1299 }
1300 return ConditionResult::from(
1301 value.starts_with('+')
1302 && value.len() > 1
1303 && value[1..].chars().all(|c| c.is_ascii_digit()),
1304 );
1305 }
1306 }
1307 }
1308 ConditionResult::Unknown
1309 }
1310
1311 /// [2036] Pro Nachricht ist die SG27 genau einmal anzugeben
1312 // REVIEW: Cardinality condition requiring SG27 to appear exactly once per message. SG27 is the transaction group (tx_group) in ORDRSP FV2510. Uses the group navigator to count SG27 instances at the top level. Falls back to Unknown when no navigator is available (e.g., when context is used without a pre-assembled tree). This is a structural cardinality rule rather than a content condition. (medium confidence)
1313 fn evaluate_2036(&self, ctx: &EvaluationContext) -> ConditionResult {
1314 // SG27 must appear exactly once per message
1315 // SG27 is the transaction group (tx_group) in ORDRSP
1316 if let Some(nav) = ctx.navigator() {
1317 let count = nav.group_instance_count(&["SG27"]);
1318 ConditionResult::from(count == 1)
1319 } else {
1320 ConditionResult::Unknown
1321 }
1322 }
1323}