# management/commands/migrate_paperless_dokumente.py # Phase 3: Migriert DokumentLink-Einträge zu DokumentDatei (falls Paperless-Dateien lokal verfügbar) # # Verwendung: # python manage.py migrate_paperless_dokumente [--dry-run] [--limit N] # # Was dieser Befehl tut: # 1. Alle DokumentLink-Objekte abrufen (Paperless-Verweise) # 2. Für jeden Link: DokumentDatei erstellen, falls noch keine existiert (paperless_dokument_id) # 3. Suchvektor aktualisieren # 4. paperless_dokument_id setzen, damit künftige Läufe Duplikate überspringen import os from django.core.management.base import BaseCommand, CommandError from django.db import transaction from stiftung.models import DokumentDatei, DokumentLink class Command(BaseCommand): help = "Migriert Paperless-DokumentLink-Einträge zu DokumentDatei (Metadaten only)" def add_arguments(self, parser): parser.add_argument( "--dry-run", action="store_true", help="Zeigt an, was migriert würde, ohne Änderungen vorzunehmen.", ) parser.add_argument( "--limit", type=int, default=0, help="Maximale Anzahl Einträge (0 = alle).", ) def handle(self, *args, **options): dry_run = options["dry_run"] limit = options["limit"] links = DokumentLink.objects.select_related( "destinataer", "land", "paechter", "verpachtung" ).order_by("pk") if limit > 0: links = links[:limit] total = links.count() self.stdout.write(f"Gefundene DokumentLinks: {total}") if dry_run: self.stdout.write(self.style.WARNING("DRY-RUN – keine Datenbankänderungen.")) created = 0 skipped = 0 for link in links: # Bereits migriert? if DokumentDatei.objects.filter( paperless_dokument_id=link.paperless_document_id ).exists(): skipped += 1 continue titel = link.titel or f"Paperless #{link.paperless_document_id}" kontext = link.kontext or _guess_kontext(titel) if dry_run: self.stdout.write( f" [DRY] Würde anlegen: {titel!r} (kontext={kontext}, " f"paperless_id={link.paperless_document_id})" ) created += 1 continue with transaction.atomic(): dok = DokumentDatei( titel=titel, beschreibung=link.beschreibung or "", kontext=kontext, paperless_dokument_id=link.paperless_document_id, ) # Assign FKs by ID (DokumentLink stores raw UUIDs, not FK relations) if link.destinataer_id: dok.destinataer_id = link.destinataer_id if link.land_id: dok.land_id = link.land_id if link.paechter_id: dok.paechter_id = link.paechter_id if link.land_verpachtung_id: dok.verpachtung_id = link.land_verpachtung_id dok.save() dok.update_suchvektor() created += 1 self.stdout.write( self.style.SUCCESS( f"Fertig: {created} angelegt, {skipped} übersprungen (bereits migriert)." ) ) def _guess_kontext(title_lower: str) -> str: """Leitet den Kontext-Code aus dem Titel ab.""" t = title_lower.lower() if any(kw in t for kw in ["pachtvertrag", "pachtvertr"]): return "pachtvertrag" if any(kw in t for kw in ["antrag", "förderantrag"]): return "antrag" if any(kw in t for kw in ["nachweis", "verwendungsnachweis"]): return "verwendungsnachweis" if any(kw in t for kw in ["rechnung"]): return "rechnung" if any(kw in t for kw in ["bericht", "jahresbericht"]): return "bericht" if any(kw in t for kw in ["karte", "landkarte", "flurkarte"]): return "landkarte" if any(kw in t for kw in ["bescheid"]): return "bescheid" if any(kw in t for kw in ["korrespondenz", "brief"]): return "korrespondenz" if any(kw in t for kw in ["studium", "immatrikulation", "zeugnis"]): return "studiennachweis" return "anderes"