- forms.py → forms/ Package (8 Domänen: destinataere, land, finanzen, foerderung, dokumente, veranstaltung, system, geschichte) - admin.py → admin/ Package (7 Domänen, alle 22 @admin.register dekoriert) - views.py (8845 Zeilen) → views/ Package (10 Domänen: dashboard, destinataere, land, paechter, finanzen, foerderung, dokumente, unterstuetzungen, veranstaltung, geschichte, system) - __init__.py in jedem Package re-exportiert alle Symbole für Rückwärtskompatibilität - urls.py bleibt unverändert (funktioniert durch Re-Exports) - Django system check: 0 Fehler, alle URL-Auflösungen funktionieren Keine funktionalen Änderungen – reine Strukturverbesserung für Vision 2026. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
179 lines
5.4 KiB
Python
179 lines
5.4 KiB
Python
from django.contrib import admin
|
||
from django.urls import reverse
|
||
from django.utils.html import format_html
|
||
|
||
from ..models import Destinataer, DestinataerEmailEingang, DestinataerUnterstuetzung
|
||
|
||
|
||
@admin.register(Destinataer)
|
||
class DestinataerAdmin(admin.ModelAdmin):
|
||
list_display = [
|
||
"nachname",
|
||
"vorname",
|
||
"familienzweig",
|
||
"berufsgruppe",
|
||
"institution",
|
||
"finanzielle_notlage",
|
||
"aktiv",
|
||
]
|
||
list_filter = ["familienzweig", "berufsgruppe", "finanzielle_notlage", "aktiv"]
|
||
search_fields = ["nachname", "vorname", "email", "institution", "familienzweig"]
|
||
ordering = ["nachname", "vorname"]
|
||
readonly_fields = ["id"]
|
||
|
||
fieldsets = (
|
||
(
|
||
"Persönliche Daten",
|
||
{"fields": ("vorname", "nachname", "geburtsdatum", "email", "telefon")},
|
||
),
|
||
(
|
||
"Berufliche Informationen",
|
||
{"fields": ("berufsgruppe", "ausbildungsstand", "institution")},
|
||
),
|
||
(
|
||
"Projekt & Finanzen",
|
||
{
|
||
"fields": (
|
||
"projekt_beschreibung",
|
||
"jaehrliches_einkommen",
|
||
"finanzielle_notlage",
|
||
)
|
||
},
|
||
),
|
||
(
|
||
"Stiftungsdaten",
|
||
{"fields": ("familienzweig", "iban", "strasse", "plz", "ort")},
|
||
),
|
||
("Zusätzlich", {"fields": ("notizen", "aktiv")}),
|
||
("System", {"fields": ("id",), "classes": ("collapse",)}),
|
||
)
|
||
|
||
def iban_display(self, obj):
|
||
if obj.iban:
|
||
return format_html(
|
||
'<span style="font-family: monospace;">{}</span>', obj.iban
|
||
)
|
||
return "-"
|
||
|
||
iban_display.short_description = "IBAN"
|
||
|
||
|
||
@admin.register(DestinataerUnterstuetzung)
|
||
class DestinataerUnterstuetzungAdmin(admin.ModelAdmin):
|
||
list_display = [
|
||
"__str__",
|
||
"destinataer",
|
||
"betrag",
|
||
"faellig_am",
|
||
"status",
|
||
"wiederkehrend_von",
|
||
"ausgezahlt_am",
|
||
]
|
||
list_filter = ["status", "faellig_am", "erstellt_am", "konto"]
|
||
search_fields = [
|
||
"destinataer__vorname",
|
||
"destinataer__nachname",
|
||
"beschreibung",
|
||
"empfaenger_name",
|
||
]
|
||
readonly_fields = ["id", "erstellt_am", "aktualisiert_am"]
|
||
|
||
fieldsets = (
|
||
(
|
||
"Grundinformationen",
|
||
{
|
||
"fields": (
|
||
"destinataer",
|
||
"konto",
|
||
"betrag",
|
||
"faellig_am",
|
||
"status",
|
||
"beschreibung",
|
||
)
|
||
},
|
||
),
|
||
(
|
||
"Überweisungsdaten",
|
||
{"fields": ("empfaenger_iban", "empfaenger_name", "verwendungszweck")},
|
||
),
|
||
("Zahlungsinformationen", {"fields": ("ausgezahlt_am", "ausgezahlt_von")}),
|
||
("Wiederkehrend", {"fields": ("wiederkehrend_von",)}),
|
||
(
|
||
"Metadaten",
|
||
{
|
||
"fields": ("id", "erstellt_am", "aktualisiert_am"),
|
||
"classes": ("collapse",),
|
||
},
|
||
),
|
||
)
|
||
|
||
|
||
@admin.register(DestinataerEmailEingang)
|
||
class DestinataerEmailEingangAdmin(admin.ModelAdmin):
|
||
list_display = [
|
||
"eingangsdatum",
|
||
"absender_email",
|
||
"absender_name",
|
||
"destinataer_link",
|
||
"betreff_kurz",
|
||
"anzahl_anhaenge",
|
||
"status",
|
||
"created_at",
|
||
]
|
||
list_filter = ["status", "eingangsdatum"]
|
||
search_fields = [
|
||
"absender_email",
|
||
"absender_name",
|
||
"betreff",
|
||
"destinataer__vorname",
|
||
"destinataer__nachname",
|
||
]
|
||
readonly_fields = ["created_at", "absender_email", "absender_name", "eingangsdatum",
|
||
"email_text", "paperless_dokument_ids", "fehler_details"]
|
||
raw_id_fields = ["destinataer", "quartalsnachweis"]
|
||
date_hierarchy = "eingangsdatum"
|
||
ordering = ["-eingangsdatum"]
|
||
|
||
fieldsets = [
|
||
("E-Mail-Metadaten", {
|
||
"fields": ["eingangsdatum", "absender_name", "absender_email", "betreff"],
|
||
}),
|
||
("Zuordnung", {
|
||
"fields": ["destinataer", "status", "quartalsnachweis"],
|
||
}),
|
||
("Inhalt & Anhänge", {
|
||
"fields": ["email_text", "paperless_dokument_ids"],
|
||
}),
|
||
("Notizen & Fehler", {
|
||
"fields": ["notizen", "fehler_details"],
|
||
"classes": ["collapse"],
|
||
}),
|
||
("System", {
|
||
"fields": ["created_at"],
|
||
"classes": ["collapse"],
|
||
}),
|
||
]
|
||
|
||
def destinataer_link(self, obj):
|
||
if obj.destinataer:
|
||
url = reverse("admin:stiftung_destinataer_change", args=[obj.destinataer.pk])
|
||
return format_html('<a href="{}">{}</a>', url, obj.destinataer)
|
||
return format_html('<span style="color:red;">–</span>')
|
||
destinataer_link.short_description = "Destinatär"
|
||
|
||
def betreff_kurz(self, obj):
|
||
return (obj.betreff or "")[:60]
|
||
betreff_kurz.short_description = "Betreff"
|
||
|
||
def anzahl_anhaenge(self, obj):
|
||
n = len(obj.paperless_dokument_ids or [])
|
||
return n if n else "–"
|
||
anzahl_anhaenge.short_description = "Anhänge"
|
||
|
||
actions = ["mark_verarbeitet"]
|
||
|
||
def mark_verarbeitet(self, request, queryset):
|
||
updated = queryset.filter(status__in=["neu", "zugewiesen"]).update(status="verarbeitet")
|
||
self.message_user(request, f"{updated} E-Mail(s) als verarbeitet markiert.")
|
||
mark_verarbeitet.short_description = "Als verarbeitet markieren"
|