use actix_web::{web, HttpResponse, Responder}; use serde::Deserialize; use sqlx::PgPool; use crate::{ endpoints::assignment::PlanEventPersonalTablePartialTemplate, utils::{ event_planning_template::{ generate_availability_assignment_list, generate_status_whether_staff_is_required, }, ApplicationError, TemplateResponse, }, }; use brass_db::{ models::{Assignment, AssignmentChangeset, AssignmentContext, Event, Function, User}, validation::AsyncValidate, }; #[derive(Deserialize)] pub struct AssignmentQuery { availability: i32, function: u8, event: i32, } #[actix_web::post("/assignments/new")] pub async fn post( user: web::ReqData, pool: web::Data, query: web::Query, ) -> Result { let Some(event) = Event::read_by_id_including_location(pool.get_ref(), query.event).await? else { return Ok(HttpResponse::NotFound().finish()); }; let function = Function::try_from(query.function)?; let changeset = AssignmentChangeset { function, time: (event.start, event.end), }; let context = AssignmentContext { user: &user.into_inner(), event_id: event.id, availability_id: query.availability, pool: pool.get_ref(), }; if let Err(e) = changeset.validate_with_context(&context).await { return Ok(HttpResponse::BadRequest().body(e.to_string())); }; Assignment::create(pool.get_ref(), event.id, query.availability, changeset).await?; let availabilities = generate_availability_assignment_list(pool.get_ref(), &event).await?; let ( further_posten_required, further_fuehrungsassistent_required, further_wachhabender_required, ) = generate_status_whether_staff_is_required(pool.get_ref(), &event).await?; let template = PlanEventPersonalTablePartialTemplate { event, availabilities, further_posten_required, further_fuehrungsassistent_required, further_wachhabender_required, }; Ok(template.to_response()?) } #[cfg(test)] mod tests { use brass_db::models::{ Availability, AvailabilityChangeset, Event, EventChangeset, Location, User, }; use brass_macros::db_test; use chrono::{NaiveDate, NaiveDateTime}; use fake::{Fake, Faker}; use crate::utils::test_helper::{DbTestContext, NaiveDateTimeExt}; #[db_test] fn response_produces_updated_template(context: &DbTestContext) { let app = context.app().await; Location::create(&context.db_pool, &Faker.fake::(), 1) .await .unwrap(); let start = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 10, 0, 0).unwrap(); let end = NaiveDateTime::from_ymd_and_hms(2025, 01, 10, 20, 0, 0).unwrap(); Event::create( &context.db_pool, EventChangeset::create_for_test(start, end), ) .await .unwrap(); User::create(&context.db_pool, Faker.fake()).await.unwrap(); // Availability::create(pool, 1, AvailabilityChangeset { time () }) assert!(false) } #[db_test] fn fails_when_availability_does_not_exist(context: &DbTestContext) { assert!(false) } #[db_test] fn fails_when_event_does_not_exist(context: &DbTestContext) { assert!(false) } #[db_test] fn fails_when_area_manager_is_different_area_from_event(context: &DbTestContext) { assert!(false) } #[db_test] fn fails_when_availability_user_not_in_event_area(context: &DbTestContext) { assert!(false) } #[db_test] fn fails_assignment_time_doesnt_fit_into_availability_time(context: &DbTestContext) { assert!(false) } #[db_test] fn fails_when_end_time_lies_before_start_time(context: &DbTestContext) { assert!(false) } #[db_test] fn fails_when_availability_time_already_assigned(context: &DbTestContext) { assert!(false) } #[db_test] fn fails_when_availability_user_does_not_have_function(context: &DbTestContext) { assert!(false) } #[db_test] fn fails_when_event_already_has_enough_assignments_for_function(context: &DbTestContext) { assert!(false) } }