202 lines
7.3 KiB
Python
202 lines
7.3 KiB
Python
import models.models as models
|
|
from reportlab.lib.pagesizes import A4
|
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak
|
|
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
|
|
from reportlab.lib.units import mm
|
|
from reportlab.lib import colors
|
|
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
|
|
from segno import helpers
|
|
from payment_report import get_payment_table_element
|
|
import datetime
|
|
import locale
|
|
import os
|
|
from config_loader import load_config
|
|
from salutation_helpers import get_gender_salutation, get_pronouns
|
|
|
|
cfg = load_config()
|
|
year = cfg['year']
|
|
yearly_fee = cfg['yearly_fee']
|
|
|
|
MM_TO_POINTS = 72 / 25.4
|
|
offset_2mm = 2 * MM_TO_POINTS
|
|
offset_1mm = MM_TO_POINTS
|
|
|
|
def create_payment_slip(member: models.Members = None,
|
|
forMail: bool = False):
|
|
|
|
locale.setlocale(locale.LC_ALL, '')
|
|
|
|
w, h = A4
|
|
|
|
# Create EPC QR code
|
|
if not member is None:
|
|
qrcode = helpers.make_epc_qr(
|
|
name='Sportunion St. Thomas',
|
|
iban='AT493443700000113407',
|
|
amount=yearly_fee * member.member_count,
|
|
reference=f'{year}-4732-{member.id:03}-{member.member_count}'
|
|
)
|
|
qrcode.save("epc_qr.png", scale=2)
|
|
|
|
subfolder = "mail" if member.member_email else ""
|
|
fullfilepath = os.path.join(
|
|
os.path.expanduser("~"),
|
|
"sust",
|
|
f"payment_slips_{year}",
|
|
subfolder,
|
|
f"{member.member_zip}_payment_slip_member{member.id}.pdf"
|
|
)
|
|
else:
|
|
fullfilepath = os.path.join(
|
|
os.path.expanduser("~"),
|
|
"sust",
|
|
f"payment_slips_{year}",
|
|
"",
|
|
f"4732_payment_slip_blanko.pdf"
|
|
)
|
|
|
|
os.makedirs(os.path.dirname(fullfilepath), exist_ok=True)
|
|
|
|
# Create PDF with Platypus
|
|
doc = SimpleDocTemplate(fullfilepath, pagesize=A4, topMargin=15*mm, bottomMargin=15*mm)
|
|
elements = []
|
|
styles = getSampleStyleSheet()
|
|
|
|
# Custom styles
|
|
header_style = ParagraphStyle(
|
|
'CustomHeader',
|
|
parent=styles['Normal'],
|
|
fontSize=11,
|
|
leading=14
|
|
)
|
|
|
|
body_style = ParagraphStyle(
|
|
'CustomBody',
|
|
parent=styles['Normal'],
|
|
fontSize=9,
|
|
leading=12
|
|
)
|
|
|
|
small_style = ParagraphStyle(
|
|
'CustomSmall',
|
|
parent=styles['Normal'],
|
|
fontSize=7,
|
|
leading=9
|
|
)
|
|
|
|
# Logo and header
|
|
image_path = os.path.join(os.path.dirname(__file__), "Sportunion quer 4c.png")
|
|
from reportlab.platypus import Image
|
|
logo = Image(image_path, width=150*mm/25.4, height=50*mm/25.4)
|
|
elements.append(logo)
|
|
elements.append(Spacer(1, 5*mm))
|
|
|
|
# Address and salutation
|
|
if not member is None:
|
|
if member.member_count > 1:
|
|
address_line1 = f"{member.member_firstname_spouse} u. {member.member_firstname} {member.member_surname}"
|
|
else:
|
|
address_line1 = f"{member.member_firstname} {member.member_surname} {member.member_suffix}"
|
|
|
|
address_text = f"""
|
|
{address_line1}<br/>
|
|
{member.member_street} {member.member_streetnumber}<br/>
|
|
{member.member_zip} {member.member_city}
|
|
"""
|
|
elements.append(Paragraph(address_text, header_style))
|
|
elements.append(Spacer(1, 5*mm))
|
|
|
|
# Salutation
|
|
if member.member_count > 1:
|
|
spouse_salutation = get_gender_salutation(str(member.spouse.member_gender), capitalize=False)
|
|
member_salutation = get_gender_salutation(str(member.member_gender), capitalize=False)
|
|
salutation_text = f"{spouse_salutation.capitalize()} {member.spouse.member_firstname} und {member_salutation} {member.member_firstname}!"
|
|
pronouns = get_pronouns(is_plural=True)
|
|
salutation = pronouns['possessive']
|
|
salutation2 = pronouns['neutral']
|
|
salutation3 = pronouns['accusative']
|
|
salutation4 = pronouns['conditional']
|
|
salutation5 = pronouns['verb']
|
|
else:
|
|
member_salutation = get_gender_salutation(str(member.member_gender), capitalize=True)
|
|
salutation_text = f"{member_salutation} {member.member_firstname}!"
|
|
pronouns = get_pronouns(is_plural=False)
|
|
salutation = pronouns['possessive']
|
|
salutation2 = pronouns['neutral']
|
|
salutation3 = pronouns['accusative']
|
|
salutation4 = pronouns['conditional']
|
|
salutation5 = pronouns['verb']
|
|
|
|
elements.append(Paragraph(salutation_text, body_style))
|
|
elements.append(Spacer(1, 3*mm))
|
|
|
|
# Main text
|
|
main_text = f"""
|
|
Vielen Dank für {salutation} Treue!<br/><br/>
|
|
{salutation2.capitalize()} Beitrag ist gut angelegt, denn der Sportverein St. Thomas bietet für jede(n) etwas:<br/>
|
|
<br/>
|
|
• Skigymnastik<br/>
|
|
• Radfahren<br/>
|
|
• Stockschiessen<br/>
|
|
• Pilates<br/>
|
|
• Tagesskifahrt<br/>
|
|
• uvam
|
|
"""
|
|
elements.append(Paragraph(main_text, body_style))
|
|
elements.append(Spacer(1, 3*mm))
|
|
|
|
# Email request
|
|
if not forMail:
|
|
email_text = f"""
|
|
Wir möchten das Zustellen des Mitgliedsbeitrags-Zahlscheines zuküntig auf Mail umstellen,
|
|
daher bitten wir {salutation3}, uns eine Mail mit dem Betreff "Zahlschein" an unsere
|
|
Mail-Adresse sv.stthomas@gmx.at zu senden!
|
|
"""
|
|
elements.append(Paragraph(email_text, body_style))
|
|
|
|
elements.append(Spacer(1, 3*mm))
|
|
|
|
closing_text = f"{salutation2.capitalize()} Sportverein-Team!"
|
|
elements.append(Paragraph(closing_text, body_style))
|
|
|
|
# GDPR disclaimer
|
|
elements.append(Spacer(1, 5*mm))
|
|
gdpr_text = f"""
|
|
Auf Grund der DSGVO müssen wir darauf hinweisen, dass wir außer Name, Adresse, Mail-Adresse
|
|
zum Zwecke der Einebung des Mitgliedsbeitrags, keine persönlichen Daten unserer Mitglieder führen!
|
|
Diese Daten werden von uns nicht an Dritte weitergegeben!
|
|
Weiters informieren wir darüber, dass Fotos, die bei Veranstaltungen oder Aktivitäten entstehen,
|
|
auf unserer Homepage oder in Zeitungen veröffentlicht werden können.
|
|
{salutation4} gegen die Speicherung {salutation}r Daten oder die Veröffentlichung diverser Foto sein, {salutation5} uns bitte eine Mail.
|
|
"""
|
|
elements.append(Paragraph(gdpr_text, small_style))
|
|
|
|
# Payment details table (right aligned)
|
|
if not member is None:
|
|
amount = locale.format_string('%.2f', yearly_fee * member.member_count)
|
|
member_number = f"4732-{member.id:03}"
|
|
payment_reference = f"{year}-4732-{member.id:03}-{member.member_count}"
|
|
|
|
payment_details = f"""
|
|
<b>Beitrag gesamt:</b> {amount}<br/>
|
|
<b>Mitgliedsnummer:</b> {member_number}<br/>
|
|
<b>Zahlungsreferenz:</b> {payment_reference}<br/>
|
|
"""
|
|
|
|
elements.append(Spacer(1, 5*mm))
|
|
elements.append(Paragraph(payment_details, body_style))
|
|
|
|
# Page break before payment table
|
|
elements.append(PageBreak())
|
|
|
|
# Add payment summary table
|
|
# payment_table = get_payment_table_element()
|
|
# if payment_table:
|
|
# elements.append(Paragraph("Zahlungsübersicht", styles['Heading2']))
|
|
# elements.append(Spacer(1, 5*mm))
|
|
# elements.append(payment_table)
|
|
|
|
# Build PDF
|
|
doc.build(elements)
|
|
|
|
print(f"✅ Payment slip created: {fullfilepath}") |