473 lines
15 KiB
Rust
473 lines
15 KiB
Rust
// TODO: put back in `src/model/user/mod.rs` once that is cleaned up
|
|
|
|
use super::{AllowedToEditPaymentStatusUser, ManageUserUser, User};
|
|
use crate::model::{
|
|
activity::Activity, family::Family, log::Log, mail::valid_mails, notification::Notification,
|
|
role::Role,
|
|
};
|
|
use chrono::NaiveDate;
|
|
use rocket::{fs::TempFile, tokio::io::AsyncReadExt};
|
|
use sqlx::SqlitePool;
|
|
|
|
impl User {
|
|
pub(crate) async fn add_note(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
user: &User,
|
|
note: &str,
|
|
) -> Result<(), String> {
|
|
let note = note.trim();
|
|
|
|
Activity::create(
|
|
db,
|
|
&format!("({updated_by}) {note}"),
|
|
&format!("user-{};", user.id),
|
|
None,
|
|
)
|
|
.await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn update_mail(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_mail: &str,
|
|
) -> Result<(), String> {
|
|
let new_mail = new_mail.trim();
|
|
|
|
if !valid_mails(new_mail) {
|
|
return Err(format!(
|
|
"{new_mail} ist kein gültiges Format für eine Mailadresse"
|
|
));
|
|
}
|
|
|
|
sqlx::query!("UPDATE user SET mail = ? where id = ?", new_mail, self.id)
|
|
.execute(db)
|
|
.await
|
|
.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}"),
|
|
};
|
|
Log::create(db, msg).await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn update_phone(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_phone: &str,
|
|
) {
|
|
let new_phone = new_phone.trim();
|
|
|
|
let query = if new_phone.is_empty() {
|
|
if self.phone.is_none() {
|
|
return; // nothing to do
|
|
}
|
|
sqlx::query!("UPDATE user SET phone = NULL where id = ?", self.id)
|
|
} else {
|
|
if let Some(old_phone) = &self.phone {
|
|
if old_phone == new_phone {
|
|
return; //nothing to do
|
|
}
|
|
}
|
|
sqlx::query!("UPDATE user SET phone = ? where id = ?", new_phone, self.id)
|
|
};
|
|
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}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
}
|
|
|
|
pub(crate) async fn update_address(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_address: &str,
|
|
) {
|
|
let new_address = new_address.trim();
|
|
|
|
let query = if new_address.is_empty() {
|
|
if !self.address.is_none() {
|
|
return; // nothing to do
|
|
}
|
|
sqlx::query!("UPDATE user SET address = NULL where id = ?", self.id)
|
|
} else {
|
|
if let Some(old_address) = &self.address {
|
|
if old_address == new_address {
|
|
return; //nothing to do
|
|
}
|
|
}
|
|
sqlx::query!(
|
|
"UPDATE user SET address = ? where id = ?",
|
|
new_address,
|
|
self.id
|
|
)
|
|
};
|
|
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}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
}
|
|
|
|
pub(crate) async fn update_nickname(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_nickname: &str,
|
|
) -> Result<(), String> {
|
|
let new_nickname = new_nickname.trim();
|
|
|
|
let query = if new_nickname.is_empty() {
|
|
sqlx::query!("UPDATE user SET nickname = NULL where id = ?", self.id)
|
|
} else {
|
|
sqlx::query!(
|
|
"UPDATE user SET nickname = ? where id = ?",
|
|
new_nickname,
|
|
self.id
|
|
)
|
|
};
|
|
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}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn update_member_since(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_member_since_date: &NaiveDate,
|
|
) {
|
|
sqlx::query!(
|
|
"UPDATE user SET member_since_date = ? where id = ?",
|
|
new_member_since_date,
|
|
self.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.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}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
}
|
|
|
|
pub(crate) async fn update_birthdate(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
new_birthdate: &NaiveDate,
|
|
) {
|
|
sqlx::query!(
|
|
"UPDATE user SET birthdate = ? where id = ?",
|
|
new_birthdate,
|
|
self.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.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}")
|
|
};
|
|
Log::create(db, msg).await;
|
|
}
|
|
|
|
pub(crate) async fn update_family(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
family: Option<Family>,
|
|
) {
|
|
if let Some(family) = family {
|
|
let family_id = family.id;
|
|
sqlx::query!(
|
|
"UPDATE user SET family_id = ? where id = ?",
|
|
family_id,
|
|
self.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.unwrap();
|
|
} else {
|
|
sqlx::query!("UPDATE user SET family_id = NULL where id = ?", self.id)
|
|
.execute(db)
|
|
.await
|
|
.unwrap();
|
|
};
|
|
|
|
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(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
skill: Option<Role>,
|
|
) -> Result<(), String> {
|
|
let old_skill = self.skill(db).await;
|
|
|
|
let member = Role::find_by_name(db, "Donau Linz").await.unwrap();
|
|
let cox = Role::find_by_name(db, "cox").await.unwrap();
|
|
let bootsfuehrer = Role::find_by_name(db, "Bootsführer").await.unwrap();
|
|
|
|
match (old_skill, skill) {
|
|
(old, new) if old == None && new == Some(cox.clone()) => {
|
|
self.add_role(db, updated_by, &cox).await?;
|
|
Notification::create_for_role(
|
|
db,
|
|
&member,
|
|
&format!(
|
|
"Liebes Vereinsmitglied, {self} ist ab sofort Steuerperson 🎉 Hip hip ...!"
|
|
),
|
|
"Neue Steuerperson",
|
|
None,
|
|
None,
|
|
)
|
|
.await;
|
|
}
|
|
(old, new) if old == Some(cox.clone()) && new == Some(bootsfuehrer.clone()) => {
|
|
self.remove_role(db, updated_by, &cox).await?;
|
|
self.add_role(db, updated_by, &bootsfuehrer).await?;
|
|
Notification::create_for_role(
|
|
db,
|
|
&member,
|
|
&format!(
|
|
"Liebes Vereinsmitglied, {self} ist ab sofort Bootsführer:in 🎉 Hip hip ...!"
|
|
),
|
|
"Neue:r Bootsführer:in",
|
|
None,
|
|
None,
|
|
)
|
|
.await;
|
|
}
|
|
(old, new) if new == None => {
|
|
if let Some(old) = old {
|
|
self.remove_role(db, updated_by, &old).await?;
|
|
let vorstand = Role::find_by_name(db, "Vorstand").await.unwrap();
|
|
Notification::create_for_role(
|
|
db,
|
|
&vorstand,
|
|
&format!("Lieber Vorstand, {self} ist ab kein {old} mehr."),
|
|
"Steuerperson --",
|
|
None,
|
|
None,
|
|
)
|
|
.await;
|
|
}
|
|
}
|
|
(old, new) => return Err(format!("Not allowed to change from {old:?} to {new:?}")),
|
|
};
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn change_financial(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
financial: Option<Role>,
|
|
) -> Result<(), String> {
|
|
let mut new = String::new();
|
|
let mut old = String::new();
|
|
|
|
if let Some(old_financial) = self.financial(db).await {
|
|
self.remove_role(db, updated_by, &old_financial).await?;
|
|
old.push_str(&old_financial.name);
|
|
} else {
|
|
old.push_str("Keine Ermäßigung");
|
|
}
|
|
|
|
if let Some(new_financial) = financial {
|
|
self.add_role(db, updated_by, &new_financial).await?;
|
|
new.push_str(&new_financial.name);
|
|
} else {
|
|
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,
|
|
)
|
|
.await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn remove_role(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
role: &Role,
|
|
) -> Result<(), String> {
|
|
if !self.has_role(db, &role.name).await {
|
|
return Err(format!("Kann Rolle {role} von User {self} nicht entfernen, da der User die Rolle gar nicht hat"));
|
|
}
|
|
|
|
sqlx::query!(
|
|
"DELETE FROM user_role WHERE user_id = ? and role_id = ?",
|
|
self.id,
|
|
role.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.unwrap();
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} has removed role {role} from user {self}"),
|
|
)
|
|
.await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn has_not_paid(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &AllowedToEditPaymentStatusUser,
|
|
) {
|
|
let paid = Role::find_by_name(db, "paid").await.unwrap();
|
|
|
|
sqlx::query!(
|
|
"DELETE FROM user_role WHERE user_id = ? and role_id = ?",
|
|
self.id,
|
|
paid.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.unwrap();
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} has set that user {self} has NOT paid the fee (yet)"),
|
|
)
|
|
.await;
|
|
}
|
|
pub(crate) async fn has_paid(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &AllowedToEditPaymentStatusUser,
|
|
) {
|
|
let paid = Role::find_by_name(db, "paid").await.unwrap();
|
|
|
|
sqlx::query!(
|
|
"INSERT INTO user_role(user_id, role_id) VALUES (?, ?)",
|
|
self.id,
|
|
paid.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.expect("paid role has no group");
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} has set that user {self} has paid the fee (yet)"),
|
|
)
|
|
.await;
|
|
}
|
|
|
|
pub(crate) async fn add_role(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
role: &Role,
|
|
) -> Result<(), String> {
|
|
if self.has_role(db, &role.name).await {
|
|
return Err(format!("Kann Rolle {role} von User {self} nicht hinzufügen, da der User die Rolle schon hat"));
|
|
}
|
|
|
|
sqlx::query!(
|
|
"INSERT INTO user_role(user_id, role_id) VALUES (?, ?)",
|
|
self.id,
|
|
role.id
|
|
)
|
|
.execute(db)
|
|
.await
|
|
.map_err(|_| {
|
|
format!(
|
|
"User already has a role in the cluster '{}'",
|
|
role.cluster
|
|
.clone()
|
|
.expect("db trigger can't activate on empty string")
|
|
)
|
|
})?;
|
|
|
|
Log::create(
|
|
db,
|
|
format!("{updated_by} has added role {role} to user {self}"),
|
|
)
|
|
.await;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub(crate) async fn add_membership_pdf(
|
|
&self,
|
|
db: &SqlitePool,
|
|
updated_by: &ManageUserUser,
|
|
membership_pdf: &TempFile<'_>,
|
|
) -> Result<(), String> {
|
|
if self.has_membership_pdf(db).await {
|
|
return Err(format!("User {self} hat bereits eine Beitrittserklärung."));
|
|
}
|
|
if membership_pdf.len() == 0 {
|
|
return Err(format!("Keine Beitrittserklärung mitgeschickt."));
|
|
}
|
|
|
|
let mut stream = membership_pdf.open().await.unwrap();
|
|
let mut buffer = Vec::new();
|
|
stream.read_to_end(&mut buffer).await.unwrap();
|
|
sqlx::query!(
|
|
"UPDATE user SET membership_pdf = ? where id = ?",
|
|
buffer,
|
|
self.id
|
|
)
|
|
.execute(db)
|
|
.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}"),
|
|
)
|
|
.await;
|
|
|
|
Ok(())
|
|
}
|
|
}
|