123 lines
3.3 KiB
Rust
123 lines
3.3 KiB
Rust
use chrono::{Duration, Local};
|
|
use futures::future;
|
|
use sqlx::{query, query_as};
|
|
use terminwahl_typen::{IdType, Nutzer, PlannedAppointment};
|
|
|
|
use crate::api::write::AppointmentTeacherSlot;
|
|
|
|
use super::Pool;
|
|
|
|
pub async fn save_appointments(
|
|
pool: &Pool,
|
|
appointments: &[PlannedAppointment],
|
|
nutzer_id: IdType,
|
|
validation_key: &str,
|
|
) -> Result<(), sqlx::Error> {
|
|
for appointment in appointments {
|
|
let _ = query!("DELETE FROM appointments WHERE datetime(expires) < datetime('now');")
|
|
.execute(pool)
|
|
.await;
|
|
let now = Local::now().naive_local();
|
|
let in_three_hours = now + Duration::hours(3);
|
|
query!(
|
|
"INSERT INTO appointments (teacher_id, slot_id, nutzer_id, validation_key, expires) VALUES ($1, $2, $3, $4, $5)",
|
|
appointment.teacher_id,
|
|
appointment.slot_id,
|
|
nutzer_id,
|
|
validation_key,
|
|
in_three_hours
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn save_nutzer(pool: &Pool, nutzer: &Nutzer) -> Result<IdType, sqlx::Error> {
|
|
query!(
|
|
"INSERT INTO nutzer (name, schueler, email) VALUES ($1, $2, $3)",
|
|
nutzer.name,
|
|
nutzer.schüler,
|
|
nutzer.email
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
|
|
let db_nutzer = query!(
|
|
"SELECT id FROM nutzer WHERE name = ? and email = ?",
|
|
nutzer.name,
|
|
nutzer.email
|
|
)
|
|
.fetch_one(pool)
|
|
.await?;
|
|
|
|
Ok(db_nutzer.id)
|
|
}
|
|
|
|
pub async fn confirm_appointments(
|
|
pool: &Pool,
|
|
validation_key: &str,
|
|
) -> Result<Vec<AppointmentTeacherSlot>, sqlx::Error> {
|
|
let _ = query!(
|
|
"UPDATE appointments SET expires = NULL WHERE validation_key = ?",
|
|
validation_key
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
let appointments = query_as!(
|
|
PlannedAppointment,
|
|
"Select teacher_id, slot_id from appointments WHERE validation_key = ? and expires is NULL",
|
|
validation_key
|
|
)
|
|
.fetch_all(pool)
|
|
.await?;
|
|
|
|
let full_appointments = future::try_join_all(appointments.into_iter().map(
|
|
|PlannedAppointment {
|
|
teacher_id,
|
|
slot_id,
|
|
}| { AppointmentTeacherSlot::get(pool, teacher_id, slot_id) },
|
|
))
|
|
.await
|
|
.expect("Failed to get full list of appointments");
|
|
|
|
Ok(full_appointments)
|
|
}
|
|
|
|
pub async fn cancel_appointment(
|
|
pool: &Pool,
|
|
teacher_id: IdType,
|
|
slot_id: IdType,
|
|
validation_key: &str,
|
|
) -> Result<Vec<AppointmentTeacherSlot>, sqlx::Error> {
|
|
let _ = query!(
|
|
"DELETE FROM appointments WHERE teacher_id = ? AND slot_id = ? AND validation_key = ?",
|
|
teacher_id,
|
|
slot_id,
|
|
validation_key
|
|
)
|
|
.execute(pool)
|
|
.await?;
|
|
|
|
// Fetch the remaining appointments
|
|
let appointments = query_as!(
|
|
PlannedAppointment,
|
|
"Select teacher_id, slot_id from appointments WHERE validation_key = ? and expires is NULL",
|
|
validation_key
|
|
)
|
|
.fetch_all(pool)
|
|
.await?;
|
|
|
|
// Fetch the teacher names and times
|
|
let full_appointments = future::try_join_all(appointments.into_iter().map(
|
|
|PlannedAppointment {
|
|
teacher_id,
|
|
slot_id,
|
|
}| { AppointmentTeacherSlot::get(pool, teacher_id, slot_id) },
|
|
))
|
|
.await
|
|
.expect("Failed to get full list of appointments");
|
|
|
|
Ok(full_appointments)
|
|
}
|