koprogo_api/domain/entities/
building.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5#[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}