224 lines
6.3 KiB
Rust
224 lines
6.3 KiB
Rust
use chrono::NaiveDate;
|
|
use rocket::{
|
|
form::Form,
|
|
get, post,
|
|
request::FlashMessage,
|
|
response::{Flash, Redirect},
|
|
routes, FromForm, Route, State,
|
|
};
|
|
use rocket_dyn_templates::Template;
|
|
use sqlx::SqlitePool;
|
|
use tera::Context;
|
|
|
|
use crate::{
|
|
model::{
|
|
boat::Boat,
|
|
boatreservation::{BoatReservation, BoatReservationToAdd},
|
|
log::Log,
|
|
user::{DonauLinzUser, User, UserWithRolesAndNotificationCount},
|
|
},
|
|
tera::log::KioskCookie,
|
|
};
|
|
|
|
#[get("/")]
|
|
async fn index_kiosk(
|
|
db: &State<SqlitePool>,
|
|
flash: Option<FlashMessage<'_>>,
|
|
_kiosk: KioskCookie,
|
|
) -> Template {
|
|
let boatreservations = BoatReservation::all_future(db).await;
|
|
|
|
let mut context = Context::new();
|
|
if let Some(msg) = flash {
|
|
context.insert("flash", &msg.into_inner());
|
|
}
|
|
|
|
let linz_boats = Boat::all_for_boatshouse(db).await;
|
|
let mut boats = Vec::new();
|
|
for boat in linz_boats {
|
|
if boat.boat.owner.is_none() {
|
|
boats.push(boat);
|
|
}
|
|
}
|
|
|
|
context.insert("boatreservations", &boatreservations);
|
|
context.insert("boats", &boats);
|
|
context.insert("user", &User::all(db).await);
|
|
context.insert("show_kiosk_header", &true);
|
|
|
|
Template::render("boatreservations", context.into_json())
|
|
}
|
|
|
|
#[get("/", rank = 2)]
|
|
async fn index(
|
|
db: &State<SqlitePool>,
|
|
flash: Option<FlashMessage<'_>>,
|
|
user: DonauLinzUser,
|
|
) -> Template {
|
|
let boatreservations = BoatReservation::all_future(db).await;
|
|
|
|
let mut context = Context::new();
|
|
if let Some(msg) = flash {
|
|
context.insert("flash", &msg.into_inner());
|
|
}
|
|
|
|
let linz_boats = Boat::all_for_boatshouse(db).await;
|
|
let mut boats = Vec::new();
|
|
for boat in linz_boats {
|
|
if boat.boat.owner.is_none() {
|
|
boats.push(boat);
|
|
}
|
|
}
|
|
|
|
context.insert("boatreservations", &boatreservations);
|
|
context.insert("boats", &boats);
|
|
context.insert("user", &User::all(db).await);
|
|
context.insert(
|
|
"loggedin_user",
|
|
&UserWithRolesAndNotificationCount::from_user(user.into(), db).await,
|
|
);
|
|
|
|
Template::render("boatreservations", context.into_json())
|
|
}
|
|
|
|
#[derive(Debug, FromForm)]
|
|
pub struct FormBoatReservationToAdd<'r> {
|
|
pub boat_id: i64,
|
|
pub start_date: &'r str,
|
|
pub end_date: &'r str,
|
|
pub time_desc: &'r str,
|
|
pub usage: &'r str,
|
|
pub user_id_applicant: Option<i64>,
|
|
}
|
|
|
|
#[post("/new", data = "<data>", rank = 2)]
|
|
async fn create<'r>(
|
|
db: &State<SqlitePool>,
|
|
data: Form<FormBoatReservationToAdd<'r>>,
|
|
user: DonauLinzUser,
|
|
) -> Flash<Redirect> {
|
|
let user_applicant: User = user.into();
|
|
let boat = Boat::find_by_id(db, data.boat_id as i32).await.unwrap();
|
|
let boatreservation_to_add = BoatReservationToAdd {
|
|
boat: &boat,
|
|
start_date: NaiveDate::parse_from_str(data.start_date, "%Y-%m-%d").unwrap(),
|
|
end_date: NaiveDate::parse_from_str(data.end_date, "%Y-%m-%d").unwrap(),
|
|
time_desc: data.time_desc,
|
|
usage: data.usage,
|
|
user_applicant: &user_applicant,
|
|
};
|
|
match BoatReservation::create(db, boatreservation_to_add).await {
|
|
Ok(_) => Flash::success(
|
|
Redirect::to("/boatreservation"),
|
|
"Reservierung erfolgreich hinzugefügt",
|
|
),
|
|
Err(e) => Flash::error(Redirect::to("/boatreservation"), format!("Fehler: {e}")),
|
|
}
|
|
}
|
|
|
|
#[post("/new", data = "<data>")]
|
|
async fn create_from_kiosk<'r>(
|
|
db: &State<SqlitePool>,
|
|
data: Form<FormBoatReservationToAdd<'r>>,
|
|
_kiosk: KioskCookie,
|
|
) -> Flash<Redirect> {
|
|
let user_applicant: User = User::find_by_id(db, data.user_id_applicant.unwrap() as i32)
|
|
.await
|
|
.unwrap();
|
|
let boat = Boat::find_by_id(db, data.boat_id as i32).await.unwrap();
|
|
let boatreservation_to_add = BoatReservationToAdd {
|
|
boat: &boat,
|
|
start_date: NaiveDate::parse_from_str(data.start_date, "%Y-%m-%d").unwrap(),
|
|
end_date: NaiveDate::parse_from_str(data.end_date, "%Y-%m-%d").unwrap(),
|
|
time_desc: data.time_desc,
|
|
usage: data.usage,
|
|
user_applicant: &user_applicant,
|
|
};
|
|
match BoatReservation::create(db, boatreservation_to_add).await {
|
|
Ok(_) => Flash::success(
|
|
Redirect::to("/boatreservation"),
|
|
"Reservierung erfolgreich hinzugefügt",
|
|
),
|
|
Err(e) => Flash::error(Redirect::to("/boatreservation"), format!("Fehler: {e}")),
|
|
}
|
|
}
|
|
|
|
#[derive(FromForm, Debug)]
|
|
pub struct ReservationEditForm {
|
|
pub(crate) id: i32,
|
|
pub(crate) time_desc: String,
|
|
pub(crate) usage: String,
|
|
}
|
|
|
|
#[post("/", data = "<data>")]
|
|
async fn update(
|
|
db: &State<SqlitePool>,
|
|
data: Form<ReservationEditForm>,
|
|
user: User,
|
|
) -> Flash<Redirect> {
|
|
let Some(reservation) = BoatReservation::find_by_id(db, data.id).await else {
|
|
return Flash::error(
|
|
Redirect::to("/boatreservation"),
|
|
format!("Reservation with ID {} does not exist!", data.id),
|
|
);
|
|
};
|
|
|
|
if user.id != reservation.user_id_applicant && !user.has_role(db, "admin").await {
|
|
return Flash::error(
|
|
Redirect::to("/boatreservation"),
|
|
format!("Not allowed to update reservation (only admins + creator do so)."),
|
|
);
|
|
}
|
|
|
|
Log::create(
|
|
db,
|
|
format!(
|
|
"{} updated reservation from {reservation:?} to {data:?}",
|
|
user.name
|
|
),
|
|
)
|
|
.await;
|
|
|
|
reservation.update(db, data.into_inner()).await;
|
|
|
|
Flash::success(
|
|
Redirect::to("/boatreservation"),
|
|
"Reservierung erfolgreich bearbeitet",
|
|
)
|
|
}
|
|
|
|
#[get("/<reservation_id>/delete")]
|
|
async fn delete<'r>(
|
|
db: &State<SqlitePool>,
|
|
reservation_id: i32,
|
|
user: DonauLinzUser,
|
|
) -> Flash<Redirect> {
|
|
let reservation = BoatReservation::find_by_id(db, reservation_id)
|
|
.await
|
|
.unwrap();
|
|
|
|
if user.id == reservation.user_id_applicant || user.has_role(db, "admin").await {
|
|
reservation.delete(db).await;
|
|
Flash::success(
|
|
Redirect::to("/boatreservation"),
|
|
"Reservierung erfolgreich gelöscht",
|
|
)
|
|
} else {
|
|
Flash::error(
|
|
Redirect::to("/boatreservation"),
|
|
"Nur der Reservierer darf die Reservierung löschen.".to_string(),
|
|
)
|
|
}
|
|
}
|
|
|
|
pub fn routes() -> Vec<Route> {
|
|
routes![
|
|
index,
|
|
index_kiosk,
|
|
create,
|
|
create_from_kiosk,
|
|
delete,
|
|
update
|
|
]
|
|
}
|