Skip to main content

datasynth_core/models/audit/
audit_scope.rs

1//! Audit scope model (ISA 220 / ISA 300 planning).
2//!
3//! An [`AuditScope`] defines the boundaries of an audit engagement:
4//! which entity is in scope, which financial statement areas are covered,
5//! and what the applicable materiality threshold is.
6//!
7//! Each scope record links to an [`AuditEngagement`] and is referenced
8//! by [`CombinedRiskAssessment`] records to indicate the planning boundary.
9
10use rust_decimal::Decimal;
11use serde::{Deserialize, Serialize};
12
13/// Minimal audit scope record describing what the engagement covers.
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct AuditScope {
16    /// Unique scope identifier (e.g. "SCOPE-AUD-2025-001-C001").
17    pub id: String,
18    /// Engagement this scope belongs to (FK → AuditEngagement.engagement_id).
19    pub engagement_id: String,
20    /// Entity / company code in scope.
21    pub entity_code: String,
22    /// Financial statement areas / audit focus areas covered by this scope.
23    pub scope_areas: Vec<String>,
24    /// Planning materiality threshold applicable to this scope.
25    pub materiality: Decimal,
26}
27
28impl AuditScope {
29    /// Standard scope areas used when no specific areas are configured.
30    pub const DEFAULT_SCOPE_AREAS: &'static [&'static str] = &[
31        "Revenue",
32        "Accounts Receivable",
33        "Inventory",
34        "Property Plant & Equipment",
35        "Accounts Payable",
36        "Payroll",
37        "Cash & Bank",
38        "Financial Reporting Close",
39    ];
40
41    /// Create a new `AuditScope` with default scope areas.
42    pub fn new(
43        id: impl Into<String>,
44        engagement_id: impl Into<String>,
45        entity_code: impl Into<String>,
46        materiality: Decimal,
47    ) -> Self {
48        Self {
49            id: id.into(),
50            engagement_id: engagement_id.into(),
51            entity_code: entity_code.into(),
52            scope_areas: Self::DEFAULT_SCOPE_AREAS
53                .iter()
54                .map(|s| s.to_string())
55                .collect(),
56            materiality,
57        }
58    }
59
60    /// Create an `AuditScope` with explicit scope areas.
61    pub fn with_areas(
62        id: impl Into<String>,
63        engagement_id: impl Into<String>,
64        entity_code: impl Into<String>,
65        scope_areas: Vec<String>,
66        materiality: Decimal,
67    ) -> Self {
68        Self {
69            id: id.into(),
70            engagement_id: engagement_id.into(),
71            entity_code: entity_code.into(),
72            scope_areas,
73            materiality,
74        }
75    }
76}