more updates after meeting
Some checks failed
CI/CD Pipeline / deploy-staging (push) Has been cancelled
CI/CD Pipeline / deploy-main (push) Has been cancelled
CI/CD Pipeline / test (push) Has been cancelled

This commit is contained in:
2025-06-17 22:52:04 +02:00
parent 86b8d3a30d
commit 1f0bfb04e4
5 changed files with 51 additions and 25 deletions

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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 {

View File

@ -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]

View File

@ -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">