diff --git a/src/model/logbook.rs b/src/model/logbook.rs index 1e282f4..bef803f 100644 --- a/src/model/logbook.rs +++ b/src/model/logbook.rs @@ -60,6 +60,22 @@ pub struct LogToFinalize { pub rowers: Vec, } +#[derive(FromForm, Debug, Clone)] +pub struct LogToUpdate { + pub id: i64, + pub boat_id: i64, + pub shipmaster: i64, + pub steering_person: i64, + pub shipmaster_only_steering: bool, + pub departure: String, + pub arrival: Option, + pub destination: Option, + pub distance_in_km: Option, + pub comments: Option, + pub logtype: Option, + pub rowers: Vec, +} + impl TryFrom for LogToFinalize { type Error = String; @@ -94,6 +110,11 @@ pub struct LogbookWithBoatAndRowers { pub rowers: Vec, } +#[derive(Debug, PartialEq)] +pub enum LogbookAdminUpdateError { + NotAllowed, +} + #[derive(Debug, PartialEq)] pub enum LogbookUpdateError { NotYourEntry, @@ -172,7 +193,7 @@ impl Logbook { .await .ok() } - pub async fn find_by_id(db: &SqlitePool, id: i32) -> Option { + pub async fn find_by_id(db: &SqlitePool, id: i64) -> Option { sqlx::query_as!( Self, " @@ -437,6 +458,35 @@ ORDER BY departure DESC Ok(ret) } + pub async fn update( + &self, + db: &SqlitePool, + data: LogToUpdate, + user: &User, + ) -> Result<(), LogbookAdminUpdateError> { + if !user.has_role(db, "Vorstand").await { + return Err(LogbookAdminUpdateError::NotAllowed); + } + + sqlx::query!( + "UPDATE logbook SET boat_id=?, shipmaster=?, steering_person=?, shipmaster_only_steering=?, departure=?, arrival=?, destination=?, distance_in_km=?, comments=?, logtype=? WHERE id=?", + data.boat_id, + data.shipmaster, + data.steering_person, + data.shipmaster_only_steering, + data.departure, + data.arrival, + data.destination, + data.distance_in_km, + data.comments, + data.logtype, + self.id + ) + .execute(db) + .await.unwrap(); + Ok(()) + } + pub async fn distances(db: &SqlitePool) -> Vec<(String, i64)> { let result = sqlx::query!("SELECT destination, distance_in_km FROM logbook WHERE id IN (SELECT MIN(id) FROM logbook GROUP BY destination) AND destination IS NOT NULL AND distance_in_km IS NOT NULL;") .fetch_all(db) diff --git a/src/tera/log.rs b/src/tera/log.rs index cf07751..ccca5fd 100644 --- a/src/tera/log.rs +++ b/src/tera/log.rs @@ -20,11 +20,11 @@ use crate::model::{ boatreservation::BoatReservation, log::Log, logbook::{ - LogToAdd, LogToFinalize, Logbook, LogbookCreateError, LogbookDeleteError, - LogbookUpdateError, + LogToAdd, LogToFinalize, LogToUpdate, Logbook, LogbookAdminUpdateError, LogbookCreateError, + LogbookDeleteError, LogbookUpdateError, }, logtype::LogType, - user::{AdminUser, DonauLinzUser, User, UserWithDetails}, + user::{AdminUser, DonauLinzUser, User, UserWithDetails, VorstandUser}, }; pub struct KioskCookie(()); @@ -282,10 +282,40 @@ async fn create_kiosk( create_logbook(db, data, &DonauLinzUser(creator)).await //TODO: fixme } +#[post("/update", data = "")] +async fn update( + db: &State, + data: Form, + user: VorstandUser, +) -> Flash { + Log::create( + db, + format!("User {} tries to update log entry={:?}", &user.name, data), + ) + .await; + + let data = data.into_inner(); + + let Some(logbook) = Logbook::find_by_id(db, data.id).await else { + return Flash::error(Redirect::to("/log"), &format!("Logbucheintrag kann nicht bearbeitet werden, da es einen Logbuch-Eintrag mit ID={} nicht gibt", data.id)); + }; + + match logbook.update(db, data, &user.0).await { + Ok(()) => Flash::success( + Redirect::to("/log/show"), + format!("Logbucheintrag erfolgreich bearbeitet"), + ), + Err(LogbookAdminUpdateError::NotAllowed) => Flash::error( + Redirect::to("/log/show"), + format!("Du hast keine Erlaubnis, diesen Logbucheintrag zu bearbeiten!"), + ), + } +} + async fn home_logbook( db: &SqlitePool, data: Form, - logbook_id: i32, + logbook_id: i64, user: &DonauLinzUser, ) -> Flash { let logbook: Option = Logbook::find_by_id(db, logbook_id).await; @@ -312,7 +342,7 @@ async fn home_logbook( async fn home_kiosk( db: &State, data: Form, - logbook_id: i32, + logbook_id: i64, _kiosk: KioskCookie, ) -> Flash { let logbook = Logbook::find_by_id(db, logbook_id).await.unwrap(); //TODO: fixme @@ -340,7 +370,7 @@ async fn home_kiosk( async fn home( db: &State, data: Form, - logbook_id: i32, + logbook_id: i64, user: DonauLinzUser, ) -> Flash { Log::create( @@ -356,7 +386,7 @@ async fn home( } #[get("//delete", rank = 2)] -async fn delete(db: &State, logbook_id: i32, user: DonauLinzUser) -> Flash { +async fn delete(db: &State, logbook_id: i64, user: DonauLinzUser) -> Flash { let logbook = Logbook::find_by_id(db, logbook_id).await; if let Some(logbook) = logbook { Log::create( @@ -385,7 +415,7 @@ async fn delete(db: &State, logbook_id: i32, user: DonauLinzUser) -> #[get("//delete")] async fn delete_kiosk( db: &State, - logbook_id: i32, + logbook_id: i64, _kiosk: KioskCookie, ) -> Flash { let logbook = Logbook::find_by_id(db, logbook_id).await; @@ -425,7 +455,8 @@ pub fn routes() -> Vec { show_kiosk, show_for_year, delete, - delete_kiosk + delete_kiosk, + update ] } diff --git a/templates/includes/forms/log.html.tera b/templates/includes/forms/log.html.tera index 6a5fb50..6f1de37 100644 --- a/templates/includes/forms/log.html.tera +++ b/templates/includes/forms/log.html.tera @@ -169,77 +169,101 @@ {% endmacro show %} -{% macro show_old(log, state, allowed_to_close=false, index) %} +{% macro show_old(log, state, allowed_to_close=false, allowed_to_edit=false, index) %}
- {% if log.logtype %} -
- {% if log.logtype == 1 %} - Wanderfahrt - {% else %} - {% if log.logtype == 2 %} - Regatta - {% else %} - {{ log.logtype }} - {% endif %} - {% endif %} -
- {% endif %} -
- {{ log.boat.name }} - ({{ log.shipmaster_user.name -}} - {% if log.shipmaster_only_steering %} - - handgesteuert - {%- endif -%} - ) - - {% if state == "completed" and log.departure | date(format='%d.%m.%Y') == log.arrival | date(format='%d.%m.%Y') %} - {{ log.departure | date(format='%d.%m.%Y') }} - ({{ log.departure | date(format='%H:%M') }} - - - {{ log.arrival | date(format='%H:%M') }}) - {% else %} - {{ log.departure | date(format='%d.%m.%Y (%H:%M)') }} - {% if state == "completed" %} - - - {{ log.arrival | date(format='%d.%m.%Y (%H:%M)') }} - {% endif %} - {% endif %} - - {% set amount_rowers = log.rowers | length %} - {% set amount_guests = log.boat.amount_seats - amount_rowers %} - {% if allowed_to_close and state == "on_water" %} - {{ log::home(log=log) }} - {% else %} -
- {{ log.destination }} - {% if state == "completed" %} - ({{ log.distance_in_km }} - km) - {% endif %} - {% if log.comments %}- "{{ log.comments }}"{% endif %} -
- {% if amount_guests > 0 or log.rowers | length > 0 %} - {% if not log.boat.amount_seats == 1 %} -
- Ruderer: - {% for rower in log.rowers -%} - {{ rower.name }} - {%- if rower.id == log.steering_user.id and rower.id != log.shipmaster_user.id %} - (Steuerperson){%- endif -%} - {%- if not loop.last or amount_guests > 0 and not log.boat.external %},{% endif %} - {% endfor -%} - {% if amount_guests > 0 and not log.boat.external %} - Gäste - (ohne Account): - {{ amount_guests }} - {% endif %} -
+
+ + {% if log.logtype %} +
+ {% if log.logtype == 1 %} + Wanderfahrt + {% else %} + {% if log.logtype == 2 %} + Regatta + {% else %} + {{ log.logtype }} + {% endif %} {% endif %} - {% endif %} +
{% endif %} -
+
+ {{ log.boat.name }} + ({{ log.shipmaster_user.name -}} + {% if log.shipmaster_only_steering %} + - handgesteuert + {%- endif -%} + ) + + {% if state == "completed" and log.departure | date(format='%d.%m.%Y') == log.arrival | date(format='%d.%m.%Y') %} + {{ log.departure | date(format='%d.%m.%Y') }} + ({{ log.departure | date(format='%H:%M') }} + - + {{ log.arrival | date(format='%H:%M') }}) + {% else %} + {{ log.departure | date(format='%d.%m.%Y (%H:%M)') }} + {% if state == "completed" %} + - + {{ log.arrival | date(format='%d.%m.%Y (%H:%M)') }} + {% endif %} + {% endif %} + + {% set amount_rowers = log.rowers | length %} + {% set amount_guests = log.boat.amount_seats - amount_rowers %} + {% if allowed_to_close and state == "on_water" %} + {{ log::home(log=log) }} + {% else %} +
+ {{ log.destination }} + {% if state == "completed" %} + ({{ log.distance_in_km }} + km) + {% endif %} + {% if log.comments %}- "{{ log.comments }}"{% endif %} +
+ {% if amount_guests > 0 or log.rowers | length > 0 %} + {% if not log.boat.amount_seats == 1 %} +
+ Ruderer: + {% for rower in log.rowers -%} + {{ rower.name }} + {%- if rower.id == log.steering_user.id and rower.id != log.shipmaster_user.id %} + (Steuerperson){%- endif -%} + {%- if not loop.last or amount_guests > 0 and not log.boat.external %},{% endif %} + {% endfor -%} + {% if amount_guests > 0 and not log.boat.external %} + Gäste + (ohne Account): + {{ amount_guests }} + {% endif %} +
+ {% endif %} + {% endif %} + {% endif %} +
+ + {% if allowed_to_edit %} +
+ + + + + + + + + + + + +
+ {% endif %} +
{% endmacro show_old %} {% macro home(log) %} diff --git a/templates/includes/macros.html.tera b/templates/includes/macros.html.tera index 0549f5b..a68069a 100644 --- a/templates/includes/macros.html.tera +++ b/templates/includes/macros.html.tera @@ -143,9 +143,9 @@ {{ label }} diff --git a/templates/log.completed.html.tera b/templates/log.completed.html.tera index 0b2b75c..6f16fa6 100644 --- a/templates/log.completed.html.tera +++ b/templates/log.completed.html.tera @@ -23,7 +23,15 @@ placeholder="Suchen nach Bootsname oder Ruderer...">
- {% for log in logs %}{{ log::show_old(log=log, state="completed", only_ones=false, index=loop.index) }}{% endfor %} + {% for log in logs %} + {% set_global allowed_to_edit = false %} + {% if loggedin_user %} + {% if "Vorstand" in loggedin_user.roles %} + {% set_global allowed_to_edit = true %} + {% endif %} + {% endif %} + {{ log::show_old(log=log, state="completed", only_ones=false, index=loop.index, allowed_to_edit=allowed_to_edit) }} + {% endfor %}