187 lines
5.5 KiB
Rust
187 lines
5.5 KiB
Rust
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};
|
|
use rust_xlsxwriter::workbook::Workbook;
|
|
use serde::Deserialize;
|
|
use sqlx::PgPool;
|
|
|
|
use crate::{
|
|
models::{Role, User},
|
|
utils::{ApplicationError, DateTimeFormat},
|
|
};
|
|
|
|
#[derive(Deserialize)]
|
|
struct ExportQuery {
|
|
start: NaiveDate,
|
|
end: NaiveDate,
|
|
area: Option<i32>,
|
|
}
|
|
|
|
#[derive(PartialEq)]
|
|
struct EventExportEntry {
|
|
date: String,
|
|
weekday: String,
|
|
start_time: String,
|
|
end_time: String,
|
|
hours: f32,
|
|
location: String,
|
|
name: String,
|
|
assigned_name: Option<String>,
|
|
assigned_function: Option<String>,
|
|
}
|
|
|
|
fn read(rows: Vec<ExportEventRow>) -> Vec<EventExportEntry> {
|
|
let mut entries = Vec::new();
|
|
|
|
for r in rows {
|
|
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())),
|
|
};
|
|
|
|
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"
|
|
};
|
|
|
|
entries.push(create_new_entry(None, Some(function)));
|
|
}
|
|
|
|
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()),
|
|
));
|
|
}
|
|
|
|
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 {
|
|
entries.push(create_new_entry(Some(&v), Some("Fzg")));
|
|
}
|
|
}
|
|
|
|
entries
|
|
}
|
|
|
|
#[actix_web::get("/export/eventsdata")]
|
|
pub async fn get(
|
|
pool: web::Data<PgPool>,
|
|
user: web::ReqData<User>,
|
|
query: web::Query<ExportQuery>,
|
|
) -> Result<impl Responder, ApplicationError> {
|
|
if user.role != Role::Admin && user.role != Role::AreaManager {
|
|
return Err(ApplicationError::Unauthorized);
|
|
}
|
|
|
|
let rows_to_export = ExportEventRow::read(pool.get_ref()).await?;
|
|
let entries = read(rows_to_export);
|
|
|
|
let mut workbook = Workbook::new();
|
|
let worksheet = workbook.add_worksheet();
|
|
// let time_format = Format::new();
|
|
// time_format.set_num_format(num_format)
|
|
|
|
const HEADER: [&str; 10] = [
|
|
"Datum",
|
|
"Wochentag",
|
|
"Beginn",
|
|
"Ende",
|
|
"Stunden",
|
|
"Ort",
|
|
"VA",
|
|
"Namen",
|
|
"Fkt",
|
|
"Reserve",
|
|
];
|
|
worksheet.write_row(2, 0, HEADER).unwrap();
|
|
|
|
for (i, entry) in entries.iter().enumerate() {
|
|
let i = (i + 3) as u32;
|
|
|
|
worksheet.write(i, 0, &entry.date).unwrap();
|
|
worksheet.write(i, 1, &entry.weekday).unwrap();
|
|
worksheet.write(i, 2, &entry.start_time).unwrap();
|
|
worksheet.write(i, 3, &entry.end_time).unwrap();
|
|
worksheet.write(i, 4, entry.hours).unwrap();
|
|
worksheet
|
|
.write(i, 4, format!("{:.1}", entry.hours))
|
|
.unwrap();
|
|
worksheet.write(i, 5, &entry.location).unwrap();
|
|
worksheet.write(i, 6, &entry.name).unwrap();
|
|
worksheet.write(i, 7, entry.assigned_name.as_ref()).unwrap();
|
|
worksheet
|
|
.write(i, 8, entry.assigned_function.as_ref())
|
|
.unwrap();
|
|
}
|
|
|
|
worksheet.autofit();
|
|
|
|
let buffer = workbook.save_to_buffer().unwrap();
|
|
|
|
return Ok(HttpResponse::Ok()
|
|
.content_type("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
|
.insert_header((
|
|
CONTENT_DISPOSITION,
|
|
ContentDisposition::attachment("export.xlsx"),
|
|
))
|
|
.body(buffer));
|
|
}
|