Merge pull request 'Fill acitivites from various activities; Fixes #972' (#977) from single-user-edit-page into staging
Reviewed-on: #977
This commit is contained in:
commit
67d5df9c18
@ -14,6 +14,37 @@ pub struct Activity {
|
||||
pub keep_until: Option<NaiveDateTime>,
|
||||
}
|
||||
|
||||
pub struct ActivityBuilder {
|
||||
text: String,
|
||||
relevant_for: String,
|
||||
keep_until: Option<NaiveDateTime>,
|
||||
}
|
||||
|
||||
impl ActivityBuilder {
|
||||
pub fn new(text: &str) -> Self {
|
||||
Self {
|
||||
text: text.into(),
|
||||
relevant_for: String::new(),
|
||||
keep_until: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn relevant_for_user(self, user: &User) -> Self {
|
||||
Self {
|
||||
relevant_for: format!("{}user-{};", self.relevant_for, user.id),
|
||||
..self
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn save(self, db: &SqlitePool) {
|
||||
Activity::create(db, &self.text, &self.relevant_for, self.keep_until).await;
|
||||
}
|
||||
|
||||
pub async fn save_tx(self, db: &mut Transaction<'_, Sqlite>) {
|
||||
Activity::create_with_tx(db, &self.text, &self.relevant_for, self.keep_until).await;
|
||||
}
|
||||
}
|
||||
|
||||
impl Activity {
|
||||
pub async fn find_by_id(db: &SqlitePool, id: i64) -> Option<Self> {
|
||||
sqlx::query_as!(
|
||||
@ -25,7 +56,7 @@ impl Activity {
|
||||
.await
|
||||
.ok()
|
||||
}
|
||||
pub async fn create_with_tx(
|
||||
pub(super) async fn create_with_tx(
|
||||
db: &mut Transaction<'_, Sqlite>,
|
||||
text: &str,
|
||||
relevant_for: &str,
|
||||
@ -42,7 +73,7 @@ impl Activity {
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
pub async fn create(
|
||||
pub(super) async fn create(
|
||||
db: &SqlitePool,
|
||||
text: &str,
|
||||
relevant_for: &str,
|
||||
|
@ -9,7 +9,7 @@ use sqlx::{Sqlite, SqlitePool, Transaction};
|
||||
|
||||
use crate::tera::admin::mail::MailToSend;
|
||||
|
||||
use super::{family::Family, log::Log, role::Role, user::User};
|
||||
use super::{activity::ActivityBuilder, family::Family, log::Log, role::Role, user::User};
|
||||
|
||||
pub struct Mail {}
|
||||
|
||||
@ -253,6 +253,12 @@ Der Vorstand");
|
||||
|
||||
// Send the email
|
||||
mailer.send(&email).unwrap();
|
||||
ActivityBuilder::new(&format!(
|
||||
"{user} hat die Info-Mail bzgl. Gebühren gesendet bekommen."
|
||||
))
|
||||
.relevant_for_user(&user)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -369,6 +375,12 @@ Der Vorstand");
|
||||
|
||||
// Send the email
|
||||
mailer.send(&email).unwrap();
|
||||
ActivityBuilder::new(&format!(
|
||||
"{user} hat die Mahn-Mail bzgl. Gebühren gesendet bekommen."
|
||||
))
|
||||
.relevant_for_user(&user)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
use super::{AllowedToEditPaymentStatusUser, ManageUserUser, User};
|
||||
use crate::model::{
|
||||
activity::Activity, family::Family, log::Log, mail::valid_mails, notification::Notification,
|
||||
activity::ActivityBuilder, family::Family, mail::valid_mails, notification::Notification,
|
||||
role::Role,
|
||||
};
|
||||
use chrono::NaiveDate;
|
||||
@ -19,13 +19,10 @@ impl User {
|
||||
) -> Result<(), String> {
|
||||
let note = note.trim();
|
||||
|
||||
Activity::create(
|
||||
db,
|
||||
&format!("({updated_by}) {note}"),
|
||||
&format!("user-{};", user.id),
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!("({updated_by}) {note}"))
|
||||
.relevant_for_user(&user)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -50,12 +47,18 @@ impl User {
|
||||
.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
|
||||
let msg = match &self.mail {
|
||||
Some(old_mail) => format!(
|
||||
"{updated_by} has changed the mail address of {self} from {old_mail} to {new_mail}"
|
||||
),
|
||||
None => format!("{updated_by} has added a mail address for {self}: {new_mail}"),
|
||||
Some(old_mail) => {
|
||||
format!("{updated_by} hat die Mail-Adresse von {self} von {old_mail} auf {new_mail} geändert.")
|
||||
}
|
||||
None => {
|
||||
format!("{updated_by} eine neue Mail-Adresse für {self} hinzugefügt: {new_mail}")
|
||||
}
|
||||
};
|
||||
Log::create(db, msg).await;
|
||||
|
||||
ActivityBuilder::new(&msg)
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -84,11 +87,15 @@ impl User {
|
||||
query.execute(db).await.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
|
||||
let msg = match &self.phone {
|
||||
Some(old_phone) if new_phone.is_empty() => format!("{updated_by} has removed the phone number of {self} (old number: {old_phone})"),
|
||||
Some(old_phone) => format!("{updated_by} has changed the phone number of {self} from {old_phone} to {new_phone}"),
|
||||
None => format!("{updated_by} has added a phone number for {self}: {new_phone}")
|
||||
Some(old_phone) if new_phone.is_empty() => format!("{updated_by} hat die Telefonnummer von {self} entfernt (alte Nummer: {old_phone})"),
|
||||
Some(old_phone) => format!("{updated_by} hat die Telefonnummer von {self} von {old_phone} auf {new_phone} geändert."),
|
||||
None => format!("{updated_by} hat eine neue Telefonnummer für {self} hinzugefügt: {new_phone}")
|
||||
};
|
||||
Log::create(db, msg).await;
|
||||
|
||||
ActivityBuilder::new(&msg)
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub(crate) async fn update_address(
|
||||
@ -119,11 +126,15 @@ impl User {
|
||||
query.execute(db).await.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
|
||||
let msg = match &self.address {
|
||||
Some(old_address) if new_address.is_empty() => format!("{updated_by} has removed the address of {self} (old address: {old_address})"),
|
||||
Some(old_address) => format!("{updated_by} has changed the address of {self} from {old_address} to {new_address}"),
|
||||
None => format!("{updated_by} has added an address for {self}: {new_address}")
|
||||
Some(old_address) if new_address.is_empty() => format!("{updated_by} hat die Adresse von {self} entfernt (alte Adresse: {old_address})"),
|
||||
Some(old_address) => format!("{updated_by} hat die Adresse von {self} von {old_address} auf {new_address} geändert."),
|
||||
None => format!("{updated_by} hat eine Adresse für {self} hinzugefügt: {new_address}")
|
||||
};
|
||||
Log::create(db, msg).await;
|
||||
|
||||
ActivityBuilder::new(&msg)
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub(crate) async fn update_nickname(
|
||||
@ -146,11 +157,14 @@ impl User {
|
||||
query.execute(db).await.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
|
||||
let msg = match &self.nickname {
|
||||
Some(old_nickname) if new_nickname.is_empty() => format!("{updated_by} has removed the nickname of {self} (old nickname: {old_nickname})"),
|
||||
Some(old_nickname) => format!("{updated_by} has changed the nickname of {self} from {old_nickname} to {new_nickname}"),
|
||||
None => format!("{updated_by} has added a nickname for {self}: {new_nickname}")
|
||||
Some(old_nickname) if new_nickname.is_empty() => format!("{updated_by} hat den Sitznamen von {self} entfernt (alter Spitzname: {old_nickname})"),
|
||||
Some(old_nickname) => format!("{updated_by} hat den Spitznamen von {self} von {old_nickname} auf {new_nickname} geändert."),
|
||||
None => format!("{updated_by} hat einen neuen Spitznamen für {self} hinzugefügt: {new_nickname}")
|
||||
};
|
||||
Log::create(db, msg).await;
|
||||
ActivityBuilder::new(&msg)
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -171,10 +185,14 @@ impl User {
|
||||
.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
|
||||
let msg = match &self.member_since_date {
|
||||
Some(old_member_since_date) => format!("{updated_by} has changed the member_since date of {self} from {old_member_since_date} to {new_member_since_date}"),
|
||||
None => format!("{updated_by} has added a member_since_date for {self}: {new_member_since_date}")
|
||||
Some(old_member_since_date) => format!("{updated_by} hat das Beitrittsdatum von {self} von {old_member_since_date} auf {new_member_since_date} geändert."),
|
||||
None => format!("{updated_by} hat ein neues Beitrittsdatum für {self} hinzugefügt: {new_member_since_date}")
|
||||
};
|
||||
Log::create(db, msg).await;
|
||||
|
||||
ActivityBuilder::new(&msg)
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub(crate) async fn update_birthdate(
|
||||
@ -193,10 +211,14 @@ impl User {
|
||||
.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
|
||||
let msg = match &self.birthdate{
|
||||
Some(old_birthdate) => format!("{updated_by} has changed the birthdate of {self} from {old_birthdate} to {new_birthdate}"),
|
||||
None => format!("{updated_by} has added a birthdate for {self}: {new_birthdate}")
|
||||
Some(old_birthdate) => format!("{updated_by} hat das Geburtsdatum von {self} von {old_birthdate} auf {new_birthdate} geändert."),
|
||||
None => format!("{updated_by} hat ein Geburtsdatum für {self} hinzugefügt: {new_birthdate}")
|
||||
};
|
||||
Log::create(db, msg).await;
|
||||
|
||||
ActivityBuilder::new(&msg)
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub(crate) async fn update_family(
|
||||
@ -215,20 +237,26 @@ impl User {
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap();
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat {self} zu einer Familie hinzugefügt."
|
||||
))
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
} else {
|
||||
sqlx::query!("UPDATE user SET family_id = NULL where id = ?", self.id)
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap();
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat die Familienzugehörigkeit von {self} gelöscht."
|
||||
))
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
};
|
||||
|
||||
Family::clean_families_without_members(db).await;
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{updated_by} hat die Familie von {self} aktualisiert."),
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub(crate) async fn change_skill(
|
||||
@ -257,6 +285,10 @@ impl User {
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!("{updated_by} hat {self} zur Steuerperson gemacht"))
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
(old, new) if old == Some(cox.clone()) && new == Some(bootsfuehrer.clone()) => {
|
||||
self.remove_role(db, updated_by, &cox).await?;
|
||||
@ -272,6 +304,10 @@ impl User {
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!("{updated_by} hat {self} zum Bootsführer gemacht"))
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
(old, new) if new == None => {
|
||||
if let Some(old) = old {
|
||||
@ -286,6 +322,10 @@ impl User {
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!("{updated_by} hat {self} zum normalen Mitlgied gemacht (keine Steuerperson/Schiffsführer mehr)"))
|
||||
.relevant_for_user(self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
}
|
||||
(old, new) => return Err(format!("Not allowed to change from {old:?} to {new:?}")),
|
||||
@ -317,12 +357,11 @@ impl User {
|
||||
new.push_str("Keine Ermäßigung");
|
||||
}
|
||||
|
||||
Activity::create(
|
||||
db,
|
||||
&format!("({updated_by}) Ermäßigung von {self} von {old} auf {new} geändert"),
|
||||
&format!("user-{};", self.id),
|
||||
None,
|
||||
)
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat die Ermäßigung von {self} von {old} auf {new} geändert"
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
@ -347,10 +386,11 @@ impl User {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{updated_by} has removed role {role} from user {self}"),
|
||||
)
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat die Rolle {role} von {self} entfernt."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
@ -372,10 +412,11 @@ impl User {
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{updated_by} has set that user {self} has NOT paid the fee (yet)"),
|
||||
)
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat den Bezahlstatus von {self} auf 'nicht bezahlt' gesetzt."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
pub(crate) async fn has_paid(
|
||||
@ -394,10 +435,11 @@ impl User {
|
||||
.await
|
||||
.expect("paid role has no group");
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{updated_by} has set that user {self} has paid the fee (yet)"),
|
||||
)
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat den Bezahlstatus von {self} auf 'bezahlt' gesetzt."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
@ -427,11 +469,14 @@ impl User {
|
||||
)
|
||||
})?;
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{updated_by} has added role {role} to user {self}"),
|
||||
)
|
||||
.await;
|
||||
if !role.hide_in_lists {
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat die Rolle '{role}' dem Benutzer {self} hinzugefügt."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -461,10 +506,11 @@ impl User {
|
||||
.await
|
||||
.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{updated_by} has added the membership pdf for user {self}"),
|
||||
)
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat die Mitgliedserklärung (PDF) für user {self} hinzugefügt."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
|
@ -1,6 +1,8 @@
|
||||
use super::User;
|
||||
use crate::{
|
||||
model::{log::Log, notification::Notification, role::Role, user::ManageUserUser},
|
||||
model::{
|
||||
activity::ActivityBuilder, notification::Notification, role::Role, user::ManageUserUser,
|
||||
},
|
||||
special_user,
|
||||
};
|
||||
use rocket::async_trait;
|
||||
@ -81,10 +83,11 @@ impl ClubMemberUser {
|
||||
)
|
||||
.await;
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{modified_by} has moved user {self} to regular membership."),
|
||||
)
|
||||
ActivityBuilder::new(&format!(
|
||||
"{modified_by} hat {self} zu einem regulären hochgestuft."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
@ -116,10 +119,11 @@ impl ClubMemberUser {
|
||||
.await;
|
||||
}
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{modified_by} has moved user {self} to unterstützend membership."),
|
||||
)
|
||||
ActivityBuilder::new(&format!(
|
||||
"{modified_by} hat {self} zu einem unterstützenden Mitglied gemacht."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
@ -151,10 +155,11 @@ impl ClubMemberUser {
|
||||
.await;
|
||||
}
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("{modified_by} has moved user {self} to fördernd membership."),
|
||||
)
|
||||
ActivityBuilder::new(&format!(
|
||||
"{modified_by} hat {self} zu ein förderndes Mitglied gemacht."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
|
@ -1,5 +1,8 @@
|
||||
use super::User;
|
||||
use crate::{model::mail::Mail, special_user};
|
||||
use crate::{
|
||||
model::{activity::ActivityBuilder, mail::Mail},
|
||||
special_user,
|
||||
};
|
||||
use rocket::async_trait;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
@ -35,6 +38,13 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
smtp_pw,
|
||||
).await?;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"User {self} hat die Info-Mail bzgl. neues förderndes Mitglied (Handbuch und WLAN Infos) an {mail} gesendet bekommen"
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ use rocket::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::{FromRow, Sqlite, SqlitePool, Transaction};
|
||||
|
||||
use super::activity::ActivityBuilder;
|
||||
use super::{
|
||||
log::Log,
|
||||
logbook::Logbook,
|
||||
@ -112,74 +113,6 @@ impl User {
|
||||
self.has_role_tx(db, "cox").await || self.has_role_tx(db, "Bootsführer").await
|
||||
}
|
||||
|
||||
pub async fn send_welcome_email(&self, db: &SqlitePool, smtp_pw: &str) -> Result<(), String> {
|
||||
let Some(mail) = &self.mail else {
|
||||
return Err(format!(
|
||||
"Could not send welcome mail, because user {} has no email address",
|
||||
self.name
|
||||
));
|
||||
};
|
||||
|
||||
if self.has_role(db, "schnupperant").await {
|
||||
self.send_welcome_mail_schnupper(db, mail, smtp_pw).await?;
|
||||
} else if let Some(scheckbuch) = ScheckbuchUser::new(db, self).await {
|
||||
scheckbuch.notify(db, smtp_pw).await?;
|
||||
} else {
|
||||
return Err(format!(
|
||||
"Could not send welcome mail, because user {} is not in Donau Linz or scheckbuch or schnupperant group",
|
||||
self.name
|
||||
));
|
||||
}
|
||||
|
||||
Log::create(
|
||||
db,
|
||||
format!("Willkommensemail wurde an {} versandt", self.name),
|
||||
)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn send_welcome_mail_schnupper(
|
||||
&self,
|
||||
db: &SqlitePool,
|
||||
mail: &str,
|
||||
smtp_pw: &str,
|
||||
) -> Result<(), String> {
|
||||
// 2 things to do:
|
||||
// 1. Send mail to user
|
||||
Mail::send_single(
|
||||
db,
|
||||
mail,
|
||||
"Schnupperrudern beim ASKÖ Ruderverein Donau Linz",
|
||||
format!(
|
||||
"Hallo {0},
|
||||
|
||||
es freut uns sehr, dich bei unserem Schnupperkurs willkommen heißen zu dürfen. Detaillierte Informationen folgen noch, ich werde sie dir ein paar Tage vor dem Termin zusenden.
|
||||
|
||||
Riemen- & Dollenbruch,
|
||||
ASKÖ Ruderverein Donau Linz", self.name),
|
||||
smtp_pw,
|
||||
).await?;
|
||||
|
||||
// 2. Notify all coxes
|
||||
let coxes = Role::find_by_name(db, "schnupper-betreuer").await.unwrap();
|
||||
Notification::create_for_role(
|
||||
db,
|
||||
&coxes,
|
||||
&format!(
|
||||
"Liebe Schnupper-Betreuer, {} nimmt am Schnupperkurs teil.",
|
||||
self.name
|
||||
),
|
||||
"Neue(r) Schnupperteilnehmer:in ",
|
||||
None,
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn amount_boats(&self, db: &SqlitePool) -> i64 {
|
||||
sqlx::query!(
|
||||
"SELECT COUNT(*) as count FROM boat WHERE owner = ?",
|
||||
@ -275,6 +208,7 @@ AND r.cluster = 'financial';
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub async fn skill(&self, db: &SqlitePool) -> Option<Role> {
|
||||
sqlx::query_as!(
|
||||
Role,
|
||||
@ -485,22 +419,6 @@ ORDER BY last_access DESC
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub async fn create(db: &SqlitePool, name: &str) -> bool {
|
||||
let name = name.trim();
|
||||
sqlx::query!("INSERT INTO USER(name) VALUES (?)", name)
|
||||
.execute(db)
|
||||
.await
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub async fn create_with_mail(db: &SqlitePool, name: &str, mail: &str) -> bool {
|
||||
let name = name.trim();
|
||||
sqlx::query!("INSERT INTO USER(name, mail) VALUES (?, ?)", name, mail)
|
||||
.execute(db)
|
||||
.await
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
pub async fn update_ergo(&self, db: &SqlitePool, dob: i32, weight: i64, sex: &str) {
|
||||
sqlx::query!(
|
||||
"UPDATE user SET dob = ?, weight = ?, sex = ? where id = ?",
|
||||
@ -540,29 +458,7 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
smtp_pw,
|
||||
).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn add_role_tx(
|
||||
&self,
|
||||
db: &mut Transaction<'_, Sqlite>,
|
||||
role: &Role,
|
||||
) -> Result<(), String> {
|
||||
sqlx::query!(
|
||||
"INSERT INTO user_role(user_id, role_id) VALUES (?, ?)",
|
||||
self.id,
|
||||
role.id
|
||||
)
|
||||
.execute(db.deref_mut())
|
||||
.await
|
||||
.map_err(|_| {
|
||||
format!(
|
||||
"User already has a role in the cluster '{}'",
|
||||
role.cluster
|
||||
.clone()
|
||||
.expect("db trigger can't activate on empty string")
|
||||
)
|
||||
})?;
|
||||
ActivityBuilder::new(&format!("User {self} hat eine Mail bekommen, dass seine 5 Ausfahrten mit der heutigen Ausfahrt aufgebraucht sind, und dass der nächste Schritt eine Vereinsmitgliedschaft wäre (inkl. Links zu Beitrittserklärung + Info, dass sie an info@ geschickt werden soll.")).relevant_for_user(&self).save_tx(db).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -609,10 +505,11 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
};
|
||||
|
||||
if user.deleted {
|
||||
Log::create(
|
||||
db,
|
||||
format!("User ({name}) already deleted (tried to login)."),
|
||||
)
|
||||
ActivityBuilder::new(&format!(
|
||||
"User {user} wollte sich einloggen, klappte jedoch nicht weil er gelöscht wurde."
|
||||
))
|
||||
.relevant_for_user(&user)
|
||||
.save(db)
|
||||
.await;
|
||||
return Err(LoginError::InvalidAuthenticationCombo); //User existed sometime ago; has
|
||||
//been deleted
|
||||
@ -623,7 +520,12 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
if password_hash == user_pw {
|
||||
return Ok(user);
|
||||
}
|
||||
Log::create(db, format!("User {name} supplied the wrong PW")).await;
|
||||
ActivityBuilder::new(&format!(
|
||||
"User {user} wollte sich einloggen, hat jedoch das falsche Passwort angegeben."
|
||||
))
|
||||
.relevant_for_user(&user)
|
||||
.save(db)
|
||||
.await;
|
||||
Err(LoginError::InvalidAuthenticationCombo)
|
||||
} else {
|
||||
info!("User {name} has no PW set");
|
||||
@ -636,6 +538,12 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
|
||||
// TODO: add responsible person
|
||||
ActivityBuilder::new(&format!("Passwort von User {self} wurde zurückgesetzt."))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn update_pw(&self, db: &SqlitePool, pw: &str) {
|
||||
@ -644,6 +552,12 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
ActivityBuilder::new(&format!(
|
||||
"Passwort von User {self} wurde erfolgreich geändert."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
fn get_hashed_pw(pw: &str) -> String {
|
||||
@ -663,6 +577,10 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
ActivityBuilder::new(&format!("User {self} hat sich eingeloggt."))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn delete(&self, db: &SqlitePool) {
|
||||
@ -670,6 +588,10 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
.execute(db)
|
||||
.await
|
||||
.unwrap(); //Okay, because we can only create a User of a valid id
|
||||
ActivityBuilder::new(&format!("User {self} wurde gelöscht."))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
}
|
||||
|
||||
pub async fn get_days(&self, db: &SqlitePool) -> Vec<Day> {
|
||||
@ -761,6 +683,10 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
None,None
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!("5 Scheckbuchausfahrten von {self} wurden mit der heutigen Ausfahrt aufgebraucht. Info-Mail wurde an {self} geschickt + alle Steuerberechtigten informiert, dass wir pot. ein neues Mitglied haben"))
|
||||
.relevant_for_user(&self)
|
||||
.save_tx(db)
|
||||
.await;
|
||||
}
|
||||
a if a > 5 => {
|
||||
let board = Role::find_by_name_tx(db, "Vorstand").await.unwrap();
|
||||
@ -775,6 +701,10 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
None,None
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!("{self} hat nun bereits die {amount_trips}. seiner 5 Scheckbuchausfahrten absolviert. Vorstand wurde via Notification informiert."))
|
||||
.relevant_for_user(&self)
|
||||
.save_tx(db)
|
||||
.await;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -794,6 +724,12 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
None,None
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!(
|
||||
"{self} hat das heurige Fahrtenabzeichen geschafft! Der Vorstand + {self} wurde via Notification informiert."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save_tx(db)
|
||||
.await;
|
||||
|
||||
Notification::create_with_tx(db, self, "Mit deiner letzten Ausfahrt hast du nun alle Anforderungen für das heurige Fahrtenzeichen erfüllt. Gratuliere! 🎉", "Fahrtenabzeichen geschafft", None, None).await;
|
||||
}
|
||||
@ -812,6 +748,10 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
None,None
|
||||
)
|
||||
.await;
|
||||
ActivityBuilder::new(&format!("{self} hat den Äquatorpreis in {level} geschafft! Der Vorstand + {self} wurde via Notification informiert."))
|
||||
.relevant_for_user(&self)
|
||||
.save_tx(db)
|
||||
.await;
|
||||
|
||||
Notification::create_with_tx(db, self, &format!("Mit deiner letzten Ausfahrt erfüllst du nun alle Anforderungen für den Äquatorpreis in {level}. Gratuliere! 🎉"), "Äquatorpreis", None, None).await;
|
||||
}
|
||||
@ -1031,20 +971,6 @@ mod test {
|
||||
assert_eq!(res.len(), 4);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_succ_create() {
|
||||
let pool = testdb!();
|
||||
|
||||
assert_eq!(User::create(&pool, "new-user-name".into()).await, true);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn test_duplicate_name_create() {
|
||||
let pool = testdb!();
|
||||
|
||||
assert_eq!(User::create(&pool, "admin".into()).await, false);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
fn succ_login_with_test_db() {
|
||||
let pool = testdb!();
|
||||
|
@ -1,5 +1,8 @@
|
||||
use super::User;
|
||||
use crate::{model::mail::Mail, special_user};
|
||||
use crate::{
|
||||
model::{activity::ActivityBuilder, mail::Mail},
|
||||
special_user,
|
||||
};
|
||||
use rocket::async_trait;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
@ -43,6 +46,11 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
smtp_pw,
|
||||
).await?;
|
||||
|
||||
ActivityBuilder::new(&format!("Willkommensmail für {self} wurde an {mail} verschickt (Handbuch, Signal-Gruppe, App-Info, Fingerprint, WLAN)."))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use super::foerdernd::FoerderndUser;
|
||||
use super::regular::RegularUser;
|
||||
use super::unterstuetzend::UnterstuetzendUser;
|
||||
use super::{ManageUserUser, User};
|
||||
use crate::model::activity::ActivityBuilder;
|
||||
use crate::model::role::Role;
|
||||
use crate::NonEmptyString;
|
||||
use crate::{
|
||||
@ -83,6 +84,13 @@ impl ScheckbuchUser {
|
||||
)
|
||||
.await;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{changed_by} hat den Scheckbuch-User {self} auf ein reguläres Mitglied upgegraded!"
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -134,6 +142,10 @@ impl ScheckbuchUser {
|
||||
)
|
||||
.await;
|
||||
}
|
||||
ActivityBuilder::new(&format!("{changed_by} hat den Scheckbuch-User {self} auf ein unterstützendes Mitglied upgegraded!"))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -184,6 +196,12 @@ impl ScheckbuchUser {
|
||||
)
|
||||
.await;
|
||||
}
|
||||
ActivityBuilder::new(&format!(
|
||||
"{changed_by} hat den Scheckbuch-User {self} auf ein förderndes Mitglied upgegraded!"
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -193,6 +211,13 @@ impl ScheckbuchUser {
|
||||
self.notify_coxes_about_new_scheckbuch(db).await;
|
||||
self.send_welcome_mail_to_user(db, smtp_pw).await?;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{self} hat eine Info-Mail bekommen (Erklärung Scheckbuch, Ruderapp) und alle Steuerberechtigten wurden informiert."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
use super::foerdernd::FoerderndUser;
|
||||
use super::regular::RegularUser;
|
||||
use super::scheckbuch::ScheckbuchUser;
|
||||
use super::schnupperinterest::SchnupperInterestUser;
|
||||
use super::unterstuetzend::UnterstuetzendUser;
|
||||
use super::{ManageUserUser, User};
|
||||
use crate::model::activity::ActivityBuilder;
|
||||
use crate::model::role::Role;
|
||||
use crate::NonEmptyString;
|
||||
use crate::{
|
||||
@ -84,6 +86,13 @@ impl SchnupperantUser {
|
||||
)
|
||||
.await;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{changed_by} hat den Schnupperant {self} auf ein reguläres Mitglied upgegraded!"
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -105,7 +114,7 @@ impl SchnupperantUser {
|
||||
}
|
||||
|
||||
let scheckbook = ScheckbuchUser::new(db, &self.user).await.unwrap();
|
||||
scheckbook.send_welcome_mail_to_user(db, smtp_pw).await?;
|
||||
scheckbook.notify(db, smtp_pw).await?;
|
||||
|
||||
Notification::create_for_steering_people(
|
||||
db,
|
||||
@ -118,6 +127,13 @@ impl SchnupperantUser {
|
||||
)
|
||||
.await;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{changed_by} hat dem ehemaligen Schnupperant {self} nun ein Scheckbuch gegeben"
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -135,6 +151,9 @@ impl SchnupperantUser {
|
||||
.add_role(db, changed_by, &schnupperinterest)
|
||||
.await?;
|
||||
|
||||
let schnupperinterest = SchnupperInterestUser::new(db, &self.user).await.unwrap();
|
||||
schnupperinterest.notify(db).await?;
|
||||
|
||||
if let Some(role) = Role::find_by_name(db, "schnupper-betreuer").await {
|
||||
Notification::create_for_role(
|
||||
db,
|
||||
@ -150,6 +169,13 @@ impl SchnupperantUser {
|
||||
.await;
|
||||
}
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{changed_by} hat dem eigentlichen Schnupperanten {self} wieder auf die 'Interessierten'-Liste zurückgegeben."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -207,6 +233,13 @@ impl SchnupperantUser {
|
||||
.await;
|
||||
}
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{changed_by} hat den Schnupperant {self} auf ein unterstützendes Mitglied upgegraded!"
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -262,6 +295,13 @@ impl SchnupperantUser {
|
||||
.await;
|
||||
}
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{changed_by} hat den Schnupperant {self} auf ein förderndes Mitglied upgegraded!"
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -270,6 +310,13 @@ impl SchnupperantUser {
|
||||
self.notify_coxes_about_new_scheckbuch(db).await;
|
||||
self.send_welcome_mail_to_user(db, smtp_pw).await?;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{self} hat eine Mail bekommen (Inhalt: wir freuen uns auf ihn + senden detailliertere Infos später zu) und die Schnupperbetreuer wurden via Notification informiert."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::scheckbuch::ScheckbuchUser;
|
||||
use super::schnupperant::SchnupperantUser;
|
||||
use super::{ManageUserUser, User};
|
||||
use crate::model::activity::ActivityBuilder;
|
||||
use crate::model::role::Role;
|
||||
use crate::{model::notification::Notification, special_user};
|
||||
use rocket::async_trait;
|
||||
@ -25,7 +26,7 @@ impl SchnupperInterestUser {
|
||||
self.user.add_role(db, changed_by, &scheckbook).await?;
|
||||
|
||||
let scheckbook = ScheckbuchUser::new(db, &self.user).await.unwrap();
|
||||
scheckbook.send_welcome_mail_to_user(db, smtp_pw).await?;
|
||||
scheckbook.notify(db, smtp_pw).await?;
|
||||
|
||||
Notification::create_for_steering_people(
|
||||
db,
|
||||
@ -39,6 +40,13 @@ impl SchnupperInterestUser {
|
||||
)
|
||||
.await;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"Der Schnupperinteressierte {self} hat sich (ohne Schnupperkurs) doch gleich direkt für ein Scheckbuch entschieden. {changed_by} hat dieses eingerichtet."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -74,6 +82,12 @@ impl SchnupperInterestUser {
|
||||
)
|
||||
.await;
|
||||
}
|
||||
ActivityBuilder::new(&format!(
|
||||
"Der Schnupperinteressierte {self} hat sich zum Schnupperkurs angemeldet."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -81,6 +95,13 @@ impl SchnupperInterestUser {
|
||||
pub(crate) async fn notify(&self, db: &SqlitePool) -> Result<(), String> {
|
||||
self.notify_schnupperbetreuer_about_new_interest(db).await;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"Der Schnupperbetreuer hat eine Info via Notification bekommen, dass {self} Interesse an einen Schnupperkurs hat."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,8 @@
|
||||
use super::User;
|
||||
use crate::{model::mail::Mail, special_user};
|
||||
use crate::{
|
||||
model::{activity::ActivityBuilder, mail::Mail},
|
||||
special_user,
|
||||
};
|
||||
use rocket::async_trait;
|
||||
use sqlx::SqlitePool;
|
||||
|
||||
@ -35,6 +38,13 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
smtp_pw,
|
||||
).await?;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{self} hat eine Mail an {mail} bekommen, mit Infos dass er/sie nun ein unterstützendes Mitglied ist (Handbuch, WLAN)."
|
||||
))
|
||||
.relevant_for_user(&self)
|
||||
.save(db)
|
||||
.await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -254,26 +254,6 @@ async fn fees_paid(
|
||||
)
|
||||
}
|
||||
|
||||
#[get("/user/<user>/send-welcome-mail")]
|
||||
async fn send_welcome_mail(
|
||||
db: &State<SqlitePool>,
|
||||
_admin: ManageUserUser,
|
||||
config: &State<Config>,
|
||||
user: i32,
|
||||
) -> Flash<Redirect> {
|
||||
let Some(user) = User::find_by_id(db, user).await else {
|
||||
return Flash::error(Redirect::to("/admin/user"), "User does not exist");
|
||||
};
|
||||
|
||||
match user.send_welcome_email(db, &config.smtp_pw).await {
|
||||
Ok(()) => Flash::success(
|
||||
Redirect::to("/admin/user"),
|
||||
format!("Willkommens-Email wurde an {} versandt.", user.name),
|
||||
),
|
||||
Err(e) => Flash::error(Redirect::to("/admin/user"), e),
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/user/<user>/reset-pw")]
|
||||
async fn resetpw(db: &State<SqlitePool>, admin: ManageUserUser, user: i32) -> Flash<Redirect> {
|
||||
let user = User::find_by_id(db, user).await;
|
||||
@ -760,32 +740,6 @@ async fn download_membership_pdf(
|
||||
(ContentType::PDF, user.membership_pdf.unwrap())
|
||||
}
|
||||
|
||||
#[derive(FromForm, Debug)]
|
||||
struct UserAddForm<'r> {
|
||||
name: &'r str,
|
||||
}
|
||||
|
||||
#[post("/user/new", data = "<data>")]
|
||||
async fn create(
|
||||
db: &State<SqlitePool>,
|
||||
data: Form<UserAddForm<'_>>,
|
||||
admin: ManageUserUser,
|
||||
) -> Flash<Redirect> {
|
||||
if User::create(db, data.name).await {
|
||||
Log::create(
|
||||
db,
|
||||
format!("{} created new user: {data:?}", admin.user.name),
|
||||
)
|
||||
.await;
|
||||
Flash::success(Redirect::to("/admin/user"), "Successfully created user")
|
||||
} else {
|
||||
Flash::error(
|
||||
Redirect::to("/admin/user"),
|
||||
format!("User {} already exists", data.name),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//#[derive(FromForm, Debug)]
|
||||
//struct UserAddScheckbuchForm<'r> {
|
||||
// name: &'r str,
|
||||
@ -1248,14 +1202,12 @@ pub fn routes() -> Vec<Route> {
|
||||
index_admin,
|
||||
view,
|
||||
resetpw,
|
||||
create,
|
||||
//create_scheckbuch,
|
||||
delete,
|
||||
fees,
|
||||
fees_paid,
|
||||
scheckbuch,
|
||||
download_membership_pdf,
|
||||
send_welcome_mail,
|
||||
//
|
||||
update_mail,
|
||||
update_phone,
|
||||
|
Loading…
x
Reference in New Issue
Block a user