Phase 4: SEPA-Validierung (schwifty), Globale Suche (Cmd+K) & Jahresbericht-Modul
- SEPA-Export: IBAN/BIC-Validierung via schwifty, Schuldner-Konto aus StiftungsKonto - Globale Suche: Cmd+K Modal über Destinatäre, Pächter, Ländereien, Förderungen, Dokumente - Jahresbericht: Vollständige Jahresbilanz mit Einnahmen/Ausgaben/Netto, Unterstützungen, Landabrechnungen, Verwaltungskosten nach Kategorie, PDF-Export Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -86,29 +86,86 @@ def bericht_list(request):
|
||||
return render(request, "stiftung/bericht_list.html", context)
|
||||
|
||||
|
||||
@login_required
|
||||
def jahresbericht_generate(request, jahr):
|
||||
"""Generate annual report for a specific year"""
|
||||
# Get data for the year
|
||||
foerderungen = Foerderung.objects.filter(jahr=jahr).select_related("person")
|
||||
verpachtungen = LandVerpachtung.objects.filter(
|
||||
pachtbeginn__year__lte=jahr, pachtende__year__gte=jahr
|
||||
).select_related("land", "paechter")
|
||||
|
||||
# Calculate statistics
|
||||
total_foerderungen = foerderungen.aggregate(total=Sum("betrag"))["total"] or 0
|
||||
total_pachtzins = (
|
||||
verpachtungen.aggregate(total=Sum("pachtzins_pauschal"))["total"] or 0
|
||||
def _jahresbericht_context(jahr):
|
||||
"""Phase 4: Aggregiert alle Daten für den Jahresbericht."""
|
||||
from stiftung.models import (
|
||||
DestinataerUnterstuetzung, LandAbrechnung, Verwaltungskosten,
|
||||
)
|
||||
|
||||
context = {
|
||||
# Förderungen (legacy)
|
||||
foerderungen = Foerderung.objects.filter(jahr=jahr).select_related("destinataer", "person")
|
||||
total_foerderungen_legacy = foerderungen.aggregate(total=Sum("betrag"))["total"] or 0
|
||||
|
||||
# Unterstützungen (Phase 2 – neue Pipeline)
|
||||
unterstuetzungen = DestinataerUnterstuetzung.objects.filter(
|
||||
faellig_am__year=jahr
|
||||
).exclude(status="storniert").select_related("destinataer", "konto")
|
||||
unterstuetzungen_ausgezahlt = unterstuetzungen.filter(
|
||||
status__in=["ausgezahlt", "abgeschlossen"]
|
||||
)
|
||||
total_unterstuetzungen = unterstuetzungen_ausgezahlt.aggregate(total=Sum("betrag"))["total"] or 0
|
||||
|
||||
# Gesamtausgaben Förderung
|
||||
total_ausgaben_foerderung = total_foerderungen_legacy + total_unterstuetzungen
|
||||
|
||||
# Verpachtungen
|
||||
verpachtungen = LandVerpachtung.objects.filter(
|
||||
pachtbeginn__year__lte=jahr
|
||||
).filter(
|
||||
Q(pachtende__isnull=True) | Q(pachtende__year__gte=jahr)
|
||||
).select_related("land", "paechter")
|
||||
total_pachtzins = verpachtungen.aggregate(total=Sum("pachtzins_pauschal"))["total"] or 0
|
||||
|
||||
# Landabrechnungen für das Jahr
|
||||
landabrechnungen = LandAbrechnung.objects.filter(
|
||||
abrechnungsjahr=jahr
|
||||
).select_related("land")
|
||||
pacht_vereinnahmt = landabrechnungen.aggregate(total=Sum("pacht_vereinnahmt"))["total"] or 0
|
||||
grundsteuer_gesamt = landabrechnungen.aggregate(total=Sum("grundsteuer_betrag"))["total"] or 0
|
||||
|
||||
# Verwaltungskosten
|
||||
verwaltungskosten_qs = Verwaltungskosten.objects.filter(datum__year=jahr)
|
||||
total_verwaltungskosten = verwaltungskosten_qs.aggregate(total=Sum("betrag"))["total"] or 0
|
||||
verwaltungskosten_nach_kategorie = (
|
||||
verwaltungskosten_qs
|
||||
.values("kategorie")
|
||||
.annotate(summe=Sum("betrag"), anzahl=Count("id"))
|
||||
.order_by("-summe")
|
||||
)
|
||||
|
||||
# Gesamtbilanz
|
||||
total_einnahmen = pacht_vereinnahmt if pacht_vereinnahmt else total_pachtzins
|
||||
total_ausgaben = total_ausgaben_foerderung + total_verwaltungskosten
|
||||
netto = total_einnahmen - total_ausgaben
|
||||
|
||||
return {
|
||||
"jahr": jahr,
|
||||
"foerderungen": foerderungen,
|
||||
"verpachtungen": verpachtungen,
|
||||
"total_foerderungen": total_foerderungen,
|
||||
"total_pachtzins": total_pachtzins,
|
||||
"title": f"Jahresbericht {jahr}",
|
||||
"foerderungen": foerderungen,
|
||||
"total_foerderungen_legacy": total_foerderungen_legacy,
|
||||
"unterstuetzungen": unterstuetzungen,
|
||||
"unterstuetzungen_ausgezahlt": unterstuetzungen_ausgezahlt,
|
||||
"total_unterstuetzungen": total_unterstuetzungen,
|
||||
"total_ausgaben_foerderung": total_ausgaben_foerderung,
|
||||
"verpachtungen": verpachtungen,
|
||||
"total_pachtzins": total_pachtzins,
|
||||
"landabrechnungen": landabrechnungen,
|
||||
"pacht_vereinnahmt": pacht_vereinnahmt,
|
||||
"grundsteuer_gesamt": grundsteuer_gesamt,
|
||||
"verwaltungskosten_nach_kategorie": verwaltungskosten_nach_kategorie,
|
||||
"total_verwaltungskosten": total_verwaltungskosten,
|
||||
"total_einnahmen": total_einnahmen,
|
||||
"total_ausgaben": total_ausgaben,
|
||||
"netto": netto,
|
||||
# Rückwärtskompatibilität
|
||||
"total_foerderungen": total_ausgaben_foerderung,
|
||||
}
|
||||
|
||||
|
||||
@login_required
|
||||
def jahresbericht_generate(request, jahr):
|
||||
"""Phase 4: Jahresbericht mit aggregierten Finanzdaten."""
|
||||
context = _jahresbericht_context(jahr)
|
||||
return render(request, "stiftung/jahresbericht.html", context)
|
||||
|
||||
|
||||
@@ -124,30 +181,12 @@ def jahresbericht_generate_redirect(request):
|
||||
|
||||
@login_required
|
||||
def jahresbericht_pdf(request, jahr):
|
||||
"""Generate PDF version of annual report"""
|
||||
"""Phase 4: PDF-Export des Jahresberichts."""
|
||||
from django.http import HttpResponse
|
||||
from django.template.loader import render_to_string
|
||||
from weasyprint import HTML
|
||||
|
||||
# Get data for the year
|
||||
foerderungen = Foerderung.objects.filter(jahr=jahr).select_related("person")
|
||||
verpachtungen = LandVerpachtung.objects.filter(
|
||||
pachtbeginn__year__lte=jahr, pachtende__year__gte=jahr
|
||||
).select_related("land", "paechter")
|
||||
|
||||
# Calculate statistics
|
||||
total_foerderungen = foerderungen.aggregate(total=Sum("betrag"))["total"] or 0
|
||||
total_pachtzins = (
|
||||
verpachtungen.aggregate(total=Sum("pachtzins_pauschal"))["total"] or 0
|
||||
)
|
||||
|
||||
context = {
|
||||
"jahr": jahr,
|
||||
"foerderungen": foerderungen,
|
||||
"verpachtungen": verpachtungen,
|
||||
"total_foerderungen": total_foerderungen,
|
||||
"total_pachtzins": total_pachtzins,
|
||||
}
|
||||
context = _jahresbericht_context(jahr)
|
||||
|
||||
# Render HTML
|
||||
html_string = render_to_string("stiftung/jahresbericht.html", context)
|
||||
|
||||
Reference in New Issue
Block a user