updates-meeting #1085
| @@ -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; | ||||
|   | ||||
| @@ -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; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -7,11 +7,11 @@ use crate::{ | ||||
|         mail::valid_mails, | ||||
|         role::Role, | ||||
|         user::{ | ||||
|             AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails, | ||||
|             UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser, | ||||
|             clubmember::ClubMemberUser, foerdernd::FoerderndUser, member::Member, | ||||
|             regular::RegularUser, scheckbuch::ScheckbuchUser, schnupperant::SchnupperantUser, | ||||
|             schnupperinterest::SchnupperInterestUser, unterstuetzend::UnterstuetzendUser, | ||||
|             AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails, | ||||
|             UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser, | ||||
|         }, | ||||
|     }, | ||||
|     tera::Config, | ||||
| @@ -19,7 +19,6 @@ use crate::{ | ||||
| use chrono::NaiveDate; | ||||
| use futures::future::join_all; | ||||
| use rocket::{ | ||||
|     FromForm, Request, Route, State, | ||||
|     form::Form, | ||||
|     fs::TempFile, | ||||
|     get, | ||||
| @@ -27,9 +26,9 @@ use rocket::{ | ||||
|     post, | ||||
|     request::{FlashMessage, FromRequest, Outcome}, | ||||
|     response::{Flash, Redirect}, | ||||
|     routes, | ||||
|     routes, FromForm, Request, Route, State, | ||||
| }; | ||||
| use rocket_dyn_templates::{Template, tera::Context}; | ||||
| use rocket_dyn_templates::{tera::Context, Template}; | ||||
| use sqlx::SqlitePool; | ||||
|  | ||||
| // Custom request guard to extract the Referer header | ||||
| @@ -357,7 +356,7 @@ async fn add_note( | ||||
|     match user.add_note(db, &admin, &data.note).await { | ||||
|         Ok(_) => Flash::success( | ||||
|             Redirect::to(format!("/admin/user/{}", user.id)), | ||||
|             "Notiz hinzugefügt", | ||||
|             "Notiz hinzugefügt. Du findest sie ab sofort unter 'Aktivitäten'.", | ||||
|         ), | ||||
|         Err(e) => Flash::error(Redirect::to(format!("/admin/user/{}", user.id)), e), | ||||
|     } | ||||
|   | ||||
| @@ -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<SqlitePool>, | ||||
|     data: Form<FormBoathouseToAdd>, | ||||
|     _admin: AdminUser, | ||||
|     user: AllowedToUpdateBoathouse, | ||||
| ) -> Flash<Redirect> { | ||||
|     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/<boathouse_id>/delete")] | ||||
| async fn delete(db: &State<SqlitePool>, _admin: AdminUser, boathouse_id: i32) -> Flash<Redirect> { | ||||
| async fn delete( | ||||
|     db: &State<SqlitePool>, | ||||
|     user: AllowedToUpdateBoathouse, | ||||
|     boathouse_id: i32, | ||||
| ) -> Flash<Redirect> { | ||||
|     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 = "<data>")] | ||||
| //async fn create( | ||||
| //    db: &State<SqlitePool>, | ||||
| //    data: Form<BoatToAdd<'_>>, | ||||
| //    _admin: AdminUser, | ||||
| //) -> Flash<Redirect> { | ||||
| //    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<Route> { | ||||
|     routes![index, new, delete] | ||||
|   | ||||
| @@ -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 %} | ||||
|                 <a class="btn btn-primary absolute end-0" | ||||
|                    href="/board/boathouse/{{ place[level].boathouse_id }}/delete">X</a> | ||||
|             {% endif %} | ||||
|         {% elif boats | length > 0 %} | ||||
|             {% if "admin" in loggedin_user.roles %} | ||||
|             {% if allowed_to_edit %} | ||||
|                 <details> | ||||
|                     <summary>Kein Boot</summary> | ||||
|                     <form action="/board/boathouse" method="post" class="grid gap-3"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user