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)
}