use actix_http::StatusCode;
use chrono::Days;
use uuid::Uuid;
use crate::{
config::data::SharedPool,
error::ServiceError,
model::{
dto::{
areas::{AreaDto, AreaKind, AreaSearchParameters, NewAreaDto, UpdateAreaDto},
areas_impl::{
from_new_area_dto_to_hydrology, from_new_area_dto_to_shading,
from_new_area_dto_to_soil_texture, from_update_area_dto_to_update_hydrology,
from_update_area_dto_to_update_shading,
from_update_area_dto_to_update_soil_texture,
},
core::TimelinePage,
},
entity::{
areas::{Hydrology, Shading, SoilTexture},
areas_impl::{
create_hydrologies, create_shadings, create_soil_textures, delete_areas_by_ids,
find_area, update_hydrologies, update_shadings, update_soil_textures,
FindAreaParameters,
},
},
},
};
pub const TIME_LINE_LOADING_OFFSET_DAYS: u64 = 356;
pub async fn find(
search_parameters: AreaSearchParameters,
pool: &SharedPool,
) -> Result<TimelinePage<AreaDto>, ServiceError> {
let mut conn = pool.get().await?;
let from = search_parameters
.relative_to_date
.checked_sub_days(Days::new(TIME_LINE_LOADING_OFFSET_DAYS))
.ok_or_else(|| {
ServiceError::new(
StatusCode::BAD_REQUEST,
"Could not add days to relative_to_date",
)
})?;
let to = search_parameters
.relative_to_date
.checked_add_days(Days::new(TIME_LINE_LOADING_OFFSET_DAYS))
.ok_or_else(|| {
ServiceError::new(
StatusCode::BAD_REQUEST,
"Could not add days to relative_to_date",
)
})?;
let search_parameters = FindAreaParameters {
area_kind: search_parameters.kind,
layer_id: search_parameters.layer_id,
from,
to,
};
let result: Vec<_> = find_area(search_parameters, &mut conn).await?;
Ok(TimelinePage {
results: result,
from,
to,
})
}
pub async fn create(
area_kind: AreaKind,
dtos: Vec<NewAreaDto>,
pool: &SharedPool,
) -> Result<Vec<AreaDto>, ServiceError> {
let mut conn = pool.get().await?;
let result = match area_kind {
AreaKind::Shade => {
let new_shadings: Vec<Shading> = from_new_area_dto_to_shading(dtos)?;
create_shadings(new_shadings, &mut conn).await?
}
AreaKind::Hydrology => {
let new_hydrologies: Vec<Hydrology> = from_new_area_dto_to_hydrology(dtos)?;
create_hydrologies(new_hydrologies, &mut conn).await?
}
AreaKind::SoilTexture => {
let new_soil_textures: Vec<SoilTexture> = from_new_area_dto_to_soil_texture(dtos)?;
create_soil_textures(new_soil_textures, &mut conn).await?
}
};
Ok(result)
}
pub async fn update(
area_kind: AreaKind,
dto: UpdateAreaDto,
pool: &SharedPool,
) -> Result<Vec<AreaDto>, ServiceError> {
let mut conn = pool.get().await?;
let result = match area_kind {
AreaKind::Shade => {
let updates = from_update_area_dto_to_update_shading(dto)?;
update_shadings(updates, &mut conn).await?
}
AreaKind::Hydrology => {
let updates = from_update_area_dto_to_update_hydrology(dto)?;
update_hydrologies(updates, &mut conn).await?
}
AreaKind::SoilTexture => {
let updates = from_update_area_dto_to_update_soil_texture(dto)?;
update_soil_textures(updates, &mut conn).await?
}
};
Ok(result)
}
pub async fn delete_by_ids(
area_kind: AreaKind,
dtos: Vec<Uuid>,
pool: &SharedPool,
) -> Result<(), ServiceError> {
let mut conn = pool.get().await?;
delete_areas_by_ids(area_kind, dtos, &mut conn).await?;
Ok(())
}