feat: vehicle assignment time

This commit is contained in:
Max Hohlfeld 2024-12-19 13:21:19 +01:00
parent 049b6e81ee
commit c327b6e637
10 changed files with 399 additions and 47 deletions

View File

@ -0,0 +1,40 @@
{
"db_name": "PostgreSQL",
"query": "SELECT * FROM vehicleAssignement WHERE vehicleAssignement.eventId = $1;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "eventid",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "vehicleid",
"type_info": "Int4"
},
{
"ordinal": 2,
"name": "starttime",
"type_info": "Time"
},
{
"ordinal": 3,
"name": "endtime",
"type_info": "Time"
}
],
"parameters": {
"Left": [
"Int4"
]
},
"nullable": [
false,
false,
false,
false
]
},
"hash": "126a17ad3fe8937dfbf70e9a8c2bd7aee56eb35fdff0d0e47037b9af3e08b34f"
}

View File

@ -0,0 +1,17 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO vehicleassignement (eventId, vehicleId, startTime, endTime) VALUES ($1, $2, $3, $4);",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int4",
"Int4",
"Time",
"Time"
]
},
"nullable": []
},
"hash": "57969291aa7b29162b3a39c00f37f260e027d55063f031c8fd0a2efbe7e3b414"
}

View File

@ -1,15 +0,0 @@
{
"db_name": "PostgreSQL",
"query": "INSERT INTO vehicleassignement (eventId, vehicleId) VALUES ($1, $2);",
"describe": {
"columns": [],
"parameters": {
"Left": [
"Int4",
"Int4"
]
},
"nullable": []
},
"hash": "5e7f7ea4cbc3d326e3ea6c694a106f21ecb353648108895ee6d33faa09caa3cc"
}

View File

@ -0,0 +1,40 @@
{
"db_name": "PostgreSQL",
"query": "SELECT * FROM vehicleAssignement WHERE vehicleAssignement.vehicleId = $1;",
"describe": {
"columns": [
{
"ordinal": 0,
"name": "eventid",
"type_info": "Int4"
},
{
"ordinal": 1,
"name": "vehicleid",
"type_info": "Int4"
},
{
"ordinal": 2,
"name": "starttime",
"type_info": "Time"
},
{
"ordinal": 3,
"name": "endtime",
"type_info": "Time"
}
],
"parameters": {
"Left": [
"Int4"
]
},
"nullable": [
false,
false,
false,
false
]
},
"hash": "8897efc635987bca2c2d1a85e001c909404ad2356fc63872fdae5a0cf76e7099"
}

190
Cargo.lock generated
View File

