allow non-cox to create ergo-trips
This commit is contained in:
parent
9d3b1d522b
commit
1f0b74554f
@ -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)]
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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 = "<data>", rank = 2)]
|
||||
async fn create_ergo(
|
||||
db: &State<SqlitePool>,
|
||||
data: Form<TripDetailsToAdd<'_>>,
|
||||
cox: ErgoUser,
|
||||
) -> Flash<Redirect> {
|
||||
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 = "<data>")]
|
||||
async fn create(
|
||||
db: &State<SqlitePool>,
|
||||
@ -50,7 +73,7 @@ async fn update(
|
||||
db: &State<SqlitePool>,
|
||||
data: Form<EditTripForm<'_>>,
|
||||
trip_id: i64,
|
||||
cox: SteeringUser,
|
||||
cox: User,
|
||||
) -> Flash<Redirect> {
|
||||
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<SqlitePool>, planned_event_id: i64, cox: SteeringUser)
|
||||
}
|
||||
|
||||
#[get("/remove/trip/<trip_id>")]
|
||||
async fn remove_trip(db: &State<SqlitePool>, trip_id: i64, cox: SteeringUser) -> Flash<Redirect> {
|
||||
async fn remove_trip(db: &State<SqlitePool>, trip_id: i64, cox: User) -> Flash<Redirect> {
|
||||
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<Route> {
|
||||
routes![
|
||||
create,
|
||||
create_ergo,
|
||||
join,
|
||||
remove,
|
||||
remove_trip,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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') }}
|
||||
{% 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 %}
|
||||
<input value="Erstellen" class="w-full btn btn-primary" type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
|
@ -190,7 +190,7 @@ function setChoiceByLabel(choicesInstance, label) {
|
||||
{{ 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) %}
|
||||
<div class="{{ wrapper_class }}">
|
||||
<label for="{{ name }}" class="text-sm text-gray-600 dark:text-gray-100">{{ label }}</label>
|
||||
{% if display == '' %}
|
||||
@ -203,7 +203,7 @@ function setChoiceByLabel(choicesInstance, label) {
|
||||
{% if default %}<option selected value>{{ default }}</option>{% endif %}
|
||||
{% if nonSelectableDefault %}<option disabled selected value>{{ nonSelectableDefault }}</option>{% endif %}
|
||||
{% for d in data %}
|
||||
<option value="{{ d.id }}" {% if d.id == selected_id %}selected{% endif %} {% if extras != '' %} {% for extra in extras %} {% if extra != 'on_water' and d[extra] %} data- {{ extra }}={{ d[extra] }} {% else %} {% if d[extra] %}disabled{% endif %} {% endif %} {% endfor %} {% endif %} {% if show_seats %} data-custom-properties='{"amount_seats": {{ d["amount_seats"] }}, "owner": "{{ d["owner"] }}", "default_destination": "{{ d["default_destination"] }}", "boat_in_ottensheim": {{ d["location_id"] == 2 }}, "boat_reserved_today": {{ d["reserved_today"] }}, "convert_handoperated_possible": {{ d["convert_handoperated_possible"] }}, "default_handoperated": {{ d["default_shipmaster_only_steering"] }}}' {% endif %}>
|
||||
<option value="{{ d.id }}" {% if only_ergo and d.id!=4 %} disabled {% endif %}{% if d.id == selected_id %}selected{% endif %} {% if extras != '' %} {% for extra in extras %} {% if extra != 'on_water' and d[extra] %} data- {{ extra }}={{ d[extra] }} {% else %} {% if d[extra] %}disabled{% endif %} {% endif %} {% endfor %} {% endif %} {% if show_seats %} data-custom-properties='{"amount_seats": {{ d["amount_seats"] }}, "owner": "{{ d["owner"] }}", "default_destination": "{{ d["default_destination"] }}", "boat_in_ottensheim": {{ d["location_id"] == 2 }}, "boat_reserved_today": {{ d["reserved_today"] }}, "convert_handoperated_possible": {{ d["convert_handoperated_possible"] }}, "default_handoperated": {{ d["default_shipmaster_only_steering"] }}}' {% endif %}>
|
||||
{% for displa in display -%}
|
||||
{%- if d[displa] -%}
|
||||
{{- d[displa] -}}
|
||||
|
@ -354,7 +354,11 @@
|
||||
{{ macros::input(label='Anzahl Ruderer', name='max_people', type='number', required=true, value=trip.max_people, min=trip.rower | length) }}
|
||||
{{ macros::input(label='Anmerkungen', name='notes', type='input', value=trip.notes) }}
|
||||
{{ macros::checkbox(label='Gesperrt', name='is_locked', id=trip.id,checked=trip.is_locked) }}
|
||||
{{ macros::select(label='Typ', name='trip_type', data=trip_types, default='Reguläre Ausfahrt', selected_id=trip.trip_type_id) }}
|
||||
{% if loggedin_user.allowed_to_steer %}
|
||||
{{ macros::select(label='Typ', name='trip_type', data=trip_types, default='Reguläre Ausfahrt', selected_id=trip.trip_type_id, only_ergo=not loggedin_user.allowed_to_steer) }}
|
||||
{% else %}
|
||||
{{ macros::select(label='Typ', name='trip_type', data=trip_types, selected_id=trip.trip_type_id, only_ergo=not loggedin_user.allowed_to_steer, only_ergos=true) }}
|
||||
{% endif %}
|
||||
<input value="Speichern" class="btn btn-primary" type="submit" />
|
||||
</form>
|
||||
</div>
|
||||
@ -421,11 +425,11 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
{# --- START Add Buttons --- #}
|
||||
{% if "manage_events" in loggedin_user.roles or loggedin_user.allowed_to_steer %}
|
||||
<div class="grid {% if "manage_events" in loggedin_user.roles and loggedin_user.allowed_to_steer %}grid-cols-2{% endif %} text-center">
|
||||
{% if "manage_events" in loggedin_user.roles or loggedin_user.allowed_to_steer or "ergo" in loggedin_user.roles %}
|
||||
<div class="grid {% if "manage_events" in loggedin_user.roles and (loggedin_user.allowed_to_steer or "ergo" in loggedin_user.roles) %}grid-cols-2{% endif %} text-center">
|
||||
{% if "manage_events" in loggedin_user.roles %}
|
||||
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>Event</strong> am {{ day.day| date(format='%d.%m.%Y') }} erstellen" data-day="{{ day.day }}" data-body="#addEventForm" class="relative inline-block w-full bg-primary-900 hover:bg-primary-950 focus:bg-primary-950 dark:bg-primary-950 text-white py-2 text-sm font-semibold
|
||||
{% if loggedin_user.allowed_to_steer %}
|
||||
{% if loggedin_user.allowed_to_steer or "ergo" in loggedin_user.roles %}
|
||||
rounded-bl-md
|
||||
{% else %}
|
||||
rounded-b-md
|
||||
@ -435,7 +439,7 @@
|
||||
Event
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if loggedin_user.allowed_to_steer %}
|
||||
{% if loggedin_user.allowed_to_steer or "ergo" in loggedin_user.roles %}
|
||||
<a href="#" data-sidebar="true" data-trigger="sidebar" data-header="<strong>Ausfahrt</strong> am {{ day.day| date(format='%d.%m.%Y') }} erstellen" data-day="{{ day.day }}" data-body="#sidebarForm" class="relative inline-block w-full py-2 text-primary-900 hover:text-primary-950 dark:bg-primary-600 dark:text-white dark:hover:bg-primary-500 dark:hover:text-white focus:text-primary-950 text-sm font-semibold bg-gray-100 hover:bg-gray-200 focus:bg-gray-200
|
||||
{% if "manage_events" in loggedin_user.roles %}
|
||||
rounded-br-md
|
||||
@ -454,7 +458,7 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% if loggedin_user.allowed_to_steer %}
|
||||
{% if loggedin_user.allowed_to_steer or "ergo" in loggedin_user.roles %}
|
||||
{% include "forms/trip" %}
|
||||
{% endif %}
|
||||
{% if "manage_events" in loggedin_user.roles %}
|
||||
|
Loading…
Reference in New Issue
Block a user