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, 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, Vec), 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, Vec) = all_vehicles.into_iter().partition(|v| { existing_vehicle_assignments_for_event .iter() .any(|va| va.vehicle_id == v.id) }); Ok((vehicles_assigned, vehicles_available)) }