import uuid from django.db import models from django.utils import timezone class GeschichteSeite(models.Model): """Wiki-style pages for foundation history""" id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) titel = models.CharField(max_length=200, verbose_name="Titel") slug = models.SlugField(max_length=200, unique=True, verbose_name="URL-Slug") inhalt = models.TextField( verbose_name="Inhalt (Markdown)", blank=True, help_text="Sie können Markdown verwenden: **fett**, *kursiv*, # Überschriften, [Links](URL), Listen, etc." ) # Metadata erstellt_am = models.DateTimeField(auto_now_add=True, verbose_name="Erstellt am") aktualisiert_am = models.DateTimeField(auto_now=True, verbose_name="Aktualisiert am") erstellt_von = models.ForeignKey( 'auth.User', on_delete=models.SET_NULL, null=True, blank=True, related_name='geschichte_seiten_erstellt', verbose_name="Erstellt von" ) aktualisiert_von = models.ForeignKey( 'auth.User', on_delete=models.SET_NULL, null=True, blank=True, related_name='geschichte_seiten_aktualisiert', verbose_name="Aktualisiert von" ) # Verknüpfte DMS-Dokumente dokumente = models.ManyToManyField( "DokumentDatei", blank=True, related_name="geschichte_seiten", verbose_name="Verknüpfte Dokumente", ) # Options ist_veroeffentlicht = models.BooleanField(default=True, verbose_name="Veröffentlicht") sortierung = models.IntegerField(default=0, verbose_name="Sortierung") class Meta: verbose_name = "Geschichte Seite" verbose_name_plural = "Geschichte Seiten" ordering = ['sortierung', 'titel'] def __str__(self): return self.titel def get_absolute_url(self): from django.urls import reverse return reverse('stiftung:geschichte_detail', kwargs={'slug': self.slug}) class GeschichteBild(models.Model): """Images for history pages""" id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) seite = models.ForeignKey( GeschichteSeite, on_delete=models.CASCADE, related_name='bilder', verbose_name="Geschichte Seite" ) titel = models.CharField(max_length=200, verbose_name="Bildtitel") bild = models.ImageField( upload_to='geschichte/bilder/%Y/%m/', verbose_name="Bild" ) beschreibung = models.TextField(blank=True, verbose_name="Beschreibung") alt_text = models.CharField(max_length=200, blank=True, verbose_name="Alt-Text") # Metadata hochgeladen_am = models.DateTimeField(auto_now_add=True, verbose_name="Hochgeladen am") hochgeladen_von = models.ForeignKey( 'auth.User', on_delete=models.SET_NULL, null=True, blank=True, verbose_name="Hochgeladen von" ) sortierung = models.IntegerField(default=0, verbose_name="Sortierung") class Meta: verbose_name = "Geschichte Bild" verbose_name_plural = "Geschichte Bilder" ordering = ['sortierung', 'titel'] def __str__(self): return f"{self.titel} ({self.seite.titel})" class StiftungsKalenderEintrag(models.Model): """Custom calendar events for foundation management""" KATEGORIE_CHOICES = [ ('termin', 'Termin/Meeting'), ('zahlung', 'Zahlungserinnerung'), ('deadline', 'Frist/Deadline'), ('geburtstag', 'Geburtstag'), ('vertrag', 'Vertrag läuft aus'), ('pruefung', 'Prüfung/Nachweis'), ('sonstiges', 'Sonstiges'), ] PRIORITAET_CHOICES = [ ('niedrig', 'Niedrig'), ('normal', 'Normal'), ('hoch', 'Hoch'), ('kritisch', 'Kritisch'), ] id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) titel = models.CharField(max_length=200, verbose_name="Titel") beschreibung = models.TextField(blank=True, verbose_name="Beschreibung") # Date and time datum = models.DateField(verbose_name="Datum") uhrzeit = models.TimeField(null=True, blank=True, verbose_name="Uhrzeit") ganztags = models.BooleanField(default=True, verbose_name="Ganztägig") # Categorization kategorie = models.CharField( max_length=20, choices=KATEGORIE_CHOICES, default='termin', verbose_name="Kategorie" ) prioritaet = models.CharField( max_length=20, choices=PRIORITAET_CHOICES, default='normal', verbose_name="Priorität" ) # Links to related objects destinataer = models.ForeignKey( 'stiftung.Destinataer', null=True, blank=True, on_delete=models.CASCADE, verbose_name="Bezogener Destinatär" ) verpachtung = models.ForeignKey( 'stiftung.LandVerpachtung', null=True, blank=True, on_delete=models.CASCADE, verbose_name="Bezogene Verpachtung" ) # Status and completion erledigt = models.BooleanField(default=False, verbose_name="Erledigt") erledigt_am = models.DateTimeField(null=True, blank=True, verbose_name="Erledigt am") # Metadata erstellt_von = models.CharField( max_length=100, null=True, blank=True, verbose_name="Erstellt von" ) erstellt_am = models.DateTimeField(auto_now_add=True, verbose_name="Erstellt am") aktualisiert_am = models.DateTimeField(auto_now=True, verbose_name="Aktualisiert am") class Meta: verbose_name = "Kalender Eintrag" verbose_name_plural = "Kalender Einträge" ordering = ['datum', 'uhrzeit'] indexes = [ models.Index(fields=['datum']), models.Index(fields=['kategorie', 'datum']), models.Index(fields=['erledigt', 'datum']), ] def __str__(self): return f"{self.datum}: {self.titel}" def get_kategorie_icon(self): icons = { 'termin': 'fas fa-calendar-alt', 'zahlung': 'fas fa-euro-sign', 'deadline': 'fas fa-exclamation-triangle', 'geburtstag': 'fas fa-birthday-cake', 'vertrag': 'fas fa-file-contract', 'pruefung': 'fas fa-clipboard-check', 'sonstiges': 'fas fa-calendar', } return icons.get(self.kategorie, 'fas fa-calendar') def get_prioritaet_color(self): colors = { 'niedrig': 'success', 'normal': 'primary', 'hoch': 'warning', 'kritisch': 'danger', } return colors.get(self.prioritaet, 'primary') def is_overdue(self): """Check if event is overdue (past due and not completed)""" if self.erledigt: return False return self.datum < timezone.now().date() def is_upcoming(self, days=7): """Check if event is upcoming within specified days""" if self.erledigt: return False today = timezone.now().date() return today <= self.datum <= (today + timezone.timedelta(days=days))