Files
SysAdmin Agent aed540fe4b
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
Add Vorlagen editor, upload portal, onboarding, and participant import command
- Dokument-Vorlagen-Editor: create/edit/reset document templates (admin)
- Upload-Portal: public portal for Nachweis uploads via token
- Onboarding: invite Destinatäre via email with multi-step wizard
- Bestätigungsschreiben: preview and send confirmation letters
- Email settings: SMTP configuration UI
- Management command: import_veranstaltung_teilnehmer for bulk participant import

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

186 lines
11 KiB
HTML
Raw Permalink 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 static help_tags %}
{% block title %}Nachweis-Board Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<!-- Header -->
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3">
<i class="fas fa-th text-primary me-2"></i>
Nachweis-Board {{ jahr_filter }}
</h1>
<div class="d-flex gap-2">
<form method="post" action="{% url 'stiftung:batch_nachweis_aufforderung_senden' %}">
{% csrf_token %}
<input type="hidden" name="jahr" value="{{ jahr_filter }}">
<button type="submit" class="btn btn-primary" onclick="return confirm('Nachweis-Aufforderungs-E-Mails für alle offenen Nachweise {{ jahr_filter }} versenden?')">
<i class="fas fa-paper-plane me-2"></i>Aufforderungen senden
</button>
</form>
{% if overdue_count > 0 %}
<form method="post" action="{% url 'stiftung:batch_erinnerung_senden' %}">
{% csrf_token %}
<input type="hidden" name="jahr" value="{{ jahr_filter }}">
<button type="submit" class="btn btn-danger" onclick="return confirm('{{ overdue_count }} säumige Destinatäre markieren?')">
<i class="fas fa-bell me-2"></i>{{ overdue_count }} Erinnerung(en)
</button>
</form>
{% endif %}
</div>
</div>
<!-- Filter Bar -->
<div class="card shadow mb-4">
<div class="card-body py-2">
<form method="get" class="d-flex gap-3 flex-wrap align-items-center">
<div class="d-flex align-items-center gap-2">
<label class="text-muted small fw-bold mb-0">Jahr:</label>
<select name="jahr" class="form-select form-select-sm" style="width: auto;" onchange="this.form.submit()">
{% for j in verfuegbare_jahre %}
<option value="{{ j }}" {% if j == jahr_filter %}selected{% endif %}>{{ j }}</option>
{% endfor %}
</select>
</div>
<div class="d-flex align-items-center gap-2">
<label class="text-muted small fw-bold mb-0">Status:</label>
<select name="status" class="form-select form-select-sm" style="width: auto;" onchange="this.form.submit()">
<option value="">Alle</option>
{% for code, label in status_choices %}
<option value="{{ code }}" {% if code == status_filter %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
</div>
<span class="ms-auto text-muted small">{{ board|length }} Destinatäre</span>
</form>
</div>
</div>
<!-- Semester-Hinweis -->
<div class="alert alert-info py-2 mb-4 small">
<i class="fas fa-info-circle me-2"></i>
<strong>Semester-Logik:</strong>
Studiennachweis-Frist Q1/Q2 → 15. März · Q3/Q4 → 15. September.
Zahlungsfrist Q1 → 15. Dez (Vorjahr) · Q2 → 15. Mär · Q3 → 15. Jun · Q4 → 15. Sep.
</div>
<!-- Board Table -->
{% if board %}
<div class="card shadow">
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-hover table-sm mb-0">
<thead class="table-dark">
<tr>
<th style="min-width:180px">Destinatär</th>
<th class="text-center">Q1 (JanMär)</th>
<th class="text-center">Q2 (AprJun)</th>
<th class="text-center">Q3 (JulSep)</th>
<th class="text-center">Q4 (OktDez)</th>
<th class="text-center">Gesamt</th>
</tr>
</thead>
<tbody>
{% for row in board %}
<tr>
<td class="align-middle">
<a href="{% url 'stiftung:destinataer_detail' pk=row.destinataer.pk %}" class="text-decoration-none fw-semibold">
{{ row.destinataer.get_full_name }}
</a>
<div class="small text-muted">
<a href="{% url 'stiftung:destinataer_timeline' pk=row.destinataer.pk %}" class="text-muted">
<i class="fas fa-stream"></i> Timeline
</a>
</div>
</td>
{% for q in "1234" %}
{% with nachweis=row.quartale|get_item:q|default:None %}
<td class="text-center align-middle">
{% if nachweis %}
{% if nachweis.status == 'geprueft' or nachweis.status == 'auto_geprueft' %}
<span class="badge bg-success" title="{{ nachweis.get_status_display }}">
<i class="fas fa-check"></i>
</span>
{% elif nachweis.status == 'eingereicht' %}
<span class="badge bg-info" title="{{ nachweis.get_status_display }}">
<i class="fas fa-paper-plane"></i>
</span>
{% elif nachweis.status == 'teilweise' %}
<span class="badge bg-warning text-dark" title="{{ nachweis.get_status_display }}">
<i class="fas fa-circle-half-stroke"></i>
</span>
{% elif nachweis.status == 'nachbesserung' %}
<span class="badge bg-orange" title="{{ nachweis.get_status_display }}" style="background:#fd7e14">
<i class="fas fa-redo"></i>
</span>
{% elif nachweis.status == 'abgelehnt' %}
<span class="badge bg-danger" title="{{ nachweis.get_status_display }}">
<i class="fas fa-times"></i>
</span>
{% elif nachweis.is_overdue %}
<span class="badge bg-danger" title="Überfällig">
<i class="fas fa-exclamation-triangle"></i>
</span>
{% else %}
<span class="badge bg-secondary" title="{{ nachweis.get_status_display }}">
<i class="fas fa-clock"></i>
</span>
{% endif %}
<div class="small mt-1">
<a href="{% url 'stiftung:quarterly_confirmation_edit' pk=nachweis.pk %}" class="text-muted">
{{ nachweis.get_completion_percentage }}%
</a>
</div>
{% if nachweis.status == 'offen' or nachweis.status == 'teilweise' or nachweis.status == 'nachbesserung' %}{% if row.destinataer.email %}
<form method="post" action="{% url 'stiftung:nachweis_aufforderung_senden' nachweis_pk=nachweis.pk %}" class="mt-1">
{% csrf_token %}
<button type="submit" class="btn btn-outline-primary btn-xs" style="font-size:0.65rem;padding:1px 5px;" title="Upload-Link per E-Mail senden" onclick="return confirm('Upload-Aufforderung an {{ row.destinataer.email }} senden?')">
<i class="fas fa-paper-plane"></i>
</button>
</form>
{% endif %}{% endif %}
{% else %}
<span class="text-muted small"></span>
{% endif %}
</td>
{% endwith %}
{% endfor %}
<td class="text-center align-middle">
{% with total=0 done=0 %}
{% for q, nachweis in row.quartale.items %}
{% if nachweis %}
{% if nachweis.status == 'geprueft' or nachweis.status == 'auto_geprueft' %}
<i class="fas fa-check-circle text-success"></i>
{% endif %}
{% endif %}
{% endfor %}
{% endwith %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<!-- Legend -->
<div class="mt-3 d-flex flex-wrap gap-3 small text-muted">
<span><span class="badge bg-success"><i class="fas fa-check"></i></span> Geprüft</span>
<span><span class="badge bg-info"><i class="fas fa-paper-plane"></i></span> Eingereicht</span>
<span><span class="badge bg-warning text-dark"><i class="fas fa-circle-half-stroke"></i></span> Teilweise</span>
<span><span class="badge bg-danger"><i class="fas fa-exclamation-triangle"></i></span> Überfällig</span>
<span><span class="badge bg-secondary"><i class="fas fa-clock"></i></span> Offen</span>
</div>
{% else %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
Keine aktiven Destinatäre gefunden.
</div>
{% endif %}
</div>
</div>
{% endblock %}