Skip to main content

datasynth_core/models/
currency_translation_result.rs

1//! IAS 21 currency translation result models.
2//!
3//! These models capture the output of translating an entity's financial
4//! statements from its functional currency into the group presentation currency.
5//!
6//! Under the **current-rate method** (most common for foreign operations):
7//! - Balance sheet monetary items → closing rate
8//! - Balance sheet non-monetary items (PP&E, equity) → historical rate
9//! - P&L items → average rate for the period
10//! - The balancing difference is the **Currency Translation Adjustment (CTA)**,
11//!   recognised as Other Comprehensive Income (OCI).
12
13use rust_decimal::Decimal;
14use serde::{Deserialize, Serialize};
15
16/// The overall IAS 21 translation method applied.
17#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
18#[serde(rename_all = "snake_case")]
19pub enum Ias21TranslationMethod {
20    /// Current-rate method — all balance-sheet items at closing rate except
21    /// equity which uses historical rates; P&L at average rate.
22    CurrentRate,
23    /// Temporal method — monetary items at closing rate, non-monetary at
24    /// historical rate; P&L at average rate.
25    Temporal,
26}
27
28impl std::fmt::Display for Ias21TranslationMethod {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        match self {
31            Self::CurrentRate => write!(f, "current_rate"),
32            Self::Temporal => write!(f, "temporal"),
33        }
34    }
35}
36
37/// Which exchange rate was used to translate a particular line item.
38#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
39#[serde(rename_all = "snake_case")]
40pub enum TranslationRateType {
41    /// Period-end (closing) rate — used for balance-sheet monetary items.
42    ClosingRate,
43    /// Rate prevailing at the original transaction date — used for equity and
44    /// non-monetary balance-sheet items.
45    HistoricalRate,
46    /// Weighted average rate for the period — used for P&L items.
47    AverageRate,
48    /// One-to-one (no translation required; functional == presentation).
49    NoTranslation,
50}
51
52impl std::fmt::Display for TranslationRateType {
53    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
54        match self {
55            Self::ClosingRate => write!(f, "closing_rate"),
56            Self::HistoricalRate => write!(f, "historical_rate"),
57            Self::AverageRate => write!(f, "average_rate"),
58            Self::NoTranslation => write!(f, "no_translation"),
59        }
60    }
61}
62
63/// A single translated line item (one GL account / account group).
64#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct TranslatedLineItem {
66    /// GL account code.
67    pub account: String,
68    /// Account type label (e.g. "Asset", "Liability", "Revenue").
69    pub account_type: String,
70    /// Amount in the entity's functional currency.
71    pub functional_amount: Decimal,
72    /// Exchange rate applied.
73    pub rate_used: Decimal,
74    /// Category of rate used.
75    pub rate_type: TranslationRateType,
76    /// Translated amount in the presentation currency.
77    pub presentation_amount: Decimal,
78}
79
80/// Full IAS 21 translation result for one entity and one reporting period.
81#[derive(Debug, Clone, Serialize, Deserialize)]
82pub struct CurrencyTranslationResult {
83    /// Entity (company) code.
84    pub entity_code: String,
85    /// Functional currency of the entity (ISO 4217).
86    pub functional_currency: String,
87    /// Presentation (group reporting) currency (ISO 4217).
88    pub presentation_currency: String,
89    /// Period label (e.g. "2024-12").
90    pub period: String,
91    /// Translation method applied.
92    pub translation_method: Ias21TranslationMethod,
93    /// All translated line items.
94    pub translated_items: Vec<TranslatedLineItem>,
95    /// Currency Translation Adjustment recognised in OCI.
96    ///
97    /// Positive = OCI gain (foreign currency strengthened relative to
98    /// presentation currency); negative = OCI loss.
99    pub cta_amount: Decimal,
100    /// Closing rate used for balance-sheet monetary items.
101    pub closing_rate: Decimal,
102    /// Average rate used for P&L items.
103    pub average_rate: Decimal,
104    /// Total balance-sheet amount translated (functional currency).
105    pub total_balance_sheet_functional: Decimal,
106    /// Total balance-sheet amount translated (presentation currency).
107    pub total_balance_sheet_presentation: Decimal,
108    /// Total P&L amount translated (functional currency).
109    pub total_pnl_functional: Decimal,
110    /// Total P&L amount translated (presentation currency).
111    pub total_pnl_presentation: Decimal,
112}