koprogo_api/domain/entities/
owner.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5/// Représente un copropriétaire
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7pub struct Owner {
8    pub id: Uuid,
9    pub organization_id: Uuid,
10    pub first_name: String,
11    pub last_name: String,
12    pub email: String,
13    pub phone: Option<String>,
14    pub address: String,
15    pub city: String,
16    pub postal_code: String,
17    pub country: String,
18    pub created_at: DateTime<Utc>,
19    pub updated_at: DateTime<Utc>,
20}
21
22impl Owner {
23    #[allow(clippy::too_many_arguments)]
24    pub fn new(
25        organization_id: Uuid,
26        first_name: String,
27        last_name: String,
28        email: String,
29        phone: Option<String>,
30        address: String,
31        city: String,
32        postal_code: String,
33        country: String,
34    ) -> Result<Self, String> {
35        if first_name.is_empty() {
36            return Err("First name cannot be empty".to_string());
37        }
38        if last_name.is_empty() {
39            return Err("Last name cannot be empty".to_string());
40        }
41        if !Self::is_valid_email(&email) {
42            return Err("Invalid email format".to_string());
43        }
44
45        let now = Utc::now();
46        Ok(Self {
47            id: Uuid::new_v4(),
48            organization_id,
49            first_name,
50            last_name,
51            email,
52            phone,
53            address,
54            city,
55            postal_code,
56            country,
57            created_at: now,
58            updated_at: now,
59        })
60    }
61
62    fn is_valid_email(email: &str) -> bool {
63        email.contains('@') && email.contains('.')
64    }
65
66    pub fn full_name(&self) -> String {
67        format!("{} {}", self.first_name, self.last_name)
68    }
69
70    pub fn update_contact(&mut self, email: String, phone: Option<String>) -> Result<(), String> {
71        if !Self::is_valid_email(&email) {
72            return Err("Invalid email format".to_string());
73        }
74        self.email = email;
75        self.phone = phone;
76        self.updated_at = Utc::now();
77        Ok(())
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::*;
84
85    #[test]
86    fn test_create_owner_success() {
87        let org_id = Uuid::new_v4();
88        let owner = Owner::new(
89            org_id,
90            "Jean".to_string(),
91            "Dupont".to_string(),
92            "jean.dupont@example.com".to_string(),
93            Some("+33612345678".to_string()),
94            "123 Rue de la Paix".to_string(),
95            "Paris".to_string(),
96            "75001".to_string(),
97            "France".to_string(),
98        );
99
100        assert!(owner.is_ok());
101        let owner = owner.unwrap();
102        assert_eq!(owner.organization_id, org_id);
103        assert_eq!(owner.full_name(), "Jean Dupont");
104    }
105
106    #[test]
107    fn test_create_owner_invalid_email_fails() {
108        let org_id = Uuid::new_v4();
109        let owner = Owner::new(
110            org_id,
111            "Jean".to_string(),
112            "Dupont".to_string(),
113            "invalid-email".to_string(),
114            None,
115            "123 Rue de la Paix".to_string(),
116            "Paris".to_string(),
117            "75001".to_string(),
118            "France".to_string(),
119        );
120
121        assert!(owner.is_err());
122        assert_eq!(owner.unwrap_err(), "Invalid email format");
123    }
124
125    #[test]
126    fn test_update_contact() {
127        let org_id = Uuid::new_v4();
128        let mut owner = Owner::new(
129            org_id,
130            "Jean".to_string(),
131            "Dupont".to_string(),
132            "jean.dupont@example.com".to_string(),
133            None,
134            "123 Rue de la Paix".to_string(),
135            "Paris".to_string(),
136            "75001".to_string(),
137            "France".to_string(),
138        )
139        .unwrap();
140
141        let result = owner.update_contact(
142            "new.email@example.com".to_string(),
143            Some("+33699999999".to_string()),
144        );
145
146        assert!(result.is_ok());
147        assert_eq!(owner.email, "new.email@example.com");
148    }
149}