use crate::db::{Model, Storable, DbError, DbResult}; use super::shareholder::Shareholder; // Use super:: for sibling module use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::fmt::Debug; /// CompanyStatus represents the status of a company #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum CompanyStatus { Active, Inactive, Suspended, } /// BusinessType represents the type of a business #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct BusinessType(pub String); impl BusinessType { pub const CORPORATION: &'static str = "Corporation"; pub const PARTNERSHIP: &'static str = "Partnership"; pub const LLC: &'static str = "LLC"; pub const COOP: &'static str = "Coop"; pub const SINGLE: &'static str = "Single"; pub const TWIN: &'static str = "Twin"; pub const STARTER: &'static str = "Starter"; pub const GLOBAL: &'static str = "Global"; /// Create a new BusinessType, validating that the type is one of the predefined types pub fn new(type_str: String) -> Result { if Self::is_valid(&type_str) { Ok(BusinessType(type_str)) } else { Err(format!("Invalid business type: {}. Valid types are: {}", type_str, Self::valid_types().join(", "))) } } /// Create a new BusinessType without validation (use with caution) pub fn new_unchecked(type_str: String) -> Self { BusinessType(type_str) } /// Get the string value of the business type pub fn as_str(&self) -> &str { &self.0 } /// Check if a string is a valid business type pub fn is_valid(type_str: &str) -> bool { Self::valid_types().contains(&type_str.to_string()) } /// Get a list of all valid business types pub fn valid_types() -> Vec { vec![ Self::CORPORATION.to_string(), Self::PARTNERSHIP.to_string(), Self::LLC.to_string(), Self::COOP.to_string(), Self::SINGLE.to_string(), Self::TWIN.to_string(), Self::STARTER.to_string(), Self::GLOBAL.to_string(), ] } } /// Company represents a company entity #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] // Added PartialEq pub struct Company { pub id: u32, pub name: String, pub registration_number: String, pub incorporation_date: DateTime, pub fiscal_year_end: String, pub email: String, pub phone: String, pub website: String, pub address: String, pub business_type: BusinessType, pub industry: String, pub description: String, pub status: CompanyStatus, pub created_at: DateTime, pub updated_at: DateTime, // Removed shareholders property } // Model requires get_id and db_prefix impl Model for Company { fn get_id(&self) -> u32 { self.id } fn db_prefix() -> &'static str { "company" // Prefix for company records in the database } } impl Company { /// Create a new company with default timestamps pub fn new( id: u32, name: String, registration_number: String, incorporation_date: DateTime, fiscal_year_end: String, email: String, phone: String, website: String, address: String, business_type: BusinessType, industry: String, description: String, status: CompanyStatus, ) -> Self { let now = Utc::now(); Self { id, name, registration_number, incorporation_date, fiscal_year_end, email, phone, website, address, business_type, industry, description, status, created_at: now, updated_at: now, } } /// Add a shareholder to the company, saving it to the database pub fn add_shareholder( &mut self, db: &mut DB, // Pass in the DB instance mut shareholder: Shareholder, ) -> DbResult<()> { shareholder.company_id = self.id; // Set the company_id db.set(&shareholder)?; // Insert the shareholder into the DB self.updated_at = Utc::now(); Ok(()) } /// Link this company to a Circle for access control pub fn link_to_circle(&mut self, circle_id: u32) -> DbResult<()> { // Implementation would involve updating a mapping in a separate database // For now, we'll just update the timestamp to indicate the change self.updated_at = Utc::now(); Ok(()) } /// Link this company to a Customer in the biz module pub fn link_to_customer(&mut self, customer_id: u32) -> DbResult<()> { // Implementation would involve updating a mapping in a separate database // For now, we'll just update the timestamp to indicate the change self.updated_at = Utc::now(); Ok(()) } /// Get all resolutions for this company pub fn get_resolutions(&self, db: &DB) -> DbResult> { let all_resolutions = db.list::()?; let company_resolutions = all_resolutions .into_iter() .filter(|resolution| resolution.company_id == self.id) .collect(); Ok(company_resolutions) } // Future methods: // /// Get all committees for this company // pub fn get_committees(&self, db: &DB) -> DbResult> { ... } // // /// Get all compliance requirements for this company // pub fn get_compliance_requirements(&self, db: &DB) -> DbResult> { ... } }