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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use crate::errors::SwiftValidationError;
use crate::fields::*;
use crate::parser::utils::*;
use serde::{Deserialize, Serialize};
/// **MT112: Status of a Request for Stop Payment of a Cheque**
///
/// Response from drawee bank to drawer bank confirming actions taken on MT111 stop payment request.
/// Provides status information about the stop payment instruction.
///
/// **Usage:** Stop payment status notifications
/// **Category:** Category 1 (Customer Payments)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
pub struct MT112 {
/// Transaction reference (Field 20)
#[serde(rename = "20")]
pub field_20: Field20,
/// Cheque number (Field 21)
#[serde(rename = "21")]
pub field_21: Field21NoOption,
/// Date of issue (Field 30)
#[serde(rename = "30")]
pub field_30: Field30,
/// Amount (Field 32)
#[serde(flatten)]
pub field_32: Field32AB,
/// Drawer bank (Field 52)
#[serde(flatten, skip_serializing_if = "Option::is_none")]
pub field_52: Option<Field52OrderingInstitution>,
/// Payee (Field 59)
#[serde(rename = "59", skip_serializing_if = "Option::is_none")]
pub field_59: Option<Field59NoOption>,
/// Answers (Field 76)
#[serde(rename = "76")]
pub field_76: Field76,
}
impl MT112 {
/// Parse message from Block 4 content
pub fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
let mut parser = crate::parser::MessageParser::new(block4, "112");
// Parse mandatory fields
let field_20 = parser.parse_field::<Field20>("20")?;
let field_21 = parser.parse_field::<Field21NoOption>("21")?;
let field_30 = parser.parse_field::<Field30>("30")?;
// Parse amount - can be 32A or 32B per spec
let field_32 = parser.parse_variant_field::<Field32AB>("32")?;
// Parse optional fields
let field_52 = parser.parse_optional_variant_field::<Field52OrderingInstitution>("52")?;
let field_59 = parser.parse_optional_field::<Field59NoOption>("59")?;
// Parse mandatory field 76
let field_76 = parser.parse_field::<Field76>("76")?;
Ok(MT112 {
field_20,
field_21,
field_30,
field_32,
field_52,
field_59,
field_76,
})
}
/// Parse from generic SWIFT input (tries to detect blocks)
pub fn parse(input: &str) -> Result<Self, crate::errors::ParseError> {
let block4 = extract_block4(input)?;
Self::parse_from_block4(&block4)
}
/// Convert to SWIFT MT text format
pub fn to_mt_string(&self) -> String {
let mut result = String::new();
append_field(&mut result, &self.field_20);
append_field(&mut result, &self.field_21);
append_field(&mut result, &self.field_30);
append_field(&mut result, &self.field_32);
append_optional_field(&mut result, &self.field_52);
append_optional_field(&mut result, &self.field_59);
append_field(&mut result, &self.field_76);
finalize_mt_string(result, false)
}
// ========================================================================
// NETWORK VALIDATION RULES (SR 2025 MT112)
// ========================================================================
/// Main validation method - validates all network rules
/// Returns array of validation errors, respects stop_on_first_error flag
///
/// **Note**: According to SR 2025 specifications, MT112 has no network validated rules.
/// This method is provided for consistency with other message types and future extensibility.
pub fn validate_network_rules(&self, _stop_on_first_error: bool) -> Vec<SwiftValidationError> {
// MT112 has no network validated rules according to SR 2025
// All validation is handled at the field level
Vec::new()
}
}
impl crate::traits::SwiftMessageBody for MT112 {
fn message_type() -> &'static str {
"112"
}
fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
// Call the existing public method implementation
MT112::parse_from_block4(block4)
}
fn to_mt_string(&self) -> String {
// Call the existing public method implementation
MT112::to_mt_string(self)
}
fn validate_network_rules(&self, stop_on_first_error: bool) -> Vec<SwiftValidationError> {
// Call the existing public method implementation
MT112::validate_network_rules(self, stop_on_first_error)
}
}