102 lines
2.9 KiB
Rust
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()
|
|
}
|