only-last-30-days-notifications #331
118
Cargo.lock
generated
118
Cargo.lock
generated
@ -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]]
|
||||
|
@ -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");
|
||||
|
@ -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(())
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ GROUP BY family.id;"
|
||||
}
|
||||
|
||||
pub async fn members(&self, db: &SqlitePool) -> Vec<User> {
|
||||
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()
|
||||
|
@ -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(),
|
||||
|
@ -58,7 +58,7 @@ impl Notification {
|
||||
pub async fn for_user(db: &SqlitePool, user: &User) -> Vec<Self> {
|
||||
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)
|
||||
|
@ -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=?)
|
||||
",
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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<String>,
|
||||
pub address: Option<String>,
|
||||
pub family_id: Option<i64>,
|
||||
pub membership_pdf: Option<Vec<u8>>,
|
||||
}
|
||||
|
||||
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<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl UserWithMembershipPdf {
|
||||
pub(crate) async fn from(db: &SqlitePool, user: User) -> Self {
|
||||
let membership_pdf: Option<Vec<u8>> =
|
||||
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;
|
||||
|
@ -11,7 +11,7 @@ impl UserTrip {
|
||||
user: &User,
|
||||
trip_details: &TripDetails,
|
||||
user_note: Option<String>,
|
||||
) -> Result<(), UserTripError> {
|
||||
) -> Result<String, UserTripError> {
|
||||
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(
|
||||
|
@ -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<u8>) {
|
||||
let user = User::find_by_id(db, user).await.unwrap();
|
||||
let user = UserWithMembershipPdf::from(db, user).await;
|
||||
Log::create(
|
||||
db,
|
||||
format!(
|
||||
|
@ -63,7 +63,8 @@ async fn join(
|
||||
};
|
||||
|
||||
match UserTrip::create(db, &user, &trip_details, user_note).await {
|
||||
Ok(_) => {
|
||||
Ok(registered_user) => {
|
||||
if registered_user == user.name {
|
||||
Log::create(
|
||||
db,
|
||||
format!(
|
||||
@ -72,6 +73,15 @@ async fn join(
|
||||
),
|
||||
)
|
||||
.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) => {
|
||||
|
@ -7,7 +7,7 @@
|
||||
justify-content: space-around;
|
||||
padding: 0;
|
||||
list-style: none">
|
||||
<li style="display: inline-block;">22.04. | Christian Gusenbauer | Boot: Linz + kleiner Hänger</li>
|
||||
<li style="display: inline-block;">30.03. | Manuela Firmötz | Boot: Urfahr</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -50,7 +50,8 @@
|
||||
</a>
|
||||
<div class="hidden">
|
||||
<div id="mobile-menu">
|
||||
<a href="/log" class="block w-100 py-2 hover:text-primary-600">Ausfahrt eintragen</a>
|
||||
<a href="/planned" class="block w-100 py-2 hover:text-primary-600">Geplante Ausfahrten</a>
|
||||
<a href="/log" class="block w-100 py-2 hover:text-primary-600 border-t">Ausfahrt eintragen</a>
|
||||
<a href="/log/show"
|
||||
class="block w-100 py-2 hover:text-primary-600 border-t">Logbuch</a>
|
||||
{% if "admin" in loggedin_user.roles or "Vorstand" in loggedin_user.roles %}
|
||||
|
@ -176,4 +176,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock content %}
|
||||
</div>
|
||||
{% endblock content %}
|
||||
|
Loading…
Reference in New Issue
Block a user