show steering person in logs if not cox #375
@ -81,7 +81,7 @@ test("Cox can start and finish trip", async ({ page }, testInfo) => {
|
|||||||
const currentValue = await page.$eval(datetimeSelector, el => el.value);
|
const currentValue = await page.$eval(datetimeSelector, el => el.value);
|
||||||
const currentDate = new Date(currentValue);
|
const currentDate = new Date(currentValue);
|
||||||
currentDate.setMinutes(currentDate.getMinutes() + 1);
|
currentDate.setMinutes(currentDate.getMinutes() + 1);
|
||||||
currentDate.setHours(currentDate.getHours() + 1);
|
currentDate.setHours(currentDate.getHours() - new Date().getTimezoneOffset()/60);
|
||||||
const newDatetime = currentDate.toISOString().slice(0, 16);
|
const newDatetime = currentDate.toISOString().slice(0, 16);
|
||||||
await page.$eval(datetimeSelector, (el, value) => el.value = value, newDatetime);
|
await page.$eval(datetimeSelector, (el, value) => el.value = value, newDatetime);
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ test("Kiosk can start and finish trip", async ({ page }, testInfo) => {
|
|||||||
const currentValue = await page.$eval(datetimeSelector, el => el.value);
|
const currentValue = await page.$eval(datetimeSelector, el => el.value);
|
||||||
const currentDate = new Date(currentValue);
|
const currentDate = new Date(currentValue);
|
||||||
currentDate.setMinutes(currentDate.getMinutes() + 1);
|
currentDate.setMinutes(currentDate.getMinutes() + 1);
|
||||||
currentDate.setHours(currentDate.getHours() + 1);
|
currentDate.setHours(currentDate.getHours() - new Date().getTimezoneOffset()/60);
|
||||||
const newDatetime = currentDate.toISOString().slice(0, 16);
|
const newDatetime = currentDate.toISOString().slice(0, 16);
|
||||||
await page.$eval(datetimeSelector, (el, value) => el.value = value, newDatetime);
|
await page.$eval(datetimeSelector, (el, value) => el.value = value, newDatetime);
|
||||||
|
|
||||||
|
@ -5,7 +5,9 @@ use rocket::FromForm;
|
|||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||||
|
|
||||||
use super::{boat::Boat, log::Log, notification::Notification, rower::Rower, user::User};
|
use super::{
|
||||||
|
boat::Boat, log::Log, notification::Notification, role::Role, rower::Rower, user::User,
|
||||||
|
};
|
||||||
|
|
||||||
#[derive(FromRow, Serialize, Clone, Debug)]
|
#[derive(FromRow, Serialize, Clone, Debug)]
|
||||||
pub struct Logbook {
|
pub struct Logbook {
|
||||||
@ -505,7 +507,7 @@ ORDER BY departure DESC
|
|||||||
|
|
||||||
let dep = NaiveDateTime::parse_from_str(&log.departure, "%Y-%m-%dT%H:%M").unwrap();
|
let dep = NaiveDateTime::parse_from_str(&log.departure, "%Y-%m-%dT%H:%M").unwrap();
|
||||||
let arr = NaiveDateTime::parse_from_str(&log.arrival, "%Y-%m-%dT%H:%M").unwrap();
|
let arr = NaiveDateTime::parse_from_str(&log.arrival, "%Y-%m-%dT%H:%M").unwrap();
|
||||||
if arr.timestamp() <= dep.timestamp() {
|
if arr.timestamp() < dep.timestamp() {
|
||||||
return Err(LogbookUpdateError::ArrivalNotAfterDeparture);
|
return Err(LogbookUpdateError::ArrivalNotAfterDeparture);
|
||||||
}
|
}
|
||||||
let today = Local::now().date_naive();
|
let today = Local::now().date_naive();
|
||||||
@ -560,6 +562,31 @@ ORDER BY departure DESC
|
|||||||
.execute(db.deref_mut())
|
.execute(db.deref_mut())
|
||||||
.await.unwrap(); //TODO: fixme
|
.await.unwrap(); //TODO: fixme
|
||||||
|
|
||||||
|
let duration = arr - dep;
|
||||||
|
if duration.num_days() > 0 {
|
||||||
|
let vorstand = Role::find_by_name_tx(db, "Vorstand").await.unwrap();
|
||||||
|
|
||||||
|
Notification::create_for_role_tx(
|
||||||
|
db,
|
||||||
|
&vorstand,
|
||||||
|
&format!("'{}' hat eine mehrtägige Ausfahrt vom {} bis {} eingetragen ({} km; Ziel: {}; Anmerkungen: {}). Falls das nicht stimmen sollte, bitte nachhaken.",user.name,log.departure, log.arrival, log.distance_in_km, log.destination, log.comments.clone().unwrap_or("".into())),
|
||||||
|
"Mehrtägige Ausfahrt eingetragen",
|
||||||
|
None,
|
||||||
|
).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
if boat.name == "Externes Boot" {
|
||||||
|
let vorstand = Role::find_by_name_tx(db, "Vorstand").await.unwrap();
|
||||||
|
|
||||||
|
Notification::create_for_role_tx(
|
||||||
|
db,
|
||||||
|
&vorstand,
|
||||||
|
&format!("'{}' hat eine Ausfahrt mit *Externem Boot* am {} eingetragen ({} km; Ziel: {}; Anmerkungen: {}). Falls das nicht stimmen sollte, bitte nachhaken.",user.name,log.departure,log.distance_in_km, log.destination, log.comments.unwrap_or("".into())),
|
||||||
|
"Ausfahrt mit externem Boot eingetragen",
|
||||||
|
None,
|
||||||
|
).await;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use chrono::NaiveDateTime;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||||
|
|
||||||
use super::user::User;
|
use super::{role::Role, user::User};
|
||||||
|
|
||||||
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
||||||
pub struct Notification {
|
pub struct Notification {
|
||||||
@ -55,6 +55,20 @@ impl Notification {
|
|||||||
tx.commit().await.unwrap();
|
tx.commit().await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn create_for_role_tx(
|
||||||
|
db: &mut Transaction<'_, Sqlite>,
|
||||||
|
role: &Role,
|
||||||
|
message: &str,
|
||||||
|
category: &str,
|
||||||
|
link: Option<&str>,
|
||||||
|
) {
|
||||||
|
let users = User::all_with_role_tx(db, role).await;
|
||||||
|
|
||||||
|
for user in users {
|
||||||
|
Self::create_with_tx(db, &user, message, category, link).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn for_user(db: &SqlitePool, user: &User) -> Vec<Self> {
|
pub async fn for_user(db: &SqlitePool, user: &User) -> Vec<Self> {
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(
|
||||||
Self,
|
Self,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||||
|
|
||||||
#[derive(FromRow, Serialize, Clone)]
|
#[derive(FromRow, Serialize, Clone)]
|
||||||
pub struct Role {
|
pub struct Role {
|
||||||
@ -45,6 +47,21 @@ WHERE name like ?
|
|||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn find_by_name_tx(db: &mut Transaction<'_, Sqlite>, name: &str) -> Option<Self> {
|
||||||
|
sqlx::query_as!(
|
||||||
|
Self,
|
||||||
|
"
|
||||||
|
SELECT id, name
|
||||||
|
FROM role
|
||||||
|
WHERE name like ?
|
||||||
|
",
|
||||||
|
name
|
||||||
|
)
|
||||||
|
.fetch_one(db.deref_mut())
|
||||||
|
.await
|
||||||
|
.ok()
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn names_from_role(&self, db: &SqlitePool) -> Vec<String> {
|
pub async fn names_from_role(&self, db: &SqlitePool) -> Vec<String> {
|
||||||
let query = format!(
|
let query = format!(
|
||||||
"SELECT u.name
|
"SELECT u.name
|
||||||
|
@ -370,6 +370,13 @@ ORDER BY last_access DESC
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn all_with_role(db: &SqlitePool, role: &Role) -> Vec<Self> {
|
pub async fn all_with_role(db: &SqlitePool, role: &Role) -> Vec<Self> {
|
||||||
|
let mut tx = db.begin().await.unwrap();
|
||||||
|
let ret = Self::all_with_role_tx(&mut tx, role).await;
|
||||||
|
tx.commit().await.unwrap();
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn all_with_role_tx(db: &mut Transaction<'_, Sqlite>, role: &Role) -> Vec<Self> {
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(
|
||||||
Self,
|
Self,
|
||||||
"
|
"
|
||||||
@ -380,7 +387,7 @@ WHERE ur.role_id = ? AND deleted = 0
|
|||||||
ORDER BY name;
|
ORDER BY name;
|
||||||
", role.id
|
", role.id
|
||||||
)
|
)
|
||||||
.fetch_all(db)
|
.fetch_all(db.deref_mut())
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -222,9 +222,11 @@
|
|||||||
<div class="text-sm text-gray-600 dark:text-gray-100">
|
<div class="text-sm text-gray-600 dark:text-gray-100">
|
||||||
Ruderer:
|
Ruderer:
|
||||||
{% for rower in log.rowers -%}
|
{% for rower in log.rowers -%}
|
||||||
{{ rower.name -}}
|
{{ rower.name }}
|
||||||
{% if not loop.last or amount_guests > 0 and log.boat.name != 'Externes Boot' %},{% endif %}
|
{%- if rower.id == log.steering_user.id and rower.id != log.shipmaster_user.id %}
|
||||||
{% endfor %}
|
(Steuerperson){%- endif -%}
|
||||||
|
{%- if not loop.last or amount_guests > 0 and log.boat.name != 'Externes Boot' %},{% endif %}
|
||||||
|
{% endfor -%}
|
||||||
{% if amount_guests > 0 and log.boat.name != 'Externes Boot' %}
|
{% if amount_guests > 0 and log.boat.name != 'Externes Boot' %}
|
||||||
Gäste
|
Gäste
|
||||||
<small class="text-gray-600 dark:text-gray-100">(ohne Account)</small>:
|
<small class="text-gray-600 dark:text-gray-100">(ohne Account)</small>:
|
||||||
|
Loading…
Reference in New Issue
Block a user