@ -104,7 +104,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
dependencies = [ dependencies = [
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -238,7 +238,7 @@ dependencies = [
"actix-router", "actix-router",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -361,6 +361,55 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anstream"
version = "0.6.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
[[package]]
name = "anstyle-parse"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
dependencies = [
"anstyle",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.94" version = "1.0.94"
@ -379,6 +428,16 @@ dependencies = [
"password-hash", "password-hash",
] ]
[[package]]
name = "async-attributes"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5"
dependencies = [
"quote",
"syn 1.0.109",
]
[[package]] [[package]]
name = "async-channel" name = "async-channel"
version = "1.9.0" version = "1.9.0"
@ -495,6 +554,7 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615"
dependencies = [ dependencies = [
"async-attributes",
"async-channel 1.9.0", "async-channel 1.9.0",
"async-global-executor", "async-global-executor",
"async-io 2.4.0", "async-io 2.4.0",
@ -529,7 +589,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -669,7 +729,7 @@ name = "brass-macros"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -825,9 +885,62 @@ dependencies = [
"inout", "inout",
] ]
[[package]]
name = "clap"
version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.90",
]
[[package]]
name = "clap_lex"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
[[package]] [[package]]
name = "cli" name = "cli"
version = "0.1.0" version = "0.1.0"
dependencies = [
"anyhow",
"async-std",
"brass-config",
"clap",
"sqlx",
]
[[package]]
name = "colorchoice"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]] [[package]]
name = "concurrent-queue" name = "concurrent-queue"
@ -985,7 +1098,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -996,7 +1109,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
dependencies = [ dependencies = [
"darling_core", "darling_core",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -1037,7 +1150,7 @@ dependencies = [
"darling", "darling",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -1047,7 +1160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c"
dependencies = [ dependencies = [
"derive_builder_core", "derive_builder_core",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -1060,7 +1173,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"rustc_version", "rustc_version",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -1080,7 +1193,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
"unicode-xid", "unicode-xid",
] ]
@ -1110,7 +1223,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -1386,7 +1499,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -1755,7 +1868,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -1843,6 +1956,12 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "itertools" name = "itertools"
version = "0.13.0" version = "0.13.0"
@ -2192,7 +2311,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -2562,7 +2681,7 @@ dependencies = [
"rinja_parser", "rinja_parser",
"rustc-hash", "rustc-hash",
"serde", "serde",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -2751,7 +2870,7 @@ checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -2964,7 +3083,7 @@ dependencies = [
"quote", "quote",
"sqlx-core", "sqlx-core",
"sqlx-macros-core", "sqlx-macros-core",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -2988,7 +3107,7 @@ dependencies = [
"sqlx-mysql", "sqlx-mysql",
"sqlx-postgres", "sqlx-postgres",
"sqlx-sqlite", "sqlx-sqlite",
"syn", "syn 2.0.90",
"tempfile", "tempfile",
"url", "url",
] ]
@ -3152,6 +3271,17 @@ version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.90" version = "2.0.90"
@ -3171,7 +3301,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -3204,7 +3334,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -3313,7 +3443,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -3415,6 +3545,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "v_htmlescape" name = "v_htmlescape"
version = "0.15.8" version = "0.15.8"
@ -3478,7 +3614,7 @@ dependencies = [
"log", "log",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -3513,7 +3649,7 @@ checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
"wasm-bindgen-backend", "wasm-bindgen-backend",
"wasm-bindgen-shared", "wasm-bindgen-shared",
] ]
@ -3774,7 +3910,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
"synstructure", "synstructure",
] ]
@ -3796,7 +3932,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]
@ -3816,7 +3952,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
"synstructure", "synstructure",
] ]
@ -3845,7 +3981,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn 2.0.90",
] ]
[[package]] [[package]]

View File

@ -78,6 +78,8 @@ CREATE TABLE vehicleassignement
( (
eventId INTEGER REFERENCES event (id) ON DELETE CASCADE, eventId INTEGER REFERENCES event (id) ON DELETE CASCADE,
vehicleId INTEGER REFERENCES vehicle (id) ON DELETE CASCADE, vehicleId INTEGER REFERENCES vehicle (id) ON DELETE CASCADE,
startTime TIME NOT NULL,
endTime TIME NOT NULL,
PRIMARY KEY (eventId, vehicleId) PRIMARY KEY (eventId, vehicleId)
); );

View File

