125 lines
3.7 KiB
Python
125 lines
3.7 KiB
Python
"""Generate the 3 fictitious PWG scan PDFs used by the pilot demo.
|
|
|
|
Run: python _generateScans.py
|
|
|
|
Produces:
|
|
scans/mieter01-bestaetigt.pdf -> all fields ok, signed
|
|
scans/mieter02-abweichung-betrag.pdf -> rent on scan != journal lines
|
|
scans/mieter03-keine-unterschrift.pdf -> hasSignature=false
|
|
"""
|
|
from pathlib import Path
|
|
|
|
from reportlab.lib.pagesizes import A4
|
|
from reportlab.pdfgen import canvas
|
|
|
|
|
|
def _renderForm(outPath: Path, *, tenantName: str, tenantAddress: str,
|
|
objectAddress: str, period: str, rentChf: float,
|
|
tenantNotes: str, hasSignature: bool) -> None:
|
|
c = canvas.Canvas(str(outPath), pagesize=A4)
|
|
w, h = A4
|
|
margin = 60
|
|
y = h - margin
|
|
|
|
c.setFont("Helvetica-Bold", 16)
|
|
c.drawString(margin, y, "Stiftung PWG")
|
|
y -= 18
|
|
c.setFont("Helvetica", 10)
|
|
c.drawString(margin, y, "Postfach 1234 · 8000 Zürich")
|
|
y -= 30
|
|
|
|
c.setFont("Helvetica-Bold", 14)
|
|
c.drawString(margin, y, f"Jahresmietzinsbestätigung {period}")
|
|
y -= 28
|
|
|
|
c.setFont("Helvetica", 11)
|
|
c.drawString(margin, y, "Sehr geehrte Damen und Herren,")
|
|
y -= 18
|
|
c.drawString(margin, y, "hiermit bestätige ich die nachstehenden Angaben für die o.g. Periode:")
|
|
y -= 28
|
|
|
|
rows = [
|
|
("Mieter / in:", tenantName),
|
|
("Wohnadresse:", tenantAddress),
|
|
("Mietobjekt:", objectAddress),
|
|
("Periode:", period),
|
|
("Bestätigter Mietzins (CHF, monatlich):", f"{rentChf:.2f}"),
|
|
("Anmerkungen:", tenantNotes or "(keine)"),
|
|
]
|
|
c.setFont("Helvetica", 11)
|
|
for lab, val in rows:
|
|
c.drawString(margin, y, lab)
|
|
c.drawString(margin + 220, y, str(val))
|
|
y -= 18
|
|
y -= 28
|
|
|
|
c.drawString(margin, y, "Ort, Datum: Zürich, 12.04.2026")
|
|
y -= 28
|
|
c.drawString(margin, y, "Unterschrift Mieter / in:")
|
|
y -= 36
|
|
|
|
if hasSignature:
|
|
c.setFont("Helvetica-Oblique", 14)
|
|
c.drawString(margin + 220, y + 24, _signatureFor(tenantName))
|
|
else:
|
|
c.setFont("Helvetica", 9)
|
|
c.drawString(margin + 220, y + 24, "(handschriftlich)")
|
|
c.line(margin + 215, y + 22, margin + 415, y + 22)
|
|
|
|
c.showPage()
|
|
c.save()
|
|
|
|
|
|
def _signatureFor(name: str) -> str:
|
|
parts = name.split()
|
|
if not parts:
|
|
return "____"
|
|
return parts[0][0] + ". " + parts[-1]
|
|
|
|
|
|
def _main() -> None:
|
|
here = Path(__file__).resolve().parent
|
|
outDir = here / "scans"
|
|
outDir.mkdir(parents=True, exist_ok=True)
|
|
|
|
# 1) bestätigt — exakt passend zu seed (Anna Müller, 1850.00)
|
|
_renderForm(
|
|
outDir / "mieter01-bestaetigt.pdf",
|
|
tenantName="Anna Müller",
|
|
tenantAddress="Bahnhofstrasse 12, 8001 Zürich",
|
|
objectAddress="Bahnhofstrasse 12, 3.OG, 8001 Zürich",
|
|
period="2026",
|
|
rentChf=1850.00,
|
|
tenantNotes="",
|
|
hasSignature=True,
|
|
)
|
|
|
|
# 2) abweichung_betrag — Mieter trägt 2300 ein, Buchhaltung sagt 2200
|
|
_renderForm(
|
|
outDir / "mieter02-abweichung-betrag.pdf",
|
|
tenantName="Beat Schneider",
|
|
tenantAddress="Limmatquai 45, 8001 Zürich",
|
|
objectAddress="Limmatquai 45, 1.OG, 8001 Zürich",
|
|
period="2026",
|
|
rentChf=2300.00,
|
|
tenantNotes="Mietzins gemäss letzter Indexanpassung — bitte prüfen.",
|
|
hasSignature=True,
|
|
)
|
|
|
|
# 3) keine_unterschrift — Carla Weber, 1650 stimmt, aber nicht unterschrieben
|
|
_renderForm(
|
|
outDir / "mieter03-keine-unterschrift.pdf",
|
|
tenantName="Carla Weber",
|
|
tenantAddress="Seestrasse 88, 8002 Zürich",
|
|
objectAddress="Seestrasse 88, EG, 8002 Zürich",
|
|
period="2026",
|
|
rentChf=1650.00,
|
|
tenantNotes="",
|
|
hasSignature=False,
|
|
)
|
|
|
|
print(f"Generated 3 scans in {outDir}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
_main()
|