Files
stiftung-management-system/app/templates/stiftung/zahlungs_pipeline.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

163 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 %}Zahlungs-Pipeline 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-tasks text-primary me-2"></i>
Zahlungs-Pipeline
</h1>
<div class="d-flex gap-2">
<a href="{% url 'stiftung:sepa_xml_export' %}" class="btn btn-outline-success">
<i class="fas fa-file-code me-2"></i>SEPA XML exportieren
</a>
<a href="{% url 'stiftung:unterstuetzung_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-2"></i>Neue Zahlung
</a>
</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">Destinatär:</label>
<select name="destinataer" class="form-select form-select-sm" style="width:200px" onchange="this.form.submit()">
<option value="">Alle</option>
{% for d in destinataere %}
<option value="{{ d.pk }}" {% if d.pk|stringformat:'s' == destinataer_filter %}selected{% endif %}>{{ d.get_full_name }}</option>
{% endfor %}
</select>
</div>
<div class="d-flex align-items-center gap-2">
<label class="text-muted small fw-bold mb-0">Konto:</label>
<select name="konto" class="form-select form-select-sm" style="width:180px" onchange="this.form.submit()">
<option value="">Alle</option>
{% for k in konten %}
<option value="{{ k.pk }}" {% if k.pk|stringformat:'s' == konto_filter %}selected{% endif %}>{{ k.kontoname }}</option>
{% endfor %}
</select>
</div>
{% if destinataer_filter or konto_filter %}
<a href="{% url 'stiftung:zahlungs_pipeline' %}" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-times"></i> Filter zurücksetzen
</a>
{% endif %}
</form>
</div>
</div>
<!-- 4-Augen Hinweis -->
<div class="alert alert-warning py-2 mb-4 small">
<i class="fas fa-shield-alt me-2"></i>
<strong>Vier-Augen-Prinzip:</strong>
Zahlungen können nur von einem <em>anderen</em> Nutzer als dem Ersteller freigegeben werden.
SEPA-Export ist nur für Zahlungen im Status „Freigegeben" verfügbar.
</div>
<!-- Pipeline Kanban -->
<div class="row g-3">
{% for stage in pipeline_stages %}
<div class="col-xl col-lg-4 col-md-6">
<div class="card shadow h-100">
<div class="card-header bg-{{ stage.farbe }} {% if stage.farbe == 'secondary' or stage.farbe == 'dark' %}text-white{% elif stage.farbe == 'warning' %}text-dark{% else %}text-white{% endif %} py-2">
<div class="d-flex justify-content-between align-items-center">
<span class="fw-semibold small">
<i class="fas {{ stage.icon }} me-1"></i>{{ stage.label }}
</span>
<span class="badge bg-white text-dark">{{ stage.zahlungen|length }}</span>
</div>
{% if stage.gesamt > 0 %}
<div class="small opacity-75 mt-1">€{{ stage.gesamt|floatformat:2 }}</div>
{% endif %}
</div>
<div class="card-body p-2" style="max-height: 600px; overflow-y: auto;">
{% if stage.zahlungen %}
{% for z in stage.zahlungen %}
<div class="card mb-2 border shadow-sm" style="font-size:0.8rem;">
<div class="card-body py-2 px-2">
<div class="d-flex justify-content-between align-items-start">
<div class="fw-semibold">
<a href="{% url 'stiftung:destinataer_detail' pk=z.destinataer.pk %}" class="text-decoration-none text-dark">
{{ z.destinataer.get_full_name }}
</a>
</div>
<span class="badge bg-{{ stage.farbe }} {% if stage.farbe == 'warning' %}text-dark{% else %}text-white{% endif %}">
€{{ z.betrag|floatformat:2 }}
</span>
</div>
<div class="text-muted mt-1">
Fällig: {{ z.faellig_am|date:"d.m.Y" }}
{% if z.is_overdue %}
<span class="badge bg-danger ms-1">überfällig</span>
{% endif %}
</div>
{% if z.beschreibung %}
<div class="text-muted small mt-1">{{ z.beschreibung }}</div>
{% endif %}
{% if z.freigegeben_von %}
<div class="small text-success mt-1">
<i class="fas fa-shield-alt"></i>
{{ z.freigegeben_von.get_full_name|default:z.freigegeben_von.username }}
({{ z.freigegeben_am|date:"d.m.Y" }})
</div>
{% endif %}
<!-- Actions -->
<div class="mt-2 d-flex gap-1 flex-wrap">
{% if stage.key == 'offen' %}
<form method="post" action="{% url 'stiftung:unterstuetzung_nachweis_eingereicht' pk=z.pk %}">
{% csrf_token %}
<input type="hidden" name="next" value="{% url 'stiftung:zahlungs_pipeline' %}">
<button type="submit" class="btn btn-xs btn-outline-info" style="font-size:0.7rem;padding:2px 6px;" title="Nachweis eingereicht">
<i class="fas fa-file-alt"></i>
</button>
</form>
{% elif stage.key == 'nachweis_eingereicht' %}
<form method="post" action="{% url 'stiftung:unterstuetzung_freigeben' pk=z.pk %}">
{% csrf_token %}
<input type="hidden" name="next" value="{% url 'stiftung:zahlungs_pipeline' %}">
<button type="submit" class="btn btn-xs btn-outline-warning" style="font-size:0.7rem;padding:2px 6px;" title="4-Augen-Freigabe">
<i class="fas fa-shield-alt"></i>
</button>
</form>
{% elif stage.key == 'freigegeben' %}
<a href="{% url 'stiftung:unterstuetzung_mark_paid' pk=z.pk %}" class="btn btn-xs btn-outline-success" style="font-size:0.7rem;padding:2px 6px;" title="Als überwiesen markieren">
<i class="fas fa-university"></i>
</a>
{% elif stage.key == 'ueberwiesen' %}
<form method="post" action="{% url 'stiftung:unterstuetzung_abschliessen' pk=z.pk %}">
{% csrf_token %}
<input type="hidden" name="next" value="{% url 'stiftung:zahlungs_pipeline' %}">
<button type="submit" class="btn btn-xs btn-outline-dark" style="font-size:0.7rem;padding:2px 6px;" title="Abschließen">
<i class="fas fa-check-double"></i>
</button>
</form>
{% endif %}
<a href="{% url 'stiftung:unterstuetzung_detail' pk=z.pk %}" class="btn btn-xs btn-outline-secondary" style="font-size:0.7rem;padding:2px 6px;" title="Details">
<i class="fas fa-eye"></i>
</a>
</div>
</div>
</div>
{% endfor %}
{% else %}
<div class="text-muted text-center small py-4">
<i class="fas fa-inbox fa-2x mb-2 d-block opacity-25"></i>
Keine Zahlungen
</div>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% endblock %}