send triptype to frontend

This commit is contained in:
philipp 2023-04-28 21:19:51 +02:00
parent bd5a28b342
commit 3d5ad30904
8 changed files with 109 additions and 21 deletions

View File

@ -1,10 +1,10 @@
use chrono::NaiveDate; use chrono::NaiveDate;
use serde::Serialize; 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 struct PlannedEvent {
pub id: i64, pub id: i64,
name: String, name: String,
@ -15,12 +15,14 @@ pub struct PlannedEvent {
max_people: i64, max_people: i64,
day: String, day: String,
notes: Option<String>, notes: Option<String>,
trip_type_id: Option<i64>,
} }
#[derive(Serialize)] #[derive(Serialize)]
pub struct PlannedEventWithUser { pub struct PlannedEventWithUserAndTriptype {
#[serde(flatten)] #[serde(flatten)]
planned_event: PlannedEvent, planned_event: PlannedEvent,
trip_type: Option<TripType>,
cox_needed: bool, cox_needed: bool,
cox: Vec<Registration>, cox: Vec<Registration>,
rower: Vec<Registration>, rower: Vec<Registration>,
@ -39,7 +41,8 @@ impl PlannedEvent {
sqlx::query_as!( sqlx::query_as!(
Self, 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 FROM planned_event
INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id
WHERE planned_event.id like ? WHERE planned_event.id like ?
@ -51,11 +54,14 @@ WHERE planned_event.id like ?
.ok() .ok()
} }
pub async fn get_for_day(db: &SqlitePool, day: NaiveDate) -> Vec<PlannedEventWithUser> { pub async fn get_for_day(
db: &SqlitePool,
day: NaiveDate,
) -> Vec<PlannedEventWithUserAndTriptype> {
let day = format!("{day}"); let day = format!("{day}");
let events = sqlx::query_as!( let events = sqlx::query_as!(
PlannedEvent, 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 FROM planned_event
INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id
WHERE day=?", WHERE day=?",
@ -68,11 +74,16 @@ WHERE day=?",
let mut ret = Vec::new(); let mut ret = Vec::new();
for event in events { for event in events {
let cox = event.get_all_cox(db).await; 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(), planned_event: event.clone(),
cox_needed: event.planned_amount_cox > cox.len() as i64, cox_needed: event.planned_amount_cox > cox.len() as i64,
cox, cox,
rower: event.get_all_rower(db).await, rower: event.get_all_rower(db).await,
trip_type,
}); });
} }
ret ret

View File

@ -5,6 +5,7 @@ use sqlx::SqlitePool;
use super::{ use super::{
planned_event::{PlannedEvent, Registration}, planned_event::{PlannedEvent, Registration},
tripdetails::TripDetails, tripdetails::TripDetails,
triptype::TripType,
user::CoxUser, user::CoxUser,
}; };
@ -18,13 +19,15 @@ pub struct Trip {
max_people: i64, max_people: i64,
day: String, day: String,
notes: Option<String>, notes: Option<String>,
trip_type_id: Option<i64>,
} }
#[derive(Serialize)] #[derive(Serialize)]
pub struct TripWithUser { pub struct TripWithUserAndType {
#[serde(flatten)] #[serde(flatten)]
trip: Trip, trip: Trip,
rower: Vec<Registration>, rower: Vec<Registration>,
trip_type: Option<TripType>,
} }
impl Trip { impl Trip {
@ -44,7 +47,7 @@ impl Trip {
sqlx::query_as!( sqlx::query_as!(
Self, 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 FROM trip
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
INNER JOIN user ON trip.cox_id = user.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<TripWithUser> { pub async fn get_for_day(db: &SqlitePool, day: NaiveDate) -> Vec<TripWithUserAndType> {
let day = format!("{day}"); let day = format!("{day}");
let trips = sqlx::query_as!( let trips = sqlx::query_as!(
Trip, 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 FROM trip
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
INNER JOIN user ON trip.cox_id = user.id INNER JOIN user ON trip.cox_id = user.id
@ -110,8 +113,13 @@ WHERE day=?
.unwrap(); //TODO: fixme .unwrap(); //TODO: fixme
let mut ret = Vec::new(); let mut ret = Vec::new();
for trip in trips { 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: trip.clone(),
trip_type,
rower: trip.get_all_rower(db).await, rower: trip.get_all_rower(db).await,
}); });
} }

View File

@ -8,6 +8,7 @@ pub struct TripDetails {
max_people: i64, max_people: i64,
day: String, day: String,
notes: Option<String>, notes: Option<String>,
trip_type_id: Option<i64>,
} }
impl TripDetails { impl TripDetails {
@ -15,7 +16,7 @@ impl TripDetails {
sqlx::query_as!( sqlx::query_as!(
TripDetails, 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 FROM trip_details
WHERE id like ? WHERE id like ?
", ",
@ -33,13 +34,15 @@ WHERE id like ?
max_people: i32, max_people: i32,
day: String, day: String,
notes: Option<String>, notes: Option<String>,
trip_type_id: Option<i64>,
) -> i64 { ) -> i64 {
let query = sqlx::query!( 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, planned_starting_time,
max_people, max_people,
day, day,
notes notes,
trip_type_id
) )
.execute(db) .execute(db)
.await .await
@ -94,11 +97,11 @@ mod test {
let pool = testdb!(); let pool = testdb!();
assert_eq!( 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, 3,
); );
assert_eq!( 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, 4,
); );
} }
@ -115,4 +118,6 @@ mod test {
fn test_true_full() { fn test_true_full() {
//TODO: register user for trip_details = 1; check if is_full returns true //TODO: register user for trip_details = 1; check if is_full returns true
} }
//TODO: add new tripdetails test with trip_type != None
} }

55
src/model/triptype.rs Normal file
View File

@ -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<Self> {
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<Self> {
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
}

View File

@ -16,7 +16,7 @@ pub struct User {
pub name: String, pub name: String,
pw: Option<String>, pw: Option<String>,
pub is_cox: bool, pub is_cox: bool,
is_admin: bool, pub is_admin: bool,
is_guest: bool, is_guest: bool,
#[serde(default = "bool::default")] #[serde(default = "bool::default")]
deleted: bool, deleted: bool,

View File

@ -18,6 +18,7 @@ struct AddPlannedEventForm {
planned_starting_time: String, planned_starting_time: String,
max_people: i32, max_people: i32,
notes: Option<String>, notes: Option<String>,
trip_type: Option<i64>,
} }
#[post("/planned-event", data = "<data>")] #[post("/planned-event", data = "<data>")]
@ -33,6 +34,7 @@ async fn create(
data.max_people, data.max_people,
data.day.clone(), data.day.clone(),
data.notes.clone(), data.notes.clone(),
data.trip_type,
) )
.await; .await;

View File

@ -21,6 +21,7 @@ struct AddTripForm {
planned_starting_time: String, planned_starting_time: String,
max_people: i32, max_people: i32,
notes: Option<String>, notes: Option<String>,
trip_type: Option<i64>,
} }
#[post("/trip", data = "<data>")] #[post("/trip", data = "<data>")]
@ -32,6 +33,7 @@ async fn create(db: &State<SqlitePool>, data: Form<AddTripForm>, cox: CoxUser) -
data.max_people, data.max_people,
data.day.clone(), data.day.clone(),
data.notes.clone(), data.notes.clone(),
data.trip_type,
) )
.await; .await;
let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc just let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc just

View File

@ -13,6 +13,7 @@ use sqlx::SqlitePool;
use crate::model::{ use crate::model::{
log::Log, log::Log,
tripdetails::TripDetails, tripdetails::TripDetails,
triptype::TripType,
user::User, user::User,
usertrip::{UserTrip, UserTripError}, usertrip::{UserTrip, UserTripError},
Day, Day,
@ -26,6 +27,8 @@ mod cox;
async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_>>) -> Template { async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_>>) -> Template {
let mut days = Vec::new(); let mut days = Vec::new();
let mut context = Context::new();
let mut show_next_n_days = 6; let mut show_next_n_days = 6;
if user.is_cox { if user.is_cox {
let end_of_year = NaiveDate::from_ymd_opt(Local::now().year(), 12, 31).unwrap(); let end_of_year = NaiveDate::from_ymd_opt(Local::now().year(), 12, 31).unwrap();
@ -34,14 +37,16 @@ async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_
.num_days() .num_days()
+ 1; + 1;
} }
if user.is_cox || user.is_admin {
let triptypes = TripType::all(db).await;
context.insert("trip_types", &triptypes);
}
for i in 0..show_next_n_days { for i in 0..show_next_n_days {
let date = (Local::now() + Duration::days(i)).date_naive(); let date = (Local::now() + Duration::days(i)).date_naive();
days.push(Day::new(db, date).await); days.push(Day::new(db, date).await);
} }
let mut context = Context::new();
if let Some(msg) = flash { if let Some(msg) = flash {
context.insert("flash", &msg.into_inner()); context.insert("flash", &msg.into_inner());
} }