Merge branch 'main' of gitlab.com:PhilippHofer/rot
This commit is contained in:
commit
388be197e4
@ -24,6 +24,7 @@ CREATE TABLE IF NOT EXISTS "trip_details" (
|
||||
"day" TEXT NOT NULL,
|
||||
"allow_guests" boolean NOT NULL default false,
|
||||
"notes" TEXT,
|
||||
"always_show" boolean NOT NULL default false,
|
||||
"trip_type_id" INTEGER,
|
||||
FOREIGN KEY(trip_type_id) REFERENCES trip_type(id)
|
||||
);
|
||||
@ -34,7 +35,6 @@ CREATE TABLE IF NOT EXISTS "planned_event" (
|
||||
"planned_amount_cox" INTEGER unsigned NOT NULL,
|
||||
"trip_details_id" INTEGER NOT NULL,
|
||||
"created_at" text NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"always_show" boolean NOT NULL default false,
|
||||
FOREIGN KEY(trip_details_id) REFERENCES trip_details(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
|
@ -42,7 +42,7 @@ pub enum LogbookUpdateError {
|
||||
|
||||
pub enum LogbookCreateError {
|
||||
BoatAlreadyOnWater,
|
||||
BoatLocked
|
||||
BoatLocked,
|
||||
}
|
||||
|
||||
impl Logbook {
|
||||
@ -124,7 +124,7 @@ impl Logbook {
|
||||
) -> Result<(), LogbookCreateError> {
|
||||
//Check if boat is not locked
|
||||
//Check if boat is already on water
|
||||
sqlx::query!(
|
||||
let _ = sqlx::query!(
|
||||
"INSERT INTO logbook(boat_id, shipmaster, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype) VALUES (?,?,?,?,?,?,?,?,?)",
|
||||
boat_id, shipmaster, shipmaster_only_steering, departure, arrival, destination, distance_in_km, comments, logtype
|
||||
)
|
||||
|
@ -33,10 +33,14 @@ impl Day {
|
||||
true => PlannedEvent::get_pinned_for_day(db, day).await,
|
||||
false => PlannedEvent::get_for_day(db, day).await,
|
||||
};
|
||||
let trips = match is_pinned {
|
||||
true => Trip::get_pinned_for_day(db, day).await,
|
||||
false => Trip::get_for_day(db, day).await,
|
||||
};
|
||||
Self {
|
||||
day,
|
||||
planned_events,
|
||||
trips: Trip::get_for_day(db, day).await,
|
||||
trips,
|
||||
is_pinned,
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,8 @@ pub struct PlannedEvent {
|
||||
pub day: String,
|
||||
notes: Option<String>,
|
||||
pub allow_guests: bool,
|
||||
always_show: bool,
|
||||
trip_type_id: Option<i64>,
|
||||
always_show: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@ -105,21 +105,6 @@ WHERE day=?",
|
||||
ret
|
||||
}
|
||||
|
||||
pub async fn pinned_days(db: &SqlitePool, amount_days_to_skip: i64) -> Vec<NaiveDate> {
|
||||
let query = format!(
|
||||
"SELECT DISTINCT day
|
||||
FROM planned_event
|
||||
INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id
|
||||
WHERE always_show=true AND day > datetime('now' , '+{} days')
|
||||
ORDER BY day;",
|
||||
amount_days_to_skip
|
||||
);
|
||||
let days: Vec<String> = sqlx::query_scalar(&query).fetch_all(db).await.unwrap();
|
||||
days.into_iter()
|
||||
.map(|a| NaiveDate::parse_from_str(&a, "%Y-%m-%d").unwrap())
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub async fn all(db: &SqlitePool) -> Vec<PlannedEvent> {
|
||||
sqlx::query_as!(
|
||||
PlannedEvent,
|
||||
@ -189,15 +174,13 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM planned_even
|
||||
db: &SqlitePool,
|
||||
name: &str,
|
||||
planned_amount_cox: i32,
|
||||
always_show: bool,
|
||||
trip_details: TripDetails,
|
||||
) {
|
||||
sqlx::query!(
|
||||
"INSERT INTO planned_event(name, planned_amount_cox, trip_details_id, always_show) VALUES(?, ?, ?, ?)",
|
||||
"INSERT INTO planned_event(name, planned_amount_cox, trip_details_id) VALUES(?, ?, ?)",
|
||||
name,
|
||||
planned_amount_cox,
|
||||
trip_details.id,
|
||||
always_show
|
||||
)
|
||||
.execute(db)
|
||||
.await
|
||||
@ -214,9 +197,8 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM planned_even
|
||||
always_show: bool,
|
||||
) {
|
||||
sqlx::query!(
|
||||
"UPDATE planned_event SET planned_amount_cox = ?, always_show=? WHERE id = ?",
|
||||
"UPDATE planned_event SET planned_amount_cox = ? WHERE id = ?",
|
||||
planned_amount_cox,
|
||||
always_show,
|
||||
self.id
|
||||
)
|
||||
.execute(db)
|
||||
@ -224,9 +206,10 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM planned_even
|
||||
.unwrap(); //Okay, as planned_event can only be created with proper DB backing
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE trip_details SET max_people = ?, notes = ? WHERE id = ?",
|
||||
"UPDATE trip_details SET max_people = ?, notes = ?, always_show=? WHERE id = ?",
|
||||
max_people,
|
||||
notes,
|
||||
always_show,
|
||||
self.trip_details_id
|
||||
)
|
||||
.execute(db)
|
||||
@ -284,7 +267,7 @@ mod test {
|
||||
|
||||
let trip_details = TripDetails::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
PlannedEvent::create(&pool, "new-event".into(), 2, false, trip_details).await;
|
||||
PlannedEvent::create(&pool, "new-event".into(), 2, trip_details).await;
|
||||
|
||||
let res =
|
||||
PlannedEvent::get_for_day(&pool, NaiveDate::from_ymd_opt(1970, 1, 1).unwrap()).await;
|
||||
|
@ -21,6 +21,7 @@ pub struct Trip {
|
||||
pub notes: Option<String>,
|
||||
pub allow_guests: bool,
|
||||
trip_type_id: Option<i64>,
|
||||
always_show: bool,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@ -47,7 +48,7 @@ impl Trip {
|
||||
sqlx::query_as!(
|
||||
Self,
|
||||
"
|
||||
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id
|
||||
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id, always_show
|
||||
FROM trip
|
||||
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
|
||||
INNER JOIN user ON trip.cox_id = user.id
|
||||
@ -88,7 +89,7 @@ WHERE trip.id=?
|
||||
let trips = sqlx::query_as!(
|
||||
Trip,
|
||||
"
|
||||
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id
|
||||
SELECT trip.id, cox_id, user.name as cox_name, trip_details_id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id, always_show
|
||||
FROM trip
|
||||
INNER JOIN trip_details ON trip.trip_details_id = trip_details.id
|
||||
INNER JOIN user ON trip.cox_id = user.id
|
||||
@ -139,6 +140,7 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM trip WHERE i
|
||||
max_people: i32,
|
||||
notes: Option<&str>,
|
||||
trip_type: Option<i64>, //TODO: Move to `TripType`
|
||||
always_show: bool,
|
||||
) -> Result<(), TripUpdateError> {
|
||||
if !trip.is_trip_from_user(cox.id) {
|
||||
return Err(TripUpdateError::NotYourTrip);
|
||||
@ -156,10 +158,11 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM trip WHERE i
|
||||
};
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ? WHERE id = ?",
|
||||
"UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ?, always_show = ? WHERE id = ?",
|
||||
max_people,
|
||||
notes,
|
||||
trip_type,
|
||||
always_show,
|
||||
trip_details_id
|
||||
)
|
||||
.execute(db)
|
||||
@ -213,6 +216,15 @@ FROM user_trip WHERE trip_details_id = (SELECT trip_details_id FROM trip WHERE i
|
||||
fn is_trip_from_user(&self, user_id: i64) -> bool {
|
||||
self.cox_id == user_id
|
||||
}
|
||||
|
||||
pub(crate) async fn get_pinned_for_day(
|
||||
db: &sqlx::Pool<sqlx::Sqlite>,
|
||||
day: NaiveDate,
|
||||
) -> Vec<TripWithUserAndType> {
|
||||
let mut trips = Self::get_for_day(db, day).await;
|
||||
trips.retain(|e| e.trip.always_show);
|
||||
trips
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -319,7 +331,7 @@ mod test {
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
assert!(Trip::update_own(&pool, &cox, &trip, 10, None, None)
|
||||
assert!(Trip::update_own(&pool, &cox, &trip, 10, None, None, false)
|
||||
.await
|
||||
.is_ok());
|
||||
|
||||
@ -339,9 +351,11 @@ mod test {
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
assert!(Trip::update_own(&pool, &cox, &trip, 10, None, Some(1))
|
||||
assert!(
|
||||
Trip::update_own(&pool, &cox, &trip, 10, None, Some(1), false)
|
||||
.await
|
||||
.is_ok());
|
||||
.is_ok()
|
||||
);
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
assert_eq!(trip.max_people, 10);
|
||||
@ -360,7 +374,7 @@ mod test {
|
||||
|
||||
let trip = Trip::find_by_id(&pool, 1).await.unwrap();
|
||||
|
||||
assert!(Trip::update_own(&pool, &cox, &trip, 10, None, None)
|
||||
assert!(Trip::update_own(&pool, &cox, &trip, 10, None, None, false)
|
||||
.await
|
||||
.is_err());
|
||||
assert_eq!(trip.max_people, 1);
|
||||
|
@ -1,3 +1,4 @@
|
||||
use chrono::NaiveDate;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{FromRow, SqlitePool};
|
||||
|
||||
@ -10,6 +11,7 @@ pub struct TripDetails {
|
||||
notes: Option<String>,
|
||||
pub allow_guests: bool,
|
||||
trip_type_id: Option<i64>,
|
||||
always_show: bool,
|
||||
}
|
||||
|
||||
impl TripDetails {
|
||||
@ -17,7 +19,7 @@ impl TripDetails {
|
||||
sqlx::query_as!(
|
||||
TripDetails,
|
||||
"
|
||||
SELECT id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id
|
||||
SELECT id, planned_starting_time, max_people, day, notes, allow_guests, trip_type_id, always_show
|
||||
FROM trip_details
|
||||
WHERE id like ?
|
||||
",
|
||||
@ -37,15 +39,17 @@ WHERE id like ?
|
||||
notes: Option<&str>,
|
||||
allow_guests: bool,
|
||||
trip_type_id: Option<i64>,
|
||||
always_show: bool,
|
||||
) -> i64 {
|
||||
let query = sqlx::query!(
|
||||
"INSERT INTO trip_details(planned_starting_time, max_people, day, notes, allow_guests, trip_type_id) VALUES(?, ?, ?, ?, ?, ?)" ,
|
||||
"INSERT INTO trip_details(planned_starting_time, max_people, day, notes, allow_guests, trip_type_id, always_show) VALUES(?, ?, ?, ?, ?, ?, ?)" ,
|
||||
planned_starting_time,
|
||||
max_people,
|
||||
day,
|
||||
notes,
|
||||
allow_guests,
|
||||
trip_type_id
|
||||
trip_type_id,
|
||||
always_show
|
||||
)
|
||||
.execute(db)
|
||||
.await
|
||||
@ -65,6 +69,20 @@ WHERE id like ?
|
||||
|
||||
amount_currently_registered >= self.max_people
|
||||
}
|
||||
|
||||
pub async fn pinned_days(db: &SqlitePool, amount_days_to_skip: i64) -> Vec<NaiveDate> {
|
||||
let query = format!(
|
||||
"SELECT DISTINCT day
|
||||
FROM trip_details
|
||||
WHERE always_show=true AND day > datetime('now' , '+{} days')
|
||||
ORDER BY day;",
|
||||
amount_days_to_skip
|
||||
);
|
||||
let days: Vec<String> = sqlx::query_scalar(&query).fetch_all(db).await.unwrap();
|
||||
days.into_iter()
|
||||
.map(|a| NaiveDate::parse_from_str(&a, "%Y-%m-%d").unwrap())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -100,7 +118,8 @@ mod test {
|
||||
"1970-01-01".into(),
|
||||
None,
|
||||
false,
|
||||
None
|
||||
None,
|
||||
false
|
||||
)
|
||||
.await,
|
||||
3,
|
||||
@ -113,7 +132,8 @@ mod test {
|
||||
"1970-01-01".into(),
|
||||
None,
|
||||
false,
|
||||
None
|
||||
None,
|
||||
false
|
||||
)
|
||||
.await,
|
||||
4,
|
||||
|
@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize};
|
||||
use serde_json::json;
|
||||
use sqlx::{FromRow, SqlitePool};
|
||||
|
||||
use super::{planned_event::PlannedEvent, Day};
|
||||
use super::{tripdetails::TripDetails, Day};
|
||||
|
||||
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
||||
pub struct User {
|
||||
@ -209,7 +209,7 @@ ORDER BY last_access DESC
|
||||
}
|
||||
}
|
||||
|
||||
for date in PlannedEvent::pinned_days(db, self.amount_days_to_show()).await {
|
||||
for date in TripDetails::pinned_days(db, self.amount_days_to_show()).await {
|
||||
if self.is_guest {
|
||||
let day = Day::new_guest(db, date, true).await;
|
||||
if !day.planned_events.is_empty() {
|
||||
|
@ -18,6 +18,8 @@ impl UserTrip {
|
||||
return Err(UserTripError::GuestNotAllowedForThisEvent);
|
||||
}
|
||||
|
||||
//TODO: Check if user sees the event (otherwise she could forge trip_details_id
|
||||
|
||||
//check if cox if own event
|
||||
let is_cox = sqlx::query!(
|
||||
"SELECT count(*) as amount
|
||||
|
@ -36,6 +36,7 @@ async fn create(
|
||||
data.notes,
|
||||
data.allow_guests,
|
||||
data.trip_type,
|
||||
data.always_show,
|
||||
)
|
||||
.await;
|
||||
|
||||
@ -43,14 +44,7 @@ async fn create(
|
||||
//just created
|
||||
//the object
|
||||
|
||||
PlannedEvent::create(
|
||||
db,
|
||||
data.name,
|
||||
data.planned_amount_cox,
|
||||
data.always_show,
|
||||
trip_details,
|
||||
)
|
||||
.await;
|
||||
PlannedEvent::create(db, data.name, data.planned_amount_cox, trip_details).await;
|
||||
|
||||
Flash::success(Redirect::to("/"), "Successfully planned the event")
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ struct AddTripForm<'r> {
|
||||
notes: Option<&'r str>,
|
||||
trip_type: Option<i64>,
|
||||
allow_guests: bool,
|
||||
always_show: bool,
|
||||
}
|
||||
|
||||
#[post("/trip", data = "<data>")]
|
||||
@ -40,6 +41,7 @@ async fn create(
|
||||
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
|
||||
@ -63,6 +65,7 @@ struct EditTripForm<'r> {
|
||||
max_people: i32,
|
||||
notes: Option<&'r str>,
|
||||
trip_type: Option<i64>,
|
||||
always_show: bool,
|
||||
}
|
||||
|
||||
#[post("/trip/<trip_id>", data = "<data>")]
|
||||
@ -73,7 +76,17 @@ async fn update(
|
||||
cox: CoxUser,
|
||||
) -> Flash<Redirect> {
|
||||
if let Some(trip) = Trip::find_by_id(db, trip_id).await {
|
||||
match Trip::update_own(db, &cox, &trip, data.max_people, data.notes, data.trip_type).await {
|
||||
match Trip::update_own(
|
||||
db,
|
||||
&cox,
|
||||
&trip,
|
||||
data.max_people,
|
||||
data.notes,
|
||||
data.trip_type,
|
||||
data.always_show,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => Flash::success(Redirect::to("/"), "Ausfahrt erfolgreich aktualisiert."),
|
||||
Err(TripUpdateError::NotYourTrip) => {
|
||||
Flash::error(Redirect::to("/"), "Nicht deine Ausfahrt!")
|
||||
|
@ -6,6 +6,7 @@
|
||||
{{ macros::input(label='Startzeit (zB "10:00")', name='planned_starting_time', type='time', required=true) }}
|
||||
{{ macros::input(label='Anzahl Ruderer (ohne Steuerperson)', name='max_people', type='number', required=true, min='0') }}
|
||||
{{ macros::checkbox(label='Gäste erlauben', name='allow_guests') }}
|
||||
{{ macros::checkbox(label='Immer anzeigen', name='always_show') }}
|
||||
{{ macros::input(label='Anmerkungen', name='notes', type='input') }}
|
||||
{{ macros::select(data=trip_types, select_name='trip_type', default='Reguläre Ausfahrt') }}
|
||||
|
||||
|
@ -210,6 +210,7 @@
|
||||
<form action="/cox/trip/{{ trip.id }}" method="post" class="grid gap-3">
|
||||
{{ macros::input(label='Anzahl Ruderer', name='max_people', type='number', required=true, value=trip.max_people, min='0') }}
|
||||
{{ macros::input(label='Anmerkungen', name='notes', type='input', value=trip.notes) }}
|
||||
{{ macros::checkbox(label='Immer anzeigen', name='always_show', id=trip.id,checked=trip.always_show) }}
|
||||
{{ macros::select(select_name='trip_type', data=trip_types, default='Reguläre Ausfahrt', selected_id=trip.trip_type_id) }}
|
||||
|
||||
<input value="Speichern" class="btn btn-primary" type="submit" />
|
||||
|
Loading…
Reference in New Issue
Block a user