refactor: correct output of event export

This commit is contained in:
Max Hohlfeld 2025-06-04 15:24:27 +02:00
parent f953b6d208
commit d1e1ccd906
5 changed files with 95 additions and 105 deletions

View File

@ -0,0 +1,4 @@
CREATE TYPE simpleAssignment AS (
name text,
function function
);

View File

@ -1,4 +1,4 @@
use crate::models::{ExportEventRow, Function};
use crate::models::{ExportEventRow, Function, SimpleAssignment};
use actix_http::header::CONTENT_DISPOSITION;
use actix_web::{http::header::ContentDisposition, web, HttpResponse, Responder};
use chrono::{Datelike, NaiveDate};
@ -35,117 +35,87 @@ fn read(rows: Vec<ExportEventRow>) -> Vec<EventExportEntry> {
let mut entries = Vec::new();
for r in rows {
let date = r
.start_timestamp
.format(DateTimeFormat::DayMonthYear.into());
let weekday = r.start_timestamp.weekday();
let start_time = r
.start_timestamp
.time()
.format(DateTimeFormat::HourMinute.into());
let end_time = r
.end_timestamp
.time()
.format(DateTimeFormat::HourMinute.into());
let hours = (r.end_timestamp - r.start_timestamp).as_seconds_f32() / 3600.0 + 1.0;
let create_new_entry = |n: Option<&str>, f: Option<&str>| EventExportEntry {
date: r
.start_timestamp
.format(DateTimeFormat::DayMonthYear.into())
.to_string(),
weekday: r.start_timestamp.weekday().to_string(),
start_time: r
.start_timestamp
.time()
.format(DateTimeFormat::HourMinute.into())
.to_string(),
end_time: r
.end_timestamp
.time()
.format(DateTimeFormat::HourMinute.into())
.to_string(),
hours: (r.end_timestamp - r.start_timestamp).as_seconds_f32() / 3600.0 + 1.0,
location: r.location_name.to_string(),
name: r.event_name.to_string(),
assigned_name: n.and_then(|s| Some(s.to_string())),
assigned_function: f.and_then(|s| Some(s.to_string())),
};
let mut event_new: Vec<EventExportEntry> = Vec::new();
let mut assigned_posten: i16 = 0;
let mut assigned_wachhabender = false;
let mut assigned_fuehrungassistent = false;
for (assigned_name, assigned_function) in r.assignments {
match assigned_function {
Function::Posten => {
assigned_posten += 1;
}
Function::Wachhabender => {
assigned_wachhabender = true;
}
Function::Fuehrungsassistent => {
assigned_fuehrungassistent = true;
}
};
event_new.push(EventExportEntry {
date: date.to_string(),
weekday: weekday.to_string(),
start_time: start_time.to_string(),
end_time: end_time.to_string(),
hours,
location: r.location_name.to_string(),
name: r.event_name.to_string(),
assigned_name: Some(assigned_name.trim().to_string()),
assigned_function: Some(assigned_function.to_string()),
});
}
if !assigned_wachhabender {
if let Some(assigned_wh) = r
.assignments
.iter()
.find(|a| a.function == Function::Wachhabender)
{
entries.push(create_new_entry(
Some(&assigned_wh.name),
Some(&assigned_wh.function.short_display()),
));
} else {
let function = if r.voluntary_wachhabender {
"WH"
} else {
"BF-WH"
};
event_new.push(EventExportEntry {
date: date.to_string(),
weekday: weekday.to_string(),
start_time: start_time.to_string(),
end_time: end_time.to_string(),
hours,
location: r.location_name.to_string(),
name: r.event_name.to_string(),
assigned_name: None,
assigned_function: Some(function.to_string()),
});
entries.push(create_new_entry(None, Some(function)));
}
if !assigned_fuehrungassistent && r.voluntary_fuehrungsassistent {
event_new.push(EventExportEntry {
date: date.to_string(),
weekday: weekday.to_string(),
start_time: start_time.to_string(),
end_time: end_time.to_string(),
hours,
location: r.location_name.to_string(),
name: r.event_name.to_string(),
assigned_name: None,
assigned_function: Some("FüAss".to_string()),
});
if let Some(assigned_fuass) = r
.assignments
.iter()
.find(|a| a.function == Function::Fuehrungsassistent)
{
entries.push(create_new_entry(
Some(&assigned_fuass.name),
Some(&assigned_fuass.function.short_display()),
));
} else if r.voluntary_fuehrungsassistent {
entries.push(create_new_entry(
None,
Some(&Function::Fuehrungsassistent.short_display()),
));
}
if assigned_posten < r.amount_of_posten {
for _ in 0..(r.amount_of_posten - assigned_posten) {
event_new.push(EventExportEntry {
date: date.to_string(),
weekday: weekday.to_string(),
start_time: start_time.to_string(),
end_time: end_time.to_string(),
hours,
location: r.location_name.to_string(),
name: r.event_name.to_string(),
assigned_name: None,
assigned_function: Some("PO".to_string()),
});
let assigned_po: Vec<&SimpleAssignment> = r
.assignments
.iter()
.filter(|a| a.function == Function::Posten)
.collect();
for i in 0..r.amount_of_posten {
if let Some(po) = assigned_po.get(i as usize) {
entries.push(create_new_entry(
Some(&po.name),
Some(&po.function.short_display()),
));
} else {
entries.push(create_new_entry(
None,
Some(&Function::Posten.short_display()),
));
}
}
for v in r.vehicles {
event_new.push(EventExportEntry {
date: date.to_string(),
weekday: weekday.to_string(),
start_time: start_time.to_string(),
end_time: end_time.to_string(),
hours,
location: r.location_name.to_string(),
name: r.event_name.to_string(),
assigned_name: Some(v.to_string()),
assigned_function: Some(String::from("Fzg")),
});
entries.push(create_new_entry(Some(&v), Some("Fzg")));
}
entries.append(&mut event_new);
}
entries

View File

@ -1,5 +1,8 @@
use chrono::NaiveDateTime;
use sqlx::{query, PgPool};
use sqlx::{
postgres::{PgHasArrayType, PgTypeInfo},
query, PgPool,
};
use crate::utils::ApplicationError;
@ -13,10 +16,23 @@ pub struct ExportEventRow {
pub voluntary_wachhabender: bool,
pub location_name: String,
pub event_name: String,
pub assignments: Vec<(String, Function)>,
pub assignments: Vec<SimpleAssignment>,
pub vehicles: Vec<String>,
}
#[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(pool: &PgPool) -> Result<Vec<ExportEventRow>, ApplicationError> {
let rows = query!(
@ -30,7 +46,7 @@ impl ExportEventRow {
event.name as eventName,
array (
select
row (user_.name, assignment.function)
row (user_.name, assignment.function) ::simpleAssignment
from
assignment
join availability on
@ -38,7 +54,7 @@ impl ExportEventRow {
join user_ on
availability.userid = user_.id
where
assignment.eventId = event.id) as \"assignments: Vec<(String, Function)>\",
assignment.eventId = event.id) as \"assignments: Vec<SimpleAssignment>\",
array (
select
vehicle.station || ' ' || vehicle.radiocallname

View File

@ -44,11 +44,11 @@ impl Default for Function {
}
impl Function {
pub fn short_display(&self) -> &'static str {
pub fn short_display(&self) -> String {
match self {
Function::Posten => "PO",
Function::Fuehrungsassistent => "FüAss",
Function::Wachhabender => "WH",
Function::Posten => "PO".to_string(),
Function::Fuehrungsassistent => "FüAss".to_string(),
Function::Wachhabender => "WH".to_string(),
}
}
}

View File

@ -30,7 +30,7 @@ pub use availability_changeset::{
pub use clothing::Clothing;
pub use event::Event;
pub use event_changeset::{EventChangeset, EventContext};
pub use export_event_row::ExportEventRow;
pub use export_event_row::{ExportEventRow, SimpleAssignment};
pub use function::Function;
pub use location::Location;
pub use password_reset::{NoneToken, PasswordReset, Token};