swift_mt_message/messages/
mt112.rs

1use crate::fields::*;
2use serde::{Deserialize, Serialize};
3use swift_mt_message_macros::{SwiftMessage, serde_swift_fields};
4
5/// # MT112: Status of Request for Stop Payment of a Cheque
6///
7/// This message is used by financial institutions to communicate the status of a stop payment
8/// request that was previously submitted via MT111. It provides confirmation, rejection, or
9/// status updates regarding the processing of the stop payment request.
10///
11/// ## Structure
12/// Simple flat structure with no repeating sequences - all fields are at message level.
13///
14/// ## Key Features
15/// - Status response to MT111 stop payment requests
16/// - References original stop payment request details  
17/// - Provides detailed status information and reasons
18/// - Support for partial processing scenarios
19/// - Optional additional correspondence information
20/// - Maintains audit trail for stop payment lifecycle
21#[serde_swift_fields]
22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
23#[validation_rules(MT112_VALIDATION_RULES)]
24pub struct MT112 {
25    // Mandatory Fields
26    #[field("20", mandatory)]
27    pub field_20: GenericReferenceField, // Transaction Reference Number
28
29    #[field("21", mandatory)]
30    pub field_21: GenericReferenceField, // Cheque Number
31
32    #[field("30", mandatory)]
33    pub field_30: GenericTextField, // Date of Issue (YYMMDD)
34
35    #[field("32A", mandatory)]
36    pub field_32a: GenericCurrencyAmountField, // Amount
37
38    #[field("76", mandatory)]
39    pub field_76: GenericMultiLine6x35, // Answers (Status Information)
40
41    // Optional Fields
42    #[field("52A", optional)]
43    pub field_52a: Option<GenericBicField>, // Drawer Bank A
44
45    #[field("52B", optional)]
46    pub field_52b: Option<GenericPartyField>, // Drawer Bank B
47
48    #[field("52D", optional)]
49    pub field_52d: Option<GenericNameAddressField>, // Drawer Bank D
50
51    #[field("59", optional)]
52    pub field_59: Option<Field59>, // Payee (without account number)
53}
54
55/// Validation rules for MT112 - Status of Request for Stop Payment of a Cheque
56const MT112_VALIDATION_RULES: &str = r#"{
57  "rules": [
58    {
59      "id": "C1",
60      "description": "Date of Issue (30) must be valid YYMMDD format",
61      "condition": {
62        "matches": [
63          {"var": "field_30.value"},
64          "^[0-9]{6}$"
65        ]
66      }
67    },
68    {
69      "id": "C2", 
70      "description": "Transaction Reference (20) must not start or end with '/' and must not contain '//'",
71      "condition": {
72        "and": [
73          {"!": {"matches": [{"var": "field_20.value"}, "^/"]}},
74          {"!": {"matches": [{"var": "field_20.value"}, "/$"]}},
75          {"!": {"matches": [{"var": "field_20.value"}, "//"]}}
76        ]
77      }
78    },
79    {
80      "id": "C3",
81      "description": "Cheque Number (21) must not start or end with '/' and must not contain '//'", 
82      "condition": {
83        "and": [
84          {"!": {"matches": [{"var": "field_21.value"}, "^/"]}},
85          {"!": {"matches": [{"var": "field_21.value"}, "/$"]}},
86          {"!": {"matches": [{"var": "field_21.value"}, "//"]}}
87        ]
88      }
89    },
90    {
91      "id": "C4",
92      "description": "Only one option of Drawer Bank (52A/B/D) may be present",
93      "condition": {
94        "<=": [
95          {"+": [
96            {"if": [{"var": "field_52a.is_some"}, 1, 0]},
97            {"if": [{"var": "field_52b.is_some"}, 1, 0]},
98            {"if": [{"var": "field_52d.is_some"}, 1, 0]}
99          ]},
100          1
101        ]
102      }
103    },
104    {
105      "id": "C5",
106      "description": "Payee field (59) must not contain account number in first line",
107      "condition": {
108        "if": [
109          {"var": "field_59.is_some"},
110          {"!": {"matches": [{"var": "field_59.lines.0"}, "^/"]}},
111          true
112        ]
113      }
114    },
115    {
116      "id": "C6",
117      "description": "Answers field (76) should contain predefined status codes when applicable",
118      "condition": {
119        "or": [
120          {"matches": [{"var": "field_76.lines.0"}, "STOP PAYMENT"]},
121          {"matches": [{"var": "field_76.lines.0"}, "REQUEST"]},
122          {"matches": [{"var": "field_76.lines.0"}, "PROCESSING"]},
123          {"matches": [{"var": "field_76.lines.0"}, "/[0-9]{2}/"]},
124          true
125        ]
126      }
127    }
128  ]
129}"#;