1#[allow(unused_imports)]
8use crate::eval::format_validators::*;
9use crate::eval::{ConditionEvaluator, ConditionResult, EvaluationContext};
10
11pub struct PartinConditionEvaluatorFV2504 {
13 external_conditions: std::collections::HashSet<u32>,
15}
16
17impl Default for PartinConditionEvaluatorFV2504 {
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(17);
25 external_conditions.insert(18);
26 external_conditions.insert(19);
27 external_conditions.insert(20);
28 external_conditions.insert(21);
29 external_conditions.insert(22);
30 external_conditions.insert(23);
31 external_conditions.insert(24);
32 external_conditions.insert(25);
33 external_conditions.insert(26);
34 external_conditions.insert(35);
35 external_conditions.insert(36);
36 Self {
37 external_conditions,
38 }
39 }
40}
41
42impl ConditionEvaluator for PartinConditionEvaluatorFV2504 {
43 fn message_type(&self) -> &str {
44 "PARTIN"
45 }
46
47 fn format_version(&self) -> &str {
48 "FV2504"
49 }
50
51 fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
52 match condition {
53 1 => self.evaluate_1(ctx),
54 2 => self.evaluate_2(ctx),
55 3 => self.evaluate_3(ctx),
56 4 => self.evaluate_4(ctx),
57 5 => self.evaluate_5(ctx),
58 6 => self.evaluate_6(ctx),
59 7 => self.evaluate_7(ctx),
60 8 => self.evaluate_8(ctx),
61 10 => self.evaluate_10(ctx),
62 11 => self.evaluate_11(ctx),
63 12 => self.evaluate_12(ctx),
64 13 => self.evaluate_13(ctx),
65 14 => self.evaluate_14(ctx),
66 15 => self.evaluate_15(ctx),
67 16 => self.evaluate_16(ctx),
68 17 => self.evaluate_17(ctx),
69 18 => self.evaluate_18(ctx),
70 19 => self.evaluate_19(ctx),
71 20 => self.evaluate_20(ctx),
72 21 => self.evaluate_21(ctx),
73 22 => self.evaluate_22(ctx),
74 23 => self.evaluate_23(ctx),
75 24 => self.evaluate_24(ctx),
76 25 => self.evaluate_25(ctx),
77 26 => self.evaluate_26(ctx),
78 27 => self.evaluate_27(ctx),
79 28 => self.evaluate_28(ctx),
80 29 => self.evaluate_29(ctx),
81 30 => self.evaluate_30(ctx),
82 31 => self.evaluate_31(ctx),
83 32 => self.evaluate_32(ctx),
84 33 => self.evaluate_33(ctx),
85 34 => self.evaluate_34(ctx),
86 35 => self.evaluate_35(ctx),
87 36 => self.evaluate_36(ctx),
88 490 => self.evaluate_490(ctx),
89 491 => self.evaluate_491(ctx),
90 494 => self.evaluate_494(ctx),
91 500 => self.evaluate_500(ctx),
92 501 => self.evaluate_501(ctx),
93 502 => self.evaluate_502(ctx),
94 503 => self.evaluate_503(ctx),
95 504 => self.evaluate_504(ctx),
96 505 => self.evaluate_505(ctx),
97 506 => self.evaluate_506(ctx),
98 508 => self.evaluate_508(ctx),
99 908 => self.evaluate_908(ctx),
100 931 => self.evaluate_931(ctx),
101 932 => self.evaluate_932(ctx),
102 933 => self.evaluate_933(ctx),
103 939 => self.evaluate_939(ctx),
104 940 => self.evaluate_940(ctx),
105 _ => ConditionResult::Unknown,
106 }
107 }
108
109 fn is_external(&self, condition: u32) -> bool {
110 self.external_conditions.contains(&condition)
111 }
112 fn is_known(&self, condition: u32) -> bool {
113 matches!(
114 condition,
115 1 | 2
116 | 3
117 | 4
118 | 5
119 | 6
120 | 7
121 | 8
122 | 10
123 | 11
124 | 12
125 | 13
126 | 14
127 | 15
128 | 16
129 | 17
130 | 18
131 | 19
132 | 20
133 | 21
134 | 22
135 | 23
136 | 24
137 | 25
138 | 26
139 | 27
140 | 28
141 | 29
142 | 30
143 | 31
144 | 32
145 | 33
146 | 34
147 | 35
148 | 36
149 | 490
150 | 491
151 | 494
152 | 500
153 | 501
154 | 502
155 | 503
156 | 504
157 | 505
158 | 506
159 | 508
160 | 908
161 | 931
162 | 932
163 | 933
164 | 939
165 | 940
166 )
167 }
168}
169
170impl PartinConditionEvaluatorFV2504 {
171 fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
174 ctx.external.evaluate("mp_id_is_strom")
175 }
176
177 fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
180 ctx.external.evaluate("country_code_has_plz")
181 }
182
183 fn evaluate_3(&self, _ctx: &EvaluationContext) -> ConditionResult {
185 ConditionResult::True
187 }
188
189 fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
192 ctx.external.evaluate("vorgaengerversion_vorhanden")
193 }
194
195 fn evaluate_490(&self, ctx: &EvaluationContext) -> ConditionResult {
197 let dtm_segs = ctx.find_segments("DTM");
199 match dtm_segs
200 .first()
201 .and_then(|s| s.elements.first())
202 .and_then(|e| e.get(1))
203 {
204 Some(val) => is_mesz_utc(val),
205 None => ConditionResult::False, }
207 }
208
209 fn evaluate_491(&self, ctx: &EvaluationContext) -> ConditionResult {
211 let dtm_segs = ctx.find_segments("DTM");
212 match dtm_segs
213 .first()
214 .and_then(|s| s.elements.first())
215 .and_then(|e| e.get(1))
216 {
217 Some(val) => is_mez_utc(val),
218 None => ConditionResult::False, }
220 }
221
222 fn evaluate_494(&self, _ctx: &EvaluationContext) -> ConditionResult {
225 ConditionResult::True
229 }
230
231 fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
234 ctx.external.evaluate("recipient_is_lf")
235 }
236
237 fn evaluate_6(&self, ctx: &EvaluationContext) -> ConditionResult {
239 let coms = ctx.find_segments("COM");
240 if coms.is_empty() {
241 return ConditionResult::Unknown;
242 }
243 ConditionResult::from(coms.iter().any(|s| {
244 s.elements
245 .first()
246 .and_then(|e| e.get(1))
247 .is_some_and(|v| v == "EM")
248 }))
249 }
250
251 fn evaluate_7(&self, ctx: &EvaluationContext) -> ConditionResult {
253 let coms = ctx.find_segments("COM");
254 if coms.is_empty() {
255 return ConditionResult::Unknown;
256 }
257 ConditionResult::from(coms.iter().any(|s| {
258 s.elements
259 .first()
260 .and_then(|e| e.get(1))
261 .is_some_and(|v| matches!(v.as_str(), "TE" | "FX" | "AJ" | "AL"))
262 }))
263 }
264
265 fn evaluate_8(&self, ctx: &EvaluationContext) -> ConditionResult {
267 let coms = ctx.find_segments("COM");
268 if coms.is_empty() {
269 return ConditionResult::Unknown;
270 }
271 ConditionResult::from(coms.iter().any(|s| {
272 s.elements
273 .first()
274 .and_then(|e| e.get(1))
275 .is_some_and(|v| matches!(v.as_str(), "TE" | "FX"))
276 }))
277 }
278
279 fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
281 match ctx.find_segment("BGM") {
282 None => ConditionResult::False, Some(bgm) => ConditionResult::from(
284 bgm.elements
285 .get(4)
286 .and_then(|e| e.first())
287 .map(|v| v != "11")
288 .unwrap_or(true),
289 ),
290 }
291 }
292
293 fn evaluate_11(&self, ctx: &EvaluationContext) -> ConditionResult {
295 let nads = ctx.find_segments_with_qualifier("NAD", 0, "SU");
296 match nads.first() {
297 None => ConditionResult::False, Some(nad) => ConditionResult::from(
299 nad.elements
300 .get(8)
301 .and_then(|e| e.first())
302 .is_some_and(|v| v == "DE"),
303 ),
304 }
305 }
306
307 fn evaluate_12(&self, ctx: &EvaluationContext) -> ConditionResult {
309 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DDM");
310 match nads.first() {
311 None => ConditionResult::False, Some(nad) => ConditionResult::from(
313 nad.elements
314 .get(8)
315 .and_then(|e| e.first())
316 .is_some_and(|v| v == "DE"),
317 ),
318 }
319 }
320
321 fn evaluate_13(&self, ctx: &EvaluationContext) -> ConditionResult {
323 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DEB");
324 match nads.first() {
325 None => ConditionResult::False, Some(nad) => ConditionResult::from(
327 nad.elements
328 .get(8)
329 .and_then(|e| e.first())
330 .is_some_and(|v| v == "DE"),
331 ),
332 }
333 }
334
335 fn evaluate_14(&self, ctx: &EvaluationContext) -> ConditionResult {
337 let nads = ctx.find_segments_with_qualifier("NAD", 0, "SU");
338 match nads.first() {
339 None => ConditionResult::False, Some(nad) => ConditionResult::from(
341 nad.elements
342 .get(8)
343 .and_then(|e| e.first())
344 .map(|v| v != "DE")
345 .unwrap_or(true),
346 ),
347 }
348 }
349
350 fn evaluate_15(&self, ctx: &EvaluationContext) -> ConditionResult {
352 let nads = ctx.find_segments_with_qualifier("NAD", 0, "DDM");
353 match nads.first() {
354 None => ConditionResult::False, Some(nad) => ConditionResult::from(
356 nad.elements
357 .get(8)
358 .and_then(|e| e.first())
359 .map(|v| v != "DE")
360 .unwrap_or(true),
361 ),
362 }
363 }
364
365 fn evaluate_16(&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 .map(|v| v != "DE")
375 .unwrap_or(true),
376 ),
377 }
378 }
379
380 fn evaluate_17(&self, ctx: &EvaluationContext) -> ConditionResult {
383 ctx.external.evaluate("recipient_is_lf_nb_msb")
384 }
385
386 fn evaluate_18(&self, ctx: &EvaluationContext) -> ConditionResult {
389 ctx.external.evaluate("recipient_is_lf_msb")
390 }
391
392 fn evaluate_19(&self, ctx: &EvaluationContext) -> ConditionResult {
395 ctx.external.evaluate("recipient_is_lf_msb_nb_uenb")
396 }
397
398 fn evaluate_20(&self, ctx: &EvaluationContext) -> ConditionResult {
401 ctx.external.evaluate("recipient_is_lf_msb_uenb")
402 }
403
404 fn evaluate_21(&self, ctx: &EvaluationContext) -> ConditionResult {
407 ctx.external.evaluate("recipient_is_lf_nb_esa")
408 }
409
410 fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
413 ctx.external.evaluate("recipient_is_msb")
414 }
415
416 fn evaluate_23(&self, ctx: &EvaluationContext) -> ConditionResult {
419 ctx.external.evaluate("recipient_is_nb_uenb")
420 }
421
422 fn evaluate_24(&self, ctx: &EvaluationContext) -> ConditionResult {
425 ctx.external.evaluate("recipient_is_nb_lf_msb_esa")
426 }
427
428 fn evaluate_25(&self, ctx: &EvaluationContext) -> ConditionResult {
431 ctx.external.evaluate("recipient_is_nb")
432 }
433
434 fn evaluate_26(&self, ctx: &EvaluationContext) -> ConditionResult {
437 ctx.external.evaluate("recipient_is_nb_lf_bkv_biko")
438 }
439
440 fn evaluate_27(&self, ctx: &EvaluationContext) -> ConditionResult {
442 ctx.has_qualified_value("NAD", 0, "Z31", 8, 0, &["DE"])
443 }
444
445 fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
447 ctx.has_qualified_value("NAD", 0, "Z34", 8, 0, &["DE"])
448 }
449
450 fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
452 ctx.has_qualified_value("NAD", 0, "Z35", 8, 0, &["DE"])
453 }
454
455 fn evaluate_30(&self, ctx: &EvaluationContext) -> ConditionResult {
457 ctx.has_qualified_value("NAD", 0, "Z36", 8, 0, &["DE"])
458 }
459
460 fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
462 match ctx.has_qualified_value("NAD", 0, "Z31", 8, 0, &["DE"]) {
463 ConditionResult::True => ConditionResult::False,
464 ConditionResult::False => ConditionResult::True,
465 ConditionResult::Unknown => ConditionResult::Unknown,
466 }
467 }
468
469 fn evaluate_32(&self, ctx: &EvaluationContext) -> ConditionResult {
471 let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z34");
472 if nads.is_empty() {
473 return ConditionResult::True;
474 }
475 let has_de = nads.iter().any(|s| {
476 s.elements
477 .get(8)
478 .and_then(|e| e.first())
479 .is_some_and(|v| v == "DE")
480 });
481 ConditionResult::from(!has_de)
482 }
483
484 fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
486 let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z35");
487 if nads.is_empty() {
488 return ConditionResult::True;
489 }
490 let has_de = nads.iter().any(|s| {
491 s.elements
492 .get(8)
493 .and_then(|e| e.first())
494 .is_some_and(|v| v == "DE")
495 });
496 ConditionResult::from(!has_de)
497 }
498
499 fn evaluate_34(&self, ctx: &EvaluationContext) -> ConditionResult {
501 let nads = ctx.find_segments_with_qualifier("NAD", 0, "Z36");
502 if nads.is_empty() {
503 return ConditionResult::True;
504 }
505 let has_de = nads.iter().any(|s| {
506 s.elements
507 .get(8)
508 .and_then(|e| e.first())
509 .is_some_and(|v| v == "DE")
510 });
511 ConditionResult::from(!has_de)
512 }
513
514 fn evaluate_35(&self, ctx: &EvaluationContext) -> ConditionResult {
517 ctx.external.evaluate("recipient_is_uenb")
518 }
519
520 fn evaluate_36(&self, ctx: &EvaluationContext) -> ConditionResult {
523 ctx.external.evaluate("recipient_is_bkv")
524 }
525
526 fn evaluate_500(&self, _ctx: &EvaluationContext) -> ConditionResult {
528 ConditionResult::True
531 }
532
533 fn evaluate_501(&self, _ctx: &EvaluationContext) -> ConditionResult {
535 ConditionResult::True
538 }
539
540 fn evaluate_502(&self, _ctx: &EvaluationContext) -> ConditionResult {
542 ConditionResult::True
545 }
546
547 fn evaluate_503(&self, _ctx: &EvaluationContext) -> ConditionResult {
549 ConditionResult::True
551 }
552
553 fn evaluate_504(&self, _ctx: &EvaluationContext) -> ConditionResult {
555 ConditionResult::True
557 }
558
559 fn evaluate_505(&self, ctx: &EvaluationContext) -> ConditionResult {
562 let acw_segments = ctx.find_segments_with_qualifier("RFF", 0, "ACW");
563 if acw_segments.is_empty() {
564 return ConditionResult::False;
565 }
566 let agk_segments = ctx.find_segments_with_qualifier("RFF", 0, "AGK");
567 let current_version = agk_segments
568 .first()
569 .and_then(|s| s.elements.first())
570 .and_then(|e| e.get(3))
571 .and_then(|v| v.parse::<i64>().ok());
572 let predecessor_version = acw_segments
573 .first()
574 .and_then(|s| s.elements.first())
575 .and_then(|e| e.get(3))
576 .and_then(|v| v.parse::<i64>().ok());
577 match (current_version, predecessor_version) {
578 (Some(cur), Some(pred)) => ConditionResult::from(cur >= pred + 1),
579 _ => ConditionResult::Unknown,
580 }
581 }
582
583 fn evaluate_506(&self, _ctx: &EvaluationContext) -> ConditionResult {
585 ConditionResult::True
587 }
588
589 fn evaluate_508(&self, _ctx: &EvaluationContext) -> ConditionResult {
591 ConditionResult::True
593 }
594
595 fn evaluate_908(&self, _ctx: &EvaluationContext) -> ConditionResult {
597 ConditionResult::True
599 }
600
601 fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
603 let dtm_segs = ctx.find_segments("DTM");
605 match dtm_segs
606 .first()
607 .and_then(|s| s.elements.first())
608 .and_then(|e| e.get(1))
609 {
610 Some(val) => validate_timezone_utc(val),
611 None => ConditionResult::False, }
613 }
614
615 fn evaluate_932(&self, ctx: &EvaluationContext) -> ConditionResult {
617 let dtm_segs = ctx.find_segments("DTM");
619 match dtm_segs
620 .first()
621 .and_then(|s| s.elements.first())
622 .and_then(|e| e.get(1))
623 {
624 Some(val) => validate_hhmm_equals(val, "2200"),
625 None => ConditionResult::False, }
627 }
628
629 fn evaluate_933(&self, ctx: &EvaluationContext) -> ConditionResult {
631 let dtm_segs = ctx.find_segments("DTM");
633 match dtm_segs
634 .first()
635 .and_then(|s| s.elements.first())
636 .and_then(|e| e.get(1))
637 {
638 Some(val) => validate_hhmm_equals(val, "2300"),
639 None => ConditionResult::False, }
641 }
642
643 fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
645 let segs = ctx.find_segments("COM");
647 match segs
648 .first()
649 .and_then(|s| s.elements.first())
650 .and_then(|e| e.first())
651 {
652 Some(val) => validate_email(val),
653 None => ConditionResult::False, }
655 }
656
657 fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
659 let segs = ctx.find_segments("COM");
661 match segs
662 .first()
663 .and_then(|s| s.elements.first())
664 .and_then(|e| e.first())
665 {
666 Some(val) => validate_phone(val),
667 None => ConditionResult::False, }
669 }
670}