koprogo_api/application/dto/
acp_dto.rs1use serde::{Deserialize, Serialize};
7use validator::Validate;
8
9#[derive(Debug, Clone, Serialize, Deserialize, Validate, utoipa::ToSchema)]
18pub struct CreateAcpDto {
19 pub organization_id: Option<String>,
20
21 #[validate(length(
22 min = 2,
23 max = 160,
24 message = "Name must be between 2 and 160 characters"
25 ))]
26 pub name: String,
27
28 #[validate(length(min = 1, message = "address_street cannot be empty"))]
29 pub address_street: String,
30
31 #[validate(length(min = 1, message = "address_postal_code cannot be empty"))]
32 pub address_postal_code: String,
33
34 #[validate(length(min = 1, message = "address_city cannot be empty"))]
35 pub address_city: String,
36
37 #[validate(length(max = 20, message = "bce_number too long"))]
38 pub bce_number: Option<String>,
39
40 #[validate(range(min = 1, message = "total_tantiemes must be > 0"))]
43 pub total_tantiemes: Option<i32>,
44}
45
46#[derive(Debug, Clone, Serialize, Deserialize, Validate, utoipa::ToSchema)]
49pub struct UpdateAcpDto {
50 #[serde(default, skip_serializing_if = "Option::is_none")]
54 pub organization_id: Option<Option<String>>,
55
56 #[validate(length(
57 min = 2,
58 max = 160,
59 message = "Name must be between 2 and 160 characters"
60 ))]
61 pub name: String,
62
63 #[validate(length(min = 1, message = "address_street cannot be empty"))]
64 pub address_street: String,
65
66 #[validate(length(min = 1, message = "address_postal_code cannot be empty"))]
67 pub address_postal_code: String,
68
69 #[validate(length(min = 1, message = "address_city cannot be empty"))]
70 pub address_city: String,
71
72 #[validate(length(max = 20, message = "bce_number too long"))]
73 pub bce_number: Option<String>,
74
75 #[validate(range(min = 1, message = "total_tantiemes must be > 0"))]
77 pub total_tantiemes: Option<i32>,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
85pub struct AcpResponseDto {
86 pub id: String,
87 pub organization_id: Option<String>,
88 pub name: String,
89 pub slug: String,
90 pub legal_status: String,
91 pub total_tantiemes: i32,
92 pub bce_number: Option<String>,
93 pub address_street: String,
94 pub address_postal_code: String,
95 pub address_city: String,
96 pub created_at: String,
97 pub updated_at: String,
98}
99
100#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
120pub struct AcpAvecMetriquesDto {
121 #[serde(flatten)]
122 pub acp: AcpResponseDto,
123 pub buildings_count: i32,
125 pub units_count: i32,
127 pub declared_units_total: i32,
129 pub quota_sum: String,
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use validator::Validate;
141
142 #[test]
143 fn happy_valid_create_dto_passes_validation() {
144 let dto = CreateAcpDto {
145 organization_id: Some(uuid::Uuid::new_v4().to_string()),
146 name: "Acp Test".to_string(),
147 address_street: "Rue X 1".to_string(),
148 address_postal_code: "1000".to_string(),
149 address_city: "Bruxelles".to_string(),
150 bce_number: None,
151 total_tantiemes: None,
152 };
153 assert!(dto.validate().is_ok());
154 }
155
156 #[test]
157 fn negative_too_short_name_fails_validation() {
158 let dto = CreateAcpDto {
159 organization_id: None,
160 name: "A".to_string(),
161 address_street: "Rue X 1".to_string(),
162 address_postal_code: "1000".to_string(),
163 address_city: "Bruxelles".to_string(),
164 bce_number: None,
165 total_tantiemes: None,
166 };
167 assert!(dto.validate().is_err());
168 }
169
170 #[test]
171 fn negative_empty_street_fails_validation() {
172 let dto = CreateAcpDto {
173 organization_id: None,
174 name: "Acp Test".to_string(),
175 address_street: "".to_string(),
176 address_postal_code: "1000".to_string(),
177 address_city: "Bruxelles".to_string(),
178 bce_number: None,
179 total_tantiemes: None,
180 };
181 assert!(dto.validate().is_err());
182 }
183}