from sqlalchemy import extract from models.database import engine, SessionLocal import models.models as models import logging, sys import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.application import MIMEApplication from os.path import exists import datetime from create_payment_slip import create_payment_slip import os from config_loader import load_config import argparse from salutation_helpers import get_gender_salutation, get_pronouns cfg = load_config() year = cfg['year'] # Parse CLI arguments parser = argparse.ArgumentParser(description='Send payment slip emails to members') parser.add_argument('--resend', action='store_true', help='Send email again even if already mailed') args = parser.parse_args() logging.basicConfig(stream=sys.stderr, level=logging.DEBUG) def payment_slip_delivered(member: models.Members, year: int): return db.query(models.Deliveries.delivery_date)\ .filter(models.Deliveries.member_id == member.id, extract('year', models.Deliveries.delivery_date) == year)\ .count() def payment_slip_paid(member: models.Members, year: int): return db.query(models.Payments.payment_year)\ .filter(models.Payments.member_id == member.id, extract('year', models.Payments.payment_year) == year)\ .count() def send_mail(member: models.Members, force_resend: bool = False): paid = payment_slip_paid(member, year) if paid: logging.debug(f'Member: {member.member_surname} already paid!') return delivered = payment_slip_delivered(member, year) if delivered and not force_resend: logging.debug(f'Member: {member.member_surname} already mailed or delivered!') return smtp_server = 'mail.gmx.com' smtp_port = 587 smtp_username = 'zisco@gmx.at' #TODO Secure smtp_password = '[Jy010]Q&7te2qR&2x0d' from_email = 'sv.stthomas@gmx.at' to_email = member.member_email subject = f'Mitgliedsbeitrag {year}' is_plural = bool(member.member_count > 1) pronouns = get_pronouns(is_plural=is_plural) salutation = pronouns['possessive'] salutation2 = pronouns['neutral'] salutation3 = pronouns['accusative'] salutation4 = pronouns['conditional'] salutation5 = pronouns['verb'] # Get spouse's salutation based on their gender if is_plural and member.spouse: spouse_salutation = get_gender_salutation(str(member.spouse.member_gender), capitalize=False) member_salutation = get_gender_salutation(str(member.member_gender), capitalize=False) combined_salutation = f"{spouse_salutation.capitalize()} {member.spouse.member_firstname} und {member_salutation} {member.member_firstname}" else: combined_salutation = f"{get_gender_salutation(str(member.member_gender), capitalize=True)} {member.member_firstname}" body = f"{combined_salutation},\n\n{salutation2} Zahlschein für {year} liegt bei.\n\nBitte mittels auf beiliegendem Zahlschein aufgedrucktem QR-Code überweisen.\nDanke sagt Dein Team vom Sportverein!" msg = MIMEMultipart() msg['From'] = from_email msg['To'] = to_email msg['Subject'] = subject msg.attach(MIMEText(body)) path_to_file = os.path.join(os.path.expanduser("~"),"sust",f"payment_slips_{year}","mail",f"{member.member_zip}_payment_slip_member{member.id}.pdf") if not exists(path_to_file): create_payment_slip(member=member, forMail=True) with open(path_to_file, 'rb') as f: attachment = MIMEApplication(f.read(), _subtype='pdf') attachment.add_header('Content-Disposition', 'attachment', filename=f'{member.member_zip}_payment_slip_member{member.id}.pdf') msg.attach(attachment) with smtplib.SMTP(smtp_server, smtp_port) as smtp: smtp.starttls() smtp.login(smtp_username, smtp_password) # smtp.send_message(msg) # Send to recipient AND BCC to sender (so it appears in sent folder) recipients = [to_email, from_email] # Add from_email as BCC smtp.sendmail(from_email, recipients, msg.as_string()) newDelivery = models.Deliveries(delivery_date = datetime.datetime.now(), member_id = member.id, delivered_by_id = 186, delivery_year = datetime.date.today()) db.add(newDelivery) db.commit() logging.debug(f'Sent mail to {member.member_email}') db = SessionLocal() models.Base.metadata.create_all(bind=engine) members = db.query(models.Members).filter( models.Members.member_active == True, models.Members.member_email != None, models.Members.member_primary == True ).all() #members = db.query(models.Members).filter(models.Members.member_email != None, ~models.Members.id.in_([183,51,200,49])).all() #members = db.query(models.Members).filter(models.Members.member_active == True).all() #members = db.query(models.Members).filter(models.Members.id.in_([2,3,9,199]), models.Members.member_active == True, models.Members.member_printed == False).all() members = db.query(models.Members).filter(models.Members.id.in_([77])).all() for member in members: if member.member_email: send_mail(member=member, force_resend=args.resend) else: logging.debug(f'Member {member.member_surname} has no email associated!')