Files
stiftung-management-system/app/templates/stiftung/nachweis_board.html
SysAdmin Agent ee2c827d85 Phase 2: Destinatär-Timeline, Nachweis-Board, Zahlungs-Pipeline & Pächter-Workflow
2a. Destinatär-Timeline (/destinataere/<pk>/timeline/)
    - Chronologische Ansicht aller Events (Zahlungen, Nachweise, E-Mails, Notizen)
    - Filter nach Typ via GET-Parameter

2b. Nachweis-Board (/nachweis-board/)
    - Quartals-Übersicht aller aktiver Destinatäre (Q1–Q4) in einer Tabellenansicht
    - Batch-Erinnerung: erzeugt Audit-Log-Einträge für säumige Destinatäre
    - Semester-Logik erhalten (15.03 / 15.09 Fristen)

2c. Zahlungs-Pipeline (/zahlungs-pipeline/)
    - 5-Stufen-Kanban: Offen → Nachweis eingereicht → Freigegeben → Überwiesen → Abgeschlossen
    - Vier-Augen-Prinzip: can_be_freigegeben() prüft anderen Nutzer als Ersteller
    - SEPA pain.001 XML-Export (/sepa-export/) für freigegebene Zahlungen
    - Neue Status-Werte: nachweis_eingereicht, freigegeben, abgeschlossen
    - Neue Felder: freigegeben_von, freigegeben_am, erstellt_von

2d. Pächter-Workflow (/paechter/workflow/)
    - Pipeline nach Restlaufzeit: abgelaufen / <6M / 6–24M / >24M / unbefristet
    - Ausstehende Jahresabrechnungen (Vorjahr ohne Abrechnung)
    - Pachtanpassungen fällig (Verträge > 5 Jahre laufend)
    - Top-Pächter nach Gesamtfläche

Sidebar-Navigation um Pipeline, Nachweis-Board und Pacht-Workflow erweitert.
Migration 0047 erzeugt und angewendet.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 10:40:43 +00:00

171 lines
9.7 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 static %}
{% 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">
{% 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>
{% 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 %}