verify, that boat is not on water on adding log entry; Fixes #625 #697
@ -1,5 +1,6 @@
|
|||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
|
use chrono::NaiveDateTime;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rocket::serde::{Deserialize, Serialize};
|
use rocket::serde::{Deserialize, Serialize};
|
||||||
use rocket::FromForm;
|
use rocket::FromForm;
|
||||||
@ -391,6 +392,39 @@ ORDER BY amount_seats DESC
|
|||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn on_water_between(
|
||||||
|
&self,
|
||||||
|
db: &mut Transaction<'_, Sqlite>,
|
||||||
|
dep: NaiveDateTime,
|
||||||
|
arr: NaiveDateTime,
|
||||||
|
) -> bool {
|
||||||
|
let dep = dep.format("%Y-%m-%dT%H:%M").to_string();
|
||||||
|
let arr = arr.format("%Y-%m-%dT%H:%M").to_string();
|
||||||
|
|
||||||
|
sqlx::query!(
|
||||||
|
"SELECT COUNT(*) AS overlap_count
|
||||||
|
FROM logbook
|
||||||
|
WHERE boat_id = ?
|
||||||
|
AND (
|
||||||
|
(departure <= ? AND arrival >= ?) -- Existing entry covers the entire new period
|
||||||
|
OR (departure >= ? AND departure < ?) -- Existing entry starts during the new period
|
||||||
|
OR (arrival > ? AND arrival <= ?) -- Existing entry ends during the new period
|
||||||
|
);",
|
||||||
|
self.id,
|
||||||
|
arr,
|
||||||
|
arr,
|
||||||
|
dep,
|
||||||
|
dep,
|
||||||
|
dep,
|
||||||
|
arr
|
||||||
|
)
|
||||||
|
.fetch_one(db.deref_mut())
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
.overlap_count
|
||||||
|
> 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -142,6 +142,7 @@ pub enum LogbookUpdateError {
|
|||||||
TooFast(i64, i64),
|
TooFast(i64, i64),
|
||||||
AlreadyFinalized,
|
AlreadyFinalized,
|
||||||
ExternalSteeringPersonMustSteerOrShipmaster,
|
ExternalSteeringPersonMustSteerOrShipmaster,
|
||||||
|
BoatAlreadyOnWater,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@ -196,6 +197,7 @@ impl From<LogbookUpdateError> for LogbookCreateError {
|
|||||||
LogbookUpdateError::ExternalSteeringPersonMustSteerOrShipmaster => {
|
LogbookUpdateError::ExternalSteeringPersonMustSteerOrShipmaster => {
|
||||||
LogbookCreateError::ExternalSteeringPersonMustSteerOrShipmaster
|
LogbookCreateError::ExternalSteeringPersonMustSteerOrShipmaster
|
||||||
}
|
}
|
||||||
|
LogbookUpdateError::BoatAlreadyOnWater => LogbookCreateError::BoatAlreadyOnWater,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -573,6 +575,12 @@ ORDER BY departure DESC
|
|||||||
return Err(LogbookUpdateError::ArrivalNotAfterDeparture);
|
return Err(LogbookUpdateError::ArrivalNotAfterDeparture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !boat.external {
|
||||||
|
if boat.on_water_between(db, dep, arr).await {
|
||||||
|
return Err(LogbookUpdateError::BoatAlreadyOnWater);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let duration_in_mins = (arr.and_utc().timestamp() - dep.and_utc().timestamp()) / 60;
|
let duration_in_mins = (arr.and_utc().timestamp() - dep.and_utc().timestamp()) / 60;
|
||||||
// Not possible to row < 1 min / 500 m = < 2 min / km
|
// Not possible to row < 1 min / 500 m = < 2 min / km
|
||||||
let possible_distance_km = duration_in_mins / 2;
|
let possible_distance_km = duration_in_mins / 2;
|
||||||
|
@ -347,6 +347,7 @@ async fn home_logbook(
|
|||||||
Err(LogbookUpdateError::TooFast(km, min)) => Flash::error(Redirect::to("/log"), format!("KM zu groß für die eingegebene Dauer ({km} km in {min} Minuten). Bitte überprüfe deine Start- und Endzeit und versuche es erneut.")),
|
Err(LogbookUpdateError::TooFast(km, min)) => Flash::error(Redirect::to("/log"), format!("KM zu groß für die eingegebene Dauer ({km} km in {min} Minuten). Bitte überprüfe deine Start- und Endzeit und versuche es erneut.")),
|
||||||
Err(LogbookUpdateError::AlreadyFinalized) => Flash::error(Redirect::to("/log"), "Logbucheintrag wurde bereits abgeschlossen."),
|
Err(LogbookUpdateError::AlreadyFinalized) => Flash::error(Redirect::to("/log"), "Logbucheintrag wurde bereits abgeschlossen."),
|
||||||
Err(LogbookUpdateError::ExternalSteeringPersonMustSteerOrShipmaster) => Flash::error(Redirect::to("/log"), "Wenn du eine 'Externe Steuerperson' hinzufügst, muss diese steuern oder Schiffsführer sein!"),
|
Err(LogbookUpdateError::ExternalSteeringPersonMustSteerOrShipmaster) => Flash::error(Redirect::to("/log"), "Wenn du eine 'Externe Steuerperson' hinzufügst, muss diese steuern oder Schiffsführer sein!"),
|
||||||
|
Err(LogbookUpdateError::BoatAlreadyOnWater) => Flash::error(Redirect::to("/log"), "Das Boot war in diesem Zeitraum schon am Wasser. Bitte überprüfe das Datum und die Zeit."),
|
||||||
Err(e) => Flash::error(
|
Err(e) => Flash::error(
|
||||||
Redirect::to("/log"),
|
Redirect::to("/log"),
|
||||||
format!("Eintrag {logbook_id} konnte nicht abgesendet werden (Fehler: {e:?})!"),
|
format!("Eintrag {logbook_id} konnte nicht abgesendet werden (Fehler: {e:?})!"),
|
||||||
|
Loading…
Reference in New Issue
Block a user