1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// <auto-generated>
// Generated by automapper-generator generate-conditions
// AHB: xml-migs-and-ahbs/FV2610/INVOIC_AHB_1_0b_20260401.xml
// Generated: 2026-04-22T18:10:21Z
// Delegates unchanged conditions to InvoicConditionEvaluatorFV2510 (FV2510).
// </auto-generated>
#![allow(clippy::style, clippy::complexity)]
#[allow(unused_imports)]
use crate::eval::format_validators::*;
use crate::eval::{ConditionEvaluator, ConditionResult, EvaluationContext};
use crate::generated::fv2510::InvoicConditionEvaluatorFV2510;
/// Condition evaluator for INVOIC FV2610.
///
/// Delegates to [`InvoicConditionEvaluatorFV2510`] for conditions whose AHB description is
/// unchanged from that version. Local overrides: [5, 6, 56, 90, 527, 903, 2000].
pub struct InvoicConditionEvaluatorFV2610 {
fallback: InvoicConditionEvaluatorFV2510,
}
impl Default for InvoicConditionEvaluatorFV2610 {
fn default() -> Self {
Self {
fallback: InvoicConditionEvaluatorFV2510::default(),
}
}
}
/// Condition IDs whose implementation differs from the fallback.
const FV2610_OVERRIDES: &[u32] = &[5, 6, 56, 90, 527, 903, 2000];
impl ConditionEvaluator for InvoicConditionEvaluatorFV2610 {
fn message_type(&self) -> &str {
"INVOIC"
}
fn format_version(&self) -> &str {
"FV2610"
}
fn evaluate(&self, condition: u32, ctx: &EvaluationContext) -> ConditionResult {
match condition {
5 => self.evaluate_5(ctx),
6 => self.evaluate_6(ctx),
56 => self.evaluate_56(ctx),
90 => self.evaluate_90(ctx),
527 => self.evaluate_527(ctx),
903 => self.evaluate_903(ctx),
2000 => self.evaluate_2000(ctx),
other => self.fallback.evaluate(other, ctx),
}
}
fn is_external(&self, condition: u32) -> bool {
self.fallback.is_external(condition)
}
fn is_known(&self, condition: u32) -> bool {
FV2610_OVERRIDES.contains(&condition) || self.fallback.is_known(condition)
}
}
impl InvoicConditionEvaluatorFV2610 {
/// [5] Wenn NAD+MR DE3207 <> "DE"
fn evaluate_5(&self, ctx: &EvaluationContext) -> ConditionResult {
match ctx.has_qualified_value("NAD", 0, "MR", 8, 0, &["DE"]) {
ConditionResult::True => ConditionResult::False,
ConditionResult::False => ConditionResult::True,
ConditionResult::Unknown => ConditionResult::Unknown,
}
}
/// [6] Wenn NAD+MR DE3207 = "DE"
fn evaluate_6(&self, ctx: &EvaluationContext) -> ConditionResult {
ctx.has_qualified_value("NAD", 0, "MR", 8, 0, &["DE"])
}
/// [56] Wenn DTM+137 (Nachrichtendatum) ≥ 1.1.2023 0:00 gesetzlicher deutscher Zeit
fn evaluate_56(&self, ctx: &EvaluationContext) -> ConditionResult {
ctx.dtm_ge("137", "202301010000")
}
/// [90] Der Wert muss < 01.01.2027 00:00 Uhr gesetzlicher deutscher Zeit sein
// REVIEW: Der Wert targets the current field value. Uses format_check to prefer ctx.resolved_value (tree-based path) with string comparison on the first 12 characters (CCYYMMDDHHMM) to handle potential timezone suffixes. January 1 is in CET (UTC+1) so local 00:00 is the threshold. Confidence medium because the fallback segment tag 'DTM' and element position 0/1 are assumed from INVOIC context. (medium confidence)
fn evaluate_90(&self, ctx: &EvaluationContext) -> ConditionResult {
ctx.format_check("DTM", 0, 1, |val| {
let comparable = val.get(..12).unwrap_or(val);
ConditionResult::from(!comparable.is_empty() && comparable < "202701010000")
})
}
/// [527] Hinweis: Es ist die Umsatzsteuer- bzw. Steuernummer anzugeben, die vorher per PARTIN ausgetauscht wurde.
fn evaluate_527(&self, _ctx: &EvaluationContext) -> ConditionResult {
// Hinweis: Es ist die Umsatzsteuer- bzw. Steuernummer anzugeben, die vorher per PARTIN ausgetauscht wurde.
ConditionResult::True
}
/// [903] Format: Möglicher Wert: 1
fn evaluate_903(&self, ctx: &EvaluationContext) -> ConditionResult {
if let Some(val) = ctx.resolved_value {
return ConditionResult::from(val == "1");
}
ConditionResult::Unknown
}
/// [2000] Segmentgruppe ist genau einmal anzugeben.
fn evaluate_2000(&self, _ctx: &EvaluationContext) -> ConditionResult {
// Segmentgruppe ist genau einmal anzugeben — informational cardinality constraint
ConditionResult::True
}
}