- 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>
118 lines
4.3 KiB
Python
118 lines
4.3 KiB
Python
# views/dashboard.py
|
||
# Phase 0: Vision 2026 – Code-Refactoring
|
||
|
||
import csv
|
||
import io
|
||
import json
|
||
import os
|
||
import time
|
||
from datetime import datetime, timedelta, date
|
||
from decimal import Decimal
|
||
|
||
import qrcode
|
||
import qrcode.image.svg
|
||
import requests
|
||
from django.conf import settings
|
||
from django.contrib import messages
|
||
from django.contrib.auth.decorators import login_required
|
||
from django.core.paginator import Paginator
|
||
from django.db.models import (Avg, Count, DecimalField, F, IntegerField, Q,
|
||
Sum, Value)
|
||
from django.db.models.functions import Cast, Coalesce, NullIf, Replace
|
||
from django.http import HttpResponse, JsonResponse
|
||
from django.shortcuts import get_object_or_404, redirect, render
|
||
from django.urls import reverse
|
||
from django.utils import timezone
|
||
from django.views.decorators.csrf import csrf_exempt
|
||
from django_otp.decorators import otp_required
|
||
from django_otp.plugins.otp_totp.models import TOTPDevice
|
||
from django_otp.plugins.otp_static.models import StaticDevice, StaticToken
|
||
from django_otp.util import random_hex
|
||
from rest_framework.decorators import api_view
|
||
from rest_framework.response import Response
|
||
|
||
from stiftung.models import (AppConfiguration, AuditLog, BackupJob, BankTransaction,
|
||
BriefVorlage, CSVImport, Destinataer,
|
||
DestinataerEmailEingang, DestinataerNotiz,
|
||
DestinataerUnterstuetzung,
|
||
DokumentLink, Foerderung, GeschichteBild, GeschichteSeite,
|
||
Land, LandAbrechnung, LandVerpachtung, Paechter, Person,
|
||
Rentmeister, StiftungsKalenderEintrag, StiftungsKonto,
|
||
UnterstuetzungWiederkehrend, Veranstaltung,
|
||
Veranstaltungsteilnehmer, Verwaltungskosten,
|
||
VierteljahresNachweis)
|
||
from stiftung.forms import (
|
||
DestinataerForm, DestinataerUnterstuetzungForm, DestinataerNotizForm,
|
||
FoerderungForm, GeschichteBildForm, GeschichteSeiteForm,
|
||
LandForm, LandVerpachtungForm, LandAbrechnungForm,
|
||
PaechterForm, DokumentLinkForm,
|
||
RentmeisterForm, StiftungsKontoForm, VerwaltungskostenForm,
|
||
BankTransactionForm, BankImportForm,
|
||
UnterstuetzungForm, UnterstuetzungWiederkehrendForm,
|
||
UnterstuetzungMarkAsPaidForm, VierteljahresNachweisForm,
|
||
UserCreationForm, UserUpdateForm, PasswordChangeForm, UserPermissionForm,
|
||
TwoFactorSetupForm, TwoFactorVerifyForm, TwoFactorDisableForm,
|
||
BackupTokenRegenerateForm, PersonForm,
|
||
VeranstaltungForm, VeranstaltungsteilnehmerForm,
|
||
)
|
||
|
||
|
||
@login_required
|
||
def home(request):
|
||
"""Home page for the Stiftungsverwaltung application"""
|
||
from stiftung.services.calendar_service import StiftungsKalenderService
|
||
|
||
# Get upcoming events for the calendar widget
|
||
calendar_service = StiftungsKalenderService()
|
||
|
||
# Get all events for the next 14 days
|
||
from datetime import timedelta
|
||
today = timezone.now().date()
|
||
end_date = today + timedelta(days=14)
|
||
all_events = calendar_service.get_all_events(today, end_date)
|
||
|
||
# Filter for upcoming and overdue
|
||
upcoming_events = [e for e in all_events if not getattr(e, 'overdue', False)]
|
||
overdue_events = [e for e in all_events if getattr(e, 'overdue', False)]
|
||
|
||
# Get current month events for mini calendar
|
||
from calendar import monthrange
|
||
_, last_day = monthrange(today.year, today.month)
|
||
month_start = today.replace(day=1)
|
||
month_end = today.replace(day=last_day)
|
||
current_month_events = calendar_service.get_all_events(month_start, month_end)
|
||
|
||
context = {
|
||
"title": "Stiftungsverwaltung",
|
||
"description": "Foundation Management System",
|
||
"upcoming_events": upcoming_events[:5], # Show only 5 upcoming events
|
||
"overdue_events": overdue_events[:3], # Show only 3 overdue events
|
||
"current_month_events": current_month_events,
|
||
"today": today,
|
||
}
|
||
|
||
return render(request, "stiftung/home.html", context)
|
||
|
||
|
||
@api_view(["GET"])
|
||
def health_check(request):
|
||
"""Simple health check endpoint for deployment monitoring"""
|
||
return JsonResponse(
|
||
{
|
||
"status": "healthy",
|
||
"timestamp": timezone.now().isoformat(),
|
||
"service": "stiftung-web",
|
||
}
|
||
)
|
||
|
||
|
||
## Removed duplicate paperless_ping referencing non-existent PAPERLESS_URL
|
||
|
||
|
||
# CSV Import Views
|
||
@api_view(["GET"])
|
||
def health(_request):
|
||
return Response({"status": "ok"})
|
||
|
||
|