diff --git a/src/model/planned_event.rs b/src/model/planned_event.rs index 4d1fdd8..1012cc9 100644 --- a/src/model/planned_event.rs +++ b/src/model/planned_event.rs @@ -1,10 +1,10 @@ use chrono::NaiveDate; use serde::Serialize; -use sqlx::SqlitePool; +use sqlx::{FromRow, SqlitePool}; -use super::tripdetails::TripDetails; +use super::{tripdetails::TripDetails, triptype::TripType}; -#[derive(Serialize, Clone)] +#[derive(Serialize, Clone, FromRow)] pub struct PlannedEvent { pub id: i64, name: String, @@ -15,12 +15,14 @@ pub struct PlannedEvent { max_people: i64, day: String, notes: Option, + trip_type_id: Option, } #[derive(Serialize)] -pub struct PlannedEventWithUser { +pub struct PlannedEventWithUserAndTriptype { #[serde(flatten)] planned_event: PlannedEvent, + trip_type: Option, cox_needed: bool, cox: Vec, rower: Vec, @@ -39,7 +41,8 @@ impl PlannedEvent { sqlx::query_as!( Self, " -SELECT planned_event.id, name, planned_amount_cox, allow_guests, trip_details_id, planned_starting_time, max_people, day, notes +SELECT + planned_event.id, planned_event.name, planned_amount_cox, allow_guests, trip_details_id, planned_starting_time, max_people, day, notes, trip_type_id FROM planned_event INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id WHERE planned_event.id like ? @@ -51,11 +54,14 @@ WHERE planned_event.id like ? .ok() } - pub async fn get_for_day(db: &SqlitePool, day: NaiveDate) -> Vec { + pub async fn get_for_day( + db: &SqlitePool, + day: NaiveDate, + ) -> Vec { let day = format!("{day}"); let events = sqlx::query_as!( PlannedEvent, - "SELECT planned_event.id, name, planned_amount_cox, allow_guests, trip_details_id, planned_starting_time, max_people, day, notes + "SELECT planned_event.id, planned_event.name, planned_amount_cox, allow_guests, trip_details_id, planned_starting_time, max_people, day, notes, trip_type_id FROM planned_event INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id WHERE day=?", @@ -68,11 +74,16 @@ WHERE day=?", let mut ret = Vec::new(); for event in events { let cox = event.get_all_cox(db).await; - ret.push(PlannedEventWithUser { + let mut trip_type = None; + if let Some(trip_type_id) = event.trip_type_id { + trip_type = TripType::find_by_id(db, trip_type_id).await; + } + ret.push(PlannedEventWithUserAndTriptype { planned_event: event.clone(), cox_needed: event.planned_amount_cox > cox.len() as i64, cox, rower: event.get_all_rower(db).await, + trip_type, }); } ret diff --git a/src/model/trip.rs b/src/model/trip.rs index c40bbfa..fb9d8b8 100644 --- a/src/model/trip.rs +++ b/src/model/trip.rs @@ -5,6 +5,7 @@ use sqlx::SqlitePool; use super::{ planned_event::{PlannedEvent, Registration}, tripdetails::TripDetails, + triptype::TripType, user::CoxUser, }; @@ -18,13 +19,15 @@ pub struct Trip { max_people: i64, day: String, notes: Option, + trip_type_id: Option, } #[derive(Serialize)] -pub struct TripWithUser { +pub struct TripWithUserAndType { #[serde(flatten)] trip: Trip, rower: Vec, + trip_type: Option, } impl Trip { @@ -44,7 +47,7 @@ impl Trip { sqlx::query_as!( Self, " -SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes +SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes, trip_type_id FROM trip INNER JOIN trip_details ON trip.trip_details_id = trip_details.id INNER JOIN user ON trip.cox_id = user.id @@ -92,12 +95,12 @@ WHERE trip.id=? } } - pub async fn get_for_day(db: &SqlitePool, day: NaiveDate) -> Vec { + pub async fn get_for_day(db: &SqlitePool, day: NaiveDate) -> Vec { let day = format!("{day}"); let trips = sqlx::query_as!( Trip, " -SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes +SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes, trip_type_id FROM trip INNER JOIN trip_details ON trip.trip_details_id = trip_details.id INNER JOIN user ON trip.cox_id = user.id @@ -110,8 +113,13 @@ WHERE day=? .unwrap(); //TODO: fixme let mut ret = Vec::new(); for trip in trips { - ret.push(TripWithUser { + let mut trip_type = None; + if let Some(trip_type_id) = trip.trip_type_id { + trip_type = TripType::find_by_id(db, trip_type_id).await; + } + ret.push(TripWithUserAndType { trip: trip.clone(), + trip_type, rower: trip.get_all_rower(db).await, }); } diff --git a/src/model/tripdetails.rs b/src/model/tripdetails.rs index 663620d..fcdf28e 100644 --- a/src/model/tripdetails.rs +++ b/src/model/tripdetails.rs @@ -8,6 +8,7 @@ pub struct TripDetails { max_people: i64, day: String, notes: Option, + trip_type_id: Option, } impl TripDetails { @@ -15,7 +16,7 @@ impl TripDetails { sqlx::query_as!( TripDetails, " -SELECT id, planned_starting_time, max_people, day, notes +SELECT id, planned_starting_time, max_people, day, notes, trip_type_id FROM trip_details WHERE id like ? ", @@ -33,13 +34,15 @@ WHERE id like ? max_people: i32, day: String, notes: Option, + trip_type_id: Option, ) -> i64 { let query = sqlx::query!( - "INSERT INTO trip_details(planned_starting_time, max_people, day, notes) VALUES(?, ?, ?, ?)" , + "INSERT INTO trip_details(planned_starting_time, max_people, day, notes, trip_type_id) VALUES(?, ?, ?, ?, ?)" , planned_starting_time, max_people, day, - notes + notes, + trip_type_id ) .execute(db) .await @@ -94,11 +97,11 @@ mod test { let pool = testdb!(); assert_eq!( - TripDetails::create(&pool, "10:00".into(), 2, "1970-01-01".into(), None).await, + TripDetails::create(&pool, "10:00".into(), 2, "1970-01-01".into(), None, None).await, 3, ); assert_eq!( - TripDetails::create(&pool, "10:00".into(), 2, "1970-01-01".into(), None).await, + TripDetails::create(&pool, "10:00".into(), 2, "1970-01-01".into(), None, None).await, 4, ); } @@ -115,4 +118,6 @@ mod test { fn test_true_full() { //TODO: register user for trip_details = 1; check if is_full returns true } + + //TODO: add new tripdetails test with trip_type != None } diff --git a/src/model/triptype.rs b/src/model/triptype.rs new file mode 100644 index 0000000..f13e634 --- /dev/null +++ b/src/model/triptype.rs @@ -0,0 +1,55 @@ +use serde::{Deserialize, Serialize}; +use sqlx::{FromRow, SqlitePool}; + +#[derive(FromRow, Debug, Serialize, Deserialize, Clone)] +pub struct TripType { + pub id: i64, + name: String, + desc: String, + question: String, + icon: String, +} + +impl TripType { + pub async fn find_by_id(db: &SqlitePool, id: i64) -> Option { + sqlx::query_as!( + Self, + " +SELECT id, name, desc, question, icon +FROM trip_type +WHERE id like ? + ", + id + ) + .fetch_one(db) + .await + .ok() + } + + pub async fn all(db: &SqlitePool) -> Vec { + sqlx::query_as!( + Self, + " +SELECT id, name, desc, question, icon +FROM trip_type + " + ) + .fetch_all(db) + .await + .unwrap() //TODO: fixme + } +} + +#[cfg(test)] +mod test { + use crate::testdb; + + use sqlx::SqlitePool; + + #[sqlx::test] + fn test_find_true() { + let pool = testdb!(); + } + + //TODO: write tests +} diff --git a/src/model/user.rs b/src/model/user.rs index ac9f85b..767636b 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -16,7 +16,7 @@ pub struct User { pub name: String, pw: Option, pub is_cox: bool, - is_admin: bool, + pub is_admin: bool, is_guest: bool, #[serde(default = "bool::default")] deleted: bool, diff --git a/src/rest/admin/planned_event.rs b/src/rest/admin/planned_event.rs index 61cd20f..ff0c30f 100644 --- a/src/rest/admin/planned_event.rs +++ b/src/rest/admin/planned_event.rs @@ -18,6 +18,7 @@ struct AddPlannedEventForm { planned_starting_time: String, max_people: i32, notes: Option, + trip_type: Option, } #[post("/planned-event", data = "")] @@ -33,6 +34,7 @@ async fn create( data.max_people, data.day.clone(), data.notes.clone(), + data.trip_type, ) .await; diff --git a/src/rest/cox.rs b/src/rest/cox.rs index 5e379ea..caeefda 100644 --- a/src/rest/cox.rs +++ b/src/rest/cox.rs @@ -21,6 +21,7 @@ struct AddTripForm { planned_starting_time: String, max_people: i32, notes: Option, + trip_type: Option, } #[post("/trip", data = "")] @@ -32,6 +33,7 @@ async fn create(db: &State, data: Form, cox: CoxUser) - data.max_people, data.day.clone(), data.notes.clone(), + data.trip_type, ) .await; let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc just diff --git a/src/rest/mod.rs b/src/rest/mod.rs index 4c8222b..327f848 100644 --- a/src/rest/mod.rs +++ b/src/rest/mod.rs @@ -13,6 +13,7 @@ use sqlx::SqlitePool; use crate::model::{ log::Log, tripdetails::TripDetails, + triptype::TripType, user::User, usertrip::{UserTrip, UserTripError}, Day, @@ -26,6 +27,8 @@ mod cox; async fn index(db: &State, user: User, flash: Option>) -> Template { let mut days = Vec::new(); + let mut context = Context::new(); + let mut show_next_n_days = 6; if user.is_cox { let end_of_year = NaiveDate::from_ymd_opt(Local::now().year(), 12, 31).unwrap(); @@ -34,14 +37,16 @@ async fn index(db: &State, user: User, flash: Option