swift_mt_message/messages/
mt112.rs

1use crate::errors::SwiftValidationError;
2use crate::fields::*;
3use crate::parser::utils::*;
4use serde::{Deserialize, Serialize};
5
6/// **MT112: Status of a Request for Stop Payment of a Cheque**
7///
8/// Response from drawee bank to drawer bank confirming actions taken on MT111 stop payment request.
9/// Provides status information about the stop payment instruction.
10///
11/// **Usage:** Stop payment status notifications
12/// **Category:** Category 1 (Customer Payments)
13#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
14pub struct MT112 {
15    /// Transaction reference (Field 20)
16    #[serde(rename = "20")]
17    pub field_20: Field20,
18
19    /// Cheque number (Field 21)
20    #[serde(rename = "21")]
21    pub field_21: Field21NoOption,
22
23    /// Date of issue (Field 30)
24    #[serde(rename = "30")]
25    pub field_30: Field30,
26
27    /// Amount (Field 32)
28    #[serde(flatten)]
29    pub field_32: Field32AB,
30
31    /// Drawer bank (Field 52)
32    #[serde(flatten, skip_serializing_if = "Option::is_none")]
33    pub field_52: Option<Field52OrderingInstitution>,
34
35    /// Payee (Field 59)
36    #[serde(rename = "59", skip_serializing_if = "Option::is_none")]
37    pub field_59: Option<Field59NoOption>,
38
39    /// Answers (Field 76)
40    #[serde(rename = "76")]
41    pub field_76: Field76,
42}
43
44impl MT112 {
45    /// Parse message from Block 4 content
46    pub fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
47        let mut parser = crate::parser::MessageParser::new(block4, "112");
48
49        // Parse mandatory fields
50        let field_20 = parser.parse_field::<Field20>("20")?;
51        let field_21 = parser.parse_field::<Field21NoOption>("21")?;
52        let field_30 = parser.parse_field::<Field30>("30")?;
53
54        // Parse amount - can be 32A or 32B per spec
55        let field_32 = parser.parse_variant_field::<Field32AB>("32")?;
56
57        // Parse optional fields
58        let field_52 = parser.parse_optional_variant_field::<Field52OrderingInstitution>("52")?;
59        let field_59 = parser.parse_optional_field::<Field59NoOption>("59")?;
60
61        // Parse mandatory field 76
62        let field_76 = parser.parse_field::<Field76>("76")?;
63
64        Ok(MT112 {
65            field_20,
66            field_21,
67            field_30,
68            field_32,
69            field_52,
70            field_59,
71            field_76,
72        })
73    }
74
75    /// Parse from generic SWIFT input (tries to detect blocks)
76    pub fn parse(input: &str) -> Result<Self, crate::errors::ParseError> {
77        let block4 = extract_block4(input)?;
78        Self::parse_from_block4(&block4)
79    }
80
81    /// Convert to SWIFT MT text format
82    pub fn to_mt_string(&self) -> String {
83        let mut result = String::new();
84
85        append_field(&mut result, &self.field_20);
86        append_field(&mut result, &self.field_21);
87        append_field(&mut result, &self.field_30);
88        append_field(&mut result, &self.field_32);
89        append_optional_field(&mut result, &self.field_52);
90        append_optional_field(&mut result, &self.field_59);
91        append_field(&mut result, &self.field_76);
92
93        result.push('-');
94        result
95    }
96
97    // ========================================================================
98    // NETWORK VALIDATION RULES (SR 2025 MT112)
99    // ========================================================================
100
101    /// Main validation method - validates all network rules
102    /// Returns array of validation errors, respects stop_on_first_error flag
103    ///
104    /// **Note**: According to SR 2025 specifications, MT112 has no network validated rules.
105    /// This method is provided for consistency with other message types and future extensibility.
106    pub fn validate_network_rules(&self, _stop_on_first_error: bool) -> Vec<SwiftValidationError> {
107        // MT112 has no network validated rules according to SR 2025
108        // All validation is handled at the field level
109        Vec::new()
110    }
111}
112
113impl crate::traits::SwiftMessageBody for MT112 {
114    fn message_type() -> &'static str {
115        "112"
116    }
117
118    fn parse_from_block4(block4: &str) -> Result<Self, crate::errors::ParseError> {
119        // Call the existing public method implementation
120        MT112::parse_from_block4(block4)
121    }
122
123    fn to_mt_string(&self) -> String {
124        // Call the existing public method implementation
125        MT112::to_mt_string(self)
126    }
127
128    fn validate_network_rules(&self, stop_on_first_error: bool) -> Vec<SwiftValidationError> {
129        // Call the existing public method implementation
130        MT112::validate_network_rules(self, stop_on_first_error)
131    }
132}