swift_mt_message/messages/
mt935.rs

1use crate::fields::*;
2use serde::{Deserialize, Serialize};
3use swift_mt_message_macros::{SwiftMessage, serde_swift_fields};
4
5/// # MT935: Rate Change Advice
6///
7/// This message is used by a financial institution to advise another financial institution
8/// of a change in interest rates. This message is critical for managing interest
9/// rate exposure, updating pricing models, and ensuring accurate interest calculations
10/// across correspondent banking relationships and customer accounts.
11///
12/// ## Key Features
13/// - **Interest rate updates**: Notifying changes in deposit or lending rates
14/// - **Base rate changes**: Communicating central bank rate adjustments
15/// - **Account-specific rates**: Updating rates for specific customer accounts
16/// - **Product rate changes**: Modifying rates for specific banking products
17/// - **Regulatory compliance**: Meeting rate disclosure requirements
18/// - **Risk management**: Coordinating rate changes across institutions
19///
20/// ## Field Structure
21/// All fields follow the enhanced macro system with proper validation rules.
22/// The message supports repetitive rate change sequences for bulk updates.
23///
24/// ## Conditional Rules
25/// - **C1**: The repeating sequence of fields 23/25/30/37H must occur at least once and at most 10 times
26/// - **C2**: Either Field 23 or Field 25 must be present in each sequence, but not both
27#[serde_swift_fields]
28#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
29#[validation_rules(MT935_VALIDATION_RULES)]
30pub struct MT935 {
31    /// **Transaction Reference Number** - Field 20
32    ///
33    /// Unique sender's reference for this rate change advice.
34    /// Used for tracking and auditing rate change communications.
35    #[field("20", mandatory)]
36    pub field_20: GenericReferenceField,
37
38    /// **Rate Change Sequences** (Repetitive)
39    ///
40    /// Each sequence represents one rate change with either rate type
41    /// identification (Field 23) or account identification (Field 25),
42    /// along with the effective date and new rate.
43    #[field("RATE_CHANGES", repetitive)]
44    pub rate_changes: Vec<MT935RateChange>,
45
46    /// **Sender to Receiver Information** - Field 72 (Optional)
47    ///
48    /// Additional information about the rate changes.
49    /// Can include structured text or narrative details.
50    #[field("72", optional)]
51    pub field_72: Option<GenericMultiLineTextField<6, 35>>,
52}
53
54/// # MT935 Rate Change Sequence
55///
56/// Represents a single rate change within an MT935 message.
57/// Each sequence must have either Field 23 (rate type) OR Field 25 (account), but not both.
58/// Enhanced with SwiftMessage derive for automatic parsing and validation as a sub-message structure.
59#[serde_swift_fields]
60#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftMessage)]
61#[validation_rules(MT935_RATE_CHANGE_VALIDATION_RULES)]
62pub struct MT935RateChange {
63    /// **Further Identification** - Field 23 (Conditional C2)
64    ///
65    /// Identifies the type of rate being changed (BASE, CALL, COMMERCIAL, etc.)
66    /// Function codes: BASE, CALL, COMMERCIAL, CURRENT, DEPOSIT, NOTICE, PRIME
67    #[field("23", optional)]
68    pub field_23: Option<Field23>,
69
70    /// **Account Identification** - Field 25 (Conditional C2)
71    ///
72    /// Identifies specific account for account-specific rate changes.
73    /// Alternative to Field 23 when rate applies to individual account.
74    #[field("25", optional)]
75    pub field_25: Option<GenericTextField>,
76
77    /// **Effective Date of New Rate** - Field 30 (Mandatory)
78    ///
79    /// When the new rate becomes effective (YYMMDD format).
80    /// Must be a valid calendar date.
81    #[field("30", mandatory)]
82    pub field_30: GenericTextField,
83
84    /// **New Interest Rate** - Field 37H (Mandatory)
85    ///
86    /// The new interest rate value with C/D indicator.
87    /// Indicator: 'C' for credit rate, 'D' for debit rate.
88    #[field("37H", mandatory)]
89    pub field_37h: Field37H,
90}
91
92/// Enhanced validation rules for MT935
93const MT935_VALIDATION_RULES: &str = r#"{
94  "rules": [
95    {
96      "id": "C1",
97      "description": "Rate change sequences must occur 1-10 times",
98      "condition": {
99        "and": [
100          {">=": [{"length": {"var": "rate_changes"}}, 1]},
101          {"<=": [{"length": {"var": "rate_changes"}}, 10]}
102        ]
103      }
104    },
105    {
106      "id": "REF_FORMAT", 
107      "description": "Transaction reference must not have invalid slash patterns",
108      "condition": {
109        "and": [
110          {"!": {"startsWith": [{"var": "field_20.value"}, "/"]}},
111          {"!": {"endsWith": [{"var": "field_20.value"}, "/"]}},
112          {"!": {"includes": [{"var": "field_20.value"}, "//"]}}
113        ]
114      }
115    },
116    {
117      "id": "REQUIRED_FIELDS",
118      "description": "All mandatory fields must be present and non-empty",
119      "condition": {
120        "!=": [{"var": "field_20.value"}, ""]
121      }
122    }
123  ]
124}"#;
125
126/// Validation rules specific to MT935 rate change sequences
127const MT935_RATE_CHANGE_VALIDATION_RULES: &str = r#"{
128  "rules": [
129    {
130      "id": "C2",
131      "description": "Either Field 23 or Field 25 must be present, but not both",
132      "condition": {
133        "or": [
134          {
135            "and": [
136              {"var": "field_23.is_some"},
137              {"var": "field_25.is_none"}
138            ]
139          },
140          {
141            "and": [
142              {"var": "field_23.is_none"},
143              {"var": "field_25.is_some"}
144            ]
145          }
146        ]
147      }
148    },
149    {
150      "id": "REQUIRED_SEQUENCE_FIELDS",
151      "description": "Effective date and new rate must be present and non-empty",
152      "condition": {
153        "and": [
154          {"!=": [{"var": "field_30.value"}, ""]},
155          {"var": "field_37h.is_valid"}
156        ]
157      }
158    }
159  ]
160}"#;