swift_mt_message/messages/
mt942.rs

1use crate::fields::*;
2use serde::{Deserialize, Serialize};
3use swift_mt_message_macros::{SwiftMessage, serde_swift_fields};
4
5/// # MT942: Interim Transaction Report
6///
7/// This message is used by financial institutions to send periodic interim
8/// transaction reports containing summary information about account activity
9/// within a specified period. Unlike MT940, this message focuses on transaction
10/// summaries rather than detailed transaction lines.
11///
12/// ## Key Features
13/// - **Interim reporting**: Regular transaction summaries between full statements
14/// - **Transaction counts**: Summary of debit and credit transaction volumes
15/// - **Floor limits**: Threshold-based reporting for significant transactions
16/// - **Balance progression**: Opening and closing balance information
17/// - **High-volume accounts**: Efficient reporting for accounts with many transactions
18/// - **Cash management**: Regular monitoring of account activity
19///
20/// ## Field Structure
21/// All fields follow the enhanced macro system with proper validation rules.
22/// The message supports optional floor limit information and transaction summaries.
23///
24/// ## Business Rules
25/// - All balance fields must use the same currency
26/// - Transaction counts represent actual processed transactions
27/// - Floor limits determine which transactions are included in summaries
28/// - Entry counts should match the sum of individual transaction counts
29#[serde_swift_fields]
30#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
31#[validation_rules(MT942_VALIDATION_RULES)]
32pub struct MT942 {
33    /// **Transaction Reference Number** - Field 20
34    ///
35    /// Unique reference for this interim transaction report.
36    /// Used for tracking and referencing this specific report.
37    #[field("20", mandatory)]
38    pub field_20: GenericReferenceField,
39
40    /// **Related Reference** - Field 21 (Optional)
41    ///
42    /// Links to MT920 request if applicable.
43    /// Provides connection to report request that triggered this response.
44    #[field("21", optional)]
45    pub field_21: Option<GenericReferenceField>,
46
47    /// **Account Identification** - Field 25
48    ///
49    /// IBAN or account identifier for the reported account.
50    /// Identifies the account for which transaction summary is provided.
51    #[field("25", mandatory)]
52    pub field_25: GenericTextField,
53
54    /// **Statement Number** - Field 28C
55    ///
56    /// Statement sequence number and optional page number.
57    /// Enables proper sequencing of interim reports.
58    #[field("28C", mandatory)]
59    pub field_28c: Field28C,
60
61    /// **Floor Limit Indicator** - Field 34F (Optional)
62    ///
63    /// Minimum transaction amount for inclusion in the report.
64    /// Transactions below this threshold may be excluded from summaries.
65    #[field("34F", optional)]
66    pub field_34f: Option<Field34F>,
67
68    /// **Date/Time Indication** - Field 13D (Optional)
69    ///
70    /// Date and time when the report was generated.
71    /// Provides timestamp for report generation context.
72    #[field("13D", optional)]
73    pub field_13d: Option<Field13D>,
74
75    /// **Opening Balance** - Field 60F
76    ///
77    /// Booked opening balance at start of reporting period.
78    /// Reference point for transaction summaries during the period.
79    #[field("60F", mandatory)]
80    pub field_60f: GenericBalanceField,
81
82    /// **Sum of Debit Entries** - Field 90D (Optional)
83    ///
84    /// Total amount and count of debit transactions.
85    /// Summarizes all debit activity during the reporting period.
86    #[field("90D", optional)]
87    pub field_90d: Option<Field90D>,
88
89    /// **Sum of Credit Entries** - Field 90C (Optional)
90    ///
91    /// Total amount and count of credit transactions.
92    /// Summarizes all credit activity during the reporting period.
93    #[field("90C", optional)]
94    pub field_90c: Option<Field90C>,
95
96    /// **Closing Balance** - Field 62F
97    ///
98    /// Booked closing balance at end of reporting period.
99    /// Final balance after all transactions during the period.
100    #[field("62F", mandatory)]
101    pub field_62f: GenericBalanceField,
102
103    /// **Closing Available Balance** - Field 64 (Optional)
104    ///
105    /// Available funds at close of reporting period.
106    /// Shows actual spendable balance after reserves and holds.
107    #[field("64", optional)]
108    pub field_64: Option<GenericBalanceField>,
109
110    /// **Forward Available Balance** - Field 65 (Optional)
111    ///
112    /// Value-dated available balance for future periods.
113    /// Shows projected available funds considering pending transactions.
114    #[field("65", optional)]
115    pub field_65: Option<GenericBalanceField>,
116
117    /// **Info to Account Owner** - Field 86 (Optional)
118    ///
119    /// Additional narrative information about the report.
120    /// Provides context or explanatory details for the transaction summary.
121    #[field("86", optional)]
122    pub field_86: Option<GenericMultiLineTextField<6, 65>>,
123}
124
125/// Enhanced validation rules for MT942
126const MT942_VALIDATION_RULES: &str = r#"{
127  "rules": [
128    {
129      "id": "CURRENCY_CONSISTENCY",
130      "description": "All balance fields must use the same currency",
131      "condition": {
132        "and": [
133          {"==": [
134            {"var": "field_60f.currency"},
135            {"var": "field_62f.currency"}
136          ]},
137          {
138            "if": [
139              {"var": "field_64.is_some"},
140              {"==": [
141                {"var": "field_60f.currency"},
142                {"var": "field_64.currency"}
143              ]},
144              true
145            ]
146          },
147          {
148            "if": [
149              {"var": "field_65.is_some"},
150              {"==": [
151                {"var": "field_60f.currency"},
152                {"var": "field_65.currency"}
153              ]},
154              true
155            ]
156          }
157        ]
158      }
159    },
160    {
161      "id": "ENTRY_CURRENCY_CONSISTENCY",
162      "description": "Entry summaries must use same currency as balances",
163      "condition": {
164        "and": [
165          {
166            "if": [
167              {"var": "field_90d.is_some"},
168              {"==": [
169                {"var": "field_60f.currency"},
170                {"var": "field_90d.currency"}
171              ]},
172              true
173            ]
174          },
175          {
176            "if": [
177              {"var": "field_90c.is_some"},
178              {"==": [
179                {"var": "field_60f.currency"},
180                {"var": "field_90c.currency"}
181              ]},
182              true
183            ]
184          }
185        ]
186      }
187    },
188    {
189      "id": "REF_FORMAT",
190      "description": "Transaction reference must not have invalid slash patterns",
191      "condition": {
192        "and": [
193          {"!": {"startsWith": [{"var": "field_20.value"}, "/"]}},
194          {"!": {"endsWith": [{"var": "field_20.value"}, "/"]}},
195          {"!": {"includes": [{"var": "field_20.value"}, "//"]}}
196        ]
197      }
198    },
199    {
200      "id": "REQUIRED_FIELDS",
201      "description": "All mandatory fields must be present and non-empty",
202      "condition": {
203        "and": [
204          {"!=": [{"var": "field_20.value"}, ""]},
205          {"!=": [{"var": "field_25.value"}, ""]},
206          {"var": "field_28c.is_valid"},
207          {"var": "field_60f.is_valid"},
208          {"var": "field_62f.is_valid"}
209        ]
210      }
211    }
212  ]
213}"#;