datasynth_core/models/prior_year.rs
1//! Prior-year comparative data models for year-over-year audit analysis.
2//!
3//! Supports ISA 315 (Understanding the Entity) and ISA 520 (Analytical Procedures)
4//! by providing prior-year balances, variances, and prior-year audit findings
5//! for follow-up procedures.
6
7use chrono::NaiveDate;
8use rust_decimal::Decimal;
9use serde::{Deserialize, Serialize};
10use uuid::Uuid;
11
12/// Prior-year comparative data for year-over-year analysis.
13///
14/// Each record pairs a current-year account balance with its prior-year
15/// counterpart and computes the variance (absolute and percentage).
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct PriorYearComparative {
18 /// GL account code (e.g., "1100", "4000")
19 pub account_code: String,
20 /// Account description
21 pub account_name: String,
22 /// Current-year closing balance
23 #[serde(with = "rust_decimal::serde::str")]
24 pub current_year_amount: Decimal,
25 /// Prior-year closing balance (derived with realistic variance)
26 #[serde(with = "rust_decimal::serde::str")]
27 pub prior_year_amount: Decimal,
28 /// Absolute variance: current_year_amount - prior_year_amount
29 #[serde(with = "rust_decimal::serde::str")]
30 pub variance: Decimal,
31 /// Variance as percentage: (current - prior) / |prior| * 100
32 pub variance_pct: f64,
33 /// Entity / company code
34 pub entity_code: String,
35 /// Fiscal period label (e.g., "2025-12", "2025-Q4")
36 pub period: String,
37}
38
39/// Prior-year audit finding for follow-up procedures.
40///
41/// Findings from the prior-year engagement that may require current-year
42/// follow-up, re-testing, or disclosure in the current audit report.
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct PriorYearFinding {
45 /// Unique finding identifier (deterministic UUID)
46 pub finding_id: Uuid,
47 /// Fiscal year the finding was originally raised
48 pub fiscal_year: i32,
49 /// Finding classification: "control_deficiency", "misstatement",
50 /// "significant_deficiency", "material_weakness"
51 pub finding_type: String,
52 /// Narrative description of the finding
53 pub description: String,
54 /// Current remediation status: "remediated", "open", "recurring",
55 /// "partially_remediated"
56 pub status: String,
57 /// Risk area: "revenue", "receivables", "payables", "inventory", "estimates"
58 pub risk_area: String,
59 /// Original monetary amount of the finding (if applicable)
60 #[serde(default, skip_serializing_if = "Option::is_none")]
61 pub original_amount: Option<Decimal>,
62 /// Date on which remediation was completed (if applicable)
63 #[serde(default, skip_serializing_if = "Option::is_none")]
64 pub remediation_date: Option<NaiveDate>,
65 /// Whether the current-year audit team must follow up
66 pub follow_up_required: bool,
67}
68
69/// Prior-year audit engagement summary.
70///
71/// An aggregate record that bundles the prior-year opinion, materiality,
72/// comparatives, and findings into a single envelope for the current-year
73/// audit team.
74#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct PriorYearSummary {
76 /// Prior fiscal year (e.g., 2024 if current year is 2025)
77 pub fiscal_year: i32,
78 /// Entity / company code
79 pub entity_code: String,
80 /// Audit opinion issued: "unmodified", "qualified", "adverse", "disclaimer"
81 pub opinion_type: String,
82 /// Prior-year materiality threshold
83 #[serde(with = "rust_decimal::serde::str")]
84 pub materiality: Decimal,
85 /// Total number of findings raised
86 pub total_findings: usize,
87 /// Number of findings still open or recurring
88 pub open_findings: usize,
89 /// Key audit matters from the prior-year report
90 pub key_audit_matters: Vec<String>,
91 /// Per-account comparative data
92 pub comparatives: Vec<PriorYearComparative>,
93 /// Prior-year findings carried forward
94 pub findings: Vec<PriorYearFinding>,
95}