brass/web/src/utils/event_planning_template.rs

113 lines
3.8 KiB
Rust

use sqlx::PgPool;
use crate::models::{
Assignment, Availability, AvailabilityAssignmentState, Event, Function, Vehicle,
VehicleAssignment,
};
use super::ApplicationError;
pub async fn generate_availability_assignment_list(
pool: &PgPool,
event: &Event,
) -> Result<Vec<(Availability, AvailabilityAssignmentState)>, ApplicationError> {
let availabilities_in_db = Availability::read_by_date_time_area_including_user(
pool,
event.start.date(),
(event.start, event.end),
event.location.as_ref().unwrap().area_id,
)
.await?;
let mut availabilities = Vec::new();
for availability in availabilities_in_db {
let assignments = Assignment::read_all_by_availability(pool, availability.id).await?;
if let Some(assignment) = assignments
.iter()
.find(|assignment| assignment.event_id == event.id)
{
let state = match assignment.function {
Function::Posten => {
AvailabilityAssignmentState::AssignedPosten(assignment.availability_id)
}
Function::Fuehrungsassistent => {
AvailabilityAssignmentState::AssignedFührungsassistent(
assignment.availability_id,
)
}
Function::Wachhabender => {
AvailabilityAssignmentState::AssignedWachhabender(assignment.availability_id)
}
};
availabilities.push((availability, state));
continue;
}
let has_start_time_during_event =
|a: &Assignment| a.start >= event.start && a.start <= event.end;
let has_end_time_during_event = |a: &Assignment| a.end >= event.start && a.end <= event.end;
if assignments
.iter()
.any(|a| has_start_time_during_event(a) || has_end_time_during_event(a))
{
availabilities.push((availability, AvailabilityAssignmentState::Conflicting));
continue;
}
availabilities.push((availability, AvailabilityAssignmentState::Unassigned));
}
//println!(" {availabilities:#?}");
Ok(availabilities)
}
pub async fn generate_status_whether_staff_is_required(
pool: &PgPool,
event: &Event,
) -> Result<(bool, bool, bool), ApplicationError> {
let existing_assignments_for_event = Assignment::read_all_by_event(pool, event.id).await?;
let further_posten_required = existing_assignments_for_event
.iter()
.filter(|a| a.function == Function::Posten)
.count()
< event.amount_of_posten as usize;
let further_fuehrungsassistent_required = event.voluntary_fuehrungsassistent
&& existing_assignments_for_event
.iter()
.all(|a| a.function != Function::Fuehrungsassistent);
let further_wachhabender_required = event.voluntary_wachhabender
&& existing_assignments_for_event
.iter()
.all(|a| a.function != Function::Wachhabender);
//println!("further_posten {further_posten_required}");
Ok((
further_posten_required,
further_fuehrungsassistent_required,
further_wachhabender_required,
))
}
pub async fn generate_vehicles_assigned_and_available(
pool: &PgPool,
event: &Event,
) -> Result<(Vec<Vehicle>, Vec<Vehicle>), ApplicationError> {
let all_vehicles = Vehicle::read_all(pool).await?;
let existing_vehicle_assignments_for_event =
VehicleAssignment::read_all_by_event(pool, event.id).await?;
let (vehicles_assigned, vehicles_available): (Vec<Vehicle>, Vec<Vehicle>) =
all_vehicles.into_iter().partition(|v| {
existing_vehicle_assignments_for_event
.iter()
.any(|va| va.vehicle_id == v.id)
});
Ok((vehicles_assigned, vehicles_available))
}