2023-07-23 19:45:48 +02:00
|
|
|
use chrono::NaiveDate;
|
2023-07-25 13:22:11 +02:00
|
|
|
use rocket::FromForm;
|
2023-04-04 12:19:56 +02:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use sqlx::{FromRow, SqlitePool};
|
|
|
|
|
|
|
|
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
|
|
|
pub struct TripDetails {
|
|
|
|
pub id: i64,
|
2023-07-25 13:22:11 +02:00
|
|
|
pub planned_starting_time: String,
|
|
|
|
pub max_people: i64,
|
|
|
|
pub day: String,
|
|
|
|
pub notes: Option<String>,
|
2023-04-29 18:57:01 +02:00
|
|
|
pub allow_guests: bool,
|
2023-07-25 13:22:11 +02:00
|
|
|
pub trip_type_id: Option<i64>,
|
|
|
|
pub always_show: bool,
|
2023-08-09 11:54:18 +02:00
|
|
|
pub is_locked: bool,
|
2023-07-25 13:22:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(FromForm, Serialize)]
|
|
|
|
pub struct TripDetailsToAdd<'r> {
|
|
|
|
//TODO: properly parse `planned_starting_time`
|
|
|
|
pub planned_starting_time: &'r str,
|
|
|
|
pub max_people: i32,
|
|
|
|
pub day: String,
|
|
|
|
//#[field(validate = range(1..))] TODO: fixme
|
|
|
|
pub notes: Option<&'r str>,
|
|
|
|
pub trip_type: Option<i64>,
|
|
|
|
pub allow_guests: bool,
|
|
|
|
pub always_show: bool,
|
2023-04-04 12:19:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl TripDetails {
|
2023-04-26 12:21:30 +02:00
|
|
|
pub async fn find_by_id(db: &SqlitePool, id: i64) -> Option<Self> {
|
|
|
|
sqlx::query_as!(
|
|
|
|
TripDetails,
|
|
|
|
"
|
2023-08-09 11:54:18 +02:00
|
|
|
SELECT id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id, always_show, is_locked
|
2023-04-26 12:21:30 +02:00
|
|
|
FROM trip_details
|
|
|
|
WHERE id like ?
|
|
|
|
",
|
|
|
|
id
|
|
|
|
)
|
|
|
|
.fetch_one(db)
|
|
|
|
.await
|
|
|
|
.ok()
|
|
|
|
}
|
|
|
|
|
2023-04-26 11:31:02 +02:00
|
|
|
/// Creates a new entry in `trip_details` and returns its id.
|
2023-07-25 13:22:11 +02:00
|
|
|
pub async fn create(db: &SqlitePool, tripdetails: TripDetailsToAdd<'_>) -> i64 {
|
2023-04-04 12:19:56 +02:00
|
|
|
let query = sqlx::query!(
|
2023-07-23 19:45:48 +02:00
|
|
|
"INSERT INTO trip_details(planned_starting_time, max_people, day, notes, allow_guests, trip_type_id, always_show) VALUES(?, ?, ?, ?, ?, ?, ?)" ,
|
2023-07-25 13:22:11 +02:00
|
|
|
tripdetails.planned_starting_time,
|
|
|
|
tripdetails.max_people,
|
|
|
|
tripdetails.day,
|
|
|
|
tripdetails.notes,
|
|
|
|
tripdetails.allow_guests,
|
|
|
|
tripdetails.trip_type,
|
|
|
|
tripdetails.always_show
|
2023-04-04 12:19:56 +02:00
|
|
|
)
|
|
|
|
.execute(db)
|
|
|
|
.await
|
2023-04-26 12:21:30 +02:00
|
|
|
.unwrap(); //Okay, TripDetails can only be created if self.id exists
|
2023-04-04 12:19:56 +02:00
|
|
|
query.last_insert_rowid()
|
|
|
|
}
|
2023-04-26 12:21:30 +02:00
|
|
|
|
|
|
|
pub async fn is_full(&self, db: &SqlitePool) -> bool {
|
|
|
|
let amount_currently_registered = sqlx::query!(
|
|
|
|
"SELECT COUNT(*) as count FROM user_trip WHERE trip_details_id = ?",
|
|
|
|
self.id
|
|
|
|
)
|
|
|
|
.fetch_one(db)
|
|
|
|
.await
|
|
|
|
.unwrap(); //TODO: fixme
|
|
|
|
let amount_currently_registered = i64::from(amount_currently_registered.count);
|
|
|
|
|
2023-05-03 13:32:23 +02:00
|
|
|
amount_currently_registered >= self.max_people
|
2023-04-26 12:21:30 +02:00
|
|
|
}
|
2023-07-23 19:45:48 +02:00
|
|
|
|
|
|
|
pub async fn pinned_days(db: &SqlitePool, amount_days_to_skip: i64) -> Vec<NaiveDate> {
|
|
|
|
let query = format!(
|
|
|
|
"SELECT DISTINCT day
|
|
|
|
FROM trip_details
|
|
|
|
WHERE always_show=true AND day > datetime('now' , '+{} days')
|
|
|
|
ORDER BY day;",
|
|
|
|
amount_days_to_skip
|
|
|
|
);
|
|
|
|
let days: Vec<String> = sqlx::query_scalar(&query).fetch_all(db).await.unwrap();
|
|
|
|
days.into_iter()
|
|
|
|
.map(|a| NaiveDate::parse_from_str(&a, "%Y-%m-%d").unwrap())
|
|
|
|
.collect()
|
|
|
|
}
|
2023-04-04 12:19:56 +02:00
|
|
|
}
|
2023-04-26 11:31:02 +02:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2023-07-25 13:22:11 +02:00
|
|
|
use crate::{model::tripdetails::TripDetailsToAdd, testdb};
|
2023-04-26 11:31:02 +02:00
|
|
|
|
|
|
|
use super::TripDetails;
|
|
|
|
use sqlx::SqlitePool;
|
|
|
|
|
|
|
|
#[sqlx::test]
|
2023-04-26 12:21:30 +02:00
|
|
|
fn test_find_true() {
|
|
|
|
let pool = testdb!();
|
|
|
|
|
|
|
|
assert!(TripDetails::find_by_id(&pool, 1).await.is_some());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[sqlx::test]
|
|
|
|
fn test_find_false() {
|
|
|
|
let pool = testdb!();
|
|
|
|
|
|
|
|
assert!(TripDetails::find_by_id(&pool, 1337).await.is_none());
|
|
|
|
}
|
|
|
|
|
|
|
|
#[sqlx::test]
|
|
|
|
fn test_create() {
|
2023-04-26 11:31:02 +02:00
|
|
|
let pool = testdb!();
|
|
|
|
|
|
|
|
assert_eq!(
|
2023-04-29 18:57:01 +02:00
|
|
|
TripDetails::create(
|
|
|
|
&pool,
|
2023-07-25 13:22:11 +02:00
|
|
|
TripDetailsToAdd {
|
|
|
|
planned_starting_time: "10:00".into(),
|
|
|
|
max_people: 2,
|
|
|
|
day: "1970-01-01".into(),
|
|
|
|
notes: None,
|
|
|
|
allow_guests: false,
|
|
|
|
trip_type: None,
|
|
|
|
always_show: false
|
|
|
|
}
|
2023-04-29 18:57:01 +02:00
|
|
|
)
|
|
|
|
.await,
|
2023-04-26 16:54:53 +02:00
|
|
|
3,
|
2023-04-26 11:31:02 +02:00
|
|
|
);
|
|
|
|
assert_eq!(
|
2023-04-29 18:57:01 +02:00
|
|
|
TripDetails::create(
|
|
|
|
&pool,
|
2023-07-25 13:22:11 +02:00
|
|
|
TripDetailsToAdd {
|
|
|
|
planned_starting_time: "10:00".into(),
|
|
|
|
max_people: 2,
|
|
|
|
day: "1970-01-01".into(),
|
|
|
|
notes: None,
|
|
|
|
allow_guests: false,
|
|
|
|
trip_type: None,
|
|
|
|
always_show: false
|
|
|
|
}
|
2023-04-29 18:57:01 +02:00
|
|
|
)
|
|
|
|
.await,
|
2023-04-26 16:54:53 +02:00
|
|
|
4,
|
2023-04-26 11:31:02 +02:00
|
|
|
);
|
|
|
|
}
|
2023-04-26 12:21:30 +02:00
|
|
|
|
|
|
|
#[sqlx::test]
|
|
|
|
fn test_false_full() {
|
|
|
|
let pool = testdb!();
|
|
|
|
|
|
|
|
let trip_details = TripDetails::find_by_id(&pool, 1).await.unwrap();
|
|
|
|
assert_eq!(trip_details.is_full(&pool).await, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[sqlx::test]
|
|
|
|
fn test_true_full() {
|
|
|
|
//TODO: register user for trip_details = 1; check if is_full returns true
|
|
|
|
}
|
2023-04-28 21:19:51 +02:00
|
|
|
|
|
|
|
//TODO: add new tripdetails test with trip_type != None
|
2023-04-26 11:31:02 +02:00
|
|
|
}
|