diff --git a/src/model/boat.rs b/src/model/boat.rs index 2959b08..df3e9fd 100644 --- a/src/model/boat.rs +++ b/src/model/boat.rs @@ -1,8 +1,8 @@ use std::ops::DerefMut; use chrono::NaiveDateTime; -use rocket::FromForm; use rocket::serde::{Deserialize, Serialize}; +use rocket::FromForm; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; use crate::model::boathouse::Boathouse; diff --git a/src/model/boathouse.rs b/src/model/boathouse.rs index 03d0f78..632c8e5 100644 --- a/src/model/boathouse.rs +++ b/src/model/boathouse.rs @@ -1,7 +1,10 @@ use rocket::serde::{Deserialize, Serialize}; use sqlx::{FromRow, SqlitePool}; -use crate::tera::board::boathouse::FormBoathouseToAdd; +use crate::{ + model::{log::Log, user::AllowedToUpdateBoathouse}, + tera::board::boathouse::FormBoathouseToAdd, +}; use super::boat::Boat; @@ -114,7 +117,11 @@ impl Boathouse { BoathouseAisles::from(db, boathouses).await } - pub async fn create(db: &SqlitePool, data: FormBoathouseToAdd) -> Result<(), String> { + pub async fn create( + db: &SqlitePool, + changed_by: &AllowedToUpdateBoathouse, + data: FormBoathouseToAdd, + ) -> Result<(), String> { sqlx::query!( "INSERT INTO boathouse(boat_id, aisle, side, level) VALUES (?,?,?,?)", data.boat_id, @@ -125,6 +132,17 @@ impl Boathouse { .execute(db) .await .map_err(|e| e.to_string())?; + + let boat = Boat::find_by_id(db, data.boat_id).await.unwrap(); + Log::create( + db, + format!( + "{changed_by} hat das Boot {boat} auf den Gang {}, Seite {}, und Höhe {} 'gelegt'.", + data.aisle, data.side, data.level + ), + ) + .await; + Ok(()) } @@ -135,10 +153,20 @@ impl Boathouse { .ok() } - pub async fn delete(&self, db: &SqlitePool) { + pub async fn delete(&self, db: &SqlitePool, changed_by: &AllowedToUpdateBoathouse) { sqlx::query!("DELETE FROM boathouse WHERE id=?", self.id) .execute(db) .await .unwrap(); //Okay, because we can only create a Boat of a valid id + + let boat = Boat::find_by_id(db, self.boat_id as i32).await.unwrap(); + Log::create( + db, + format!( + "{changed_by} hat das Boot {boat} von Gang {}, Seite {}, und Höhe {} gelöscht.", + self.aisle, self.side, self.level + ), + ) + .await; } } diff --git a/src/model/user/mod.rs b/src/model/user/mod.rs index 49791fb..5fe241e 100644 --- a/src/model/user/mod.rs +++ b/src/model/user/mod.rs @@ -859,6 +859,7 @@ special_user!(AllowedToEditPaymentStatusUser, +"kassier", +"admin"); special_user!(ManageUserUser, +"admin", +"schriftfuehrer"); special_user!(AllowedToSendFeeReminderUser, +"admin", +"schriftfuehrer", +"kassier"); special_user!(AllowedToUpdateTripToAlwaysBeShownUser, +"admin"); +special_user!(AllowedToUpdateBoathouse, +"admin", +"Vorstand", +"tech"); #[derive(FromRow, Serialize, Deserialize, Clone, Debug)] pub struct UserWithRolesAndMembershipPdf { diff --git a/src/tera/board/boathouse.rs b/src/tera/board/boathouse.rs index 7d31f95..ac8ba6f 100644 --- a/src/tera/board/boathouse.rs +++ b/src/tera/board/boathouse.rs @@ -1,17 +1,16 @@ use crate::model::{ boat::Boat, boathouse::Boathouse, - user::{AdminUser, UserWithDetails, VorstandUser}, + user::{AllowedToUpdateBoathouse, UserWithDetails, VorstandUser}, }; use rocket::{ - FromForm, Route, State, form::Form, get, post, request::FlashMessage, response::{Flash, Redirect}, - routes, + routes, FromForm, Route, State, }; -use rocket_dyn_templates::{Template, tera::Context}; +use rocket_dyn_templates::{tera::Context, Template}; use sqlx::SqlitePool; #[get("/boathouse")] @@ -38,6 +37,11 @@ async fn index( let boathouse = Boathouse::get(db).await; context.insert("boathouse", &boathouse); + let allowed_to_edit = AllowedToUpdateBoathouse::new(db, &admin.user) + .await + .is_some(); + context.insert("allowed_to_edit", &boathouse); + context.insert( "loggedin_user", &UserWithDetails::from_user(admin.into_inner(), db).await, @@ -57,36 +61,29 @@ pub struct FormBoathouseToAdd { async fn new<'r>( db: &State, data: Form, - _admin: AdminUser, + user: AllowedToUpdateBoathouse, ) -> Flash { - match Boathouse::create(db, data.into_inner()).await { + match Boathouse::create(db, &user, data.into_inner()).await { Ok(_) => Flash::success(Redirect::to("/board/boathouse"), "Boot hinzugefügt"), Err(e) => Flash::error(Redirect::to("/board/boathouse"), e), } } #[get("/boathouse//delete")] -async fn delete(db: &State, _admin: AdminUser, boathouse_id: i32) -> Flash { +async fn delete( + db: &State, + user: AllowedToUpdateBoathouse, + boathouse_id: i32, +) -> Flash { let boat = Boathouse::find_by_id(db, boathouse_id).await; match boat { Some(boat) => { - boat.delete(db).await; + boat.delete(db, &user).await; Flash::success(Redirect::to("/board/boathouse"), "Bootsplatz gelöscht") } None => Flash::error(Redirect::to("/board/boathouse"), "Boatplace does not exist"), } } -//#[post("/boat/new", data = "")] -//async fn create( -// db: &State, -// data: Form>, -// _admin: AdminUser, -//) -> Flash { -// match Boat::create(db, data.into_inner()).await { -// Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Boot hinzugefügt"), -// Err(e) => Flash::error(Redirect::to("/admin/boat"), e), -// } -//} pub fn routes() -> Vec { routes![index, new, delete] diff --git a/templates/board/boathouse.html.tera b/templates/board/boathouse.html.tera index 9223dd3..fa717d5 100644 --- a/templates/board/boathouse.html.tera +++ b/templates/board/boathouse.html.tera @@ -7,12 +7,12 @@ {% set place = boathouse[aisle_name][side_name].boats %} {% if place[level] %} {{ place[level].boat.name }} - {% if "admin" in loggedin_user.roles %} + {% if allowed_to_edit %} X {% endif %} {% elif boats | length > 0 %} - {% if "admin" in loggedin_user.roles %} + {% if allowed_to_edit %}
Kein Boot