feat: calculate dates for export events

This commit is contained in:
Max Hohlfeld 2025-06-09 19:26:57 +02:00
parent 784b7cea4e
commit e591b419bb
3 changed files with 75 additions and 13 deletions

View File

@ -1,6 +1,6 @@
use actix_web::{web, Responder};
use askama::Template;
use chrono::{Datelike, NaiveDate, Utc};
use chrono::{Datelike, Months, NaiveDate, Utc};
use sqlx::PgPool;
use crate::{
@ -14,6 +14,10 @@ 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")]
@ -32,17 +36,66 @@ pub async fn get(
};
let today = Utc::now().date_naive();
let start = NaiveDate::from_ymd_opt(today.year(), today.month0() + 1, 1).unwrap();
let end = NaiveDate::from_ymd_opt(today.year(), today.month0() + 2, 1)
.unwrap()
.pred_opt()
.unwrap();
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: (start, end),
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()
}

View File

@ -44,6 +44,7 @@ $primary: $crimson,
@forward "bulma/sass/helpers/flexbox";
@forward "bulma/sass/helpers/color";
@forward "bulma/sass/helpers/visibility";
@forward "bulma/sass/helpers/other";
// Import the themes so that all CSS variables have a value
@forward "bulma/sass/themes";

View File

@ -11,20 +11,28 @@
<div class="field">
<label class="label">Zeitraum Start</label>
<div class="control">
<input class="input" type="date" name="start" required value="{{ daterange.0 }}" />
<input class="input" type="date" name="start" id="start" required value="{{ daterange.0 }}" />
</div>
<div class="tags help">
<span class="tag">aktueller Monat</span>
<span class="tag">nächster Monat</span>
<span class="tag">aktuelles Quartal</span>
<span class="tag">nächstes Quartal</span>
<span class="tag is-link is-light is-clickable"
_='on click set the value of #start to "{{ current_month.0 }}" then set the value of #end to "{{ current_month.1 }}"'>
aktueller Monat</span>
<span class="tag is-link is-light is-clickable"
_='on click set the value of #start to "{{ next_month.0 }}" then set the value of #end to "{{ next_month.1 }}"'>
nächster Monat</span>
<span class="tag is-link is-light is-clickable"
_='on click set the value of #start to "{{ current_quarter.0 }}" then set the value of #end to "{{ current_quarter.1 }}"'>
aktuelles Quartal</span>
<span class="tag is-link is-light is-clickable"
_='on click set the value of #start to "{{ next_quarter.0 }}" then set the value of #end to "{{ next_quarter.1 }}"'>
nächstes Quartal</span>
</div>
</div>
<div class="field">
<label class="label">Zeitraum Ende</label>
<div class="control">
<input class="input" type="date" name="end" required value="{{ daterange.1 }}" />
<input class="input" type="date" name="end" id="end" required value="{{ daterange.1 }}" />
</div>
</div>