Merge pull request 'updates-meeting' (#1084) from updates-meeting into staging
Reviewed-on: #1084
This commit is contained in:
@ -1,8 +1,8 @@
|
|||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use rocket::FromForm;
|
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
|
use rocket::FromForm;
|
||||||
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||||
|
|
||||||
use crate::model::boathouse::Boathouse;
|
use crate::model::boathouse::Boathouse;
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use rocket::serde::{Deserialize, Serialize};
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
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;
|
use super::boat::Boat;
|
||||||
|
|
||||||
@ -114,7 +117,11 @@ impl Boathouse {
|
|||||||
BoathouseAisles::from(db, boathouses).await
|
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!(
|
sqlx::query!(
|
||||||
"INSERT INTO boathouse(boat_id, aisle, side, level) VALUES (?,?,?,?)",
|
"INSERT INTO boathouse(boat_id, aisle, side, level) VALUES (?,?,?,?)",
|
||||||
data.boat_id,
|
data.boat_id,
|
||||||
@ -125,6 +132,17 @@ impl Boathouse {
|
|||||||
.execute(db)
|
.execute(db)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| e.to_string())?;
|
.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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,10 +153,20 @@ impl Boathouse {
|
|||||||
.ok()
|
.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)
|
sqlx::query!("DELETE FROM boathouse WHERE id=?", self.id)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
.await
|
.await
|
||||||
.unwrap(); //Okay, because we can only create a Boat of a valid id
|
.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!(ManageUserUser, +"admin", +"schriftfuehrer");
|
||||||
special_user!(AllowedToSendFeeReminderUser, +"admin", +"schriftfuehrer", +"kassier");
|
special_user!(AllowedToSendFeeReminderUser, +"admin", +"schriftfuehrer", +"kassier");
|
||||||
special_user!(AllowedToUpdateTripToAlwaysBeShownUser, +"admin");
|
special_user!(AllowedToUpdateTripToAlwaysBeShownUser, +"admin");
|
||||||
|
special_user!(AllowedToUpdateBoathouse, +"admin", +"Vorstand", +"tech");
|
||||||
|
|
||||||
#[derive(FromRow, Serialize, Deserialize, Clone, Debug)]
|
#[derive(FromRow, Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct UserWithRolesAndMembershipPdf {
|
pub struct UserWithRolesAndMembershipPdf {
|
||||||
|
@ -7,11 +7,11 @@ use crate::{
|
|||||||
mail::valid_mails,
|
mail::valid_mails,
|
||||||
role::Role,
|
role::Role,
|
||||||
user::{
|
user::{
|
||||||
AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails,
|
|
||||||
UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser,
|
|
||||||
clubmember::ClubMemberUser, foerdernd::FoerderndUser, member::Member,
|
clubmember::ClubMemberUser, foerdernd::FoerderndUser, member::Member,
|
||||||
regular::RegularUser, scheckbuch::ScheckbuchUser, schnupperant::SchnupperantUser,
|
regular::RegularUser, scheckbuch::ScheckbuchUser, schnupperant::SchnupperantUser,
|
||||||
schnupperinterest::SchnupperInterestUser, unterstuetzend::UnterstuetzendUser,
|
schnupperinterest::SchnupperInterestUser, unterstuetzend::UnterstuetzendUser,
|
||||||
|
AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails,
|
||||||
|
UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tera::Config,
|
tera::Config,
|
||||||
@ -19,7 +19,6 @@ use crate::{
|
|||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
use futures::future::join_all;
|
use futures::future::join_all;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
FromForm, Request, Route, State,
|
|
||||||
form::Form,
|
form::Form,
|
||||||
fs::TempFile,
|
fs::TempFile,
|
||||||
get,
|
get,
|
||||||
@ -27,9 +26,9 @@ use rocket::{
|
|||||||
post,
|
post,
|
||||||
request::{FlashMessage, FromRequest, Outcome},
|
request::{FlashMessage, FromRequest, Outcome},
|
||||||
response::{Flash, Redirect},
|
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;
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
// Custom request guard to extract the Referer header
|
// 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 {
|
match user.add_note(db, &admin, &data.note).await {
|
||||||
Ok(_) => Flash::success(
|
Ok(_) => Flash::success(
|
||||||
Redirect::to(format!("/admin/user/{}", user.id)),
|
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),
|
Err(e) => Flash::error(Redirect::to(format!("/admin/user/{}", user.id)), e),
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
use crate::model::{
|
use crate::model::{
|
||||||
boat::Boat,
|
boat::Boat,
|
||||||
boathouse::Boathouse,
|
boathouse::Boathouse,
|
||||||
user::{AdminUser, UserWithDetails, VorstandUser},
|
user::{AllowedToUpdateBoathouse, UserWithDetails, VorstandUser},
|
||||||
};
|
};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
FromForm, Route, State,
|
|
||||||
form::Form,
|
form::Form,
|
||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
response::{Flash, Redirect},
|
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;
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
#[get("/boathouse")]
|
#[get("/boathouse")]
|
||||||
@ -38,6 +37,11 @@ async fn index(
|
|||||||
let boathouse = Boathouse::get(db).await;
|
let boathouse = Boathouse::get(db).await;
|
||||||
context.insert("boathouse", &boathouse);
|
context.insert("boathouse", &boathouse);
|
||||||
|
|
||||||
|
let allowed_to_edit = AllowedToUpdateBoathouse::new(db, &admin.user)
|
||||||
|
.await
|
||||||
|
.is_some();
|
||||||
|
context.insert("allowed_to_edit", &boathouse);
|
||||||
|
|
||||||
context.insert(
|
context.insert(
|
||||||
"loggedin_user",
|
"loggedin_user",
|
||||||
&UserWithDetails::from_user(admin.into_inner(), db).await,
|
&UserWithDetails::from_user(admin.into_inner(), db).await,
|
||||||
@ -57,36 +61,29 @@ pub struct FormBoathouseToAdd {
|
|||||||
async fn new<'r>(
|
async fn new<'r>(
|
||||||
db: &State<SqlitePool>,
|
db: &State<SqlitePool>,
|
||||||
data: Form<FormBoathouseToAdd>,
|
data: Form<FormBoathouseToAdd>,
|
||||||
_admin: AdminUser,
|
user: AllowedToUpdateBoathouse,
|
||||||
) -> Flash<Redirect> {
|
) -> 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"),
|
Ok(_) => Flash::success(Redirect::to("/board/boathouse"), "Boot hinzugefügt"),
|
||||||
Err(e) => Flash::error(Redirect::to("/board/boathouse"), e),
|
Err(e) => Flash::error(Redirect::to("/board/boathouse"), e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/boathouse/<boathouse_id>/delete")]
|
#[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;
|
let boat = Boathouse::find_by_id(db, boathouse_id).await;
|
||||||
match boat {
|
match boat {
|
||||||
Some(boat) => {
|
Some(boat) => {
|
||||||
boat.delete(db).await;
|
boat.delete(db, &user).await;
|
||||||
Flash::success(Redirect::to("/board/boathouse"), "Bootsplatz gelöscht")
|
Flash::success(Redirect::to("/board/boathouse"), "Bootsplatz gelöscht")
|
||||||
}
|
}
|
||||||
None => Flash::error(Redirect::to("/board/boathouse"), "Boatplace does not exist"),
|
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> {
|
pub fn routes() -> Vec<Route> {
|
||||||
routes![index, new, delete]
|
routes![index, new, delete]
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
{% set place = boathouse[aisle_name][side_name].boats %}
|
{% set place = boathouse[aisle_name][side_name].boats %}
|
||||||
{% if place[level] %}
|
{% if place[level] %}
|
||||||
{{ place[level].boat.name }}
|
{{ place[level].boat.name }}
|
||||||
{% if "admin" in loggedin_user.roles %}
|
{% if allowed_to_edit %}
|
||||||
<a class="btn btn-primary absolute end-0"
|
<a class="btn btn-primary absolute end-0"
|
||||||
href="/board/boathouse/{{ place[level].boathouse_id }}/delete">X</a>
|
href="/board/boathouse/{{ place[level].boathouse_id }}/delete">X</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% elif boats | length > 0 %}
|
{% elif boats | length > 0 %}
|
||||||
{% if "admin" in loggedin_user.roles %}
|
{% if allowed_to_edit %}
|
||||||
<details>
|
<details>
|
||||||
<summary>Kein Boot</summary>
|
<summary>Kein Boot</summary>
|
||||||
<form action="/board/boathouse" method="post" class="grid gap-3">
|
<form action="/board/boathouse" method="post" class="grid gap-3">
|
||||||
|
Reference in New Issue
Block a user