1use actix_http::StatusCode;
4use chrono::Days;
5use uuid::Uuid;
6
7use crate::{
8 config::data::SharedPool,
9 error::ServiceError,
10 model::{
11 dto::{
12 areas::{AreaDto, AreaKind, AreaSearchParameters, NewAreaDto, UpdateAreaDto},
13 areas_impl::{
14 from_new_area_dto_to_hydrology, from_new_area_dto_to_shading,
15 from_new_area_dto_to_soil_texture, from_update_area_dto_to_update_hydrology,
16 from_update_area_dto_to_update_shading,
17 from_update_area_dto_to_update_soil_texture,
18 },
19 core::TimelinePage,
20 },
21 entity::{
22 areas::{Hydrology, Shading, SoilTexture},
23 areas_impl::{
24 create_hydrologies, create_shadings, create_soil_textures, delete_areas_by_ids,
25 find_area, update_hydrologies, update_shadings, update_soil_textures,
26 FindAreaParameters,
27 },
28 },
29 },
30};
31
32pub const TIME_LINE_LOADING_OFFSET_DAYS: u64 = 356;
34
35pub async fn find(
40 search_parameters: AreaSearchParameters,
41 pool: &SharedPool,
42) -> Result<TimelinePage<AreaDto>, ServiceError> {
43 let mut conn = pool.get().await?;
44
45 let from = search_parameters
46 .relative_to_date
47 .checked_sub_days(Days::new(TIME_LINE_LOADING_OFFSET_DAYS))
48 .ok_or_else(|| {
49 ServiceError::new(
50 StatusCode::BAD_REQUEST,
51 "Could not add days to relative_to_date",
52 )
53 })?;
54
55 let to = search_parameters
56 .relative_to_date
57 .checked_add_days(Days::new(TIME_LINE_LOADING_OFFSET_DAYS))
58 .ok_or_else(|| {
59 ServiceError::new(
60 StatusCode::BAD_REQUEST,
61 "Could not add days to relative_to_date",
62 )
63 })?;
64
65 let search_parameters = FindAreaParameters {
66 area_kind: search_parameters.kind,
67 layer_id: search_parameters.layer_id,
68 from,
69 to,
70 };
71 let result: Vec<_> = find_area(search_parameters, &mut conn).await?;
72
73 Ok(TimelinePage {
74 results: result,
75 from,
76 to,
77 })
78}
79
80pub async fn create(
85 area_kind: AreaKind,
86 dtos: Vec<NewAreaDto>,
87 pool: &SharedPool,
88 user_id: Uuid,
89) -> Result<Vec<AreaDto>, ServiceError> {
90 let mut conn = pool.get().await?;
91
92 let result = match area_kind {
93 AreaKind::Shade => {
94 let new_shadings: Vec<Shading> = from_new_area_dto_to_shading(dtos, user_id)?;
95 create_shadings(new_shadings, &mut conn).await?
96 }
97 AreaKind::Hydrology => {
98 let new_hydrologies: Vec<Hydrology> = from_new_area_dto_to_hydrology(dtos, user_id)?;
99 create_hydrologies(new_hydrologies, &mut conn).await?
100 }
101 AreaKind::SoilTexture => {
102 let new_soil_textures: Vec<SoilTexture> =
103 from_new_area_dto_to_soil_texture(dtos, user_id)?;
104 create_soil_textures(new_soil_textures, &mut conn).await?
105 }
106 };
107 Ok(result)
108}
109
110pub async fn update(
115 area_kind: AreaKind,
116 dto: UpdateAreaDto,
117 pool: &SharedPool,
118 user_id: Uuid,
119) -> Result<Vec<AreaDto>, ServiceError> {
120 let mut conn = pool.get().await?;
121
122 let result = match area_kind {
123 AreaKind::Shade => {
124 let updates = from_update_area_dto_to_update_shading(dto, user_id)?;
125 update_shadings(updates, &mut conn).await?
126 }
127 AreaKind::Hydrology => {
128 let updates = from_update_area_dto_to_update_hydrology(dto, user_id)?;
129 update_hydrologies(updates, &mut conn).await?
130 }
131 AreaKind::SoilTexture => {
132 let updates = from_update_area_dto_to_update_soil_texture(dto, user_id)?;
133 update_soil_textures(updates, &mut conn).await?
134 }
135 };
136
137 Ok(result)
138}
139
140pub async fn delete_by_ids(
145 area_kind: AreaKind,
146 dtos: Vec<Uuid>,
147 pool: &SharedPool,
148) -> Result<(), ServiceError> {
149 let mut conn = pool.get().await?;
150 delete_areas_by_ids(area_kind, dtos, &mut conn).await?;
151 Ok(())
152}