swift_mt_message/fields/field32.rs
1//! # Field 32: Value Date, Currency Code, Amount
2//!
3//! ## Purpose
4//! Specifies the value date, currency, and settlement amount for payment instructions.
5//! This is the core monetary field that defines when and how much will be transferred,
6//! serving as the foundation for all payment processing and settlement calculations.
7//!
8//! ## Options Overview
9//! - **Option A**: Value Date + Currency + Amount (complete settlement information)
10//! - **Option B**: Currency + Amount (amount without specific value date)
11//!
12//! ## Format Specifications
13//! ### Option A Format
14//! - **Swift Format**: `6!n3!a15d`
15//! - **Components**:
16//! - `6!n`: Value date (YYMMDD format)
17//! - `3!a`: Currency code (ISO 4217, 3 alphabetic characters)
18//! - `15d`: Amount (up to 15 digits including decimal, comma as decimal separator)
19//!
20//! ### Option B Format
21//! - **Swift Format**: `3!a15d`
22//! - **Components**:
23//! - `3!a`: Currency code (ISO 4217, 3 alphabetic characters)
24//! - `15d`: Amount (up to 15 digits including decimal, comma as decimal separator)
25//!
26//! ## Presence and Usage
27//! - **Status**: Mandatory in all payment messages (MT103, MT202, etc.)
28//! - **Swift Error Codes**: T40 (invalid date), T52 (invalid currency), T51 (invalid amount)
29//! - **Referenced in Rules**: C1, C7, C8, C9 (MT103), currency validation across message types
30//!
31//! ## Value Date Rules (Option A)
32//! - **Format**: YYMMDD (2-digit year, month, day)
33//! - **Validation**: Must be a valid calendar date
34//! - **Business Rules**: Cannot be more than 1 year in the past or future (typical limit)
35//! - **Weekends/Holidays**: System may adjust for banking days depending on currency
36//!
37//! ## Currency Code Rules
38//! - **Standard**: ISO 4217 three-letter currency codes
39//! - **Validation**: Must be an active, tradeable currency
40//! - **Examples**: USD, EUR, GBP, JPY, CHF, CAD, AUD
41//! - **Restrictions**: Some currencies may be restricted for certain corridors
42//!
43//! ## Amount Rules
44//! - **Format**: Up to 15 digits with decimal precision
45//! - **Decimal Separator**: Comma (,) for decimal values in Swift format
46//! - **Precision**: Typically 2 decimal places, varies by currency (JPY has 0, BHD has 3)
47//! - **Range**: Must be positive (> 0), maximum depends on currency and institution limits
48//!
49//! ## Network Validation Rules
50//! - **C1 (MT103)**: If field 33B differs from 32A currency, field 36 (Exchange Rate) required
51//! - **C7**: Amount must be positive and properly formatted for currency
52//! - **C8**: If charges apply (71F/71G), 33B becomes mandatory for charge calculations
53//! - **C9**: Currency in 71G must match 32A currency for charge consistency
54//!
55//! ## Usage Guidelines
56//! - **Settlement**: This amount determines the final settlement obligation
57//! - **Exchange Rates**: When currency differs from instructed amount (33B), exchange rate (36) needed
58//! - **Charges**: Original instructed amount before any fee deductions
59//! - **Precision**: Must respect currency-specific decimal precision rules
60//!
61//! ## STP Compliance
62//! - **Amount Format**: Must comply with STP formatting standards (no trailing zeros)
63//! - **Currency Support**: STP corridors may support limited currency pairs
64//! - **Validation**: Enhanced validation for STP messages to prevent manual intervention
65//!
66//! ## Regional Considerations
67//! - **SEPA**: EUR payments within SEPA zone have specific amount and date rules
68//! - **US Domestic**: USD payments may require different value date handling
69//! - **Emerging Markets**: Some currencies have additional restrictions or validations
70//!
71//! ## Examples
72//! ```text
73//! :32A:240719EUR1250,50 // July 19, 2024, EUR 1,250.50
74//! :32A:240720USD10000,00 // July 20, 2024, USD 10,000.00
75//! :32A:240721JPY1500000 // July 21, 2024, JPY 1,500,000 (no decimal)
76//! :32B:EUR5000,00 // EUR 5,000.00 (no value date)
77//! ```
78//!
79//! ## Related Fields Integration
80//! - **Field 33B**: Instructed Amount (if different from settlement amount)
81//! - **Field 36**: Exchange Rate (when 33B currency differs from 32A)
82//! - **Field 71F/71G**: Sender's/Receiver's Charges (affect final settlement)
83//! - **Field 30**: Execution Date (in some message types)
84//!
85//! ## Error Prevention
86//! - **Invalid Date**: T40 error if date is malformed or unrealistic
87//! - **Invalid Currency**: T52 error if currency code not recognized
88//! - **Invalid Amount**: T51 error if amount format incorrect or negative
89//! - **Business Rule**: C-rule violations if currency/amount conflicts with other fields
90//!
91//! ## Amount Precision by Currency
92//! - **Most Currencies**: 2 decimal places (USD, EUR, GBP, etc.)
93//! - **Japanese Yen**: 0 decimal places (JPY)
94//! - **Bahraini Dinar**: 3 decimal places (BHD)
95//! - **Cryptocurrency**: Variable precision (check current standards)
96//!
97//! ## See Also
98//! - Swift FIN User Handbook: Currency and Amount Specifications
99//! - ISO 4217: Currency Code Standard
100//! - MT103 Usage Rules: Value Date and Settlement Guidelines
101//! - STP Implementation Guide: Amount Format Requirements
102
103use chrono::NaiveDate;
104use serde::{Deserialize, Serialize};
105use swift_mt_message_macros::SwiftField;
106
107/// **Field 32A: Value Date, Currency Code, Amount**
108///
109/// Complete settlement information variant of [Field 32 module](index.html). Specifies the value date,
110/// currency, and settlement amount for payment instructions.
111///
112/// **Components:**
113/// - Value date (6!n, YYMMDD format)
114/// - Currency code (3!a, ISO 4217)
115/// - Amount (15d, decimal with comma separator)
116///
117/// For complete documentation, see the [Field 32 module](index.html).
118#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftField)]
119pub struct Field32A {
120 /// Value date when the payment becomes effective
121 ///
122 /// Format: 6!n (YYMMDD) - Must be valid calendar date
123 /// Business rule: Typically within 1 year of today
124 #[component("6!n")]
125 pub value_date: Option<NaiveDate>,
126
127 /// ISO 4217 three-letter currency code
128 ///
129 /// Format: 3!a - Must be valid, active currency
130 /// Examples: USD, EUR, GBP, JPY, CHF
131 #[component("3!a")]
132 pub currency: String,
133
134 /// Settlement amount in the specified currency
135 ///
136 /// Format: 15d - Up to 15 digits, comma decimal separator
137 /// Must be positive, respect currency precision rules
138 #[component("15d")]
139 pub amount: f64,
140}
141
142/// **Field 32B: Currency Code, Amount**
143///
144/// Currency and amount variant of [Field 32 module](index.html). Specifies currency and amount
145/// without a specific value date.
146///
147/// **Components:**
148/// - Currency code (3!a, ISO 4217)
149/// - Amount (15d, decimal with comma separator)
150///
151/// For complete documentation, see the [Field 32 module](index.html).
152#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftField)]
153pub struct Field32B {
154 /// Currency code (ISO 4217)
155 #[component("3!a")]
156 pub currency: String,
157 /// Amount
158 #[component("15d")]
159 pub amount: f64,
160}
161
162/// **Field 32C: Value Date, Currency Code, Amount (Credit)**
163///
164/// Credit variant of [Field 32 module](index.html). Specifies the value date,
165/// currency, and amount credited. Used in MT n90 messages (MT190, MT290, etc.)
166/// to indicate credit adjustments.
167///
168/// **Components:**
169/// - Value date (6!n, YYMMDD format)
170/// - Currency code (3!a, ISO 4217)
171/// - Amount (15d, decimal with comma separator)
172///
173/// For complete documentation, see the [Field 32 module](index.html).
174#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftField)]
175pub struct Field32C {
176 /// Value date when the credit becomes effective
177 ///
178 /// Format: 6!n (YYMMDD) - Must be valid calendar date
179 #[component("6!n")]
180 pub value_date: Option<NaiveDate>,
181
182 /// ISO 4217 three-letter currency code
183 ///
184 /// Format: 3!a - Must be valid, active currency
185 #[component("3!a")]
186 pub currency: String,
187
188 /// Credit amount in the specified currency
189 ///
190 /// Format: 15d - Up to 15 digits, comma decimal separator
191 #[component("15d")]
192 pub amount: f64,
193}
194
195/// **Field 32D: Value Date, Currency Code, Amount (Debit)**
196///
197/// Debit variant of [Field 32 module](index.html). Specifies the value date,
198/// currency, and amount debited. Used in MT n90 messages (MT190, MT290, etc.)
199/// to indicate debit adjustments.
200///
201/// **Components:**
202/// - Value date (6!n, YYMMDD format)
203/// - Currency code (3!a, ISO 4217)
204/// - Amount (15d, decimal with comma separator)
205///
206/// For complete documentation, see the [Field 32 module](index.html).
207#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, SwiftField)]
208pub struct Field32D {
209 /// Value date when the debit becomes effective
210 ///
211 /// Format: 6!n (YYMMDD) - Must be valid calendar date
212 #[component("6!n")]
213 pub value_date: Option<NaiveDate>,
214
215 /// ISO 4217 three-letter currency code
216 ///
217 /// Format: 3!a - Must be valid, active currency
218 #[component("3!a")]
219 pub currency: String,
220
221 /// Debit amount in the specified currency
222 ///
223 /// Format: 15d - Up to 15 digits, comma decimal separator
224 #[component("15d")]
225 pub amount: f64,
226}
227
228/// **Field 32 Enum: Value Date, Currency, Amount Variants**
229///
230/// Enum wrapper for [Field 32 module](index.html) variants providing different
231/// levels of settlement information detail.
232///
233/// For complete documentation, see the [Field 32 module](index.html).
234#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, SwiftField)]
235pub enum Field32 {
236 A(Field32A),
237 B(Field32B),
238 C(Field32C),
239 D(Field32D),
240}