Skip to main content

datasynth_generators/industry/
factory.rs

1//! Industry-specific generator factory.
2//!
3//! Dispatches to the appropriate industry transaction generator based on the
4//! configured industry sector and returns the GL accounts specific to that
5//! industry vertical.
6
7use super::common::IndustryGlAccount;
8use datasynth_core::models::IndustrySector;
9use serde::{Deserialize, Serialize};
10
11/// Industry generation output.
12#[derive(Debug, Clone, Default, Serialize, Deserialize)]
13pub struct IndustryOutput {
14    /// Industry-specific GL accounts.
15    pub gl_accounts: Vec<IndustryGlAccount>,
16    /// The industry sector that was used.
17    pub industry: String,
18}
19
20/// Generate industry-specific data based on the configured industry sector.
21///
22/// Currently returns GL accounts for retail, manufacturing, and healthcare.
23/// Other industry sectors return an empty account list.
24pub fn generate_industry_output(sector: IndustrySector) -> IndustryOutput {
25    let gl_accounts = match sector {
26        IndustrySector::Retail => super::RetailTransactionGenerator::gl_accounts(),
27        IndustrySector::Manufacturing => super::ManufacturingTransactionGenerator::gl_accounts(),
28        IndustrySector::Healthcare => super::HealthcareTransactionGenerator::gl_accounts(),
29        _ => Vec::new(),
30    };
31
32    IndustryOutput {
33        gl_accounts,
34        industry: format!("{sector:?}"),
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41
42    #[test]
43    fn test_retail_factory() {
44        let output = generate_industry_output(IndustrySector::Retail);
45        assert_eq!(output.industry, "Retail");
46        assert!(!output.gl_accounts.is_empty());
47        assert!(output.gl_accounts.len() >= 10);
48        // Verify a known retail account exists
49        assert!(output
50            .gl_accounts
51            .iter()
52            .any(|a| a.account_number == "1400"));
53    }
54
55    #[test]
56    fn test_manufacturing_factory() {
57        let output = generate_industry_output(IndustrySector::Manufacturing);
58        assert_eq!(output.industry, "Manufacturing");
59        assert!(!output.gl_accounts.is_empty());
60        assert!(output.gl_accounts.len() >= 10);
61        // Verify WIP account exists
62        assert!(output
63            .gl_accounts
64            .iter()
65            .any(|a| a.account_number == "1400" && a.name.contains("Work in Process")));
66    }
67
68    #[test]
69    fn test_healthcare_factory() {
70        let output = generate_industry_output(IndustrySector::Healthcare);
71        assert_eq!(output.industry, "Healthcare");
72        assert!(!output.gl_accounts.is_empty());
73        assert!(output.gl_accounts.len() >= 10);
74        // Verify patient AR account exists
75        assert!(output
76            .gl_accounts
77            .iter()
78            .any(|a| a.account_number == "1200"));
79    }
80
81    #[test]
82    fn test_unsupported_industry_returns_empty() {
83        let output = generate_industry_output(IndustrySector::Technology);
84        assert_eq!(output.industry, "Technology");
85        assert!(output.gl_accounts.is_empty());
86    }
87
88    #[test]
89    fn test_output_serializable() {
90        let output = generate_industry_output(IndustrySector::Retail);
91        let json = serde_json::to_string(&output).expect("should serialize");
92        assert!(json.contains("Retail"));
93        assert!(json.contains("gl_accounts"));
94    }
95}