feat: show crossareal in event planning
This commit is contained in:
parent
18875a9e0c
commit
760897b301
@ -14,12 +14,15 @@ SELECT
|
||||
user_.areaId,
|
||||
user_.locked,
|
||||
user_.lastLogin,
|
||||
user_.receiveNotifications
|
||||
user_.receiveNotifications,
|
||||
area.name AS areaName
|
||||
FROM availability
|
||||
JOIN
|
||||
user_ ON availability.userId = user_.id
|
||||
JOIN
|
||||
area ON user_.areaId = area.id
|
||||
WHERE
|
||||
availability.starttimestamp::date = $1
|
||||
AND user_.areaId = $2
|
||||
AND (user_.areaId = $2 OR availability.crossAreal = true)
|
||||
AND availability.startTimestamp <= $3
|
||||
AND availability.endTimestamp >= $4;
|
||||
|
@ -18,7 +18,7 @@ impl Availability {
|
||||
pub async fn create(
|
||||
pool: &PgPool,
|
||||
user_id: i32,
|
||||
changeset: AvailabilityChangeset,
|
||||
changeset: &AvailabilityChangeset,
|
||||
) -> Result<()> {
|
||||
query_file!(
|
||||
"sql/availability/create.sql",
|
||||
@ -75,7 +75,7 @@ impl Availability {
|
||||
Ok(availabilities)
|
||||
}
|
||||
|
||||
/// loads availabilities for the area and the same day as the start date and which fully lie inside the daterange
|
||||
/// loads availabilities for the area or ones that are cross-area and the same day as the start date and which fully lie inside the daterange
|
||||
pub async fn read_all_by_daterange_and_area_including_user_for_event_planning(
|
||||
pool: &PgPool,
|
||||
date_range: (NaiveDateTime, NaiveDateTime),
|
||||
@ -105,7 +105,10 @@ impl Availability {
|
||||
role: r.role,
|
||||
function: r.function.clone(),
|
||||
area_id: r.areaid,
|
||||
area: None,
|
||||
area: Some(Area {
|
||||
id: r.areaid,
|
||||
name: r.areaname.clone(),
|
||||
}),
|
||||
locked: r.locked,
|
||||
last_login: r.lastlogin,
|
||||
receive_notifications: r.receivenotifications,
|
||||
|
@ -15,8 +15,6 @@ snapshot_kind: text
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
<td>Max Mustermann</td>
|
||||
<td>
|
||||
|
@ -0,0 +1,210 @@
|
||||
---
|
||||
source: web/src/endpoints/events/get_plan.rs
|
||||
expression: body
|
||||
snapshot_kind: text
|
||||
---
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h1 class="title">Eventplanung</h1>
|
||||
|
||||
<div class="box">
|
||||
<h5 class="title is-5">Allgemeines</h5>
|
||||
|
||||
<div class="fixed-grid has-1-cols-mobile">
|
||||
<div class="grid content">
|
||||
<div class="cell is-col-span-2">
|
||||
<p><b>Name:</b> Große Veranstaltung</p>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<p><b>Datum:</b> Mittwoch, 01.01.2025</p>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<p><b>Uhrzeit:</b> 12:00 Uhr - 01.01.2025 22:00 Uhr</p>
|
||||
</div>
|
||||
|
||||
<div class="cell is-col-span-2">
|
||||
<p><b>Veranstaltungsort:</b> Location</p>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<p><b>Wachhabender:</b> FF</p>
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<p><b>Führungsassistent benötigt:</b> ja</p>
|
||||
</div>
|
||||
|
||||
<div class="cell is-col-span-2">
|
||||
<p><b>Anzahl der Posten:</b> 5</p>
|
||||
</div>
|
||||
|
||||
<div class="cell is-col-span-2">
|
||||
<p><b>Anzugsordnung:</b> Tuchuniform</p>
|
||||
</div>
|
||||
|
||||
<div class="cell is-col-span-2">
|
||||
<p><b>Anmerkungen:</b> </p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h5 class="title is-5">Einteilung Personal</h5>
|
||||
|
||||
|
||||
<table class="table is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Funktion</th>
|
||||
<th>Zeitraum</th>
|
||||
<th>Kommentar</th>
|
||||
<th>Planung</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Max Mustermann</td>
|
||||
<td>
|
||||
<div class="tags"><span class="tag is-primary is-light">Posten</span></div>
|
||||
</td>
|
||||
<td>
|
||||
12:00 bis 01.01.2025 22:00
|
||||
</td>
|
||||
<td>
|
||||
Kommentar
|
||||
</td>
|
||||
<td>
|
||||
<div class="dropdown">
|
||||
<div class="dropdown-trigger"
|
||||
_="on click[.dropdown does not contain target] from elsewhere
|
||||
or keyup[key is 'Escape'] from elsewhere
|
||||
or click[parentElement of me does not match .is-active]
|
||||
remove .is-active from .dropdown end
|
||||
on click toggle .is-active on the parentElement of me">
|
||||
<button class="button" aria-haspopup="true" aria-controls="dropdown-menu">
|
||||
|
||||
<span>als Posten geplant</span>
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#edit-2" />
|
||||
</svg>
|
||||
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content" hx-target="closest table" hx-swap="outerHTML">
|
||||
|
||||
<a class="dropdown-item"
|
||||
hx-post="/assignments/new?event=1&availability=1&function=1" disabled>
|
||||
als Posten planen</a>
|
||||
|
||||
|
||||
|
||||
|
||||
<hr class="dropdown-divider" />
|
||||
<a class="dropdown-item"
|
||||
hx-delete="/assignments/delete?event=1&availability=1"
|
||||
class="button is-small">entplanen</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Rudi Tester (Fremdbereich Süd)</td>
|
||||
<td>
|
||||
<div class="tags"><span class="tag is-primary is-light">Posten</span></div>
|
||||
</td>
|
||||
<td>
|
||||
12:00 bis 01.01.2025 22:00
|
||||
</td>
|
||||
<td>
|
||||
Kommentar
|
||||
</td>
|
||||
<td>
|
||||
<div class="dropdown">
|
||||
<div class="dropdown-trigger"
|
||||
_="on click[.dropdown does not contain target] from elsewhere
|
||||
or keyup[key is 'Escape'] from elsewhere
|
||||
or click[parentElement of me does not match .is-active]
|
||||
remove .is-active from .dropdown end
|
||||
on click toggle .is-active on the parentElement of me">
|
||||
<button class="button" aria-haspopup="true" aria-controls="dropdown-menu">
|
||||
|
||||
<span>Planen</span>
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#chevron-down" />
|
||||
</svg>
|
||||
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu" role="menu">
|
||||
<div class="dropdown-content" hx-target="closest table" hx-swap="outerHTML">
|
||||
|
||||
<a class="dropdown-item"
|
||||
hx-post="/assignments/new?event=1&availability=2&function=1" >
|
||||
als Posten planen</a>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h5 class="title is-5">Einteilung Fahrzeuge</h5>
|
||||
<div id="vehicle-plan">
|
||||
<div class="field is-grouped is-grouped-multiline">
|
||||
|
||||
<div class="control">
|
||||
<div class="tags has-addons">
|
||||
<span class="tag is-link"> 11.49.1 - HLF FF Ost</span>
|
||||
<button class="tag is-delete" hx-delete="/vehicleassignments/delete?event=1&vehicle=1"
|
||||
hx-target="#vehicle-plan" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label">Fahrzeug hinzufügen</label>
|
||||
<div class="control">
|
||||
<div class="select">
|
||||
<select name="vehicle" hx-post="/vehicleassignments/new?event=1" hx-include="this"
|
||||
hx-target="#vehicle-plan">
|
||||
<option selected></option>
|
||||
|
||||
<option value="2">11.19.1 - MTW FF Ost</option>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control">
|
||||
<a class="button is-link is-light" hx-boost="true" href="/calendar?date=2025-01-01">
|
||||
<svg class="icon">
|
||||
<use href="/static/feather-sprite.svg#arrow-left" />
|
||||
</svg>
|
||||
<span>Zurück</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
@ -98,7 +98,7 @@ mod tests {
|
||||
),
|
||||
comment: None,
|
||||
};
|
||||
Availability::create(pool, 1, new_availability).await?;
|
||||
Availability::create(pool, 1, &new_availability).await?;
|
||||
|
||||
let new_assignment = AssignmentChangeset {
|
||||
function: Function::Posten,
|
||||
|
@ -117,7 +117,7 @@ mod tests {
|
||||
Availability::create(
|
||||
pool,
|
||||
1,
|
||||
AvailabilityChangeset {
|
||||
&AvailabilityChangeset {
|
||||
time: (start, end),
|
||||
comment: None,
|
||||
},
|
||||
@ -335,7 +335,7 @@ mod tests {
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
1,
|
||||
AvailabilityChangeset {
|
||||
&AvailabilityChangeset {
|
||||
time: (start, end),
|
||||
comment: None,
|
||||
},
|
||||
@ -346,7 +346,7 @@ mod tests {
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
2,
|
||||
AvailabilityChangeset {
|
||||
&AvailabilityChangeset {
|
||||
time: (start, end),
|
||||
comment: None,
|
||||
},
|
||||
|
@ -34,21 +34,23 @@ mod tests {
|
||||
use brass_macros::db_test;
|
||||
use chrono::NaiveDateTime;
|
||||
use fake::{Fake, Faker};
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::utils::test_helper::{
|
||||
create_test_login_user, test_delete, DbTestContext, NaiveDateTimeExt, RequestConfig,
|
||||
};
|
||||
|
||||
#[db_test]
|
||||
async fn deletes_when_availability_is_from_user_itself(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/availability/delete/1");
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
async fn arrange(pool: &PgPool, availability_id: i32, area_id: i32) -> Result<(), sqlx::Error> {
|
||||
Area::create(pool, "Süd").await?;
|
||||
let mut changeset: UserChangeset = Faker.fake();
|
||||
changeset.area_id = area_id;
|
||||
|
||||
User::create(pool, &changeset).await?;
|
||||
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
1,
|
||||
AvailabilityChangeset {
|
||||
pool,
|
||||
availability_id,
|
||||
&AvailabilityChangeset {
|
||||
time: (
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
|
||||
@ -56,8 +58,18 @@ mod tests {
|
||||
comment: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[db_test]
|
||||
async fn deletes_when_availability_is_from_user_itself(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/availability/delete/1");
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
arrange(&context.db_pool, 1, 1).await.unwrap();
|
||||
|
||||
let response = test_delete(&app, &config).await;
|
||||
assert_eq!(StatusCode::OK, response.status());
|
||||
@ -73,22 +85,7 @@ mod tests {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/availability/delete/1").with_role(Role::AreaManager);
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
User::create(&context.db_pool, &Faker.fake()).await.unwrap();
|
||||
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
2,
|
||||
AvailabilityChangeset {
|
||||
time: (
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
|
||||
),
|
||||
comment: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
arrange(&context.db_pool, 2, 1).await.unwrap();
|
||||
|
||||
let response = test_delete(&app, &config).await;
|
||||
assert_eq!(StatusCode::OK, response.status());
|
||||
@ -104,26 +101,7 @@ mod tests {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/availability/delete/1").with_role(Role::AreaManager);
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
Area::create(&context.db_pool, "Süd").await.unwrap();
|
||||
let mut changeset: UserChangeset = Faker.fake();
|
||||
changeset.area_id = 2;
|
||||
|
||||
User::create(&context.db_pool, &changeset).await.unwrap();
|
||||
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
2,
|
||||
AvailabilityChangeset {
|
||||
time: (
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
|
||||
),
|
||||
comment: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
arrange(&context.db_pool, 2, 2).await.unwrap();
|
||||
|
||||
let response = test_delete(&app, &config).await;
|
||||
assert_eq!(StatusCode::UNAUTHORIZED, response.status());
|
||||
@ -139,22 +117,7 @@ mod tests {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/availability/delete/1").with_role(Role::Admin);
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
User::create(&context.db_pool, &Faker.fake()).await.unwrap();
|
||||
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
2,
|
||||
AvailabilityChangeset {
|
||||
time: (
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
|
||||
),
|
||||
comment: None,
|
||||
},
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
arrange(&context.db_pool, 2, 1).await.unwrap();
|
||||
|
||||
let response = test_delete(&app, &config).await;
|
||||
assert_eq!(StatusCode::OK, response.status());
|
||||
|
@ -66,7 +66,7 @@ pub async fn post(
|
||||
|
||||
Availability::update(pool.get_ref(), a.id, changeset).await?;
|
||||
} else {
|
||||
Availability::create(pool.get_ref(), user_for_availability, changeset).await?;
|
||||
Availability::create(pool.get_ref(), user_for_availability, &changeset).await?;
|
||||
}
|
||||
|
||||
let url = utils::get_return_url_for_date(&form.startdate);
|
||||
|
@ -106,7 +106,7 @@ mod tests {
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
2,
|
||||
AvailabilityChangeset {
|
||||
&AvailabilityChangeset {
|
||||
time: (
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
|
||||
@ -169,7 +169,7 @@ mod tests {
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
2,
|
||||
AvailabilityChangeset {
|
||||
&AvailabilityChangeset {
|
||||
time: (
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
|
||||
@ -216,7 +216,7 @@ mod tests {
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
1,
|
||||
AvailabilityChangeset {
|
||||
&AvailabilityChangeset {
|
||||
time: (
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
|
||||
@ -267,7 +267,7 @@ mod tests {
|
||||
Availability::create(
|
||||
&context.db_pool,
|
||||
2,
|
||||
AvailabilityChangeset {
|
||||
&AvailabilityChangeset {
|
||||
time: (
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 10, 0, 0).unwrap(),
|
||||
NaiveDateTime::from_ymd_and_hms(2025, 02, 01, 10, 0, 0).unwrap(),
|
||||
|
@ -18,7 +18,12 @@ use crate::{
|
||||
use brass_db::models::{Availability, AvailabilityAssignmentState, Event, Role, User, Vehicle};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "events/plan.html")]
|
||||
#[cfg_attr(not(test), template(path = "events/plan.html"))]
|
||||
#[cfg_attr(
|
||||
test,
|
||||
template(path = "events/plan.html", block = "content"),
|
||||
allow(dead_code)
|
||||
)]
|
||||
pub struct PlanEventTemplate {
|
||||
user: User,
|
||||
event: Event,
|
||||
@ -72,3 +77,132 @@ pub async fn get(
|
||||
|
||||
Ok(template.to_response()?)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use actix_http::StatusCode;
|
||||
use brass_macros::db_test;
|
||||
use chrono::NaiveDateTime;
|
||||
use fake::{Fake, Faker};
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::utils::test_helper::{
|
||||
assert_snapshot, create_test_login_user, test_get, DbTestContext, NaiveDateTimeExt,
|
||||
RequestConfig, ServiceResponseExt,
|
||||
};
|
||||
use brass_db::models::{
|
||||
Area, Assignment, AssignmentChangeset, Availability, AvailabilityChangeset, Event,
|
||||
EventChangeset, Function, Location, Role, User, UserChangeset, Vehicle, VehicleAssignment,
|
||||
};
|
||||
|
||||
#[db_test]
|
||||
async fn generates_template_for_admin(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/events/1/plan").with_role(Role::Admin);
|
||||
arrange(&context.db_pool).await.unwrap();
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
let (status, body) = test_get(app, &config).await.into_status_and_body().await;
|
||||
|
||||
assert_eq!(StatusCode::OK, status);
|
||||
assert_snapshot!(body);
|
||||
}
|
||||
|
||||
#[db_test]
|
||||
async fn returns_ok_for_area_manager_of_same_area(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/events/1/plan").with_role(Role::AreaManager);
|
||||
arrange(&context.db_pool).await.unwrap();
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
let response = test_get(app, &config).await;
|
||||
|
||||
assert_eq!(StatusCode::OK, response.status());
|
||||
}
|
||||
|
||||
#[db_test]
|
||||
async fn returns_unauthorized_for_area_manager_of_different_area(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/events/1/plan")
|
||||
.with_role(Role::AreaManager)
|
||||
.with_user_area(2);
|
||||
arrange(&context.db_pool).await.unwrap();
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
let response = test_get(app, &config).await;
|
||||
|
||||
assert_eq!(StatusCode::UNAUTHORIZED, response.status());
|
||||
}
|
||||
|
||||
#[db_test]
|
||||
async fn returns_unauthorized_for_user(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/events/1/plan");
|
||||
arrange(&context.db_pool).await.unwrap();
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
let response = test_get(app, &config).await;
|
||||
|
||||
assert_eq!(StatusCode::UNAUTHORIZED, response.status());
|
||||
}
|
||||
|
||||
#[db_test]
|
||||
async fn returns_not_found_when_event_doesnt_exist(context: &DbTestContext) {
|
||||
let app = context.app().await;
|
||||
let config = RequestConfig::new("/events/1/plan").with_role(Role::AreaManager);
|
||||
create_test_login_user(&context.db_pool, &config).await;
|
||||
|
||||
let response = test_get(app, &config).await;
|
||||
|
||||
assert_eq!(StatusCode::NOT_FOUND, response.status());
|
||||
}
|
||||
|
||||
async fn arrange(pool: &PgPool) -> anyhow::Result<()> {
|
||||
Location::create(pool, "Location", 1).await?;
|
||||
Area::create(pool, "Süd").await.unwrap();
|
||||
|
||||
let mut user_changeset: UserChangeset = Faker.fake();
|
||||
user_changeset.name = "Max Mustermann".to_string();
|
||||
User::create(pool, &user_changeset).await?;
|
||||
|
||||
let mut other_area_user: UserChangeset = Faker.fake();
|
||||
other_area_user.area_id = 2;
|
||||
other_area_user.name = "Rudi Tester".to_string();
|
||||
User::create(pool, &other_area_user).await?;
|
||||
|
||||
let start = NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 12, 0, 0).unwrap();
|
||||
let end = NaiveDateTime::from_ymd_and_hms(2025, 01, 01, 22, 0, 0).unwrap();
|
||||
|
||||
let mut new_event = EventChangeset::create_for_test(start, end);
|
||||
new_event.name = "Große Veranstaltung".to_string();
|
||||
Event::create(pool, new_event).await?;
|
||||
|
||||
let new_availability = AvailabilityChangeset {
|
||||
time: (start, end),
|
||||
comment: Some("Kommentar".to_string()),
|
||||
};
|
||||
Availability::create(pool, 1, &new_availability).await?;
|
||||
Availability::create(pool, 2, &new_availability).await?;
|
||||
Availability::update_cross_areal(pool, 2, true)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let new_assignment = AssignmentChangeset {
|
||||
function: Function::Posten,
|
||||
time: (start, end),
|
||||
};
|
||||
Assignment::create(pool, 1, 1, new_assignment).await?;
|
||||
|
||||
Vehicle::create(pool, "11.49.1", "HLF FF Ost")
|
||||
.await
|
||||
.unwrap();
|
||||
Vehicle::create(pool, "11.19.1", "MTW FF Ost")
|
||||
.await
|
||||
.unwrap();
|
||||
VehicleAssignment::create(pool, 1, 1, start, end)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
</div>
|
||||
|
||||
<div class="cell">
|
||||
<p><b>Führungsassistent benötigt:</b> {% if event.fuehrungsassistent_required %}ja{% else %}nein{% endif %}
|
||||
<p><b>Führungsassistent benötigt:</b> {% if event.fuehrungsassistent_required %}ja{% else %}nein{% endif -%}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
@ -19,10 +19,11 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for (availability, status) in availabilities %}
|
||||
{% let u = availability.user.as_ref().unwrap() %}
|
||||
{% for (availability, status) in availabilities -%}
|
||||
{%- let u = availability.user.as_ref().unwrap() -%}
|
||||
<tr>
|
||||
<td>{{ u.name }}</td>
|
||||
<td>{{ u.name }}{% if u.area_id != event.location.as_ref().unwrap().area_id %} (Fremdbereich {{ u.area.as_ref().unwrap().name
|
||||
}}){% endif %}</td>
|
||||
<td>
|
||||
{{ u.function|show_tree|safe }}
|
||||
</td>
|
||||
|
Loading…
x
Reference in New Issue
Block a user