refactor: WIP datetime event and assignments
This commit is contained in:
parent
93e6a79a38
commit
8b61bb37a8
@ -88,21 +88,25 @@ mod tests {
|
|||||||
let start = NaiveTime::from_hms_opt(10, 0, 0).unwrap();
|
let start = NaiveTime::from_hms_opt(10, 0, 0).unwrap();
|
||||||
let end = NaiveTime::from_hms_opt(15, 30, 0).unwrap();
|
let end = NaiveTime::from_hms_opt(15, 30, 0).unwrap();
|
||||||
|
|
||||||
let new_event = EventChangeset::create_for_test(date.clone(), start.clone(), end.clone());
|
let new_event = EventChangeset::create_for_test(date.and_time(start), date.and_time(end));
|
||||||
Event::create(pool, new_event).await?;
|
Event::create(pool, new_event).await?;
|
||||||
|
|
||||||
let new_availability = AvailabilityChangeset {
|
let new_availability = AvailabilityChangeset {
|
||||||
time: (date.and_hms_opt(12, 0, 0).unwrap(), date.and_hms_opt(15, 0, 0).unwrap()),
|
time: (
|
||||||
|
date.and_hms_opt(12, 0, 0).unwrap(),
|
||||||
|
date.and_hms_opt(15, 0, 0).unwrap(),
|
||||||
|
),
|
||||||
comment: None,
|
comment: None,
|
||||||
};
|
};
|
||||||
Availability::create(pool, 1, new_availability).await?;
|
Availability::create(pool, 1, new_availability).await?;
|
||||||
|
|
||||||
let new_assignment = AssignmentChangeset {
|
let new_assignment = AssignmentChangeset {
|
||||||
function: Function::Posten,
|
function: Function::Posten,
|
||||||
time: (start, end),
|
time: (date.and_time(start), date.and_time(end)),
|
||||||
};
|
};
|
||||||
Assignment::create(pool, 1, 1, new_assignment).await?;
|
Assignment::create(pool, 1, 1, new_assignment).await?;
|
||||||
|
|
||||||
|
// TODO: check this test after large refactoring
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ pub async fn post(
|
|||||||
|
|
||||||
let changeset = AssignmentChangeset {
|
let changeset = AssignmentChangeset {
|
||||||
function,
|
function,
|
||||||
time: (event.start_time, event.end_time),
|
time: (event.start, event.end),
|
||||||
};
|
};
|
||||||
|
|
||||||
let assignments_for_event = Assignment::read_all_by_event(pool.get_ref(), event.id).await?;
|
let assignments_for_event = Assignment::read_all_by_event(pool.get_ref(), event.id).await?;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
||||||
use chrono::NaiveTime;
|
|
||||||
use garde::Validate;
|
use garde::Validate;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
|
||||||
@ -10,7 +9,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
models::{Availability, AvailabilityChangeset, AvailabilityContext, User},
|
models::{Availability, AvailabilityChangeset, AvailabilityContext, User},
|
||||||
utils::{self, ApplicationError},
|
utils::{self, ApplicationError},
|
||||||
END_OF_DAY,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[actix_web::post("/availabillity/edit/{id}")]
|
#[actix_web::post("/availabillity/edit/{id}")]
|
||||||
|
@ -33,7 +33,7 @@ pub async fn delete(
|
|||||||
|
|
||||||
Event::delete(pool.get_ref(), event.id).await?;
|
Event::delete(pool.get_ref(), event.id).await?;
|
||||||
|
|
||||||
let url = utils::get_return_url_for_date(&event.date);
|
let url = utils::get_return_url_for_date(&event.start.date());
|
||||||
Ok(HttpResponse::Ok()
|
Ok(HttpResponse::Ok()
|
||||||
.insert_header(("HX-LOCATION", url))
|
.insert_header(("HX-LOCATION", url))
|
||||||
.finish())
|
.finish())
|
||||||
|
@ -39,7 +39,7 @@ pub async fn get(
|
|||||||
|
|
||||||
let template = NewEventTemplate {
|
let template = NewEventTemplate {
|
||||||
user: user.into_inner(),
|
user: user.into_inner(),
|
||||||
date: event.date,
|
date: event.start.date(),
|
||||||
locations,
|
locations,
|
||||||
event: Some(event),
|
event: Some(event),
|
||||||
amount_of_planned_posten: assignments
|
amount_of_planned_posten: assignments
|
||||||
@ -85,11 +85,12 @@ async fn produces_template(context: &DbTestContext) {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let date = NaiveDate::parse_from_str("2025-01-01", "%F").unwrap();
|
||||||
|
|
||||||
let changeset = crate::models::EventChangeset {
|
let changeset = crate::models::EventChangeset {
|
||||||
date: NaiveDate::parse_from_str("2025-01-01", "%F").unwrap(),
|
|
||||||
time: (
|
time: (
|
||||||
NaiveTime::parse_from_str("08:00", "%R").unwrap(),
|
date.and_time(NaiveTime::parse_from_str("08:00", "%R").unwrap()),
|
||||||
NaiveTime::parse_from_str("10:00", "%R").unwrap(),
|
date.and_time(NaiveTime::parse_from_str("10:00", "%R").unwrap()),
|
||||||
),
|
),
|
||||||
name: "Vorstellung".to_string(),
|
name: "Vorstellung".to_string(),
|
||||||
location_id: 1,
|
location_id: 1,
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use chrono::Days;
|
||||||
use crate::filters;
|
use crate::filters;
|
||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
use askama::Template;
|
use askama::Template;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
||||||
use chrono::{NaiveDate, NaiveTime};
|
use chrono::{Days, NaiveDateTime};
|
||||||
use garde::Validate;
|
use garde::Validate;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
@ -7,18 +7,18 @@ use sqlx::PgPool;
|
|||||||
use crate::{
|
use crate::{
|
||||||
endpoints::IdPath,
|
endpoints::IdPath,
|
||||||
models::{
|
models::{
|
||||||
Assignment, AssignmentChangeset, Availability, Event, EventChangeset,
|
Assignment, AssignmentChangeset, Availability, Event, EventChangeset, EventContext,
|
||||||
EventContext, Function, Location, Role, User,
|
Function, Location, Role, User,
|
||||||
},
|
},
|
||||||
utils::{self, ApplicationError},
|
utils::{self, ApplicationError},
|
||||||
|
END_OF_DAY, START_OF_DAY,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct EditEventForm {
|
pub struct EditEventForm {
|
||||||
name: String,
|
name: String,
|
||||||
date: NaiveDate,
|
from: NaiveDateTime,
|
||||||
from: NaiveTime,
|
till: NaiveDateTime,
|
||||||
till: NaiveTime,
|
|
||||||
location: i32,
|
location: i32,
|
||||||
voluntarywachhabender: Option<bool>,
|
voluntarywachhabender: Option<bool>,
|
||||||
voluntaryfuehrungsassistent: Option<bool>,
|
voluntaryfuehrungsassistent: Option<bool>,
|
||||||
@ -58,7 +58,6 @@ pub async fn post(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let changeset = EventChangeset {
|
let changeset = EventChangeset {
|
||||||
date: form.date,
|
|
||||||
amount_of_posten: form.amount,
|
amount_of_posten: form.amount,
|
||||||
clothing: form.clothing.clone(),
|
clothing: form.clothing.clone(),
|
||||||
location_id: form.location,
|
location_id: form.location,
|
||||||
@ -74,10 +73,10 @@ pub async fn post(
|
|||||||
|
|
||||||
let assignments_for_event = Assignment::read_all_by_event(pool.get_ref(), event.id).await?;
|
let assignments_for_event = Assignment::read_all_by_event(pool.get_ref(), event.id).await?;
|
||||||
|
|
||||||
let mut common_time = (
|
let start = event.start.date();
|
||||||
NaiveTime::parse_from_str("00:00", "%R").unwrap(),
|
let end = event.start.date().checked_add_days(Days::new(1)).unwrap();
|
||||||
NaiveTime::parse_from_str("23:59", "%R").unwrap(),
|
let mut common_time = (start.and_time(START_OF_DAY), end.and_time(END_OF_DAY));
|
||||||
);
|
|
||||||
for assignment in &assignments_for_event {
|
for assignment in &assignments_for_event {
|
||||||
let availability = Availability::read_by_id(pool.get_ref(), assignment.availabillity_id)
|
let availability = Availability::read_by_id(pool.get_ref(), assignment.availabillity_id)
|
||||||
.await?
|
.await?
|
||||||
@ -87,39 +86,37 @@ pub async fn post(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if all_assignments.len() == 1 {
|
if all_assignments.len() == 1 {
|
||||||
// TODO: refactor
|
if availability.start > common_time.0 {
|
||||||
if availability.start.time() > common_time.0 {
|
common_time.0 = availability.start;
|
||||||
common_time.0 = availability.start.time();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if availability.end.time() < common_time.1 {
|
if availability.end < common_time.1 {
|
||||||
common_time.1 = availability.end.time();
|
common_time.1 = availability.end;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// TODO: refactor
|
let mut slots = vec![(availability.start, availability.end)];
|
||||||
let mut slots = vec![(availability.start.time(), availability.end.time())];
|
|
||||||
for a in all_assignments
|
for a in all_assignments
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|x| x.event_id != assignment.event_id)
|
.filter(|x| x.event_id != assignment.event_id)
|
||||||
{
|
{
|
||||||
let (fit, rest) = slots
|
let (fit, rest) = slots
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.partition(|s| s.0 >= a.start_time && s.1 <= a.end_time);
|
.partition(|s| s.0 >= a.start && s.1 <= a.end);
|
||||||
slots = rest;
|
slots = rest;
|
||||||
let fit = fit.first().unwrap();
|
let fit = fit.first().unwrap();
|
||||||
|
|
||||||
if fit.0 != a.start_time {
|
if fit.0 != a.start {
|
||||||
slots.push((fit.0, a.start_time));
|
slots.push((fit.0, a.start));
|
||||||
}
|
}
|
||||||
|
|
||||||
if fit.1 != a.end_time {
|
if fit.1 != a.end {
|
||||||
slots.push((a.end_time, fit.1));
|
slots.push((a.end, fit.1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let slot = slots
|
let slot = slots
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|s| s.0 >= assignment.start_time && s.1 <= assignment.end_time)
|
.find(|s| s.0 >= assignment.start && s.1 <= assignment.end)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
if slot.0 > common_time.0 {
|
if slot.0 > common_time.0 {
|
||||||
@ -133,7 +130,7 @@ pub async fn post(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let context = Some(EventContext {
|
let context = Some(EventContext {
|
||||||
date_in_db: event.date,
|
date_in_db: event.start.date(),
|
||||||
common_min_max_available_time: common_time,
|
common_min_max_available_time: common_time,
|
||||||
// safe as max amount of posten can be only 100
|
// safe as max amount of posten can be only 100
|
||||||
amount_of_assigned_posten: assignments_for_event
|
amount_of_assigned_posten: assignments_for_event
|
||||||
@ -152,7 +149,7 @@ pub async fn post(
|
|||||||
return Ok(HttpResponse::BadRequest().body(e.to_string()));
|
return Ok(HttpResponse::BadRequest().body(e.to_string()));
|
||||||
};
|
};
|
||||||
|
|
||||||
if event.start_time != changeset.time.0 || event.end_time != changeset.time.1 {
|
if event.start != changeset.time.0 || event.end != changeset.time.1 {
|
||||||
for a in assignments_for_event {
|
for a in assignments_for_event {
|
||||||
let c = AssignmentChangeset {
|
let c = AssignmentChangeset {
|
||||||
function: a.function,
|
function: a.function,
|
||||||
@ -164,7 +161,7 @@ pub async fn post(
|
|||||||
|
|
||||||
Event::update(pool.get_ref(), event.id, changeset).await?;
|
Event::update(pool.get_ref(), event.id, changeset).await?;
|
||||||
|
|
||||||
let url = utils::get_return_url_for_date(&form.date);
|
let url = utils::get_return_url_for_date(&form.from.date());
|
||||||
//println!("redirecto to {url}");
|
//println!("redirecto to {url}");
|
||||||
Ok(HttpResponse::Found()
|
Ok(HttpResponse::Found()
|
||||||
.insert_header((LOCATION, url.clone()))
|
.insert_header((LOCATION, url.clone()))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
||||||
use chrono::{NaiveDate, NaiveTime};
|
use chrono::NaiveDateTime;
|
||||||
use garde::Validate;
|
use garde::Validate;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
@ -12,9 +12,8 @@ use crate::{
|
|||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct NewEventForm {
|
pub struct NewEventForm {
|
||||||
name: String,
|
name: String,
|
||||||
date: NaiveDate,
|
from: NaiveDateTime,
|
||||||
from: NaiveTime,
|
till: NaiveDateTime,
|
||||||
till: NaiveTime,
|
|
||||||
location: i32,
|
location: i32,
|
||||||
voluntarywachhabender: Option<bool>,
|
voluntarywachhabender: Option<bool>,
|
||||||
voluntaryfuehrungsassistent: Option<bool>,
|
voluntaryfuehrungsassistent: Option<bool>,
|
||||||
@ -42,7 +41,6 @@ pub async fn post(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let changeset = EventChangeset {
|
let changeset = EventChangeset {
|
||||||
date: form.date,
|
|
||||||
amount_of_posten: form.amount,
|
amount_of_posten: form.amount,
|
||||||
clothing: form.clothing.clone(),
|
clothing: form.clothing.clone(),
|
||||||
location_id: form.location,
|
location_id: form.location,
|
||||||
@ -62,7 +60,7 @@ pub async fn post(
|
|||||||
|
|
||||||
Event::create(pool.get_ref(), changeset).await?;
|
Event::create(pool.get_ref(), changeset).await?;
|
||||||
|
|
||||||
let url = utils::get_return_url_for_date(&form.date);
|
let url = utils::get_return_url_for_date(&form.from.date());
|
||||||
//println!("redirecto to {url}");
|
//println!("redirecto to {url}");
|
||||||
Ok(HttpResponse::Found()
|
Ok(HttpResponse::Found()
|
||||||
.insert_header((LOCATION, url.clone()))
|
.insert_header((LOCATION, url.clone()))
|
||||||
|
@ -47,7 +47,7 @@ async fn handle_set_event_cancelation_to(
|
|||||||
Event::update_cancelation(pool.get_ref(), event.id, cancelation_state).await?;
|
Event::update_cancelation(pool.get_ref(), event.id, cancelation_state).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let url = utils::get_return_url_for_date(&event.date);
|
let url = utils::get_return_url_for_date(&event.start.date());
|
||||||
Ok(HttpResponse::Ok()
|
Ok(HttpResponse::Ok()
|
||||||
.insert_header(("HX-LOCATION", url))
|
.insert_header(("HX-LOCATION", url))
|
||||||
.finish())
|
.finish())
|
||||||
|
@ -45,13 +45,16 @@ pub async fn post(
|
|||||||
return Ok(HttpResponse::NotFound().finish());
|
return Ok(HttpResponse::NotFound().finish());
|
||||||
};
|
};
|
||||||
|
|
||||||
let existing_assignments_for_vehicle =
|
let existing_assignments_for_vehicle = VehicleAssignement::read_all_by_vehicle_and_date(
|
||||||
VehicleAssignement::read_all_by_vehicle_and_date(pool.get_ref(), vehicle.id, event.date)
|
pool.get_ref(),
|
||||||
|
vehicle.id,
|
||||||
|
event.start.date(),
|
||||||
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let has_start_time_during_event =
|
let has_start_time_during_event =
|
||||||
|a: &VehicleAssignement| a.start_time >= event.start_time && a.start_time <= event.end_time;
|
|a: &VehicleAssignement| a.start >= event.start && a.start <= event.end;
|
||||||
let has_end_time_during_event =
|
let has_end_time_during_event =
|
||||||
|a: &VehicleAssignement| a.end_time >= event.start_time && a.end_time <= event.end_time;
|
|a: &VehicleAssignement| a.end >= event.start && a.end <= event.end;
|
||||||
|
|
||||||
let availability_already_assigned = existing_assignments_for_vehicle
|
let availability_already_assigned = existing_assignments_for_vehicle
|
||||||
.iter()
|
.iter()
|
||||||
@ -62,13 +65,7 @@ pub async fn post(
|
|||||||
.body("Vehicle already assigned to a timely conflicting event."));
|
.body("Vehicle already assigned to a timely conflicting event."));
|
||||||
}
|
}
|
||||||
|
|
||||||
VehicleAssignement::create(
|
VehicleAssignement::create(pool.get_ref(), event.id, vehicle.id, event.start, event.end)
|
||||||
pool.get_ref(),
|
|
||||||
event.id,
|
|
||||||
vehicle.id,
|
|
||||||
event.start_time,
|
|
||||||
event.end_time,
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let (vehicles_assigned, vehicles_available) =
|
let (vehicles_assigned, vehicles_available) =
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use chrono::{NaiveDate, NaiveDateTime};
|
||||||
use maud::html;
|
use maud::html;
|
||||||
|
|
||||||
use crate::models::UserFunction;
|
use crate::models::UserFunction;
|
||||||
@ -57,3 +58,19 @@ pub fn show_tree(f: &UserFunction) -> askama::Result<String> {
|
|||||||
|
|
||||||
Ok(html.into_string())
|
Ok(html.into_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dt_f(v: &NaiveDateTime) -> askama::Result<String> {
|
||||||
|
Ok(v.format("%F").to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dt_d(v: &NaiveDateTime) -> askama::Result<String> {
|
||||||
|
Ok(v.format("%d.%m.%Y").to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn date_d(v: &NaiveDate) -> askama::Result<String> {
|
||||||
|
Ok(v.format("%d.%m.%Y").to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dt_t(v: &NaiveDateTime) -> askama::Result<String> {
|
||||||
|
Ok(v.format("%R").to_string())
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use chrono::{Local, NaiveDateTime, NaiveTime};
|
use chrono::NaiveDateTime;
|
||||||
use sqlx::{query, PgPool};
|
use sqlx::{query, PgPool};
|
||||||
|
|
||||||
use super::{assignment_changeset::AssignmentChangeset, Function, Result};
|
use super::{assignment_changeset::AssignmentChangeset, Function, Result};
|
||||||
@ -7,8 +7,8 @@ pub struct Assignment {
|
|||||||
pub event_id: i32,
|
pub event_id: i32,
|
||||||
pub availabillity_id: i32,
|
pub availabillity_id: i32,
|
||||||
pub function: Function,
|
pub function: Function,
|
||||||
pub start_time: NaiveTime,
|
pub start: NaiveDateTime,
|
||||||
pub end_time: NaiveTime,
|
pub end: NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Assignment {
|
impl Assignment {
|
||||||
@ -18,10 +18,6 @@ impl Assignment {
|
|||||||
availabillity_id: i32,
|
availabillity_id: i32,
|
||||||
changeset: AssignmentChangeset,
|
changeset: AssignmentChangeset,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// TODO: refactor
|
|
||||||
let date1 = Local::now();
|
|
||||||
let date2 = Local::now();
|
|
||||||
|
|
||||||
query!(
|
query!(
|
||||||
r##"
|
r##"
|
||||||
INSERT INTO assignment (eventId, availabillityId, function, startTimestamp, endTimestamp)
|
INSERT INTO assignment (eventId, availabillityId, function, startTimestamp, endTimestamp)
|
||||||
@ -30,8 +26,8 @@ impl Assignment {
|
|||||||
event_id,
|
event_id,
|
||||||
availabillity_id,
|
availabillity_id,
|
||||||
changeset.function as Function,
|
changeset.function as Function,
|
||||||
date1,
|
changeset.time.0.and_utc(),
|
||||||
date2
|
changeset.time.1.and_utc()
|
||||||
)
|
)
|
||||||
.execute(pool)
|
.execute(pool)
|
||||||
.await?;
|
.await?;
|
||||||
@ -65,9 +61,8 @@ impl Assignment {
|
|||||||
event_id: r.eventid,
|
event_id: r.eventid,
|
||||||
availabillity_id: r.availabillityid,
|
availabillity_id: r.availabillityid,
|
||||||
function: r.function,
|
function: r.function,
|
||||||
// TODO: refactor
|
start: r.starttimestamp.naive_utc(),
|
||||||
start_time: r.starttimestamp.time(),
|
end: r.endtimestamp.naive_utc(),
|
||||||
end_time: r.endtimestamp.time(),
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -97,9 +92,8 @@ impl Assignment {
|
|||||||
event_id: r.eventid,
|
event_id: r.eventid,
|
||||||
availabillity_id: r.availabillityid,
|
availabillity_id: r.availabillityid,
|
||||||
function: r.function,
|
function: r.function,
|
||||||
// TODO: refactor
|
start: r.starttimestamp.naive_utc(),
|
||||||
start_time: r.starttimestamp.time(),
|
end: r.endtimestamp.naive_utc(),
|
||||||
end_time: r.endtimestamp.time(),
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -134,9 +128,8 @@ impl Assignment {
|
|||||||
event_id: r.eventid,
|
event_id: r.eventid,
|
||||||
availabillity_id: r.availabillityid,
|
availabillity_id: r.availabillityid,
|
||||||
function: r.function,
|
function: r.function,
|
||||||
// TODO: refactor
|
start: r.starttimestamp.naive_utc(),
|
||||||
start_time: r.starttimestamp.time(),
|
end: r.endtimestamp.naive_utc(),
|
||||||
end_time: r.endtimestamp.time(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(assignemnet)
|
Ok(assignemnet)
|
||||||
@ -148,11 +141,7 @@ impl Assignment {
|
|||||||
availabillity_id: i32,
|
availabillity_id: i32,
|
||||||
changeset: AssignmentChangeset,
|
changeset: AssignmentChangeset,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// TODO: refactor
|
query!("UPDATE assignment SET function = $1, startTimestamp = $2, endTimestamp = $3 WHERE eventId = $4 AND availabillityId = $5;", changeset.function as Function, changeset.time.0.and_utc(), changeset.time.1.and_utc(), event_id, availabillity_id).execute(pool).await?;
|
||||||
let date1 = Local::now();
|
|
||||||
let date2 = Local::now();
|
|
||||||
|
|
||||||
query!("UPDATE assignment SET function = $1, startTimestamp = $2, endTimestamp = $3 WHERE eventId = $4 AND availabillityId = $5;", changeset.function as Function, date1, date2, event_id, availabillity_id).execute(pool).await?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use chrono::NaiveTime;
|
use chrono::NaiveDateTime;
|
||||||
use garde::Validate;
|
use garde::Validate;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
start_time_lies_before_end_time, Assignment, Availability, Event, Function, UserFunction,
|
start_date_time_lies_before_end_date_time, Assignment, Availability, Event, Function, UserFunction,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Validate)]
|
#[derive(Validate)]
|
||||||
@ -17,10 +17,10 @@ pub struct AssignmentChangeset {
|
|||||||
pub function: Function,
|
pub function: Function,
|
||||||
#[garde(
|
#[garde(
|
||||||
custom(available_time_fits),
|
custom(available_time_fits),
|
||||||
custom(start_time_lies_before_end_time),
|
custom(start_date_time_lies_before_end_date_time),
|
||||||
custom(availabillity_not_already_assigned)
|
custom(availabillity_not_already_assigned)
|
||||||
)]
|
)]
|
||||||
pub time: (NaiveTime, NaiveTime),
|
pub time: (NaiveDateTime, NaiveDateTime),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AssignmentContext {
|
pub struct AssignmentContext {
|
||||||
@ -32,16 +32,14 @@ pub struct AssignmentContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn available_time_fits(
|
fn available_time_fits(
|
||||||
value: &(NaiveTime, NaiveTime),
|
value: &(NaiveDateTime, NaiveDateTime),
|
||||||
context: &AssignmentContext,
|
context: &AssignmentContext,
|
||||||
) -> garde::Result {
|
) -> garde::Result {
|
||||||
// if let AvailabilityTime::Temporarily(start, end) = context.availabillity.time {
|
if value.0 < context.availabillity.start || value.1 > context.availabillity.end {
|
||||||
// if value.0 < start || value.1 > end {
|
return Err(garde::Error::new(
|
||||||
// return Err(garde::Error::new(
|
"time not made available can't be assigned",
|
||||||
// "time not made available can't be assigned",
|
));
|
||||||
// ));
|
}
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -89,7 +87,7 @@ fn event_has_free_slot_for_function(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn availabillity_not_already_assigned(
|
fn availabillity_not_already_assigned(
|
||||||
value: &(NaiveTime, NaiveTime),
|
value: &(NaiveDateTime, NaiveDateTime),
|
||||||
context: &AssignmentContext,
|
context: &AssignmentContext,
|
||||||
) -> garde::Result {
|
) -> garde::Result {
|
||||||
let list: Vec<&Assignment> = context
|
let list: Vec<&Assignment> = context
|
||||||
@ -101,9 +99,8 @@ fn availabillity_not_already_assigned(
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let has_start_time_during_assignment =
|
let has_start_time_during_assignment =
|
||||||
|a: &Assignment| a.start_time >= value.0 && a.start_time <= value.1;
|
|a: &Assignment| a.start >= value.0 && a.start <= value.1;
|
||||||
let has_end_time_during_assignment =
|
let has_end_time_during_assignment = |a: &Assignment| a.end >= value.0 && a.end <= value.1;
|
||||||
|a: &Assignment| a.end_time >= value.0 && a.end_time <= value.1;
|
|
||||||
|
|
||||||
if list
|
if list
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -3,7 +3,7 @@ use garde::Validate;
|
|||||||
|
|
||||||
use crate::{END_OF_DAY, START_OF_DAY};
|
use crate::{END_OF_DAY, START_OF_DAY};
|
||||||
|
|
||||||
use super::{start_date_time_lies_before_end_time, Availability};
|
use super::{start_date_time_lies_before_end_date_time, Availability};
|
||||||
|
|
||||||
#[derive(Validate)]
|
#[derive(Validate)]
|
||||||
#[garde(allow_unvalidated)]
|
#[garde(allow_unvalidated)]
|
||||||
@ -11,7 +11,7 @@ use super::{start_date_time_lies_before_end_time, Availability};
|
|||||||
pub struct AvailabilityChangeset {
|
pub struct AvailabilityChangeset {
|
||||||
#[garde(
|
#[garde(
|
||||||
custom(time_is_not_already_made_available),
|
custom(time_is_not_already_made_available),
|
||||||
custom(start_date_time_lies_before_end_time)
|
custom(start_date_time_lies_before_end_date_time)
|
||||||
)]
|
)]
|
||||||
pub time: (NaiveDateTime, NaiveDateTime),
|
pub time: (NaiveDateTime, NaiveDateTime),
|
||||||
pub comment: Option<String>,
|
pub comment: Option<String>,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use chrono::{Local, NaiveDate, NaiveDateTime, NaiveTime};
|
use chrono::{NaiveDate, NaiveDateTime};
|
||||||
use sqlx::{query, PgPool};
|
use sqlx::{query, PgPool};
|
||||||
|
|
||||||
use super::{Area, AvailabilityChangeset, Result, Role, User, UserFunction};
|
use super::{Area, AvailabilityChangeset, Result, Role, User, UserFunction};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use chrono::{Local, NaiveDate, NaiveTime};
|
use chrono::{NaiveDate, NaiveDateTime};
|
||||||
use sqlx::{query, PgPool};
|
use sqlx::{query, PgPool};
|
||||||
|
|
||||||
use super::{event_changeset::EventChangeset, Location, Result};
|
use super::{event_changeset::EventChangeset, Location, Result};
|
||||||
@ -6,9 +6,8 @@ use super::{event_changeset::EventChangeset, Location, Result};
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Event {
|
pub struct Event {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
pub date: NaiveDate,
|
pub start: NaiveDateTime,
|
||||||
pub start_time: NaiveTime,
|
pub end: NaiveDateTime,
|
||||||
pub end_time: NaiveTime,
|
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub location_id: i32,
|
pub location_id: i32,
|
||||||
pub location: Option<Location>,
|
pub location: Option<Location>,
|
||||||
@ -22,15 +21,11 @@ pub struct Event {
|
|||||||
|
|
||||||
impl Event {
|
impl Event {
|
||||||
pub async fn create(pool: &PgPool, changeset: EventChangeset) -> Result<()> {
|
pub async fn create(pool: &PgPool, changeset: EventChangeset) -> Result<()> {
|
||||||
// TODO: refactor
|
|
||||||
let date1 = Local::now();
|
|
||||||
let date2 = Local::now();
|
|
||||||
|
|
||||||
query!(r#"
|
query!(r#"
|
||||||
INSERT INTO event (startTimestamp, endTimestamp, name, locationId, voluntaryWachhabender, voluntaryFuehrungsassistent, amountOfPosten, clothing, note)
|
INSERT INTO event (startTimestamp, endTimestamp, name, locationId, voluntaryWachhabender, voluntaryFuehrungsassistent, amountOfPosten, clothing, note)
|
||||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9);
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9);
|
||||||
"#,
|
"#,
|
||||||
date1, date2, changeset.name, changeset.location_id, changeset.voluntary_wachhabender, changeset.voluntary_fuehrungsassistent, changeset.amount_of_posten, changeset.clothing, changeset.note).execute(pool).await?;
|
changeset.time.0.and_utc(), changeset.time.1.and_utc(), changeset.name, changeset.location_id, changeset.voluntary_wachhabender, changeset.voluntary_fuehrungsassistent, changeset.amount_of_posten, changeset.clothing, changeset.note).execute(pool).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -73,9 +68,8 @@ impl Event {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|record| Event {
|
.map(|record| Event {
|
||||||
id: record.eventid,
|
id: record.eventid,
|
||||||
date: record.starttimestamp.date_naive(),
|
start: record.starttimestamp.naive_utc(),
|
||||||
start_time: record.starttimestamp.time(),
|
end: record.endtimestamp.naive_utc(),
|
||||||
end_time: record.endtimestamp.time(),
|
|
||||||
name: record.name.to_string(),
|
name: record.name.to_string(),
|
||||||
location_id: record.locationid,
|
location_id: record.locationid,
|
||||||
location: Some(Location {
|
location: Some(Location {
|
||||||
@ -125,9 +119,8 @@ impl Event {
|
|||||||
|
|
||||||
let event = record.map(|record| Event {
|
let event = record.map(|record| Event {
|
||||||
id: record.eventid,
|
id: record.eventid,
|
||||||
date: record.starttimestamp.date_naive(),
|
start: record.starttimestamp.naive_utc(),
|
||||||
start_time: record.starttimestamp.time(),
|
end: record.endtimestamp.naive_utc(),
|
||||||
end_time: record.endtimestamp.time(),
|
|
||||||
name: record.name.to_string(),
|
name: record.name.to_string(),
|
||||||
location_id: record.locationid,
|
location_id: record.locationid,
|
||||||
location: Some(Location {
|
location: Some(Location {
|
||||||
@ -148,16 +141,18 @@ impl Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(pool: &PgPool, id: i32, changeset: EventChangeset) -> Result<()> {
|
pub async fn update(pool: &PgPool, id: i32, changeset: EventChangeset) -> Result<()> {
|
||||||
// TODO: refactor
|
|
||||||
let date1 = Local::now();
|
|
||||||
let date2 = Local::now();
|
|
||||||
|
|
||||||
query!(r#"
|
query!(r#"
|
||||||
UPDATE event SET startTimestamp = $1, endTimestamp = $2, name = $3, locationId = $4, voluntaryWachhabender = $5, voluntaryFuehrungsassistent = $6, amountOfPosten = $7, clothing = $8, note = $9 WHERE id = $10;
|
UPDATE event SET startTimestamp = $1, endTimestamp = $2, name = $3, locationId = $4, voluntaryWachhabender = $5, voluntaryFuehrungsassistent = $6, amountOfPosten = $7, clothing = $8, note = $9 WHERE id = $10;
|
||||||
"#,
|
"#,
|
||||||
date1,
|
changeset.time.0.and_utc(),
|
||||||
date2
|
changeset.time.1.and_utc(),
|
||||||
,changeset.name, changeset.location_id, changeset.voluntary_wachhabender, changeset.voluntary_fuehrungsassistent, changeset.amount_of_posten, changeset.clothing, changeset.note, id)
|
changeset.name,
|
||||||
|
changeset.location_id,
|
||||||
|
changeset.voluntary_wachhabender,
|
||||||
|
changeset.voluntary_fuehrungsassistent,
|
||||||
|
changeset.amount_of_posten,
|
||||||
|
changeset.clothing,
|
||||||
|
changeset.note, id)
|
||||||
.execute(pool)
|
.execute(pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
use chrono::NaiveTime;
|
use chrono::NaiveDateTime;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use fake::{Faker, Fake};
|
use fake::{Fake, Faker};
|
||||||
use garde::Validate;
|
use garde::Validate;
|
||||||
|
|
||||||
use super::start_time_lies_before_end_time;
|
use super::start_date_time_lies_before_end_date_time;
|
||||||
|
|
||||||
#[derive(Validate)]
|
#[derive(Validate)]
|
||||||
#[garde(allow_unvalidated)]
|
#[garde(allow_unvalidated)]
|
||||||
#[garde(context(Option<EventContext> as ctx))]
|
#[garde(context(Option<EventContext> as ctx))]
|
||||||
pub struct EventChangeset {
|
pub struct EventChangeset {
|
||||||
#[garde(custom(date_unchanged_if_edit))]
|
|
||||||
pub date: NaiveDate,
|
|
||||||
#[garde(
|
#[garde(
|
||||||
custom(start_time_lies_before_end_time),
|
custom(start_date_time_lies_before_end_date_time),
|
||||||
custom(time_can_be_extended_if_edit)
|
custom(time_can_be_extended_if_edit),
|
||||||
|
custom(date_unchanged_if_edit)
|
||||||
)]
|
)]
|
||||||
pub time: (NaiveTime, NaiveTime),
|
pub time: (NaiveDateTime, NaiveDateTime),
|
||||||
pub name: String,
|
pub name: String,
|
||||||
/// check before: must exist and user can create event for this location
|
/// check before: must exist and user can create event for this location
|
||||||
pub location_id: i32,
|
pub location_id: i32,
|
||||||
@ -32,9 +31,8 @@ pub struct EventChangeset {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl EventChangeset {
|
impl EventChangeset {
|
||||||
pub fn create_for_test(date: NaiveDate, start: NaiveTime, end: NaiveTime) -> EventChangeset {
|
pub fn create_for_test(start: NaiveDateTime, end: NaiveDateTime) -> EventChangeset {
|
||||||
let changeset = EventChangeset {
|
let changeset = EventChangeset {
|
||||||
date,
|
|
||||||
time: (start, end),
|
time: (start, end),
|
||||||
name: Faker.fake(),
|
name: Faker.fake(),
|
||||||
location_id: 1,
|
location_id: 1,
|
||||||
@ -51,14 +49,14 @@ impl EventChangeset {
|
|||||||
|
|
||||||
pub struct EventContext {
|
pub struct EventContext {
|
||||||
pub date_in_db: NaiveDate,
|
pub date_in_db: NaiveDate,
|
||||||
pub common_min_max_available_time: (NaiveTime, NaiveTime),
|
pub common_min_max_available_time: (NaiveDateTime, NaiveDateTime),
|
||||||
pub wachhabender_assigned: bool,
|
pub wachhabender_assigned: bool,
|
||||||
pub fuehrungsassistent_assigned: bool,
|
pub fuehrungsassistent_assigned: bool,
|
||||||
pub amount_of_assigned_posten: i16,
|
pub amount_of_assigned_posten: i16,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn date_unchanged_if_edit(value: &NaiveDate, context: &Option<EventContext>) -> garde::Result {
|
fn date_unchanged_if_edit(value: &(NaiveDateTime, NaiveDateTime), context: &Option<EventContext>) -> garde::Result {
|
||||||
if context.as_ref().is_some_and(|c| c.date_in_db != *value) {
|
if context.as_ref().is_some_and(|c| c.date_in_db != value.0.date() ) {
|
||||||
return Err(garde::Error::new("event date can't be changed"));
|
return Err(garde::Error::new("event date can't be changed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +64,7 @@ fn date_unchanged_if_edit(value: &NaiveDate, context: &Option<EventContext>) ->
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn time_can_be_extended_if_edit(
|
fn time_can_be_extended_if_edit(
|
||||||
value: &(NaiveTime, NaiveTime),
|
value: &(NaiveDateTime, NaiveDateTime),
|
||||||
context: &Option<EventContext>,
|
context: &Option<EventContext>,
|
||||||
) -> garde::Result {
|
) -> garde::Result {
|
||||||
if let Some(context) = context {
|
if let Some(context) = context {
|
||||||
|
@ -25,7 +25,7 @@ pub use availability_changeset::{
|
|||||||
};
|
};
|
||||||
pub use availabillity::Availability;
|
pub use availabillity::Availability;
|
||||||
pub use availabillity_assignment_state::AvailabillityAssignmentState;
|
pub use availabillity_assignment_state::AvailabillityAssignmentState;
|
||||||
use chrono::{NaiveDateTime, NaiveTime};
|
use chrono::NaiveDateTime;
|
||||||
pub use event::Event;
|
pub use event::Event;
|
||||||
pub use event_changeset::{EventChangeset, EventContext};
|
pub use event_changeset::{EventChangeset, EventContext};
|
||||||
pub use function::Function;
|
pub use function::Function;
|
||||||
@ -41,18 +41,7 @@ pub use vehicle_assignement::VehicleAssignement;
|
|||||||
|
|
||||||
type Result<T> = std::result::Result<T, sqlx::Error>;
|
type Result<T> = std::result::Result<T, sqlx::Error>;
|
||||||
|
|
||||||
fn start_time_lies_before_end_time<T>(
|
fn start_date_time_lies_before_end_date_time<T>(
|
||||||
value: &(NaiveTime, NaiveTime),
|
|
||||||
_context: &T,
|
|
||||||
) -> garde::Result {
|
|
||||||
if value.0 >= value.1 {
|
|
||||||
return Err(garde::Error::new("endtime can't lie before starttime"));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn start_date_time_lies_before_end_time<T>(
|
|
||||||
value: &(NaiveDateTime, NaiveDateTime),
|
value: &(NaiveDateTime, NaiveDateTime),
|
||||||
_context: &T,
|
_context: &T,
|
||||||
) -> garde::Result {
|
) -> garde::Result {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use chrono::{Local, NaiveDate, NaiveTime};
|
use chrono::{NaiveDate, NaiveDateTime};
|
||||||
use sqlx::{query, PgPool};
|
use sqlx::{query, PgPool};
|
||||||
|
|
||||||
use super::Result;
|
use super::Result;
|
||||||
@ -6,8 +6,8 @@ use super::Result;
|
|||||||
pub struct VehicleAssignement {
|
pub struct VehicleAssignement {
|
||||||
pub event_id: i32,
|
pub event_id: i32,
|
||||||
pub vehicle_id: i32,
|
pub vehicle_id: i32,
|
||||||
pub start_time: NaiveTime,
|
pub start: NaiveDateTime,
|
||||||
pub end_time: NaiveTime,
|
pub end: NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VehicleAssignement {
|
impl VehicleAssignement {
|
||||||
@ -15,19 +15,15 @@ impl VehicleAssignement {
|
|||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
event_id: i32,
|
event_id: i32,
|
||||||
vehicle_id: i32,
|
vehicle_id: i32,
|
||||||
start_time: NaiveTime,
|
start: NaiveDateTime,
|
||||||
end_time: NaiveTime,
|
end: NaiveDateTime,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// TODO: refactor
|
|
||||||
let date1 = Local::now();
|
|
||||||
let date2 = Local::now();
|
|
||||||
|
|
||||||
query!(
|
query!(
|
||||||
"INSERT INTO vehicleassignement (eventId, vehicleId, startTimestamp, endTimestamp) VALUES ($1, $2, $3, $4);",
|
"INSERT INTO vehicleassignement (eventId, vehicleId, startTimestamp, endTimestamp) VALUES ($1, $2, $3, $4);",
|
||||||
event_id,
|
event_id,
|
||||||
vehicle_id,
|
vehicle_id,
|
||||||
date1,
|
start.and_utc(),
|
||||||
date2
|
end.and_utc()
|
||||||
)
|
)
|
||||||
.execute(pool)
|
.execute(pool)
|
||||||
.await?;
|
.await?;
|
||||||
@ -43,12 +39,11 @@ impl VehicleAssignement {
|
|||||||
let record = query!("SELECT * FROM vehicleAssignement WHERE vehicleAssignement.eventId = $1 AND vehicleAssignement.vehicleId = $2;", event_id, vehicle_id).fetch_optional(pool)
|
let record = query!("SELECT * FROM vehicleAssignement WHERE vehicleAssignement.eventId = $1 AND vehicleAssignement.vehicleId = $2;", event_id, vehicle_id).fetch_optional(pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
let vehicle_assignment = record.map(|r| VehicleAssignement {
|
let vehicle_assignment = record.map(|r| VehicleAssignement {
|
||||||
event_id: r.eventid,
|
event_id: r.eventid,
|
||||||
vehicle_id: r.vehicleid,
|
vehicle_id: r.vehicleid,
|
||||||
start_time: r.starttimestamp.time(),
|
start: r.starttimestamp.naive_utc(),
|
||||||
end_time: r.endtimestamp.time(),
|
end: r.endtimestamp.naive_utc(),
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(vehicle_assignment)
|
Ok(vehicle_assignment)
|
||||||
@ -65,14 +60,13 @@ impl VehicleAssignement {
|
|||||||
.fetch_all(pool)
|
.fetch_all(pool)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
let vehicle_assignments = records
|
let vehicle_assignments = records
|
||||||
.iter()
|
.iter()
|
||||||
.map(|r| VehicleAssignement {
|
.map(|r| VehicleAssignement {
|
||||||
event_id: r.eventid,
|
event_id: r.eventid,
|
||||||
vehicle_id: r.vehicleid,
|
vehicle_id: r.vehicleid,
|
||||||
start_time: r.starttimestamp.time(),
|
start: r.starttimestamp.naive_utc(),
|
||||||
end_time: r.endtimestamp.time(),
|
end: r.endtimestamp.naive_utc(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -82,7 +76,7 @@ impl VehicleAssignement {
|
|||||||
pub async fn read_all_by_vehicle_and_date(
|
pub async fn read_all_by_vehicle_and_date(
|
||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
vehicle_id: i32,
|
vehicle_id: i32,
|
||||||
date: NaiveDate
|
date: NaiveDate,
|
||||||
) -> Result<Vec<VehicleAssignement>> {
|
) -> Result<Vec<VehicleAssignement>> {
|
||||||
let records = query!(
|
let records = query!(
|
||||||
r#"
|
r#"
|
||||||
@ -109,8 +103,8 @@ impl VehicleAssignement {
|
|||||||
.map(|r| VehicleAssignement {
|
.map(|r| VehicleAssignement {
|
||||||
event_id: r.eventid,
|
event_id: r.eventid,
|
||||||
vehicle_id: r.vehicleid,
|
vehicle_id: r.vehicleid,
|
||||||
start_time: r.starttimestamp.time(),
|
start: r.starttimestamp.naive_utc(),
|
||||||
end_time: r.endtimestamp.time(),
|
end: r.endtimestamp.naive_utc(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ pub async fn generate_availabillity_assignment_list(
|
|||||||
) -> Result<Vec<(Availability, AvailabillityAssignmentState)>, ApplicationError> {
|
) -> Result<Vec<(Availability, AvailabillityAssignmentState)>, ApplicationError> {
|
||||||
let availabillities_in_db = Availability::read_by_date_time_area_including_user(
|
let availabillities_in_db = Availability::read_by_date_time_area_including_user(
|
||||||
pool,
|
pool,
|
||||||
event.date,
|
event.start.date(),
|
||||||
(event.start_time, event.end_time),
|
(event.start, event.end),
|
||||||
event.location.as_ref().unwrap().area_id,
|
event.location.as_ref().unwrap().area_id,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@ -46,9 +46,8 @@ pub async fn generate_availabillity_assignment_list(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let has_start_time_during_event =
|
let has_start_time_during_event =
|
||||||
|a: &Assignment| a.start_time >= event.start_time && a.start_time <= event.end_time;
|
|a: &Assignment| a.start >= event.start && a.start <= event.end;
|
||||||
let has_end_time_during_event =
|
let has_end_time_during_event = |a: &Assignment| a.end >= event.start && a.end <= event.end;
|
||||||
|a: &Assignment| a.end_time >= event.start_time && a.end_time <= event.end_time;
|
|
||||||
|
|
||||||
if assignments
|
if assignments
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -8,11 +8,9 @@
|
|||||||
<h1 class="title">Event '{{ event.name }}' bearbeiten</h1>
|
<h1 class="title">Event '{{ event.name }}' bearbeiten</h1>
|
||||||
{% else %}
|
{% else %}
|
||||||
<form method="post" action="/events/new">
|
<form method="post" action="/events/new">
|
||||||
<h1 class="title">Neues Event anlegen für den {{ date.format("%d.%m.%Y") }}</h1>
|
<h1 class="title">Neues Event anlegen für den {{ date|date_d }}</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<input type="hidden" name="date" value="{{ date }}">
|
|
||||||
|
|
||||||
{% if let Some(event) = event %}
|
{% if let Some(event) = event %}
|
||||||
<div class="field is-horizontal">
|
<div class="field is-horizontal">
|
||||||
<div class="field-label"></div>
|
<div class="field-label"></div>
|
||||||
@ -32,8 +30,9 @@
|
|||||||
<div class="control">
|
<div class="control">
|
||||||
{% let delete_disabled = amount_of_planned_posten > 0 || is_wachhabender_planned ||
|
{% let delete_disabled = amount_of_planned_posten > 0 || is_wachhabender_planned ||
|
||||||
is_fuehrungsassistent_planned %}
|
is_fuehrungsassistent_planned %}
|
||||||
<button class="button is-danger" type="button" hx-delete="/events/{{ event.id }}" {{
|
<button class="button is-danger" type="button"
|
||||||
delete_disabled|cond_show("disabled") }} hx-trigger="confirmed">
|
hx-delete="/events/{{ event.id }}" {{ delete_disabled|cond_show("disabled") }}
|
||||||
|
hx-trigger="confirmed">
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use href="/static/feather-sprite.svg#x-circle" />
|
<use href="/static/feather-sprite.svg#x-circle" />
|
||||||
</svg>
|
</svg>
|
||||||
@ -59,8 +58,9 @@
|
|||||||
<div class="field-body">
|
<div class="field-body">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" name="name" placeholder="Wave Gotik Treffen" required {% if let Some(event)=event
|
<input class="input" name="name" placeholder="Wave Gotik Treffen" required
|
||||||
%} value="{{ event.name }}" {% endif %} {{ disabled|cond_show("disabled") }} />
|
{% if let Some(event)=event %} value="{{ event.name }}" {% endif %}
|
||||||
|
{{ disabled|cond_show("disabled") }} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -71,14 +71,17 @@
|
|||||||
<label class="label">Startzeit - Endzeit</label>
|
<label class="label">Startzeit - Endzeit</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-body">
|
<div class="field-body">
|
||||||
{% let f = "%H:%M" %}
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<input class="input" type="time" id="from" name="from" required value="{% if let Some(event)=event
|
<input class="input" type="datetime-local" id="from" name="from" required
|
||||||
%}{{ event.start_time.format(f) }}{% else %}00:00{% endif %}" {{ disabled|cond_show("disabled") }} />
|
value="{% if let Some(event)=event %}{{ event.start|dt_f }}{% else %}{{ date }}{% endif
|
||||||
|
%}"
|
||||||
|
{{ disabled|cond_show("disabled") }} min="{{ date }}T00:00" max="{{ date }}T23:59" />
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<input class="input" type="time" id="till" name="till" required value="{% if let Some(event)=event
|
<input class="input" type="datetime-local" id="till" name="till" required
|
||||||
%}{{ event.end_time.format(f) }}{% else %}23:59{% endif %}" {{ disabled|cond_show("disabled") }} />
|
value="{% if let Some(event)=event %}{{ event.end|dt_f }}{% else %}{{ date }}{% endif %}"
|
||||||
|
{{ disabled|cond_show("disabled") }} min="{{ date }}T00:00"
|
||||||
|
max="{{ date.checked_add_days(Days::new(1)).unwrap() }}T23:59" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -94,7 +97,8 @@
|
|||||||
<select name="location" required {{ disabled|cond_show("disabled") }}>
|
<select name="location" required {{ disabled|cond_show("disabled") }}>
|
||||||
{% for location in locations %}
|
{% for location in locations %}
|
||||||
<option value="{{ location.id }}" {% if let Some(event)=event %}{{
|
<option value="{{ location.id }}" {% if let Some(event)=event %}{{
|
||||||
(event.location_id==location.id)|cond_show("selected") }}{% endif %}>{{ location.name }}{% if
|
(event.location_id==location.id)|cond_show("selected") }}{% endif %}>{{ location.name }}{%
|
||||||
|
if
|
||||||
user.role == Role::Admin %} - ({{
|
user.role == Role::Admin %} - ({{
|
||||||
location.area.as_ref().unwrap().name }}){% endif %}
|
location.area.as_ref().unwrap().name }}){% endif %}
|
||||||
</option>
|
</option>
|
||||||
@ -117,7 +121,8 @@
|
|||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input class="checkbox" type="checkbox" name="voluntarywachhabender" value="true" {{
|
<input class="checkbox" type="checkbox" name="voluntarywachhabender" value="true" {{
|
||||||
wh_disabled|cond_show("disabled")}} {% if let Some(event)=event %} {{
|
wh_disabled|cond_show("disabled")}} {% if let Some(event)=event %} {{
|
||||||
event.voluntary_wachhabender|cond_show("checked") }} {% endif %} {{ disabled|cond_show("disabled")
|
event.voluntary_wachhabender|cond_show("checked") }} {% endif %} {{
|
||||||
|
disabled|cond_show("disabled")
|
||||||
}}>
|
}}>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@ -163,7 +168,8 @@
|
|||||||
{% let posten_planned = event.is_some() && amount_of_planned_posten > 0 %}
|
{% let posten_planned = event.is_some() && amount_of_planned_posten > 0 %}
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input class="input" type="number" name="amount"
|
<input class="input" type="number" name="amount"
|
||||||
min="{% if posten_planned %}{{ amount_of_planned_posten }}{% else %}0{% endif %}" max="100" required
|
min="{% if posten_planned %}{{ amount_of_planned_posten }}{% else %}0{% endif %}" max="100"
|
||||||
|
required
|
||||||
{% if let Some(event)=event %} value="{{ event.amount_of_posten }}" {% endif %} {{
|
{% if let Some(event)=event %} value="{{ event.amount_of_posten }}" {% endif %} {{
|
||||||
disabled|cond_show("disabled") }} />
|
disabled|cond_show("disabled") }} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -15,11 +15,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
<p><b>Datum:</b> {{ event.date.format("%d.%m.%Y") }}</p>
|
<p><b>Datum:</b> {{ event.start.format("%d.%m.%Y") }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
<p><b>Uhrzeit:</b> {{ event.start_time.format("%R") }} Uhr - {{ event.end_time.format("%R") }} Uhr</p>
|
<p><b>Uhrzeit:</b> {{ event.start.format("%R") }} Uhr - {{ event.end.format("%d.%m.%Y %R") }} Uhr</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell is-col-span-2">
|
<div class="cell is-col-span-2">
|
||||||
@ -62,7 +62,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<a class="button is-link is-light" hx-boost="true" href="/?date={{ event.date }}">
|
<a class="button is-link is-light" hx-boost="true" href="/?date={{ event.start.date() }}">
|
||||||
<svg class="icon">
|
<svg class="icon">
|
||||||
<use href="/static/feather-sprite.svg#arrow-left" />
|
<use href="/static/feather-sprite.svg#arrow-left" />
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
<p><b>Uhrzeit:</b> {{ event.start_time.format("%R") }} Uhr - {{ event.end_time.format("%R") }} Uhr</p>
|
<p><b>Uhrzeit:</b> {{ event.start|dt_t }} Uhr - {{ event.end|dt_f }} Uhr</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="cell">
|
<div class="cell">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user