Files
stiftung-management-system/app/templates/stiftung/email_eingang/detail.html
Stiftung CEO Agent 4b21f553c3
Some checks failed
CI/CD Pipeline / test (push) Has been cancelled
CI/CD Pipeline / deploy (push) Has been cancelled
Code Quality / quality (push) Has been cancelled
feat: Email-Eingangsverarbeitung für Destinatäre implementieren
Neues System zur automatischen Verarbeitung eingehender E-Mails von
Destinatären. IMAP-Polling alle 15 Minuten via Celery Beat, automatische
Zuordnung zu Destinatären anhand der E-Mail-Adresse, Upload von Anhängen
zu Paperless-NGX.

Umfasst:
- DestinataerEmailEingang Model mit Status-Tracking
- Celery Task für IMAP-Polling und Paperless-Integration
- Web-UI (Liste + Detail) mit Such- und Filterfunktion
- Admin-Interface mit Bulk-Actions
- Agent-Dokumentation (SysAdmin, RentmeisterAI)
- Dev-Environment Modernisierung (docker compose v2)

Reviewed by: SysAdmin (STI-15), RentmeisterAI (STI-16)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 21:11:22 +00:00

228 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends 'base.html' %}
{% load humanize %}
{% block title %}E-Mail-Eingang Detail - van Hees-Theyssen-Vogel'sche Stiftung{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<div class="d-sm-flex align-items-center justify-content-between mb-4">
<h1 class="h3 mb-0 text-gray-800">
<i class="fas fa-envelope me-2"></i>E-Mail-Eingang
</h1>
<a href="{% url 'stiftung:email_eingang_list' %}" class="btn btn-outline-secondary btn-sm">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Übersicht
</a>
</div>
</div>
</div>
<div class="row">
<!-- Linke Spalte: E-Mail-Details -->
<div class="col-lg-8">
<div class="card mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<span><i class="fas fa-envelope-open me-2"></i>E-Mail-Details</span>
<span>
{% if eingang.status == "neu" %}<span class="badge bg-warning text-dark">Neu</span>
{% elif eingang.status == "zugewiesen" %}<span class="badge bg-primary">Zugewiesen</span>
{% elif eingang.status == "verarbeitet" %}<span class="badge bg-success">Verarbeitet</span>
{% elif eingang.status == "unbekannt" %}<span class="badge bg-danger">Unbekannter Absender</span>
{% elif eingang.status == "fehler" %}<span class="badge bg-secondary">Fehler</span>
{% endif %}
</span>
</div>
<div class="card-body">
<dl class="row">
<dt class="col-sm-3">Eingangsdatum</dt>
<dd class="col-sm-9">{{ eingang.eingangsdatum|date:"d.m.Y H:i" }} Uhr</dd>
<dt class="col-sm-3">Absender</dt>
<dd class="col-sm-9">
{% if eingang.absender_name %}{{ eingang.absender_name }} &lt;{% endif %}
<a href="mailto:{{ eingang.absender_email }}">{{ eingang.absender_email }}</a>
{% if eingang.absender_name %}&gt;{% endif %}
</dd>
<dt class="col-sm-3">Betreff</dt>
<dd class="col-sm-9">{{ eingang.betreff|default:"(kein Betreff)" }}</dd>
<dt class="col-sm-3">Destinatär</dt>
<dd class="col-sm-9">
{% if eingang.destinataer %}
<a href="{% url 'stiftung:destinataer_detail' eingang.destinataer.pk %}">
{{ eingang.destinataer }}
</a>
{% else %}
<span class="text-danger"><i class="fas fa-exclamation-circle me-1"></i>Nicht zugeordnet</span>
{% endif %}
</dd>
{% if eingang.quartalsnachweis %}
<dt class="col-sm-3">Quartalsnachweis</dt>
<dd class="col-sm-9">
Q{{ eingang.quartalsnachweis.quartal }} / {{ eingang.quartalsnachweis.jahr }}
</dd>
{% endif %}
</dl>
{% if eingang.email_text %}
<hr>
<h6 class="text-muted"><i class="fas fa-align-left me-1"></i>E-Mail-Text</h6>
<div class="bg-light rounded p-3" style="white-space: pre-wrap; font-family: monospace; font-size: 0.85rem; max-height: 400px; overflow-y: auto;">{{ eingang.email_text }}</div>
{% endif %}
{% if eingang.fehler_details %}
<hr>
<div class="alert alert-danger">
<strong><i class="fas fa-exclamation-triangle me-1"></i>Fehlerdetails:</strong>
<pre class="mb-0 mt-1" style="font-size: 0.8rem;">{{ eingang.fehler_details }}</pre>
</div>
{% endif %}
</div>
</div>
<!-- Anhänge / Paperless-Dokumente -->
{% if dokument_links %}
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-paperclip me-2"></i>Anhänge in Paperless-NGX
</div>
<div class="card-body p-0">
<table class="table mb-0">
<thead class="table-light">
<tr>
<th>Titel</th>
<th>Kontext</th>
<th>Paperless-ID</th>
<th></th>
</tr>
</thead>
<tbody>
{% for link in dokument_links %}
<tr>
<td>{{ link.titel }}</td>
<td>{{ link.get_kontext_display }}</td>
<td><code>{{ link.paperless_document_id }}</code></td>
<td>
<a href="{{ link.get_paperless_url }}" target="_blank" class="btn btn-sm btn-outline-info">
<i class="fas fa-external-link-alt me-1"></i>Öffnen
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% elif eingang.paperless_dokument_ids %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-1"></i>
{{ eingang.paperless_dokument_ids|length }} Anhang/-hänge in Paperless hochgeladen
(IDs: {{ eingang.paperless_dokument_ids|join:", " }}), aber noch kein DokumentLink erstellt.
</div>
{% else %}
<div class="card mb-4">
<div class="card-body text-muted text-center py-3">
<i class="fas fa-paperclip me-1"></i>Keine Anhänge in dieser E-Mail.
</div>
</div>
{% endif %}
</div>
<!-- Rechte Spalte: Aktionen -->
<div class="col-lg-4">
<!-- Manuelle Destinatär-Zuordnung -->
{% if not eingang.destinataer or eingang.status == "unbekannt" %}
<div class="card mb-4 border-warning">
<div class="card-header bg-warning text-dark">
<i class="fas fa-user-plus me-2"></i>Destinatär manuell zuordnen
</div>
<div class="card-body">
<p class="small text-muted">
Die E-Mail-Adresse <strong>{{ eingang.absender_email }}</strong>
konnte keinem Destinatär automatisch zugeordnet werden.
Bitte wählen Sie den passenden Destinatär aus.
</p>
<form method="post">
{% csrf_token %}
<input type="hidden" name="action" value="assign_destinataer">
<div class="mb-3">
<label class="form-label">Destinatär</label>
<select class="form-select" name="destinataer_id" required>
<option value=""> Bitte wählen </option>
{% for d in alle_destinataere %}
<option value="{{ d.pk }}">{{ d.nachname }}, {{ d.vorname }}
{% if d.email %} ({{ d.email }}){% endif %}
</option>
{% endfor %}
</select>
</div>
<button type="submit" class="btn btn-warning w-100">
<i class="fas fa-link me-1"></i>Zuordnen & Speichern
</button>
</form>
</div>
</div>
{% endif %}
<!-- Als verarbeitet markieren -->
{% if eingang.status != "verarbeitet" %}
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-check-circle me-2"></i>Als verarbeitet markieren
</div>
<div class="card-body">
<form method="post">
{% csrf_token %}
<input type="hidden" name="action" value="mark_verarbeitet">
<div class="mb-3">
<label class="form-label">Interne Notiz (optional)</label>
<textarea class="form-control" name="notizen" rows="3"
placeholder="Z. B. 'Studiennachweis für WS 2025/26 eingegangen und geprüft.'">{{ eingang.notizen }}</textarea>
</div>
<button type="submit" class="btn btn-success w-100">
<i class="fas fa-check me-1"></i>Verarbeitet
</button>
</form>
</div>
</div>
{% endif %}
<!-- Notizen bearbeiten -->
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-sticky-note me-2"></i>Interne Notizen
</div>
<div class="card-body">
<form method="post">
{% csrf_token %}
<input type="hidden" name="action" value="save_notizen">
<div class="mb-3">
<textarea class="form-control" name="notizen" rows="5"
placeholder="Interne Notizen zur E-Mail...">{{ eingang.notizen }}</textarea>
</div>
<button type="submit" class="btn btn-outline-secondary w-100">
<i class="fas fa-save me-1"></i>Notizen speichern
</button>
</form>
</div>
</div>
<!-- Metadaten -->
<div class="card">
<div class="card-header"><i class="fas fa-info-circle me-2"></i>Metadaten</div>
<div class="card-body">
<dl class="row mb-0 small">
<dt class="col-6">Erfasst am</dt>
<dd class="col-6">{{ eingang.created_at|date:"d.m.Y H:i" }}</dd>
<dt class="col-6">Datensatz-ID</dt>
<dd class="col-6 text-muted"><code>{{ eingang.pk|stringformat:"s"|slice:":8" }}…</code></dd>
</dl>
</div>
</div>
</div>
</div>
{% endblock %}