brass/src/models/availabillity.rs

276 lines
10 KiB
Rust

use chrono::{NaiveDate, NaiveTime};
use sqlx::{query, PgPool};
use super::{function::Function, role::Role, user::User, Area};
#[derive(Clone)]
pub struct Availabillity {
pub id: i32,
pub user_id: i32,
pub user: Option<User>,
pub date: NaiveDate,
pub start_time: Option<NaiveTime>,
pub end_time: Option<NaiveTime>,
pub comment: Option<String>,
}
impl Availabillity {
pub async fn create(
pool: &PgPool,
user_id: i32,
date: NaiveDate,
start_time: Option<NaiveTime>,
end_time: Option<NaiveTime>,
comment: Option<String>,
) -> anyhow::Result<i32> {
let result = match (start_time, end_time, comment) {
(Some(start_time), Some(end_time), Some(comment)) => query!("INSERT INTO availabillity (userId, date, startTime, endTime, comment) VALUES ($1, $2, $3, $4, $5) RETURNING id;", user_id, date, start_time, end_time, comment).fetch_one(pool).await?.id,
(Some(start_time), Some(end_time), None) => query!("INSERT INTO availabillity (userId, date, startTime, endTime) VALUES ($1, $2, $3, $4) RETURNING id;", user_id, date, start_time, end_time).fetch_one(pool).await?.id,
(None, None, Some(comment)) => query!("INSERT INTO availabillity (userId, date, comment) VALUES ($1, $2, $3) RETURNING id;", user_id, date, comment).fetch_one(pool).await?.id,
(_, _, _) => query!("INSERT INTO availabillity (userId, date) VALUES ($1, $2) RETURNING id;", user_id, date).fetch_one(pool).await?.id
};
Ok(result)
}
pub async fn read_by_date_and_area_including_user(
pool: &PgPool,
date: NaiveDate,
area_id: i32
) -> anyhow::Result<Vec<Availabillity>> {
let records = query!(
r##"
SELECT
availabillity.id,
availabillity.userId,
availabillity.date,
availabillity.startTime,
availabillity.endTime,
availabillity.comment,
user_.name,
user_.email,
user_.password,
user_.salt,
user_.role AS "role: Role",
user_.function AS "function: Function",
user_.areaId,
user_.locked,
user_.lastLogin,
user_.receiveNotifications
FROM availabillity
JOIN user_ ON availabillity.userId = user_.id
WHERE availabillity.date = $1
AND user_.areaId = $2;
"##,
date,
area_id
)
.fetch_all(pool)
.await?;
let availabillities = records
.iter()
.map(|r| Availabillity {
id: r.id,
user_id: r.userid,
user: Some(User {
id: r.userid,
name: r.name.clone(),
email: r.email.clone(),
password: r.password.clone(),
salt: r.salt.clone(),
role: r.role.clone(),
function: r.function.clone(),
area_id: r.areaid,
area: None,
locked: r.locked,
last_login: r.lastlogin,
receive_notifications: r.receivenotifications,
}),
date: r.date,
start_time: r.starttime,
end_time: r.endtime,
comment: r.comment.clone(),
})
.collect();
Ok(availabillities)
}
pub async fn read_not_assigned_by_date_including_user(
pool: &PgPool,
date: NaiveDate,
) -> anyhow::Result<Vec<Availabillity>> {
let records = query!(
r##"
SELECT
availabillity.id,
availabillity.userId,
availabillity.date,
availabillity.startTime,
availabillity.endTime,
availabillity.comment,
user_.name,
user_.email,
user_.password,
user_.salt,
user_.role AS "role: Role",
user_.function AS "function: Function",
user_.areaId,
user_.locked,
user_.lastLogin,
user_.receiveNotifications
FROM availabillity
LEFT JOIN assignment ON availabillity.Id = assignment.availabillityId
JOIN user_ ON availabillity.userId = user_.id
WHERE availabillity.date = $1;
"##,
date
)
.fetch_all(pool)
.await?;
let availabillities = records
.iter()
.map(|r| Availabillity {
id: r.id,
user_id: r.userid,
user: Some(User {
id: r.userid,
name: r.name.clone(),
email: r.email.clone(),
password: r.password.clone(),
salt: r.salt.clone(),
role: r.role.clone(),
function: r.function.clone(),
area_id: r.areaid,
area: None,
locked: r.locked,
last_login: r.lastlogin,
receive_notifications: r.receivenotifications,
}),
date: r.date,
start_time: r.starttime,
end_time: r.endtime,
comment: r.comment.clone(),
})
.collect();
Ok(availabillities)
}
pub async fn read_by_id(pool: &PgPool, id: i32) -> anyhow::Result<Availabillity> {
let record = query!("SELECT * FROM availabillity WHERE id = $1", id)
.fetch_one(pool)
.await?;
let availabillity = Availabillity {
id: record.id,
user_id: record.userid,
user: None,
date: record.date,
start_time: record.starttime,
end_time: record.endtime,
comment: record.comment.clone(),
};
Ok(availabillity)
}
pub async fn read_for_export(
pool: &PgPool,
date_range: (NaiveDate, NaiveDate),
area_id: i32,
) -> anyhow::Result<Vec<Availabillity>> {
let records = query!(
r##"
SELECT
availabillity.id,
availabillity.userId,
availabillity.date,
availabillity.startTime,
availabillity.endTime,
availabillity.comment,
user_.name,
user_.email,
user_.password,
user_.salt,
user_.role AS "role: Role",
user_.function AS "function: Function",
user_.areaId,
user_.locked,
user_.lastLogin,
user_.receiveNotifications,
area.name AS areaName
FROM availabillity
JOIN user_ ON availabillity.userId = user_.id
JOIN area ON user_.areaId = area.id
WHERE user_.areaId = $1 AND
availabillity.date >= $2 AND
availabillity.date <= $3;
"##,
area_id,
date_range.0,
date_range.1
)
.fetch_all(pool)
.await?;
let availabillities = records
.iter()
.map(|r| Availabillity {
id: r.id,
user_id: r.userid,
user: Some(User {
id: r.userid,
name: r.name.clone(),
email: r.email.clone(),
password: r.password.clone(),
salt: r.salt.clone(),
role: r.role.clone(),
function: r.function.clone(),
area_id: r.areaid,
area: Some(Area {
id: r.areaid,
name: r.areaname.clone(),
}),
locked: r.locked,
last_login: r.lastlogin,
receive_notifications: r.receivenotifications,
}),
date: r.date,
start_time: r.starttime,
end_time: r.endtime,
comment: r.comment.clone(),
})
.collect();
Ok(availabillities)
}
pub async fn update(
pool: &PgPool,
id: i32,
updated_availabillity: &Availabillity,
) -> anyhow::Result<()> {
query!(
"UPDATE availabillity SET startTime = $1, endTime = $2, comment = $3 WHERE id = $4",
updated_availabillity.start_time,
updated_availabillity.end_time,
updated_availabillity.comment,
id
)
.execute(pool)
.await?;
Ok(())
}
pub async fn delete(pool: &PgPool, id: i32) -> anyhow::Result<()> {
query!("DELETE FROM availabillity WHERE id = $1", id)
.execute(pool)
.await?;
Ok(())
}
}