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