koprogo_api/domain/entities/
building.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5/// Représente un immeuble en copropriété
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
7pub struct Building {
8    pub id: Uuid,
9    pub organization_id: Uuid,
10    pub name: String,
11    pub address: String,
12    pub city: String,
13    pub postal_code: String,
14    pub country: String,
15    pub total_units: i32,
16    pub construction_year: Option<i32>,
17    pub created_at: DateTime<Utc>,
18    pub updated_at: DateTime<Utc>,
19}
20
21impl Building {
22    #[allow(clippy::too_many_arguments)]
23    pub fn new(
24        organization_id: Uuid,
25        name: String,
26        address: String,
27        city: String,
28        postal_code: String,
29        country: String,
30        total_units: i32,
31        construction_year: Option<i32>,
32    ) -> Result<Self, String> {
33        if name.is_empty() {
34            return Err("Building name cannot be empty".to_string());
35        }
36        if total_units <= 0 {
37            return Err("Total units must be greater than 0".to_string());
38        }
39
40        let now = Utc::now();
41        Ok(Self {
42            id: Uuid::new_v4(),
43            organization_id,
44            name,
45            address,
46            city,
47            postal_code,
48            country,
49            total_units,
50            construction_year,
51            created_at: now,
52            updated_at: now,
53        })
54    }
55
56    pub fn update_info(
57        &mut self,
58        name: String,
59        address: String,
60        city: String,
61        postal_code: String,
62    ) {
63        self.name = name;
64        self.address = address;
65        self.city = city;
66        self.postal_code = postal_code;
67        self.updated_at = Utc::now();
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn test_create_building_success() {
77        let org_id = Uuid::new_v4();
78        let building = Building::new(
79            org_id,
80            "Résidence Les Jardins".to_string(),
81            "123 Rue de la Paix".to_string(),
82            "Paris".to_string(),
83            "75001".to_string(),
84            "France".to_string(),
85            50,
86            Some(1985),
87        );
88
89        assert!(building.is_ok());
90        let building = building.unwrap();
91        assert_eq!(building.organization_id, org_id);
92        assert_eq!(building.name, "Résidence Les Jardins");
93        assert_eq!(building.total_units, 50);
94    }
95
96    #[test]
97    fn test_create_building_empty_name_fails() {
98        let org_id = Uuid::new_v4();
99        let building = Building::new(
100            org_id,
101            "".to_string(),
102            "123 Rue de la Paix".to_string(),
103            "Paris".to_string(),
104            "75001".to_string(),
105            "France".to_string(),
106            50,
107            Some(1985),
108        );
109
110        assert!(building.is_err());
111        assert_eq!(building.unwrap_err(), "Building name cannot be empty");
112    }
113
114    #[test]
115    fn test_create_building_zero_units_fails() {
116        let org_id = Uuid::new_v4();
117        let building = Building::new(
118            org_id,
119            "Résidence Les Jardins".to_string(),
120            "123 Rue de la Paix".to_string(),
121            "Paris".to_string(),
122            "75001".to_string(),
123            "France".to_string(),
124            0,
125            Some(1985),
126        );
127
128        assert!(building.is_err());
129        assert_eq!(building.unwrap_err(), "Total units must be greater than 0");
130    }
131
132    #[test]
133    fn test_update_building_info() {
134        let org_id = Uuid::new_v4();
135        let mut building = Building::new(
136            org_id,
137            "Old Name".to_string(),
138            "Old Address".to_string(),
139            "Old City".to_string(),
140            "00000".to_string(),
141            "France".to_string(),
142            10,
143            None,
144        )
145        .unwrap();
146
147        let old_updated_at = building.updated_at;
148
149        building.update_info(
150            "New Name".to_string(),
151            "New Address".to_string(),
152            "New City".to_string(),
153            "11111".to_string(),
154        );
155
156        assert_eq!(building.name, "New Name");
157        assert_eq!(building.address, "New Address");
158        assert!(building.updated_at > old_updated_at);
159    }
160}