diff --git a/src/model/boat.rs b/src/model/boat.rs index 22818f4..051d645 100644 --- a/src/model/boat.rs +++ b/src/model/boat.rs @@ -1,9 +1,8 @@ use std::ops::DerefMut; use chrono::NaiveDateTime; -use itertools::Itertools; -use rocket::FromForm; use rocket::serde::{Deserialize, Serialize}; +use rocket::FromForm; use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; use crate::model::boathouse::Boathouse; @@ -102,24 +101,10 @@ impl Boat { } pub async fn shipmaster_allowed(&self, db: &SqlitePool, user: &User) -> bool { - if let Some(owner_id) = self.owner { - return owner_id == user.id; - } - - if user.has_role(db, "Rennrudern").await { - let ottensheim = Location::find_by_name(db, "Ottensheim".into()) - .await - .unwrap(); - if self.location_id == ottensheim.id { - return true; - } - } - - if self.amount_seats == 1 { - return true; - } - - user.allowed_to_steer(db).await + let mut tx = db.begin().await.unwrap(); + let ret = self.shipmaster_allowed_tx(&mut tx, user).await; + tx.commit().await.unwrap(); + ret } pub async fn shipmaster_allowed_tx( @@ -127,10 +112,27 @@ impl Boat { db: &mut Transaction<'_, Sqlite>, user: &User, ) -> bool { + if user.has_role_tx(db, "admin").await { + return true; + } + if let Some(owner_id) = self.owner { return owner_id == user.id; } + if user.has_role_tx(db, "Rennrudern").await { + let ottensheim = Location::find_by_name_tx(db, "Ottensheim".into()) + .await + .unwrap(); + if self.location_id == ottensheim.id { + return true; + } + } + + if self.name == "Externes Boot" { + return true; + } + if self.amount_seats == 1 { return true; } @@ -257,58 +259,16 @@ ORDER BY } pub async fn for_user(db: &SqlitePool, user: &User) -> Vec { - if user.has_role(db, "admin").await { - return Self::all(db).await; - } - let mut boats = if user.allowed_to_steer(db).await { - sqlx::query_as!( - Boat, - " -SELECT id, name, amount_seats, location_id, owner, year_built, boatbuilder, default_shipmaster_only_steering, default_destination, skull, external, deleted, convert_handoperated_possible -FROM boat -WHERE (owner is null or owner = ?) AND deleted = 0 -ORDER BY amount_seats DESC - ", - user.id - ) - .fetch_all(db) - .await - .unwrap() //TODO: fixme - } else { - sqlx::query_as!( - Boat, - " -SELECT id, name, amount_seats, location_id, owner, year_built, boatbuilder, default_shipmaster_only_steering, default_destination, skull, external, deleted, convert_handoperated_possible -FROM boat -WHERE (owner = ? OR (owner is null and amount_seats = 1)) AND deleted = 0 -ORDER BY amount_seats DESC - ", - user.id - ) - .fetch_all(db) - .await - .unwrap() //TODO: fixme - }; + let all_boats = Self::all(db).await; + let mut filtered_boats = Vec::new(); - if user.has_role(db, "Rennrudern").await { - let ottensheim = Location::find_by_name(db, "Ottensheim".into()) - .await - .unwrap(); - let boats_in_ottensheim = sqlx::query_as!( - Boat, - "SELECT id, name, amount_seats, location_id, owner, year_built, boatbuilder, default_shipmaster_only_steering, default_destination, skull, external, deleted, convert_handoperated_possible -FROM boat -WHERE (owner is null and location_id = ?) AND deleted = 0 -ORDER BY amount_seats DESC - ",ottensheim.id) - .fetch_all(db) - .await - .unwrap(); //TODO: fixme - boats.extend(boats_in_ottensheim.into_iter()); + for boat in all_boats { + if boat.boat.shipmaster_allowed(db, user).await { + filtered_boats.push(boat); + } } - let boats = boats.into_iter().unique().collect(); - Self::boats_to_details(db, boats).await + filtered_boats } pub async fn all_at_location(db: &SqlitePool, location: String) -> Vec { diff --git a/src/model/location.rs b/src/model/location.rs index 7d174ec..17a84ac 100644 --- a/src/model/location.rs +++ b/src/model/location.rs @@ -1,5 +1,6 @@ use serde::{Deserialize, Serialize}; -use sqlx::{FromRow, SqlitePool}; +use sqlx::{FromRow, Sqlite, SqlitePool, Transaction}; +use std::ops::DerefMut; #[derive(FromRow, Debug, Serialize, Deserialize)] pub struct Location { @@ -37,6 +38,20 @@ impl Location { .await .ok() } + pub async fn find_by_name_tx(db: &mut Transaction<'_, Sqlite>, name: String) -> Option { + sqlx::query_as!( + Self, + " + SELECT id, name + FROM location + WHERE name=? + ", + name + ) + .fetch_one(db.deref_mut()) + .await + .ok() + } pub async fn all(db: &SqlitePool) -> Vec { sqlx::query_as!(Self, "SELECT id, name FROM location")