Skip to content
This repository has been archived by the owner on Apr 24, 2024. It is now read-only.

Commit

Permalink
Set remove_date when creating plantings according to its life_cycle.
Browse files Browse the repository at this point in the history
  • Loading branch information
horenso committed Apr 22, 2024
1 parent 41a5b15 commit 236d5c0
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 3 deletions.
48 changes: 46 additions & 2 deletions backend/src/model/entity/plantings_impl.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Contains the implementation of [`Planting`].
use chrono::NaiveDate;
use chrono::{Duration, NaiveDate};
use diesel::pg::Pg;
use diesel::{
debug_query, BoolExpressionMethods, ExpressionMethods, NullableExpressionMethods, QueryDsl,
Expand All @@ -15,7 +15,9 @@ use crate::model::dto::plantings::{
DeletePlantingDto, NewPlantingDto, PlantingDto, UpdatePlantingDto,
};
use crate::model::entity::plantings::Planting;
use crate::model::r#enum::life_cycle::LifeCycle;
use crate::schema::plantings::{self, layer_id, plant_id};
use crate::schema::plants;
use crate::schema::seeds;

use super::plantings::UpdatePlanting;
Expand Down Expand Up @@ -94,6 +96,45 @@ impl Planting {
.collect())
}

/// Helper that sets `end_date` according to the `life_cycle`.
async fn set_end_date_according_to_cycle_types(
conn: &mut AsyncPgConnection,
plantings: &mut Vec<Self>,
) -> QueryResult<()> {
/// life cycles are currently persisted as optional lists of optional values
type LifeCycleType = Option<Vec<Option<LifeCycle>>>;

let plant_ids: Vec<i32> = plantings.iter().map(|p| p.plant_id).collect();
let life_cycles_query = plants::table
.filter(plants::id.eq_any(&plant_ids))
.select((plants::id, plants::life_cycle.nullable()));

let life_cycle_lookup = life_cycles_query.load::<(i32, LifeCycleType)>(conn).await?;

for planting in plantings {
if let Some(add_date) = planting.add_date {
let current_plant_id = planting.plant_id;
let life_cycle_info_opt: Option<(i32, LifeCycleType)> = life_cycle_lookup
.iter()
.find_map(|x| (x.0 == current_plant_id).then(|| x.clone()));
if let Some((_, Some(life_cycles))) = life_cycle_info_opt {
let filtered = life_cycles
.iter()
.filter_map(|l| *l)
.collect::<Vec<LifeCycle>>();
if filtered.contains(&LifeCycle::Perennial) {
continue;
} else if filtered.contains(&LifeCycle::Biennial) {
planting.remove_date = Some(add_date + Duration::days(2 * 365));
} else if filtered.contains(&LifeCycle::Annual) {
planting.remove_date = Some(add_date + Duration::days(365));
}
};
};
}
Ok(())
}

/// Create a new planting in the database.
///
/// # Errors
Expand All @@ -103,7 +144,10 @@ impl Planting {
dto_vec: Vec<NewPlantingDto>,
conn: &mut AsyncPgConnection,
) -> QueryResult<Vec<PlantingDto>> {
let planting_creations: Vec<Self> = dto_vec.into_iter().map(Into::into).collect();
let mut planting_creations: Vec<Self> = dto_vec.into_iter().map(Into::into).collect();

Self::set_end_date_according_to_cycle_types(conn, &mut planting_creations).await?;

let query = diesel::insert_into(plantings::table).values(&planting_creations);

debug!("{}", debug_query::<Pg, _>(&query));
Expand Down
2 changes: 1 addition & 1 deletion backend/src/model/enum/life_cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use utoipa::ToSchema;

#[allow(clippy::missing_docs_in_private_items)] // TODO: See #97.
#[typeshare]
#[derive(Serialize, Deserialize, DbEnum, Debug, ToSchema)]
#[derive(Serialize, Deserialize, DbEnum, Debug, PartialEq, Eq, ToSchema, Clone, Copy)]
#[ExistingTypePath = "crate::schema::sql_types::LifeCycle"]
pub enum LifeCycle {
#[serde(rename = "annual")]
Expand Down

0 comments on commit 236d5c0

Please sign in to comment.