rowt/src/model/trip.rs

166 lines
4.3 KiB
Rust
Raw Normal View History

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
}
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 = ?)",
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
}
/// 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
}
/// 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
{
Ok(_) => Ok(()),
Err(_) => Err(CoxHelpError::AlreadyRegisteredAsCox),
}
2023-04-04 15:16:21 +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();
}
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;
if registered_rower.len() > 0 {
return Err(TripDeleteError::SomebodyAlreadyRegistered);
}
let trip_cox = sqlx::query!("SELECT cox_id FROM trip WHERE id = ?", trip_id)
.fetch_one(db)
.await
.unwrap(); //TODO: fixme
if trip_cox.cox_id != user_id {
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-04 15:16:21 +02:00
pub enum CoxHelpError {
AlreadyRegisteredAsRower,
AlreadyRegisteredAsCox,
2023-04-04 15:16:21 +02:00
}
pub enum TripDeleteError {
SomebodyAlreadyRegistered,
NotYourTrip,
}