use chrono::{NaiveDate, NaiveDateTime}; use sqlx::{ postgres::{PgHasArrayType, PgTypeInfo}, query, PgPool, }; use crate::utils::ApplicationError; use super::Function; pub struct ExportEventRow { pub start_timestamp: NaiveDateTime, pub end_timestamp: NaiveDateTime, pub amount_of_posten: i16, pub voluntary_fuehrungsassistent: bool, pub voluntary_wachhabender: bool, pub location_name: String, pub event_name: String, pub assignments: Vec, pub vehicles: Vec, } #[derive(Debug, sqlx::Type)] #[sqlx(type_name = "function", no_pg_array)] pub struct SimpleAssignment { pub name: String, pub function: Function, } impl PgHasArrayType for SimpleAssignment { fn array_type_info() -> sqlx::postgres::PgTypeInfo { PgTypeInfo::with_name("simpleAssignment[]") } } impl ExportEventRow { pub async fn read_all_for_timerange_and_area( pool: &PgPool, time: (NaiveDate, NaiveDate), area: i32, ) -> Result, ApplicationError> { let rows = query!( "select event.starttimestamp, event.endtimestamp, event.amountofposten, event.voluntaryfuehrungsassistent, event.voluntarywachhabender, location.name as locationName, event.name as eventName, array ( select row (user_.name, assignment.function) ::simpleAssignment from assignment join availability on assignment.availabilityid = availability.id join user_ on availability.userid = user_.id where assignment.eventId = event.id) as \"assignments: Vec\", array ( select vehicle.station || ' ' || vehicle.radiocallname from vehicleassignment join vehicle on vehicleassignment.vehicleId = vehicle.id where vehicleassignment.eventId = event.id) as vehicles from event join location on event.locationId = location.id where event.starttimestamp::date >= $1 and event.starttimestamp::date <= $2 and location.areaId = $3 order by event.starttimestamp", time.0, time.1, area ) .fetch_all(pool) .await?; let export_rows = rows .into_iter() .map(|r| ExportEventRow { start_timestamp: r.starttimestamp.naive_utc(), end_timestamp: r.endtimestamp.naive_utc(), amount_of_posten: r.amountofposten, voluntary_fuehrungsassistent: r.voluntaryfuehrungsassistent, voluntary_wachhabender: r.voluntarywachhabender, location_name: r.locationname, event_name: r.eventname, assignments: r.assignments.unwrap_or(Vec::new()), vehicles: r.vehicles.unwrap_or(Vec::new()), }) .collect(); Ok(export_rows) } }