use actix_web::{http::header::LOCATION, web, HttpResponse, Responder}; use garde::Validate; use sqlx::PgPool; use crate::{ endpoints::availability::{find_adjacend_availability, AvailabillityForm}, models::{Availability, AvailabilityChangeset, AvailabilityContext, User}, utils::{self, ApplicationError}, }; #[actix_web::post("/availabillity/new")] pub async fn post( user: web::ReqData, pool: web::Data, form: web::Form, ) -> Result { let existing_availabilities = Availability::read_by_user_and_date(pool.get_ref(), user.id, &form.startdate).await?; let context = AvailabilityContext { existing_availabilities: existing_availabilities.clone(), }; let start = form.startdate.and_time(form.starttime); let end = form.enddate.and_time(form.endtime); let mut changeset = AvailabilityChangeset { time: (start, end), comment: form.comment.clone(), }; if let Err(e) = changeset.validate_with(&context) { return Ok(HttpResponse::BadRequest().body(e.to_string())); }; if let Some(a) = find_adjacend_availability(&changeset, None, &existing_availabilities) { let (changeset_start, changeset_end) = changeset.time; if a.end == changeset_start { changeset.time.0 = a.start; } if a.start == changeset_end { changeset.time.1 = a.end; } Availability::update(pool.get_ref(), a.id, changeset).await?; } else { Availability::create(pool.get_ref(), user.id, changeset).await?; } let url = utils::get_return_url_for_date(&form.startdate); Ok(HttpResponse::Found() .insert_header((LOCATION, url.clone())) .insert_header(("HX-LOCATION", url)) .finish()) }