2023-04-04 15:16:21 +02:00
|
|
|
use chrono::NaiveDate;
|
|
|
|
use serde::Serialize;
|
|
|
|
use sqlx::SqlitePool;
|
|
|
|
|
2023-04-05 17:25:22 +02:00
|
|
|
use super::planned_event::Registration;
|
|
|
|
|
2023-04-04 15:16:21 +02:00
|
|
|
#[derive(Serialize, Clone)]
|
|
|
|
pub struct Trip {
|
|
|
|
id: i64,
|
|
|
|
cox_id: i64,
|
|
|
|
cox_name: String,
|
|
|
|
trip_details_id: Option<i64>,
|
|
|
|
planned_starting_time: String,
|
|
|
|
max_people: i64,
|
|
|
|
day: String,
|
|
|
|
notes: Option<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize)]
|
|
|
|
pub struct TripWithUser {
|
|
|
|
#[serde(flatten)]
|
|
|
|
trip: Trip,
|
2023-04-05 17:25:22 +02:00
|
|
|
rower: Vec<Registration>,
|
2023-04-04 15:16:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Trip {
|
|
|
|
pub async fn get_for_day(db: &SqlitePool, day: NaiveDate) -> Vec<TripWithUser> {
|
2023-04-04 19:49:27 +02:00
|
|
|
let day = format!("{day}");
|
2023-04-04 15:16:21 +02:00
|
|
|
let trips = sqlx::query_as!(
|
|
|
|
Trip,
|
|
|
|
"
|
|
|
|
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes
|
|
|
|
FROM trip
|
|
|
|
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
|
|
|
|
INNER JOIN user ON trip.cox_id = user.id
|
|
|
|
WHERE day=?
|
|
|
|
",
|
|
|
|
day
|
|
|
|
)
|
|
|
|
.fetch_all(db)
|
|
|
|
.await
|
|
|
|
.unwrap(); //TODO: fixme
|
|
|
|
let mut ret = Vec::new();
|
|
|
|
for trip in trips {
|
|
|
|
ret.push(TripWithUser {
|
|
|
|
trip: trip.clone(),
|
|
|
|
rower: Self::get_all_rower_for_id(db, trip.id).await,
|
2023-04-04 19:49:27 +02:00
|
|
|
});
|
2023-04-04 15:16:21 +02:00
|
|
|
}
|
|
|
|
ret
|
|
|
|
}
|
|
|
|
|
2023-04-07 11:16:39 +02:00
|
|
|
async fn get_all_rower_for_id(db: &SqlitePool, trip_id: i64) -> Vec<Registration> {
|
2023-04-05 17:25:22 +02:00
|
|
|
sqlx::query_as!(
|
|
|
|
Registration,
|
2023-04-04 15:16:21 +02:00
|
|
|
"
|
2023-04-05 17:25:22 +02:00
|
|
|
SELECT
|
|
|
|
(SELECT name FROM user WHERE user_trip.user_id = user.id) as name,
|
|
|
|
(SELECT created_at FROM user WHERE user_trip.user_id = user.id) as registered_at
|
|
|
|
FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM trip WHERE id = ?)",
|
2023-04-07 11:16:39 +02:00
|
|
|
trip_id
|
2023-04-04 15:16:21 +02:00
|
|
|
)
|
|
|
|
.fetch_all(db)
|
|
|
|
.await
|
2023-04-05 17:25:22 +02:00
|
|
|
.unwrap() //TODO: fixme
|
2023-04-04 15:16:21 +02:00
|
|
|
}
|
|
|
|
|
2023-04-05 21:49:48 +02:00
|
|
|
/// Cox decides to create own trip.
|
2023-04-04 15:16:21 +02:00
|
|
|
pub async fn new_own(db: &SqlitePool, cox_id: i64, trip_details_id: i64) {
|
|
|
|
sqlx::query!(
|
|
|
|
"INSERT INTO trip (cox_id, trip_details_id) VALUES(?, ?)",
|
|
|
|
cox_id,
|
|
|
|
trip_details_id
|
|
|
|
)
|
|
|
|
.execute(db)
|
|
|
|
.await
|
|
|
|
.unwrap(); //TODO: fixme
|
|
|
|
}
|
|
|
|
|
2023-04-05 21:49:48 +02:00
|
|
|
/// Cox decides to help in a planned event.
|
|
|
|
pub async fn new_join(
|
|
|
|
db: &SqlitePool,
|
|
|
|
cox_id: i64,
|
|
|
|
planned_event_id: i64,
|
|
|
|
) -> Result<(), CoxHelpError> {
|
|
|
|
let is_rower = sqlx::query!(
|
|
|
|
"SELECT count(*) as amount
|
|
|
|
FROM user_trip
|
|
|
|
WHERE trip_details_id =
|
|
|
|
(SELECT trip_details_id FROM planned_event WHERE id = ?)
|
|
|
|
AND user_id = ?",
|
|
|
|
planned_event_id,
|
|
|
|
cox_id
|
|
|
|
)
|
|
|
|
.fetch_one(db)
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
if is_rower.amount > 0 {
|
|
|
|
return Err(CoxHelpError::AlreadyRegisteredAsRower);
|
|
|
|
}
|
|
|
|
|
|
|
|
match sqlx::query!(
|
2023-04-04 15:16:21 +02:00
|
|
|
"INSERT INTO trip (cox_id, planned_event_id) VALUES(?, ?)",
|
|
|
|
cox_id,
|
|
|
|
planned_event_id
|
|
|
|
)
|
|
|
|
.execute(db)
|
|
|
|
.await
|
2023-04-05 21:49:48 +02:00
|
|
|
{
|
|
|
|
Ok(_) => Ok(()),
|
|
|
|
Err(_) => Err(CoxHelpError::AlreadyRegisteredAsCox),
|
|
|
|
}
|
2023-04-04 15:16:21 +02:00
|
|
|
}
|
|
|
|
|
2023-04-07 11:54:56 +02:00
|
|
|
/// Cox decides to update own trip.
|
|
|
|
pub async fn update_own(
|
|
|
|
db: &SqlitePool,
|
|
|
|
cox_id: i64,
|
|
|
|
trip_id: i64,
|
|
|
|
max_people: i32,
|
|
|
|
notes: Option<String>,
|
|
|
|
) -> Result<(), TripUpdateError> {
|
|
|
|
if !Self::is_trip_from_user(db, cox_id, trip_id).await {
|
|
|
|
return Err(TripUpdateError::NotYourTrip);
|
|
|
|
}
|
|
|
|
|
|
|
|
let trip_details = sqlx::query!(
|
|
|
|
"SELECT trip_details_id as id FROM trip WHERE id = ?",
|
|
|
|
trip_id
|
|
|
|
)
|
|
|
|
.fetch_one(db)
|
|
|
|
.await
|
|
|
|
.unwrap(); //TODO: fixme
|
|
|
|
let trip_details_id = match trip_details.id {
|
|
|
|
Some(id) => id,
|
|
|
|
None => {
|
|
|
|
return Err(TripUpdateError::TripDoesNotExist);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
sqlx::query!(
|
|
|
|
"UPDATE trip_details SET max_people = ?, notes = ? WHERE id = ?",
|
|
|
|
max_people,
|
|
|
|
notes,
|
|
|
|
trip_details_id
|
|
|
|
)
|
|
|
|
.execute(db)
|
|
|
|
.await
|
|
|
|
.unwrap(); //TODO: fixme
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2023-04-07 11:16:39 +02:00
|
|
|
pub async fn delete_by_planned_event_id(db: &SqlitePool, user_id: i64, planned_event_id: i64) {
|
2023-04-04 15:16:21 +02:00
|
|
|
let _ = sqlx::query!(
|
|
|
|
"DELETE FROM trip WHERE cox_id = ? AND planned_event_id = ?",
|
|
|
|
user_id,
|
|
|
|
planned_event_id
|
|
|
|
)
|
|
|
|
.execute(db)
|
|
|
|
.await
|
|
|
|
.is_ok();
|
|
|
|
}
|
2023-04-07 11:16:39 +02:00
|
|
|
|
|
|
|
pub(crate) async fn delete(
|
|
|
|
db: &SqlitePool,
|
|
|
|
user_id: i64,
|
|
|
|
trip_id: i64,
|
|
|
|
) -> Result<(), TripDeleteError> {
|
|
|
|
let registered_rower = Self::get_all_rower_for_id(db, trip_id).await;
|
2023-04-24 14:34:06 +02:00
|
|
|
if registered_rower.is_empty() {
|
2023-04-07 11:16:39 +02:00
|
|
|
return Err(TripDeleteError::SomebodyAlreadyRegistered);
|
|
|
|
}
|
|
|
|
|
2023-04-07 11:54:56 +02:00
|
|
|
if !Self::is_trip_from_user(db, user_id, trip_id).await {
|
2023-04-07 11:16:39 +02:00
|
|
|
return Err(TripDeleteError::NotYourTrip);
|
|
|
|
}
|
|
|
|
|
|
|
|
sqlx::query!(
|
|
|
|
"DELETE FROM trip WHERE cox_id = ? AND id = ?",
|
|
|
|
user_id,
|
|
|
|
trip_id
|
|
|
|
)
|
|
|
|
.execute(db)
|
|
|
|
.await
|
|
|
|
.unwrap(); //TODO: fixme
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2023-04-07 11:54:56 +02:00
|
|
|
|
|
|
|
async fn is_trip_from_user(db: &SqlitePool, user_id: i64, trip_id: i64) -> bool {
|
|
|
|
let trip_cox = sqlx::query!("SELECT cox_id FROM trip WHERE id = ?", trip_id)
|
|
|
|
.fetch_one(db)
|
|
|
|
.await
|
|
|
|
.unwrap(); //TODO: fixme
|
|
|
|
trip_cox.cox_id == user_id
|
|
|
|
}
|
2023-04-05 21:49:48 +02:00
|
|
|
}
|
2023-04-04 15:16:21 +02:00
|
|
|
|
2023-04-05 21:49:48 +02:00
|
|
|
pub enum CoxHelpError {
|
|
|
|
AlreadyRegisteredAsRower,
|
|
|
|
AlreadyRegisteredAsCox,
|
2023-04-04 15:16:21 +02:00
|
|
|
}
|
2023-04-07 11:16:39 +02:00
|
|
|
|
|
|
|
pub enum TripDeleteError {
|
|
|
|
SomebodyAlreadyRegistered,
|
|
|
|
NotYourTrip,
|
|
|
|
}
|
2023-04-07 11:54:56 +02:00
|
|
|
|
|
|
|
pub enum TripUpdateError {
|
|
|
|
NotYourTrip,
|
|
|
|
TripDoesNotExist,
|
|
|
|
}
|