Merge branch 'main' of gitlab.com:PhilippHofer/rot
This commit is contained in:
		| @@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS "trip_details" ( | ||||
| 	"planned_starting_time" text NOT NULL, | ||||
| 	"max_people" INTEGER NOT NULL, | ||||
| 	"day" TEXT NOT NULL, | ||||
| 	"allow_guests" boolean NOT NULL default false, | ||||
| 	"notes" TEXT, | ||||
| 	"trip_type_id" INTEGER, | ||||
| 	FOREIGN KEY(trip_type_id) REFERENCES trip_type(id) | ||||
| @@ -30,7 +31,6 @@ CREATE TABLE IF NOT EXISTS "planned_event" ( | ||||
| 	"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, | ||||
| 	"name" text NOT NULL, | ||||
| 	"planned_amount_cox" INTEGER unsigned NOT NULL, | ||||
| 	"allow_guests" boolean NOT NULL default false, | ||||
| 	"trip_details_id" INTEGER NOT NULL, | ||||
| 	"created_at" text NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||||
| 	FOREIGN KEY(trip_details_id) REFERENCES trip_details(id) ON DELETE CASCADE | ||||
|   | ||||
| @@ -30,4 +30,21 @@ impl Day { | ||||
|             trips: Trip::get_for_day(db, day).await, | ||||
|         } | ||||
|     } | ||||
|     pub async fn new_guest(db: &SqlitePool, day: NaiveDate) -> Self { | ||||
|         let mut day = Self::new(db, day).await; | ||||
|  | ||||
|         day.planned_events = day | ||||
|             .planned_events | ||||
|             .into_iter() | ||||
|             .filter(|e| e.planned_event.allow_guests) | ||||
|             .collect(); | ||||
|  | ||||
|         day.trips = day | ||||
|             .trips | ||||
|             .into_iter() | ||||
|             .filter(|t| t.trip.allow_guests) | ||||
|             .collect(); | ||||
|  | ||||
|         day | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -9,19 +9,19 @@ pub struct PlannedEvent { | ||||
|     pub id: i64, | ||||
|     name: String, | ||||
|     planned_amount_cox: i64, | ||||
|     allow_guests: bool, | ||||
|     trip_details_id: i64, | ||||
|     planned_starting_time: String, | ||||
|     max_people: i64, | ||||
|     day: String, | ||||
|     notes: Option<String>, | ||||
|     pub allow_guests: bool, | ||||
|     trip_type_id: Option<i64>, | ||||
| } | ||||
|  | ||||
| #[derive(Serialize)] | ||||
| pub struct PlannedEventWithUserAndTriptype { | ||||
|     #[serde(flatten)] | ||||
|     planned_event: PlannedEvent, | ||||
|     pub planned_event: PlannedEvent, | ||||
|     trip_type: Option<TripType>, | ||||
|     cox_needed: bool, | ||||
|     cox: Vec<Registration>, | ||||
| @@ -42,7 +42,7 @@ impl PlannedEvent { | ||||
|             Self, | ||||
|             " | ||||
| 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 | ||||
|     planned_event.id, planned_event.name, planned_amount_cox, trip_details_id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id | ||||
| FROM planned_event  | ||||
| INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id | ||||
| WHERE planned_event.id like ? | ||||
| @@ -61,7 +61,7 @@ WHERE planned_event.id like ? | ||||
|         let day = format!("{day}"); | ||||
|         let events = sqlx::query_as!( | ||||
|             PlannedEvent, | ||||
|             "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 | ||||
|             "SELECT planned_event.id, planned_event.name, planned_amount_cox, trip_details_id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id | ||||
| FROM planned_event | ||||
| INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id | ||||
| WHERE day=?", | ||||
| @@ -127,12 +127,13 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM planned_even | ||||
|         db: &SqlitePool, | ||||
|         name: String, | ||||
|         planned_amount_cox: i32, | ||||
|         allow_guests: bool, | ||||
|         trip_details: TripDetails, | ||||
|     ) { | ||||
|         sqlx::query!( | ||||
|             "INSERT INTO planned_event(name, planned_amount_cox, allow_guests, trip_details_id) VALUES(?, ?, ?, ?)", | ||||
|             name, planned_amount_cox, allow_guests, trip_details.id | ||||
|             "INSERT INTO planned_event(name, planned_amount_cox, trip_details_id) VALUES(?, ?, ?)", | ||||
|             name, | ||||
|             planned_amount_cox, | ||||
|             trip_details.id | ||||
|         ) | ||||
|         .execute(db) | ||||
|         .await | ||||
| @@ -170,7 +171,7 @@ mod test { | ||||
|  | ||||
|         let trip_details = TripDetails::find_by_id(&pool, 1).await.unwrap(); | ||||
|  | ||||
|         PlannedEvent::create(&pool, "new-event".into(), 2, false, trip_details).await; | ||||
|         PlannedEvent::create(&pool, "new-event".into(), 2, trip_details).await; | ||||
|  | ||||
|         let res = | ||||
|             PlannedEvent::get_for_day(&pool, NaiveDate::from_ymd_opt(1970, 1, 1).unwrap()).await; | ||||
|   | ||||
| @@ -19,13 +19,14 @@ pub struct Trip { | ||||
|     max_people: i64, | ||||
|     day: String, | ||||
|     notes: Option<String>, | ||||
|     pub allow_guests: bool, | ||||
|     trip_type_id: Option<i64>, | ||||
| } | ||||
|  | ||||
| #[derive(Serialize)] | ||||
| pub struct TripWithUserAndType { | ||||
|     #[serde(flatten)] | ||||
|     trip: Trip, | ||||
|     pub trip: Trip, | ||||
|     rower: Vec<Registration>, | ||||
|     trip_type: Option<TripType>, | ||||
| } | ||||
| @@ -47,7 +48,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, trip_type_id | ||||
| SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes, allow_guests, 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 | ||||
| @@ -100,7 +101,7 @@ WHERE trip.id=? | ||||
|         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, trip_type_id | ||||
| SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes, allow_guests, 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 | ||||
|   | ||||
| @@ -8,6 +8,7 @@ pub struct TripDetails { | ||||
|     max_people: i64, | ||||
|     day: String, | ||||
|     notes: Option<String>, | ||||
|     pub allow_guests: bool, | ||||
|     trip_type_id: Option<i64>, | ||||
| } | ||||
|  | ||||
| @@ -16,7 +17,7 @@ impl TripDetails { | ||||
|         sqlx::query_as!( | ||||
|             TripDetails, | ||||
|             " | ||||
| SELECT id, planned_starting_time, max_people, day, notes, trip_type_id | ||||
| SELECT id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id | ||||
| FROM trip_details  | ||||
| WHERE id like ? | ||||
|         ", | ||||
| @@ -34,14 +35,16 @@ WHERE id like ? | ||||
|         max_people: i32, | ||||
|         day: String, | ||||
|         notes: Option<String>, | ||||
|         allow_guests: bool, | ||||
|         trip_type_id: Option<i64>, | ||||
|     ) -> i64 { | ||||
|         let query = sqlx::query!( | ||||
|             "INSERT INTO trip_details(planned_starting_time, max_people, day, notes, trip_type_id) VALUES(?, ?, ?, ?, ?)" , | ||||
|             "INSERT INTO trip_details(planned_starting_time, max_people, day, notes, allow_guests, trip_type_id) VALUES(?, ?, ?, ?, ?, ?)" , | ||||
|             planned_starting_time, | ||||
|             max_people, | ||||
|             day, | ||||
|             notes, | ||||
|             allow_guests, | ||||
|             trip_type_id | ||||
|         ) | ||||
|         .execute(db) | ||||
| @@ -97,11 +100,29 @@ mod test { | ||||
|         let pool = testdb!(); | ||||
|  | ||||
|         assert_eq!( | ||||
|             TripDetails::create(&pool, "10:00".into(), 2, "1970-01-01".into(), None, None).await, | ||||
|             TripDetails::create( | ||||
|                 &pool, | ||||
|                 "10:00".into(), | ||||
|                 2, | ||||
|                 "1970-01-01".into(), | ||||
|                 None, | ||||
|                 false, | ||||
|                 None | ||||
|             ) | ||||
|             .await, | ||||
|             3, | ||||
|         ); | ||||
|         assert_eq!( | ||||
|             TripDetails::create(&pool, "10:00".into(), 2, "1970-01-01".into(), None, None).await, | ||||
|             TripDetails::create( | ||||
|                 &pool, | ||||
|                 "10:00".into(), | ||||
|                 2, | ||||
|                 "1970-01-01".into(), | ||||
|                 None, | ||||
|                 false, | ||||
|                 None | ||||
|             ) | ||||
|             .await, | ||||
|             4, | ||||
|         ); | ||||
|     } | ||||
|   | ||||
| @@ -17,7 +17,7 @@ pub struct User { | ||||
|     pw: Option<String>, | ||||
|     pub is_cox: bool, | ||||
|     pub is_admin: bool, | ||||
|     is_guest: bool, | ||||
|     pub is_guest: bool, | ||||
|     #[serde(default = "bool::default")] | ||||
|     deleted: bool, | ||||
| } | ||||
|   | ||||
| @@ -14,6 +14,10 @@ impl UserTrip { | ||||
|             return Err(UserTripError::EventAlreadyFull); | ||||
|         } | ||||
|  | ||||
|         if user.is_guest && !trip_details.allow_guests { | ||||
|             return Err(UserTripError::GuestNotAllowedForThisEvent); | ||||
|         } | ||||
|  | ||||
|         //check if cox if own event | ||||
|         let is_cox = sqlx::query!( | ||||
|             "SELECT count(*) as amount | ||||
| @@ -80,6 +84,7 @@ pub enum UserTripError { | ||||
|     AlreadyRegisteredAsCox, | ||||
|     EventAlreadyFull, | ||||
|     CantRegisterAtOwnEvent, | ||||
|     GuestNotAllowedForThisEvent, | ||||
| } | ||||
|  | ||||
| #[cfg(test)] | ||||
| @@ -180,4 +185,19 @@ mod test { | ||||
|  | ||||
|         assert_eq!(result, UserTripError::AlreadyRegisteredAsCox); | ||||
|     } | ||||
|  | ||||
|     #[sqlx::test] | ||||
|     fn test_fail_create_guest() { | ||||
|         let pool = testdb!(); | ||||
|  | ||||
|         let user = User::find_by_name(&pool, "guest".into()).await.unwrap(); | ||||
|  | ||||
|         let trip_details = TripDetails::find_by_id(&pool, 1).await.unwrap(); | ||||
|  | ||||
|         let result = UserTrip::create(&pool, &user, &trip_details) | ||||
|             .await | ||||
|             .expect_err("Not allowed for guests"); | ||||
|  | ||||
|         assert_eq!(result, UserTripError::GuestNotAllowedForThisEvent); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -34,6 +34,7 @@ async fn create( | ||||
|         data.max_people, | ||||
|         data.day.clone(), | ||||
|         data.notes.clone(), | ||||
|         data.allow_guests, | ||||
|         data.trip_type, | ||||
|     ) | ||||
|     .await; | ||||
| @@ -43,14 +44,7 @@ async fn create( | ||||
|                                                                                     //the object | ||||
|  | ||||
|     //TODO: fix clone() | ||||
|     PlannedEvent::create( | ||||
|         db, | ||||
|         data.name.clone(), | ||||
|         data.planned_amount_cox, | ||||
|         data.allow_guests, | ||||
|         trip_details, | ||||
|     ) | ||||
|     .await; | ||||
|     PlannedEvent::create(db, data.name.clone(), data.planned_amount_cox, trip_details).await; | ||||
|  | ||||
|     Flash::success(Redirect::to("/"), "Successfully planned the event") | ||||
| } | ||||
|   | ||||
| @@ -22,6 +22,7 @@ struct AddTripForm { | ||||
|     max_people: i32, | ||||
|     notes: Option<String>, | ||||
|     trip_type: Option<i64>, | ||||
|     allow_guests: bool, | ||||
| } | ||||
|  | ||||
| #[post("/trip", data = "<data>")] | ||||
| @@ -33,6 +34,7 @@ async fn create(db: &State<SqlitePool>, data: Form<AddTripForm>, cox: CoxUser) - | ||||
|         data.max_people, | ||||
|         data.day.clone(), | ||||
|         data.notes.clone(), | ||||
|         data.allow_guests, | ||||
|         data.trip_type, | ||||
|     ) | ||||
|     .await; | ||||
|   | ||||
| @@ -37,6 +37,7 @@ async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_ | ||||
|             .num_days() | ||||
|             + 1; | ||||
|     } | ||||
|  | ||||
|     if user.is_cox || user.is_admin { | ||||
|         let triptypes = TripType::all(db).await; | ||||
|         context.insert("trip_types", &triptypes); | ||||
| @@ -44,8 +45,13 @@ async fn index(db: &State<SqlitePool>, user: User, flash: Option<FlashMessage<'_ | ||||
|  | ||||
|     for i in 0..show_next_n_days { | ||||
|         let date = (Local::now() + Duration::days(i)).date_naive(); | ||||
|  | ||||
|         if user.is_guest { | ||||
|             days.push(Day::new_guest(db, date).await); | ||||
|         } else { | ||||
|             days.push(Day::new(db, date).await); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if let Some(msg) = flash { | ||||
|         context.insert("flash", &msg.into_inner()); | ||||
| @@ -86,6 +92,10 @@ async fn join(db: &State<SqlitePool>, trip_details_id: i64, user: User) -> Flash | ||||
|             Redirect::to("/"), | ||||
|             "Du kannst bei einer selbst ausgeschriebenen Fahrt nicht mitrudern ;)", | ||||
|         ), | ||||
|         Err(UserTripError::GuestNotAllowedForThisEvent) => Flash::error( | ||||
|             Redirect::to("/"), | ||||
|             "Bei dieser Ausfahrt können leider keine Gäste mitfahren.", | ||||
|         ), | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     {{ macros::input(label='Startzeit', name='planned_starting_time', type='time', required=true) }} | ||||
|     {{ macros::input(label='Anzahl Steuerleute', name='planned_amount_cox', type='number', required=true, min='0') }} | ||||
|     {{ macros::input(label='Anzahl Ruderer (ohne Steuerperson)', name='max_people', type='number', required=true, min='0') }} | ||||
|     {{ macros::checkbox(label='Gäste erlauben', name='max_allow_guestspeople') }} | ||||
|     {{ macros::checkbox(label='Gäste erlauben', name='allow_guests') }} | ||||
|     {{ macros::input(label='Anmerkungen', name='notes', type='input') }} | ||||
|     <input value="Erstellen" class="w-full btn btn-primary" type="submit" /> | ||||
|   </form> | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
|         <input class="day-js" type="hidden" name="day" value="" /> | ||||
|         {{ macros::input(label='Startzeit (zB "10:00")', name='planned_starting_time', type='time', required=true) }} | ||||
|         {{ macros::input(label='Anzahl Ruderer (ohne Steuerperson)', name='max_people', type='number', required=true, min='0') }} | ||||
|     	{{ macros::checkbox(label='Gäste erlauben', name='allow_guests') }} | ||||
|         {{ macros::input(label='Anmerkungen', name='notes', type='input') }} | ||||
|         <input value="Erstellen" class="w-full btn btn-primary" type="submit" /> | ||||
|     </form> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Philipp
					Philipp