Enhancements
This commit is contained in:
@@ -0,0 +1,202 @@
|
||||
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}")
|
||||
Reference in New Issue
Block a user