diff --git a/src/model/event.rs b/src/model/event.rs index 1f5e1ac..71a2c3c 100644 --- a/src/model/event.rs +++ b/src/model/event.rs @@ -1,8 +1,8 @@ use std::io::Write; -use chrono::NaiveDate; +use chrono::{Duration, NaiveDate, NaiveTime}; use ics::{ - properties::{DtStart, Summary}, + properties::{DtEnd, DtStart, Summary}, ICalendar, }; use serde::Serialize; @@ -191,7 +191,8 @@ INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id", let mut ret = Vec::new(); let events = Self::all(db).await; for event in events { - if event.is_rower_registered(db, user).await { + if event.is_rower_registered(db, user).await || event.is_cox_registered(db, user).await + { ret.push(event); } } @@ -215,6 +216,21 @@ INNER JOIN trip_details ON planned_event.trip_details_id = trip_details.id", is_rower.amount > 0 } + pub async fn is_cox_registered(&self, db: &SqlitePool, user: &User) -> bool { + let is_rower = sqlx::query!( + "SELECT count(*) as amount + FROM trip + WHERE planned_event_id = ? + AND cox_id = ?", + self.id, + user.id + ) + .fetch_one(db) + .await + .unwrap(); //Okay, bc planned_event can only be created with proper DB backing + is_rower.amount > 0 + } + pub async fn find_by_trip_details(db: &SqlitePool, tripdetails_id: i64) -> Option { sqlx::query_as!( Self, @@ -425,12 +441,26 @@ WHERE trip_details.id=? } pub(crate) async fn get_vevent(self, db: &SqlitePool) -> ics::Event { - let mut vevent = ics::Event::new(format!("{}@ruad.at", self.id), "19900101T180000"); + let mut vevent = ics::Event::new(format!("event-{}@ruad.at", self.id), "19900101T180000"); vevent.push(DtStart::new(format!( "{}T{}00", self.day.replace('-', ""), self.planned_starting_time.replace(':', "") ))); + + let original_time = NaiveTime::parse_from_str(&self.planned_starting_time, "%H:%M") + .expect("Failed to parse time"); + let later_time = original_time + Duration::hours(3); + if later_time > original_time { + // Check if no day-overflow + let time_three_hours_later = later_time.format("%H%M").to_string(); + vevent.push(DtEnd::new(format!( + "{}T{}00", + self.day.replace('-', ""), + time_three_hours_later + ))); + } + let tripdetails = self.trip_details(db).await; let mut name = String::new(); if self.is_cancelled() { @@ -513,6 +543,6 @@ mod test { let today = Local::now().date_naive().format("%Y%m%d").to_string(); let actual = Event::get_ics_feed(&pool).await; - assert_eq!(format!("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:ics-rs\r\nBEGIN:VEVENT\r\nUID:1@ruad.at\r\nDTSTAMP:19900101T180000\r\nDTSTART:{today}T100000\r\nSUMMARY:test-planned-event \r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"), actual); + assert_eq!(format!("BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:ics-rs\r\nBEGIN:VEVENT\r\nUID:event-1@ruad.at\r\nDTSTAMP:19900101T180000\r\nDTSTART:{today}T100000\r\nDTEND:{today}T130000\r\nSUMMARY:test-planned-event \r\nEND:VEVENT\r\nEND:VCALENDAR\r\n"), actual); } } diff --git a/src/model/trip.rs b/src/model/trip.rs index c2eeeec..e69dfac 100644 --- a/src/model/trip.rs +++ b/src/model/trip.rs @@ -1,5 +1,5 @@ -use chrono::{Local, NaiveDate}; -use ics::properties::{DtStart, Summary}; +use chrono::{Duration, Local, NaiveDate, NaiveTime}; +use ics::properties::{DtEnd, DtStart, Summary}; use serde::Serialize; use sqlx::SqlitePool; @@ -128,12 +128,26 @@ WHERE trip_details.id=? } pub(crate) async fn get_vevent(self, user: &User) -> ics::Event { - let mut vevent = ics::Event::new(format!("{}@ruad.at", self.id), "19900101T180000"); + let mut vevent = ics::Event::new(format!("trip-{}@ruad.at", self.id), "19900101T180000"); vevent.push(DtStart::new(format!( "{}T{}00", self.day.replace('-', ""), self.planned_starting_time.replace(':', "") ))); + + let original_time = NaiveTime::parse_from_str(&self.planned_starting_time, "%H:%M") + .expect("Failed to parse time"); + let later_time = original_time + Duration::hours(3); + if later_time > original_time { + // Check if no day-overflow + let time_three_hours_later = later_time.format("%H%M").to_string(); + vevent.push(DtEnd::new(format!( + "{}T{}00", + self.day.replace('-', ""), + time_three_hours_later + ))); + } + let mut name = String::new(); if self.is_cancelled() { name.push_str("ABGESAGT");