Merge branch 'staging' into notification
This commit is contained in:
@ -17,22 +17,52 @@ pub struct Boathouse {
|
||||
}
|
||||
|
||||
impl Boathouse {
|
||||
pub async fn get(db: &SqlitePool) -> HashMap<&str, HashMap<&str, [Option<(i64, Boat)>; 4]>> {
|
||||
let mut ret: HashMap<&str, HashMap<&str, [Option<(i64, Boat)>; 4]>> = HashMap::new();
|
||||
pub async fn get(db: &SqlitePool) -> HashMap<&str, HashMap<&str, [Option<(i64, Boat)>; 12]>> {
|
||||
let mut ret: HashMap<&str, HashMap<&str, [Option<(i64, Boat)>; 12]>> = HashMap::new();
|
||||
|
||||
let mut mountain = HashMap::new();
|
||||
mountain.insert("mountain", [None, None, None, None]);
|
||||
mountain.insert("water", [None, None, None, None]);
|
||||
mountain.insert(
|
||||
"mountain",
|
||||
[
|
||||
None, None, None, None, None, None, None, None, None, None, None, None,
|
||||
],
|
||||
);
|
||||
mountain.insert(
|
||||
"water",
|
||||
[
|
||||
None, None, None, None, None, None, None, None, None, None, None, None,
|
||||
],
|
||||
);
|
||||
ret.insert("mountain-aisle", mountain);
|
||||
|
||||
let mut middle = HashMap::new();
|
||||
middle.insert("mountain", [None, None, None, None]);
|
||||
middle.insert("water", [None, None, None, None]);
|
||||
middle.insert(
|
||||
"mountain",
|
||||
[
|
||||
None, None, None, None, None, None, None, None, None, None, None, None,
|
||||
],
|
||||
);
|
||||
middle.insert(
|
||||
"water",
|
||||
[
|
||||
None, None, None, None, None, None, None, None, None, None, None, None,
|
||||
],
|
||||
);
|
||||
ret.insert("middle-aisle", middle);
|
||||
|
||||
let mut water = HashMap::new();
|
||||
water.insert("mountain", [None, None, None, None]);
|
||||
water.insert("water", [None, None, None, None]);
|
||||
water.insert(
|
||||
"mountain",
|
||||
[
|
||||
None, None, None, None, None, None, None, None, None, None, None, None,
|
||||
],
|
||||
);
|
||||
water.insert(
|
||||
"water",
|
||||
[
|
||||
None, None, None, None, None, None, None, None, None, None, None, None,
|
||||
],
|
||||
);
|
||||
ret.insert("water-aisle", water);
|
||||
|
||||
let boathouses = sqlx::query_as!(
|
||||
|
@ -472,7 +472,7 @@ ORDER BY departure DESC
|
||||
mut log: LogToFinalize,
|
||||
) -> Result<(), LogbookUpdateError> {
|
||||
//TODO: extract common tests with `create()`
|
||||
if user.id != self.shipmaster {
|
||||
if !user.has_role_tx(db, "Vorstand").await && user.id != self.shipmaster {
|
||||
return Err(LogbookUpdateError::NotYourEntry);
|
||||
}
|
||||
|
||||
@ -549,7 +549,10 @@ ORDER BY departure DESC
|
||||
pub async fn delete(&self, db: &SqlitePool, user: &User) -> Result<(), LogbookDeleteError> {
|
||||
Log::create(db, format!("{user:?} deleted trip: {self:?}")).await;
|
||||
|
||||
if user.has_role(db, "admin").await || user.id == self.shipmaster {
|
||||
if user.has_role(db, "admin").await
|
||||
|| user.has_role(db, "Vorstand").await
|
||||
|| user.id == self.shipmaster
|
||||
{
|
||||
sqlx::query!("DELETE FROM logbook WHERE id=?", self.id)
|
||||
.execute(db)
|
||||
.await
|
||||
|
@ -182,4 +182,116 @@ Der Vorstand
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn fees_final(db: &SqlitePool, smtp_pw: String) {
|
||||
let users = User::all_payer_groups(db).await;
|
||||
for user in users {
|
||||
if let Some(fee) = user.fee(db).await {
|
||||
if !fee.paid {
|
||||
let mut is_family = false;
|
||||
let mut send_to = String::new();
|
||||
match Family::find_by_opt_id(db, user.family_id).await {
|
||||
Some(family) => {
|
||||
is_family = true;
|
||||
for member in family.members(db).await {
|
||||
if let Some(mail) = member.mail {
|
||||
send_to.push_str(&format!("{mail},"))
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
if let Some(mail) = &user.mail {
|
||||
send_to.push_str(mail)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let fees = user.fee(db).await;
|
||||
if let Some(fees) = fees {
|
||||
let mut content = format!(
|
||||
"Liebes Vereinsmitglied, \n\n\
|
||||
wir möchten darauf hinweisen, dass wir deinen Mitgliedsbeitrag für das laufende Jahr bislang nicht verbuchen konnten. Es besteht die Möglichkeit, dass es sich hierbei um ein Versehen unsererseits handelt. Solltest du den Betrag bereits überwiesen haben, bitte kurz auf diese E-Mail antworten, damit wir es richtigstellen können.
|
||||
|
||||
Falls die Zahlung noch nicht erfolgt ist, bitten wir um umgehende Überweisung des ausstehenden Betrags, spätestens jedoch bis zum 31. März, auf unser Bankkonto.\n\n\
|
||||
Dein Vereinsbeitrag für das aktuelle Jahr beträgt {}€",
|
||||
fees.sum_in_cents / 100,
|
||||
);
|
||||
|
||||
if fees.parts.len() == 1 {
|
||||
content.push_str(&format!(" ({}).\n", fees.parts[0].0))
|
||||
} else {
|
||||
content
|
||||
.push_str(". Dieser setzt sich aus folgenden Teilen zusammen: \n");
|
||||
for (desc, fee_in_cents) in fees.parts {
|
||||
content.push_str(&format!("- {}: {}€\n", desc, fee_in_cents / 100))
|
||||
}
|
||||
}
|
||||
if is_family {
|
||||
content.push_str(&format!(
|
||||
"Dieser gilt für die gesamte Familie ({}).\n",
|
||||
fees.name
|
||||
))
|
||||
}
|
||||
content.push_str("\n\
|
||||
Gemäß § 7 Abs. 3 lit. c unseres Status behalten wir uns vor, bei ausbleibender Zahlung die Mitgliedschaft zu beenden. Dies möchten wir vermeiden und hoffen auf deine Unterstützung.\n\n\
|
||||
Bei Fragen oder Problemen stehen wir gerne zur Verfügung.
|
||||
|
||||
Bankverbindung: IBAN: AT13 1200 0804 1300 1200 (Unter https://app.rudernlinz.at/planned findest du einen QR Code, den du mit deiner Bankapp scannen kannst um alle Eingaben bereits ausgefüllt zu haben.)
|
||||
|
||||
Mit freundlichen Grüßen,\n\
|
||||
Der Vorstand");
|
||||
let mut email = Message::builder()
|
||||
.from(
|
||||
"ASKÖ Ruderverein Donau Linz <no-reply@rudernlinz.at>"
|
||||
.parse()
|
||||
.unwrap(),
|
||||
)
|
||||
.reply_to(
|
||||
"ASKÖ Ruderverein Donau Linz <it@rudernlinz.at>"
|
||||
.parse()
|
||||
.unwrap(),
|
||||
)
|
||||
.to("ASKÖ Ruderverein Donau Linz <no-reply@rudernlinz.at>"
|
||||
.parse()
|
||||
.unwrap());
|
||||
let splitted = send_to.split(',');
|
||||
let mut send_mail = false;
|
||||
for single_rec in splitted {
|
||||
let single_rec = single_rec.trim();
|
||||
match single_rec.parse() {
|
||||
Ok(val) => {
|
||||
email = email.bcc(val);
|
||||
send_mail = true;
|
||||
}
|
||||
Err(_) => {
|
||||
println!("Error in mail: {single_rec}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if send_mail {
|
||||
let email = email
|
||||
.subject("Mahnung Vereinsgebühren | ASKÖ Ruderverein Donau Linz")
|
||||
.header(ContentType::TEXT_PLAIN)
|
||||
.body(content)
|
||||
.unwrap();
|
||||
|
||||
let creds = Credentials::new(
|
||||
"no-reply@rudernlinz.at".to_owned(),
|
||||
smtp_pw.clone(),
|
||||
);
|
||||
|
||||
let mailer = SmtpTransport::relay("mail.your-server.de")
|
||||
.unwrap()
|
||||
.credentials(creds)
|
||||
.build();
|
||||
|
||||
// Send the email
|
||||
mailer.send(&email).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,7 +73,8 @@ WHERE u.id NOT IN (
|
||||
WHERE ro.name = 'Donau Linz'
|
||||
)
|
||||
AND l.distance_in_km IS NOT NULL
|
||||
AND l.arrival LIKE '{year}-%';
|
||||
AND l.arrival LIKE '{year}-%'
|
||||
AND u.name != 'Externe Steuerperson';
|
||||
"
|
||||
))
|
||||
.fetch_one(db)
|
||||
@ -87,6 +88,16 @@ AND l.arrival LIKE '{year}-%';
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn sum_people(db: &SqlitePool, year: Option<i32>) -> i32 {
|
||||
let stats = Self::people(db, year).await;
|
||||
let mut sum = 0;
|
||||
for stat in stats {
|
||||
sum += stat.rowed_km;
|
||||
}
|
||||
|
||||
sum
|
||||
}
|
||||
|
||||
pub async fn people(db: &SqlitePool, year: Option<i32>) -> Vec<Stat> {
|
||||
let year = match year {
|
||||
Some(year) => year,
|
||||
|
@ -25,7 +25,7 @@ const REGULAR: i32 = 22000;
|
||||
const UNTERSTUETZEND: i32 = 2500;
|
||||
const FOERDERND: i32 = 8500;
|
||||
|
||||
#[derive(FromRow, Debug, Serialize, Deserialize)]
|
||||
#[derive(FromRow, Debug, Serialize, Deserialize, Clone)]
|
||||
pub struct User {
|
||||
pub id: i64,
|
||||
pub name: String,
|
||||
@ -106,6 +106,7 @@ pub struct Fee {
|
||||
pub name: String,
|
||||
pub user_ids: String,
|
||||
pub paid: bool,
|
||||
pub users: Vec<User>,
|
||||
}
|
||||
|
||||
impl Default for Fee {
|
||||
@ -121,6 +122,7 @@ impl Fee {
|
||||
name: "".into(),
|
||||
parts: Vec::new(),
|
||||
user_ids: "".into(),
|
||||
users: Vec::new(),
|
||||
paid: false,
|
||||
}
|
||||
}
|
||||
@ -139,6 +141,7 @@ impl Fee {
|
||||
self.name.push_str(&user.name);
|
||||
|
||||
self.user_ids.push_str(&format!("user_ids[]={}", user.id));
|
||||
self.users.push(user.clone());
|
||||
}
|
||||
|
||||
pub fn paid(&mut self) {
|
||||
@ -509,6 +512,8 @@ ORDER BY last_access DESC
|
||||
if ![
|
||||
"n-sageder",
|
||||
"p-hofer",
|
||||
"daniel-kortschak",
|
||||
"rudernlinz",
|
||||
"m-birner",
|
||||
"s-sollberger",
|
||||
"d-kortschak",
|
||||
|
Reference in New Issue
Block a user