@ -11,6 +11,7 @@ mod location;
pub mod user; pub mod user;
mod imprint; mod imprint;
mod vehicle; mod vehicle;
mod vehicle_assignment;
#[derive(Deserialize)] #[derive(Deserialize)]
pub struct IdPath { pub struct IdPath {

View File

@ -0,0 +1 @@
pub mod post_new;

View File

@ -0,0 +1,71 @@
use actix_web::{web, HttpResponse, Responder};
use rinja::Template;
use serde::Deserialize;
use sqlx::PgPool;
use crate::{
endpoints::assignment::PlanEventPersonalTablePartialTemplate,
models::{Assignment, Availabillity, Event, Function, Role, User, Vehicle, VehicleAssignement},
utils::{
event_planning_template::{
generate_availabillity_assignment_list, generate_status_whether_staff_is_required,
},
ApplicationError,
},
};
#[derive(Deserialize)]
pub struct VehicleAssignmentQuery {
vehicle: i32,
event: i32,
}
#[actix_web::post("/vehicleassignments/new")]
pub async fn post(
user: web::ReqData<User>,
pool: web::Data<PgPool>,
query: web::Query<VehicleAssignmentQuery>,
) -> Result<impl Responder, ApplicationError> {
let Some(event) = Event::read_by_id_including_location(pool.get_ref(), query.event).await?
else {
return Ok(HttpResponse::NotFound().finish());
};
let user_is_admin_or_area_manager_of_event_area = user.role == Role::Admin
|| (user.role == Role::AreaManager
&& user.area_id == event.location.as_ref().unwrap().area_id);
if !user_is_admin_or_area_manager_of_event_area {
return Err(ApplicationError::Unauthorized);
}
let Some(vehicle) = Vehicle::read(pool.get_ref(), query.vehicle).await? else {
return Ok(HttpResponse::NotFound().finish());
};
let existing_assignments_for_vehicle =
VehicleAssignement::read_all_by_vehicle(pool.get_ref(), vehicle.id).await?;
let has_start_time_during_event =
|a: &VehicleAssignement| a.start_time >= event.start_time && a.start_time <= event.end_time;
let has_end_time_during_event =
|a: &VehicleAssignement| a.end_time >= event.start_time && a.end_time <= event.end_time;
let availability_already_assigned = existing_assignments_for_vehicle
.iter()
.any(|a| has_start_time_during_event(a) || has_end_time_during_event(a));
if availability_already_assigned {
return Ok(HttpResponse::BadRequest().body("Vehicle already assigned to a timely conflicting event."));
}
VehicleAssignement::create(
pool.get_ref(),
event.id,
vehicle.id,
event.start_time,
event.end_time,
)
.await?;
return Ok(HttpResponse::NotFound().finish());
}

View File

@ -1,18 +1,29 @@
use chrono::NaiveTime;
use sqlx::{query, PgPool}; use sqlx::{query, PgPool};
use super::Result; use super::Result;
pub struct VehicleAssignement { pub struct VehicleAssignement {
event_id: i32, pub event_id: i32,
vehicle_id: i32, pub vehicle_id: i32,
pub start_time: NaiveTime,
pub end_time: NaiveTime,
} }
impl VehicleAssignement { impl VehicleAssignement {
pub async fn create(pool: &PgPool, event_id: i32, vehicle_id: i32) -> Result<()> { pub async fn create(
pool: &PgPool,
event_id: i32,
vehicle_id: i32,
start_time: NaiveTime,
end_time: NaiveTime,
) -> Result<()> {
query!( query!(
"INSERT INTO vehicleassignement (eventId, vehicleId) VALUES ($1, $2);", "INSERT INTO vehicleassignement (eventId, vehicleId, startTime, endTime) VALUES ($1, $2, $3, $4);",
event_id, event_id,
vehicle_id vehicle_id,
start_time,
end_time
) )
.execute(pool) .execute(pool)
.await?; .await?;
@ -20,6 +31,54 @@ impl VehicleAssignement {
Ok(()) Ok(())
} }
pub async fn read_all_by_event(
pool: &PgPool,
event_id: i32,
) -> Result<Vec<VehicleAssignement>> {
let records = query!(
"SELECT * FROM vehicleAssignement WHERE vehicleAssignement.eventId = $1;",
event_id
)
.fetch_all(pool)
.await?;
let vehicle_assignments = records
.iter()
.map(|r| VehicleAssignement {
event_id: r.eventid,
vehicle_id: r.vehicleid,
start_time: r.starttime,
end_time: r.endtime,
})
.collect();
Ok(vehicle_assignments)
}
pub async fn read_all_by_vehicle(
pool: &PgPool,
vehicle_id: i32,
) -> Result<Vec<VehicleAssignement>> {
let records = query!(
"SELECT * FROM vehicleAssignement WHERE vehicleAssignement.vehicleId = $1;",
vehicle_id
)
.fetch_all(pool)
.await?;
let vehicle_assignments = records
.iter()
.map(|r| VehicleAssignement {
event_id: r.eventid,
vehicle_id: r.vehicleid,
start_time: r.starttime,
end_time: r.endtime,
})
.collect();
Ok(vehicle_assignments)
}
pub async fn delete(pool: &PgPool, event_id: i32, vehicle_id: i32) -> Result<()> { pub async fn delete(pool: &PgPool, event_id: i32, vehicle_id: i32) -> Result<()> {
query!( query!(
"DELETE FROM vehicleassignement WHERE eventId = $1 AND vehicleId = $2;", "DELETE FROM vehicleassignement WHERE eventId = $1 AND vehicleId = $2;",