brass/web/src/endpoints/export/get_events.rs

102 lines
2.9 KiB
Rust

use actix_web::{web, Responder};
use askama::Template;
use chrono::{Datelike, Months, NaiveDate, Utc};
use sqlx::PgPool;
use crate::{
models::{Area, Role, User},
utils::{ApplicationError, TemplateResponse},
};
#[derive(Template)]
#[template(path = "export/events.html")]
struct EventExportTemplate {
user: User,
areas: Option<Vec<Area>>,
daterange: (NaiveDate, NaiveDate),
current_month: (NaiveDate, NaiveDate),
current_quarter: (NaiveDate, NaiveDate),
next_month: (NaiveDate, NaiveDate),
next_quarter: (NaiveDate, NaiveDate),
}
#[actix_web::get("/export/events")]
pub async fn get(
user: web::ReqData<User>,
pool: web::Data<PgPool>,
) -> Result<impl Responder, ApplicationError> {
if user.role != Role::Admin && user.role != Role::AreaManager {
return Err(ApplicationError::Unauthorized);
}
let areas = if user.role == Role::Admin {
Some(Area::read_all(pool.get_ref()).await?)
} else {
None
};
let today = Utc::now().date_naive();
let today_plus_month = today.checked_add_months(Months::new(1)).unwrap();
let today_plus_three_month = today.checked_add_months(Months::new(3)).unwrap();
let template = EventExportTemplate {
user: user.into_inner(),
areas,
daterange: (
first_day_of_month(&today).unwrap(),
last_day_of_month(&today).unwrap(),
),
current_month: (
first_day_of_month(&today).unwrap(),
last_day_of_month(&today).unwrap(),
),
next_month: (
first_day_of_month(&today_plus_month).unwrap(),
last_day_of_month(&today_plus_month).unwrap(),
),
current_quarter: (
first_day_of_quarter(&today).unwrap(),
last_day_of_quarter(&today).unwrap(),
),
next_quarter: (
first_day_of_quarter(&today_plus_three_month).unwrap(),
last_day_of_quarter(&today_plus_three_month).unwrap(),
),
};
Ok(template.to_response()?)
}
fn first_day_of_month(date: &NaiveDate) -> Option<NaiveDate> {
NaiveDate::from_ymd_opt(date.year(), date.month0() + 1, 1)
}
fn last_day_of_month(date: &NaiveDate) -> Option<NaiveDate> {
let month0 = date.month0() + 1;
let year = if month0 > 11 {
date.year() + 1
} else {
date.year()
};
let month = (month0 % 12) + 1;
NaiveDate::from_ymd_opt(year, month, 1)?.pred_opt()
}
fn first_day_of_quarter(date: &NaiveDate) -> Option<NaiveDate> {
let start_month = (date.quarter() * 3) - 2;
NaiveDate::from_ymd_opt(date.year(), start_month, 1)
}
fn last_day_of_quarter(date: &NaiveDate) -> Option<NaiveDate> {
let quarter = date.quarter();
let (year, next_month) = if quarter == 4 {
(date.year() + 1, 1)
} else {
(date.year(), (quarter * 3) + 1)
};
NaiveDate::from_ymd_opt(year, next_month, 1)?.pred_opt()
}