157 lines
4.2 KiB
Rust

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<User>,
pool: web::Data<PgPool>,
query: web::Query<AssignmentQuery>,
) -> Result<impl Responder, ApplicationError> {
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::<String>(), 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)
}
}