1#[allow(unused_imports)]
8use crate::eval::format_validators::*;
9use crate::eval::{ConditionEvaluator, ConditionResult, EvaluationContext};
10
11pub struct PartinConditionEvaluatorFV2604 {
13 external_conditions: std::collections::HashSet<u32>,
15}
16
17impl Default for PartinConditionEvaluatorFV2604 {
18 fn default() -> Self {
19 let mut external_conditions = std::collections::HashSet::new();
20 external_conditions.insert(1);
21 external_conditions.insert(2);
22 external_conditions.insert(4);
23 external_conditions.insert(5);
24 external_conditions.insert(9);
25 external_conditions.insert(17);
26 external_conditions.insert(18);
27 external_conditions.insert(19);
28 external_conditions.insert(20);
29 external_conditions.insert(21);
30 external_conditions.insert(22);
31 external_conditions.insert(23);
32 external_conditions.insert(24);
33 external_conditions.insert(25);
34 external_conditions.insert(26);
35 external_conditions.insert(35);
36 external_conditions.insert(36);
37 external_conditions.insert(41);
38 external_conditions.insert(45);
39 external_conditions.insert(46);
40 external_conditions.insert(49);
41 external_conditions.insert(50);
42 Self {
43 external_conditions,
44 }
45 }
46}
47
48impl ConditionEvaluator for PartinConditionEvaluatorFV2604 {
49 fn message_type(&self) -> &str {
50 "PARTIN"
51 }
52
53 fn format_version(&self) -> &str {
54 "FV2604"
55 }
56
57 fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
58 match condition {
59 1 => self.evaluate_1(ctx),
60 2 => self.evaluate_2(ctx),
61 3 => self.evaluate_3(ctx),
62 4 => self.evaluate_4(ctx),
63 5 => self.evaluate_5(ctx),
64 6 => self.evaluate_6(ctx),
65 7 => self.evaluate_7(ctx),
66 8 => self.evaluate_8(ctx),
67 9 => self.evaluate_9(ctx),
68 10 => self.evaluate_10(ctx),
69 11 => self.evaluate_11(ctx),
70 12 => self.evaluate_12(ctx),
71 13 => self.evaluate_13(ctx),
72 14 => self.evaluate_14(ctx),
73 15 => self.evaluate_15(ctx),
74 16 => self.evaluate_16(ctx),
75 17 => self.evaluate_17(ctx),
76 18 => self.evaluate_18(ctx),
77 19 => self.evaluate_19(ctx),
78 20 => self.evaluate_20(ctx),
79 21 => self.evaluate_21(ctx),
80 22 => self.evaluate_22(ctx),
81 23 => self.evaluate_23(ctx),
82 24 => self.evaluate_24(ctx),
83 25 => self.evaluate_25(ctx),
84 26 => self.evaluate_26(ctx),
85 27 => self.evaluate_27(ctx),
86 28 => self.evaluate_28(ctx),
87 29 => self.evaluate_29(ctx),
88 30 => self.evaluate_30(ctx),
89 31 => self.evaluate_31(ctx),
90 32 => self.evaluate_32(ctx),
91 33 => self.evaluate_33(ctx),
92 34 => self.evaluate_34(ctx),
93 35 => self.evaluate_35(ctx),
94 36 => self.evaluate_36(ctx),
95 41 => self.evaluate_41(ctx),
96 43 => self.evaluate_43(ctx),
97 44 => self.evaluate_44(ctx),
98 45 => self.evaluate_45(ctx),
99 46 => self.evaluate_46(ctx),
100 49 => self.evaluate_49(ctx),
101 50 => self.evaluate_50(ctx),
102 490 => self.evaluate_490(ctx),
103 491 => self.evaluate_491(ctx),
104 494 => self.evaluate_494(ctx),
105 500 => self.evaluate_500(ctx),
106 501 => self.evaluate_501(ctx),
107 502 => self.evaluate_502(ctx),
108 503 => self.evaluate_503(ctx),
109 504 => self.evaluate_504(ctx),
110 505 => self.evaluate_505(ctx),
111 506 => self.evaluate_506(ctx),
112 508 => self.evaluate_508(ctx),
113 908 => self.evaluate_908(ctx),
114 931 => self.evaluate_931(ctx),
115 932 => self.evaluate_932(ctx),
116 933 => self.evaluate_933(ctx),
117 939 => self.evaluate_939(ctx),
118 940 => self.evaluate_940(ctx),
119 _ => ConditionResult::Unknown,
120 }
121 }
122
123 fn is_external(&self, condition: u32) -> bool {
124 self.external_conditions.contains(&condition)
125 }
126 fn is_known(&self, condition: u32) -> bool {
127 matches!(
128 condition,
129 1 | 2
130 | 3
131 | 4
132 | 5
133 | 6
134 | 7
135 | 8
136 | 9
137 | 10
138 | 11
139 | 12
140 | 13
141 | 14
142 | 15
143 | 16
144 | 17
145 | 18
146 | 19
147 | 20
148 | 21
149 | 22
150 | 23
151 | 24
152 | 25
153 | 26
154 | 27
155 | 28
156 | 29
157 | 30
158 | 31
159 | 32
160 | 33
161 | 34
162 | 35
163 | 36
164 | 41
165 | 43
166 | 44
167 | 45
168 | 46
169 | 49
170 | 50
171 | 490
172 | 491
173 | 494
174 | 500
175 | 501
176 | 502
177 | 503
178 | 504
179 | 505
180 | 506
181 | 508
182 | 908
183 | 931
184 | 932
185 | 933
186 | 939
187 | 940
188 )
189 }
190}
191
192impl PartinConditionEvaluatorFV2604 {
193 fn evaluate_9(&self, ctx: &EvaluationContext) -> ConditionResult {
196 ctx.external.evaluate("sender_communication_inactive")
197 }
198
199 fn evaluate_41(&self, ctx: &EvaluationContext) -> ConditionResult {
202 ctx.external.evaluate("mp_id_is_gas_sector")
203 }
204
205 fn evaluate_43(&self, ctx: &EvaluationContext) -> ConditionResult {
207 ctx.has_segment_matching("NAD", &[(0, 0, "Z71"), (8, 0, "DE")])
209 }
210
211 fn evaluate_44(&self, ctx: &EvaluationContext) -> ConditionResult {
213 match ctx.has_segment_matching("NAD", &[(0, 0, "Z71"), (8, 0, "DE")]) {
215 ConditionResult::True => ConditionResult::False,
216 ConditionResult::False => ConditionResult::True,
217 ConditionResult::Unknown => ConditionResult::Unknown,
218 }
219 }
220
221 fn evaluate_45(&self, ctx: &EvaluationContext) -> ConditionResult {
224 ctx.external.evaluate("recipient_is_lf_or_nb")
225 }
226
227 fn evaluate_46(&self, ctx: &EvaluationContext) -> ConditionResult {
230 ctx.external.evaluate("recipient_is_lf_msb_mgv")
231 }
232
233 fn evaluate_49(&self, ctx: &EvaluationContext) -> ConditionResult {
236 ctx.external.evaluate("recipient_is_lf_mgv")
237 }
238
239 fn evaluate_50(&self, ctx: &EvaluationContext) -> ConditionResult {
242 ctx.external.evaluate("recipient_is_lf_mgv_nb")
243 }
244
245 fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
247 ConditionResult::True
249 }
250
251 fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
254 ctx.external.evaluate("mp_id_is_strom")
255 }
256
257 fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
260 ctx.external.evaluate("country_has_postal_code")
261 }
262
263 fn evaluate_3(&self, _ctx: &EvaluationContext) -> ConditionResult {
265 ConditionResult::True
267 }
268
269 fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
272 ctx.external.evaluate("predecessor_version_exists")
273 }
274
275 fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
278 ctx.external.evaluate("recipient_is_lf")
279 }
280
281 fn evaluate_6(&self, ctx: &EvaluationContext) -> ConditionResult {
283 let coms = ctx.find_segments("COM");
284 if coms.is_empty() {
285 return ConditionResult::Unknown;
286 }
287 ConditionResult::from(coms.iter().any(|s| {
288 s.elements
289 .first()
290 .and_then(|e| e.get(1))
291 .is_some_and(|v| v == "EM")
292 }))
293 }
294
295 fn evaluate_7(&self, ctx: &EvaluationContext) -> ConditionResult {
297 let coms = ctx.find_segments("COM");
298 if coms.is_empty() {
299 return ConditionResult::Unknown;
300 }
301 ConditionResult::from(coms.iter().any(|s| {
302 s.elements
303 .first()
304 .and_then(|e| e.get(1))
305 .is_some_and(|v| matches!(v.as_str(), "TE" | "FX" | "AJ" | "AL"))
306 }))
307 }
308
309 fn evaluate_8(&self, ctx: &EvaluationContext) -> ConditionResult {
311 let coms = ctx.find_segments("COM");
312 if coms.is_empty() {
313 return ConditionResult::Unknown;
314 }
315 ConditionResult::from(coms.iter().any(|s| {
316 s.elements
317 .first()
318 .and_then(|e| e.get(1))
319 .is_some_and(|v| matches!(v.as_str(), "TE" | "FX"))
320 }))
321 }
322
323 fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
325 match ctx.find_segment("BGM") {
326 None => ConditionResult::False, Some(bgm) => ConditionResult::from(
328 bgm.elements
329 .get(4)
330 .and_then(|e| e.first())
331 .map(|v| v != "11")
332 .unwrap_or(true),
333 ),
334 }
335 }
336
337 fn evaluate_11(&self, ctx: &EvaluationContext) -> ConditionResult {
339 let nads = ctx.find_segments_with_qualifier("NAD", 0, "SU");
340 match nads.first() {
341 None => ConditionResult::False, Some(nad) => ConditionResult::from(
343 nad.elements
344 .get(8)
345 .and_then(|e| e.first())
346 .is_some_and(|v| v == "DE"),
347 ),
348 }
349 }
350
351 fn evaluate_12(&self, ctx: &EvaluationContext) -> ConditionResult {
353 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DDM");
354 match nads.first() {
355 None => ConditionResult::False, Some(nad) => ConditionResult::from(
357 nad.elements
358 .get(8)
359 .and_then(|e| e.first())
360 .is_some_and(|v| v == "DE"),
361 ),
362 }
363 }
364
365 fn evaluate_13(&self, ctx: &EvaluationContext) -> ConditionResult {
367 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DEB");
368 match nads.first() {
369 None => ConditionResult::False, Some(nad) => ConditionResult::from(
371 nad.elements
372 .get(8)
373 .and_then(|e| e.first())
374 .is_some_and(|v| v == "DE"),
375 ),
376 }
377 }
378
379 fn evaluate_14(&self, ctx: &EvaluationContext) -> ConditionResult {
381 let nads = ctx.find_segments_with_qualifier("NAD", 0, "SU");
382 match nads.first() {
383 None => ConditionResult::False, Some(nad) => ConditionResult::from(
385 nad.elements
386 .get(8)
387 .and_then(|e| e.first())
388 .map(|v| v != "DE")
389 .unwrap_or(true),
390 ),
391 }
392 }
393
394 fn evaluate_15(&self, ctx: &EvaluationContext) -> ConditionResult {
396 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DDM");
397 match nads.first() {
398 None => ConditionResult::False, Some(nad) => ConditionResult::from(
400 nad.elements
401 .get(8)
402 .and_then(|e| e.first())
403 .map(|v| v != "DE")
404 .unwrap_or(true),
405 ),
406 }
407 }
408
409 fn evaluate_16(&self, ctx: &EvaluationContext) -> ConditionResult {
411 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DEB");
412 match nads.first() {
413 None => ConditionResult::False, Some(nad) => ConditionResult::from(
415 nad.elements
416 .get(8)
417 .and_then(|e| e.first())
418 .map(|v| v != "DE")
419 .unwrap_or(true),
420 ),
421 }
422 }
423
424 fn evaluate_17(&self, ctx: &EvaluationContext) -> ConditionResult {
427 ctx.external.evaluate("recipient_is_lf_nb_msb")
428 }
429
430 fn evaluate_18(&self, ctx: &EvaluationContext) -> ConditionResult {
433 ctx.external.evaluate("recipient_is_lf_msb")
434 }
435
436 fn evaluate_19(&self, ctx: &EvaluationContext) -> ConditionResult {
439 ctx.external.evaluate("recipient_is_lf_msb_nb_uenb")
440 }
441
442 fn evaluate_20(&self, ctx: &EvaluationContext) -> ConditionResult {
445 ctx.external.evaluate("recipient_is_lf_msb_uenb")
446 }
447
448 fn evaluate_21(&self, ctx: &EvaluationContext) -> ConditionResult {
451 ctx.external.evaluate("recipient_is_lf_nb_esa")
452 }
453
454 fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
457 ctx.external.evaluate("recipient_is_msb")
458 }
459
460 fn evaluate_23(&self, ctx: &EvaluationContext) -> ConditionResult {
463 ctx.external.evaluate("recipient_is_nb_uenb")
464 }
465
466 fn evaluate_24(&self, ctx: &EvaluationContext) -> ConditionResult {
469 ctx.external.evaluate("recipient_is_nb_lf_msb_esa")
470 }
471
472 fn evaluate_25(&self, ctx: &EvaluationContext) -> ConditionResult {
475 ctx.external.evaluate("recipient_is_nb")
476 }
477
478 fn evaluate_26(&self, ctx: &EvaluationContext) -> ConditionResult {
481 ctx.external.evaluate("recipient_is_nb_lf_bkv_biko")
482 }
483
484 fn evaluate_27(&self, ctx: &EvaluationContext) -> ConditionResult {
486 ctx.has_qualified_value("NAD", 0, "Z31", 8, 0, &["DE"])
487 }
488
489 fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
491 ctx.has_qualified_value("NAD", 0, "Z34", 8, 0, &["DE"])
492 }
493
494 fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
496 ctx.has_qualified_value("NAD", 0, "Z35", 8, 0, &["DE"])
497 }
498
499 fn evaluate_30(&self, ctx: &EvaluationContext) -> ConditionResult {
501 ctx.has_qualified_value("NAD", 0, "Z36", 8, 0, &["DE"])
502 }
503
504 fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
506 match ctx.has_qualified_value("NAD", 0, "Z31", 8, 0, &["DE"]) {
507 ConditionResult::True => ConditionResult::False,
508 ConditionResult::False => ConditionResult::True,
509 ConditionResult::Unknown => ConditionResult::Unknown,
510 }
511 }
512
513 fn evaluate_32(&self, ctx: &EvaluationContext) -> ConditionResult {
515 let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z34");
516 if nads.is_empty() {
517 return ConditionResult::True;
518 }
519 let has_de = nads.iter().any(|s| {
520 s.elements
521 .get(8)
522 .and_then(|e| e.first())
523 .is_some_and(|v| v == "DE")
524 });
525 ConditionResult::from(!has_de)
526 }
527
528 fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
530 let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z35");
531 if nads.is_empty() {
532 return ConditionResult::True;
533 }
534 let has_de = nads.iter().any(|s| {
535 s.elements
536 .get(8)
537 .and_then(|e| e.first())
538 .is_some_and(|v| v == "DE")
539 });
540 ConditionResult::from(!has_de)
541 }
542
543 fn evaluate_34(&self, ctx: &EvaluationContext) -> ConditionResult {
545 let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z36");
546 if nads.is_empty() {
547 return ConditionResult::True;
548 }
549 let has_de = nads.iter().any(|s| {
550 s.elements
551 .get(8)
552 .and_then(|e| e.first())
553 .is_some_and(|v| v == "DE")
554 });
555 ConditionResult::from(!has_de)
556 }
557
558 fn evaluate_35(&self, ctx: &EvaluationContext) -> ConditionResult {
561 ctx.external.evaluate("recipient_is_uenb")
562 }
563
564 fn evaluate_36(&self, ctx: &EvaluationContext) -> ConditionResult {
567 ctx.external.evaluate("recipient_is_bkv")
568 }
569
570 fn evaluate_490(&self, ctx: &EvaluationContext) -> ConditionResult {
572 let dtm_segs = ctx.find_segments("DTM");
574 match dtm_segs
575 .first()
576 .and_then(|s| s.elements.first())
577 .and_then(|e| e.get(1))
578 {
579 Some(val) => is_mesz_utc(val),
580 None => ConditionResult::False, }
582 }
583
584 fn evaluate_491(&self, ctx: &EvaluationContext) -> ConditionResult {
586 let dtm_segs = ctx.find_segments("DTM");
587 match dtm_segs
588 .first()
589 .and_then(|s| s.elements.first())
590 .and_then(|e| e.get(1))
591 {
592 Some(val) => is_mez_utc(val),
593 None => ConditionResult::False, }
595 }
596
597 fn evaluate_494(&self, _ctx: &EvaluationContext) -> ConditionResult {
600 ConditionResult::True
604 }
605
606 fn evaluate_501(&self, _ctx: &EvaluationContext) -> ConditionResult {
608 ConditionResult::True
611 }
612
613 fn evaluate_502(&self, _ctx: &EvaluationContext) -> ConditionResult {
615 ConditionResult::True
618 }
619
620 fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
622 ConditionResult::True
624 }
625
626 fn evaluate_504(&self, _ctx: &EvaluationContext) -> ConditionResult {
628 ConditionResult::True
630 }
631
632 fn evaluate_505(&self, ctx: &EvaluationContext) -> ConditionResult {
635 let acw_segments = ctx.find_segments_with_qualifier("RFF", 0, "ACW");
636 if acw_segments.is_empty() {
637 return ConditionResult::False;
638 }
639 let agk_segments = ctx.find_segments_with_qualifier("RFF", 0, "AGK");
640 let current_version = agk_segments
641 .first()
642 .and_then(|s| s.elements.first())
643 .and_then(|e| e.get(3))
644 .and_then(|v| v.parse::<i64>().ok());
645 let predecessor_version = acw_segments
646 .first()
647 .and_then(|s| s.elements.first())
648 .and_then(|e| e.get(3))
649 .and_then(|v| v.parse::<i64>().ok());
650 match (current_version, predecessor_version) {
651 (Some(cur), Some(pred)) => ConditionResult::from(cur >= pred + 1),
652 _ => ConditionResult::Unknown,
653 }
654 }
655
656 fn evaluate_506(&self, _ctx: &EvaluationContext) -> ConditionResult {
658 ConditionResult::True
660 }
661
662 fn evaluate_508(&self, _ctx: &EvaluationContext) -> ConditionResult {
664 ConditionResult::True
666 }
667
668 fn evaluate_908(&self, _ctx: &EvaluationContext) -> ConditionResult {
670 ConditionResult::True
672 }
673
674 fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
676 let dtm_segs = ctx.find_segments("DTM");
678 match dtm_segs
679 .first()
680 .and_then(|s| s.elements.first())
681 .and_then(|e| e.get(1))
682 {
683 Some(val) => validate_timezone_utc(val),
684 None => ConditionResult::False, }
686 }
687
688 fn evaluate_932(&self, ctx: &EvaluationContext) -> ConditionResult {
690 let dtm_segs = ctx.find_segments("DTM");
692 match dtm_segs
693 .first()
694 .and_then(|s| s.elements.first())
695 .and_then(|e| e.get(1))
696 {
697 Some(val) => validate_hhmm_equals(val, "2200"),
698 None => ConditionResult::False, }
700 }
701
702 fn evaluate_933(&self, ctx: &EvaluationContext) -> ConditionResult {
704 let dtm_segs = ctx.find_segments("DTM");
706 match dtm_segs
707 .first()
708 .and_then(|s| s.elements.first())
709 .and_then(|e| e.get(1))
710 {
711 Some(val) => validate_hhmm_equals(val, "2300"),
712 None => ConditionResult::False, }
714 }
715
716 fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
718 let segs = ctx.find_segments("COM");
720 match segs
721 .first()
722 .and_then(|s| s.elements.first())
723 .and_then(|e| e.first())
724 {
725 Some(val) => validate_email(val),
726 None => ConditionResult::False, }
728 }
729
730 fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
732 let segs = ctx.find_segments("COM");
734 match segs
735 .first()
736 .and_then(|s| s.elements.first())
737 .and_then(|e| e.first())
738 {
739 Some(val) => validate_phone(val),
740 None => ConditionResult::False, }
742 }
743}