use sqlx::PgPool; use crate::models::{ Assignment, Availabillity, AvailabillityAssignmentState, Event, Function, Vehicle, VehicleAssignement, }; use super::ApplicationError; pub async fn generate_availabillity_assignment_list( pool: &PgPool, event: &Event, ) -> Result, ApplicationError> { let availabillities_in_db = Availabillity::read_by_date_and_area_including_user( pool, event.date, event.location.as_ref().unwrap().area_id, ) .await?; let mut availabillities = Vec::new(); for availabillity in availabillities_in_db { let assignments = Assignment::read_all_by_availabillity(pool, availabillity.id).await?; if let Some(assignment) = assignments .iter() .find(|assignment| assignment.event_id == event.id) { let state = match assignment.function { Function::Posten => { AvailabillityAssignmentState::AssignedPosten(assignment.availabillity_id) } Function::Fuehrungsassistent => { AvailabillityAssignmentState::AssignedFührungsassistent( assignment.availabillity_id, ) } Function::Wachhabender => { AvailabillityAssignmentState::AssignedWachahabender(assignment.availabillity_id) } }; availabillities.push((availabillity, state)); continue; } let has_start_time_during_event = |a: &Assignment| a.start_time >= event.start_time && a.start_time <= event.end_time; let has_end_time_during_event = |a: &Assignment| a.end_time >= event.start_time && a.end_time <= event.end_time; if assignments .iter() .any(|a| has_start_time_during_event(a) || has_end_time_during_event(a)) { availabillities.push((availabillity, AvailabillityAssignmentState::Conflicting)); continue; } availabillities.push((availabillity, AvailabillityAssignmentState::Unassigned)); } //println!(" {availabillities:#?}"); Ok(availabillities) } 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 = VehicleAssignement::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)) }