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
use crate::errors::SwiftValidationError;
use crate::fields::*;
use crate::parser::utils::*;
use serde::{Deserialize, Serialize};
/// **MT111: Request for Stop Payment of a Cheque**
///
/// Request from drawer bank to drawee bank to stop payment of a specific cheque.
/// Used to prevent payment when cheque is lost, stolen, or disputed.
///
/// **Usage:** Cheque stop payment requests
/// **Category:** Category 1 (Customer Payments)
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
pub struct MT111 {
/// Sender's 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>,
/// Queries (Field 75)
#[serde(rename = "75", skip_serializing_if = "Option::is_none")]
pub field_75: Option<Field75>,
}
impl MT111 {
/// 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, "111");
// 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")?;
let field_75 = parser.parse_optional_field::<Field75>("75")?;
Ok(MT111 {
field_20,
field_21,
field_30,
field_32,
field_52,
field_59,
field_75,
})
}
/// 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)
}
// ========================================================================
// NETWORK VALIDATION RULES (SR 2025 MT111)
// ========================================================================
// NOTE: MT111 has no message-level network validation rules (C-series, D-series, E-series, T-series)
// per SR 2025 specification. All validation is performed at the field level:
// - Field 20, 21: Reference format validation (implemented in field types)
// - Field 30: Date validation (implemented in field types)
// - Field 32a: Currency and amount validation (implemented in field types)
// - Field 52a: BIC validation (implemented in field types)
// - Field 59: Account must not be used (enforced by Field59NoOption type)
// - Field 75: Narrative format (implemented in field types)
/// Main validation method - validates all network rules
/// Returns array of validation errors, respects stop_on_first_error flag
pub fn validate_network_rules(&self, _stop_on_first_error: bool) -> Vec<SwiftValidationError> {
// No message-level network validation rules for MT111
Vec::new()
}
}
impl crate::traits::SwiftMessageBody for MT111 {
fn message_type() -> &'static str {
"111"
}
fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
// Call the existing public method implementation
MT111::parse_from_block4(block4)
}
fn to_mt_string(&self) -> String {
// Call the existing public method implementation
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_optional_field(&mut result, &self.field_75);
finalize_mt_string(result, false)
}
fn validate_network_rules(&self, stop_on_first_error: bool) -> Vec<SwiftValidationError> {
// Call the existing public method implementation
MT111::validate_network_rules(self, stop_on_first_error)
}
}