diff --git a/src/model/notification.rs b/src/model/notification.rs index fedc3b3..841ad3c 100644 --- a/src/model/notification.rs +++ b/src/model/notification.rs @@ -152,12 +152,27 @@ ORDER BY read_at DESC, created_at DESC; } } } + // Cox read notification about cancelled event + let re = Regex::new(r"^remove_trip_by_planned_event:(\d+)$").unwrap(); + if let Some(caps) = re.captures(action) { + if let Some(matched) = caps.get(1) { + if let Ok(number) = matched.as_str().parse::() { + let _ = sqlx::query!( + "DELETE FROM trip WHERE cox_id = ? AND planned_event_id = ?", + self.user_id, + number + ) + .execute(db) + .await + .unwrap(); + } + } + } } } - pub(crate) async fn delete_by_action(db: &sqlx::Pool, action: &str) { sqlx::query!( - "DELETE FROM notification WHERE action_after_reading=? and read_at = null", + "DELETE FROM notification WHERE action_after_reading=? and read_at is null", action ) .execute(db) diff --git a/src/model/planned_event.rs b/src/model/planned_event.rs index 2db5692..147b187 100644 --- a/src/model/planned_event.rs +++ b/src/model/planned_event.rs @@ -8,7 +8,7 @@ use ics::{ use serde::Serialize; use sqlx::{FromRow, Row, SqlitePool}; -use super::{tripdetails::TripDetails, triptype::TripType, user::User}; +use super::{notification::Notification, tripdetails::TripDetails, triptype::TripType, user::User}; #[derive(Serialize, Clone, FromRow, Debug, PartialEq)] pub struct PlannedEvent { @@ -17,7 +17,7 @@ pub struct PlannedEvent { planned_amount_cox: i64, trip_details_id: i64, pub planned_starting_time: String, - max_people: i64, + pub(crate) max_people: i64, pub day: String, pub notes: Option, pub allow_guests: bool, @@ -227,6 +227,9 @@ INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id", .await .unwrap(); //Okay, as planned_event can only be created with proper DB backing + let tripdetails = self.trip_details(db).await; + let was_already_cancelled = tripdetails.max_people == 0; + sqlx::query!( "UPDATE trip_details SET max_people = ?, notes = ?, always_show = ?, is_locked = ? WHERE id = ?", max_people, @@ -238,6 +241,69 @@ INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id", .execute(db) .await .unwrap(); //Okay, as planned_event can only be created with proper DB backing + + if max_people == 0 && !was_already_cancelled { + let coxes = Registration::all_cox(db, self.id).await; + for user in coxes { + if let Some(user) = User::find_by_name(db, &user.name).await { + let notes = match notes { + Some(n) if !n.is_empty() => n, + _ => ".", + }; + + Notification::create( + db, + &user, + &format!( + "Die Ausfahrt {} am {} um {} wurde abgesagt{}", + self.name, self.day, self.planned_starting_time, notes + ), + "Absage Ausfahrt", + None, + Some(&format!("remove_trip_by_planned_event:{}", self.id)), + ) + .await; + } + } + + let rower = Registration::all_rower(db, self.trip_details_id).await; + for user in rower { + if let Some(user) = User::find_by_name(db, &user.name).await { + let notes = match notes { + Some(n) if !n.is_empty() => n, + _ => ".", + }; + + Notification::create( + db, + &user, + &format!( + "Die Ausfahrt {} am {} um {} wurde abgesagt{}", + self.name, self.day, self.planned_starting_time, notes + ), + "Absage Ausfahrt", + None, + Some(&format!( + "remove_user_trip_with_trip_details_id:{}", + tripdetails.id + )), + ) + .await; + } + } + } + if max_people > 0 && was_already_cancelled { + Notification::delete_by_action( + db, + &format!("remove_user_trip_with_trip_details_id:{}", tripdetails.id), + ) + .await; + Notification::delete_by_action( + db, + &format!("remove_trip_by_planned_event:{}", self.id), + ) + .await; + } } pub async fn delete(&self, db: &SqlitePool) -> Result<(), String> { @@ -250,7 +316,7 @@ INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id", "Event kann nicht gelöscht werden, weil mind. 1 Ruderer angemeldet ist.".into(), ); } - if Registration::all_cox(db, self.trip_details_id).await.len() > 0 { + if Registration::all_cox(db, self.id).await.len() > 0 { return Err( "Event kann nicht gelöscht werden, weil mind. 1 Steuerperson angemeldet ist." .into(), @@ -326,7 +392,7 @@ mod test { let pool = testdb!(); let planned_event = PlannedEvent::find_by_id(&pool, 1).await.unwrap(); - planned_event.delete(&pool).await; + planned_event.delete(&pool).await.unwrap(); let res = PlannedEvent::get_for_day(&pool, NaiveDate::from_ymd_opt(1970, 1, 1).unwrap()).await; diff --git a/src/model/trip.rs b/src/model/trip.rs index 704c4b9..4b1badd 100644 --- a/src/model/trip.rs +++ b/src/model/trip.rs @@ -137,6 +137,10 @@ WHERE trip.id=? return Err(CoxHelpError::DetailsLocked); } + if planned_event.max_people == 0 { + return Err(CoxHelpError::CanceledEvent); + } + match sqlx::query!( "INSERT INTO trip (cox_id, planned_event_id) VALUES(?, ?)", cox.id, @@ -193,6 +197,9 @@ WHERE day=? return Err(TripUpdateError::TripDetailsDoesNotExist); //TODO: Remove? }; + let tripdetails = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); + let was_already_cancelled = tripdetails.max_people == 0; + sqlx::query!( "UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ?, always_show = ?, is_locked = ? WHERE id = ?", max_people, @@ -206,7 +213,7 @@ WHERE day=? .await .unwrap(); //Okay, as trip_details can only be created with proper DB backing - if max_people == 0 { + if max_people == 0 && !was_already_cancelled { let rowers = TripWithUserAndType::from(db, trip.clone()).await.rower; for user in rowers { if let Some(user) = User::find_by_name(db, &user.name).await { @@ -240,6 +247,14 @@ WHERE day=? .await; } + if max_people > 0 && was_already_cancelled { + Notification::delete_by_action( + db, + &format!("remove_user_trip_with_trip_details_id:{}", trip_details_id), + ) + .await; + } + let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); trip_details.check_free_spaces(db).await; @@ -324,6 +339,7 @@ pub enum CoxHelpError { AlreadyRegisteredAsRower, AlreadyRegisteredAsCox, DetailsLocked, + CanceledEvent, } #[derive(Debug, PartialEq)] diff --git a/src/model/user.rs b/src/model/user.rs index a0a1c1b..2066693 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -435,7 +435,7 @@ WHERE id like ? " SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user -WHERE name like ? +WHERE name=? ", name ) diff --git a/src/tera/cox.rs b/src/tera/cox.rs index cc31580..a2610e9 100644 --- a/src/tera/cox.rs +++ b/src/tera/cox.rs @@ -97,6 +97,9 @@ async fn join(db: &State, planned_event_id: i64, cox: CoxUser) -> Fl .await; Flash::success(Redirect::to("/planned"), "Danke für's helfen!") } + Err(CoxHelpError::CanceledEvent) => { + Flash::error(Redirect::to("/planned"), "Die Ausfahrt wurde leider abgesagt...") + } Err(CoxHelpError::AlreadyRegisteredAsCox) => { Flash::error(Redirect::to("/planned"), "Du hilfst bereits aus!") } diff --git a/templates/admin/notification.html.tera b/templates/admin/notification.html.tera index ecc0531..9d9cc7c 100644 --- a/templates/admin/notification.html.tera +++ b/templates/admin/notification.html.tera @@ -8,7 +8,9 @@