reflect new fee structure
This commit is contained in:
		@@ -23,6 +23,9 @@ pub(crate) const UNTERSTUETZEND: i64 = 2500;
 | 
			
		||||
pub(crate) const FOERDERND: i64 = 8500;
 | 
			
		||||
pub(crate) const SCHECKBUCH: i64 = 3000;
 | 
			
		||||
pub(crate) const EINSCHREIBGEBUEHR: i64 = 3000;
 | 
			
		||||
pub(crate) const DUAL_MEMBERSHIP: i64 = 18000;
 | 
			
		||||
pub(crate) const TRIAL_ROWING: i64 = 12000;
 | 
			
		||||
pub(crate) const TRIAL_ROWING_REDUCED: i64 = 6000;
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
			
		||||
pub struct NonEmptyString(String);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
use std::{error::Error, fs};
 | 
			
		||||
 | 
			
		||||
use lettre::{
 | 
			
		||||
    Address, Message, SmtpTransport, Transport,
 | 
			
		||||
    message::{Attachment, MultiPart, SinglePart, header::ContentType},
 | 
			
		||||
    message::{header::ContentType, Attachment, MultiPart, SinglePart},
 | 
			
		||||
    transport::smtp::authentication::Credentials,
 | 
			
		||||
    Address, Message, SmtpTransport, Transport,
 | 
			
		||||
};
 | 
			
		||||
use sqlx::{Sqlite, SqlitePool, Transaction};
 | 
			
		||||
 | 
			
		||||
