diff --git a/Cargo.lock b/Cargo.lock index 78d0e39..8272604 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,18 +174,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] name = "async-trait" -version = "0.1.78" +version = "0.1.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" +checksum = "a507401cad91ec6a857ed5513a2073c82a9b9048762b885bb98655b306964681" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -214,15 +214,15 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -239,6 +239,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "base64ct" version = "1.6.0" @@ -314,9 +320,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" @@ -332,9 +338,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.35" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a" +checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" dependencies = [ "android-tzdata", "iana-time-zone", @@ -402,12 +408,12 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "cookie" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ "aes-gcm", - "base64", + "base64 0.22.0", "hkdf", "percent-encoding", "rand", @@ -597,7 +603,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -629,11 +635,11 @@ dependencies = [ [[package]] name = "email-encoding" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfb21b9878cf7a348dcb8559109aabc0ec40d69924bd706fa5149846c4fef75" +checksum = "a87260449b06739ee78d6281c68d2a0ff3e3af64a78df63d3a1aeb3c06997c8a" dependencies = [ - "base64", + "base64 0.22.0", "memchr", ] @@ -710,9 +716,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "figment" @@ -863,7 +869,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -962,7 +968,7 @@ dependencies = [ "bstr", "log", "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -1203,9 +1209,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.5" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown", @@ -1269,9 +1275,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" @@ -1313,11 +1319,11 @@ dependencies = [ [[package]] name = "lettre" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357ff5edb6d8326473a64c82cf41ddf78ab116f89668c50c4fac1b321e5e80f4" +checksum = "8305b122b8ccc64e437b0de101851f9f00aade5886246e85f341c1d9a15a91b7" dependencies = [ - "base64", + "base64 0.22.0", "chumsky", "email-encoding", "email_address", @@ -1653,7 +1659,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -1759,7 +1765,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -1808,7 +1814,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -1940,7 +1946,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", "version_check", "yansi", ] @@ -2031,19 +2037,19 @@ checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", "regex-automata 0.4.6", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -2063,7 +2069,7 @@ checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -2074,9 +2080,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "ring" @@ -2142,7 +2148,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.53", + "syn 2.0.55", "unicode-xid", "version_check", ] @@ -2265,7 +2271,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64", + "base64 0.21.7", ] [[package]] @@ -2370,14 +2376,14 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] name = "serde_json" -version = "1.0.114" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", @@ -2623,7 +2629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", - "base64", + "base64 0.21.7", "bitflags 2.5.0", "byteorder", "bytes", @@ -2667,7 +2673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", - "base64", + "base64 0.21.7", "bitflags 2.5.0", "byteorder", "chrono", @@ -2786,9 +2792,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.53" +version = "2.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" dependencies = [ "proc-macro2", "quote", @@ -2846,7 +2852,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -2931,7 +2937,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -3019,7 +3025,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] @@ -3296,7 +3302,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", "wasm-bindgen-shared", ] @@ -3318,7 +3324,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3561,7 +3567,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.53", + "syn 2.0.55", ] [[package]] diff --git a/frontend/tests/cox.spec.ts b/frontend/tests/cox.spec.ts index 339d98a..c19ae45 100644 --- a/frontend/tests/cox.spec.ts +++ b/frontend/tests/cox.spec.ts @@ -7,7 +7,7 @@ test("cox can create and delete trip", async ({ page }) => { await page.getByPlaceholder("Name").press("Tab"); await page.getByPlaceholder("Passwort").fill("cox"); await page.getByPlaceholder("Passwort").press("Enter"); - await page.locator('a').filter({ hasText: /^Geplante Ausfahrten$/ }).click(); + await page.locator('li').filter({ hasText: 'Geplante Ausfahrten' }).getByRole('link').click(); await page.locator(".relative").first().click(); await page.locator("#sidebar #planned_starting_time").click(); await page.locator("#sidebar #planned_starting_time").fill("18:00"); @@ -38,7 +38,7 @@ test.describe("cox can edit trips", () => { await page.getByPlaceholder("Name").press("Tab"); await page.getByPlaceholder("Passwort").fill("cox"); await page.getByPlaceholder("Passwort").press("Enter"); - await page.locator('a').filter({ hasText: /^Geplante Ausfahrten$/ }).click(); + await page.locator('li').filter({ hasText: 'Geplante Ausfahrten' }).getByRole('link').click(); await page.locator(".relative").first().click(); await page.locator("#sidebar #planned_starting_time").click(); await page.locator("#sidebar #planned_starting_time").fill("18:00"); diff --git a/src/model/boatdamage.rs b/src/model/boatdamage.rs index 37207f2..1f9802e 100644 --- a/src/model/boatdamage.rs +++ b/src/model/boatdamage.rs @@ -5,6 +5,8 @@ use rocket::FromForm; use sqlx::{FromRow, SqlitePool}; use super::log::Log; +use super::notification::Notification; +use super::role::Role; #[derive(FromRow, Debug, Serialize, Deserialize)] pub struct BoatDamage { @@ -124,35 +126,125 @@ ORDER BY created_at DESC .execute(db) .await .map_err(|e| e.to_string())?; + + let technicals = + User::all_with_role(db, &Role::find_by_name(db, "tech").await.unwrap()).await; + for technical in technicals { + if technical.id as i32 != boatdamage.user_id_created { + Notification::create( + db, + &technical, + &format!( + "{} hat einen neuen Bootschaden für Boot '{}' angelegt: {}", + User::find_by_id(db, boatdamage.user_id_created) + .await + .unwrap() + .name, + Boat::find_by_id(db, boatdamage.boat_id as i32) + .await + .unwrap() + .name, + boatdamage.desc + ), + "Neuer Bootsschaden angelegt", + None, + ) + .await; + } + } + + Notification::create( + db, + &User::find_by_id(db, boatdamage.user_id_created) + .await + .unwrap(), + &format!( + "Du hat einen neuen Bootschaden für Boot '{}' angelegt: {}", + Boat::find_by_id(db, boatdamage.boat_id as i32) + .await + .unwrap() + .name, + boatdamage.desc + ), + "Neuer Bootsschaden angelegt", + None, + ) + .await; + Ok(()) } - pub async fn fixed(&self, db: &SqlitePool, boat: BoatDamageFixed<'_>) -> Result<(), String> { - Log::create(db, format!("Fixed boat damage: {boat:?}")).await; + pub async fn fixed( + &self, + db: &SqlitePool, + boat_damage: BoatDamageFixed<'_>, + ) -> Result<(), String> { + Log::create(db, format!("Fixed boat damage: {boat_damage:?}")).await; + + let boat = Boat::find_by_id(db, self.boat_id as i32).await.unwrap(); sqlx::query!( "UPDATE boat_damage SET desc=?, user_id_fixed=?, fixed_at=CURRENT_TIMESTAMP WHERE id=?", - boat.desc, - boat.user_id_fixed, + boat_damage.desc, + boat_damage.user_id_fixed, self.id ) .execute(db) .await .map_err(|e| e.to_string())?; - let user = User::find_by_id(db, boat.user_id_fixed).await.unwrap(); + let user = User::find_by_id(db, boat_damage.user_id_fixed) + .await + .unwrap(); if user.has_role(db, "tech").await { return self .verified( db, BoatDamageVerified { - desc: boat.desc, + desc: boat_damage.desc, user_id_verified: user.id as i32, }, ) .await; } + let technicals = + User::all_with_role(db, &Role::find_by_name(db, "tech").await.unwrap()).await; + for technical in technicals { + if technical.id as i32 != boat_damage.user_id_fixed { + Notification::create( + db, + &technical, + &format!( + "{} hat den Bootschaden '{}' beim Boot '{}' repariert. Könntest du das bei Gelegenheit verifizieren?", + User::find_by_id(db, boat_damage.user_id_fixed) + .await + .unwrap() + .name, + boat_damage.desc, + boat.name, + ), + "Bootsschaden repariert", + None, + ) + .await; + } + } + + Notification::create( + db, + &User::find_by_id(db, boat_damage.user_id_fixed) + .await + .unwrap(), + &format!( + "Du hat den Bootschaden '{}' beim Boot '{}' repariert. Danke für deine Hilfe!", + boat_damage.desc, boat.name, + ), + "Bootsschaden repariert", + None, + ) + .await; + Ok(()) } diff --git a/src/model/family.rs b/src/model/family.rs index 6bff530..f648cfd 100644 --- a/src/model/family.rs +++ b/src/model/family.rs @@ -75,7 +75,7 @@ GROUP BY family.id;" } pub async fn members(&self, db: &SqlitePool) -> Vec { - sqlx::query_as!(User, "SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf FROM user WHERE family_id = ?", self.id) + sqlx::query_as!(User, "SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE family_id = ?", self.id) .fetch_all(db) .await .unwrap() diff --git a/src/model/logbook.rs b/src/model/logbook.rs index 9dbbf64..36fcd9c 100644 --- a/src/model/logbook.rs +++ b/src/model/logbook.rs @@ -531,7 +531,7 @@ ORDER BY departure DESC db, &user, &format!( - "Ausfahrt am {}.{}.{} nach {} ({} km)", + "Ausfahrt am {}.{}.{}; Ziel: {} ({} km)", dep.day(), dep.month(), dep.year(), diff --git a/src/model/notification.rs b/src/model/notification.rs index 8cfc6a1..3268e6d 100644 --- a/src/model/notification.rs +++ b/src/model/notification.rs @@ -58,7 +58,7 @@ impl Notification { pub async fn for_user(db: &SqlitePool, user: &User) -> Vec { sqlx::query_as!( Self, - "SELECT * FROM notification WHERE user_id = ?", + "SELECT * FROM notification WHERE user_id = ? ORDER BY created_at DESC", user.id ) .fetch_all(db) diff --git a/src/model/rower.rs b/src/model/rower.rs index a953738..7099cff 100644 --- a/src/model/rower.rs +++ b/src/model/rower.rs @@ -16,7 +16,7 @@ impl Rower { sqlx::query_as!( User, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE id in (SELECT rower_id FROM rower WHERE logbook_id=?) ", diff --git a/src/model/tripdetails.rs b/src/model/tripdetails.rs index 485e66f..6eafa88 100644 --- a/src/model/tripdetails.rs +++ b/src/model/tripdetails.rs @@ -138,7 +138,7 @@ ORDER BY day;", pub(crate) async fn user_allowed_to_change(&self, db: &SqlitePool, user: &User) -> bool { if self.belongs_to_event(db).await { - user.has_role(db, "admin").await + user.has_role(db, "planned_event").await } else { self.user_is_cox(db, user).await != CoxAtTrip::No } diff --git a/src/model/user.rs b/src/model/user.rs index 1e0a0da..b6fef48 100644 --- a/src/model/user.rs +++ b/src/model/user.rs @@ -26,7 +26,7 @@ const REGULAR: i32 = 22000; const UNTERSTUETZEND: i32 = 2500; const FOERDERND: i32 = 8500; -#[derive(FromRow, Serialize, Deserialize, Clone)] +#[derive(FromRow, Serialize, Deserialize, Clone, Debug)] pub struct User { pub id: i64, pub name: String, @@ -44,30 +44,6 @@ pub struct User { pub phone: Option, pub address: Option, pub family_id: Option, - pub membership_pdf: Option>, -} - -impl std::fmt::Debug for User { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("User") - .field("id", &self.id) - .field("name", &self.name) - .field("dob", &self.dob) - .field("weight", &self.weight) - .field("sex", &self.sex) - .field("deleted", &self.deleted) - .field("last_access", &self.last_access) - .field("member_since_date", &self.member_since_date) - .field("birthdate", &self.birthdate) - .field("mail", &self.mail) - .field("nickname", &self.nickname) - .field("notes", &self.notes) - .field("phone", &self.phone) - .field("address", &self.address) - .field("family_id", &self.family_id) - // Note that membership_pdf is intentionally omitted here - .finish() - } } #[derive(Debug, Serialize, Deserialize)] @@ -310,7 +286,7 @@ impl User { sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE id like ? ", @@ -325,7 +301,7 @@ WHERE id like ? sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE id like ? ", @@ -340,7 +316,7 @@ WHERE id like ? sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE name like ? ", @@ -382,7 +358,7 @@ WHERE name like ? sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE deleted = 0 ORDER BY last_access DESC @@ -397,7 +373,7 @@ ORDER BY last_access DESC sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user u JOIN user_role ur ON u.id = ur.user_id WHERE ur.role_id = ? AND deleted = 0 @@ -413,14 +389,14 @@ ORDER BY name; sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf FROM user +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE family_id IS NOT NULL GROUP BY family_id UNION -- Select users with a null family_id, without grouping -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf FROM user +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE family_id IS NULL; " ) @@ -433,7 +409,7 @@ WHERE family_id IS NULL; sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE deleted = 0 AND dob != '' and weight != '' and sex != '' ORDER BY name @@ -448,7 +424,7 @@ ORDER BY name sqlx::query_as!( Self, " -SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id, membership_pdf +SELECT id, name, pw, deleted, last_access, dob, weight, sex, member_since_date, birthdate, mail, nickname, notes, phone, address, family_id FROM user WHERE deleted = 0 AND (SELECT COUNT(*) FROM user_role WHERE user_id=user.id AND role_id = (SELECT id FROM role WHERE name = 'cox')) > 0 ORDER BY last_access DESC @@ -473,7 +449,9 @@ ORDER BY last_access DESC family_id = Some(Family::insert(db).await) } - if self.membership_pdf.is_none() { + let user_with_membershippdf = UserWithMembershipPdf::from(db, self.clone()).await; + + if user_with_membershippdf.membership_pdf.is_none() { if let Some(membership_pdf) = data.membership_pdf { let mut stream = membership_pdf.open().await.unwrap(); let mut buffer = Vec::new(); @@ -982,6 +960,29 @@ impl Deref for PlannedEventUser { } } +#[derive(FromRow, Serialize, Deserialize, Clone, Debug)] +pub struct UserWithMembershipPdf { + #[serde(flatten)] + pub user: User, + pub membership_pdf: Option>, +} + +impl UserWithMembershipPdf { + pub(crate) async fn from(db: &SqlitePool, user: User) -> Self { + let membership_pdf: Option> = + sqlx::query_scalar!("SELECT membership_pdf FROM user WHERE id = $1", user.id) + .fetch_optional(db) + .await + .unwrap() + .unwrap(); + + Self { + user, + membership_pdf, + } + } +} + #[async_trait] impl<'r> FromRequest<'r> for PlannedEventUser { type Error = LoginError; diff --git a/src/model/usertrip.rs b/src/model/usertrip.rs index 47603dc..e2a510c 100644 --- a/src/model/usertrip.rs +++ b/src/model/usertrip.rs @@ -11,7 +11,7 @@ impl UserTrip { user: &User, trip_details: &TripDetails, user_note: Option, - ) -> Result<(), UserTripError> { + ) -> Result { if trip_details.is_full(db).await { return Err(UserTripError::EventAlreadyFull); } @@ -81,7 +81,7 @@ impl UserTrip { .await; } - Ok(()) + Ok(name_newly_registered_person) } pub async fn delete( diff --git a/src/tera/admin/user.rs b/src/tera/admin/user.rs index aca09e9..332c74a 100644 --- a/src/tera/admin/user.rs +++ b/src/tera/admin/user.rs @@ -5,7 +5,7 @@ use crate::model::{ log::Log, logbook::Logbook, role::Role, - user::{AdminUser, User, UserWithRoles, VorstandUser}, + user::{AdminUser, User, UserWithMembershipPdf, UserWithRoles, VorstandUser}, }; use futures::future::join_all; use rocket::{ @@ -280,6 +280,7 @@ async fn download_membership_pdf( user: i32, ) -> (ContentType, Vec) { let user = User::find_by_id(db, user).await.unwrap(); + let user = UserWithMembershipPdf::from(db, user).await; Log::create( db, format!( diff --git a/src/tera/planned.rs b/src/tera/planned.rs index 468bd05..785b9b3 100644 --- a/src/tera/planned.rs +++ b/src/tera/planned.rs @@ -63,15 +63,25 @@ async fn join( }; match UserTrip::create(db, &user, &trip_details, user_note).await { - Ok(_) => { - Log::create( - db, - format!( - "User {} registered for trip_details.id={}", - user.name, trip_details_id - ), - ) - .await; + Ok(registered_user) => { + if registered_user == user.name { + Log::create( + db, + format!( + "User {} registered for trip_details.id={}", + user.name, trip_details_id + ), + ) + .await; + }else{ + Log::create( + db, + format!( + "User {} registered the guest '{}' for trip_details.id={}", + user.name, registered_user, trip_details_id + ), + ).await; + } Flash::success(Redirect::to("/planned"), "Erfolgreich angemeldet!") } Err(UserTripError::EventAlreadyFull) => { diff --git a/templates/includes/macros.html.tera b/templates/includes/macros.html.tera index 1c49080..96865a7 100644 --- a/templates/includes/macros.html.tera +++ b/templates/includes/macros.html.tera @@ -7,7 +7,7 @@ justify-content: space-around; padding: 0; list-style: none"> -
  • 22.04. | Christian Gusenbauer | Boot: Linz + kleiner Hänger
  • +
  • 30.03. | Manuela Firmötz | Boot: Urfahr
  • @@ -50,7 +50,8 @@ - {% endblock content %} + +{% endblock content %}