Merge branch 'main' of gitlab.com:PhilippHofer/rot

This commit is contained in:
Philipp 2023-07-23 19:58:47 +02:00
commit 388be197e4
12 changed files with 84 additions and 52 deletions

View File

@ -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
);

View File

@ -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
)

View File

@ -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,
}
}

View File

@ -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;

View File

@ -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))
.await
.is_ok());
assert!(
Trip::update_own(&pool, &cox, &trip, 10, None, Some(1), false)
.await
.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);

View File

@ -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,

View File

@ -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() {

View File

@ -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

View File

@ -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")
}

View File

@ -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!")

View File

@ -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') }}

View File

@ -128,7 +128,7 @@
<input type="hidden" name="id" value="{{ planned_event.id }}" />
{{ macros::input(label='Anzahl Ruderer', name='max_people', type='number', required=true, value=planned_event.max_people, min='0') }}
{{ macros::input(label='Anzahl Steuerleute', name='planned_amount_cox', type='number', value=planned_event.planned_amount_cox, required=true, min='0') }}
{{ macros::checkbox(label='Immer anzeigen', name='always_show', id=planned_event.id,checked=planned_event.always_show) }}
{{ macros::checkbox(label='Immer anzeigen', name='always_show', id=planned_event.id,checked=planned_event.always_show) }}
{{ macros::input(label='Anmerkungen', name='notes', type='input', value=planned_event.notes) }}
<input value="Speichern" class="btn btn-primary" type="submit" />
@ -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" />