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