Merge pull request 'be able to change membership status on non-membership users' (#1195) from fix-user into main
Reviewed-on: #1195
This commit was merged in pull request #1195.
This commit is contained in:
@@ -14,6 +14,7 @@ pub(crate) enum Member {
|
|||||||
Regular(User),
|
Regular(User),
|
||||||
Foerdernd(User),
|
Foerdernd(User),
|
||||||
Unterstuetzend(User),
|
Unterstuetzend(User),
|
||||||
|
NoMembership(User),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Member {
|
impl Member {
|
||||||
@@ -31,7 +32,7 @@ impl Member {
|
|||||||
} else if user.has_role(db, "Unterstützend").await {
|
} else if user.has_role(db, "Unterstützend").await {
|
||||||
Self::Unterstuetzend(user)
|
Self::Unterstuetzend(user)
|
||||||
} else {
|
} else {
|
||||||
panic!("User {user} has no membership_type!!");
|
Self::NoMembership(user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ mod fee;
|
|||||||
pub(crate) mod foerdernd;
|
pub(crate) mod foerdernd;
|
||||||
pub(crate) mod member;
|
pub(crate) mod member;
|
||||||
pub mod merge;
|
pub mod merge;
|
||||||
|
pub(crate) mod nomembership;
|
||||||
pub(crate) mod regular;
|
pub(crate) mod regular;
|
||||||
pub(crate) mod scheckbuch;
|
pub(crate) mod scheckbuch;
|
||||||
pub(crate) mod schnupperant;
|
pub(crate) mod schnupperant;
|
||||||
|
|||||||
233
src/model/user/nomembership.rs
Normal file
233
src/model/user/nomembership.rs
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
use super::foerdernd::FoerderndUser;
|
||||||
|
use super::regular::RegularUser;
|
||||||
|
use super::scheckbuch::ScheckbuchUser;
|
||||||
|
use super::unterstuetzend::UnterstuetzendUser;
|
||||||
|
use super::{ManageUserUser, User};
|
||||||
|
use crate::NonEmptyString;
|
||||||
|
use crate::model::activity::ActivityBuilder;
|
||||||
|
use crate::model::role::Role;
|
||||||
|
use crate::model::notification::Notification;
|
||||||
|
use chrono::NaiveDate;
|
||||||
|
use rocket::fs::TempFile;
|
||||||
|
use sqlx::SqlitePool;
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
pub(crate) struct NoMembershipUser {
|
||||||
|
pub(crate) user: User,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for NoMembershipUser {
|
||||||
|
type Target = User;
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for NoMembershipUser {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.user.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NoMembershipUser {
|
||||||
|
pub(crate) async fn new(db: &SqlitePool, user: &User) -> Option<Self> {
|
||||||
|
if ScheckbuchUser::new(db, user).await.is_some() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if user.has_role(db, "schnupper-interessierte").await {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if user.has_role(db, "schnupperant").await {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if user.has_role(db, "Donau Linz").await {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if user.has_role(db, "Förderndes Mitglied").await {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if user.has_role(db, "Unterstützend").await {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(Self { user: user.clone() })
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_data_for_clubmember(
|
||||||
|
&self,
|
||||||
|
db: &SqlitePool,
|
||||||
|
changed_by: &ManageUserUser,
|
||||||
|
member_since: &NaiveDate,
|
||||||
|
birthdate: &NaiveDate,
|
||||||
|
phone: NonEmptyString,
|
||||||
|
address: NonEmptyString,
|
||||||
|
membership_pdf: &TempFile<'_>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
self.user.update_birthdate(db, changed_by, birthdate).await;
|
||||||
|
self.user
|
||||||
|
.update_member_since(db, changed_by, member_since)
|
||||||
|
.await;
|
||||||
|
self.user.update_phone(db, changed_by, &phone).await;
|
||||||
|
self.user.update_address(db, changed_by, &address).await;
|
||||||
|
self.user
|
||||||
|
.add_membership_pdf(db, changed_by, membership_pdf)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn convert_to_regular_user(
|
||||||
|
self,
|
||||||
|
db: &SqlitePool,
|
||||||
|
smtp_pw: &str,
|
||||||
|
changed_by: &ManageUserUser,
|
||||||
|
member_since: &NaiveDate,
|
||||||
|
birthdate: &NaiveDate,
|
||||||
|
phone: NonEmptyString,
|
||||||
|
address: NonEmptyString,
|
||||||
|
membership_pdf: &TempFile<'_>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
self.set_data_for_clubmember(
|
||||||
|
db,
|
||||||
|
changed_by,
|
||||||
|
member_since,
|
||||||
|
birthdate,
|
||||||
|
phone,
|
||||||
|
address,
|
||||||
|
membership_pdf,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let regular = Role::find_by_name(db, "Donau Linz").await.unwrap();
|
||||||
|
self.user.add_role(db, changed_by, ®ular).await?;
|
||||||
|
|
||||||
|
let regular = RegularUser::new(db, &self.user).await.unwrap();
|
||||||
|
regular.send_welcome_mail_to_user(db, smtp_pw).await?;
|
||||||
|
Notification::create_for_steering_people(
|
||||||
|
db,
|
||||||
|
&format!(
|
||||||
|
"Liebe Steuerberechtigte, {} hatte keinen Mitgliedsstatus und ist nun seit {} ein neues reguläres Mitglied. 🎉",
|
||||||
|
self.name,
|
||||||
|
member_since
|
||||||
|
),
|
||||||
|
"Neues Vereinsmitglied",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
ActivityBuilder::new(&format!(
|
||||||
|
"{changed_by} hat den User ohne Mitgliedsstatus {self} auf ein reguläres Mitglied upgegraded! Die Steuerpersonen wurden via Notification informiert."
|
||||||
|
))
|
||||||
|
.user(&self)
|
||||||
|
.save(db)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn convert_to_unterstuetzend_user(
|
||||||
|
self,
|
||||||
|
db: &SqlitePool,
|
||||||
|
smtp_pw: &str,
|
||||||
|
changed_by: &ManageUserUser,
|
||||||
|
member_since: &NaiveDate,
|
||||||
|
birthdate: &NaiveDate,
|
||||||
|
phone: NonEmptyString,
|
||||||
|
address: NonEmptyString,
|
||||||
|
membership_pdf: &TempFile<'_>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
self.set_data_for_clubmember(
|
||||||
|
db,
|
||||||
|
changed_by,
|
||||||
|
member_since,
|
||||||
|
birthdate,
|
||||||
|
phone,
|
||||||
|
address,
|
||||||
|
membership_pdf,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let unterstuetzend = Role::find_by_name(db, "Unterstützend").await.unwrap();
|
||||||
|
self.user.add_role(db, changed_by, &unterstuetzend).await?;
|
||||||
|
|
||||||
|
let unterstuetzend = UnterstuetzendUser::new(db, &self.user).await.unwrap();
|
||||||
|
unterstuetzend
|
||||||
|
.send_welcome_mail_to_user(db, smtp_pw)
|
||||||
|
.await?;
|
||||||
|
if let Some(vorstand) = Role::find_by_name(db, "vorstand").await {
|
||||||
|
Notification::create_for_role(
|
||||||
|
db,
|
||||||
|
&vorstand,
|
||||||
|
&format!(
|
||||||
|
"Lieber Vorstand, {} hatte keinen Mitgliedsstatus und ist nun seit {} ein neues unterstützendes Mitglied.",
|
||||||
|
self.name,
|
||||||
|
member_since
|
||||||
|
),
|
||||||
|
"Neues unterstützendes Vereinsmitglied",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
ActivityBuilder::new(&format!(
|
||||||
|
"{changed_by} hat den User ohne Mitgliedsstatus {self} auf ein unterstützendes Mitglied upgegraded!"
|
||||||
|
))
|
||||||
|
.user(&self)
|
||||||
|
.save(db)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn convert_to_foerdernd_user(
|
||||||
|
self,
|
||||||
|
db: &SqlitePool,
|
||||||
|
smtp_pw: &str,
|
||||||
|
changed_by: &ManageUserUser,
|
||||||
|
member_since: &NaiveDate,
|
||||||
|
birthdate: &NaiveDate,
|
||||||
|
phone: NonEmptyString,
|
||||||
|
address: NonEmptyString,
|
||||||
|
membership_pdf: &TempFile<'_>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
self.set_data_for_clubmember(
|
||||||
|
db,
|
||||||
|
changed_by,
|
||||||
|
member_since,
|
||||||
|
birthdate,
|
||||||
|
phone,
|
||||||
|
address,
|
||||||
|
membership_pdf,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let foerdernd = Role::find_by_name(db, "Förderndes Mitglied").await.unwrap();
|
||||||
|
self.user.add_role(db, changed_by, &foerdernd).await?;
|
||||||
|
|
||||||
|
let foerdernd = FoerderndUser::new(db, &self.user).await.unwrap();
|
||||||
|
foerdernd.send_welcome_mail_to_user(db, smtp_pw).await?;
|
||||||
|
if let Some(vorstand) = Role::find_by_name(db, "vorstand").await {
|
||||||
|
Notification::create_for_role(
|
||||||
|
db,
|
||||||
|
&vorstand,
|
||||||
|
&format!(
|
||||||
|
"Lieber Vorstand, {} hatte keinen Mitgliedsstatus und ist nun seit {} ein neues förderndes Mitglied.",
|
||||||
|
self.name,
|
||||||
|
member_since
|
||||||
|
),
|
||||||
|
"Neues förderndes Vereinsmitglied",
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
ActivityBuilder::new(&format!(
|
||||||
|
"{changed_by} hat den User ohne Mitgliedsstatus {self} auf ein förderndes Mitglied upgegraded!"
|
||||||
|
))
|
||||||
|
.user(&self)
|
||||||
|
.save(db)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,8 +8,9 @@ use crate::{
|
|||||||
role::Role,
|
role::Role,
|
||||||
user::{
|
user::{
|
||||||
clubmember::ClubMemberUser, foerdernd::FoerderndUser, member::Member,
|
clubmember::ClubMemberUser, foerdernd::FoerderndUser, member::Member,
|
||||||
regular::RegularUser, scheckbuch::ScheckbuchUser, schnupperant::SchnupperantUser,
|
nomembership::NoMembershipUser, regular::RegularUser, scheckbuch::ScheckbuchUser,
|
||||||
schnupperinterest::SchnupperInterestUser, unterstuetzend::UnterstuetzendUser,
|
schnupperant::SchnupperantUser, schnupperinterest::SchnupperInterestUser,
|
||||||
|
unterstuetzend::UnterstuetzendUser,
|
||||||
AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails,
|
AdminUser, AllowedToEditPaymentStatusUser, ManageUserUser, User, UserWithDetails,
|
||||||
UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser,
|
UserWithMembershipPdf, UserWithRolesAndMembershipPdf, VorstandUser,
|
||||||
},
|
},
|
||||||
@@ -1141,6 +1142,115 @@ async fn scheckbook_to_regular(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[post("/user/<id>/nomembership-to-regular", data = "<data>")]
|
||||||
|
async fn nomembership_to_regular(
|
||||||
|
db: &State<SqlitePool>,
|
||||||
|
data: Form<ScheckToRegularForm<'_>>,
|
||||||
|
admin: ManageUserUser,
|
||||||
|
config: &State<Config>,
|
||||||
|
id: i32,
|
||||||
|
) -> Flash<Redirect> {
|
||||||
|
let Some(user) = User::find_by_id(db, id).await else {
|
||||||
|
return Flash::error(
|
||||||
|
Redirect::to("/admin/user"),
|
||||||
|
format!("User with ID {} does not exist!", id),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
let Ok(birthdate) = NaiveDate::parse_from_str(&data.birthdate, "%Y-%m-%d") else {
|
||||||
|
return Flash::error(
|
||||||
|
Redirect::to(format!("/admin/user/{id}")),
|
||||||
|
format!(
|
||||||
|
"Geburtsdatum {} ist nicht im YYYY-MM-DD Format",
|
||||||
|
&data.birthdate
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
let Ok(member_since) = NaiveDate::parse_from_str(&data.member_since, "%Y-%m-%d") else {
|
||||||
|
return Flash::error(
|
||||||
|
Redirect::to(format!("/admin/user/{id}")),
|
||||||
|
format!(
|
||||||
|
"Beitrittsdatum {} ist nicht im YYYY-MM-DD Format",
|
||||||
|
&data.birthdate
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(user) = NoMembershipUser::new(db, &user).await else {
|
||||||
|
return Flash::error(
|
||||||
|
Redirect::to(format!("/admin/user/{id}")),
|
||||||
|
"User hat keinen fehlenden Mitgliedsstatus",
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
let Ok(phone) = data.phone.clone().try_into() else {
|
||||||
|
return Flash::error(
|
||||||
|
Redirect::to(format!("/admin/user/{id}")),
|
||||||
|
"Vereinsmitglied braucht eine Telefonnummer",
|
||||||
|
);
|
||||||
|
};
|
||||||
|
let Ok(address) = data.address.clone().try_into() else {
|
||||||
|
return Flash::error(
|
||||||
|
Redirect::to(format!("/admin/user/{id}")),
|
||||||
|
"Vereinsmitglied braucht eine Adresse",
|
||||||
|
);
|
||||||
|
};
|
||||||
|
let response = match &*data.membertype {
|
||||||
|
"regular" => {
|
||||||
|
user.convert_to_regular_user(
|
||||||
|
db,
|
||||||
|
&config.smtp_pw,
|
||||||
|
&admin,
|
||||||
|
&member_since,
|
||||||
|
&birthdate,
|
||||||
|
phone,
|
||||||
|
address,
|
||||||
|
&data.membership_pdf,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
"unterstuetzend" => {
|
||||||
|
user.convert_to_unterstuetzend_user(
|
||||||
|
db,
|
||||||
|
&config.smtp_pw,
|
||||||
|
&admin,
|
||||||
|
&member_since,
|
||||||
|
&birthdate,
|
||||||
|
phone,
|
||||||
|
address,
|
||||||
|
&data.membership_pdf,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
"foerdernd" => {
|
||||||
|
user.convert_to_foerdernd_user(
|
||||||
|
db,
|
||||||
|
&config.smtp_pw,
|
||||||
|
&admin,
|
||||||
|
&member_since,
|
||||||
|
&birthdate,
|
||||||
|
phone,
|
||||||
|
address,
|
||||||
|
&data.membership_pdf,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Flash::error(
|
||||||
|
Redirect::to(format!("/admin/user/{id}")),
|
||||||
|
"Membertype gibts ned",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match response {
|
||||||
|
Ok(_) => Flash::success(
|
||||||
|
Redirect::to(format!("/admin/user/{}", id)),
|
||||||
|
"Mitgliedstyp umgewandelt und Infos versendet",
|
||||||
|
),
|
||||||
|
Err(e) => Flash::error(Redirect::to(format!("/admin/user/{}", id)), e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(FromForm, Debug)]
|
#[derive(FromForm, Debug)]
|
||||||
pub struct ChangeMembertypeForm {
|
pub struct ChangeMembertypeForm {
|
||||||
membertype: String,
|
membertype: String,
|
||||||
@@ -1554,6 +1664,7 @@ pub fn routes() -> Vec<Route> {
|
|||||||
remove_role,
|
remove_role,
|
||||||
// Moves
|
// Moves
|
||||||
scheckbook_to_regular,
|
scheckbook_to_regular,
|
||||||
|
nomembership_to_regular,
|
||||||
schnupperant_to_regular,
|
schnupperant_to_regular,
|
||||||
schnupperant_to_scheckbook,
|
schnupperant_to_scheckbook,
|
||||||
schnupperinterest_to_schnupperant,
|
schnupperinterest_to_schnupperant,
|
||||||
|
|||||||
@@ -73,6 +73,8 @@
|
|||||||
Förderndes Vereinsmitglied
|
Förderndes Vereinsmitglied
|
||||||
{% elif "Unterstuetzend" in member %}
|
{% elif "Unterstuetzend" in member %}
|
||||||
Unterstützendes Vereinsmitglied
|
Unterstützendes Vereinsmitglied
|
||||||
|
{% elif "NoMembership" in member %}
|
||||||
|
⚠️ Kein Mitgliedsstatus!
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</small>
|
</small>
|
||||||
</h2>
|
</h2>
|
||||||
@@ -229,7 +231,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if "Scheckbuch" in member or "Schnupperant" in member %}
|
{% if "Scheckbuch" in member or "Schnupperant" in member or "NoMembership" in member %}
|
||||||
{% if allowed_to_edit %}
|
{% if allowed_to_edit %}
|
||||||
<div class="grid gap-3 pb-3 mt-3">
|
<div class="grid gap-3 pb-3 mt-3">
|
||||||
<button type="button"
|
<button type="button"
|
||||||
@@ -257,6 +259,8 @@
|
|||||||
{% set action = "scheckbook-to-regular" %}
|
{% set action = "scheckbook-to-regular" %}
|
||||||
{% elif "Schnupperant" in member %}
|
{% elif "Schnupperant" in member %}
|
||||||
{% set action = "schnupperant-to-regular" %}
|
{% set action = "schnupperant-to-regular" %}
|
||||||
|
{% elif "NoMembership" in member %}
|
||||||
|
{% set action = "nomembership-to-regular" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<form action="/admin/user/{{ user.id }}/{{ action }}"
|
<form action="/admin/user/{{ user.id }}/{{ action }}"
|
||||||
method="post"
|
method="post"
|
||||||
|
|||||||
Reference in New Issue
Block a user