feat: WIP combine adjacent availability

This commit is contained in:
Max Hohlfeld 2025-01-27 13:23:19 +01:00
parent 1066b877d5
commit 6995599a81
2 changed files with 55 additions and 7 deletions

View File

@ -15,18 +15,18 @@ pub async fn post(
path: web::Path<IdPath>,
form: web::Form<AvailabillityForm>,
) -> Result<impl Responder, ApplicationError> {
let Some(availabillity) = Availability::read_by_id(pool.get_ref(), path.id).await? else {
let Some(availability) = Availability::read_by_id(pool.get_ref(), path.id).await? else {
return Ok(HttpResponse::NotFound().finish());
};
if availabillity.user_id != user.id {
if availability.user_id != user.id {
return Err(ApplicationError::Unauthorized);
}
let existing_availabilities =
Availability::read_by_user_and_date(pool.get_ref(), user.id, &availabillity.date).await?;
Availability::read_by_user_and_date(pool.get_ref(), user.id, &availability.date).await?;
let context = AvailabilityContext {
existing_availabilities,
existing_availabilities: existing_availabilities.clone(),
};
let time = if form.from.is_some() && form.till.is_some() {
@ -35,7 +35,7 @@ pub async fn post(
AvailabilityTime::WholeDay
};
let changeset = AvailabilityChangeset {
let mut changeset = AvailabilityChangeset {
time,
comment: form.comment.clone(),
};
@ -44,8 +44,38 @@ pub async fn post(
return Ok(HttpResponse::BadRequest().body(e.to_string()));
};
// TODO: check if adjacent availabillity is present and combine
Availability::update(pool.get_ref(), availabillity.id, changeset).await?;
let mut adjacent = None;
if let AvailabilityTime::Temporarily(changeset_start, changeset_end) = changeset.time {
for a in existing_availabilities
.iter()
.filter(|a| a.id != availability.id)
{
if let AvailabilityTime::Temporarily(start, end) = a.time {
if start == changeset_end || end == changeset_start {
adjacent = Some(a);
break;
}
}
}
}
if let Some(a) = adjacent {
let (changeset_start, changeset_end) = changeset.time.time_tuple_opt().unwrap();
let (adjacent_start, adjacent_end) = changeset.time.time_tuple_opt().unwrap();
if adjacent_end == changeset_start {
changeset.time = AvailabilityTime::Temporarily(adjacent_start, changeset_end);
}
if adjacent_start == changeset_end {
changeset.time = AvailabilityTime::Temporarily(changeset_start, adjacent_end);
}
Availability::update(pool.get_ref(), a.id, changeset).await?;
Availability::delete(pool.get_ref(), availability.id).await?;
} else {
Availability::update(pool.get_ref(), availability.id, changeset).await?;
}
let url = utils::get_return_url_for_date(&form.date);
Ok(HttpResponse::Found()

View File

@ -1,6 +1,8 @@
use chrono::{NaiveDate, NaiveTime};
use sqlx::{query, PgPool};
use crate::{END_OF_DAY, START_OF_DAY};
use super::{Area, AvailabilityChangeset, Function, Result, Role, User};
#[derive(Clone, Debug)]
@ -19,6 +21,22 @@ pub enum AvailabilityTime {
Temporarily(NaiveTime, NaiveTime),
}
impl AvailabilityTime {
pub fn time_tuple(&self) -> (NaiveTime, NaiveTime) {
match self {
AvailabilityTime::WholeDay => (START_OF_DAY, END_OF_DAY),
AvailabilityTime::Temporarily(start, end) => (*start, *end),
}
}
pub fn time_tuple_opt(&self) -> Option<(NaiveTime, NaiveTime)> {
match self {
AvailabilityTime::WholeDay => None,
AvailabilityTime::Temporarily(start, end) => Some((*start, *end)),
}
}
}
impl Availability {
// TODO: fix db name
pub async fn create(