@@ -161,6 +161,11 @@ impl Mail {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if user.has_role(db, "schnupperant").await {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if !user.has_role(db, "paid").await || test.is_some() {
 | 
			
		||||
                let mut is_family = false;
 | 
			
		||||
                let mut send_to = String::new();
 | 
			
		||||
@@ -273,6 +278,11 @@ Der Vorstand");
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if user.has_role(db, "schnupperant").await {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if let Some(fee) = user.fee(db).await {
 | 
			
		||||
                if !fee.paid || test.is_some() {
 | 
			
		||||
                    let mut is_family = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -519,6 +519,15 @@ impl User {
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub(crate) async fn remove_membership_pdf(&self, db: &SqlitePool, updated_by: &ManageUserUser) {
 | 
			
		||||
        sqlx::query!(
 | 
			
		||||
            "UPDATE user SET membership_pdf = null where id = ?",
 | 
			
		||||
            self.id
 | 
			
		||||
        )
 | 
			
		||||
        .execute(db)
 | 
			
		||||
        .await
 | 
			
		||||
        .unwrap(); //Okay, because we can only create a User of a valid id
 | 
			
		||||
    }
 | 
			
		||||
    pub(crate) async fn add_membership_pdf(
 | 
			
		||||
        &self,
 | 
			
		||||
        db: &SqlitePool,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,8 @@
 | 
			
		||||
use super::User;
 | 
			
		||||
use crate::{
 | 
			
		||||
    BOAT_STORAGE, EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE, FAMILY_TWO, FOERDERND, REGULAR,
 | 
			
		||||
    RENNRUDERBEITRAG, STUDENT_OR_PUPIL, UNTERSTUETZEND, model::family::Family,
 | 
			
		||||
    model::family::Family, BOAT_STORAGE, DUAL_MEMBERSHIP, EINSCHREIBGEBUEHR, FAMILY_THREE_OR_MORE,
 | 
			
		||||
    FAMILY_TWO, FOERDERND, REGULAR, RENNRUDERBEITRAG, STUDENT_OR_PUPIL, TRIAL_ROWING,
 | 
			
		||||
    TRIAL_ROWING_REDUCED, UNTERSTUETZEND,
 | 
			
		||||
};
 | 
			
		||||
use chrono::{Datelike, Local, NaiveDate};
 | 
			
		||||
use serde::Serialize;
 | 
			
		||||
@@ -68,6 +69,7 @@ impl User {
 | 
			
		||||
        if !self.has_role(db, "Donau Linz").await
 | 
			
		||||
            && !self.has_role(db, "Unterstützend").await
 | 
			
		||||
            && !self.has_role(db, "Förderndes Mitglied").await
 | 
			
		||||
            && !self.has_role(db, "schnupperant").await
 | 
			
		||||
        {
 | 
			
		||||
            return None;
 | 
			
		||||
        }
 | 
			
		||||
@@ -107,6 +109,7 @@ impl User {
 | 
			
		||||
        if !self.has_role(db, "Donau Linz").await
 | 
			
		||||
            && !self.has_role(db, "Unterstützend").await
 | 
			
		||||
            && !self.has_role(db, "Förderndes Mitglied").await
 | 
			
		||||
            && !self.has_role(db, "schnupperant").await
 | 
			
		||||
        {
 | 
			
		||||
            return fee;
 | 
			
		||||
        }
 | 
			
		||||
@@ -126,13 +129,16 @@ impl User {
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if let Some(member_since_date) = &self.member_since_date {
 | 
			
		||||
            if let Ok(member_since_date) = NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d")
 | 
			
		||||
            {
 | 
			
		||||
                if member_since_date.year() == Local::now().year()
 | 
			
		||||
                    && !self.has_role(db, "no-einschreibgebuehr").await
 | 
			
		||||
        if !self.has_role(db, "schnupperant").await {
 | 
			
		||||
            if let Some(member_since_date) = &self.member_since_date {
 | 
			
		||||
                if let Ok(member_since_date) =
 | 
			
		||||
                    NaiveDate::parse_from_str(member_since_date, "%Y-%m-%d")
 | 
			
		||||
                {
 | 
			
		||||
                    fee.add("Einschreibgebühr".into(), EINSCHREIBGEBUEHR);
 | 
			
		||||
                    if member_since_date.year() == Local::now().year()
 | 
			
		||||
                        && !self.has_role(db, "no-einschreibgebuehr").await
 | 
			
		||||
                    {
 | 
			
		||||
                        fee.add("Einschreibgebühr".into(), EINSCHREIBGEBUEHR);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -150,7 +156,13 @@ impl User {
 | 
			
		||||
            false
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        if self.has_role(db, "Unterstützend").await {
 | 
			
		||||
        if self.has_role(db, "schnupperant").await {
 | 
			
		||||
            if self.has_role(db, "Student").await || self.has_role(db, "Schüler").await {
 | 
			
		||||
                fee.add("Schnupperkurs (reduziert)".into(), TRIAL_ROWING_REDUCED);
 | 
			
		||||
            } else {
 | 
			
		||||
                fee.add("Schnupperkurs".into(), TRIAL_ROWING);
 | 
			
		||||
            }
 | 
			
		||||
        } else if self.has_role(db, "Unterstützend").await {
 | 
			
		||||
            fee.add("Unterstützendes Mitglied".into(), UNTERSTUETZEND);
 | 
			
		||||
        } else if self.has_role(db, "Förderndes Mitglied").await {
 | 
			
		||||
            fee.add("Förderndes Mitglied".into(), FOERDERND);
 | 
			
		||||
@@ -163,6 +175,18 @@ impl User {
 | 
			
		||||
                }
 | 
			
		||||
            } else if self.has_role(db, "Ehrenmitglied").await {
 | 
			
		||||
                fee.add("Ehrenmitglied".into(), 0);
 | 
			
		||||
            } else if self.has_role(db, "dual_membership").await {
 | 
			
		||||
                if halfprice {
 | 
			
		||||
                    fee.add(
 | 
			
		||||
                        "Doppelmitgliedschaft mit anderem österr. Ruderverein (Halbpreis)".into(),
 | 
			
		||||
                        DUAL_MEMBERSHIP / 2,
 | 
			
		||||
                    );
 | 
			
		||||
                } else {
 | 
			
		||||
                    fee.add(
 | 
			
		||||
                        "Doppelmitgliedschaft mit anderem österr. Ruderverein".into(),
 | 
			
		||||
                        DUAL_MEMBERSHIP,
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            } else if halfprice {
 | 
			
		||||
                fee.add("Mitgliedsbeitrag (Halbpreis)".into(), REGULAR / 2);
 | 
			
		||||
            } else {
 | 
			
		||||
@@ -170,6 +194,19 @@ impl User {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if !self.has_role(db, "schnupperant").await
 | 
			
		||||
            && self.has_role(db, "participated_schnupperkurs").await
 | 
			
		||||
        {
 | 
			
		||||
            if self.has_role(db, "Student").await || self.has_role(db, "Schüler").await {
 | 
			
		||||
                fee.add(
 | 
			
		||||
                    "Anrechnung reduzierter Schnupperkurs".into(),
 | 
			
		||||
                    -TRIAL_ROWING_REDUCED,
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                fee.add("Anrechnung Schnupperkurs".into(), -TRIAL_ROWING);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        fee
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
use super::{ManageUserUser, User};
 | 
			
		||||
use crate::{
 | 
			
		||||
    NonEmptyString,
 | 
			
		||||
    model::{activity::ActivityBuilder, mail::Mail, notification::Notification, role::Role},
 | 
			
		||||
    special_user,
 | 
			
		||||
    special_user, NonEmptyString,
 | 
			
		||||
};
 | 
			
		||||
use chrono::NaiveDate;
 | 
			
		||||
use rocket::{async_trait, fs::TempFile, tokio::io::AsyncReadExt};
 | 
			
		||||
@@ -93,6 +92,8 @@ Beim nächsten Treffen im Verein, erinnere jemand vom Vorstand (https://rudernli
 | 
			
		||||
 | 
			
		||||
Damit du dich noch mehr verbunden fühlst (:-)), haben wir im Bootshaus ein WLAN für Vereinsmitglieder 'ASKÖ Ruderverein Donau Linz' eingerichtet. Das Passwort dafür lautet 'donau1921' (ohne Anführungszeichen). Bitte gib das Passwort an keine vereinsfremden Personen weiter.
 | 
			
		||||
 | 
			
		||||
Falls du deinen Mitgliedsbeitrag noch nicht bezahlt hast, erledige dies bitte demnächst. Den genauen Betrag und einen QR Code, den du mit deiner Bankapp scannen kannst findest du unter https://app.rudernlinz.at/planned
 | 
			
		||||
 | 
			
		||||
Wir freuen uns darauf, dich bald am Wasser zu sehen und gemeinsam tolle Erfahrungen zu sammeln!
 | 
			
		||||
 | 
			
		||||
Riemen- & Dollenbruch
 | 
			
		||||
 
 | 
			
		||||
@@ -4,9 +4,9 @@ use super::scheckbuch::ScheckbuchUser;
 | 
			
		||||
use super::schnupperinterest::SchnupperInterestUser;
 | 
			
		||||
use super::unterstuetzend::UnterstuetzendUser;
 | 
			
		||||
use super::{ManageUserUser, User};
 | 
			
		||||
use crate::NonEmptyString;
 | 
			
		||||
use crate::model::activity::ActivityBuilder;
 | 
			
		||||
use crate::model::role::Role;
 | 
			
		||||
use crate::NonEmptyString;
 | 
			
		||||
use crate::{
 | 
			
		||||
    model::{mail::Mail, notification::Notification},
 | 
			
		||||
    special_user,
 | 
			
		||||
@@ -65,20 +65,32 @@ impl SchnupperantUser {
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
        // Change roles
 | 
			
		||||
        let regular = Role::find_by_name(db, "Donau Linz").await.unwrap();
 | 
			
		||||
        let paid = Role::find_by_name(db, "paid").await.unwrap();
 | 
			
		||||
        if self.user.remove_role(db, changed_by, &paid).await.is_err() {
 | 
			
		||||
            self.remove_membership_pdf(db, changed_by).await;
 | 
			
		||||
            return Err("Kann noch kein normales Mitglied werden, da die Schnupperkurs-Gebühr noch nicht bezahlt wurde.".into());
 | 
			
		||||
        }
 | 
			
		||||
        let scheckbook = Role::find_by_name(db, "schnupperant").await.unwrap();
 | 
			
		||||
        self.user.remove_role(db, changed_by, &scheckbook).await?;
 | 
			
		||||
 | 
			
		||||
        let regular = Role::find_by_name(db, "Donau Linz").await.unwrap();
 | 
			
		||||
        self.user.add_role(db, changed_by, ®ular).await?;
 | 
			
		||||
 | 
			
		||||
        let participated_schnupperkurs = Role::find_by_name(db, "participated_schnupperkurs")
 | 
			
		||||
            .await
 | 
			
		||||
            .unwrap();
 | 
			
		||||
        self.user
 | 
			
		||||
            .add_role(db, changed_by, &participated_schnupperkurs)
 | 
			
		||||
            .await?;
 | 
			
		||||
 | 
			
		||||
        // Notify
 | 
			
		||||
        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, {} nahm an unserem Schnupperkurs teil und ist nun seit {} ein neues reguläres Mitglied. 🎉",
 | 
			
		||||
                self.name,
 | 
			
		||||
                self.member_since_date.clone().unwrap()
 | 
			
		||||
                "Liebe Steuerberechtigte, {} nahm an unserem Schnupperkurs teil und ist nun seit {member_since} ein neues reguläres Mitglied. 🎉",
 | 
			
		||||
                self.name
 | 
			
		||||
            ),
 | 
			
		||||
            "Neues Vereinsmitglied",
 | 
			
		||||
            None,
 | 
			
		||||
@@ -203,6 +215,11 @@ impl SchnupperantUser {
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
        // Change roles
 | 
			
		||||
        let paid = Role::find_by_name(db, "paid").await.unwrap();
 | 
			
		||||
        if self.user.remove_role(db, changed_by, &paid).await.is_err() {
 | 
			
		||||
            self.remove_membership_pdf(db, changed_by).await;
 | 
			
		||||
            return Err("Kann noch kein normales Mitglied werden, da die Schnupperkurs-Gebühr noch nicht bezahlt wurde.".into());
 | 
			
		||||
        }
 | 
			
		||||
        let unterstuetzend = Role::find_by_name(db, "Unterstützend").await.unwrap();
 | 
			
		||||
        let scheckbook = Role::find_by_name(db, "schnupperant").await.unwrap();
 | 
			
		||||
        self.user.remove_role(db, changed_by, &scheckbook).await?;
 | 
			
		||||
@@ -267,6 +284,11 @@ impl SchnupperantUser {
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
        // Change roles
 | 
			
		||||
        let paid = Role::find_by_name(db, "paid").await.unwrap();
 | 
			
		||||
        if self.user.remove_role(db, changed_by, &paid).await.is_err() {
 | 
			
		||||
            self.remove_membership_pdf(db, changed_by).await;
 | 
			
		||||
            return Err("Kann noch kein normales Mitglied werden, da die Schnupperkurs-Gebühr noch nicht bezahlt wurde.".into());
 | 
			
		||||
        }
 | 
			
		||||
        let unterstuetzend = Role::find_by_name(db, "Förderndes Mitglied").await.unwrap();
 | 
			
		||||
        let scheckbook = Role::find_by_name(db, "schnupperant").await.unwrap();
 | 
			
		||||
        self.user.remove_role(db, changed_by, &scheckbook).await?;
 | 
			
		||||
@@ -307,7 +329,7 @@ impl SchnupperantUser {
 | 
			
		||||
 | 
			
		||||
    // TODO: make private
 | 
			
		||||
    pub(crate) async fn notify(&self, db: &SqlitePool, smtp_pw: &str) -> Result<(), String> {
 | 
			
		||||
        self.notify_coxes_about_new_scheckbuch(db).await;
 | 
			
		||||
        self.notify_coxes_about_new_schnupperant(db).await;
 | 
			
		||||
        self.send_welcome_mail_to_user(db, smtp_pw).await?;
 | 
			
		||||
 | 
			
		||||
        ActivityBuilder::new(&format!(
 | 
			
		||||
@@ -335,19 +357,27 @@ impl SchnupperantUser {
 | 
			
		||||
            mail,
 | 
			
		||||
            "ASKÖ Ruderverein Donau Linz | Anmeldung Schnupperkurs",
 | 
			
		||||
            format!(
 | 
			
		||||
"Hallo {0},
 | 
			
		||||
                "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.
 | 
			
		||||
es freut uns sehr, dich bei unserem Schnupperkurs willkommen heißen zu dürfen.
 | 
			
		||||
 | 
			
		||||
Bitte überweise die {1} € auf unser Bankkonto (IBAN: AT58 2032 0321 0072 9256) und gib beim Verwendungszweck 'Schnupperkurs {0}' an.
 | 
			
		||||
 | 
			
		||||
Detaillierte Informationen folgen noch, du wirst sie ein paar Tage vor dem Termin bekommen (wenn das Wetter/Wasserstand/... abschätzbar ist).
 | 
			
		||||
 | 
			
		||||
Riemen- & Dollenbruch,
 | 
			
		||||
ASKÖ Ruderverein Donau Linz", self.name),
 | 
			
		||||
ASKÖ Ruderverein Donau Linz",
 | 
			
		||||
                self.name,
 | 
			
		||||
                self.fee(db).await.unwrap().sum_in_cents/100
 | 
			
		||||
            ),
 | 
			
		||||
            smtp_pw,
 | 
			
		||||
        ).await?;
 | 
			
		||||
        )
 | 
			
		||||
        .await?;
 | 
			
		||||
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    async fn notify_coxes_about_new_scheckbuch(&self, db: &SqlitePool) {
 | 
			
		||||
    async fn notify_coxes_about_new_schnupperant(&self, db: &SqlitePool) {
 | 
			
		||||
        if let Some(role) = Role::find_by_name(db, "schnupper-betreuer").await {
 | 
			
		||||
            Notification::create_for_role(
 | 
			
		||||
                db,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,44 +5,5 @@ INSERT INTO user(name) VALUES('Philipp');
 | 
			
		||||
INSERT INTO "user_role" (user_id, role_id) VALUES((SELECT id from user where name = 'Philipp'),(SELECT id FROM role where name = 'Donau Linz'));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- Step 1: Create a new table without the 'notes' column
 | 
			
		||||
CREATE TABLE "user_new" (
 | 
			
		||||
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
 | 
			
		||||
    "name" text NOT NULL UNIQUE,
 | 
			
		||||
    "pw" text, 
 | 
			
		||||
    "deleted" boolean NOT NULL DEFAULT FALSE,
 | 
			
		||||
    "last_access" DATETIME,
 | 
			
		||||
    "dob" text,
 | 
			
		||||
    "weight" text,
 | 
			
		||||
    "sex" text,
 | 
			
		||||
    "dirty_thirty" text,
 | 
			
		||||
    "dirty_dozen" text,
 | 
			
		||||
    "member_since_date" text,
 | 
			
		||||
    "birthdate" text,
 | 
			
		||||
    "mail" text,
 | 
			
		||||
    "nickname" text,
 | 
			
		||||
    "phone" text,
 | 
			
		||||
    "address" text,
 | 
			
		||||
    "family_id" INTEGER REFERENCES family(id),
 | 
			
		||||
    "membership_pdf" BLOB,
 | 
			
		||||
    "user_token" TEXT NOT NULL DEFAULT (lower(hex(randomblob(16))))
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
-- Step 2: Copy data from the old table to the new one (excluding 'notes')
 | 
			
		||||
INSERT INTO user_new (
 | 
			
		||||
    id, name, pw, deleted, last_access, dob, weight, sex, 
 | 
			
		||||
    dirty_thirty, dirty_dozen, member_since_date, birthdate, 
 | 
			
		||||
    mail, nickname, phone, address, family_id, membership_pdf, user_token
 | 
			
		||||
)
 | 
			
		||||
SELECT 
 | 
			
		||||
    id, name, pw, deleted, last_access, dob, weight, sex, 
 | 
			
		||||
    dirty_thirty, dirty_dozen, member_since_date, birthdate, 
 | 
			
		||||
    mail, nickname, phone, address, family_id, membership_pdf, user_token
 | 
			
		||||
FROM user;
 | 
			
		||||
 | 
			
		||||
-- Step 3: Drop the old table
 | 
			
		||||
DROP TABLE user;
 | 
			
		||||
 | 
			
		||||
-- Step 4: Rename the new table to the original name
 | 
			
		||||
ALTER TABLE user_new RENAME TO user;
 | 
			
		||||
 | 
			
		||||
insert into role(name, cluster, formatted_name) values('dual_membership', 'financial', 'Doppelmitgliedschaft mit anderem österr. Ruderverein');
 | 
			
		||||
insert into role(name, hide_in_lists) values('participated_schnupperkurs', true);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user