swift_mt_message/messages/
mt292.rs

1use crate::fields::*;
2use serde::{Deserialize, Serialize};
3use swift_mt_message_macros::{SwiftMessage, serde_swift_fields};
4
5/// # MT292: Request for Cancellation (Treasury)
6///
7/// This message is sent by a financial institution to request the cancellation
8/// of a previously sent treasury-related message. MT292 is used for cancellation
9/// requests related to treasury operations, interbank transfers, and institutional transactions.
10///
11/// ## Key Features
12/// - **Treasury cancellation**: Official request to cancel treasury/institutional messages
13/// - **Reference tracking**: Links to the original message through multiple reference fields
14/// - **Conditional structure**: Either narrative (field 79) or copy of original message fields
15/// - **Audit trail**: Maintains complete cancellation audit records for treasury operations
16/// - **Reason codes**: Standardized cancellation reason codes for institutional processing
17///
18/// ## Field Structure
19/// The message follows a conditional structure where either field 79 (narrative description)
20/// or a copy of the mandatory fields from the original message must be present, or both.
21/// This structure is identical to MT192 but used for treasury/institutional contexts.
22///
23/// ## Cancellation Process
24/// Used when a treasury department or institutional sender needs to request cancellation
25/// of a previously sent message, typically MT2xx series messages for interbank transfers,
26/// due to errors, regulatory requirements, or operational changes.
27#[serde_swift_fields]
28#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
29#[validation_rules(MT292_VALIDATION_RULES)]
30pub struct MT292 {
31    /// **Transaction Reference Number** - Field 20
32    ///
33    /// Unique reference assigned by the sender for this treasury cancellation request.
34    /// This reference is used throughout the cancellation lifecycle for tracking,
35    /// acknowledgment, and audit purposes. Must be unique within sender's system per business day.
36    #[field("20", mandatory)]
37    pub field_20: GenericReferenceField,
38
39    /// **Related Reference** - Field 21
40    ///
41    /// Contains the reference from field 20 of the treasury message to be cancelled.
42    /// This creates a direct link between the cancellation request and the original
43    /// treasury message, enabling the receiver to identify exactly which message to cancel.
44    #[field("21", mandatory)]
45    pub field_21: GenericReferenceField,
46
47    /// **MT and Date of the Original Message** - Field 11S
48    ///
49    /// Specifies the message type, date, session number, and Input Sequence Number (ISN)
50    /// of the original treasury message to be cancelled. Format: 3!n6!n4!n/4!n
51    /// Example: 202231215001/0123 (MT202 dated 2023-12-15, session 0001, ISN 0123)
52    #[field("11S", mandatory)]
53    pub field_11s: Field11S,
54
55    /// **Narrative Description of the Original Message** - Field 79 (Conditional)
56    ///
57    /// Contains cancellation reason codes and free-form text explaining the cancellation.
58    /// Must be present if copy of original message fields is not included, or both may be present.
59    /// Common reason codes: AGNT, AM09, COVR, CURR, CUST, CUTA, DUPL, FRAD, TECH, UPAY
60    #[field("79", optional)]
61    pub field_79: Option<GenericMultiLine6x35>,
62
63    /// **Copy of Mandatory Fields from Original Message** - Multiple Fields (Conditional)
64    ///
65    /// When present, contains a copy of at least the mandatory fields from the original treasury message.
66    /// This helps the receiver identify the exact treasury transaction to be cancelled.
67    /// The specific fields depend on the original message type referenced in field 11S.
68    ///
69    /// For MT202: Would include fields 32A, 53, 58
70    /// For MT205: Would include fields 32A, 53, 56, 57, 58  
71    /// For MT210: Would include fields 32A, 53
72    ///
73    /// Note: This is represented as optional structured content that can contain
74    /// various field combinations depending on the original treasury message type.
75
76    #[field("32A", optional)]
77    pub field_32a: Option<Field32A>,
78
79    #[field("58A", optional)]
80    pub field_58a: Option<GenericBicField>,
81
82    #[field("52A", optional)]
83    pub field_52a: Option<GenericBicField>,
84
85    #[field("53A", optional)]
86    pub field_53a: Option<GenericBicField>,
87
88    #[field("56A", optional)]
89    pub field_56a: Option<GenericBicField>,
90
91    #[field("57A", optional)]
92    pub field_57a: Option<GenericBicField>,
93}
94
95/// Enhanced validation rules for MT292
96const MT292_VALIDATION_RULES: &str = r#"{
97  "rules": [
98    {
99      "id": "CONDITIONAL_C1",
100      "description": "Either field 79 or copy of original message fields must be present, or both",
101      "condition": {
102        "or": [
103          {"!!": {"var": "field_79"}},
104          {
105            "or": [
106              {"!!": {"var": "field_32a"}},
107              {"!!": {"var": "field_58a"}},
108              {"!!": {"var": "field_52a"}},
109              {"!!": {"var": "field_53a"}},
110              {"!!": {"var": "field_56a"}},
111              {"!!": {"var": "field_57a"}}
112            ]
113          }
114        ]
115      }
116    },
117    {
118      "id": "REFERENCE_FORMAT",
119      "description": "Reference fields must not have invalid slash patterns",
120      "condition": {
121        "and": [
122          {"!": {"startsWith": [{"var": "field_20.value"}, "/"]}},
123          {"!": {"endsWith": [{"var": "field_20.value"}, "/"]}},
124          {"!": {"includes": [{"var": "field_20.value"}, "//"]}},
125          {"!": {"startsWith": [{"var": "field_21.value"}, "/"]}},
126          {"!": {"endsWith": [{"var": "field_21.value"}, "/"]}},
127          {"!": {"includes": [{"var": "field_21.value"}, "//"]}}
128        ]
129      }
130    },
131    {
132      "id": "FIELD_11S_FORMAT",
133      "description": "Field 11S must have proper format for MT and date reference",
134      "condition": {
135        "and": [
136          {"==": [{"strlen": {"var": "field_11s.message_type"}}, 3]},
137          {"==": [{"strlen": {"var": "field_11s.date"}}, 6]},
138          {"==": [{"strlen": {"var": "field_11s.session_number"}}, 4]},
139          {"==": [{"strlen": {"var": "field_11s.input_sequence_number"}}, 4]}
140        ]
141      }
142    },
143    {
144      "id": "TREASURY_MESSAGE_TYPE",
145      "description": "Field 11S should reference valid treasury message types",
146      "condition": {
147        "in": [
148          {"var": "field_11s.message_type"},
149          ["200", "202", "205", "210", "256", "299"]
150        ]
151      }
152    },
153    {
154      "id": "REQUIRED_FIELDS",
155      "description": "All mandatory fields must be present and non-empty",
156      "condition": {
157        "and": [
158          {"!=": [{"var": "field_20.value"}, ""]},
159          {"!=": [{"var": "field_21.value"}, ""]},
160          {"!=": [{"var": "field_11s.message_type"}, ""]},
161          {"!=": [{"var": "field_11s.date"}, ""]}
162        ]
163      }
164    },
165    {
166      "id": "REASON_CODE_VALIDATION",
167      "description": "If field 79 is present, it should contain valid cancellation reason codes",
168      "condition": {
169        "if": [
170          {"!!": {"var": "field_79"}},
171          {
172            "or": [
173              {"includes": [{"var": "field_79.lines.0"}, "AGNT"]},
174              {"includes": [{"var": "field_79.lines.0"}, "AM09"]},
175              {"includes": [{"var": "field_79.lines.0"}, "COVR"]},
176              {"includes": [{"var": "field_79.lines.0"}, "CURR"]},
177              {"includes": [{"var": "field_79.lines.0"}, "CUST"]},
178              {"includes": [{"var": "field_79.lines.0"}, "CUTA"]},
179              {"includes": [{"var": "field_79.lines.0"}, "DUPL"]},
180              {"includes": [{"var": "field_79.lines.0"}, "FRAD"]},
181              {"includes": [{"var": "field_79.lines.0"}, "TECH"]},
182              {"includes": [{"var": "field_79.lines.0"}, "UPAY"]}
183            ]
184          },
185          true
186        ]
187      }
188    }
189  ]
190}"#;