102 lines
3.2 KiB
Rust
102 lines
3.2 KiB
Rust
use actix_web::{web, HttpResponse, Responder};
|
|
use garde::Validate;
|
|
use serde::Deserialize;
|
|
use sqlx::PgPool;
|
|
|
|
use crate::{
|
|
endpoints::assignment::PlanEventPersonalTablePartialTemplate,
|
|
models::{
|
|
Assignment, AssignmentChangeset, AssignmentContext, Availability, Event, Function, Role,
|
|
User,
|
|
},
|
|
utils::{
|
|
event_planning_template::{
|
|
generate_availabillity_assignment_list, generate_status_whether_staff_is_required,
|
|
},
|
|
ApplicationError, TemplateResponse,
|
|
},
|
|
};
|
|
|
|
#[derive(Deserialize)]
|
|
pub struct AssignmentQuery {
|
|
availabillity: 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 user_is_admin_or_area_manager_of_event_area = user.role == Role::Admin
|
|
|| (user.role == Role::AreaManager
|
|
&& user.area_id == event.location.as_ref().unwrap().area_id);
|
|
|
|
if !user_is_admin_or_area_manager_of_event_area {
|
|
return Err(ApplicationError::Unauthorized);
|
|
}
|
|
|
|
let Some(availabillity) =
|
|
Availability::read_by_id_including_user(pool.get_ref(), query.availabillity).await?
|
|
else {
|
|
return Ok(HttpResponse::NotFound().finish());
|
|
};
|
|
|
|
let availability_user_not_in_event_location_area =
|
|
availabillity.user.as_ref().unwrap().area_id != event.location.as_ref().unwrap().area_id;
|
|
|
|
if availability_user_not_in_event_location_area {
|
|
return Ok(HttpResponse::BadRequest()
|
|
.body("availability user is not in the same area as event location"));
|
|
}
|
|
|
|
let function = Function::try_from(query.function)?;
|
|
|
|
let changeset = AssignmentChangeset {
|
|
function,
|
|
time: (event.start, event.end),
|
|
};
|
|
|
|
let assignments_for_event = Assignment::read_all_by_event(pool.get_ref(), event.id).await?;
|
|
let assignments_for_availabillity =
|
|
Assignment::read_all_by_availabillity(pool.get_ref(), availabillity.id).await?;
|
|
let context = AssignmentContext {
|
|
event: event.clone(),
|
|
availabillity: availabillity.clone(),
|
|
user_function: availabillity.user.as_ref().unwrap().function.clone(),
|
|
assignments_for_event,
|
|
assignments_for_availabillity,
|
|
};
|
|
|
|
if let Err(e) = changeset.validate_with(&context) {
|
|
return Ok(HttpResponse::BadRequest().body(e.to_string()));
|
|
};
|
|
|
|
Assignment::create(pool.get_ref(), event.id, availabillity.id, changeset).await?;
|
|
|
|
let availabillities = generate_availabillity_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,
|
|
availabillities,
|
|
further_posten_required,
|
|
further_fuehrungsassistent_required,
|
|
further_wachhabender_required,
|
|
};
|
|
|
|
Ok(template.to_response()?)
|
|
}
|