Fix DMS entity assignment and Geschichte document linking
- DMS edit view: add Destinatär, Land, Pächter, Verpachtung dropdowns so documents can be assigned to entities after upload - Geschichte: add M2M dokumente field on GeschichteSeite model - Geschichte form: checkboxes to select/link Stiftungsgeschichte docs - Geschichte detail: show linked documents in sidebar with download Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
18
app/stiftung/migrations/0053_geschichte_dokumente_m2m.py
Normal file
18
app/stiftung/migrations/0053_geschichte_dokumente_m2m.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 5.0.6 on 2026-03-12 10:40
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('stiftung', '0052_alter_dokumentdatei_kontext_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='geschichteseite',
|
||||||
|
name='dokumente',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='geschichte_seiten', to='stiftung.dokumentdatei', verbose_name='Verknüpfte Dokumente'),
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -36,6 +36,14 @@ class GeschichteSeite(models.Model):
|
|||||||
verbose_name="Aktualisiert von"
|
verbose_name="Aktualisiert von"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Verknüpfte DMS-Dokumente
|
||||||
|
dokumente = models.ManyToManyField(
|
||||||
|
"DokumentDatei",
|
||||||
|
blank=True,
|
||||||
|
related_name="geschichte_seiten",
|
||||||
|
verbose_name="Verknüpfte Dokumente",
|
||||||
|
)
|
||||||
|
|
||||||
# Options
|
# Options
|
||||||
ist_veroeffentlicht = models.BooleanField(default=True, verbose_name="Veröffentlicht")
|
ist_veroeffentlicht = models.BooleanField(default=True, verbose_name="Veröffentlicht")
|
||||||
sortierung = models.IntegerField(default=0, verbose_name="Sortierung")
|
sortierung = models.IntegerField(default=0, verbose_name="Sortierung")
|
||||||
|
|||||||
@@ -247,13 +247,34 @@ def dms_edit(request, pk):
|
|||||||
dok.titel = request.POST.get("titel", dok.titel).strip()[:255]
|
dok.titel = request.POST.get("titel", dok.titel).strip()[:255]
|
||||||
dok.beschreibung = request.POST.get("beschreibung", "").strip()
|
dok.beschreibung = request.POST.get("beschreibung", "").strip()
|
||||||
dok.kontext = request.POST.get("kontext", dok.kontext)
|
dok.kontext = request.POST.get("kontext", dok.kontext)
|
||||||
|
|
||||||
|
# Entity assignments
|
||||||
|
dest_id = request.POST.get("destinataer_id", "").strip()
|
||||||
|
land_id = request.POST.get("land_id", "").strip()
|
||||||
|
paechter_id = request.POST.get("paechter_id", "").strip()
|
||||||
|
verp_id = request.POST.get("verpachtung_id", "").strip()
|
||||||
|
|
||||||
|
dok.destinataer_id = int(dest_id) if dest_id else None
|
||||||
|
dok.land_id = int(land_id) if land_id else None
|
||||||
|
dok.paechter_id = int(paechter_id) if paechter_id else None
|
||||||
|
dok.verpachtung_id = verp_id if verp_id else None
|
||||||
|
|
||||||
dok.save()
|
dok.save()
|
||||||
dok.update_suchvektor()
|
dok.update_suchvektor()
|
||||||
messages.success(request, "Metadaten gespeichert.")
|
messages.success(request, "Metadaten gespeichert.")
|
||||||
return redirect("stiftung:dms_detail", pk=dok.pk)
|
return redirect("stiftung:dms_detail", pk=dok.pk)
|
||||||
|
|
||||||
|
destinataere = Destinataer.objects.filter(aktiv=True).order_by("nachname", "vorname")
|
||||||
|
laendereien = Land.objects.filter(aktiv=True).order_by("lfd_nr")
|
||||||
|
paechter_qs = Paechter.objects.filter(aktiv=True).order_by("nachname")
|
||||||
|
verpachtungen = LandVerpachtung.objects.select_related("land", "paechter").order_by("-vertragsbeginn")[:50]
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
"dok": dok,
|
"dok": dok,
|
||||||
"kontext_choices": DokumentDatei.KONTEXT_CHOICES,
|
"kontext_choices": DokumentDatei.KONTEXT_CHOICES,
|
||||||
|
"destinataere": destinataere,
|
||||||
|
"laendereien": laendereien,
|
||||||
|
"paechter_qs": paechter_qs,
|
||||||
|
"verpachtungen": verpachtungen,
|
||||||
}
|
}
|
||||||
return render(request, "stiftung/dms/edit.html", context)
|
return render(request, "stiftung/dms/edit.html", context)
|
||||||
|
|||||||
@@ -99,12 +99,19 @@ def geschichte_create(request):
|
|||||||
seite.erstellt_von = request.user
|
seite.erstellt_von = request.user
|
||||||
seite.aktualisiert_von = request.user
|
seite.aktualisiert_von = request.user
|
||||||
seite.save()
|
seite.save()
|
||||||
|
form.save_m2m()
|
||||||
|
|
||||||
|
# Link selected DMS documents
|
||||||
|
dok_ids = request.POST.getlist("dokument_ids")
|
||||||
|
if dok_ids:
|
||||||
|
from stiftung.models import DokumentDatei
|
||||||
|
seite.dokumente.set(DokumentDatei.objects.filter(pk__in=dok_ids))
|
||||||
|
|
||||||
messages.success(request, f'Geschichtsseite "{seite.titel}" wurde erfolgreich erstellt.')
|
messages.success(request, f'Geschichtsseite "{seite.titel}" wurde erfolgreich erstellt.')
|
||||||
return redirect('stiftung:geschichte_detail', slug=seite.slug)
|
return redirect('stiftung:geschichte_detail', slug=seite.slug)
|
||||||
else:
|
else:
|
||||||
form = GeschichteSeiteForm()
|
form = GeschichteSeiteForm()
|
||||||
|
|
||||||
# Verfuegbare Stiftungsgeschichte-Dokumente aus DMS
|
# Verfuegbare Stiftungsgeschichte-Dokumente aus DMS
|
||||||
from stiftung.models import DokumentDatei
|
from stiftung.models import DokumentDatei
|
||||||
geschichte_dokumente = DokumentDatei.objects.filter(
|
geschichte_dokumente = DokumentDatei.objects.filter(
|
||||||
@@ -115,6 +122,7 @@ def geschichte_create(request):
|
|||||||
'form': form,
|
'form': form,
|
||||||
'title': 'Neue Geschichtsseite',
|
'title': 'Neue Geschichtsseite',
|
||||||
'geschichte_dokumente': geschichte_dokumente,
|
'geschichte_dokumente': geschichte_dokumente,
|
||||||
|
'selected_dok_ids': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'stiftung/geschichte/form.html', context)
|
return render(request, 'stiftung/geschichte/form.html', context)
|
||||||
@@ -135,23 +143,33 @@ def geschichte_edit(request, slug):
|
|||||||
seite = form.save(commit=False)
|
seite = form.save(commit=False)
|
||||||
seite.aktualisiert_von = request.user
|
seite.aktualisiert_von = request.user
|
||||||
seite.save()
|
seite.save()
|
||||||
|
form.save_m2m()
|
||||||
|
|
||||||
|
# Update linked DMS documents
|
||||||
|
dok_ids = request.POST.getlist("dokument_ids")
|
||||||
|
from stiftung.models import DokumentDatei
|
||||||
|
seite.dokumente.set(DokumentDatei.objects.filter(pk__in=dok_ids))
|
||||||
|
|
||||||
messages.success(request, f'Geschichtsseite "{seite.titel}" wurde erfolgreich aktualisiert.')
|
messages.success(request, f'Geschichtsseite "{seite.titel}" wurde erfolgreich aktualisiert.')
|
||||||
return redirect('stiftung:geschichte_detail', slug=seite.slug)
|
return redirect('stiftung:geschichte_detail', slug=seite.slug)
|
||||||
else:
|
else:
|
||||||
form = GeschichteSeiteForm(instance=seite)
|
form = GeschichteSeiteForm(instance=seite)
|
||||||
|
|
||||||
# Verfuegbare Stiftungsgeschichte-Dokumente aus DMS
|
# Verfuegbare Stiftungsgeschichte-Dokumente aus DMS
|
||||||
from stiftung.models import DokumentDatei
|
from stiftung.models import DokumentDatei
|
||||||
geschichte_dokumente = DokumentDatei.objects.filter(
|
geschichte_dokumente = DokumentDatei.objects.filter(
|
||||||
kontext="stiftungsgeschichte"
|
kontext="stiftungsgeschichte"
|
||||||
).order_by("-erstellt_am")[:20]
|
).order_by("-erstellt_am")[:20]
|
||||||
|
|
||||||
|
# IDs der bereits verknuepften Dokumente
|
||||||
|
selected_dok_ids = list(seite.dokumente.values_list("pk", flat=True))
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'form': form,
|
'form': form,
|
||||||
'seite': seite,
|
'seite': seite,
|
||||||
'title': f'Bearbeiten: {seite.titel}',
|
'title': f'Bearbeiten: {seite.titel}',
|
||||||
'geschichte_dokumente': geschichte_dokumente,
|
'geschichte_dokumente': geschichte_dokumente,
|
||||||
|
'selected_dok_ids': selected_dok_ids,
|
||||||
}
|
}
|
||||||
|
|
||||||
return render(request, 'stiftung/geschichte/form.html', context)
|
return render(request, 'stiftung/geschichte/form.html', context)
|
||||||
|
|||||||
@@ -41,6 +41,56 @@
|
|||||||
<textarea name="beschreibung" class="form-control" rows="3">{{ dok.beschreibung }}</textarea>
|
<textarea name="beschreibung" class="form-control" rows="3">{{ dok.beschreibung }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Zuordnung -->
|
||||||
|
<hr>
|
||||||
|
<h6 class="fw-semibold mb-3"><i class="fas fa-link me-2"></i>Zuordnung</h6>
|
||||||
|
<div class="row g-3 mb-4">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label small fw-semibold">Destinatär</label>
|
||||||
|
<select name="destinataer_id" class="form-select form-select-sm">
|
||||||
|
<option value="">– keine –</option>
|
||||||
|
{% for d in destinataere %}
|
||||||
|
<option value="{{ d.pk }}" {% if dok.destinataer_id == d.pk %}selected{% endif %}>
|
||||||
|
{{ d.get_full_name }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label small fw-semibold">Länderei</label>
|
||||||
|
<select name="land_id" class="form-select form-select-sm">
|
||||||
|
<option value="">– keine –</option>
|
||||||
|
{% for l in laendereien %}
|
||||||
|
<option value="{{ l.pk }}" {% if dok.land_id == l.pk %}selected{% endif %}>
|
||||||
|
{{ l.lfd_nr }}{% if l.gemeinde %} – {{ l.gemeinde }}{% endif %}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label small fw-semibold">Pächter</label>
|
||||||
|
<select name="paechter_id" class="form-select form-select-sm">
|
||||||
|
<option value="">– keine –</option>
|
||||||
|
{% for p in paechter_qs %}
|
||||||
|
<option value="{{ p.pk }}" {% if dok.paechter_id == p.pk %}selected{% endif %}>
|
||||||
|
{{ p.get_full_name }}
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<label class="form-label small fw-semibold">Verpachtung</label>
|
||||||
|
<select name="verpachtung_id" class="form-select form-select-sm">
|
||||||
|
<option value="">– keine –</option>
|
||||||
|
{% for v in verpachtungen %}
|
||||||
|
<option value="{{ v.pk }}" {% if dok.verpachtung_id == v.pk %}selected{% endif %}>
|
||||||
|
{{ v.land.lfd_nr }} – {{ v.paechter.get_full_name }} ({{ v.vertragsbeginn|date:"Y" }})
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="d-flex gap-2 justify-content-end">
|
<div class="d-flex gap-2 justify-content-end">
|
||||||
<a href="{% url 'stiftung:dms_detail' pk=dok.pk %}" class="btn btn-outline-secondary">Abbrechen</a>
|
<a href="{% url 'stiftung:dms_detail' pk=dok.pk %}" class="btn btn-outline-secondary">Abbrechen</a>
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary">
|
||||||
|
|||||||
@@ -120,12 +120,39 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-lg-4">
|
<div class="col-lg-4">
|
||||||
|
{% if seite.dokumente.exists %}
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="card-header bg-dark text-white">
|
||||||
|
<h6 class="mb-0"><i class="fas fa-landmark me-2"></i>Verknüpfte Dokumente</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<div class="list-group list-group-flush">
|
||||||
|
{% for dok in seite.dokumente.all %}
|
||||||
|
<a href="{% url 'stiftung:dms_detail' pk=dok.pk %}" class="list-group-item list-group-item-action">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<div>
|
||||||
|
<div class="small fw-bold">
|
||||||
|
{% if dok.is_pdf %}<i class="fas fa-file-pdf text-danger me-1"></i>{% else %}<i class="fas fa-file text-primary me-1"></i>{% endif %}
|
||||||
|
{{ dok.titel|truncatechars:35 }}
|
||||||
|
</div>
|
||||||
|
<small class="text-muted">{{ dok.dateiname_original }} · {{ dok.get_human_size }}</small>
|
||||||
|
</div>
|
||||||
|
<span class="btn btn-sm btn-outline-success" title="Herunterladen" onclick="event.preventDefault(); window.location='{% url 'stiftung:dms_download' dok.pk %}';">
|
||||||
|
<i class="fas fa-download"></i>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header bg-secondary text-white">
|
<div class="card-header bg-secondary text-white">
|
||||||
<h6 class="mb-0"><i class="fas fa-list me-2"></i>Weitere Seiten</h6>
|
<h6 class="mb-0"><i class="fas fa-list me-2"></i>Weitere Seiten</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<!-- This could be populated with other history pages -->
|
|
||||||
<p class="text-muted small">Navigation zu anderen Geschichtsseiten wird hier angezeigt.</p>
|
<p class="text-muted small">Navigation zu anderen Geschichtsseiten wird hier angezeigt.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -181,28 +181,41 @@
|
|||||||
{% if geschichte_dokumente %}
|
{% if geschichte_dokumente %}
|
||||||
<div class="card mt-3">
|
<div class="card mt-3">
|
||||||
<div class="card-header bg-dark text-white">
|
<div class="card-header bg-dark text-white">
|
||||||
<h6 class="mb-0"><i class="fas fa-landmark me-2"></i>Verfuegbare Geschichtsdokumente</h6>
|
<h6 class="mb-0"><i class="fas fa-landmark me-2"></i>Dokumente verknüpfen</h6>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body p-0">
|
<div class="card-body p-0">
|
||||||
<div class="list-group list-group-flush">
|
<div class="list-group list-group-flush">
|
||||||
{% for dok in geschichte_dokumente %}
|
{% for dok in geschichte_dokumente %}
|
||||||
<div class="list-group-item">
|
<label class="list-group-item list-group-item-action" style="cursor: pointer;">
|
||||||
<div class="d-flex justify-content-between align-items-start">
|
<div class="d-flex align-items-start">
|
||||||
<div>
|
<input type="checkbox" name="dokument_ids" value="{{ dok.pk }}"
|
||||||
|
class="form-check-input me-2 mt-1"
|
||||||
|
form="geschichteForm"
|
||||||
|
{% if dok.pk in selected_dok_ids %}checked{% endif %}>
|
||||||
|
<div class="flex-grow-1">
|
||||||
<div class="small fw-bold">{{ dok.titel|truncatechars:40 }}</div>
|
<div class="small fw-bold">{{ dok.titel|truncatechars:40 }}</div>
|
||||||
<small class="text-muted">{{ dok.dateiname_original }} ({{ dok.get_human_size }})</small>
|
<small class="text-muted">{{ dok.dateiname_original }} ({{ dok.get_human_size }})</small>
|
||||||
<br><small class="text-muted">{{ dok.erstellt_am|date:"d.m.Y" }}</small>
|
<br><small class="text-muted">{{ dok.erstellt_am|date:"d.m.Y" }}</small>
|
||||||
</div>
|
</div>
|
||||||
<a href="{% url 'stiftung:dms_download' dok.pk %}" class="btn btn-sm btn-outline-primary" title="Herunterladen">
|
<a href="{% url 'stiftung:dms_download' dok.pk %}" class="btn btn-sm btn-outline-primary ms-1" title="Herunterladen" onclick="event.stopPropagation();">
|
||||||
<i class="fas fa-download"></i>
|
<i class="fas fa-download"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</label>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer small text-muted">
|
<div class="card-footer small text-muted">
|
||||||
Dokumente aus dem DMS mit Kontext "Stiftungsgeschichte". Eingegangen per E-Mail oder manuell hochgeladen.
|
Dokumente aus dem DMS mit Kontext "Stiftungsgeschichte" auswählen, um sie mit diesem Beitrag zu verknüpfen.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="card mt-3">
|
||||||
|
<div class="card-header bg-dark text-white">
|
||||||
|
<h6 class="mb-0"><i class="fas fa-landmark me-2"></i>Dokumente verknüpfen</h6>
|
||||||
|
</div>
|
||||||
|
<div class="card-body text-muted small">
|
||||||
|
Keine Stiftungsgeschichte-Dokumente im DMS vorhanden. Laden Sie Dokumente mit dem Kontext "Stiftungsgeschichte" im <a href="{% url 'stiftung:dms_upload' %}?kontext=stiftungsgeschichte">DMS hoch</a>.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
Reference in New Issue
Block a user