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 // Hinweis: Möglicher Wert: ZB4 oder ZB5 — informational note documenting permitted values
535 ConditionResult::True
536 }
537
538 /// [39] Möglicher Wert: E17 oder Z07
539 fn evaluate_39(&self, _ctx: &EvaluationContext) -> ConditionResult {
540 // Hinweis: Möglicher Wert: E17 oder Z07 — informational note documenting permitted values
541 ConditionResult::True
542 }
543
544 /// [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
545 /// EXTERNAL: Requires context from outside the message.
546 fn evaluate_40(&self, ctx: &EvaluationContext) -> ConditionResult {
547 ctx.external.evaluate("country_has_postal_code")
548 }
549
550 /// [41] wenn SG2 AJT (Einzelheiten zu einer Anpassung/Änderung) DE4465 mit Wert ZB5 vorhanden
551 fn evaluate_41(&self, ctx: &EvaluationContext) -> ConditionResult {
552 ctx.has_qualifier("AJT", 0, "ZB5")
553 }
554
555 /// [42] Wenn SG2 AJT+Z07 (Antwortkategorie: Ablehnung (Keine Berechtigung)) vorhanden
556 fn evaluate_42(&self, ctx: &EvaluationContext) -> ConditionResult {
557 ctx.has_qualifier("AJT", 0, "Z07")
558 }
559
560 /// [43] Wenn AJT+A02/A03+E_1001 vorhanden
561 fn evaluate_43(&self, ctx: &EvaluationContext) -> ConditionResult {
562 let ajts = ctx.find_segments("AJT");
563 let found = ajts.iter().any(|s| {
564 let code = s
565 .elements
566 .first()
567 .and_then(|e| e.first())
568 .map(|v| v.as_str());
569 let pos = s
570 .elements
571 .get(1)
572 .and_then(|e| e.first())
573 .map(|v| v.as_str());
574 matches!(code, Some("A02") | Some("A03")) && matches!(pos, Some("E_1001"))
575 });
576 ConditionResult::from(found)
577 }
578
579 /// [44] Wenn AJT+A05+E_1000 vorhanden
580 fn evaluate_44(&self, ctx: &EvaluationContext) -> ConditionResult {
581 let ajts = ctx.find_segments("AJT");
582 let found = ajts.iter().any(|s| {
583 let code = s
584 .elements
585 .first()
586 .and_then(|e| e.first())
587 .map(|v| v.as_str());
588 let pos = s
589 .elements
590 .get(1)
591 .and_then(|e| e.first())
592 .map(|v| v.as_str());
593 matches!(code, Some("A05")) && matches!(pos, Some("E_1000"))
594 });
595 ConditionResult::from(found)
596 }
597
598 /// [45] Wenn AJT+A09+E_1000 vorhanden
599 fn evaluate_45(&self, ctx: &EvaluationContext) -> ConditionResult {
600 let ajts = ctx.find_segments("AJT");
601 let found = ajts.iter().any(|s| {
602 let code = s
603 .elements
604 .first()
605 .and_then(|e| e.first())
606 .map(|v| v.as_str());
607 let pos = s
608 .elements
609 .get(1)
610 .and_then(|e| e.first())
611 .map(|v| v.as_str());
612 matches!(code, Some("A09")) && matches!(pos, Some("E_1000"))
613 });
614 ConditionResult::from(found)
615 }
616
617 /// [46] Wenn AJT+A06+E_0552 vorhanden
618 fn evaluate_46(&self, ctx: &EvaluationContext) -> ConditionResult {
619 let ajts = ctx.find_segments("AJT");
620 let found = ajts.iter().any(|s| {
621 let code = s
622 .elements
623 .first()
624 .and_then(|e| e.first())
625 .map(|v| v.as_str());
626 let pos = s
627 .elements
628 .get(1)
629 .and_then(|e| e.first())
630 .map(|v| v.as_str());
631 matches!(code, Some("A06")) && matches!(pos, Some("E_0552"))
632 });
633 ConditionResult::from(found)
634 }
635
636 /// [47] Wenn AJT+A06+E_0553 vorhanden
637 fn evaluate_47(&self, ctx: &EvaluationContext) -> ConditionResult {
638 let ajts = ctx.find_segments("AJT");
639 let found = ajts.iter().any(|s| {
640 let code = s
641 .elements
642 .first()
643 .and_then(|e| e.first())
644 .map(|v| v.as_str());
645 let pos = s
646 .elements
647 .get(1)
648 .and_then(|e| e.first())
649 .map(|v| v.as_str());
650 matches!(code, Some("A06")) && matches!(pos, Some("E_0553"))
651 });
652 ConditionResult::from(found)
653 }
654
655 /// [48] Wenn AJT+A06+E_0554 vorhanden
656 fn evaluate_48(&self, ctx: &EvaluationContext) -> ConditionResult {
657 let ajts = ctx.find_segments("AJT");
658 let found = ajts.iter().any(|s| {
659 let code = s
660 .elements
661 .first()
662 .and_then(|e| e.first())
663 .map(|v| v.as_str());
664 let pos = s
665 .elements
666 .get(1)
667 .and_then(|e| e.first())
668 .map(|v| v.as_str());
669 matches!(code, Some("A06")) && matches!(pos, Some("E_0554"))
670 });
671 ConditionResult::from(found)
672 }
673
674 /// [49] nur, wenn in ursprünglicher Nachricht IMD++Z60 (Abbestellung Messprodukt mit Zählzeitdefinition des LF) vorhanden war
675 /// EXTERNAL: Requires context from outside the message.
676 fn evaluate_49(&self, ctx: &EvaluationContext) -> ConditionResult {
677 ctx.external.evaluate("original_order_had_imd_z60")
678 }
679
680 /// [50] wenn im DE3155 in demselben COM der Code EM vorhanden ist
681 fn evaluate_50(&self, ctx: &EvaluationContext) -> ConditionResult {
682 let coms = ctx.find_segments("COM");
683 ConditionResult::from(coms.iter().any(|s| {
684 s.elements
685 .first()
686 .and_then(|e| e.get(1))
687 .map(|v| v == "EM")
688 .unwrap_or(false)
689 }))
690 }
691
692 /// [51] wenn im DE3155 in demselben COM der Code TE / FX / AJ / AL vorhanden ist
693 fn evaluate_51(&self, ctx: &EvaluationContext) -> ConditionResult {
694 let coms = ctx.find_segments("COM");
695 ConditionResult::from(coms.iter().any(|s| {
696 matches!(
697 s.elements
698 .first()
699 .and_then(|e| e.get(1))
700 .map(|v| v.as_str()),
701 Some("TE") | Some("FX") | Some("AJ") | Some("AL")
702 )
703 }))
704 }
705
706 /// [53] Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z59
707 fn evaluate_53(&self, _ctx: &EvaluationContext) -> ConditionResult {
708 // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z59 — informational note about value origin, always applies
709 ConditionResult::True
710 }
711
712 /// [54] Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z80
713 fn evaluate_54(&self, _ctx: &EvaluationContext) -> ConditionResult {
714 // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z80 — informational note about value origin, always applies
715 ConditionResult::True
716 }
717
718 /// [55] Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z81
719 fn evaluate_55(&self, _ctx: &EvaluationContext) -> ConditionResult {
720 // Hinweis: Vorgangsnummer aus IDE DE7402 der UTILTS mit BGM+Z81 — informational note about value origin, always applies
721 ConditionResult::True
722 }
723
724 /// [56] wenn SG2 AJT+A02/A03/A06/A07/A10/A11+E_0548 vorhanden
725 fn evaluate_56(&self, ctx: &EvaluationContext) -> ConditionResult {
726 let ajts = ctx.find_segments("AJT");
727 ConditionResult::from(ajts.iter().any(|s| {
728 let de4465 = s
729 .elements
730 .first()
731 .and_then(|e| e.first())
732 .map(|s| s.as_str());
733 let de1082 = s
734 .elements
735 .get(1)
736 .and_then(|e| e.first())
737 .map(|s| s.as_str());
738 matches!(
739 de4465,
740 Some("A02") | Some("A03") | Some("A06") | Some("A07") | Some("A10") | Some("A11")
741 ) && de1082 == Some("E_0548")
742 }))
743 }
744
745 /// [57] wenn SG2 AJT+A02/A03/A06/A07/A10/A11+E_0549 vorhanden
746 fn evaluate_57(&self, ctx: &EvaluationContext) -> ConditionResult {
747 let ajts = ctx.find_segments("AJT");
748 ConditionResult::from(ajts.iter().any(|s| {
749 let de4465 = s
750 .elements
751 .first()
752 .and_then(|e| e.first())
753 .map(|s| s.as_str());
754 let de1082 = s
755 .elements
756 .get(1)
757 .and_then(|e| e.first())
758 .map(|s| s.as_str());
759 matches!(
760 de4465,
761 Some("A02") | Some("A03") | Some("A06") | Some("A07") | Some("A10") | Some("A11")
762 ) && de1082 == Some("E_0549")
763 }))
764 }
765
766 /// [58] wenn SG2 AJT+A02/A03/A06/A07+E_0550 vorhanden
767 fn evaluate_58(&self, ctx: &EvaluationContext) -> ConditionResult {
768 let ajts = ctx.find_segments("AJT");
769 ConditionResult::from(ajts.iter().any(|s| {
770 let de4465 = s
771 .elements
772 .first()
773 .and_then(|e| e.first())
774 .map(|s| s.as_str());
775 let de1082 = s
776 .elements
777 .get(1)
778 .and_then(|e| e.first())
779 .map(|s| s.as_str());
780 matches!(
781 de4465,
782 Some("A02") | Some("A03") | Some("A06") | Some("A07")
783 ) && de1082 == Some("E_0550")
784 }))
785 }
786
787 /// [59] wenn SG2 AJT+A02/A03/A06/A07/A10/A11+E_0551 vorhanden
788 fn evaluate_59(&self, ctx: &EvaluationContext) -> ConditionResult {
789 let ajts = ctx.find_segments("AJT");
790 ConditionResult::from(ajts.iter().any(|s| {
791 let de4465 = s
792 .elements
793 .first()
794 .and_then(|e| e.first())
795 .map(|s| s.as_str());
796 let de1082 = s
797 .elements
798 .get(1)
799 .and_then(|e| e.first())
800 .map(|s| s.as_str());
801 matches!(
802 de4465,
803 Some("A02") | Some("A03") | Some("A06") | Some("A07") | Some("A10") | Some("A11")
804 ) && de1082 == Some("E_0551")
805 }))
806 }
807
808 /// [61] wenn es sich bei der Reklamation um die Reklamation der Übersicht der Schaltzeitdefinitionen handelte
809 // 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)
810 fn evaluate_61(&self, ctx: &EvaluationContext) -> ConditionResult {
811 // Reklamation der Übersicht der Schaltzeitdefinitionen → ORDRSP with BGM+Z60
812 ctx.has_qualifier("BGM", 0, "Z60")
813 }
814
815 /// [62] wenn es sich bei der Reklamation um die Reklamation der Übersicht der Leistungskurvendefinitionen handelte
816 // 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)
817 fn evaluate_62(&self, ctx: &EvaluationContext) -> ConditionResult {
818 // Reklamation der Übersicht der Leistungskurvendefinitionen → BGM+Z78 or BGM+Z79
819 let bgm_segs = ctx.find_segments("BGM");
820 match bgm_segs.first() {
821 Some(s) => {
822 let code = s
823 .elements
824 .first()
825 .and_then(|e| e.first())
826 .map(|v| v.as_str());
827 ConditionResult::from(matches!(code, Some("Z78") | Some("Z79")))
828 }
829 None => ConditionResult::False, // segment absent → condition not applicable
830 }
831 }
832
833 /// [63] Dokumentennummer aus BGM+Z60 DE1004 der UTILTS
834 fn evaluate_63(&self, _ctx: &EvaluationContext) -> ConditionResult {
835 // Hinweis: Dokumentennummer aus BGM+Z60 DE1004 der UTILTS — informational note, always applies
836 ConditionResult::True
837 }
838
839 /// [64] Dokumentennummer aus BGM+Z78 DE1004 der UTILTS
840 fn evaluate_64(&self, _ctx: &EvaluationContext) -> ConditionResult {
841 // Hinweis: Dokumentennummer aus BGM+Z78 DE1004 der UTILTS — informational note, always applies
842 ConditionResult::True
843 }
844
845 /// [65] Dokumentennummer aus BGM+Z79 DE1004 der UTILTS
846 fn evaluate_65(&self, _ctx: &EvaluationContext) -> ConditionResult {
847 // Hinweis: Dokumentennummer aus BGM+Z79 DE1004 der UTILTS — informational note, always applies
848 ConditionResult::True
849 }
850
851 /// [66] wenn SG2 AJT+A01/A02/A03+E_0544 vorhanden
852 fn evaluate_66(&self, ctx: &EvaluationContext) -> ConditionResult {
853 let ajts = ctx.find_segments("AJT");
854 ConditionResult::from(ajts.iter().any(|s| {
855 let de4465 = s
856 .elements
857 .first()
858 .and_then(|e| e.first())
859 .map(|s| s.as_str());
860 let de1082 = s
861 .elements
862 .get(1)
863 .and_then(|e| e.first())
864 .map(|s| s.as_str());
865 matches!(de4465, Some("A01") | Some("A02") | Some("A03")) && de1082 == Some("E_0544")
866 }))
867 }
868
869 /// [67] wenn SG2 AJT+A01/A02/A03+E_0545 vorhanden
870 fn evaluate_67(&self, ctx: &EvaluationContext) -> ConditionResult {
871 let ajts = ctx.find_segments("AJT");
872 ConditionResult::from(ajts.iter().any(|s| {
873 let de4465 = s
874 .elements
875 .first()
876 .and_then(|e| e.first())
877 .map(|s| s.as_str());
878 let de1082 = s
879 .elements
880 .get(1)
881 .and_then(|e| e.first())
882 .map(|s| s.as_str());
883 matches!(de4465, Some("A01") | Some("A02") | Some("A03")) && de1082 == Some("E_0545")
884 }))
885 }
886
887 /// [68] wenn SG2 AJT+A02/A03+E_0546 vorhanden
888 fn evaluate_68(&self, ctx: &EvaluationContext) -> ConditionResult {
889 let ajts = ctx.find_segments("AJT");
890 ConditionResult::from(ajts.iter().any(|s| {
891 let de4465 = s
892 .elements
893 .first()
894 .and_then(|e| e.first())
895 .map(|s| s.as_str());
896 let de1082 = s
897 .elements
898 .get(1)
899 .and_then(|e| e.first())
900 .map(|s| s.as_str());
901 matches!(de4465, Some("A02") | Some("A03")) && de1082 == Some("E_0546")
902 }))
903 }
904
905 /// [69] wenn SG2 AJT+A01/A02/A03+E_0547 vorhanden
906 fn evaluate_69(&self, ctx: &EvaluationContext) -> ConditionResult {
907 let ajts = ctx.find_segments("AJT");
908 ConditionResult::from(ajts.iter().any(|s| {
909 let de4465 = s
910 .elements
911 .first()
912 .and_then(|e| e.first())
913 .map(|s| s.as_str());
914 let de1082 = s
915 .elements
916 .get(1)
917 .and_then(|e| e.first())
918 .map(|s| s.as_str());
919 matches!(de4465, Some("A01") | Some("A02") | Some("A03")) && de1082 == Some("E_0547")
920 }))
921 }
922
923 /// [72] wenn AJT+A04+E_0552 vorhanden
924 fn evaluate_72(&self, ctx: &EvaluationContext) -> ConditionResult {
925 ctx.has_qualified_value("AJT", 0, "A04", 1, 0, &["E_0552"])
926 }
927
928 /// [73] wenn AJT+A04+E_0553 vorhanden
929 fn evaluate_73(&self, ctx: &EvaluationContext) -> ConditionResult {
930 ctx.has_qualified_value("AJT", 0, "A04", 1, 0, &["E_0553"])
931 }
932
933 /// [74] wenn AJT+A04+E_0554 vorhanden
934 fn evaluate_74(&self, ctx: &EvaluationContext) -> ConditionResult {
935 ctx.has_qualified_value("AJT", 0, "A04", 1, 0, &["E_0554"])
936 }
937
938 /// [76] Wenn FTX+Z27 (IP-Adresse des Absenders) nicht vorhanden
939 fn evaluate_76(&self, ctx: &EvaluationContext) -> ConditionResult {
940 ctx.lacks_qualifier("FTX", 0, "Z27")
941 }
942
943 /// [77] Wenn FTX+Z28 (IP-Range des Absenders) nicht vorhanden
944 fn evaluate_77(&self, ctx: &EvaluationContext) -> ConditionResult {
945 ctx.lacks_qualifier("FTX", 0, "Z28")
946 }
947
948 /// [492] wenn MP-ID in NAD+MR aus Sparte Strom
949 /// EXTERNAL: Requires context from outside the message.
950 fn evaluate_492(&self, ctx: &EvaluationContext) -> ConditionResult {
951 ctx.external.evaluate("recipient_is_strom")
952 }
953
954 /// [493] wenn MP-ID in NAD+MR aus Sparte Gas
955 /// EXTERNAL: Requires context from outside the message.
956 fn evaluate_493(&self, ctx: &EvaluationContext) -> ConditionResult {
957 ctx.external.evaluate("recipient_is_gas")
958 }
959
960 /// [494] Das hier genannte Datum muss der Zeitpunkt sein, zu dem das Dokument erstellt wurde, oder ein Zeitpunkt, der davor liegt.
961 // 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)
962 fn evaluate_494(&self, _ctx: &EvaluationContext) -> ConditionResult {
963 ConditionResult::True
964 }
965
966 /// [500] Hinweis: Angabe eines technischen Ansprechpartners für die Geräteübernahme
967 fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
968 ConditionResult::True
969 }
970
971 /// [503] Hinweis: Datum, bis zu dem der MSBA zur Fortführung verpflichtet wurde
972 fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
973 ConditionResult::True
974 }
975
976 /// [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...
977 fn evaluate_504(&self, _ctx: &EvaluationContext) -> ConditionResult {
978 // 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.
979 ConditionResult::True
980 }
981
982 /// [513] Hinweis: Wert aus BGM+Z12 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
983 fn evaluate_513(&self, _ctx: &EvaluationContext) -> ConditionResult {
984 // Hinweis: Wert aus BGM+Z12 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
985 ConditionResult::True
986 }
987
988 /// [518] Hinweis: Wert aus BGM+Z10 DE1004 der ORDERS, mit der die Bestellung erfolgt ist
989 fn evaluate_518(&self, _ctx: &EvaluationContext) -> ConditionResult {
990 // Hinweis: Wert aus BGM+Z10 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
991 ConditionResult::True
992 }
993
994 /// [519] Hinweis: Wert aus BGM+7 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
995 fn evaluate_519(&self, _ctx: &EvaluationContext) -> ConditionResult {
996 // Hinweis: Wert aus BGM+7 DE1004 der ORDERS, mit der die Bestellung erfolgt ist.
997 ConditionResult::True
998 }
999
1000 /// [520] Hinweis: Wert aus BGM+Z29 DE1004 der ORDERS, mit der die Anfrage zur Beendigung der Rechnungsabwicklung erfolgt ist.
1001 fn evaluate_520(&self, _ctx: &EvaluationContext) -> ConditionResult {
1002 // Hinweis: Wert aus BGM+Z29 DE1004 der ORDERS, mit der die Anfrage zur Beendigung der Rechnungsabwicklung erfolgt ist.
1003 ConditionResult::True
1004 }
1005
1006 /// [521] Hinweis: Wert aus BGM+Z14/Z61/Z62 DE1004 der ORDERS, mit der die Anforderung von Stammdaten erfolgt ist
1007 fn evaluate_521(&self, _ctx: &EvaluationContext) -> ConditionResult {
1008 // Hinweis: Wert aus BGM+Z14/Z61/Z62 DE1004 der ORDERS, mit der die Anforderung von Stammdaten erfolgt ist
1009 // Informational note — documents that the BGM DE1004 value originates from the original ORDERS request.
1010 ConditionResult::True
1011 }
1012
1013 /// [522] Hinweis: Wert aus BGM+7/Z28/Z48 DE1004 der ORDERS, mit der die Anforderung von Werten erfolgt ist.
1014 fn evaluate_522(&self, _ctx: &EvaluationContext) -> ConditionResult {
1015 // Hinweis: Wert aus BGM+7/Z28/Z48 DE1004 der ORDERS — informational note, always applies
1016 ConditionResult::True
1017 }
1018
1019 /// [523] Hinweis: Wert aus BGM+7 DE1004 der ORDERS, mit der die Anforderung Anforderung von Brennwert und Zustandszahl erfolgt ist.
1020 fn evaluate_523(&self, _ctx: &EvaluationContext) -> ConditionResult {
1021 // Hinweis: Wert aus BGM+7 DE1004 der ORDERS — informational note, always applies
1022 ConditionResult::True
1023 }
1024
1025 /// [524] Hinweis: Wert aus BGM+Z14 DE1004 der ORDERS, mit der die Anfrage vom MSB Gas erfolgt ist.
1026 fn evaluate_524(&self, _ctx: &EvaluationContext) -> ConditionResult {
1027 // Hinweis: Wert aus BGM+Z14 DE1004 der ORDERS — informational note, always applies
1028 ConditionResult::True
1029 }
1030
1031 /// [525] Hinweis: Wert aus BGM+Z24 DE1004 der ORDERS, mit der die Anforderung Allokationsliste erfolgt ist
1032 fn evaluate_525(&self, _ctx: &EvaluationContext) -> ConditionResult {
1033 // Hinweis: Wert aus BGM+Z24 DE1004 der ORDERS — informational note, always applies
1034 ConditionResult::True
1035 }
1036
1037 /// [526] Hinweis: Wert aus BGM+Z23 DE1004 der ORDERS, mit der die Anforderung bilanzierte Menge erfolgt ist
1038 fn evaluate_526(&self, _ctx: &EvaluationContext) -> ConditionResult {
1039 // Hinweis: Wert aus BGM+Z23 DE1004 der ORDERS — informational note, always applies
1040 ConditionResult::True
1041 }
1042
1043 /// [527] Hinweis: Wert aus BGM+Z34 DE1004 der ORDERS, mit der die Reklamation von Werten erfolgt ist.
1044 fn evaluate_527(&self, _ctx: &EvaluationContext) -> ConditionResult {
1045 // Hinweis: Wert aus BGM+Z34 DE1004 der ORDERS, mit der die Reklamation von Werten erfolgt ist. — informational note, always applies
1046 ConditionResult::True
1047 }
1048
1049 /// [529] Hinweis: Dokumentennummer aus BGM DE1004 der ORDERS
1050 fn evaluate_529(&self, _ctx: &EvaluationContext) -> ConditionResult {
1051 // Hinweis: Dokumentennummer aus BGM DE1004 der ORDERS — informational note, always applies
1052 ConditionResult::True
1053 }
1054
1055 /// [530] Hinweis: Dokumentennummer aus BGM DE1004 der ORDCHG
1056 fn evaluate_530(&self, _ctx: &EvaluationContext) -> ConditionResult {
1057 // Hinweis: Dokumentennummer aus BGM DE1004 der ORDCHG — informational note, always applies
1058 ConditionResult::True
1059 }
1060
1061 /// [533] Hinweis: Wert aus BGM+Z51 DE1004 der ORDCHG
1062 fn evaluate_533(&self, _ctx: &EvaluationContext) -> ConditionResult {
1063 // Hinweis: Wert aus BGM+Z51 DE1004 der ORDCHG — informational note, always applies
1064 ConditionResult::True
1065 }
1066
1067 /// [534] Hinweis: Wert aus BGM+Z52 DE1004 der ORDCHG
1068 fn evaluate_534(&self, _ctx: &EvaluationContext) -> ConditionResult {
1069 // Hinweis: Wert aus BGM+Z52 DE1004 der ORDCHG — informational note, always applies
1070 ConditionResult::True
1071 }
1072
1073 /// [535] Hinweis: Wert aus BGM+Z13 DE1004 der ORDERS, mit der die Ankündigung Gerätewechselabsicht erfolgt ist.
1074 fn evaluate_535(&self, _ctx: &EvaluationContext) -> ConditionResult {
1075 // Hinweis: Wert aus BGM+Z13 DE1004 der ORDERS — informational note, always applies
1076 ConditionResult::True
1077 }
1078
1079 /// [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.
1080 fn evaluate_536(&self, _ctx: &EvaluationContext) -> ConditionResult {
1081 // Hinweis: MP-ID des Eigentümers (MSB) angeben — informational note, always applies
1082 ConditionResult::True
1083 }
1084
1085 /// [537] Hinweis: Wert aus BGM+Z72 DE1004 der ORDERS, mit der die Bestellung Beendigung der Konfiguration erfolgt ist.
1086 fn evaluate_537(&self, _ctx: &EvaluationContext) -> ConditionResult {
1087 // Hinweis: Wert aus BGM+Z72 DE1004 der ORDERS — informational note, always applies
1088 ConditionResult::True
1089 }
1090
1091 /// [538] Hinweis: Wert aus BGM+Z76 DE1004 der ORDERS, mit der die Reklamation der Konfiguration erfolgt ist.
1092 fn evaluate_538(&self, _ctx: &EvaluationContext) -> ConditionResult {
1093 // Hinweis: Wert aus BGM+Z76 DE1004 der ORDERS — informational note, always applies
1094 ConditionResult::True
1095 }
1096
1097 /// [539] Hinweis: Wert aus BGM+Z73/Z74 DE1004 der ORDERS, mit der die Bestellung der Konfiguration erfolgt ist.
1098 fn evaluate_539(&self, _ctx: &EvaluationContext) -> ConditionResult {
1099 // Hinweis: Wert aus BGM+Z73/Z74 DE1004 der ORDERS — informational note, always applies
1100 ConditionResult::True
1101 }
1102
1103 /// [540] Hinweis: Es darf nur eine Information im DE3148 übermittelt werden
1104 fn evaluate_540(&self, _ctx: &EvaluationContext) -> ConditionResult {
1105 // Hinweis: Es darf nur eine Information im DE3148 übermittelt werden — informational note, always applies
1106 ConditionResult::True
1107 }
1108
1109 /// [542] Hinweis: Wert aus BGM+Z91 DE1004 der ORDERS, mit der die Bestellung Änderung der Abrechnungsdaten erfolgt ist.
1110 fn evaluate_542(&self, _ctx: &EvaluationContext) -> ConditionResult {
1111 // Hinweis: Wert aus BGM+Z91 DE1004 der ORDERS — informational note about value origin, always applies
1112 ConditionResult::True
1113 }
1114
1115 /// [902] Format: Format: Möglicher Wert: ≥ 0
1116 // 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)
1117 fn evaluate_902(&self, ctx: &EvaluationContext) -> ConditionResult {
1118 ctx.format_check("QTY", 0, 1, |val| validate_numeric(val, ">=", 0.0))
1119 }
1120
1121 /// [903] Format: Möglicher Wert: 1
1122 // 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)
1123 fn evaluate_903(&self, ctx: &EvaluationContext) -> ConditionResult {
1124 ctx.format_check("QTY", 0, 1, |val| validate_numeric(val, "==", 1.0))
1125 }
1126
1127 /// [930] Format: max. 2 Nachkommastellen
1128 // 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)
1129 fn evaluate_930(&self, ctx: &EvaluationContext) -> ConditionResult {
1130 ctx.format_check("QTY", 0, 1, |val| validate_max_decimal_places(val, 2))
1131 }
1132
1133 /// [931] Format: ZZZ = +00
1134 fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
1135 ctx.format_check("DTM", 0, 1, validate_timezone_utc)
1136 }
1137
1138 /// [932] Format: HHMM = 2200
1139 fn evaluate_932(&self, ctx: &EvaluationContext) -> ConditionResult {
1140 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "2200"))
1141 }
1142
1143 /// [933] Format: HHMM = 2300
1144 fn evaluate_933(&self, ctx: &EvaluationContext) -> ConditionResult {
1145 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "2300"))
1146 }
1147
1148 /// [934] Format: HHMM = 0400
1149 fn evaluate_934(&self, ctx: &EvaluationContext) -> ConditionResult {
1150 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "0400"))
1151 }
1152
1153 /// [935] Format: HHMM = 0500
1154 fn evaluate_935(&self, ctx: &EvaluationContext) -> ConditionResult {
1155 ctx.format_check("DTM", 0, 1, |val| validate_hhmm_equals(val, "0500"))
1156 }
1157
1158 /// [939] Format: Die Zeichenkette muss die Zeichen @ und . enthalten
1159 // 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)
1160 fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
1161 // Format: string must contain '@' and '.' — email address format check
1162 // Applied to COM segment with EM (Electronic Mail) qualifier
1163 // COM+address:qualifier → elements[0] = ["address", "qualifier"]
1164 let com_segs = ctx.find_segments("COM");
1165 for seg in &com_segs {
1166 if let Some(elem0) = seg.elements.first() {
1167 if elem0.get(1).map(|q| q == "EM").unwrap_or(false) {
1168 let value = elem0.first().map(|s| s.as_str()).unwrap_or("");
1169 if value.is_empty() {
1170 return ConditionResult::Unknown;
1171 }
1172 return ConditionResult::from(value.contains('@') && value.contains('.'));
1173 }
1174 }
1175 }
1176 ConditionResult::Unknown
1177 }
1178
1179 /// [940] Format: Die Zeichenkette muss mit dem Zeichen + beginnen und danach dürfen nur noch Ziffern folgen
1180 // 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)
1181 fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
1182 // Format: string must start with '+' and be followed only by digits — international phone number format
1183 // Applied to COM segments with phone-type qualifiers: TE (Telephone), FX (Telefax), AH (After Hours)
1184 // COM+number:qualifier → elements[0] = ["number", "qualifier"]
1185 let com_segs = ctx.find_segments("COM");
1186 for seg in &com_segs {
1187 if let Some(elem0) = seg.elements.first() {
1188 let qualifier = elem0.get(1).map(|s| s.as_str()).unwrap_or("");
1189 if matches!(qualifier, "TE" | "FX" | "AH") {
1190 let value = elem0.first().map(|s| s.as_str()).unwrap_or("");
1191 if value.is_empty() {
1192 return ConditionResult::Unknown;
1193 }
1194 return ConditionResult::from(
1195 value.starts_with('+')
1196 && value.len() > 1
1197 && value[1..].chars().all(|c| c.is_ascii_digit()),
1198 );
1199 }
1200 }
1201 }
1202 ConditionResult::Unknown
1203 }
1204
1205 /// [2036] Pro Nachricht ist die SG27 genau einmal anzugeben
1206 // 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)
1207 fn evaluate_2036(&self, ctx: &EvaluationContext) -> ConditionResult {
1208 // SG27 must appear exactly once per message
1209 // SG27 is the transaction group (tx_group) in ORDRSP
1210 if let Some(nav) = ctx.navigator() {
1211 let count = nav.group_instance_count(&["SG27"]);
1212 ConditionResult::from(count == 1)
1213 } else {
1214 ConditionResult::Unknown
1215 }
1216 }
1217}