swift_mt_message/messages/
mt940.rs

1use crate::fields::*;
2use serde::{Deserialize, Serialize};
3use swift_mt_message_macros::{SwiftMessage, serde_swift_fields};
4
5/// # MT940: Customer Statement Message
6///
7/// This message is used by financial institutions to send customer account statements
8/// containing transaction details and balance information. This message provides
9/// a detailed view of account activity over a specific period.
10///
11/// ## Key Features
12/// - **Account statements**: Detailed transaction history for customer accounts
13/// - **Balance information**: Opening and closing balance details
14/// - **Transaction details**: Individual transaction lines with narrative
15/// - **Multi-part statements**: Support for statement sequencing
16/// - **Available balance**: Optional closing available balance reporting
17/// - **Reconciliation support**: Comprehensive data for account reconciliation
18///
19/// ## Field Structure
20/// All fields follow the enhanced macro system with proper validation rules.
21/// The message supports repetitive statement lines for multiple transactions.
22///
23/// ## Business Rules
24/// - Opening balance (60F) and closing balance (62F) must be in consistent currency
25/// - Each Field 61 (transaction line) may be followed by optional Field 86
26/// - Balances use comma as decimal separator
27/// - Statement supports multi-part statements via Field 28C
28#[serde_swift_fields]
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
30#[validation_rules(MT940_VALIDATION_RULES)]
31pub struct MT940 {
32    /// **Transaction Reference Number** - Field 20
33    ///
34    /// Unique ID for this statement, no leading/trailing slashes.
35    /// Used for tracking and referencing this specific statement.
36    #[field("20", mandatory)]
37    pub field_20: GenericReferenceField,
38
39    /// **Related Reference** - Field 21 (Optional)
40    ///
41    /// Links to MT920 if applicable.
42    /// Provides connection to statement request that triggered this response.
43    #[field("21", optional)]
44    pub field_21: Option<GenericReferenceField>,
45
46    /// **Account Identification** - Field 25
47    ///
48    /// IBAN or account identifier, BIC optional.
49    /// Identifies the account for which this statement is provided.
50    #[field("25", mandatory)]
51    pub field_25: GenericTextField,
52
53    /// **Statement/Sequence Number** - Field 28C
54    ///
55    /// Statement and sub-sequence numbers for multi-part statements.
56    /// Enables tracking of statement parts and sequencing.
57    #[field("28C", mandatory)]
58    pub field_28c: Field28C,
59
60    /// **Opening Balance** - Field 60F
61    ///
62    /// Booked opening balance at start of statement period.
63    /// Must be consistent with currency used in closing balance.
64    #[field("60F", mandatory)]
65    pub field_60f: GenericBalanceField,
66
67    /// **Statement Lines** (Repetitive)
68    ///
69    /// Transaction lines with optional accompanying Field 86.
70    /// Each statement line represents one transaction with optional narrative.
71    #[field("STATEMENT_LINES", repetitive)]
72    pub statement_lines: Vec<MT940StatementLine>,
73
74    /// **Closing Balance** - Field 62F
75    ///
76    /// Booked closing balance at end of statement period.
77    /// Must be consistent with currency used in opening balance.
78    #[field("62F", mandatory)]
79    pub field_62f: GenericBalanceField,
80
81    /// **Closing Available Balance** - Field 64 (Optional)
82    ///
83    /// Cash availability balance showing funds available for use.
84    /// Provides additional liquidity information beyond booked balance.
85    #[field("64", optional)]
86    pub field_64: Option<GenericBalanceField>,
87
88    /// **Forward Available Balance** - Field 65 (Optional)
89    ///
90    /// Value-dated available funds for future periods.
91    /// Shows expected available balance considering future value dates.
92    #[field("65", optional)]
93    pub field_65: Option<GenericBalanceField>,
94}
95
96/// # MT940 Statement Line
97///
98/// Represents a single transaction line (Field 61) with optional
99/// accompanying information (Field 86).
100/// Enhanced with SwiftMessage derive for automatic parsing and validation.
101#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
102#[validation_rules(MT940_STATEMENT_LINE_VALIDATION_RULES)]
103pub struct MT940StatementLine {
104    /// **Statement Line** - Field 61
105    ///
106    /// Transaction details including value date, amount, and transaction type.
107    /// Contains the core transaction information.
108    #[field("61", mandatory)]
109    pub field_61: Field61,
110
111    /// **Info to Account Owner** - Field 86 (Optional)
112    ///
113    /// Narrative details for the transaction.
114    /// Provides additional context and description for the transaction.
115    #[field("86", optional)]
116    pub field_86: Option<GenericMultiLineTextField<6, 65>>,
117}
118
119/// Enhanced validation rules for MT940
120const MT940_VALIDATION_RULES: &str = r#"{
121  "rules": [
122    {
123      "id": "CURRENCY_CONSISTENCY",
124      "description": "Opening and closing balances must have consistent currency",
125      "condition": {
126        "==": [
127          {"var": "field_60f.currency"},
128          {"var": "field_62f.currency"}
129        ]
130      }
131    },
132    {
133      "id": "REF_FORMAT",
134      "description": "Transaction reference must not have invalid slash patterns",
135      "condition": {
136        "and": [
137          {"!": {"startsWith": [{"var": "field_20.value"}, "/"]}},
138          {"!": {"endsWith": [{"var": "field_20.value"}, "/"]}},
139          {"!": {"includes": [{"var": "field_20.value"}, "//"]}}
140        ]
141      }
142    },
143    {
144      "id": "REQUIRED_FIELDS",
145      "description": "All mandatory fields must be present and non-empty",
146      "condition": {
147        "and": [
148          {"!=": [{"var": "field_20.value"}, ""]},
149          {"!=": [{"var": "field_25.value"}, ""]},
150          {"var": "field_28c.is_valid"},
151          {"var": "field_60f.is_valid"},
152          {"var": "field_62f.is_valid"}
153        ]
154      }
155    }
156  ]
157}"#;
158
159/// Validation rules specific to MT940 statement lines
160const MT940_STATEMENT_LINE_VALIDATION_RULES: &str = r#"{
161  "rules": [
162    {
163      "id": "STATEMENT_LINE_VALID",
164      "description": "Statement line must be valid",
165      "condition": {
166        "var": "field_61.is_valid"
167      }
168    }
169  ]
170}"#;