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}