refactor: move into models
This commit is contained in:
parent
075cdc713d
commit
f953b6d208
@ -1,9 +1,10 @@
|
|||||||
|
use crate::models::{ExportEventRow, Function};
|
||||||
use actix_http::header::CONTENT_DISPOSITION;
|
use actix_http::header::CONTENT_DISPOSITION;
|
||||||
use actix_web::{http::header::ContentDisposition, web, HttpResponse, Responder};
|
use actix_web::{http::header::ContentDisposition, web, HttpResponse, Responder};
|
||||||
use chrono::{Datelike, NaiveDate};
|
use chrono::{Datelike, NaiveDate};
|
||||||
use rust_xlsxwriter::{workbook::Workbook, Format};
|
use rust_xlsxwriter::workbook::Workbook;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::{query, PgPool};
|
use sqlx::PgPool;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
models::{Role, User},
|
models::{Role, User},
|
||||||
@ -30,64 +31,23 @@ struct EventExportEntry {
|
|||||||
assigned_function: Option<String>,
|
assigned_function: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read(pool: &PgPool) -> Result<Vec<EventExportEntry>, ApplicationError> {
|
fn read(rows: Vec<ExportEventRow>) -> Vec<EventExportEntry> {
|
||||||
let results = query!(
|
|
||||||
"select
|
|
||||||
event.starttimestamp,
|
|
||||||
event.endtimestamp,
|
|
||||||
event.amountofposten,
|
|
||||||
event.voluntaryfuehrungsassistent,
|
|
||||||
event.voluntarywachhabender,
|
|
||||||
location.name as locationName,
|
|
||||||
event.name as eventName,
|
|
||||||
array (
|
|
||||||
select
|
|
||||||
user_.name || ' --- ' || assignment.function
|
|
||||||
from
|
|
||||||
assignment
|
|
||||||
join availability on
|
|
||||||
assignment.availabilityid = availability.id
|
|
||||||
join user_ on
|
|
||||||
availability.userid = user_.id
|
|
||||||
where
|
|
||||||
assignment.eventId = event.id) as assignments,
|
|
||||||
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
|
|
||||||
order by event.starttimestamp"
|
|
||||||
)
|
|
||||||
.fetch_all(pool)
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let mut entries = Vec::new();
|
let mut entries = Vec::new();
|
||||||
|
|
||||||
for r in results {
|
for r in rows {
|
||||||
let date = r
|
let date = r
|
||||||
.starttimestamp
|
.start_timestamp
|
||||||
.date_naive()
|
|
||||||
.format(DateTimeFormat::DayMonthYear.into());
|
.format(DateTimeFormat::DayMonthYear.into());
|
||||||
let weekday = r.starttimestamp.date_naive().weekday();
|
let weekday = r.start_timestamp.weekday();
|
||||||
let start_time = r
|
let start_time = r
|
||||||
.starttimestamp
|
.start_timestamp
|
||||||
.time()
|
.time()
|
||||||
.format(DateTimeFormat::HourMinute.into());
|
.format(DateTimeFormat::HourMinute.into());
|
||||||
let end_time = r
|
let end_time = r
|
||||||
.endtimestamp
|
.end_timestamp
|
||||||
.time()
|
.time()
|
||||||
.format(DateTimeFormat::HourMinute.into());
|
.format(DateTimeFormat::HourMinute.into());
|
||||||
let hours = (r.endtimestamp - r.starttimestamp).as_seconds_f32() / 3600.0 + 1.0;
|
let hours = (r.end_timestamp - r.start_timestamp).as_seconds_f32() / 3600.0 + 1.0;
|
||||||
let location = r.locationname;
|
|
||||||
let name = r.eventname;
|
|
||||||
|
|
||||||
let mut event_new: Vec<EventExportEntry> = Vec::new();
|
let mut event_new: Vec<EventExportEntry> = Vec::new();
|
||||||
|
|
||||||
@ -95,23 +55,17 @@ join location on
|
|||||||
let mut assigned_wachhabender = false;
|
let mut assigned_wachhabender = false;
|
||||||
let mut assigned_fuehrungassistent = false;
|
let mut assigned_fuehrungassistent = false;
|
||||||
|
|
||||||
if let Some(assignments) = r.assignments {
|
for (assigned_name, assigned_function) in r.assignments {
|
||||||
for a in assignments {
|
match assigned_function {
|
||||||
let (assigned_name, assigned_function) = a.split_once("---").unwrap();
|
Function::Posten => {
|
||||||
let assigned_function = match assigned_function.trim() {
|
|
||||||
"posten" => {
|
|
||||||
assigned_posten += 1;
|
assigned_posten += 1;
|
||||||
"PO"
|
|
||||||
}
|
}
|
||||||
"wachhabender" => {
|
Function::Wachhabender => {
|
||||||
assigned_wachhabender = true;
|
assigned_wachhabender = true;
|
||||||
"WH"
|
|
||||||
}
|
}
|
||||||
"fuehrungsassistent" => {
|
Function::Fuehrungsassistent => {
|
||||||
assigned_fuehrungassistent = true;
|
assigned_fuehrungassistent = true;
|
||||||
"FüAss"
|
|
||||||
}
|
}
|
||||||
_ => assigned_function.trim(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
event_new.push(EventExportEntry {
|
event_new.push(EventExportEntry {
|
||||||
@ -120,16 +74,15 @@ join location on
|
|||||||
start_time: start_time.to_string(),
|
start_time: start_time.to_string(),
|
||||||
end_time: end_time.to_string(),
|
end_time: end_time.to_string(),
|
||||||
hours,
|
hours,
|
||||||
location: location.to_string(),
|
location: r.location_name.to_string(),
|
||||||
name: name.to_string(),
|
name: r.event_name.to_string(),
|
||||||
assigned_name: Some(assigned_name.trim().to_string()),
|
assigned_name: Some(assigned_name.trim().to_string()),
|
||||||
assigned_function: Some(assigned_function.to_string()),
|
assigned_function: Some(assigned_function.to_string()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if !assigned_wachhabender {
|
if !assigned_wachhabender {
|
||||||
let function = if r.voluntarywachhabender {
|
let function = if r.voluntary_wachhabender {
|
||||||
"WH"
|
"WH"
|
||||||
} else {
|
} else {
|
||||||
"BF-WH"
|
"BF-WH"
|
||||||
@ -141,63 +94,61 @@ join location on
|
|||||||
start_time: start_time.to_string(),
|
start_time: start_time.to_string(),
|
||||||
end_time: end_time.to_string(),
|
end_time: end_time.to_string(),
|
||||||
hours,
|
hours,
|
||||||
location: location.to_string(),
|
location: r.location_name.to_string(),
|
||||||
name: name.to_string(),
|
name: r.event_name.to_string(),
|
||||||
assigned_name: None,
|
assigned_name: None,
|
||||||
assigned_function: Some(function.to_string()),
|
assigned_function: Some(function.to_string()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if !assigned_fuehrungassistent && r.voluntaryfuehrungsassistent {
|
if !assigned_fuehrungassistent && r.voluntary_fuehrungsassistent {
|
||||||
event_new.push(EventExportEntry {
|
event_new.push(EventExportEntry {
|
||||||
date: date.to_string(),
|
date: date.to_string(),
|
||||||
weekday: weekday.to_string(),
|
weekday: weekday.to_string(),
|
||||||
start_time: start_time.to_string(),
|
start_time: start_time.to_string(),
|
||||||
end_time: end_time.to_string(),
|
end_time: end_time.to_string(),
|
||||||
hours,
|
hours,
|
||||||
location: location.to_string(),
|
location: r.location_name.to_string(),
|
||||||
name: name.to_string(),
|
name: r.event_name.to_string(),
|
||||||
assigned_name: None,
|
assigned_name: None,
|
||||||
assigned_function: Some("FüAss".to_string()),
|
assigned_function: Some("FüAss".to_string()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if assigned_posten < r.amountofposten {
|
if assigned_posten < r.amount_of_posten {
|
||||||
for _ in 0..(r.amountofposten - assigned_posten) {
|
for _ in 0..(r.amount_of_posten - assigned_posten) {
|
||||||
event_new.push(EventExportEntry {
|
event_new.push(EventExportEntry {
|
||||||
date: date.to_string(),
|
date: date.to_string(),
|
||||||
weekday: weekday.to_string(),
|
weekday: weekday.to_string(),
|
||||||
start_time: start_time.to_string(),
|
start_time: start_time.to_string(),
|
||||||
end_time: end_time.to_string(),
|
end_time: end_time.to_string(),
|
||||||
hours,
|
hours,
|
||||||
location: location.to_string(),
|
location: r.location_name.to_string(),
|
||||||
name: name.to_string(),
|
name: r.event_name.to_string(),
|
||||||
assigned_name: None,
|
assigned_name: None,
|
||||||
assigned_function: Some("PO".to_string()),
|
assigned_function: Some("PO".to_string()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(vehicles) = r.vehicles {
|
for v in r.vehicles {
|
||||||
for v in vehicles {
|
|
||||||
event_new.push(EventExportEntry {
|
event_new.push(EventExportEntry {
|
||||||
date: date.to_string(),
|
date: date.to_string(),
|
||||||
weekday: weekday.to_string(),
|
weekday: weekday.to_string(),
|
||||||
start_time: start_time.to_string(),
|
start_time: start_time.to_string(),
|
||||||
end_time: end_time.to_string(),
|
end_time: end_time.to_string(),
|
||||||
hours,
|
hours,
|
||||||
location: location.to_string(),
|
location: r.location_name.to_string(),
|
||||||
name: name.to_string(),
|
name: r.event_name.to_string(),
|
||||||
assigned_name: Some(v.to_string()),
|
assigned_name: Some(v.to_string()),
|
||||||
assigned_function: Some(String::from("Fzg")),
|
assigned_function: Some(String::from("Fzg")),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
entries.append(&mut event_new);
|
entries.append(&mut event_new);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(entries)
|
entries
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::get("/export/eventsdata")]
|
#[actix_web::get("/export/eventsdata")]
|
||||||
@ -210,7 +161,8 @@ pub async fn get(
|
|||||||
return Err(ApplicationError::Unauthorized);
|
return Err(ApplicationError::Unauthorized);
|
||||||
}
|
}
|
||||||
|
|
||||||
let entries = read(pool.get_ref()).await?;
|
let rows_to_export = ExportEventRow::read(pool.get_ref()).await?;
|
||||||
|
let entries = read(rows_to_export);
|
||||||
|
|
||||||
let mut workbook = Workbook::new();
|
let mut workbook = Workbook::new();
|
||||||
let worksheet = workbook.add_worksheet();
|
let worksheet = workbook.add_worksheet();
|
||||||
|
77
web/src/models/export_event_row.rs
Normal file
77
web/src/models/export_event_row.rs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
use chrono::NaiveDateTime;
|
||||||
|
use sqlx::{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<(String, Function)>,
|
||||||
|
pub vehicles: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExportEventRow {
|
||||||
|
pub async fn read(pool: &PgPool) -> Result<Vec<ExportEventRow>, 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)
|
||||||
|
from
|
||||||
|
assignment
|
||||||
|
join availability on
|
||||||
|
assignment.availabilityid = availability.id
|
||||||
|
join user_ on
|
||||||
|
availability.userid = user_.id
|
||||||
|
where
|
||||||
|
assignment.eventId = event.id) as \"assignments: Vec<(String, Function)>\",
|
||||||
|
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
|
||||||
|
order by event.starttimestamp"
|
||||||
|
)
|
||||||
|
.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)
|
||||||
|
}
|
||||||
|
}
|
@ -42,3 +42,13 @@ impl Default for Function {
|
|||||||
Self::Posten
|
Self::Posten
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Function {
|
||||||
|
pub fn short_display(&self) -> &'static str {
|
||||||
|
match self {
|
||||||
|
Function::Posten => "PO",
|
||||||
|
Function::Fuehrungsassistent => "FüAss",
|
||||||
|
Function::Wachhabender => "WH",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -7,6 +7,7 @@ mod availability_changeset;
|
|||||||
mod clothing;
|
mod clothing;
|
||||||
mod event;
|
mod event;
|
||||||
mod event_changeset;
|
mod event_changeset;
|
||||||
|
mod export_event_row;
|
||||||
mod function;
|
mod function;
|
||||||
mod location;
|
mod location;
|
||||||
mod password_reset;
|
mod password_reset;
|
||||||
@ -29,6 +30,7 @@ pub use availability_changeset::{
|
|||||||
pub use clothing::Clothing;
|
pub use clothing::Clothing;
|
||||||
pub use event::Event;
|
pub use event::Event;
|
||||||
pub use event_changeset::{EventChangeset, EventContext};
|
pub use event_changeset::{EventChangeset, EventContext};
|
||||||
|
pub use export_event_row::ExportEventRow;
|
||||||
pub use function::Function;
|
pub use function::Function;
|
||||||
pub use location::Location;
|
pub use location::Location;
|
||||||
pub use password_reset::{NoneToken, PasswordReset, Token};
|
pub use password_reset::{NoneToken, PasswordReset, Token};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user