new newbie flag
This commit is contained in:
@@ -301,8 +301,9 @@ mod test {
|
||||
always_show: event.always_show,
|
||||
is_locked: event.is_locked,
|
||||
trip_type_id: None,
|
||||
allow_guests: event.allow_guests,
|
||||
};
|
||||
event.update(&pool, &user, &cancel_update).await;
|
||||
event.update(&pool, &user, &cancel_update).await.unwrap();
|
||||
|
||||
// Rower received notification
|
||||
let notifications = Notification::for_user(&pool, &rower).await;
|
||||
@@ -331,13 +332,14 @@ mod test {
|
||||
always_show: event.always_show,
|
||||
is_locked: event.is_locked,
|
||||
trip_type_id: None,
|
||||
allow_guests: event.allow_guests,
|
||||
};
|
||||
event.update(&pool, &user, &update).await;
|
||||
event.update(&pool, &user, &update).await.unwrap();
|
||||
assert!(Notification::for_user(&pool, &rower).await.is_empty());
|
||||
assert!(Notification::for_user(&pool, &cox.user).await.is_empty());
|
||||
|
||||
// Cancel event again
|
||||
event.update(&pool, &user, &cancel_update).await;
|
||||
event.update(&pool, &user, &cancel_update).await.unwrap();
|
||||
|
||||
// Rower is removed if notification is accepted
|
||||
assert!(event.is_rower_registered(&pool, &rower).await);
|
||||
|
||||
@@ -48,6 +48,7 @@ pub struct Registration {
|
||||
pub name: String,
|
||||
pub registered_at: String,
|
||||
pub is_guest: bool,
|
||||
pub is_newbie: bool,
|
||||
pub is_real_guest: bool,
|
||||
}
|
||||
|
||||
@@ -57,12 +58,13 @@ impl Registration {
|
||||
&format!(
|
||||
r#"
|
||||
SELECT
|
||||
(SELECT name FROM user WHERE user_trip.user_id = user.id) as "name?",
|
||||
(SELECT name FROM user WHERE user_trip.user_id = user.id) as "name?",
|
||||
user_note,
|
||||
user_id,
|
||||
(SELECT created_at FROM user WHERE user_trip.user_id = user.id) as registered_at,
|
||||
(SELECT EXISTS (SELECT 1 FROM user_role WHERE user_role.user_id = user_trip.user_id AND user_role.role_id = (SELECT id FROM role WHERE name = 'scheckbuch'))) as is_guest
|
||||
FROM user_trip WHERE trip_details_id = {}
|
||||
(SELECT EXISTS (SELECT 1 FROM user_role WHERE user_role.user_id = user_trip.user_id AND user_role.role_id = (SELECT id FROM role WHERE name = 'scheckbuch'))) as is_guest,
|
||||
(SELECT EXISTS (SELECT 1 FROM user_role WHERE user_role.user_id = user_trip.user_id AND user_role.role_id = (SELECT id FROM role WHERE name = 'Vereinsneuling'))) as is_newbie
|
||||
FROM user_trip WHERE trip_details_id = {}
|
||||
"#,trip_details_id),
|
||||
)
|
||||
.fetch_all(db)
|
||||
@@ -74,6 +76,7 @@ FROM user_trip WHERE trip_details_id = {}
|
||||
name: r.get::<Option<String>, usize>(0).or(r.get::<Option<String>, usize>(1)).unwrap(), //Ok, either name or user_note needs to be set
|
||||
registered_at: r.get::<String,usize>(3),
|
||||
is_guest: r.get::<bool, usize>(4),
|
||||
is_newbie: r.get::<bool, usize>(5),
|
||||
is_real_guest: r.get::<Option<i64>, usize>(2).is_none(),
|
||||
})
|
||||
.collect()
|
||||
@@ -98,6 +101,7 @@ FROM trip WHERE planned_event_id = ?
|
||||
name: r.name.unwrap(),
|
||||
registered_at: r.registered_at.unwrap(),
|
||||
is_guest: false,
|
||||
is_newbie: false,
|
||||
is_real_guest: false,
|
||||
})
|
||||
.collect() //Okay, as Event can only be created with proper DB backing
|
||||
@@ -113,6 +117,7 @@ pub struct EventUpdate<'a> {
|
||||
pub always_show: bool,
|
||||
pub is_locked: bool,
|
||||
pub trip_type_id: Option<i64>,
|
||||
pub allow_guests: bool,
|
||||
}
|
||||
|
||||
impl EventUpdate<'_> {
|
||||
@@ -318,7 +323,17 @@ WHERE trip_details.id=?
|
||||
}
|
||||
|
||||
//TODO: create unit test
|
||||
pub async fn update(&self, db: &SqlitePool, user: &EventUser, update: &EventUpdate<'_>) {
|
||||
pub async fn update(&self, db: &SqlitePool, user: &EventUser, update: &EventUpdate<'_>) -> Result<(), String> {
|
||||
let tripdetails = self.trip_details(db).await;
|
||||
let was_already_cancelled = tripdetails.cancelled();
|
||||
|
||||
if tripdetails.allow_guests && !update.allow_guests {
|
||||
let rowers = Registration::all_rower(db, self.trip_details_id).await;
|
||||
if rowers.iter().any(|r| r.is_newbie) {
|
||||
return Err("Es sind bereits Neulinge angemeldet — 'Neulinge willkommen' kann nicht deaktiviert werden.".into());
|
||||
}
|
||||
}
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE planned_event SET name = ?, planned_amount_cox = ? WHERE id = ?",
|
||||
update.name,
|
||||
@@ -329,16 +344,14 @@ WHERE trip_details.id=?
|
||||
.await
|
||||
.unwrap(); //Okay, as planned_event can only be created with proper DB backing
|
||||
|
||||
let tripdetails = self.trip_details(db).await;
|
||||
let was_already_cancelled = tripdetails.cancelled();
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE trip_details SET max_people = ?, notes = ?, always_show = ?, is_locked = ?, trip_type_id = ? WHERE id = ?",
|
||||
"UPDATE trip_details SET max_people = ?, notes = ?, always_show = ?, is_locked = ?, trip_type_id = ?, allow_guests = ? WHERE id = ?",
|
||||
update.max_people,
|
||||
update.notes,
|
||||
update.always_show,
|
||||
update.is_locked,
|
||||
update.trip_type_id,
|
||||
update.allow_guests,
|
||||
self.trip_details_id
|
||||
)
|
||||
.execute(db)
|
||||
@@ -426,6 +439,8 @@ WHERE trip_details.id=?
|
||||
.await;
|
||||
Notification::delete_by_action(db, &format!("remove_trip_by_event:{}", self.id)).await;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete(&self, db: &SqlitePool) -> Result<(), String> {
|
||||
|
||||
@@ -48,6 +48,7 @@ pub struct TripUpdate<'a> {
|
||||
pub notes: Option<&'a str>,
|
||||
pub trip_type: Option<i64>, //TODO: Move to `TripType`
|
||||
pub is_locked: bool,
|
||||
pub allow_guests: bool,
|
||||
}
|
||||
|
||||
impl TripUpdate<'_> {
|
||||
@@ -228,6 +229,13 @@ WHERE day=?
|
||||
let tripdetails = TripDetails::find_by_id(db, trip_details_id).await.unwrap();
|
||||
let was_already_cancelled = tripdetails.cancelled();
|
||||
|
||||
if tripdetails.allow_guests && !update.allow_guests {
|
||||
let rowers = Registration::all_rower(db, trip_details_id).await;
|
||||
if rowers.iter().any(|r| r.is_newbie) {
|
||||
return Err(TripUpdateError::NeulingAlreadyRegistered);
|
||||
}
|
||||
}
|
||||
|
||||
let is_locked = if update.cancelled() {
|
||||
false
|
||||
} else {
|
||||
@@ -235,11 +243,12 @@ WHERE day=?
|
||||
};
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ?, is_locked = ? WHERE id = ?",
|
||||
"UPDATE trip_details SET max_people = ?, notes = ?, trip_type_id = ?, is_locked = ?, allow_guests = ? WHERE id = ?",
|
||||
update.max_people,
|
||||
update.notes,
|
||||
update.trip_type,
|
||||
is_locked,
|
||||
update.allow_guests,
|
||||
trip_details_id
|
||||
)
|
||||
.execute(db)
|
||||
@@ -407,6 +416,7 @@ pub enum TripUpdateError {
|
||||
NotYourTrip,
|
||||
TripDetailsDoesNotExist,
|
||||
TripTypeNotAllowed,
|
||||
NeulingAlreadyRegistered,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -540,6 +550,7 @@ mod test {
|
||||
notes: None,
|
||||
trip_type: None,
|
||||
is_locked: false,
|
||||
allow_guests: false,
|
||||
};
|
||||
|
||||
assert!(Trip::update_own(&pool, &update).await.is_ok());
|
||||
@@ -568,6 +579,7 @@ mod test {
|
||||
notes: None,
|
||||
trip_type: Some(1),
|
||||
is_locked: false,
|
||||
allow_guests: false,
|
||||
};
|
||||
assert!(Trip::update_own(&pool, &update).await.is_ok());
|
||||
|
||||
@@ -596,6 +608,7 @@ mod test {
|
||||
notes: None,
|
||||
trip_type: None,
|
||||
is_locked: false,
|
||||
allow_guests: false,
|
||||
};
|
||||
assert!(Trip::update_own(&pool, &update).await.is_err());
|
||||
assert_eq!(trip.max_people, 1);
|
||||
|
||||
@@ -528,6 +528,17 @@ impl User {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn add_vereinsneuling(
|
||||
&self,
|
||||
db: &SqlitePool,
|
||||
updated_by: &ManageUserUser,
|
||||
) -> Result<(), String> {
|
||||
if let Some(vereinsneuling) = Role::find_by_name(db, "Vereinsneuling").await {
|
||||
self.add_role(db, updated_by, &vereinsneuling).await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn remove_membership_pdf(&self, db: &SqlitePool, updated_by: &ManageUserUser) {
|
||||
ActivityBuilder::new(&format!(
|
||||
"{updated_by} hat die Beitrittserklärung vom Beutzer gelöscht."
|
||||
|
||||
+10
-5
@@ -112,6 +112,7 @@ impl UserWithDetails {
|
||||
self.roles.contains(&"Donau Linz".into())
|
||||
|| self.roles.contains(&"Förderndes Mitglied".into())
|
||||
|| self.roles.contains(&"scheckbuch".into())
|
||||
|| self.roles.contains(&"Vereinsneuling".into())
|
||||
|| self.user.name == "Externe Steuerperson"
|
||||
}
|
||||
}
|
||||
@@ -598,18 +599,22 @@ ASKÖ Ruderverein Donau Linz", self.name),
|
||||
|
||||
pub async fn get_days(&self, db: &SqlitePool) -> Vec<Day> {
|
||||
let mut days = Vec::new();
|
||||
for i in 0..self.amount_days_to_show(db).await {
|
||||
let roles = self.roles(db).await;
|
||||
let is_beginner = roles.contains(&"scheckbuch".to_string())
|
||||
|| roles.contains(&"Vereinsneuling".to_string());
|
||||
let days_to_show = self.amount_days_to_show(db).await;
|
||||
for i in 0..days_to_show {
|
||||
let date = (Local::now() + chrono::Duration::days(i)).date_naive();
|
||||
|
||||
if self.has_role(db, "scheckbuch").await {
|
||||
if is_beginner {
|
||||
days.push(Day::new_guest(db, date, false).await);
|
||||
} else {
|
||||
days.push(Day::new(db, date, false).await);
|
||||
}
|
||||
}
|
||||
|
||||
for date in TripDetails::pinned_days(db, self.amount_days_to_show(db).await - 1).await {
|
||||
if self.has_role(db, "scheckbuch").await {
|
||||
for date in TripDetails::pinned_days(db, days_to_show - 1).await {
|
||||
if is_beginner {
|
||||
let day = Day::new_guest(db, date, true).await;
|
||||
if !day.events.is_empty() {
|
||||
days.push(day);
|
||||
@@ -868,7 +873,7 @@ special_user!(TechUser, +"tech");
|
||||
special_user!(ErgoUser, +"ergo");
|
||||
special_user!(SteeringUser, +"cox", +"Bootsführer");
|
||||
special_user!(AdminUser, +"admin");
|
||||
special_user!(AllowedForPlannedTripsUser, +"Donau Linz", +"scheckbuch", +"Förderndes Mitglied");
|
||||
special_user!(AllowedForPlannedTripsUser, +"Donau Linz", +"scheckbuch", +"Förderndes Mitglied", +"Vereinsneuling");
|
||||
special_user!(DonauLinzUser, +"Donau Linz", +"Förderndes Mitglied", -"Unterstützend"); // TODO:
|
||||
// remove ->
|
||||
// RegularUser
|
||||
|
||||
@@ -99,6 +99,7 @@ impl NoMembershipUser {
|
||||
|
||||
let regular = Role::find_by_name(db, "Donau Linz").await.unwrap();
|
||||
self.user.add_role(db, changed_by, ®ular).await?;
|
||||
self.user.add_vereinsneuling(db, changed_by).await?;
|
||||
|
||||
let regular = RegularUser::new(db, &self.user).await.unwrap();
|
||||
regular.send_welcome_mail_to_user(db, smtp_pw).await?;
|
||||
@@ -149,6 +150,7 @@ impl NoMembershipUser {
|
||||
|
||||
let unterstuetzend = Role::find_by_name(db, "Unterstützend").await.unwrap();
|
||||
self.user.add_role(db, changed_by, &unterstuetzend).await?;
|
||||
self.user.add_vereinsneuling(db, changed_by).await?;
|
||||
|
||||
let unterstuetzend = UnterstuetzendUser::new(db, &self.user).await.unwrap();
|
||||
unterstuetzend
|
||||
@@ -203,6 +205,7 @@ impl NoMembershipUser {
|
||||
|
||||
let foerdernd = Role::find_by_name(db, "Förderndes Mitglied").await.unwrap();
|
||||
self.user.add_role(db, changed_by, &foerdernd).await?;
|
||||
self.user.add_vereinsneuling(db, changed_by).await?;
|
||||
|
||||
let foerdernd = FoerderndUser::new(db, &self.user).await.unwrap();
|
||||
foerdernd.send_welcome_mail_to_user(db, smtp_pw).await?;
|
||||
|
||||
@@ -47,6 +47,7 @@ pub trait ClubMember {
|
||||
let user = User::find_by_name(db, name).await.unwrap();
|
||||
user.change_financial(db, created_by, financial).await?;
|
||||
user.add_role(db, created_by, role).await?;
|
||||
user.add_vereinsneuling(db, created_by).await?;
|
||||
|
||||
ActivityBuilder::new(&format!(
|
||||
"{created_by} hat Mitglied {user} mit der Rolle {role} angelegt."
|
||||
|
||||
@@ -68,6 +68,7 @@ impl ScheckbuchUser {
|
||||
let scheckbook = Role::find_by_name(db, "scheckbuch").await.unwrap();
|
||||
self.user.remove_role(db, changed_by, &scheckbook).await?;
|
||||
self.user.add_role(db, changed_by, ®ular).await?;
|
||||
self.user.add_vereinsneuling(db, changed_by).await?;
|
||||
|
||||
// Notify
|
||||
let regular = RegularUser::new(db, &self.user).await.unwrap();
|
||||
@@ -123,6 +124,7 @@ impl ScheckbuchUser {
|
||||
let scheckbook = Role::find_by_name(db, "scheckbuch").await.unwrap();
|
||||
self.user.remove_role(db, changed_by, &scheckbook).await?;
|
||||
self.user.add_role(db, changed_by, &unterstuetzend).await?;
|
||||
self.user.add_vereinsneuling(db, changed_by).await?;
|
||||
|
||||
let unterstuetzend = UnterstuetzendUser::new(db, &self.user).await.unwrap();
|
||||
unterstuetzend
|
||||
@@ -179,6 +181,7 @@ impl ScheckbuchUser {
|
||||
let scheckbook = Role::find_by_name(db, "scheckbuch").await.unwrap();
|
||||
self.user.remove_role(db, changed_by, &scheckbook).await?;
|
||||
self.user.add_role(db, changed_by, &unterstuetzend).await?;
|
||||
self.user.add_vereinsneuling(db, changed_by).await?;
|
||||
|
||||
let foerdernd = FoerderndUser::new(db, &self.user).await.unwrap();
|
||||
foerdernd.send_welcome_mail_to_user(db, smtp_pw).await?;
|
||||
|
||||
@@ -75,6 +75,7 @@ impl SchnupperantUser {
|
||||
|
||||
let regular = Role::find_by_name(db, "Donau Linz").await.unwrap();
|
||||
self.user.add_role(db, changed_by, ®ular).await?;
|
||||
self.user.add_vereinsneuling(db, changed_by).await?;
|
||||
|
||||
let participated_schnupperkurs = Role::find_by_name(db, "participated_schnupperkurs")
|
||||
.await
|
||||
@@ -224,6 +225,7 @@ impl SchnupperantUser {
|
||||
let scheckbook = Role::find_by_name(db, "schnupperant").await.unwrap();
|
||||
self.user.remove_role(db, changed_by, &scheckbook).await?;
|
||||
self.user.add_role(db, changed_by, &unterstuetzend).await?;
|
||||
self.user.add_vereinsneuling(db, changed_by).await?;
|
||||
if let Some(no_einschreibgebuehr) = Role::find_by_name(db, "no-einschreibgebuehr").await {
|
||||
self.add_role(db, changed_by, &no_einschreibgebuehr)
|
||||
.await
|
||||
@@ -293,6 +295,7 @@ impl SchnupperantUser {
|
||||
let scheckbook = Role::find_by_name(db, "schnupperant").await.unwrap();
|
||||
self.user.remove_role(db, changed_by, &scheckbook).await?;
|
||||
self.user.add_role(db, changed_by, &unterstuetzend).await?;
|
||||
self.user.add_vereinsneuling(db, changed_by).await?;
|
||||
if let Some(no_einschreibgebuehr) = Role::find_by_name(db, "no-einschreibgebuehr").await {
|
||||
self.add_role(db, changed_by, &no_einschreibgebuehr)
|
||||
.await
|
||||
|
||||
@@ -62,6 +62,7 @@ struct UpdateEventForm<'r> {
|
||||
always_show: bool,
|
||||
is_locked: bool,
|
||||
trip_type: Option<i64>,
|
||||
allow_guests: bool,
|
||||
}
|
||||
|
||||
#[put("/planned-event", data = "<data>")]
|
||||
@@ -78,12 +79,13 @@ async fn update(
|
||||
always_show: data.always_show,
|
||||
is_locked: data.is_locked,
|
||||
trip_type_id: data.trip_type,
|
||||
allow_guests: data.allow_guests,
|
||||
};
|
||||
match Event::find_by_id(db, data.id).await {
|
||||
Some(planned_event) => {
|
||||
planned_event.update(db, &user, &update).await;
|
||||
Flash::success(Redirect::to("/planned"), "Event erfolgreich bearbeitet")
|
||||
}
|
||||
Some(planned_event) => match planned_event.update(db, &user, &update).await {
|
||||
Ok(_) => Flash::success(Redirect::to("/planned"), "Event erfolgreich bearbeitet"),
|
||||
Err(e) => Flash::error(Redirect::to("/planned"), e),
|
||||
},
|
||||
None => Flash::error(Redirect::to("/planned"), "Planned event id not found"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ struct EditTripForm<'r> {
|
||||
notes: Option<&'r str>,
|
||||
trip_type: Option<i64>,
|
||||
is_locked: bool,
|
||||
allow_guests: bool,
|
||||
}
|
||||
|
||||
#[post("/trip/<trip_id>", data = "<data>")]
|
||||
@@ -69,6 +70,7 @@ async fn update(
|
||||
notes: data.notes,
|
||||
trip_type: data.trip_type,
|
||||
is_locked: data.is_locked,
|
||||
allow_guests: data.allow_guests,
|
||||
};
|
||||
match Trip::update_own(db, &update).await {
|
||||
Ok(_) => Flash::success(
|
||||
@@ -85,6 +87,10 @@ async fn update(
|
||||
Err(TripUpdateError::TripDetailsDoesNotExist) => {
|
||||
Flash::error(Redirect::to("/planned"), "Ausfahrt gibt's nicht")
|
||||
}
|
||||
Err(TripUpdateError::NeulingAlreadyRegistered) => Flash::error(
|
||||
Redirect::to("/planned"),
|
||||
"Es sind bereits Neulinge angemeldet — 'Neulinge willkommen' kann nicht deaktiviert werden.",
|
||||
),
|
||||
}
|
||||
} else {
|
||||
Flash::error(Redirect::to("/planned"), "Ausfahrt gibt's nicht")
|
||||
|
||||
Reference in New Issue
Block a user