clean code with clippy
This commit is contained in:
parent
3765541674
commit
a7789af713
@ -1,3 +1,4 @@
|
|||||||
|
use rocket::FromForm;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, SqlitePool};
|
||||||
|
|
||||||
@ -18,36 +19,46 @@ pub struct Boat {
|
|||||||
external: bool,
|
external: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
pub struct BoatToAdd<'r> {
|
||||||
|
pub name: &'r str,
|
||||||
|
pub amount_seats: i64,
|
||||||
|
pub year_built: Option<i64>,
|
||||||
|
pub boatbuilder: Option<&'r str>,
|
||||||
|
pub default_shipmaster_only_steering: bool,
|
||||||
|
pub skull: bool,
|
||||||
|
pub external: bool,
|
||||||
|
pub location_id: Option<i64>,
|
||||||
|
pub owner: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
pub struct BoatToUpdate<'r> {
|
||||||
|
pub id: i32,
|
||||||
|
pub name: &'r str,
|
||||||
|
pub amount_seats: i64,
|
||||||
|
pub year_built: Option<i64>,
|
||||||
|
pub boatbuilder: Option<&'r str>,
|
||||||
|
pub default_shipmaster_only_steering: bool,
|
||||||
|
pub skull: bool,
|
||||||
|
pub external: bool,
|
||||||
|
pub location_id: Option<i64>,
|
||||||
|
pub owner: Option<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Boat {
|
impl Boat {
|
||||||
pub async fn find_by_id(db: &SqlitePool, id: i32) -> Option<Self> {
|
pub async fn find_by_id(db: &SqlitePool, id: i32) -> Option<Self> {
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(
|
||||||
Self,
|
Self,
|
||||||
"
|
"SELECT id, name, amount_seats, location_id, owner, year_built, boatbuilder, default_shipmaster_only_steering, skull, external
|
||||||
SELECT id, name, amount_seats, location_id, owner, year_built, boatbuilder, default_shipmaster_only_steering, skull, external
|
FROM boat
|
||||||
FROM boat
|
WHERE id like ?",
|
||||||
WHERE id like ?
|
|
||||||
",
|
|
||||||
id
|
id
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(db)
|
||||||
.await
|
.await
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// pub async fn find_by_name(db: &SqlitePool, name: &str) -> Option<Self> {
|
|
||||||
// sqlx::query_as!(
|
|
||||||
// User,
|
|
||||||
// "
|
|
||||||
//SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access
|
|
||||||
//FROM user
|
|
||||||
//WHERE name like ?
|
|
||||||
// ",
|
|
||||||
// name
|
|
||||||
// )
|
|
||||||
// .fetch_one(db)
|
|
||||||
// .await
|
|
||||||
// .ok()
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub async fn is_locked(&self, db: &SqlitePool) -> bool {
|
pub async fn is_locked(&self, db: &SqlitePool) -> bool {
|
||||||
sqlx::query!("SELECT * FROM boat_damage WHERE boat_id=? AND lock_boat=true AND user_id_verified is null", self.id).fetch_optional(db).await.unwrap().is_some()
|
sqlx::query!("SELECT * FROM boat_damage WHERE boat_id=? AND lock_boat=true AND user_id_verified is null", self.id).fetch_optional(db).await.unwrap().is_some()
|
||||||
@ -78,58 +89,35 @@ ORDER BY amount_seats DESC
|
|||||||
.unwrap() //TODO: fixme
|
.unwrap() //TODO: fixme
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create(
|
pub async fn create(db: &SqlitePool, boat: BoatToAdd<'_>) -> bool {
|
||||||
db: &SqlitePool,
|
|
||||||
name: &str,
|
|
||||||
amount_seats: i64,
|
|
||||||
year_built: Option<i64>,
|
|
||||||
boatbuilder: Option<&str>,
|
|
||||||
default_shipmaster_only_steering: bool,
|
|
||||||
skull: bool,
|
|
||||||
external: bool,
|
|
||||||
location_id: Option<i64>,
|
|
||||||
owner: Option<i64>,
|
|
||||||
) -> bool {
|
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"INSERT INTO boat(name, amount_seats, year_built, boatbuilder, default_shipmaster_only_steering, skull, external, location_id, owner) VALUES (?,?,?,?,?,?,?,?,?)",
|
"INSERT INTO boat(name, amount_seats, year_built, boatbuilder, default_shipmaster_only_steering, skull, external, location_id, owner) VALUES (?,?,?,?,?,?,?,?,?)",
|
||||||
name,
|
boat.name,
|
||||||
amount_seats,
|
boat.amount_seats,
|
||||||
year_built,
|
boat.year_built,
|
||||||
boatbuilder,
|
boat.boatbuilder,
|
||||||
default_shipmaster_only_steering,
|
boat.default_shipmaster_only_steering,
|
||||||
skull,
|
boat.skull,
|
||||||
external,
|
boat.external,
|
||||||
location_id,
|
boat.location_id,
|
||||||
owner
|
boat.owner
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
.await.is_ok()
|
.await.is_ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update(
|
pub async fn update(&self, db: &SqlitePool, boat: BoatToUpdate<'_>) -> bool {
|
||||||
&self,
|
|
||||||
db: &SqlitePool,
|
|
||||||
name: &str,
|
|
||||||
amount_seats: i64,
|
|
||||||
year_built: Option<i64>,
|
|
||||||
boatbuilder: Option<&str>,
|
|
||||||
default_shipmaster_only_steering: bool,
|
|
||||||
skull: bool,
|
|
||||||
external: bool,
|
|
||||||
location_id: Option<i64>,
|
|
||||||
owner: Option<i64>,
|
|
||||||
) -> bool {
|
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"UPDATE boat SET name=?, amount_seats=?, year_built=?, boatbuilder=?, default_shipmaster_only_steering=?, skull=?, external=?, location_id=?, owner=? WHERE id=?",
|
"UPDATE boat SET name=?, amount_seats=?, year_built=?, boatbuilder=?, default_shipmaster_only_steering=?, skull=?, external=?, location_id=?, owner=? WHERE id=?",
|
||||||
name,
|
boat.name,
|
||||||
amount_seats,
|
boat.amount_seats,
|
||||||
year_built,
|
boat.year_built,
|
||||||
boatbuilder,
|
boat.boatbuilder,
|
||||||
default_shipmaster_only_steering,
|
boat.default_shipmaster_only_steering,
|
||||||
skull,
|
boat.skull,
|
||||||
external,
|
boat.external,
|
||||||
location_id,
|
boat.location_id,
|
||||||
owner,
|
boat.owner,
|
||||||
self.id
|
self.id
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
@ -141,13 +129,16 @@ ORDER BY amount_seats DESC
|
|||||||
sqlx::query!("DELETE FROM boat WHERE id=?", self.id)
|
sqlx::query!("DELETE FROM boat WHERE id=?", self.id)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
.await
|
.await
|
||||||
.unwrap(); //Okay, because we can only create a User of a valid id
|
.unwrap(); //Okay, because we can only create a Boat of a valid id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::{model::boat::Boat, testdb};
|
use crate::{
|
||||||
|
model::boat::{Boat, BoatToAdd},
|
||||||
|
testdb,
|
||||||
|
};
|
||||||
|
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
@ -179,15 +170,17 @@ mod test {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Boat::create(
|
Boat::create(
|
||||||
&pool,
|
&pool,
|
||||||
"new-boat-name".into(),
|
BoatToAdd {
|
||||||
42,
|
name: "new-boat-name".into(),
|
||||||
None,
|
amount_seats: 42,
|
||||||
"Best Boatbuilder".into(),
|
year_built: None,
|
||||||
true,
|
boatbuilder: "Best Boatbuilder".into(),
|
||||||
true,
|
default_shipmaster_only_steering: true,
|
||||||
false,
|
skull: true,
|
||||||
Some(1),
|
external: false,
|
||||||
None
|
location_id: Some(1),
|
||||||
|
owner: None
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
true
|
true
|
||||||
@ -201,15 +194,17 @@ mod test {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Boat::create(
|
Boat::create(
|
||||||
&pool,
|
&pool,
|
||||||
"Haichenbach".into(),
|
BoatToAdd {
|
||||||
42,
|
name: "Haichenbach".into(),
|
||||||
None,
|
amount_seats: 42,
|
||||||
"Best Boatbuilder".into(),
|
year_built: None,
|
||||||
true,
|
boatbuilder: "Best Boatbuilder".into(),
|
||||||
true,
|
default_shipmaster_only_steering: true,
|
||||||
false,
|
skull: true,
|
||||||
Some(1),
|
external: false,
|
||||||
None
|
location_id: Some(1),
|
||||||
|
owner: None
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
false
|
false
|
||||||
|
@ -24,20 +24,14 @@ impl Location {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn all(db: &SqlitePool) -> Vec<Self> {
|
pub async fn all(db: &SqlitePool) -> Vec<Self> {
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(Self, "SELECT id, name FROM location")
|
||||||
Self,
|
.fetch_all(db)
|
||||||
"
|
.await
|
||||||
SELECT id, name
|
.unwrap() //TODO: fixme
|
||||||
FROM location
|
|
||||||
"
|
|
||||||
)
|
|
||||||
.fetch_all(db)
|
|
||||||
.await
|
|
||||||
.unwrap() //TODO: fixme
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create(db: &SqlitePool, name: &str) -> bool {
|
pub async fn create(db: &SqlitePool, name: &str) -> bool {
|
||||||
sqlx::query!("INSERT INTO location(name) VALUES (?)", name,)
|
sqlx::query!("INSERT INTO location(name) VALUES (?)", name)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_ok()
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
|
use rocket::FromForm;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||||
|
|
||||||
use super::{boat::Boat, rower::Rower, user::User};
|
use super::{boat::Boat, rower::Rower, user::User};
|
||||||
|
|
||||||
@ -19,6 +20,29 @@ pub struct Logbook {
|
|||||||
pub logtype: Option<i64>,
|
pub logtype: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
pub struct LogToAdd {
|
||||||
|
pub boat_id: i32,
|
||||||
|
pub shipmaster: i64,
|
||||||
|
pub shipmaster_only_steering: bool,
|
||||||
|
pub departure: String,
|
||||||
|
pub arrival: Option<String>,
|
||||||
|
pub destination: Option<String>,
|
||||||
|
pub distance_in_km: Option<i64>,
|
||||||
|
pub comments: Option<String>,
|
||||||
|
pub logtype: Option<i64>,
|
||||||
|
pub rower: Vec<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm)]
|
||||||
|
pub struct LogToFinalize {
|
||||||
|
pub destination: String,
|
||||||
|
pub distance_in_km: i64,
|
||||||
|
pub comments: Option<String>,
|
||||||
|
pub logtype: Option<i64>,
|
||||||
|
pub rower: Vec<i64>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
pub struct LogbookWithBoatAndRowers {
|
pub struct LogbookWithBoatAndRowers {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
@ -56,21 +80,6 @@ impl Logbook {
|
|||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub async fn find_by_name(db: &SqlitePool, name: &str) -> Option<Self> {
|
|
||||||
// sqlx::query_as!(
|
|
||||||
// User,
|
|
||||||
// "
|
|
||||||
//SELECT id, name, pw, is_cox, is_admin, is_guest, deleted, last_access
|
|
||||||
//FROM user
|
|
||||||
//WHERE name like ?
|
|
||||||
// ",
|
|
||||||
// name
|
|
||||||
// )
|
|
||||||
// .fetch_one(db)
|
|
||||||
// .await
|
|
||||||
// .ok()
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
pub async fn on_water(db: &SqlitePool) -> Vec<LogbookWithBoatAndRowers> {
|
pub async fn on_water(db: &SqlitePool) -> Vec<LogbookWithBoatAndRowers> {
|
||||||
let logs = sqlx::query_as!(
|
let logs = sqlx::query_as!(
|
||||||
Logbook,
|
Logbook,
|
||||||
@ -123,20 +132,8 @@ impl Logbook {
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create(
|
pub async fn create(db: &SqlitePool, log: LogToAdd) -> Result<(), LogbookCreateError> {
|
||||||
db: &SqlitePool,
|
let boat = match Boat::find_by_id(db, log.boat_id).await {
|
||||||
boat_id: i32,
|
|
||||||
shipmaster: i64,
|
|
||||||
shipmaster_only_steering: bool,
|
|
||||||
departure: NaiveDateTime,
|
|
||||||
arrival: Option<NaiveDateTime>,
|
|
||||||
destination: Option<String>,
|
|
||||||
distance_in_km: Option<i64>,
|
|
||||||
comments: Option<String>,
|
|
||||||
logtype: Option<i64>,
|
|
||||||
rower: Vec<i64>,
|
|
||||||
) -> Result<(), LogbookCreateError> {
|
|
||||||
let boat = match Boat::find_by_id(db, boat_id).await {
|
|
||||||
Some(b) => b,
|
Some(b) => b,
|
||||||
None => {
|
None => {
|
||||||
return Err(LogbookCreateError::BoatNotFound);
|
return Err(LogbookCreateError::BoatNotFound);
|
||||||
@ -151,27 +148,44 @@ impl Logbook {
|
|||||||
return Err(LogbookCreateError::BoatAlreadyOnWater);
|
return Err(LogbookCreateError::BoatAlreadyOnWater);
|
||||||
}
|
}
|
||||||
|
|
||||||
if rower.len() > boat.amount_seats as usize - 1 {
|
if log.rower.len() > boat.amount_seats as usize - 1 {
|
||||||
return Err(LogbookCreateError::TooManyRowers(
|
return Err(LogbookCreateError::TooManyRowers(
|
||||||
boat.amount_seats as usize,
|
boat.amount_seats as usize,
|
||||||
rower.len() + 1,
|
log.rower.len() + 1,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut tx = db.begin().await.unwrap();
|
||||||
|
|
||||||
|
let departure = NaiveDateTime::parse_from_str(&log.departure, "%Y-%m-%dT%H:%M").unwrap();
|
||||||
|
let arrival = log
|
||||||
|
.arrival
|
||||||
|
.map(|a| NaiveDateTime::parse_from_str(&a, "%Y-%m-%dT%H:%M").unwrap());
|
||||||
let inserted_row = sqlx::query!(
|
let inserted_row = sqlx::query!(
|
||||||
"INSERT INTO logbook(boat_id, shipmaster, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype) VALUES (?,?,?,?,?,?,?,?,?) RETURNING id",
|
"INSERT INTO logbook(boat_id, shipmaster, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype) VALUES (?,?,?,?,?,?,?,?,?) RETURNING id",
|
||||||
boat_id, shipmaster, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype
|
log.boat_id,
|
||||||
|
log.shipmaster,
|
||||||
|
log.shipmaster_only_steering,
|
||||||
|
departure,
|
||||||
|
arrival,
|
||||||
|
log.destination,
|
||||||
|
log.distance_in_km,
|
||||||
|
log.comments,
|
||||||
|
log.logtype
|
||||||
)
|
)
|
||||||
.fetch_one(db)
|
.fetch_one(&mut tx)
|
||||||
.await.unwrap();
|
.await.unwrap();
|
||||||
|
|
||||||
for rower in &rower {
|
for rower in &log.rower {
|
||||||
Rower::create(db, inserted_row.id, *rower).await;
|
Rower::create(&mut tx, inserted_row.id, *rower).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tx.commit().await.unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_rowers(&self, db: &SqlitePool) {
|
async fn remove_rowers(&self, db: &mut Transaction<'_, Sqlite>) {
|
||||||
sqlx::query!("DELETE FROM rower WHERE logbook_id=?", self.id)
|
sqlx::query!("DELETE FROM rower WHERE logbook_id=?", self.id)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
.await
|
.await
|
||||||
@ -182,11 +196,7 @@ impl Logbook {
|
|||||||
&self,
|
&self,
|
||||||
db: &SqlitePool,
|
db: &SqlitePool,
|
||||||
user: &User,
|
user: &User,
|
||||||
destination: String,
|
log: LogToFinalize,
|
||||||
distance_in_km: i64,
|
|
||||||
comments: Option<String>,
|
|
||||||
logtype: Option<i64>,
|
|
||||||
rower: Vec<i64>,
|
|
||||||
) -> Result<(), LogbookUpdateError> {
|
) -> Result<(), LogbookUpdateError> {
|
||||||
if user.id != self.shipmaster {
|
if user.id != self.shipmaster {
|
||||||
return Err(LogbookUpdateError::NotYourEntry);
|
return Err(LogbookUpdateError::NotYourEntry);
|
||||||
@ -194,35 +204,37 @@ impl Logbook {
|
|||||||
|
|
||||||
let boat = Boat::find_by_id(db, self.boat_id as i32).await.unwrap(); //ok
|
let boat = Boat::find_by_id(db, self.boat_id as i32).await.unwrap(); //ok
|
||||||
|
|
||||||
if rower.len() > boat.amount_seats as usize - 1 {
|
if log.rower.len() > boat.amount_seats as usize - 1 {
|
||||||
return Err(LogbookUpdateError::TooManyRowers(
|
return Err(LogbookUpdateError::TooManyRowers(
|
||||||
boat.amount_seats as usize,
|
boat.amount_seats as usize,
|
||||||
rower.len() + 1,
|
log.rower.len() + 1,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: check current date
|
|
||||||
|
|
||||||
let arrival = format!("{}", chrono::offset::Local::now().format("%Y-%m-%d %H:%M"));
|
let arrival = format!("{}", chrono::offset::Local::now().format("%Y-%m-%d %H:%M"));
|
||||||
|
|
||||||
|
let mut tx = db.begin().await.unwrap();
|
||||||
|
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"UPDATE logbook SET destination=?, distance_in_km=?, comments=?, logtype=?, arrival=? WHERE id=?",
|
"UPDATE logbook SET destination=?, distance_in_km=?, comments=?, logtype=?, arrival=? WHERE id=?",
|
||||||
destination,
|
log.destination,
|
||||||
distance_in_km,
|
log.distance_in_km,
|
||||||
comments,
|
log.comments,
|
||||||
logtype,
|
log.logtype,
|
||||||
arrival,
|
arrival,
|
||||||
self.id
|
self.id
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(&mut tx)
|
||||||
.await.unwrap(); //TODO: fixme
|
.await.unwrap(); //TODO: fixme
|
||||||
|
|
||||||
self.remove_rowers(db).await;
|
self.remove_rowers(&mut tx).await;
|
||||||
|
|
||||||
for rower in &rower {
|
for rower in &log.rower {
|
||||||
Rower::create(db, self.id, *rower).await;
|
Rower::create(&mut tx, self.id, *rower).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tx.commit().await.unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||||
|
|
||||||
use super::{logbook::Logbook, user::User};
|
use super::{logbook::Logbook, user::User};
|
||||||
|
|
||||||
@ -10,21 +10,6 @@ pub struct Rower {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Rower {
|
impl Rower {
|
||||||
//pub async fn find_by_id(db: &SqlitePool, id: i32) -> Option<Self> {
|
|
||||||
// sqlx::query_as!(
|
|
||||||
// Self,
|
|
||||||
// "
|
|
||||||
//SELECT id,boat_id,shipmaster,shipmaster_only_steering,departure,arrival,destination,distance_in_km,comments,logtype
|
|
||||||
//FROM logbook
|
|
||||||
//WHERE id like ?
|
|
||||||
// ",
|
|
||||||
// id
|
|
||||||
// )
|
|
||||||
// .fetch_one(db)
|
|
||||||
// .await
|
|
||||||
// .ok()
|
|
||||||
//}
|
|
||||||
|
|
||||||
pub async fn for_log(db: &SqlitePool, log: &Logbook) -> Vec<User> {
|
pub async fn for_log(db: &SqlitePool, log: &Logbook) -> Vec<User> {
|
||||||
sqlx::query_as!(
|
sqlx::query_as!(
|
||||||
User,
|
User,
|
||||||
@ -40,9 +25,7 @@ impl Rower {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create(db: &SqlitePool, logbook_id: i64, rower_id: i64) {
|
pub async fn create(db: &mut Transaction<'_, Sqlite>, logbook_id: i64, rower_id: i64) {
|
||||||
//Check if boat is not locked
|
|
||||||
//Check if boat is already on water
|
|
||||||
let _ = sqlx::query!(
|
let _ = sqlx::query!(
|
||||||
"INSERT INTO rower(logbook_id, rower_id) VALUES (?,?)",
|
"INSERT INTO rower(logbook_id, rower_id) VALUES (?,?)",
|
||||||
logbook_id,
|
logbook_id,
|
||||||
@ -52,83 +35,4 @@ impl Rower {
|
|||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub async fn delete(&self, db: &SqlitePool) {
|
|
||||||
// sqlx::query!("DELETE FROM boat WHERE id=?", self.id)
|
|
||||||
// .execute(db)
|
|
||||||
// .await
|
|
||||||
// .unwrap(); //Okay, because we can only create a User of a valid id
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
//
|
|
||||||
//#[cfg(test)]
|
|
||||||
//mod test {
|
|
||||||
// use crate::{model::boat::Boat, testdb};
|
|
||||||
//
|
|
||||||
// use sqlx::SqlitePool;
|
|
||||||
//
|
|
||||||
// #[sqlx::test]
|
|
||||||
// fn test_find_correct_id() {
|
|
||||||
// let pool = testdb!();
|
|
||||||
// let boat = Boat::find_by_id(&pool, 1).await.unwrap();
|
|
||||||
// assert_eq!(boat.id, 1);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[sqlx::test]
|
|
||||||
// fn test_find_wrong_id() {
|
|
||||||
// let pool = testdb!();
|
|
||||||
// let boat = Boat::find_by_id(&pool, 1337).await;
|
|
||||||
// assert!(boat.is_none());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[sqlx::test]
|
|
||||||
// fn test_all() {
|
|
||||||
// let pool = testdb!();
|
|
||||||
// let res = Boat::all(&pool).await;
|
|
||||||
// assert!(res.len() > 3);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[sqlx::test]
|
|
||||||
// fn test_succ_create() {
|
|
||||||
// let pool = testdb!();
|
|
||||||
//
|
|
||||||
// assert_eq!(
|
|
||||||
// Boat::create(
|
|
||||||
// &pool,
|
|
||||||
// "new-boat-name".into(),
|
|
||||||
// 42,
|
|
||||||
// None,
|
|
||||||
// "Best Boatbuilder".into(),
|
|
||||||
// true,
|
|
||||||
// true,
|
|
||||||
// false,
|
|
||||||
// Some(1),
|
|
||||||
// None
|
|
||||||
// )
|
|
||||||
// .await,
|
|
||||||
// true
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// #[sqlx::test]
|
|
||||||
// fn test_duplicate_name_create() {
|
|
||||||
// let pool = testdb!();
|
|
||||||
//
|
|
||||||
// assert_eq!(
|
|
||||||
// Boat::create(
|
|
||||||
// &pool,
|
|
||||||
// "Haichenbach".into(),
|
|
||||||
// 42,
|
|
||||||
// None,
|
|
||||||
// "Best Boatbuilder".into(),
|
|
||||||
// true,
|
|
||||||
// true,
|
|
||||||
// false,
|
|
||||||
// Some(1),
|
|
||||||
// None
|
|
||||||
// )
|
|
||||||
// .await,
|
|
||||||
// false
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
@ -1,17 +1,31 @@
|
|||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
|
use rocket::FromForm;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::{FromRow, SqlitePool};
|
use sqlx::{FromRow, SqlitePool};
|
||||||
|
|
||||||
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
||||||
pub struct TripDetails {
|
pub struct TripDetails {
|
||||||
pub id: i64,
|
pub id: i64,
|
||||||
planned_starting_time: String,
|
pub planned_starting_time: String,
|
||||||
max_people: i64,
|
pub max_people: i64,
|
||||||
day: String,
|
pub day: String,
|
||||||
notes: Option<String>,
|
pub notes: Option<String>,
|
||||||
pub allow_guests: bool,
|
pub allow_guests: bool,
|
||||||
trip_type_id: Option<i64>,
|
pub trip_type_id: Option<i64>,
|
||||||
always_show: bool,
|
pub always_show: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(FromForm, Serialize)]
|
||||||
|
pub struct TripDetailsToAdd<'r> {
|
||||||
|
//TODO: properly parse `planned_starting_time`
|
||||||
|
pub planned_starting_time: &'r str,
|
||||||
|
pub max_people: i32,
|
||||||
|
pub day: String,
|
||||||
|
//#[field(validate = range(1..))] TODO: fixme
|
||||||
|
pub notes: Option<&'r str>,
|
||||||
|
pub trip_type: Option<i64>,
|
||||||
|
pub allow_guests: bool,
|
||||||
|
pub always_show: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TripDetails {
|
impl TripDetails {
|
||||||
@ -31,25 +45,16 @@ WHERE id like ?
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new entry in `trip_details` and returns its id.
|
/// Creates a new entry in `trip_details` and returns its id.
|
||||||
pub async fn create(
|
pub async fn create(db: &SqlitePool, tripdetails: TripDetailsToAdd<'_>) -> i64 {
|
||||||
db: &SqlitePool,
|
|
||||||
planned_starting_time: &str,
|
|
||||||
max_people: i32,
|
|
||||||
day: &str,
|
|
||||||
notes: Option<&str>,
|
|
||||||
allow_guests: bool,
|
|
||||||
trip_type_id: Option<i64>,
|
|
||||||
always_show: bool,
|
|
||||||
) -> i64 {
|
|
||||||
let query = sqlx::query!(
|
let query = sqlx::query!(
|
||||||
"INSERT INTO trip_details(planned_starting_time, max_people, day, notes, allow_guests, trip_type_id, always_show) VALUES(?, ?, ?, ?, ?, ?, ?)" ,
|
"INSERT INTO trip_details(planned_starting_time, max_people, day, notes, allow_guests, trip_type_id, always_show) VALUES(?, ?, ?, ?, ?, ?, ?)" ,
|
||||||
planned_starting_time,
|
tripdetails.planned_starting_time,
|
||||||
max_people,
|
tripdetails.max_people,
|
||||||
day,
|
tripdetails.day,
|
||||||
notes,
|
tripdetails.notes,
|
||||||
allow_guests,
|
tripdetails.allow_guests,
|
||||||
trip_type_id,
|
tripdetails.trip_type,
|
||||||
always_show
|
tripdetails.always_show
|
||||||
)
|
)
|
||||||
.execute(db)
|
.execute(db)
|
||||||
.await
|
.await
|
||||||
@ -87,7 +92,7 @@ ORDER BY day;",
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::testdb;
|
use crate::{model::tripdetails::TripDetailsToAdd, testdb};
|
||||||
|
|
||||||
use super::TripDetails;
|
use super::TripDetails;
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
@ -113,13 +118,15 @@ mod test {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
TripDetails::create(
|
TripDetails::create(
|
||||||
&pool,
|
&pool,
|
||||||
"10:00".into(),
|
TripDetailsToAdd {
|
||||||
2,
|
planned_starting_time: "10:00".into(),
|
||||||
"1970-01-01".into(),
|
max_people: 2,
|
||||||
None,
|
day: "1970-01-01".into(),
|
||||||
false,
|
notes: None,
|
||||||
None,
|
allow_guests: false,
|
||||||
false
|
trip_type: None,
|
||||||
|
always_show: false
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
3,
|
3,
|
||||||
@ -127,13 +134,15 @@ mod test {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
TripDetails::create(
|
TripDetails::create(
|
||||||
&pool,
|
&pool,
|
||||||
"10:00".into(),
|
TripDetailsToAdd {
|
||||||
2,
|
planned_starting_time: "10:00".into(),
|
||||||
"1970-01-01".into(),
|
max_people: 2,
|
||||||
None,
|
day: "1970-01-01".into(),
|
||||||
false,
|
notes: None,
|
||||||
None,
|
allow_guests: false,
|
||||||
false
|
trip_type: None,
|
||||||
|
always_show: false
|
||||||
|
}
|
||||||
)
|
)
|
||||||
.await,
|
.await,
|
||||||
4,
|
4,
|
||||||
|
@ -148,15 +148,15 @@ ORDER BY last_access DESC
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login(db: &SqlitePool, name: &str, pw: &str) -> Result<Self, LoginError> {
|
pub async fn login(db: &SqlitePool, name: &str, pw: &str) -> Result<Self, LoginError> {
|
||||||
Log::create(db, format!("User '{name}' is trying to login...").into()).await;
|
Log::create(db, format!("User '{name}' is trying to login...")).await;
|
||||||
let name = name.trim(); // just to make sure...
|
let name = name.trim(); // just to make sure...
|
||||||
let Some(user) = User::find_by_name(db, name).await else {
|
let Some(user) = User::find_by_name(db, name).await else {
|
||||||
Log::create(db, format!("Username ({name}) not found").into()).await;
|
Log::create(db, format!("Username ({name}) not found")).await;
|
||||||
return Err(LoginError::InvalidAuthenticationCombo); // Username not found
|
return Err(LoginError::InvalidAuthenticationCombo); // Username not found
|
||||||
};
|
};
|
||||||
|
|
||||||
if user.deleted {
|
if user.deleted {
|
||||||
Log::create(db, format!("User ({name}) already deleted.").into()).await;
|
Log::create(db, format!("User ({name}) already deleted.")).await;
|
||||||
return Err(LoginError::InvalidAuthenticationCombo); //User existed sometime ago; has
|
return Err(LoginError::InvalidAuthenticationCombo); //User existed sometime ago; has
|
||||||
//been deleted
|
//been deleted
|
||||||
}
|
}
|
||||||
@ -165,10 +165,10 @@ ORDER BY last_access DESC
|
|||||||
Some(user_pw) => {
|
Some(user_pw) => {
|
||||||
let password_hash = &Self::get_hashed_pw(pw);
|
let password_hash = &Self::get_hashed_pw(pw);
|
||||||
if password_hash == user_pw {
|
if password_hash == user_pw {
|
||||||
Log::create(db, format!("User {name} successfully logged in").into()).await;
|
Log::create(db, format!("User {name} successfully logged in")).await;
|
||||||
return Ok(user);
|
return Ok(user);
|
||||||
}
|
}
|
||||||
Log::create(db, format!("User {name} supplied the wrong PW").into()).await;
|
Log::create(db, format!("User {name} supplied the wrong PW")).await;
|
||||||
Err(LoginError::InvalidAuthenticationCombo)
|
Err(LoginError::InvalidAuthenticationCombo)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::model::{
|
use crate::model::{
|
||||||
boat::Boat,
|
boat::{Boat, BoatToAdd, BoatToUpdate},
|
||||||
location::Location,
|
location::Location,
|
||||||
user::{AdminUser, User},
|
user::{AdminUser, User},
|
||||||
};
|
};
|
||||||
@ -8,7 +8,7 @@ use rocket::{
|
|||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
routes, FromForm, Route, State,
|
routes, Route, State,
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::{tera::Context, Template};
|
use rocket_dyn_templates::{tera::Context, Template};
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
@ -50,96 +50,39 @@ async fn delete(db: &State<SqlitePool>, _admin: AdminUser, boat: i32) -> Flash<R
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromForm)]
|
|
||||||
struct BoatEditForm<'r> {
|
|
||||||
id: i32,
|
|
||||||
name: &'r str,
|
|
||||||
amount_seats: i64,
|
|
||||||
year_built: Option<i64>,
|
|
||||||
boatbuilder: Option<&'r str>,
|
|
||||||
default_shipmaster_only_steering: bool,
|
|
||||||
skull: bool,
|
|
||||||
external: bool,
|
|
||||||
location_id: Option<i64>,
|
|
||||||
owner: Option<i64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/boat", data = "<data>")]
|
#[post("/boat", data = "<data>")]
|
||||||
async fn update(
|
async fn update(
|
||||||
db: &State<SqlitePool>,
|
db: &State<SqlitePool>,
|
||||||
data: Form<BoatEditForm<'_>>,
|
data: Form<BoatToUpdate<'_>>,
|
||||||
_admin: AdminUser,
|
_admin: AdminUser,
|
||||||
) -> Flash<Redirect> {
|
) -> Flash<Redirect> {
|
||||||
let boat = Boat::find_by_id(db, data.id).await;
|
let boat = Boat::find_by_id(db, data.id).await;
|
||||||
let Some(boat) = boat else {
|
let Some(boat) = boat else {
|
||||||
return Flash::error(
|
return Flash::error(
|
||||||
Redirect::to("/admin/boat"),
|
Redirect::to("/admin/boat"),
|
||||||
format!("Boat with ID {} does not exist!", data.id),
|
"Boat does not exist!",
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
if !boat
|
if !boat.update(db, data.into_inner()).await {
|
||||||
.update(
|
return Flash::error(Redirect::to("/admin/boat"), "Boat could not be updated!");
|
||||||
db,
|
|
||||||
data.name,
|
|
||||||
data.amount_seats,
|
|
||||||
data.year_built,
|
|
||||||
data.boatbuilder,
|
|
||||||
data.default_shipmaster_only_steering,
|
|
||||||
data.skull,
|
|
||||||
data.external,
|
|
||||||
data.location_id,
|
|
||||||
data.owner,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
return Flash::error(
|
|
||||||
Redirect::to("/admin/boat"),
|
|
||||||
format!("Boat with ID {} could not be updated!", data.id),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Flash::success(Redirect::to("/admin/boat"), "Successfully updated boat")
|
Flash::success(Redirect::to("/admin/boat"), "Successfully updated boat")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromForm)]
|
|
||||||
struct BoatAddForm<'r> {
|
|
||||||
name: &'r str,
|
|
||||||
amount_seats: i64,
|
|
||||||
year_built: Option<i64>,
|
|
||||||
boatbuilder: Option<&'r str>,
|
|
||||||
default_shipmaster_only_steering: bool,
|
|
||||||
skull: bool,
|
|
||||||
external: bool,
|
|
||||||
location_id: Option<i64>,
|
|
||||||
owner: Option<i64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/boat/new", data = "<data>")]
|
#[post("/boat/new", data = "<data>")]
|
||||||
async fn create(
|
async fn create(
|
||||||
db: &State<SqlitePool>,
|
db: &State<SqlitePool>,
|
||||||
data: Form<BoatAddForm<'_>>,
|
data: Form<BoatToAdd<'_>>,
|
||||||
_admin: AdminUser,
|
_admin: AdminUser,
|
||||||
) -> Flash<Redirect> {
|
) -> Flash<Redirect> {
|
||||||
if Boat::create(
|
if Boat::create(db, data.into_inner()).await {
|
||||||
db,
|
|
||||||
data.name,
|
|
||||||
data.amount_seats,
|
|
||||||
data.year_built,
|
|
||||||
data.boatbuilder,
|
|
||||||
data.default_shipmaster_only_steering,
|
|
||||||
data.skull,
|
|
||||||
data.external,
|
|
||||||
data.location_id,
|
|
||||||
data.owner,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Flash::success(Redirect::to("/admin/boat"), "Successfully created boat")
|
Flash::success(Redirect::to("/admin/boat"), "Successfully created boat")
|
||||||
} else {
|
} else {
|
||||||
Flash::error(
|
Flash::error(
|
||||||
Redirect::to("/admin/boat"),
|
Redirect::to("/admin/boat"),
|
||||||
format!("Error while creating boat {} in DB", data.name),
|
"Error while creating the boat in DB",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,22 @@ use rocket::{
|
|||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
routes, FromForm, Route, State,
|
routes, FromForm, Route, State,
|
||||||
};
|
};
|
||||||
|
use serde::Serialize;
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
use crate::model::{planned_event::PlannedEvent, tripdetails::TripDetails, user::AdminUser};
|
use crate::model::{
|
||||||
|
planned_event::PlannedEvent,
|
||||||
|
tripdetails::{TripDetails, TripDetailsToAdd},
|
||||||
|
user::AdminUser,
|
||||||
|
};
|
||||||
|
|
||||||
//TODO: add constraints (e.g. planned_amount_cox > 0)
|
//TODO: add constraints (e.g. planned_amount_cox > 0)
|
||||||
#[derive(FromForm)]
|
#[derive(FromForm, Serialize)]
|
||||||
struct AddPlannedEventForm<'r> {
|
struct AddPlannedEventForm<'r> {
|
||||||
day: &'r str,
|
|
||||||
name: &'r str,
|
name: &'r str,
|
||||||
planned_amount_cox: i32,
|
planned_amount_cox: i32,
|
||||||
allow_guests: bool,
|
#[serde(flatten)]
|
||||||
planned_starting_time: &'r str,
|
tripdetails: TripDetailsToAdd<'r>,
|
||||||
max_people: i32,
|
|
||||||
always_show: bool,
|
|
||||||
notes: Option<&'r str>,
|
|
||||||
trip_type: Option<i64>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/planned-event", data = "<data>")]
|
#[post("/planned-event", data = "<data>")]
|
||||||
@ -28,17 +28,9 @@ async fn create(
|
|||||||
data: Form<AddPlannedEventForm<'_>>,
|
data: Form<AddPlannedEventForm<'_>>,
|
||||||
_admin: AdminUser,
|
_admin: AdminUser,
|
||||||
) -> Flash<Redirect> {
|
) -> Flash<Redirect> {
|
||||||
let trip_details_id = TripDetails::create(
|
let data = data.into_inner();
|
||||||
db,
|
|
||||||
data.planned_starting_time,
|
let trip_details_id = TripDetails::create(db, data.tripdetails).await;
|
||||||
data.max_people,
|
|
||||||
data.day,
|
|
||||||
data.notes,
|
|
||||||
data.allow_guests,
|
|
||||||
data.trip_type,
|
|
||||||
data.always_show,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc. we
|
let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc. we
|
||||||
//just created
|
//just created
|
||||||
|
@ -10,52 +10,29 @@ use crate::model::{
|
|||||||
log::Log,
|
log::Log,
|
||||||
planned_event::PlannedEvent,
|
planned_event::PlannedEvent,
|
||||||
trip::{CoxHelpError, Trip, TripDeleteError, TripUpdateError},
|
trip::{CoxHelpError, Trip, TripDeleteError, TripUpdateError},
|
||||||
tripdetails::TripDetails,
|
tripdetails::{TripDetails, TripDetailsToAdd},
|
||||||
user::CoxUser,
|
user::CoxUser,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(FromForm)]
|
|
||||||
struct AddTripForm<'r> {
|
|
||||||
day: String,
|
|
||||||
//TODO: properly parse `planned_starting_time`
|
|
||||||
planned_starting_time: &'r str,
|
|
||||||
#[field(validate = range(1..))]
|
|
||||||
max_people: i32,
|
|
||||||
notes: Option<&'r str>,
|
|
||||||
trip_type: Option<i64>,
|
|
||||||
allow_guests: bool,
|
|
||||||
always_show: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/trip", data = "<data>")]
|
#[post("/trip", data = "<data>")]
|
||||||
async fn create(
|
async fn create(
|
||||||
db: &State<SqlitePool>,
|
db: &State<SqlitePool>,
|
||||||
data: Form<AddTripForm<'_>>,
|
data: Form<TripDetailsToAdd<'_>>,
|
||||||
cox: CoxUser,
|
cox: CoxUser,
|
||||||
) -> Flash<Redirect> {
|
) -> Flash<Redirect> {
|
||||||
let trip_details_id = TripDetails::create(
|
let trip_details_id = TripDetails::create(db, data.into_inner()).await;
|
||||||
db,
|
|
||||||
data.planned_starting_time,
|
|
||||||
data.max_people,
|
|
||||||
&data.day,
|
|
||||||
data.notes,
|
|
||||||
data.allow_guests,
|
|
||||||
data.trip_type,
|
|
||||||
data.always_show,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc just
|
let trip_details = TripDetails::find_by_id(db, trip_details_id).await.unwrap(); //Okay, bc just
|
||||||
//created
|
//created
|
||||||
Trip::new_own(db, &cox, trip_details).await;
|
Trip::new_own(db, &cox, trip_details).await; //TODO: fix
|
||||||
|
|
||||||
Log::create(
|
//Log::create(
|
||||||
db,
|
// db,
|
||||||
format!(
|
// format!(
|
||||||
"Cox {} created trip on {} @ {} for {} rower",
|
// "Cox {} created trip on {} @ {} for {} rower",
|
||||||
cox.name, data.day, data.planned_starting_time, data.max_people,
|
// cox.name, trip_details.day, trip_details.planned_starting_time, trip_details.max_people,
|
||||||
),
|
// ),
|
||||||
)
|
//)
|
||||||
.await;
|
//.await;
|
||||||
|
|
||||||
Flash::success(Redirect::to("/"), "Ausfahrt erfolgreich erstellt.")
|
Flash::success(Redirect::to("/"), "Ausfahrt erfolgreich erstellt.")
|
||||||
}
|
}
|
||||||
@ -402,7 +379,7 @@ mod test {
|
|||||||
login.dispatch().await;
|
login.dispatch().await;
|
||||||
|
|
||||||
let req = client.get("/join/1");
|
let req = client.get("/join/1");
|
||||||
let response = req.dispatch().await;
|
let _ = req.dispatch().await;
|
||||||
|
|
||||||
let req = client.get("/cox/join/1");
|
let req = client.get("/cox/join/1");
|
||||||
let response = req.dispatch().await;
|
let response = req.dispatch().await;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
use chrono::NaiveDateTime;
|
|
||||||
use rocket::{
|
use rocket::{
|
||||||
form::Form,
|
form::Form,
|
||||||
get, post,
|
get, post,
|
||||||
request::FlashMessage,
|
request::FlashMessage,
|
||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
routes, FromForm, Route, State,
|
routes, Route, State,
|
||||||
};
|
};
|
||||||
use rocket_dyn_templates::Template;
|
use rocket_dyn_templates::Template;
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
@ -12,7 +11,7 @@ use tera::Context;
|
|||||||
|
|
||||||
use crate::model::{
|
use crate::model::{
|
||||||
boat::Boat,
|
boat::Boat,
|
||||||
logbook::{Logbook, LogbookCreateError},
|
logbook::{LogToAdd, LogToFinalize, Logbook, LogbookCreateError},
|
||||||
logtype::LogType,
|
logtype::LogType,
|
||||||
user::{AdminUser, User},
|
user::{AdminUser, User},
|
||||||
};
|
};
|
||||||
@ -47,40 +46,15 @@ async fn index(
|
|||||||
Template::render("log", context.into_json())
|
Template::render("log", context.into_json())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromForm)]
|
|
||||||
struct LogAddForm {
|
|
||||||
boat_id: i32,
|
|
||||||
shipmaster: i64,
|
|
||||||
shipmaster_only_steering: bool,
|
|
||||||
departure: String,
|
|
||||||
arrival: Option<String>,
|
|
||||||
destination: Option<String>,
|
|
||||||
distance_in_km: Option<i64>,
|
|
||||||
comments: Option<String>,
|
|
||||||
logtype: Option<i64>,
|
|
||||||
rower: Vec<i64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/", data = "<data>")]
|
#[post("/", data = "<data>")]
|
||||||
async fn create(
|
async fn create(
|
||||||
db: &State<SqlitePool>,
|
db: &State<SqlitePool>,
|
||||||
data: Form<LogAddForm>,
|
data: Form<LogToAdd>,
|
||||||
_adminuser: AdminUser,
|
_adminuser: AdminUser,
|
||||||
) -> Flash<Redirect> {
|
) -> Flash<Redirect> {
|
||||||
match Logbook::create(
|
match Logbook::create(
|
||||||
db,
|
db,
|
||||||
data.boat_id,
|
data.into_inner()
|
||||||
data.shipmaster,
|
|
||||||
data.shipmaster_only_steering,
|
|
||||||
NaiveDateTime::parse_from_str(&data.departure, "%Y-%m-%dT%H:%M").unwrap(), //TODO: fix
|
|
||||||
data.arrival
|
|
||||||
.clone()
|
|
||||||
.map(|a| NaiveDateTime::parse_from_str(&a, "%Y-%m-%dT%H:%M").unwrap()), //TODO: fix
|
|
||||||
data.destination.clone(), //TODO: fix
|
|
||||||
data.distance_in_km,
|
|
||||||
data.comments.clone(), //TODO: fix
|
|
||||||
data.logtype,
|
|
||||||
data.rower.clone(), //TODO: fix
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
@ -92,19 +66,10 @@ async fn create(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(FromForm)]
|
|
||||||
struct LogHomeForm {
|
|
||||||
destination: String,
|
|
||||||
distance_in_km: i64,
|
|
||||||
comments: Option<String>,
|
|
||||||
logtype: Option<i64>,
|
|
||||||
rower: Vec<i64>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[post("/<logbook_id>", data = "<data>")]
|
#[post("/<logbook_id>", data = "<data>")]
|
||||||
async fn home(
|
async fn home(
|
||||||
db: &State<SqlitePool>,
|
db: &State<SqlitePool>,
|
||||||
data: Form<LogHomeForm>,
|
data: Form<LogToFinalize>,
|
||||||
logbook_id: i32,
|
logbook_id: i32,
|
||||||
_adminuser: AdminUser,
|
_adminuser: AdminUser,
|
||||||
) -> Flash<Redirect> {
|
) -> Flash<Redirect> {
|
||||||
@ -116,18 +81,7 @@ async fn home(
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
match logbook
|
match logbook.home(db, &_adminuser.user, data.into_inner()).await {
|
||||||
.home(
|
|
||||||
db,
|
|
||||||
&_adminuser.user,
|
|
||||||
data.destination.clone(), //TODO: fixme
|
|
||||||
data.distance_in_km,
|
|
||||||
data.comments.clone(), //TODO: fixme
|
|
||||||
data.logtype,
|
|
||||||
data.rower.clone(), //TODO: fixme
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(_) => Flash::success(Redirect::to("/log"), "Successfully updated log"),
|
Ok(_) => Flash::success(Redirect::to("/log"), "Successfully updated log"),
|
||||||
Err(_) => Flash::error(
|
Err(_) => Flash::error(
|
||||||
Redirect::to("/log"),
|
Redirect::to("/log"),
|
||||||
|
Loading…
Reference in New Issue
Block a user