delete cancelled trips if all rowers have seen the notification
This commit is contained in:
		| @@ -5,7 +5,7 @@ use regex::Regex; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; | ||||
|  | ||||
| use super::{role::Role, user::User}; | ||||
| use super::{role::Role, user::User, usertrip::UserTrip}; | ||||
|  | ||||
| #[derive(FromRow, Debug, Serialize, Deserialize, Clone)] | ||||
| pub struct Notification { | ||||
| @@ -140,15 +140,13 @@ ORDER BY read_at DESC, created_at DESC; | ||||
|             let re = Regex::new(r"^remove_user_trip_with_trip_details_id:(\d+)$").unwrap(); | ||||
|             if let Some(caps) = re.captures(action) { | ||||
|                 if let Some(matched) = caps.get(1) { | ||||
|                     if let Ok(number) = matched.as_str().parse::<i32>() { | ||||
|                         let _ = sqlx::query!( | ||||
|                             "DELETE FROM user_trip WHERE user_id = ? AND trip_details_id = ?", | ||||
|                             self.user_id, | ||||
|                             number | ||||
|                         ) | ||||
|                         .execute(db) | ||||
|                         .await | ||||
|                         .unwrap(); | ||||
|                     if let Ok(number) = matched.as_str().parse::<i64>() { | ||||
|                         if let Some(usertrip) = | ||||
|                             UserTrip::find_by_userid_and_trip_detail_id(db, self.user_id, number) | ||||
|                                 .await | ||||
|                         { | ||||
|                             let _ = usertrip.self_delete(db).await; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -215,12 +215,18 @@ WHERE day=? | ||||
|         let tripdetails = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); | ||||
|         let was_already_cancelled = tripdetails.max_people == 0; | ||||
|  | ||||
|         let is_locked = if update.max_people == 0 { | ||||
|             false | ||||
|         } else { | ||||
|             update.is_locked | ||||
|         }; | ||||
|  | ||||
|         sqlx::query!( | ||||
|             "UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ?, is_locked = ? WHERE id = ?", | ||||
|             update.max_people, | ||||
|             update.notes, | ||||
|             update.trip_type, | ||||
|             update.is_locked, | ||||
|             is_locked, | ||||
|             trip_details_id | ||||
|         ) | ||||
|         .execute(db) | ||||
| @@ -242,7 +248,7 @@ WHERE day=? | ||||
|                         db, | ||||
|                         &user, | ||||
|                         &format!( | ||||
|                             "Die Ausfahrt von {} am {} um {} wurde abgesagt. {}", | ||||
|                             "Die Ausfahrt von {} am {} um {} wurde abgesagt. {} Bitte gib Bescheid, dass du die Info erhalten hast indem du auf ✓ klickst.", | ||||
|                             update.cox.user.name, | ||||
|                             update.trip.day, | ||||
|                             update.trip.planned_starting_time, | ||||
|   | ||||
| @@ -1,9 +1,21 @@ | ||||
| use sqlx::SqlitePool; | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use sqlx::{FromRow, SqlitePool}; | ||||
|  | ||||
| use super::{notification::Notification, trip::Trip, tripdetails::TripDetails, user::User}; | ||||
| use super::{ | ||||
|     notification::Notification, | ||||
|     trip::{Trip, TripWithUserAndType}, | ||||
|     tripdetails::TripDetails, | ||||
|     user::{CoxUser, User}, | ||||
| }; | ||||
| use crate::model::tripdetails::{Action, CoxAtTrip::Yes}; | ||||
|  | ||||
| pub struct UserTrip {} | ||||
| #[derive(FromRow, Debug, Serialize, Deserialize, Clone)] | ||||
| pub struct UserTrip { | ||||
|     pub user_id: Option<i64>, | ||||
|     pub user_note: Option<String>, | ||||
|     pub trip_details_id: i64, | ||||
|     pub created_at: String, // TODO: switch to NaiveDateTime | ||||
| } | ||||
|  | ||||
| impl UserTrip { | ||||
|     pub async fn create( | ||||
| @@ -66,23 +78,27 @@ impl UserTrip { | ||||
|             .await | ||||
|             .unwrap(); | ||||
|  | ||||
|             user_note.unwrap() | ||||
|             user_note.clone().unwrap() | ||||
|         }; | ||||
|  | ||||
|         if let Some(trip) = Trip::find_by_trip_details(db, trip_details.id).await { | ||||
|             let cox = User::find_by_id(db, trip.cox_id as i32).await.unwrap(); | ||||
|             Notification::create( | ||||
|                 db, | ||||
|                 &cox, | ||||
|                 &format!( | ||||
|                     "{} hat sich für deine Ausfahrt am {} registriert", | ||||
|                     name_newly_registered_person, trip.day | ||||
|                 ), | ||||
|                 "Registrierung bei deiner Ausfahrt", | ||||
|                 None, | ||||
|                 None, | ||||
|             ) | ||||
|             .await; | ||||
|             if user_note.is_none() { | ||||
|                 // Don't show notification if we add guest (as only we are | ||||
|                 // allowed to do so) | ||||
|                 let cox = User::find_by_id(db, trip.cox_id as i32).await.unwrap(); | ||||
|                 Notification::create( | ||||
|                     db, | ||||
|                     &cox, | ||||
|                     &format!( | ||||
|                         "{} hat sich für deine Ausfahrt am {} registriert", | ||||
|                         name_newly_registered_person, trip.day | ||||
|                     ), | ||||
|                     "Registrierung bei deiner Ausfahrt", | ||||
|                     None, | ||||
|                     None, | ||||
|                 ) | ||||
|                 .await; | ||||
|             } | ||||
|  | ||||
|             trip_details.check_free_spaces(db).await; | ||||
|         } | ||||
| @@ -90,6 +106,34 @@ impl UserTrip { | ||||
|         Ok(name_newly_registered_person) | ||||
|     } | ||||
|  | ||||
|     pub async fn tripdetails(&self, db: &SqlitePool) -> TripDetails { | ||||
|         TripDetails::find_by_id(db, self.trip_details_id) | ||||
|             .await | ||||
|             .unwrap() | ||||
|     } | ||||
|  | ||||
|     pub async fn find_by_userid_and_trip_detail_id( | ||||
|         db: &SqlitePool, | ||||
|         user_id: i64, | ||||
|         trip_detail_id: i64, | ||||
|     ) -> Option<Self> { | ||||
|         sqlx::query_as!(Self, "SELECT user_id, user_note, trip_details_id, created_at FROM user_trip WHERE user_id= ? AND trip_details_id = ?", user_id, trip_detail_id) | ||||
|             .fetch_one(db) | ||||
|             .await | ||||
|             .ok() | ||||
|     } | ||||
|  | ||||
|     pub async fn self_delete(&self, db: &SqlitePool) -> Result<(), UserTripDeleteError> { | ||||
|         let trip_details = self.tripdetails(db).await; | ||||
|         if let Some(id) = self.user_id { | ||||
|             let user = User::find_by_id(db, id as i32).await.unwrap(); | ||||
|             return Self::delete(db, &user, &trip_details, self.user_note.clone()).await; | ||||
|         } | ||||
|  | ||||
|         Ok(()) // TODO: fixme | ||||
|     } | ||||
|  | ||||
|     //TODO: cleaner code | ||||
|     pub async fn delete( | ||||
|         db: &SqlitePool, | ||||
|         user: &User, | ||||
| @@ -104,7 +148,24 @@ impl UserTrip { | ||||
|             return Err(UserTripDeleteError::NotVisibleToUser); | ||||
|         } | ||||
|  | ||||
|         if let Some(name) = name { | ||||
|         let mut trip_to_delete = None; | ||||
|         let mut some_trip = None; | ||||
|         if let Some(trip) = Trip::find_by_trip_details(db, trip_details.id).await { | ||||
|             some_trip = Some(trip.clone()); | ||||
|             // If trip is cancelled, and lost rower just unregistered, delete the trip | ||||
|             if TripDetails::find_by_id(db, trip_details.id) | ||||
|                 .await | ||||
|                 .unwrap() | ||||
|                 .cancelled() | ||||
|             { | ||||
|                 let trip = TripWithUserAndType::from(db, trip.clone()).await; | ||||
|                 if trip.rower.len() == 1 { | ||||
|                     trip_to_delete = Some(trip.trip); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if let Some(name) = name.clone() { | ||||
|             if !trip_details.user_allowed_to_change(db, user).await { | ||||
|                 return Err(UserTripDeleteError::NotAllowedToDeleteGuest); | ||||
|             } | ||||
| @@ -132,6 +193,55 @@ impl UserTrip { | ||||
|             .await | ||||
|             .unwrap(); | ||||
|         } | ||||
|  | ||||
|         let mut add_info = ""; | ||||
|         if let Some(trip) = &trip_to_delete { | ||||
|             let cox = User::find_by_id(db, trip.cox_id as i32).await.unwrap(); | ||||
|             trip.delete(db, &CoxUser::new(db, cox).await.unwrap()) | ||||
|                 .await | ||||
|                 .unwrap(); | ||||
|             add_info = " Das war die letzte angemeldete Person. Nachdem nun alle Bescheid wissen, wird die Ausfahrt ab sofort nicht mehr angezeigt."; | ||||
|         } | ||||
|  | ||||
|         if let Some(trip) = some_trip { | ||||
|             let opt_cancelled = if trip_to_delete.is_some() { | ||||
|                 "abgesagten " | ||||
|             } else { | ||||
|                 "" | ||||
|             }; | ||||
|             if let Some(name) = name { | ||||
|                 if !add_info.is_empty() { | ||||
|                     let cox = User::find_by_id(db, trip.cox_id as i32).await.unwrap(); | ||||
|                     Notification::create( | ||||
|                         db, | ||||
|                         &cox, | ||||
|                         &format!( | ||||
|                             "Du hast {} von deiner {}Ausfahrt am {} abgemeldet.{}", | ||||
|                             name, opt_cancelled, trip.day, add_info | ||||
|                         ), | ||||
|                         "Abmeldung von deiner Ausfahrt", | ||||
|                         None, | ||||
|                         None, | ||||
|                     ) | ||||
|                     .await; | ||||
|                 } | ||||
|             } else { | ||||
|                 let cox = User::find_by_id(db, trip.cox_id as i32).await.unwrap(); | ||||
|                 Notification::create( | ||||
|                     db, | ||||
|                     &cox, | ||||
|                     &format!( | ||||
|                         "{} hat sich von deiner {}Ausfahrt am {} abgemeldet.{}", | ||||
|                         user.name, opt_cancelled, trip.day, add_info | ||||
|                     ), | ||||
|                     "Abmeldung von deiner Ausfahrt", | ||||
|                     None, | ||||
|                     None, | ||||
|                 ) | ||||
|                 .await; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Ok(()) | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user