Skip to main content

automapper_validation/generated/fv2604/
comdis_conditions_fv2604.rs

1// <auto-generated>
2// Generated by automapper-generator generate-conditions
3// AHB: xml-migs-and-ahbs/FV2604/COMDIS_AHB_1_0h_20251001.xml
4// Generated: 2026-03-12T11:30:28Z
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::{ConditionEvaluator, ConditionResult, EvaluationContext};
15use mig_types::segment::OwnedSegment;
16
17/// Generated condition evaluator for COMDIS FV2604.
18pub struct ComdisConditionEvaluatorFV2604 {
19    // External condition IDs that require runtime context.
20    external_conditions: std::collections::HashSet<u32>,
21}
22
23impl Default for ComdisConditionEvaluatorFV2604 {
24    fn default() -> Self {
25        let mut external_conditions = std::collections::HashSet::new();
26        external_conditions.insert(3);
27        external_conditions.insert(23);
28        external_conditions.insert(24);
29        external_conditions.insert(25);
30        external_conditions.insert(26);
31        external_conditions.insert(27);
32        external_conditions.insert(28);
33        external_conditions.insert(29);
34        external_conditions.insert(30);
35        external_conditions.insert(492);
36        external_conditions.insert(493);
37        Self {
38            external_conditions,
39        }
40    }
41}
42
43impl ConditionEvaluator for ComdisConditionEvaluatorFV2604 {
44    fn message_type(&self) -> &str {
45        "COMDIS"
46    }
47
48    fn format_version(&self) -> &str {
49        "FV2604"
50    }
51
52    fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
53        match condition {
54            1 => self.evaluate_1(ctx),
55            2 => self.evaluate_2(ctx),
56            3 => self.evaluate_3(ctx),
57            4 => self.evaluate_4(ctx),
58            5 => self.evaluate_5(ctx),
59            6 => self.evaluate_6(ctx),
60            7 => self.evaluate_7(ctx),
61            8 => self.evaluate_8(ctx),
62            9 => self.evaluate_9(ctx),
63            10 => self.evaluate_10(ctx),
64            11 => self.evaluate_11(ctx),
65            12 => self.evaluate_12(ctx),
66            13 => self.evaluate_13(ctx),
67            14 => self.evaluate_14(ctx),
68            15 => self.evaluate_15(ctx),
69            16 => self.evaluate_16(ctx),
70            17 => self.evaluate_17(ctx),
71            18 => self.evaluate_18(ctx),
72            19 => self.evaluate_19(ctx),
73            20 => self.evaluate_20(ctx),
74            21 => self.evaluate_21(ctx),
75            22 => self.evaluate_22(ctx),
76            23 => self.evaluate_23(ctx),
77            24 => self.evaluate_24(ctx),
78            25 => self.evaluate_25(ctx),
79            26 => self.evaluate_26(ctx),
80            27 => self.evaluate_27(ctx),
81            28 => self.evaluate_28(ctx),
82            29 => self.evaluate_29(ctx),
83            30 => self.evaluate_30(ctx),
84            31 => self.evaluate_31(ctx),
85            32 => self.evaluate_32(ctx),
86            33 => self.evaluate_33(ctx),
87            34 => self.evaluate_34(ctx),
88            492 => self.evaluate_492(ctx),
89            493 => self.evaluate_493(ctx),
90            505 => self.evaluate_505(ctx),
91            506 => self.evaluate_506(ctx),
92            508 => self.evaluate_508(ctx),
93            509 => self.evaluate_509(ctx),
94            510 => self.evaluate_510(ctx),
95            930 => self.evaluate_930(ctx),
96            931 => self.evaluate_931(ctx),
97            939 => self.evaluate_939(ctx),
98            940 => self.evaluate_940(ctx),
99            _ => ConditionResult::Unknown,
100        }
101    }
102
103    fn is_external(&self, condition: u32) -> bool {
104        self.external_conditions.contains(&condition)
105    }
106    fn is_known(&self, condition: u32) -> bool {
107        matches!(
108            condition,
109            1 | 2
110                | 3
111                | 4
112                | 5
113                | 6
114                | 7
115                | 8
116                | 9
117                | 10
118                | 11
119                | 12
120                | 13
121                | 14
122                | 15
123                | 16
124                | 17
125                | 18
126                | 19
127                | 20
128                | 21
129                | 22
130                | 23
131                | 24
132                | 25
133                | 26
134                | 27
135                | 28
136                | 29
137                | 30
138                | 31
139                | 32
140                | 33
141                | 34
142                | 492
143                | 493
144                | 505
145                | 506
146                | 508
147                | 509
148                | 510
149                | 930
150                | 931
151                | 939
152                | 940
153        )
154    }
155}
156
157impl ComdisConditionEvaluatorFV2604 {
158    /// [1] wenn SG3 AJT+Z61+S_0109 oder SG3 AJT+Z62+S_0109 vorhanden
159    fn evaluate_1(&self, ctx: &EvaluationContext) -> ConditionResult {
160        sg3_ajt(ctx, &["Z61", "Z62"], &["S_0109"])
161    }
162
163    /// [2] wenn SG3 AJT+Z58+S_0109 oder SG3 AJT+Z59+S_0109 oder SG3 AJT+Z60+S_0109 vorhanden
164    fn evaluate_2(&self, ctx: &EvaluationContext) -> ConditionResult {
165        sg3_ajt(ctx, &["Z58", "Z59", "Z60"], &["S_0109"])
166    }
167
168    /// [31] wenn SG3 AJT+Z61+G_0089 oder SG3 AJT+Z62+G_0089 vorhanden
169    fn evaluate_31(&self, ctx: &EvaluationContext) -> ConditionResult {
170        sg3_ajt(ctx, &["Z61", "Z62"], &["G_0089"])
171    }
172
173    /// [32] wenn SG3 AJT+Z58+G_0089 oder SG3 AJT+Z59+G_0089 oder SG3 AJT+Z60+G_0089 vorhanden
174    fn evaluate_32(&self, ctx: &EvaluationContext) -> ConditionResult {
175        sg3_ajt(ctx, &["Z58", "Z59", "Z60"], &["G_0089"])
176    }
177
178    /// [33] wenn SG3 AJT+Z58/Z59/Z60/Z61/Z62+G_0089 vorhanden
179    fn evaluate_33(&self, ctx: &EvaluationContext) -> ConditionResult {
180        sg3_ajt(ctx, &["Z58", "Z59", "Z60", "Z61", "Z62"], &["G_0089"])
181    }
182
183    /// [34] wenn SG3 AJT+A99+G_0089 vorhanden
184    fn evaluate_34(&self, ctx: &EvaluationContext) -> ConditionResult {
185        sg3_ajt(ctx, &["A99"], &["G_0089"])
186    }
187
188    /// [3] Nur MP-ID aus Sparte Strom
189    /// EXTERNAL: Requires context from outside the message.
190    fn evaluate_3(&self, ctx: &EvaluationContext) -> ConditionResult {
191        ctx.external.evaluate("mp_id_from_electricity_sector")
192    }
193
194    /// [4] wenn SG3 AJT+Z58/Z59/Z60/Z61/Z62+S_0109 vorhanden
195    fn evaluate_4(&self, ctx: &EvaluationContext) -> ConditionResult {
196        sg3_ajt(ctx, &["Z58", "Z59", "Z60", "Z61", "Z62"], &["S_0109"])
197    }
198
199    /// [5] wenn SG3 AJT+A01/A02/A03/A04/A06/A07/A09/A12/A15+E_0504 vorhanden
200    fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
201        sg3_ajt(
202            ctx,
203            &[
204                "A01", "A02", "A03", "A04", "A06", "A07", "A09", "A12", "A15",
205            ],
206            &["E_0504"],
207        )
208    }
209
210    /// [6] wenn SG3 AJT+A07+E_0504 vorhanden
211    fn evaluate_6(&self, ctx: &EvaluationContext) -> ConditionResult {
212        sg3_ajt(ctx, &["A07"], &["E_0504"])
213    }
214
215    /// [7] wenn SG3 AJT+A02+E_0504 vorhanden
216    fn evaluate_7(&self, ctx: &EvaluationContext) -> ConditionResult {
217        sg3_ajt(ctx, &["A02"], &["E_0504"])
218    }
219
220    /// [8] wenn SG3 AJT+A01/A04/A06/A09/A12+E_0504 vorhanden
221    fn evaluate_8(&self, ctx: &EvaluationContext) -> ConditionResult {
222        sg3_ajt(ctx, &["A01", "A04", "A06", "A09", "A12"], &["E_0504"])
223    }
224
225    /// [9] wenn SG3 AJT+A05/A10/A11/A14+E_0504 vorhanden
226    fn evaluate_9(&self, ctx: &EvaluationContext) -> ConditionResult {
227        sg3_ajt(ctx, &["A05", "A10", "A11", "A14"], &["E_0504"])
228    }
229
230    /// [10] wenn SG3 AJT+A03+E_0504 vorhanden
231    fn evaluate_10(&self, ctx: &EvaluationContext) -> ConditionResult {
232        sg3_ajt(ctx, &["A03"], &["E_0504"])
233    }
234
235    /// [11] wenn SG3 AJT+A15+E_0504 vorhanden
236    fn evaluate_11(&self, ctx: &EvaluationContext) -> ConditionResult {
237        sg3_ajt(ctx, &["A15"], &["E_0504"])
238    }
239
240    /// [12] wenn SG3 AJT+A99+S_0109 vorhanden
241    fn evaluate_12(&self, ctx: &EvaluationContext) -> ConditionResult {
242        sg3_ajt(ctx, &["A99"], &["S_0109"])
243    }
244
245    /// [13] wenn SG3 AJT+A07+E_1008 vorhanden
246    fn evaluate_13(&self, ctx: &EvaluationContext) -> ConditionResult {
247        sg3_ajt(ctx, &["A07"], &["E_1008"])
248    }
249
250    /// [14] wenn SG3 AJT+A02+E_1008 vorhanden
251    fn evaluate_14(&self, ctx: &EvaluationContext) -> ConditionResult {
252        sg3_ajt(ctx, &["A02"], &["E_1008"])
253    }
254
255    /// [15] wenn SG3 AJT+A01/A04/A06/A09+E_1008 vorhanden
256    fn evaluate_15(&self, ctx: &EvaluationContext) -> ConditionResult {
257        sg3_ajt(ctx, &["A01", "A04", "A06", "A09"], &["E_1008"])
258    }
259
260    /// [16] wenn SG3 AJT+A03+E_1008 vorhanden
261    fn evaluate_16(&self, ctx: &EvaluationContext) -> ConditionResult {
262        sg3_ajt(ctx, &["A03"], &["E_1008"])
263    }
264
265    /// [17] wenn SG3 AJT+A15+E_1008 vorhanden
266    fn evaluate_17(&self, ctx: &EvaluationContext) -> ConditionResult {
267        sg3_ajt(ctx, &["A15"], &["E_1008"])
268    }
269
270    /// [18] wenn SG3 AJT+A05/A10/A11+E_1008 vorhanden
271    fn evaluate_18(&self, ctx: &EvaluationContext) -> ConditionResult {
272        sg3_ajt(ctx, &["A05", "A10", "A11"], &["E_1008"])
273    }
274
275    /// [19] wenn SG3 AJT+A99+E_0265/E_0271/E_0274/E_0516/E_0520/E_0567 vorhanden
276    fn evaluate_19(&self, ctx: &EvaluationContext) -> ConditionResult {
277        sg3_ajt(
278            ctx,
279            &["A99"],
280            &["E_0265", "E_0271", "E_0274", "E_0516", "E_0520", "E_0567"],
281        )
282    }
283
284    /// [20] wenn SG3 AJT+A01/A02/A03/A04/A06/A07/A09/A15+E_1008 vorhanden
285    fn evaluate_20(&self, ctx: &EvaluationContext) -> ConditionResult {
286        sg3_ajt(
287            ctx,
288            &["A01", "A02", "A03", "A04", "A06", "A07", "A09", "A15"],
289            &["E_1008"],
290        )
291    }
292
293    /// [21] wenn im DE3155 in demselben COM der Code EM vorhanden ist
294    fn evaluate_21(&self, ctx: &EvaluationContext) -> ConditionResult {
295        let com_segments = ctx.find_segments("COM");
296        ConditionResult::from(com_segments.iter().any(|seg| {
297            seg.elements
298                .first()
299                .and_then(|e| e.get(1))
300                .map(|s| s.as_str())
301                == Some("EM")
302        }))
303    }
304
305    /// [22] wenn im DE3155 in demselben COM der Code TE / FX / AJ / AL vorhanden ist
306    fn evaluate_22(&self, ctx: &EvaluationContext) -> ConditionResult {
307        let com_segments = ctx.find_segments("COM");
308        ConditionResult::from(com_segments.iter().any(|seg| {
309            matches!(
310                seg.elements
311                    .first()
312                    .and_then(|e| e.get(1))
313                    .map(|s| s.as_str()),
314                Some("TE") | Some("FX") | Some("AJ") | Some("AL")
315            )
316        }))
317    }
318
319    /// [23] Wenn MP-ID in NAD+MS (Nachrichtensender) mit Rolle MSB vorhanden
320    /// EXTERNAL: Requires context from outside the message.
321    fn evaluate_23(&self, ctx: &EvaluationContext) -> ConditionResult {
322        ctx.external.evaluate("sender_is_msb")
323    }
324
325    /// [24] Wenn MP-ID in NAD+MR (Nachrichtenempfänger) mit Rolle ESA vorhanden
326    /// EXTERNAL: Requires context from outside the message.
327    fn evaluate_24(&self, ctx: &EvaluationContext) -> ConditionResult {
328        ctx.external.evaluate("recipient_is_esa")
329    }
330
331    /// [25] Wenn MP-ID in NAD+MR (Nachrichtenempfänger) mit Rolle LF vorhanden
332    /// EXTERNAL: Requires context from outside the message.
333    fn evaluate_25(&self, ctx: &EvaluationContext) -> ConditionResult {
334        ctx.external.evaluate("recipient_is_lf")
335    }
336
337    /// [26] Wenn MP-ID in NAD+MR (Nachrichtenempfänger) mit Rolle NB vorhanden
338    /// EXTERNAL: Requires context from outside the message.
339    fn evaluate_26(&self, ctx: &EvaluationContext) -> ConditionResult {
340        ctx.external.evaluate("recipient_is_nb")
341    }
342
343    /// [27] Wenn MP-ID in NAD+MS (Nachrichtensender) mit Rolle NB vorhanden
344    /// EXTERNAL: Requires context from outside the message.
345    fn evaluate_27(&self, ctx: &EvaluationContext) -> ConditionResult {
346        ctx.external.evaluate("sender_is_nb")
347    }
348
349    /// [28] Angabe der Datenaustauschreferenz aus der CONTRL
350    /// EXTERNAL: Requires context from outside the message.
351    // REVIEW: Condition states the field contains the data exchange reference from a prior CONTRL message. Whether the COMDIS is responding to a CONTRL cannot be determined from the EDIFACT message content alone — it depends on external business context about which prior message triggered this dispute. (medium confidence)
352    fn evaluate_28(&self, ctx: &EvaluationContext) -> ConditionResult {
353        ctx.external.evaluate("responding_to_contrl")
354    }
355
356    /// [29] Angabe der Datenaustauschreferenz aus der APERAK
357    /// EXTERNAL: Requires context from outside the message.
358    // REVIEW: Condition states the field contains the data exchange reference from a prior APERAK message. Whether the COMDIS is responding to an APERAK cannot be determined from the EDIFACT message content alone — it depends on external business context about which prior message triggered this dispute. (medium confidence)
359    fn evaluate_29(&self, ctx: &EvaluationContext) -> ConditionResult {
360        ctx.external.evaluate("responding_to_aperak")
361    }
362
363    /// [30] Angabe der Nachrichtennummer aus der APERAK
364    /// EXTERNAL: Requires context from outside the message.
365    // REVIEW: Condition states the field contains the message number from a prior APERAK. Like condition 29, whether the COMDIS is responding to an APERAK is external business context, not determinable from message content. Shares the same external predicate as condition 29. (medium confidence)
366    fn evaluate_30(&self, ctx: &EvaluationContext) -> ConditionResult {
367        ctx.external.evaluate("responding_to_aperak")
368    }
369
370    /// [492] Wenn MP-ID in NAD+MR (Nachrichtenempfänger) aus Sparte Strom
371    /// EXTERNAL: Requires context from outside the message.
372    // REVIEW: Whether NAD+MR MP-ID belongs to Sparte Strom cannot be determined from the EDIFACT message content alone — it requires external business context (market participant registry or configuration). (medium confidence)
373    fn evaluate_492(&self, ctx: &EvaluationContext) -> ConditionResult {
374        ctx.external.evaluate("recipient_is_electricity_sector")
375    }
376
377    /// [493] Wenn MP-ID in NAD+MR (Nachrichtenempfänger) aus Sparte Gas
378    /// EXTERNAL: Requires context from outside the message.
379    // REVIEW: Whether NAD+MR MP-ID belongs to Sparte Gas cannot be determined from the EDIFACT message content alone — it requires external business context (market participant registry or configuration). (medium confidence)
380    fn evaluate_493(&self, ctx: &EvaluationContext) -> ConditionResult {
381        ctx.external.evaluate("recipient_is_gas_sector")
382    }
383
384    /// [505] Hinweis: BGM DE1004 aus der vorher per REMADV abgelehnten INVOIC-Nachricht
385    fn evaluate_505(&self, _ctx: &EvaluationContext) -> ConditionResult {
386        ConditionResult::True
387    }
388
389    /// [506] Hinweis: BGM DE1004 aus der vorher per IFTSTA abgelehnten MSCONS-Nachricht
390    fn evaluate_506(&self, _ctx: &EvaluationContext) -> ConditionResult {
391        ConditionResult::True
392    }
393
394    /// [508] Hinweis: Es darf nur eine Information im DE3148 übermittelt werden
395    fn evaluate_508(&self, _ctx: &EvaluationContext) -> ConditionResult {
396        // Hinweis: Es darf nur eine Information im DE3148 übermittelt werden — informational note, always applies
397        ConditionResult::True
398    }
399
400    /// [509] Hinweis: Wenn Eingang der zugrundeliegenden Nachricht vor dem 06.06.2025, 00:00 Uhr bestätigt wurde
401    fn evaluate_509(&self, _ctx: &EvaluationContext) -> ConditionResult {
402        // Hinweis: Wenn Eingang der zugrundeliegenden Nachricht vor dem 06.06.2025, 00:00 Uhr bestätigt wurde — informational note, always applies
403        ConditionResult::True
404    }
405
406    /// [510] Hinweis: Wenn Eingang der zugrundeliegenden Nachricht nach dem 06.06.2025, 00:00 Uhr bestätigt wurde
407    fn evaluate_510(&self, _ctx: &EvaluationContext) -> ConditionResult {
408        // Hinweis: Wenn Eingang der zugrundeliegenden Nachricht nach dem 06.06.2025, 00:00 Uhr bestätigt wurde — informational note, always applies
409        ConditionResult::True
410    }
411
412    /// [930] Format: max. 2 Nachkommastellen
413    // REVIEW: Format condition for max 2 decimal places. COMDIS carries monetary amounts (MOA) as the primary numeric value segment. Using MOA elements[0][1] for the amount value. (medium confidence)
414    fn evaluate_930(&self, ctx: &EvaluationContext) -> ConditionResult {
415        ctx.format_check("MOA", 0, 1, |val| validate_max_decimal_places(val, 2))
416    }
417
418    /// [931] Format: ZZZ = +00
419    fn evaluate_931(&self, ctx: &EvaluationContext) -> ConditionResult {
420        ctx.format_check("DTM", 0, 1, validate_timezone_utc)
421    }
422
423    /// [939] Format: Die Zeichenkette muss die Zeichen @ und . enthalten
424    fn evaluate_939(&self, ctx: &EvaluationContext) -> ConditionResult {
425        ctx.format_check("COM", 0, 0, validate_email)
426    }
427
428    /// [940] Format: Die Zeichenkette muss mit dem Zeichen + beginnen und danach dürfen nur noch Ziffern folgen
429    fn evaluate_940(&self, ctx: &EvaluationContext) -> ConditionResult {
430        ctx.format_check("COM", 0, 0, validate_phone)
431    }
432}
433
434/// HAND-EDITED (#334): "wenn SG3 AJT+<answer>+<list> vorhanden" reads the AJT of
435/// the SG3 the evaluated field sits in, message-wide only when the scope does
436/// not reach an SG3. SG3 repeats once per reason, and FTX+ACD/ACB combine these
437/// conditions with `⊻`, which holds only per SG3. Absence is `False`, not
438/// `Unknown`: the SG3 is fully known.
439fn sg3_ajt(ctx: &EvaluationContext, answers: &[&str], lists: &[&str]) -> ConditionResult {
440    fn component(seg: &OwnedSegment, elem: usize) -> Option<&str> {
441        seg.elements
442            .get(elem)
443            .and_then(|e| e.first())
444            .map(String::as_str)
445    }
446    ConditionResult::from(ctx.scoped_find_segments_in("SG3", "AJT").iter().any(|seg| {
447        component(seg, 0).is_some_and(|a| answers.contains(&a))
448            && component(seg, 1).is_some_and(|l| lists.contains(&l))
449    }))
450}