feat: create new assignment
This commit is contained in:
parent
74acc02e47
commit
2f5cc33261
@ -55,13 +55,13 @@ CREATE TABLE event
|
|||||||
canceled BOOLEAN NOT NULL DEFAULT false
|
canceled BOOLEAN NOT NULL DEFAULT false
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE assignement
|
CREATE TABLE assignment
|
||||||
(
|
(
|
||||||
eventId INTEGER REFERENCES event (id),
|
eventId INTEGER REFERENCES event (id),
|
||||||
availabillityId INTEGER REFERENCES availabillity (id),
|
availabillityId INTEGER REFERENCES availabillity (id),
|
||||||
function function NOT NULL,
|
function function NOT NULL,
|
||||||
startTime TIME,
|
startTime TIME NOT NULL,
|
||||||
endTime TIME,
|
endTime TIME NOT NULL,
|
||||||
PRIMARY KEY (eventId, availabillityId)
|
PRIMARY KEY (eventId, availabillityId)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2,8 +2,11 @@ use actix_web::{web, HttpResponse, Responder};
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use sqlx::PgPool;
|
use sqlx::PgPool;
|
||||||
|
|
||||||
|
use crate::models::{Assignment, Event, Function};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct NewAssignmentsForm {
|
pub struct NewAssignmentsForm {
|
||||||
|
event: i32,
|
||||||
wachhabender: Option<i32>,
|
wachhabender: Option<i32>,
|
||||||
posten: Vec<i32>
|
posten: Vec<i32>
|
||||||
}
|
}
|
||||||
@ -11,5 +14,41 @@ pub struct NewAssignmentsForm {
|
|||||||
#[actix_web::post("/assignments/new")]
|
#[actix_web::post("/assignments/new")]
|
||||||
pub async fn post(pool: web::Data<PgPool>, form: web::Form<NewAssignmentsForm>) -> impl Responder {
|
pub async fn post(pool: web::Data<PgPool>, form: web::Form<NewAssignmentsForm>) -> impl Responder {
|
||||||
|
|
||||||
|
let event = Event::read_by_id_including_location(&pool, form.event).await.unwrap(); // TODO: Check if location is needed
|
||||||
|
|
||||||
|
if event.voluntary_wachhabender && form.wachhabender.is_some() && form.posten.contains(&form.wachhabender.unwrap()) {
|
||||||
|
return HttpResponse::BadRequest().body("Wachhabender kann nicht zugleich Posten sein!");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut joined_ids = form.posten.clone();
|
||||||
|
if let Some(id) = form.wachhabender {
|
||||||
|
joined_ids.push(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
for availabillity_id in joined_ids {
|
||||||
|
let assignments = Assignment::read_by_availabillity(pool.get_ref(), availabillity_id).await.unwrap();
|
||||||
|
|
||||||
|
let mut can_be_used = true;
|
||||||
|
|
||||||
|
for assignment in assignments {
|
||||||
|
if event.start_time >= assignment.start_time && event.start_time <= assignment.end_time {
|
||||||
|
can_be_used = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !can_be_used {
|
||||||
|
return HttpResponse::BadRequest().body("availabillity time slot bereits genutzt!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(id) = form.wachhabender {
|
||||||
|
Assignment::create(pool.get_ref(), id, event.id, Function::Wachhabender, event.start_time, event.end_time).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
for id in &form.posten {
|
||||||
|
Assignment::create(pool.get_ref(), *id, event.id, Function::Posten, event.start_time, event.end_time).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
HttpResponse::Ok().finish()
|
HttpResponse::Ok().finish()
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use chrono::NaiveTime;
|
use chrono::NaiveTime;
|
||||||
use sqlx::PgPool;
|
use sqlx::{query, PgPool};
|
||||||
|
|
||||||
use super::Function;
|
use super::Function;
|
||||||
|
|
||||||
@ -8,12 +8,66 @@ pub struct Assignment {
|
|||||||
pub availabillity_id: i32,
|
pub availabillity_id: i32,
|
||||||
pub function: Function,
|
pub function: Function,
|
||||||
pub start_time: NaiveTime,
|
pub start_time: NaiveTime,
|
||||||
pub end_time: NaiveTime
|
pub end_time: NaiveTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Assignment {
|
impl Assignment {
|
||||||
pub async fn create(pool: &PgPool) -> anyhow::Result<i32> {
|
pub async fn create(
|
||||||
|
pool: &PgPool,
|
||||||
|
availabillity_id: i32,
|
||||||
|
event_id: i32,
|
||||||
|
function: Function,
|
||||||
|
start_time: NaiveTime,
|
||||||
|
end_time: NaiveTime,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
query!(
|
||||||
|
r##"
|
||||||
|
INSERT INTO assignment (eventId, availabillityId, function, startTime, endTime)
|
||||||
|
VALUES ($1, $2, $3, $4, $5);
|
||||||
|
"##,
|
||||||
|
availabillity_id,
|
||||||
|
event_id,
|
||||||
|
function as Function,
|
||||||
|
start_time,
|
||||||
|
end_time
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
Ok(0)
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn read_by_availabillity(
|
||||||
|
pool: &PgPool,
|
||||||
|
availabillity_id: i32,
|
||||||
|
) -> anyhow::Result<Vec<Assignment>> {
|
||||||
|
let records = query!(
|
||||||
|
r##"
|
||||||
|
SELECT
|
||||||
|
assignment.eventId,
|
||||||
|
assignment.availabillityId,
|
||||||
|
assignment.function AS "function: Function",
|
||||||
|
assignment.startTime,
|
||||||
|
assignment.endTime
|
||||||
|
FROM assignment
|
||||||
|
WHERE assignment.AvailabillityId = $1;
|
||||||
|
"##,
|
||||||
|
availabillity_id
|
||||||
|
)
|
||||||
|
.fetch_all(pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let assignemnets = records
|
||||||
|
.iter()
|
||||||
|
.map(|r| Assignment {
|
||||||
|
event_id: r.eventid,
|
||||||
|
availabillity_id: r.availabillityid,
|
||||||
|
function: r.function,
|
||||||
|
start_time: r.starttime,
|
||||||
|
end_time: r.endtime,
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Ok(assignemnets)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ impl Availabillity {
|
|||||||
user_.lastLogin,
|
user_.lastLogin,
|
||||||
user_.receiveNotifications
|
user_.receiveNotifications
|
||||||
FROM availabillity
|
FROM availabillity
|
||||||
LEFT JOIN assignement ON availabillity.Id = assignement.availabillityId
|
LEFT JOIN assignment ON availabillity.Id = assignment.availabillityId
|
||||||
JOIN user_ ON availabillity.userId = user_.id
|
JOIN user_ ON availabillity.userId = user_.id
|
||||||
WHERE availabillity.date = $1;
|
WHERE availabillity.date = $1;
|
||||||
"##,
|
"##,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use sqlx::{Execute, PgPool};
|
use sqlx::PgPool;
|
||||||
|
|
||||||
use super::{Area, Function, Role};
|
use super::{Area, Function, Role};
|
||||||
|
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="section">
|
<section class="section">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<form method="post" action="/users/new">
|
<form method="post" action="/assignments/new">
|
||||||
|
<input type="hidden" name="event" value="{{ event.id }}" />
|
||||||
|
|
||||||
<h1 class="title">Planung für {{ event.name }}</h1>
|
<h1 class="title">Planung für {{ event.name }}</h1>
|
||||||
<div class="box">
|
<div class="box">
|
||||||
{% if event.canceled %}<b>Veranstaltung abgesagt!</b>{% endif %}
|
{% if event.canceled %}<b>Veranstaltung abgesagt!</b>{% endif %}
|
||||||
@ -45,6 +47,7 @@
|
|||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Posten</label>
|
<label class="label">Posten</label>
|
||||||
|
<p class="help">Mehrfachauswahl mit Strg+Mausklick</p>
|
||||||
<div class="select is-multiple">
|
<div class="select is-multiple">
|
||||||
<select name="posten" multiple size="{{ available_posten.len() }}">
|
<select name="posten" multiple size="{{ available_posten.len() }}">
|
||||||
{% for a in available_posten %}
|
{% for a in available_posten %}
|
||||||
@ -79,6 +82,20 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field is-horizontal">
|
||||||
|
<div class="field-label"></div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field is-grouped">
|
||||||
|
<div class="control">
|
||||||
|
<input class="button is-link" type="submit" value="Erstellen">
|
||||||
|
</div>
|
||||||
|
<div class="control">
|
||||||
|
<a class="button is-link is-light" href="/">Zurück</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user