use std::error::Error; use lettre::{ message::header::ContentType, transport::smtp::authentication::Credentials, Message, SmtpTransport, Transport, }; use sqlx::SqlitePool; use crate::tera::admin::mail::MailToSend; use super::{family::Family, log::Log, role::Role, user::User}; pub struct Mail {} impl Mail { pub async fn send(db: &SqlitePool, data: MailToSend, smtp_pw: String) -> bool { let mut email = Message::builder() .from( "ASKÖ Ruderverein Donau Linz " .parse() .unwrap(), ) .reply_to( "ASKÖ Ruderverein Donau Linz " .parse() .unwrap(), ) .to("ASKÖ Ruderverein Donau Linz " .parse() .unwrap()); let role = Role::find_by_id(db, data.role_id).await.unwrap(); for rec in role.mails_from_role(db).await { let splitted = rec.split(','); for single_rec in splitted { match single_rec.parse() { Ok(new_bcc_mail) => email = email.bcc(new_bcc_mail), Err(_) => { Log::create( db, format!("Mail not sent to {rec}, because it could not be parsed"), ) .await; } } } } // TODO: handle attachments let email = email .subject(data.subject) .header(ContentType::TEXT_PLAIN) .body(String::from(data.body)) .unwrap(); let creds = Credentials::new("no-reply@rudernlinz.at".to_owned(), smtp_pw); let mailer = SmtpTransport::relay("mail.your-server.de") .unwrap() .credentials(creds) .build(); // Send the email match mailer.send(&email) { Ok(_) => return true, Err(e) => println!("{:?}", e.source()), }; false } pub async fn fees(db: &SqlitePool, smtp_pw: String) { let users = User::all_payer_groups(db).await; for user in users { if !user.has_role(db, "paid").await { 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\ 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("\nBitte überweise diesen auf folgendes Konto: IBAN: AT13 1200 0804 1300 1200. Auf 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.\n\n\ Falls die Berechnung nicht stimmt (korrekte Preise findest du unter https://rudernlinz.at/unser-verein/gebuhren/) melde dich bitte bei it@rudernlinz.at. @Studenten: Bitte die aktuelle Studienbestätigung an it@rudernlinz.at schicken.\n\n\ Wenn du die Vereinsgebühren schon bezahlt hast, kannst du diese Mail einfach ignorieren.\n\n Beste Grüße\n\ Der Vorstand "); let mut email = Message::builder() .from( "ASKÖ Ruderverein Donau Linz " .parse() .unwrap(), ) .reply_to( "ASKÖ Ruderverein Donau Linz " .parse() .unwrap(), ) .to("ASKÖ Ruderverein Donau Linz " .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("ASKÖ Ruderverein Donau Linz | Vereinsgebühren") .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(); } } } } } }