1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! Deferred tax models (IAS 12 / ASC 740).
//!
//! This module provides data models for:
//! - Temporary differences (book vs. tax basis) that give rise to DTA/DTL
//! - ETR (effective tax rate) reconciliation from statutory to effective rate
//! - Deferred tax rollforward schedules tracking opening/closing DTA and DTL
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
// ---------------------------------------------------------------------------
// Enums
// ---------------------------------------------------------------------------
/// Whether a temporary difference gives rise to a deferred tax asset or liability.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum DeferredTaxType {
/// Deferred Tax Asset – book basis exceeds tax basis (e.g. accruals, bad debt).
Asset,
/// Deferred Tax Liability – tax basis exceeds book basis (e.g. accelerated depreciation).
Liability,
}
// ---------------------------------------------------------------------------
// Temporary Difference
// ---------------------------------------------------------------------------
/// A single temporary difference between book (GAAP/IFRS) and tax bases.
///
/// Under IAS 12 / ASC 740 a temporary difference arises when the carrying
/// amount of an asset or liability differs from its tax base. The deferred
/// tax effect equals `difference × statutory_rate`.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TemporaryDifference {
/// Unique identifier for this temporary difference record.
pub id: String,
/// Company / entity code this difference relates to.
pub entity_code: String,
/// GL account code associated with the underlying asset or liability.
pub account: String,
/// Human-readable description (e.g. "Accelerated depreciation – MACRS").
pub description: String,
/// Book (GAAP/IFRS) carrying amount.
#[serde(with = "crate::serde_decimal")]
pub book_basis: Decimal,
/// Tax basis of the same asset or liability.
#[serde(with = "crate::serde_decimal")]
pub tax_basis: Decimal,
/// `book_basis − tax_basis`; positive = DTA, negative = DTL (before type override).
#[serde(with = "crate::serde_decimal")]
pub difference: Decimal,
/// Whether this difference yields a DTA or DTL.
pub deferred_type: DeferredTaxType,
/// Accounting standard that created this difference (e.g. "ASC 842", "IAS 16").
pub originating_standard: Option<String>,
}
// ---------------------------------------------------------------------------
// ETR Reconciliation
// ---------------------------------------------------------------------------
/// A single permanent difference item in the ETR reconciliation.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PermanentDifference {
/// Description of the permanent difference (e.g. "Meals & entertainment (50% disallowed)").
pub description: String,
/// Pre-tax amount of the difference (positive = adds to taxable income).
#[serde(with = "crate::serde_decimal")]
pub amount: Decimal,
/// Tax effect = `amount × statutory_rate` (positive = increases tax expense).
#[serde(with = "crate::serde_decimal")]
pub tax_effect: Decimal,
}
/// Effective tax rate reconciliation for a reporting period.
///
/// Bridges from the statutory rate to the effective rate by listing all
/// permanent differences that cause the two rates to diverge.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaxRateReconciliation {
/// Company / entity code.
pub entity_code: String,
/// Period label (e.g. "FY2024", "2024-Q4").
pub period: String,
/// Pre-tax income (profit before income tax).
#[serde(with = "crate::serde_decimal")]
pub pre_tax_income: Decimal,
/// Statutory (nominal) corporate income tax rate.
#[serde(with = "crate::serde_decimal")]
pub statutory_rate: Decimal,
/// `pre_tax_income × statutory_rate` (expected tax at statutory rate).
#[serde(with = "crate::serde_decimal")]
pub expected_tax: Decimal,
/// Permanent differences that bridge expected → actual tax.
pub permanent_differences: Vec<PermanentDifference>,
/// `actual_tax / pre_tax_income`.
#[serde(with = "crate::serde_decimal")]
pub effective_rate: Decimal,
/// Actual income tax expense for the period.
#[serde(with = "crate::serde_decimal")]
pub actual_tax: Decimal,
}
// ---------------------------------------------------------------------------
// Deferred Tax Rollforward
// ---------------------------------------------------------------------------
/// Period-over-period rollforward of deferred tax asset and liability balances.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeferredTaxRollforward {
/// Company / entity code.
pub entity_code: String,
/// Period label.
pub period: String,
/// Opening Deferred Tax Asset balance.
#[serde(with = "crate::serde_decimal")]
pub opening_dta: Decimal,
/// Opening Deferred Tax Liability balance.
#[serde(with = "crate::serde_decimal")]
pub opening_dtl: Decimal,
/// Net movement during the period (DTA creation less reversal, net of DTL movement).
#[serde(with = "crate::serde_decimal")]
pub current_year_movement: Decimal,
/// Closing Deferred Tax Asset balance (`opening_dta + dta_movement`).
#[serde(with = "crate::serde_decimal")]
pub closing_dta: Decimal,
/// Closing Deferred Tax Liability balance (`opening_dtl + dtl_movement`).
#[serde(with = "crate::serde_decimal")]
pub closing_dtl: Decimal,
}