swift_mt_message/messages/
mt210.rs

1use crate::fields::*;
2use serde::{Deserialize, Serialize};
3use swift_mt_message_macros::{SwiftMessage, serde_swift_fields};
4
5/// # MT210: Notice to Receive
6///
7/// This message is used by a financial institution to notify another financial institution
8/// of an impending debit to the sender's account held with the receiver, or to request
9/// the receiver to provide funds to cover the debit. This message serves as advance
10/// notice of funds requirements and facilitates liquidity management between institutions.
11///
12/// ## Key Features
13/// - **Liquidity management**: Advance notice of funding requirements
14/// - **Correspondent banking**: Notice of impending debits to nostro accounts
15/// - **Cash management**: Coordination of funds availability
16/// - **Settlement preparation**: Pre-funding for settlement obligations
17///
18/// ## Business Rules
19/// - **Rule C1**: Message may include up to 10 notice sequences (if repeated)
20/// - **Rule C2**: Either Field 50a or Field 52a must be present, not both
21/// - **Rule C3**: Currency must be consistent in all 32B fields
22/// - **Commodity restriction**: XAU, XAG, XPD, XPT must not be used
23///
24/// ## Structure
25/// Simple flat structure with conditional fields based on ordering party type.
26#[serde_swift_fields]
27#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
28#[validation_rules(MT210_VALIDATION_RULES)]
29pub struct MT210 {
30    // 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("30", mandatory)]
38    pub field_30: GenericTextField, // Value Date (YYMMDD)
39
40    #[field("32B", mandatory)]
41    pub field_32b: GenericCurrencyAmountField, // Currency and Amount
42
43    // Optional Fields
44    #[field("25", optional)]
45    pub field_25: Option<GenericTextField>, // Account Identification
46
47    // Conditional Fields (Rule C2 - exactly one must be present)
48    #[field("50A", optional)]
49    pub field_50a: Option<Field50>, // Ordering Customer (C, F options)
50
51    #[field("52A", optional)]
52    pub field_52a: Option<GenericBicField>, // Ordering Institution (A, D options)
53
54    #[field("56A", optional)]
55    pub field_56a: Option<GenericBicField>, // Intermediary Institution (A, D options)
56}
57
58/// Validation rules for MT210 - Notice to Receive
59const MT210_VALIDATION_RULES: &str = r#"{
60  "rules": [
61    {
62      "id": "C1",
63      "description": "Transaction Reference (20) must not start or end with '/' and must not contain '//'",
64      "condition": {
65        "and": [
66          {"!": {"matches": [{"var": "field_20.value"}, "^/"]}},
67          {"!": {"matches": [{"var": "field_20.value"}, "/$"]}},
68          {"!": {"matches": [{"var": "field_20.value"}, "//"]}}
69        ]
70      }
71    },
72    {
73      "id": "C2_RULE",
74      "description": "Rule C2: Either Field 50a or Field 52a must be present, not both",
75      "condition": {
76        "xor": [
77          {"var": "field_50a.is_some"},
78          {"var": "field_52a.is_some"}
79        ]
80      }
81    },
82    {
83      "id": "C3",
84      "description": "Rule C3: Currency must be consistent in all 32B fields (single instance validation)",
85      "condition": {
86        "!=": [{"var": "field_32b.currency"}, ""]
87      }
88    },
89    {
90      "id": "C4",
91      "description": "Related Reference (21) must not start or end with '/' and must not contain '//'",
92      "condition": {
93        "and": [
94          {"!": {"matches": [{"var": "field_21.value"}, "^/"]}},
95          {"!": {"matches": [{"var": "field_21.value"}, "/$"]}},
96          {"!": {"matches": [{"var": "field_21.value"}, "//"]}}
97        ]
98      }
99    },
100    {
101      "id": "C5",
102      "description": "Value Date (30) must be valid YYMMDD format",
103      "condition": {
104        "matches": [
105          {"var": "field_30.value"},
106          "^[0-9]{6}$"
107        ]
108      }
109    },
110    {
111      "id": "C6",
112      "description": "Amount must be positive",
113      "condition": {
114        ">": [{"var": "field_32b.amount"}, 0]
115      }
116    },
117    {
118      "id": "C7",
119      "description": "Commodity currencies (XAU, XAG, XPD, XPT) must not be used",
120      "condition": {
121        "!": {
122          "in": [
123            {"var": "field_32b.currency"},
124            ["XAU", "XAG", "XPD", "XPT"]
125          ]
126        }
127      }
128    },
129    {
130      "id": "C8",
131      "description": "Account identification format validation when present",
132      "condition": {
133        "if": [
134          {"var": "field_25.is_some"},
135          {"<=": [{"length": {"var": "field_25.value"}}, 35]},
136          true
137        ]
138      }
139    },
140    {
141      "id": "C9",
142      "description": "Option F for Field 50a requires structured identity details",
143      "condition": {
144        "if": [
145          {"var": "field_50a.is_some"},
146          {"or": [
147            {"var": "field_50a.is_option_c"},
148            {"var": "field_50a.is_option_f"}
149          ]},
150          true
151        ]
152      }
153    },
154    {
155      "id": "C10",
156      "description": "Option D for Fields 52a/56a may include national clearing codes",
157      "condition": {
158        "if": [
159          {"or": [
160            {"var": "field_52a.is_some"},
161            {"var": "field_56a.is_some"}
162          ]},
163          {"or": [
164            {"var": "field_52a.is_option_a"},
165            {"var": "field_52a.is_option_d"},
166            {"var": "field_56a.is_option_a"},
167            {"var": "field_56a.is_option_d"}
168          ]},
169          true
170        ]
171      }
172    }
173  ]
174}"#;