swift_mt_message/messages/
mt205.rs

1use crate::fields::*;
2use serde::{Deserialize, Serialize};
3use swift_mt_message_macros::{SwiftMessage, serde_swift_fields};
4
5/// # MT205: General Financial Institution Transfer
6///
7/// This message enables financial institutions to transfer funds between themselves for their own
8/// account or for the account of their customers. Similar to MT202 but with key structural
9/// differences: field 54a is not present and field 52a is always mandatory.
10///
11/// ## Key Differences from MT202
12/// - **Field 54a**: Not present in MT205 (completely absent)
13/// - **Field 52a**: Always mandatory (no fallback to sender BIC)
14/// - **Settlement Logic**: Uses METAFCT003 (simplified scenarios)
15/// - **Cover Detection**: Based on Sequence B presence
16///
17/// ## Message Variants
18/// - **MT205**: Standard financial institution transfer
19/// - **MT205.COV**: Cover message for customer credit transfers
20/// - **MT205.REJT**: Rejection message
21/// - **MT205.RETN**: Return message
22///
23/// ## Structure
24/// - **Sequence A**: Bank-to-bank financial institution details
25/// - **Sequence B**: Customer details (COV variant only)
26#[serde_swift_fields]
27#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
28#[validation_rules(MT205_VALIDATION_RULES)]
29pub struct MT205 {
30    // Sequence A: Mandatory Fields
31    #[field("20", mandatory)]
32    pub field_20: GenericReferenceField, // Transaction Reference Number
33
34    #[field("21", mandatory)]
35    pub field_21: GenericReferenceField, // Related Reference
36
37    #[field("32A", mandatory)]
38    pub field_32a: Field32A, // Value Date/Currency/Amount
39
40    #[field("52A", mandatory)]
41    pub field_52a: GenericBicField, // Ordering Institution (MANDATORY in MT205)
42
43    #[field("58A", mandatory)]
44    pub field_58a: GenericBicField, // Beneficiary Institution
45
46    // Sequence A: Optional Fields
47    #[field("13C", optional)]
48    pub field_13c: Option<Vec<Field13C>>, // Time Indication (repetitive)
49
50    #[field("53A", optional)]
51    pub field_53a: Option<GenericBicField>, // Sender's Correspondent
52
53    #[field("56A", optional)]
54    pub field_56a: Option<GenericBicField>, // Intermediary Institution
55
56    #[field("57A", optional)]
57    pub field_57a: Option<GenericBicField>, // Account With Institution
58
59    #[field("72", optional)]
60    pub field_72: Option<GenericMultiLine6x35>, // Sender to Receiver Information
61
62    // Sequence B: COV Cover Message Fields (Optional)
63    #[field("50A", optional)]
64    pub field_50a: Option<Field50>, // Ordering Customer
65
66    #[field("52A_SEQ_B", optional)]
67    pub field_52a_seq_b: Option<GenericBicField>, // Ordering Institution (Seq B)
68
69    #[field("56A_SEQ_B", optional)]
70    pub field_56a_seq_b: Option<GenericBicField>, // Intermediary Institution (Seq B)
71
72    #[field("57A_SEQ_B", optional)]
73    pub field_57a_seq_b: Option<GenericBicField>, // Account With Institution (Seq B)
74
75    #[field("59A", optional)]
76    pub field_59a: Option<GenericBicField>, // Beneficiary Customer
77
78    #[field("70", optional)]
79    pub field_70: Option<GenericMultiLine4x35>, // Remittance Information
80
81    #[field("72_SEQ_B", optional)]
82    pub field_72_seq_b: Option<GenericMultiLine6x35>, // Sender to Receiver Info (Seq B)
83
84    #[field("33B", optional)]
85    pub field_33b: Option<GenericCurrencyAmountField>, // Currency/Instructed Amount
86}
87
88/// Validation rules for MT205 - General Financial Institution Transfer
89const MT205_VALIDATION_RULES: &str = r#"{
90  "rules": [
91    {
92      "id": "C1",
93      "description": "Transaction Reference (20) must not start or end with '/' and must not contain '//'",
94      "condition": {
95        "and": [
96          {"!": {"matches": [{"var": "field_20.value"}, "^/"]}},
97          {"!": {"matches": [{"var": "field_20.value"}, "/$"]}},
98          {"!": {"matches": [{"var": "field_20.value"}, "//"]}}
99        ]
100      }
101    },
102    {
103      "id": "C2",
104      "description": "Related Reference (21) must not start or end with '/' and must not contain '//'",
105      "condition": {
106        "and": [
107          {"!": {"matches": [{"var": "field_21.value"}, "^/"]}},
108          {"!": {"matches": [{"var": "field_21.value"}, "/$"]}},
109          {"!": {"matches": [{"var": "field_21.value"}, "//"]}}
110        ]
111      }
112    },
113    {
114      "id": "C3",
115      "description": "Field 52a is mandatory in MT205 (no fallback to sender BIC)",
116      "condition": {
117        "!=": [{"var": "field_52a.bic"}, ""]
118      }
119    },
120    {
121      "id": "C4",
122      "description": "Field 54a is not present in MT205 (structural difference from MT202)",
123      "condition": true
124    },
125    {
126      "id": "C5",
127      "description": "Cover message detection based on Sequence B customer fields presence",
128      "condition": {
129        "if": [
130          {"or": [
131            {"var": "field_50a.is_some"},
132            {"var": "field_59a.is_some"},
133            {"var": "field_70.is_some"}
134          ]},
135          {"var": "field_52a_seq_b.is_some"},
136          true
137        ]
138      }
139    },
140    {
141      "id": "C6",
142      "description": "Cross-currency validation: if 33B present, currency should differ from 32A",
143      "condition": {
144        "if": [
145          {"var": "field_33b.is_some"},
146          {"!=": [{"var": "field_33b.currency"}, {"var": "field_32a.currency"}]},
147          true
148        ]
149      }
150    },
151    {
152      "id": "C7",
153      "description": "REJT/RETN indicator validation in field 72",
154      "condition": {
155        "if": [
156          {"var": "field_72.is_some"},
157          {"or": [
158            {"!": {"matches": [{"var": "field_72.lines"}, "/REJT/"]}},
159            {"!": {"matches": [{"var": "field_72.lines"}, "/RETN/"]}},
160            true
161          ]},
162          true
163        ]
164      }
165    },
166    {
167      "id": "C8",
168      "description": "Time indication validation for CLS/TARGET timing",
169      "condition": {
170        "if": [
171          {"var": "field_13c.is_some"},
172          {"allValid": [
173            {"var": "field_13c"},
174            {"matches": [{"var": "time_code"}, "^(SNDTIME|RNCTIME|CLSTIME|TILTIME|FROTIME|REJTIME)$"]}
175          ]},
176          true
177        ]
178      }
179    },
180    {
181      "id": "C9",
182      "description": "Settlement method determination (METAFCT003 - simplified scenarios)",
183      "condition": {
184        "if": [
185          {"var": "field_53a.is_some"},
186          {"!=": [{"var": "field_53a.bic"}, {"var": "field_52a.bic"}]},
187          true
188        ]
189      }
190    }
191  ]
192}"#;