staging #374
@ -30,12 +30,12 @@ pub struct Trip {
|
|||||||
pub struct TripWithUserAndType {
|
pub struct TripWithUserAndType {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub trip: Trip,
|
pub trip: Trip,
|
||||||
rower: Vec<Registration>,
|
pub rower: Vec<Registration>,
|
||||||
trip_type: Option<TripType>,
|
trip_type: Option<TripType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TripWithUserAndType {
|
impl TripWithUserAndType {
|
||||||
async fn from(db: &SqlitePool, trip: Trip) -> Self {
|
pub async fn from(db: &SqlitePool, trip: Trip) -> Self {
|
||||||
let mut trip_type = None;
|
let mut trip_type = None;
|
||||||
if let Some(trip_type_id) = trip.trip_type_id {
|
if let Some(trip_type_id) = trip.trip_type_id {
|
||||||
trip_type = TripType::find_by_id(db, trip_type_id).await;
|
trip_type = TripType::find_by_id(db, trip_type_id).await;
|
||||||
@ -230,6 +230,9 @@ WHERE day=?
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap();
|
||||||
|
trip_details.check_free_spaces(db).await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,11 @@ use rocket::FromForm;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, SqlitePool};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
notification::Notification,
|
||||||
|
trip::{Trip, TripWithUserAndType},
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
||||||
pub struct TripDetails {
|
pub struct TripDetails {
|
||||||
pub id: i64,
|
pub id: i64,
|
||||||
@ -64,6 +69,57 @@ WHERE day = ? AND planned_starting_time = ?
|
|||||||
.await.unwrap()
|
.await.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This function is called when a person registers to a trip or when the cox changes the
|
||||||
|
/// amount of free places.
|
||||||
|
pub async fn check_free_spaces(&self, db: &SqlitePool) {
|
||||||
|
if !self.is_full(db).await {
|
||||||
|
// We still have space for new people, no need to do anything
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let other_trips_same_time = Self::find_by_startingdatetime(
|
||||||
|
db,
|
||||||
|
self.day.clone(),
|
||||||
|
self.planned_starting_time.clone(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
for trip in &other_trips_same_time {
|
||||||
|
if !trip.is_full(db).await {
|
||||||
|
// There are trips on the same time, with open places
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We just got fully booked and there are no other trips with remaining rower places. Send
|
||||||
|
// notification to all coxes which are registered as non-cox.
|
||||||
|
for trip_details in other_trips_same_time {
|
||||||
|
let Some(trip) = Trip::find_by_trip_details(db, trip_details.id).await else {
|
||||||
|
// This trip_details belongs to a planned_event, no need to do anything
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let pot_coxes = TripWithUserAndType::from(db, trip.clone()).await;
|
||||||
|
let pot_coxes = pot_coxes.rower;
|
||||||
|
for user in pot_coxes {
|
||||||
|
let cox = User::find_by_id(db, trip.cox_id as i32).await.unwrap();
|
||||||
|
let Some(user) = User::find_by_name(db, &user.name).await else {
|
||||||
|
// User is a guest, no need to bother.
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if !user.has_role(db, "cox").await {
|
||||||
|
// User is no cox, no need to bother
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if user.id == cox.id {
|
||||||
|
// User already offers a trip, no need to bother
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Notification::create(db, &user, &format!("Du hast dich als Ruderer bei der Ausfahrt von {} am {} um {} angemeldet. Bei allen Ausfahrten zu dieser Zeit sind nun alle Plätze ausgebucht. Damit noch mehr (Nicht-Steuerleute) mitfahren können, wäre es super, wenn du eine eigene Ausfahrt zur selben Zeit ausschreiben könntest.", cox.name, self.day, self.planned_starting_time), "Volle Ausfahrt", None).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new entry in `trip_details` and returns its id.
|
/// Creates a new entry in `trip_details` and returns its id.
|
||||||
pub async fn create(db: &SqlitePool, tripdetails: TripDetailsToAdd<'_>) -> i64 {
|
pub async fn create(db: &SqlitePool, tripdetails: TripDetailsToAdd<'_>) -> i64 {
|
||||||
let query = sqlx::query!(
|
let query = sqlx::query!(
|
||||||
|
@ -1,6 +1,11 @@
|
|||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
use super::{notification::Notification, trip::Trip, tripdetails::TripDetails, user::User};
|
use super::{
|
||||||
|
notification::Notification,
|
||||||
|
trip::{Trip, TripWithUserAndType},
|
||||||
|
tripdetails::TripDetails,
|
||||||
|
user::User,
|
||||||
|
};
|
||||||
use crate::model::tripdetails::{Action, CoxAtTrip::Yes};
|
use crate::model::tripdetails::{Action, CoxAtTrip::Yes};
|
||||||
|
|
||||||
pub struct UserTrip {}
|
pub struct UserTrip {}
|
||||||
@ -79,6 +84,8 @@ impl UserTrip {
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
trip_details.check_free_spaces(db).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(name_newly_registered_person)
|
Ok(name_newly_registered_person)
|
||||||
|
Loading…
Reference in New Issue
Block a user