From 1f0b74554fc4000ec101f321d00d13c276c0cd5b Mon Sep 17 00:00:00 2001 From: Philipp Hofer Date: Mon, 25 Nov 2024 12:12:36 +0100 Subject: [PATCH] allow non-cox to create ergo-trips --- src/model/trip.rs | 39 +++++++++++++++++++++-------- src/model/triptype.rs | 2 +- src/model/user.rs | 1 + src/tera/cox.rs | 34 ++++++++++++++++++++++--- src/tera/planned.rs | 5 +++- templates/forms/trip.html.tera | 6 ++++- templates/includes/macros.html.tera | 4 +-- templates/planned.html.tera | 16 +++++++----- 8 files changed, 82 insertions(+), 25 deletions(-) diff --git a/src/model/trip.rs b/src/model/trip.rs index cefb1ce..71d98df 100644 --- a/src/model/trip.rs +++ b/src/model/trip.rs @@ -9,7 +9,7 @@ use super::{ notification::Notification, tripdetails::TripDetails, triptype::TripType, - user::{SteeringUser, User}, + user::{ErgoUser, SteeringUser, User}, usertrip::UserTrip, }; @@ -38,7 +38,7 @@ pub struct TripWithUserAndType { } pub struct TripUpdate<'a> { - pub cox: &'a SteeringUser, + pub cox: &'a User, pub trip: &'a Trip, pub max_people: i32, pub notes: Option<&'a str>, @@ -63,9 +63,23 @@ impl TripWithUserAndType { impl Trip { /// Cox decides to create own trip. pub async fn new_own(db: &SqlitePool, cox: &SteeringUser, trip_details: TripDetails) { + Self::perform_new(db, &cox.user, trip_details).await + } + + pub async fn new_own_ergo(db: &SqlitePool, ergo: &ErgoUser, trip_details: TripDetails) { + let typ = trip_details.triptype(db).await; + if let Some(typ) = typ { + let allowed_type = TripType::find_by_id(db, 4).await.unwrap(); + if typ == allowed_type { + Self::perform_new(db, &ergo.user, trip_details).await; + } + } + } + + async fn perform_new(db: &SqlitePool, user: &User, trip_details: TripDetails) { let _ = sqlx::query!( "INSERT INTO trip (cox_id, trip_details_id) VALUES(?, ?)", - cox.id, + user.id, trip_details.id ) .execute(db) @@ -96,7 +110,7 @@ impl Trip { &user, &format!( "{} hat eine Ausfahrt zur selben Zeit ({} um {}) wie du erstellt", - cox.user.name, trip.day, trip.planned_starting_time + user.name, trip.day, trip.planned_starting_time ), "Neue Ausfahrt zur selben Zeit", None, @@ -273,6 +287,12 @@ WHERE day=? return Err(TripUpdateError::NotYourTrip); } + if update.trip_type != Some(4) { + if !update.cox.allowed_to_steer(db).await { + return Err(TripUpdateError::TripTypeNotAllowed); + } + } + let Some(trip_details_id) = update.trip.trip_details_id else { return Err(TripUpdateError::TripDetailsDoesNotExist); //TODO: Remove? }; @@ -314,7 +334,7 @@ WHERE day=? &user, &format!( "Die Ausfahrt von {} am {} um {} wurde abgesagt. {} Bitte gib Bescheid, dass du die Info erhalten hast indem du auf ✓ klickst.", - update.cox.user.name, + update.cox.name, update.trip.day, update.trip.planned_starting_time, notes @@ -384,11 +404,7 @@ WHERE day=? Ok(()) } - pub(crate) async fn delete( - &self, - db: &SqlitePool, - user: &SteeringUser, - ) -> Result<(), TripDeleteError> { + pub(crate) async fn delete(&self, db: &SqlitePool, user: &User) -> Result<(), TripDeleteError> { let registered_rower = Registration::all_rower(db, self.trip_details_id.unwrap()).await; if !registered_rower.is_empty() { return Err(TripDeleteError::SomebodyAlreadyRegistered); @@ -398,7 +414,7 @@ WHERE day=? return Err(TripDeleteError::NotYourTrip); } - Log::create(db, format!("{} deleted trip: {:#?}", user.user.name, self)).await; + Log::create(db, format!("{} deleted trip: {:#?}", user.name, self)).await; sqlx::query!("DELETE FROM trip WHERE id = ?", self.id) .execute(db) @@ -464,6 +480,7 @@ pub enum TripDeleteError { pub enum TripUpdateError { NotYourTrip, TripDetailsDoesNotExist, + TripTypeNotAllowed, } #[cfg(test)] diff --git a/src/model/triptype.rs b/src/model/triptype.rs index 370fe19..40d29d7 100644 --- a/src/model/triptype.rs +++ b/src/model/triptype.rs @@ -1,7 +1,7 @@ use serde::{Deserialize, Serialize}; use sqlx::{FromRow, SqlitePool}; -#[derive(FromRow, Debug, Serialize, Deserialize, Clone)] +#[derive(FromRow, Debug, Serialize, Deserialize, Clone, PartialEq)] pub struct TripType { pub id: i64, pub name: String, diff --git a/src/model/user.rs b/src/model/user.rs index 8634682..f03b0b4 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -1166,6 +1166,7 @@ macro_rules! special_user { } special_user!(TechUser, +"tech"); +special_user!(ErgoUser, +"ergo"); special_user!(SteeringUser, +"cox", +"Bootsführer"); special_user!(AdminUser, +"admin"); special_user!(AllowedForPlannedTripsUser, +"Donau Linz", +"scheckbuch"); diff --git a/src/tera/cox.rs b/src/tera/cox.rs index dbee671..31c791c 100644 --- a/src/tera/cox.rs +++ b/src/tera/cox.rs @@ -11,9 +11,32 @@ use crate::model::{ log::Log, trip::{self, CoxHelpError, Trip, TripDeleteError, TripHelpDeleteError, TripUpdateError}, tripdetails::{TripDetails, TripDetailsToAdd}, - user::{AllowedToUpdateTripToAlwaysBeShownUser, SteeringUser}, + user::{AllowedToUpdateTripToAlwaysBeShownUser, ErgoUser, SteeringUser, User}, }; +#[post("/trip", data = "", rank = 2)] +async fn create_ergo( + db: &State, + data: Form>, + cox: ErgoUser, +) -> Flash { + let trip_details_id = TripDetails::create(db, data.into_inner()).await; + let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc just + //created + Trip::new_own_ergo(db, &cox, trip_details).await; //TODO: fix + + //Log::create( + // db, + // format!( + // "Cox {} created trip on {} @ {} for {} rower", + // cox.name, trip_details.day, trip_details.planned_starting_time, trip_details.max_people, + // ), + //) + //.await; + + Flash::success(Redirect::to("/planned"), "Ausfahrt erfolgreich erstellt.") +} + #[post("/trip", data = "")] async fn create( db: &State, @@ -50,7 +73,7 @@ async fn update( db: &State, data: Form>, trip_id: i64, - cox: SteeringUser, + cox: User, ) -> Flash { if let Some(trip) = Trip::find_by_id(db, trip_id).await { let update = trip::TripUpdate { @@ -69,6 +92,10 @@ async fn update( Err(TripUpdateError::NotYourTrip) => { Flash::error(Redirect::to("/planned"), "Nicht deine Ausfahrt!") } + Err(TripUpdateError::TripTypeNotAllowed) => Flash::error( + Redirect::to("/planned"), + "Du darfst nur Ergo-Events erstellen", + ), Err(TripUpdateError::TripDetailsDoesNotExist) => { Flash::error(Redirect::to("/planned"), "Ausfahrt gibt's nicht") } @@ -130,7 +157,7 @@ async fn join(db: &State, planned_event_id: i64, cox: SteeringUser) } #[get("/remove/trip/")] -async fn remove_trip(db: &State, trip_id: i64, cox: SteeringUser) -> Flash { +async fn remove_trip(db: &State, trip_id: i64, cox: User) -> Flash { let trip = Trip::find_by_id(db, trip_id).await; match trip { None => Flash::error(Redirect::to("/planned"), "Trip gibt's nicht!"), @@ -185,6 +212,7 @@ async fn remove( pub fn routes() -> Vec { routes![ create, + create_ergo, join, remove, remove_trip, diff --git a/src/tera/planned.rs b/src/tera/planned.rs index 184f926..3102818 100644 --- a/src/tera/planned.rs +++ b/src/tera/planned.rs @@ -29,7 +29,10 @@ async fn index( let mut context = Context::new(); - if user.allowed_to_steer(db).await || user.has_role(db, "manage_events").await { + if user.allowed_to_steer(db).await + || user.has_role(db, "manage_events").await + || user.has_role(db, "ergo").await + { let triptypes = TripType::all(db).await; context.insert("trip_types", &triptypes); } diff --git a/templates/forms/trip.html.tera b/templates/forms/trip.html.tera index 0632e59..5cc8dea 100644 --- a/templates/forms/trip.html.tera +++ b/templates/forms/trip.html.tera @@ -6,7 +6,11 @@ {{ macros::input(label='Anzahl Ruderer (ohne Steuerperson)', name='max_people', type='number', required=true, min='0') }} {{ macros::checkbox(label='Scheckbuch-Anmeldungen erlauben', name='allow_guests') }} {{ macros::input(label='Anmerkungen', name='notes', type='input') }} - {{ macros::select(label='Typ', data=trip_types, name='trip_type', default='Reguläre Ausfahrt') }} + {% if loggedin_user.allowed_to_steer %} + {{ macros::select(label='Typ', data=trip_types, name='trip_type', default='Reguläre Ausfahrt') }} + {% else %} + {{ macros::select(label='Typ', data=trip_types, name='trip_type', only_ergo=true) }} + {% endif %} diff --git a/templates/includes/macros.html.tera b/templates/includes/macros.html.tera index e3a0b30..a8550a6 100644 --- a/templates/includes/macros.html.tera +++ b/templates/includes/macros.html.tera @@ -190,7 +190,7 @@ function setChoiceByLabel(choicesInstance, label) { {{ label }} {% endmacro checkbox %} -{% macro select(label, data, name='trip_type', default='', id='', selected_id='', display='', extras='', class='', wrapper_class='', required=false, show_seats=false, new_last_entry='', nonSelectableDefault=false) %} +{% macro select(label, data, name='trip_type', default='', id='', selected_id='', display='', extras='', class='', wrapper_class='', required=false, show_seats=false, new_last_entry='', nonSelectableDefault=false, only_ergo=false) %}
{% if display == '' %} @@ -203,7 +203,7 @@ function setChoiceByLabel(choicesInstance, label) { {% if default %}{% endif %} {% if nonSelectableDefault %}{% endif %} {% for d in data %} -
@@ -421,11 +425,11 @@ {% endif %} {# --- START Add Buttons --- #} - {% if "manage_events" in loggedin_user.roles or loggedin_user.allowed_to_steer %} -