1use actix_web::http::StatusCode;
2use chrono::Utc;
3use uuid::Uuid;
4
5use crate::{
6 error::ServiceError,
7 model::{
8 dto::areas::{AreaDto, AreaKind, AreaType, AreaUpdate, NewAreaDto, UpdateAreaDto},
9 entity::areas::{
10 Hydrology, Shading, SoilTexture, UpdateHydrology, UpdateShading, UpdateSoilTexture,
11 },
12 },
13};
14
15impl From<Shading> for AreaDto {
18 fn from(entity: Shading) -> Self {
19 Self {
20 id: entity.id,
21 layer_id: entity.layer_id,
22 area_type: AreaType::Shade(entity.shade),
23 geometry: entity.geometry,
24 add_date: entity.add_date,
25 remove_date: entity.remove_date,
26 notes: entity.notes,
27 }
28 }
29}
30
31impl From<Hydrology> for AreaDto {
32 fn from(entity: Hydrology) -> Self {
33 Self {
34 id: entity.id,
35 layer_id: entity.layer_id,
36 area_type: AreaType::Hydrology(entity.water_requirement),
37 geometry: entity.geometry,
38 add_date: entity.add_date,
39 remove_date: entity.remove_date,
40 notes: entity.notes,
41 }
42 }
43}
44
45impl From<SoilTexture> for AreaDto {
46 fn from(entity: SoilTexture) -> Self {
47 Self {
48 id: entity.id,
49 layer_id: entity.layer_id,
50 area_type: AreaType::SoilTexture(entity.soil_texture),
51 geometry: entity.geometry,
52 add_date: entity.add_date,
53 remove_date: entity.remove_date,
54 notes: entity.notes,
55 }
56 }
57}
58
59const INVALID_AREA_TYPE: &str = "invalid area type";
61
62pub fn from_new_area_dto_to_shading(
68 dtos: Vec<NewAreaDto>,
69 user_id: Uuid,
70) -> Result<Vec<Shading>, ServiceError> {
71 dtos.into_iter()
72 .map(|dto| match dto.area_type {
73 AreaType::Shade(shade) => Ok(Shading {
74 id: dto.id,
75 layer_id: dto.layer_id,
76 shade,
77 geometry: dto.geometry,
78 add_date: dto.add_date,
79 remove_date: None,
80 notes: String::new(),
81 created_at: Utc::now().naive_utc(),
82 modified_at: Utc::now().naive_utc(),
83 created_by: user_id,
84 modified_by: user_id,
85 }),
86 _ => Err(ServiceError::new(
87 StatusCode::BAD_REQUEST,
88 INVALID_AREA_TYPE,
89 )),
90 })
91 .collect()
92}
93
94pub fn from_new_area_dto_to_hydrology(
100 dtos: Vec<NewAreaDto>,
101 user_id: Uuid,
102) -> Result<Vec<Hydrology>, ServiceError> {
103 dtos.into_iter()
104 .map(|dto| match dto.area_type {
105 AreaType::Hydrology(water_requirement) => Ok(Hydrology {
106 id: dto.id,
107 layer_id: dto.layer_id,
108 water_requirement,
109 geometry: dto.geometry,
110 add_date: dto.add_date,
111 remove_date: None,
112 notes: String::new(),
113 created_at: Utc::now().naive_utc(),
114 modified_at: Utc::now().naive_utc(),
115 created_by: user_id,
116 modified_by: user_id,
117 }),
118 _ => Err(ServiceError::new(
119 StatusCode::BAD_REQUEST,
120 INVALID_AREA_TYPE,
121 )),
122 })
123 .collect()
124}
125
126pub fn from_new_area_dto_to_soil_texture(
132 dtos: Vec<NewAreaDto>,
133 user_id: Uuid,
134) -> Result<Vec<SoilTexture>, ServiceError> {
135 dtos.into_iter()
136 .map(|dto| match dto.area_type {
137 AreaType::SoilTexture(soil_texture) => Ok(SoilTexture {
138 id: dto.id,
139 layer_id: dto.layer_id,
140 soil_texture,
141 geometry: dto.geometry,
142 add_date: dto.add_date,
143 remove_date: None,
144 notes: String::new(),
145 created_at: Utc::now().naive_utc(),
146 modified_at: Utc::now().naive_utc(),
147 created_by: user_id,
148 modified_by: user_id,
149 }),
150 _ => Err(ServiceError::new(
151 StatusCode::BAD_REQUEST,
152 INVALID_AREA_TYPE,
153 )),
154 })
155 .collect()
156}
157
158pub fn from_update_area_dto_to_update_shading(
164 dto: UpdateAreaDto,
165 user_id: Uuid,
166) -> Result<Vec<UpdateShading>, ServiceError> {
167 if dto.area_kind == AreaKind::Shade {
168 match dto.update {
169 AreaUpdate::UpdateValue(geometry_vec) => Ok(geometry_vec
170 .into_iter()
171 .map(|v| UpdateShading {
172 id: v.id,
173 shade: match v.area_type {
174 AreaType::Shade(shade) => Some(shade),
175 _ => None,
176 },
177 modified_by: user_id,
178 ..Default::default()
179 })
180 .collect()),
181 AreaUpdate::UpdateAddDate(add_date_vec) => Ok(add_date_vec
182 .into_iter()
183 .map(|v| UpdateShading {
184 id: v.id,
185 add_date: Some(v.add_date),
186 modified_by: user_id,
187 ..Default::default()
188 })
189 .collect()),
190 AreaUpdate::UpdateRemoveDate(remove_date_vec) => Ok(remove_date_vec
191 .into_iter()
192 .map(|v| UpdateShading {
193 id: v.id,
194 remove_date: Some(v.remove_date),
195 modified_by: user_id,
196 ..Default::default()
197 })
198 .collect()),
199 AreaUpdate::UpdateNotes(notes_vec) => Ok(notes_vec
200 .into_iter()
201 .map(|v| UpdateShading {
202 id: v.id,
203 notes: Some(v.notes),
204 modified_by: user_id,
205 ..Default::default()
206 })
207 .collect()),
208 }
209 } else {
210 Err(ServiceError::new(
211 StatusCode::BAD_REQUEST,
212 INVALID_AREA_TYPE,
213 ))
214 }
215}
216
217pub fn from_update_area_dto_to_update_hydrology(
223 dto: UpdateAreaDto,
224 user_id: Uuid,
225) -> Result<Vec<UpdateHydrology>, ServiceError> {
226 if dto.area_kind == AreaKind::Hydrology {
227 match dto.update {
228 AreaUpdate::UpdateValue(geometry_vec) => Ok(geometry_vec
229 .into_iter()
230 .map(|v| UpdateHydrology {
231 id: v.id,
232 water_requirement: match v.area_type {
233 AreaType::Hydrology(water_requirement) => Some(water_requirement),
234 _ => None,
235 },
236 modified_by: user_id,
237 ..Default::default()
238 })
239 .collect()),
240 AreaUpdate::UpdateAddDate(add_date_vec) => Ok(add_date_vec
241 .into_iter()
242 .map(|v| UpdateHydrology {
243 id: v.id,
244 add_date: Some(v.add_date),
245 modified_by: user_id,
246 ..Default::default()
247 })
248 .collect()),
249 AreaUpdate::UpdateRemoveDate(remove_date_vec) => Ok(remove_date_vec
250 .into_iter()
251 .map(|v| UpdateHydrology {
252 id: v.id,
253 remove_date: Some(v.remove_date),
254 modified_by: user_id,
255 ..Default::default()
256 })
257 .collect()),
258 AreaUpdate::UpdateNotes(notes_vec) => Ok(notes_vec
259 .into_iter()
260 .map(|v| UpdateHydrology {
261 id: v.id,
262 notes: Some(v.notes),
263 modified_by: user_id,
264 ..Default::default()
265 })
266 .collect()),
267 }
268 } else {
269 Err(ServiceError::new(
270 StatusCode::BAD_REQUEST,
271 INVALID_AREA_TYPE,
272 ))
273 }
274}
275
276pub fn from_update_area_dto_to_update_soil_texture(
282 dto: UpdateAreaDto,
283 user_id: Uuid,
284) -> Result<Vec<UpdateSoilTexture>, ServiceError> {
285 if dto.area_kind == AreaKind::SoilTexture {
286 match dto.update {
287 AreaUpdate::UpdateValue(geometry_vec) => Ok(geometry_vec
288 .into_iter()
289 .map(|v| UpdateSoilTexture {
290 id: v.id,
291 soil_texture: match v.area_type {
292 AreaType::SoilTexture(soil_texture) => Some(soil_texture),
293 _ => None,
294 },
295 modified_by: user_id,
296 ..Default::default()
297 })
298 .collect()),
299 AreaUpdate::UpdateAddDate(add_date_vec) => Ok(add_date_vec
300 .into_iter()
301 .map(|v| UpdateSoilTexture {
302 id: v.id,
303 add_date: Some(v.add_date),
304 modified_by: user_id,
305 ..Default::default()
306 })
307 .collect()),
308 AreaUpdate::UpdateRemoveDate(remove_date_vec) => Ok(remove_date_vec
309 .into_iter()
310 .map(|v| UpdateSoilTexture {
311 id: v.id,
312 remove_date: Some(v.remove_date),
313 modified_by: user_id,
314 ..Default::default()
315 })
316 .collect()),
317 AreaUpdate::UpdateNotes(notes_vec) => Ok(notes_vec
318 .into_iter()
319 .map(|v| UpdateSoilTexture {
320 id: v.id,
321 notes: Some(v.notes),
322 ..Default::default()
323 })
324 .collect()),
325 }
326 } else {
327 Err(ServiceError::new(
328 StatusCode::BAD_REQUEST,
329 INVALID_AREA_TYPE,
330 ))
331 }
332}