feat: add comprehensive GitHub workflow and development tools

This commit is contained in:
Stiftung Development
2025-09-06 18:31:54 +02:00
commit ab23d7187e
10224 changed files with 2075210 additions and 0 deletions

View File

@@ -0,0 +1,256 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Administration - 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-cogs me-2"></i>Administration
</h1>
</div>
</div>
</div>
<!-- Statistiken -->
<div class="row mb-4">
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Audit Logs Gesamt</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.total_logs|default:0|intcomma }}</div>
</div>
<div class="col-auto">
<i class="fas fa-history fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Heute</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.logs_today|default:0 }}</div>
</div>
<div class="col-auto">
<i class="fas fa-calendar-day fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-info shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-info text-uppercase mb-1">Diese Woche</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.logs_week|default:0 }}</div>
</div>
<div class="col-auto">
<i class="fas fa-calendar-week fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-warning shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Letztes Backup</div>
<div class="small text-gray-800">
{% if stats.last_backup %}
{{ stats.last_backup.completed_at|date:"d.m.Y H:i" }}
{% else %}
Kein Backup vorhanden
{% endif %}
</div>
</div>
<div class="col-auto">
<i class="fas fa-database fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Aktuelle Audit-Aktivität -->
<div class="col-lg-8">
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-history me-2"></i>Aktuelle Audit-Aktivität
</h6>
<a href="{% url 'stiftung:audit_log_list' %}" class="btn btn-primary btn-sm">
<i class="fas fa-list me-1"></i>Alle Logs anzeigen
</a>
</div>
<div class="card-body">
{% if recent_audit %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Zeit</th>
<th>Benutzer</th>
<th>Aktion</th>
<th>Beschreibung</th>
</tr>
</thead>
<tbody>
{% for log in recent_audit %}
<tr>
<td>
<small>{{ log.timestamp|date:"d.m. H:i" }}</small>
</td>
<td>
<span class="badge bg-secondary">{{ log.username }}</span>
</td>
<td>
<span class="badge bg-{% if log.action == 'create' %}success{% elif log.action == 'update' %}warning{% elif log.action == 'delete' %}danger{% else %}info{% endif %}">
{{ log.get_action_display }}
</span>
</td>
<td>
<small>{{ log.description|truncatechars:80 }}</small>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-history fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Audit-Logs vorhanden</h5>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Benutzeraktivität -->
<div class="col-lg-4">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-users me-2"></i>Benutzeraktivität
</h6>
</div>
<div class="card-body">
{% if user_activity %}
{% for user in user_activity %}
<div class="d-flex justify-content-between align-items-center mb-2">
<span class="text-sm">{{ user.username }}</span>
<span class="badge bg-primary">{{ user.count }}</span>
</div>
{% endfor %}
{% else %}
<p class="text-muted">Keine Benutzeraktivität erfasst</p>
{% endif %}
</div>
</div>
<!-- Backup Status -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-database me-2"></i>Backup Status
</h6>
<a href="{% url 'stiftung:backup_management' %}" class="btn btn-primary btn-sm">
<i class="fas fa-cog me-1"></i>Verwalten
</a>
</div>
<div class="card-body">
{% if stats.recent_backups %}
{% for backup in stats.recent_backups %}
<div class="d-flex justify-content-between align-items-center mb-2">
<div>
<small class="text-muted">{{ backup.created_at|date:"d.m. H:i" }}</small><br>
<span class="text-sm">{{ backup.get_backup_type_display }}</span>
</div>
<span class="badge bg-{% if backup.status == 'completed' %}success{% elif backup.status == 'failed' %}danger{% elif backup.status == 'running' %}primary{% else %}secondary{% endif %}">
{{ backup.get_status_display }}
</span>
</div>
{% endfor %}
{% else %}
<p class="text-muted">Keine Backups vorhanden</p>
<a href="{% url 'stiftung:backup_management' %}" class="btn btn-success btn-sm">
<i class="fas fa-plus me-1"></i>Erstes Backup erstellen
</a>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Schnellzugriff -->
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-tachometer-alt me-2"></i>Schnellzugriff
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:audit_log_list' %}" class="btn btn-outline-primary w-100">
<i class="fas fa-history d-block mb-2 fa-2x"></i>
<span>Audit Logs</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:backup_management' %}" class="btn btn-outline-success w-100">
<i class="fas fa-database d-block mb-2 fa-2x"></i>
<span>Backup & Restore</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:unterstuetzungen_list' %}" class="btn btn-outline-success w-100">
<i class="fas fa-hand-holding-usd d-block mb-2 fa-2x"></i>
<span>Destinatärunterstützungen</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="/admin/" class="btn btn-outline-warning w-100" target="_blank">
<i class="fas fa-user-shield d-block mb-2 fa-2x"></i>
<span>Django Admin</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:user_management' %}" class="btn btn-outline-info w-100">
<i class="fas fa-users d-block mb-2 fa-2x"></i>
<span>Benutzerverwaltung</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-outline-secondary w-100">
<i class="fas fa-folder-open d-block mb-2 fa-2x"></i>
<span>Dokumentenverwaltung</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,234 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Audit Logs - Administration - 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-history me-2"></i>Audit Logs
</h1>
<a href="{% url 'stiftung:administration' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Administration
</a>
</div>
</div>
</div>
<!-- Filter -->
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-filter me-2"></i>Filter
</div>
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-2">
<label class="form-label">Benutzer</label>
<input type="text" class="form-control" name="user" value="{{ user_filter }}" placeholder="Benutzername...">
</div>
<div class="col-md-2">
<label class="form-label">Aktion</label>
<select class="form-select" name="action">
<option value="">Alle Aktionen</option>
{% for value, display in action_choices %}
<option value="{{ value }}" {% if action_filter == value %}selected{% endif %}>{{ display }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label class="form-label">Entitätstyp</label>
<select class="form-select" name="entity_type">
<option value="">Alle Typen</option>
{% for value, display in entity_choices %}
<option value="{{ value }}" {% if entity_filter == value %}selected{% endif %}>{{ display }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label class="form-label">Von Datum</label>
<input type="date" class="form-control" name="date_from" value="{{ date_from }}">
</div>
<div class="col-md-2">
<label class="form-label">Bis Datum</label>
<input type="date" class="form-control" name="date_to" value="{{ date_to }}">
</div>
<div class="col-md-2 d-flex align-items-end">
<div class="btn-group w-100">
<button type="submit" class="btn btn-primary">
<i class="fas fa-search me-1"></i>Filtern
</button>
<a href="{% url 'stiftung:audit_log_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Reset
</a>
</div>
</div>
</form>
</div>
</div>
<!-- Audit Logs -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Audit Log Einträge
<span class="badge bg-primary ms-2">{{ page_obj.paginator.count|intcomma }}</span>
</h6>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Zeitpunkt</th>
<th>Benutzer</th>
<th>Aktion</th>
<th>Entität</th>
<th>Beschreibung</th>
<th>IP</th>
<th>Details</th>
</tr>
</thead>
<tbody>
{% for log in page_obj %}
<tr>
<td>
<small>{{ log.timestamp|date:"d.m.Y" }}</small><br>
<small class="text-muted">{{ log.timestamp|date:"H:i:s" }}</small>
</td>
<td>
<span class="badge bg-secondary">{{ log.username }}</span>
</td>
<td>
<span class="badge bg-{% if log.action == 'create' %}success{% elif log.action == 'update' %}warning{% elif log.action == 'delete' %}danger{% elif log.action == 'login' %}info{% elif log.action == 'logout' %}secondary{% elif log.action == 'backup' %}primary{% elif log.action == 'restore' %}warning{% else %}light{% endif %}">
{{ log.get_action_display }}
</span>
</td>
<td>
<div>
<span class="badge bg-light text-dark">{{ log.get_entity_type_display }}</span>
{% if log.entity_name %}
<br><small class="text-muted">{{ log.entity_name|truncatechars:30 }}</small>
{% endif %}
</div>
</td>
<td>
<small>{{ log.description|truncatechars:60 }}</small>
</td>
<td>
{% if log.ip_address %}
<small class="text-muted">{{ log.ip_address }}</small>
{% else %}
<small class="text-muted">-</small>
{% endif %}
</td>
<td>
{% if log.changes %}
<button class="btn btn-outline-info btn-sm" onclick="showDetails('{{ log.id }}')">
<i class="fas fa-eye"></i>
</button>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Audit Log Pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ page_obj.previous_page_number }}">Vorherige</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ page_obj.next_page_number }}">Nächste</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-history fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Audit Logs gefunden</h5>
<p class="text-muted">Passen Sie die Filter an oder überprüfen Sie die Suchkriterien.</p>
</div>
{% endif %}
</div>
</div>
<!-- Details Modal -->
<div class="modal fade" id="detailsModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Änderungsdetails</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div id="detailsContent">
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Lädt...</span>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function showDetails(logId) {
const modal = new bootstrap.Modal(document.getElementById('detailsModal'));
const content = document.getElementById('detailsContent');
// Show loading spinner
content.innerHTML = `
<div class="text-center">
<div class="spinner-border" role="status">
<span class="visually-hidden">Lädt...</span>
</div>
</div>
`;
modal.show();
// Fetch details - for now just show that the feature is available
// In a full implementation, you'd fetch the log details via AJAX
setTimeout(() => {
content.innerHTML = `
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
Detailansicht für Log-ID: ${logId}<br>
<small>Diese Funktion kann erweitert werden, um detaillierte Änderungsinformationen anzuzeigen.</small>
</div>
`;
}, 500);
}
</script>
{% endblock %}

View File

@@ -0,0 +1,262 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Backup & Restore - Administration - 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-database me-2"></i>Backup & Restore
</h1>
<a href="{% url 'stiftung:administration' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Administration
</a>
</div>
</div>
</div>
<div class="row">
<!-- Backup Erstellung -->
<div class="col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-plus me-2"></i>Neues Backup erstellen
</h6>
</div>
<div class="card-body">
<form method="post">
{% csrf_token %}
<div class="mb-3">
<label class="form-label">Backup-Typ</label>
<select class="form-select" name="backup_type" required>
{% for value, display in backup_types %}
<option value="{{ value }}">{{ display }}</option>
{% endfor %}
</select>
<div class="form-text">
<strong>Vollständiges Backup:</strong> Datenbank + Dateien + Konfiguration<br>
<strong>Nur Datenbank:</strong> PostgreSQL Dump<br>
<strong>Nur Dateien:</strong> Uploads und Konfigurationsdateien
</div>
</div>
<button type="submit" class="btn btn-success">
<i class="fas fa-play me-1"></i>Backup starten
</button>
</form>
</div>
</div>
</div>
<!-- Restore -->
<div class="col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-warning">
<i class="fas fa-upload me-2"></i>Wiederherstellung
</h6>
</div>
<div class="card-body">
<div class="alert alert-warning">
<i class="fas fa-exclamation-triangle me-2"></i>
<strong>Warnung:</strong> Die Wiederherstellung überschreibt alle aktuellen Daten!
</div>
<form method="post" action="{% url 'stiftung:backup_restore' %}" enctype="multipart/form-data">
{% csrf_token %}
<div class="mb-3">
<label class="form-label">Backup-Datei auswählen</label>
<input type="file" class="form-control" name="backup_file" accept=".tar.gz" required>
<div class="form-text">
Nur .tar.gz Dateien von diesem System sind erlaubt.
</div>
</div>
<button type="submit" class="btn btn-warning" onclick="return confirm('Sind Sie sicher? Diese Aktion überschreibt alle aktuellen Daten!')">
<i class="fas fa-undo me-1"></i>Wiederherstellung starten
</button>
</form>
</div>
</div>
</div>
</div>
<!-- Backup Historie -->
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-history me-2"></i>Backup Historie
{% if page_obj %}
<span class="badge bg-primary ms-2">{{ page_obj.paginator.count }}</span>
{% endif %}
</h6>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Erstellt</th>
<th>Typ</th>
<th>Status</th>
<th>Größe</th>
<th>Dauer</th>
<th>Erstellt von</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for backup in page_obj %}
<tr>
<td>
<div>{{ backup.created_at|date:"d.m.Y" }}</div>
<small class="text-muted">{{ backup.created_at|date:"H:i:s" }}</small>
</td>
<td>
<span class="badge bg-info">{{ backup.get_backup_type_display }}</span>
</td>
<td>
<span class="badge bg-{% if backup.status == 'completed' %}success{% elif backup.status == 'failed' %}danger{% elif backup.status == 'running' %}primary{% else %}secondary{% endif %}">
{{ backup.get_status_display }}
</span>
{% if backup.status == 'running' %}
<br><small class="text-muted">
{% if backup.get_duration %}
Läuft seit {{ backup.get_duration.total_seconds|floatformat:0 }}s
{% endif %}
</small>
{% endif %}
</td>
<td>
{% if backup.backup_size %}
{{ backup.get_size_display }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if backup.get_duration %}
{{ backup.get_duration.total_seconds|floatformat:1 }}s
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if backup.created_by %}
<span class="badge bg-secondary">{{ backup.created_by.username }}</span>
{% else %}
<span class="text-muted">System</span>
{% endif %}
</td>
<td>
{% if backup.status == 'completed' %}
<a href="{% url 'stiftung:backup_download' backup.id %}" class="btn btn-outline-primary btn-sm" title="Herunterladen">
<i class="fas fa-download"></i>
</a>
{% elif backup.status == 'failed' %}
<button class="btn btn-outline-danger btn-sm" onclick="showError('{{ backup.error_message|escapejs }}')" title="Fehler anzeigen">
<i class="fas fa-exclamation-triangle"></i>
</button>
{% elif backup.status == 'running' %}
<button class="btn btn-outline-primary btn-sm" disabled title="Läuft...">
<i class="fas fa-spinner fa-spin"></i>
</button>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Backup Pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">Vorherige</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}">Nächste</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-database fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Backups vorhanden</h5>
<p class="text-muted">Erstellen Sie Ihr erstes Backup über das Formular oben.</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Error Modal -->
<div class="modal fade" id="errorModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Backup Fehler</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div id="errorContent"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
</div>
</div>
</div>
<script>
function showError(errorMessage) {
const modal = new bootstrap.Modal(document.getElementById('errorModal'));
document.getElementById('errorContent').innerHTML = `
<div class="alert alert-danger">
<i class="fas fa-exclamation-triangle me-2"></i>
${errorMessage}
</div>
`;
modal.show();
}
// Auto-refresh for running backups
document.addEventListener('DOMContentLoaded', function() {
const runningBackups = document.querySelectorAll('.fa-spinner');
if (runningBackups.length > 0) {
// Refresh page every 10 seconds if there are running backups
setTimeout(() => {
window.location.reload();
}, 10000);
}
});
</script>
{% endblock %}

View File

@@ -0,0 +1,201 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Berichte - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<h1 class="h3 mb-4">
<i class="fas fa-chart-bar text-primary me-2"></i>Berichte & Auswertungen
</h1>
</div>
</div>
<div class="row">
<!-- Jahresberichte -->
<div class="col-lg-6 mb-4">
<div class="card shadow h-100">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-calendar-alt me-2"></i>Jahresberichte
</h6>
</div>
<div class="card-body">
<p class="text-muted mb-4">
Generieren Sie detaillierte Jahresberichte mit allen wichtigen Informationen zu Personen,
Förderungen und Ländereien.
</p>
<form method="get" action="{% url 'stiftung:jahresbericht_generate_redirect' %}">
<div class="row g-3">
<div class="col-md-6">
<label for="jahr" class="form-label">Jahr auswählen</label>
<select name="jahr" id="jahr" class="form-select" required>
<option value="">Jahr wählen...</option>
{% for year in jahre %}
<option value="{{ year }}">{{ year }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-6 d-flex align-items-end">
<button type="submit" class="btn btn-primary w-100">
<i class="fas fa-file-alt me-2"></i>Bericht generieren
</button>
</div>
</div>
</form>
<div class="mt-4">
<h6 class="text-primary">Verfügbare Berichte:</h6>
<div class="list-group list-group-flush">
{% for year in jahre %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<span>Jahresbericht {{ year }}</span>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:jahresbericht_generate' year %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye me-1"></i>Anzeigen
</a>
<a href="{% url 'stiftung:jahresbericht_pdf' year %}" class="btn btn-sm btn-outline-success">
<i class="fas fa-download me-1"></i>PDF
</a>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
<!-- Statistik-Übersicht -->
<div class="col-lg-6 mb-4">
<div class="card shadow h-100">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-chart-pie me-2"></i>Statistik-Übersicht
</h6>
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-6">
<div class="card bg-primary text-white">
<div class="card-body text-center">
<i class="fas fa-users fa-2x mb-2"></i>
<h5 class="card-title">Personen</h5>
<h3 class="card-text">{{ total_persons|default:"0" }}</h3>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card bg-success text-white">
<div class="card-body text-center">
<i class="fas fa-gift fa-2x mb-2"></i>
<h5 class="card-title">Förderungen</h5>
<h3 class="card-text">{{ total_foerderungen|default:"0" }}</h3>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card bg-secondary text-white">
<div class="card-body text-center">
<i class="fas fa-user-friends fa-2x mb-2"></i>
<h5 class="card-title">Destinatäre</h5>
<h3 class="card-text">{{ total_destinataere|default:"0" }}</h3>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card bg-info text-white">
<div class="card-body text-center">
<i class="fas fa-map fa-2x mb-2"></i>
<h5 class="card-title">Ländereien</h5>
<h3 class="card-text">{{ total_laendereien|default:"0" }}</h3>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card bg-warning text-white">
<div class="card-body text-center">
<i class="fas fa-handshake fa-2x mb-2"></i>
<h5 class="card-title">Verpachtungen</h5>
<h3 class="card-text">{{ total_verpachtungen|default:"0" }}</h3>
</div>
</div>
</div>
</div>
<div class="mt-4">
<h6 class="text-primary">Schnellzugriff:</h6>
<div class="d-grid gap-2">
<a href="{% url 'stiftung:person_list' %}" class="btn btn-outline-primary">
<i class="fas fa-users me-2"></i>Alle Personen anzeigen
</a>
<a href="{% url 'stiftung:foerderung_list' %}" class="btn btn-outline-success">
<i class="fas fa-gift me-2"></i>Alle Förderungen anzeigen
</a>
<a href="{% url 'stiftung:land_list' %}" class="btn btn-outline-info">
<i class="fas fa-map me-2"></i>Alle Ländereien anzeigen
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Zusätzliche Berichte -->
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-cogs me-2"></i>Weitere Berichtstypen
</h6>
</div>
<div class="card-body">
<div class="row g-4">
<div class="col-md-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-body text-center">
<i class="fas fa-euro-sign fa-3x text-success mb-3"></i>
<h5 class="card-title">Finanzberichte</h5>
<p class="card-text">Detaillierte Auswertungen zu Förderungen und Ausgaben.</p>
<button class="btn btn-outline-success" disabled>
<i class="fas fa-clock me-2"></i>In Entwicklung
</button>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-body text-center">
<i class="fas fa-chart-line fa-3x text-info mb-3"></i>
<h5 class="card-title">Trendanalysen</h5>
<p class="card-text">Langzeitentwicklungen und Prognosen für die Zukunft.</p>
<button class="btn btn-outline-info" disabled>
<i class="fas fa-clock me-2"></i>In Entwicklung
</button>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-body text-center">
<i class="fas fa-file-export fa-3x text-warning mb-3"></i>
<h5 class="card-title">Export-Funktionen</h5>
<p class="card-text">Datenexport in verschiedene Formate (Excel, CSV, PDF).</p>
<button class="btn btn-outline-warning" disabled>
<i class="fas fa-clock me-2"></i>In Entwicklung
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,190 @@
{% extends 'base.html' %}
{% block title %}CSV Import - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1><i class="fas fa-file-csv text-primary"></i> CSV Import</h1>
<a href="{% url 'stiftung:csv_import_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-list"></i> Import-Verlauf
</a>
</div>
<div class="row">
<div class="col-lg-8">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-upload"></i> Neue CSV-Datei importieren
</h5>
</div>
<div class="card-body">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="mb-3">
<label for="import_type" class="form-label">
<strong>Import-Typ *</strong>
</label>
<select name="import_type" id="import_type" class="form-select" required>
<option value="">Bitte wählen...</option>
{% for value, label in import_types %}
<option value="{{ value }}">{{ label }}</option>
{% endfor %}
</select>
<div class="form-text">Wählen Sie den Typ der zu importierenden Daten aus.</div>
</div>
<div class="mb-3">
<label for="csv_file" class="form-label">
<strong>CSV-Datei *</strong>
</label>
<input type="file" name="csv_file" id="csv_file"
class="form-control" accept=".csv" required>
<div class="form-text">Nur CSV-Dateien werden unterstützt.</div>
</div>
<div class="d-grid gap-2 d-md-flex justify-content-md-end">
<a href="{% url 'stiftung:home' %}" class="btn btn-outline-secondary me-md-2">
<i class="fas fa-times"></i> Abbrechen
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-upload"></i> Import starten
</button>
</div>
</form>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card shadow-sm">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">
<i class="fas fa-info-circle"></i> Import-Informationen
</h6>
</div>
<div class="card-body">
<h6>Destinatäre Import:</h6>
<ul class="list-unstyled small">
<li><strong>Pflichtfelder:</strong> Vorname, Nachname</li>
<li><strong>Optionale Felder:</strong> E-Mail, Telefon, IBAN, Straße, PLZ, Ort, Notizen, Geburtsdatum, Familienzweig, Berufsgruppe, Ausbildungsstand, Institution, Projektbeschreibung, Jährliches_Einkommen, Finanzielle_Notlage, Aktiv</li>
<li><strong>Format:</strong> UTF-8 CSV mit Komma oder Semikolon als Trennzeichen</li>
</ul>
<hr>
<h6>Pächter Import:</h6>
<ul class="list-unstyled small">
<li><strong>Pflichtfelder:</strong> Vorname, Nachname</li>
<li><strong>Optionale Felder:</strong> E-Mail, Telefon, IBAN, Straße, PLZ, Ort, Personentyp, Notizen, Geburtsdatum, Pachtnummer, Pachtbeginn_Erste, Pachtende_Letzte, Pachtzins_Aktuell, Landwirtschaftliche_Ausbildung, Berufserfahrung_Jahre, Spezialisierung, Aktiv</li>
<li><strong>Format:</strong> UTF-8 CSV mit Komma oder Semikolon als Trennzeichen</li>
</ul>
<hr>
<h6>Ländereien Import:</h6>
<ul class="list-unstyled small">
<li><strong>Pflichtfelder:</strong> Lfd_Nr, Gemeinde, Gemarkung, Flur, Flurstück</li>
<li><strong>Optionale Felder:</strong> EW_Nummer, Amtsgericht, Größe_qm, Grünland_qm, Acker_qm, Wald_qm, Sonstiges_qm, Verpachtete_Gesamtfläche_qm, Verp_Fläche_aktuell_qm, Aktiv, Notizen</li>
<li><strong>Format:</strong> UTF-8 CSV mit Komma oder Semikolon als Trennzeichen</li>
</ul>
<hr>
<h6>Personen Import (Legacy):</h6>
<ul class="list-unstyled small">
<li><strong>Pflichtfelder:</strong> Vorname, Nachname</li>
<li><strong>Optionale Felder:</strong> E-Mail, Telefon, IBAN, Adresse, Notizen, Geburtsdatum, Familienzweig, Aktiv</li>
<li><strong>Format:</strong> UTF-8 CSV mit Komma oder Semikolon als Trennzeichen</li>
<li><strong>Hinweis:</strong> Nur für Legacy-Daten, neue Daten sollten als Destinatäre oder Pächter importiert werden</li>
</ul>
<div class="alert alert-warning mt-3">
<i class="fas fa-exclamation-triangle"></i>
<strong>Hinweis:</strong> Bestehende Datensätze werden aktualisiert, wenn sie anhand der eindeutigen Felder gefunden werden.
</div>
</div>
</div>
<div class="card shadow-sm mt-3">
<div class="card-header bg-success text-white">
<h6 class="card-title mb-0">
<i class="fas fa-download"></i> CSV-Vorlagen herunterladen
</h6>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="#" class="btn btn-outline-success btn-sm" onclick="downloadTemplate('destinataere')">
<i class="fas fa-download"></i> Destinatäre-Vorlage
</a>
<a href="#" class="btn btn-outline-success btn-sm" onclick="downloadTemplate('paechter')">
<i class="fas fa-download"></i> Pächter-Vorlage
</a>
<a href="#" class="btn btn-outline-success btn-sm" onclick="downloadTemplate('laendereien')">
<i class="fas fa-download"></i> Ländereien-Vorlage
</a>
<a href="#" class="btn btn-outline-secondary btn-sm" onclick="downloadTemplate('personen')">
<i class="fas fa-download"></i> Personen-Vorlage (Legacy)
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
function downloadTemplate(type) {
let headers, filename, exampleRow;
if (type === 'destinataere') {
headers = ['Vorname', 'Nachname', 'Familienzweig', 'E-Mail', 'Telefon', 'IBAN', 'Straße', 'PLZ', 'Ort', 'Geburtsdatum', 'Berufsgruppe', 'Ausbildungsstand', 'Institution', 'Projektbeschreibung', 'Jährliches_Einkommen', 'Finanzielle_Notlage', 'Notizen', 'Aktiv'];
filename = 'destinataere_vorlage.csv';
exampleRow = 'Max,Mustermann,hauptzweig,max@email.com,0123456789,DE12345678901234567890,Musterstraße 1,12345,Musterstadt,01.01.1990,student,Abitur,Universität Musterstadt,Studium der Informatik,15000,false,Beispiel Notiz,true';
} else if (type === 'paechter') {
headers = ['Vorname', 'Nachname', 'E-Mail', 'Telefon', 'IBAN', 'Straße', 'PLZ', 'Ort', 'Personentyp', 'Geburtsdatum', 'Pachtnummer', 'Pachtbeginn_Erste', 'Pachtende_Letzte', 'Pachtzins_Aktuell', 'Landwirtschaftliche_Ausbildung', 'Berufserfahrung_Jahre', 'Spezialisierung', 'Notizen', 'Aktiv'];
filename = 'paechter_vorlage.csv';
exampleRow = 'Hans,Bauer,hans@email.com,0123456789,DE12345678901234567890,Bauernhof 1,12345,Bauerndorf,natuerlich,01.01.1980,P001,01.01.2020,31.12.2029,5000,true,15,Ackerbau,Beispiel Notiz,true';
} else if (type === 'laendereien') {
headers = ['Lfd_Nr', 'EW_Nummer', 'Amtsgericht', 'Gemeinde', 'Gemarkung', 'Flur', 'Flurstück', 'Größe_qm', 'Grünland_qm', 'Acker_qm', 'Wald_qm', 'Sonstiges_qm', 'Verpachtete_Gesamtfläche_qm', 'Verp_Fläche_aktuell_qm', 'Aktiv', 'Notizen'];
filename = 'laendereien_vorlage.csv';
exampleRow = 'L001,EW001,Amtsgericht Musterstadt,Musterstadt,Mustergemarkung,1,123,10000,5000,3000,1500,500,8000,8000,true,Beispiel Notiz';
} else if (type === 'personen') {
headers = ['Vorname', 'Nachname', 'Familienzweig', 'E-Mail', 'Telefon', 'IBAN', 'Adresse', 'Geburtsdatum', 'Notizen', 'Aktiv'];
filename = 'personen_legacy_vorlage.csv';
exampleRow = 'Beispiel,Beispiel,hauptzweig,beispiel@email.com,0123456789,DE12345678901234567890,Beispielstraße 1,01.01.1990,Beispiel Notiz,true';
}
// Create CSV content
const csvContent = headers.join(',') + '\n' + exampleRow;
// Create download link
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const link = document.createElement('a');
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
// File validation
document.getElementById('csv_file').addEventListener('change', function(e) {
const file = e.target.files[0];
if (file && !file.name.toLowerCase().endsWith('.csv')) {
alert('Bitte wählen Sie eine gültige CSV-Datei aus.');
this.value = '';
}
});
</script>
{% endblock %}

View File

@@ -0,0 +1,327 @@
{% extends 'base.html' %}
{% block title %}CSV Import Verlauf - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1><i class="fas fa-history text-primary"></i> CSV Import Verlauf</h1>
<a href="{% url 'stiftung:csv_import_create' %}" class="btn btn-primary">
<i class="fas fa-plus"></i> Neuer Import
</a>
</div>
<!-- Statistics Cards -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-primary text-white">
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h4 class="card-title">{{ page_obj.paginator.count }}</h4>
<p class="card-text">Gesamt Imports</p>
</div>
<div class="align-self-center">
<i class="fas fa-file-csv fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h4 class="card-title">
{{ page_obj.paginator.count|default:0|add:"0"|floatformat:0 }}%
</h4>
<p class="card-text">Erfolgreich</p>
</div>
<div class="align-self-center">
<i class="fas fa-check-circle fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-white">
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h4 class="card-title">
{{ page_obj.paginator.count|default:0|add:"0"|floatformat:0 }}%
</h4>
<p class="card-text">Teilweise</p>
</div>
<div class="align-self-center">
<i class="fas fa-exclamation-triangle fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-danger text-white">
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h4 class="card-title">
{{ page_obj.paginator.count|default:0|add:"0"|floatformat:0 }}%
</h4>
<p class="card-text">Fehlgeschlagen</p>
</div>
<div class="align-self-center">
<i class="fas fa-times-circle fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Import List -->
<div class="card shadow-sm">
<div class="card-header bg-light">
<h5 class="card-title mb-0">
<i class="fas fa-list"></i> Import-Verlauf
</h5>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Typ</th>
<th>Dateiname</th>
<th>Status</th>
<th>Ergebnis</th>
<th>Erstellt von</th>
<th>Gestartet</th>
<th>Dauer</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for import in page_obj %}
<tr>
<td>
<span class="badge bg-primary">
{{ import.get_import_type_display }}
</span>
</td>
<td>
<strong>{{ import.filename }}</strong>
<br>
<small class="text-muted">
{{ import.file_size|filesizeformat }}
</small>
</td>
<td>
{% if import.status == 'completed' %}
<span class="badge bg-success">
<i class="fas fa-check"></i> Abgeschlossen
</span>
{% elif import.status == 'partial' %}
<span class="badge bg-warning">
<i class="fas fa-exclamation-triangle"></i> Teilweise
</span>
{% elif import.status == 'failed' %}
<span class="badge bg-danger">
<i class="fas fa-times"></i> Fehlgeschlagen
</span>
{% elif import.status == 'processing' %}
<span class="badge bg-info">
<i class="fas fa-spinner fa-spin"></i> Wird verarbeitet
</span>
{% else %}
<span class="badge bg-secondary">
{{ import.get_status_display }}
</span>
{% endif %}
</td>
<td>
{% if import.total_rows > 0 %}
<div class="progress" style="height: 20px;">
{% widthratio import.imported_rows import.total_rows 100 as success_percent %}
<div class="progress-bar bg-success" style="width: {{ success_percent }}%">
{{ import.imported_rows }}/{{ import.total_rows }}
</div>
</div>
<small class="text-muted">
Erfolgsrate: {{ import.get_success_rate|floatformat:1 }}%
</small>
{% else %}
<span class="text-muted">Keine Daten</span>
{% endif %}
</td>
<td>
<small>{{ import.created_by|default:"Unbekannt" }}</small>
</td>
<td>
<small>{{ import.started_at|date:"d.m.Y H:i" }}</small>
</td>
<td>
{% if import.get_duration %}
<small>{{ import.get_duration|floatformat:1 }}s</small>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-outline-info btn-sm"
data-bs-toggle="modal"
data-bs-target="#importDetailModal{{ import.id }}">
<i class="fas fa-eye"></i>
</button>
{% if import.error_log %}
<button type="button" class="btn btn-outline-warning btn-sm"
data-bs-toggle="modal"
data-bs-target="#errorModal{{ import.id }}">
<i class="fas fa-exclamation-triangle"></i>
</button>
{% endif %}
</div>
</td>
</tr>
<!-- Import Detail Modal -->
<div class="modal fade" id="importDetailModal{{ import.id }}" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Import-Details</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-6">
<h6>Allgemeine Informationen</h6>
<table class="table table-sm">
<tr><td>Typ:</td><td>{{ import.get_import_type_display }}</td></tr>
<tr><td>Dateiname:</td><td>{{ import.filename }}</td></tr>
<tr><td>Dateigröße:</td><td>{{ import.file_size|filesizeformat }}</td></tr>
<tr><td>Status:</td><td>{{ import.get_status_display }}</td></tr>
<tr><td>Erstellt von:</td><td>{{ import.created_by|default:"Unbekannt" }}</td></tr>
</table>
</div>
<div class="col-md-6">
<h6>Ergebnisse</h6>
<table class="table table-sm">
<tr><td>Gesamtzeilen:</td><td>{{ import.total_rows }}</td></tr>
<tr><td>Importiert:</td><td>{{ import.imported_rows }}</td></tr>
<tr><td>Fehlgeschlagen:</td><td>{{ import.failed_rows }}</td></tr>
<tr><td>Erfolgsrate:</td><td>{{ import.get_success_rate|floatformat:1 }}%</td></tr>
<tr><td>Dauer:</td><td>{{ import.get_duration|floatformat:1 }}s</td></tr>
</table>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
<h6>Zeitstempel</h6>
<p><strong>Gestartet:</strong> {{ import.started_at|date:"d.m.Y H:i:s" }}</p>
{% if import.completed_at %}
<p><strong>Abgeschlossen:</strong> {{ import.completed_at|date:"d.m.Y H:i:s" }}</p>
{% endif %}
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
</div>
</div>
</div>
</div>
<!-- Error Log Modal -->
{% if import.error_log %}
<div class="modal fade" id="errorModal{{ import.id }}" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-warning text-dark">
<h5 class="modal-title">
<i class="fas fa-exclamation-triangle"></i> Fehlerprotokoll
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="alert alert-warning">
<strong>Fehler beim Import:</strong> {{ import.failed_rows }} Zeilen konnten nicht importiert werden.
</div>
<h6>Fehlerdetails:</h6>
<pre class="bg-light p-3 rounded"><code>{{ import.error_log }}</code></pre>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
</div>
</div>
</div>
</div>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Import pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1">&laquo; Erste</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">Zurück</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}">Weiter</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">Letzte &raquo;</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-file-csv fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine CSV-Imports gefunden</h5>
<p class="text-muted">Starten Sie Ihren ersten CSV-Import, um Daten zu importieren.</p>
<a href="{% url 'stiftung:csv_import_create' %}" class="btn btn-primary">
<i class="fas fa-plus"></i> Ersten Import starten
</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,429 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Dashboard - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<h1 class="h3 mb-4">
<i class="fas fa-tachometer-alt text-primary me-2"></i>
Dashboard - Stiftungsverwaltung
</h1>
</div>
</div>
<!-- Statistics Cards -->
<div class="row mb-4">
<!-- Person Statistics -->
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">
Personen
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
{{ total_persons }}
</div>
<div class="text-xs text-muted">
{{ active_persons }} aktiv
</div>
</div>
<div class="col-auto">
<i class="fas fa-users fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Land Statistics -->
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">
Ländereien
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
{{ total_land }}
</div>
<div class="text-xs text-muted">
{{ total_flaeche|floatformat:0 }} qm Gesamtfläche
</div>
</div>
<div class="col-auto">
<i class="fas fa-map fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Verpachtung Statistics -->
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-info shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-info text-uppercase mb-1">
Verpachtungen
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
{{ active_verpachtungen }}
</div>
<div class="text-xs text-muted">
{{ total_verpachtet|floatformat:0 }} qm verpachtet
</div>
</div>
<div class="col-auto">
<i class="fas fa-handshake fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<!-- Financial Statistics -->
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-warning shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">
Einnahmen
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
€{{ total_pachtzins|floatformat:0 }}
</div>
<div class="text-xs text-muted">
Jährlicher Pachtzins
</div>
</div>
<div class="col-auto">
<i class="fas fa-euro-sign fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="row mb-4">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-bolt me-2"></i>Schnellzugriff
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:foerderung_create' %}" class="btn btn-outline-primary w-100 h-100 d-flex flex-column align-items-center justify-content-center p-3">
<i class="fas fa-gift fa-2x mb-2"></i>
<span>Neue Förderung</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:verpachtung_create' %}" class="btn btn-outline-success w-100 h-100 d-flex flex-column align-items-center justify-content-center p-3">
<i class="fas fa-handshake fa-2x mb-2"></i>
<span>Neue Verpachtung</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:bericht_list' %}" class="btn btn-outline-info w-100 h-100 d-flex flex-column align-items-center justify-content-center p-3">
<i class="fas fa-chart-bar fa-2x mb-2"></i>
<span>Jahresberichte</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:csv_import_create' %}" class="btn btn-outline-warning w-100 h-100 d-flex flex-column align-items-center justify-content-center p-3">
<i class="fas fa-upload fa-2x mb-2"></i>
<span>CSV Import</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-outline-info w-100 h-100 d-flex flex-column align-items-center justify-content-center p-3">
<i class="fas fa-file-alt fa-2x mb-2"></i>
<span>Dokumentenverwaltung</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:dokument_list' %}" class="btn btn-outline-secondary w-100 h-100 d-flex flex-column align-items-center justify-content-center p-3">
<i class="fas fa-link fa-2x mb-2"></i>
<span>Dokumente</span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Dokumentenübersicht -->
<div class="row mb-4">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-file-alt me-2"></i>Dokumentenübersicht
</h6>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-success btn-sm">
<i class="fas fa-external-link-alt me-1"></i>Dokumentenverwaltung
</a>
</div>
<div class="card-body">
{% if dokumente_uebersicht %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Dokument</th>
<th>Kontext</th>
<th>Verknüpft mit</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for dokument in dokumente_uebersicht %}
<tr>
<td>
<strong>{{ dokument.titel }}</strong>
<br>
<small class="text-muted">ID: {{ dokument.paperless_document_id }}</small>
</td>
<td>
<span class="badge bg-secondary">{{ dokument.get_kontext_display }}</span>
</td>
<td>
{% if dokument.verpachtung_id %}
<span class="badge bg-info">Verpachtung</span>
{% elif dokument.land_id %}
<span class="badge bg-success">Länderei</span>
{% elif dokument.paechter_id %}
<span class="badge bg-primary">Pächter</span>
{% elif dokument.destinataer_id %}
<span class="badge bg-warning">Destinatär</span>
{% elif dokument.foerderung_id %}
<span class="badge bg-secondary">Förderung</span>
{% else %}
<span class="text-muted">Keine Verknüpfung</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{{ dokument.get_paperless_url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="In Paperless öffnen">
<i class="fas fa-external-link-alt"></i>
</a>
<a href="{% url 'stiftung:dokument_detail' dokument.pk %}" class="btn btn-sm btn-outline-info" title="Details">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:dokument_update' dokument.pk %}" class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="text-center mt-3">
<a href="{% url 'stiftung:dokument_list' %}" class="btn btn-success">
Alle Dokumente anzeigen
</a>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-file-alt fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Dokumente verknüpft</h5>
<p class="text-muted">Verknüpfen Sie Dokumente aus Paperless mit Ihren Entitäten.</p>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-success">
<i class="fas fa-external-link-alt me-2"></i>Dokumentenverwaltung öffnen
</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Verfügbare Paperless-Dokumente -->
{% if available_paperless_docs %}
<div class="row mb-4">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-info">
<i class="fas fa-plus-circle me-2"></i>Verfügbare Paperless-Dokumente
</h6>
<span class="badge bg-info">{{ available_paperless_docs|length }} verfügbar</span>
</div>
<div class="card-body">
<div class="row">
{% for doc in available_paperless_docs|slice:":6" %}
<div class="col-md-6 col-lg-4 mb-3">
<div class="card h-100 border-info">
<div class="card-body">
<h6 class="card-title">{{ doc.title }}</h6>
<div class="mb-2">
{% for tag in doc.tags %}
{% if tag == 'Stiftung_Destinatäre' or tag == 'Stiftung_Land_und_Pächter' or tag == 'Stiftung_Administration' %}
<span class="badge bg-primary me-1">{{ tag }}</span>
{% else %}
<span class="badge bg-light text-dark me-1">{{ tag }}</span>
{% endif %}
{% endfor %}
</div>
<div class="d-flex justify-content-between align-items-center">
<a href="{{ doc.document_url }}" target="_blank" class="btn btn-sm btn-outline-info">
<i class="fas fa-external-link-alt me-1"></i>In Paperless öffnen
</a>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-sm btn-success">
<i class="fas fa-link me-1"></i>Verknüpfen
</a>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="text-center mt-3">
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-info">
<i class="fas fa-external-link-alt me-2"></i>Alle verfügbaren Dokumente anzeigen
</a>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Recent Activities -->
<div class="row">
<!-- Recent Lands -->
<div class="col-lg-6 mb-4">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-map me-2"></i>Neueste Ländereien
</h6>
</div>
<div class="card-body">
{% if recent_lands %}
<div class="list-group list-group-flush">
{% for land in recent_lands %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<div>
<h6 class="mb-1">{{ land.gemeinde }} - {{ land.gemarkung }}</h6>
<small class="text-muted">
Flur {{ land.flur }}, Flurstück {{ land.flurstueck }}
({{ land.groesse_qm|floatformat:0 }} qm)
</small>
</div>
<a href="{% url 'stiftung:land_detail' land.pk %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
</div>
{% endfor %}
</div>
<div class="text-center mt-3">
<a href="{% url 'stiftung:land_list' %}" class="btn btn-sm btn-primary">
Alle Ländereien anzeigen
</a>
</div>
{% else %}
<p class="text-muted text-center">Noch keine Ländereien vorhanden.</p>
{% endif %}
</div>
</div>
</div>
<!-- Recent Verpachtungen -->
<div class="col-lg-6 mb-4">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-handshake me-2"></i>Neueste Verpachtungen
</h6>
</div>
<div class="card-body">
{% if recent_verpachtungen %}
<div class="list-group list-group-flush">
{% for verpachtung in recent_verpachtungen %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<div>
<h6 class="mb-1">{{ verpachtung.land.gemeinde }}</h6>
<small class="text-muted">
{{ verpachtung.paechter.get_full_name }} -
€{{ verpachtung.pachtzins_jaehrlich|floatformat:0 }}/Jahr
</small>
</div>
<a href="{% url 'stiftung:verpachtung_detail' verpachtung.pk %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
</div>
{% endfor %}
</div>
<div class="text-center mt-3">
<a href="{% url 'stiftung:verpachtung_list' %}" class="btn btn-sm btn-primary">
Alle Verpachtungen anzeigen
</a>
</div>
{% else %}
<p class="text-muted text-center">Noch keine Verpachtungen vorhanden.</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Financial Overview -->
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-chart-pie me-2"></i>Finanzübersicht
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4 text-center">
<div class="border rounded p-3">
<h4 class="text-success">€{{ total_pachtzins|floatformat:0 }}</h4>
<p class="text-muted mb-0">Jährlicher Pachtzins</p>
</div>
</div>
<div class="col-md-4 text-center">
<div class="border rounded p-3">
<h4 class="text-info">€{{ total_foerderungen|floatformat:0 }}</h4>
<p class="text-muted mb-0">Gesamtförderungen</p>
</div>
</div>
<div class="col-md-4 text-center">
<div class="border rounded p-3">
<h4 class="text-warning">{{ total_verpachtet|floatformat:0 }} qm</h4>
<p class="text-muted mb-0">Verpachtete Fläche</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
// Auto-refresh dashboard every 5 minutes
setTimeout(function() {
location.reload();
}, 300000);
</script>
{% endblock %}

View File

@@ -0,0 +1,50 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Destinatär löschen - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-6">
<div class="card shadow">
<div class="card-header bg-danger text-white">
<h5 class="card-title mb-0">
<i class="fas fa-exclamation-triangle me-2"></i>Destinatär löschen
</h5>
</div>
<div class="card-body text-center">
<div class="mb-4">
<i class="fas fa-users fa-3x text-danger mb-3"></i>
<h4>Sind Sie sicher?</h4>
<p class="text-muted">
Sie sind dabei, den Destinatär <strong>"{{ destinataer.get_full_name }}"</strong> zu löschen.
</p>
</div>
<div class="alert alert-warning">
<h6><i class="fas fa-exclamation-triangle me-2"></i>Wichtige Hinweise:</h6>
<ul class="list-unstyled mb-0 text-start">
<li><i class="fas fa-arrow-right me-2"></i>Alle zugehörigen Förderungen werden ebenfalls gelöscht</li>
<li><i class="fas fa-arrow-right me-2"></i>Diese Aktion kann nicht rückgängig gemacht werden</li>
<li><i class="fas fa-arrow-right me-2"></i>Bitte stellen Sie sicher, dass alle Daten gesichert sind</li>
</ul>
</div>
<div class="d-flex justify-content-center gap-3">
<a href="{% url 'stiftung:destinataer_detail' pk=destinataer.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<form method="post" class="d-inline">
{% csrf_token %}
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Ja, löschen
</button>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,455 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ destinataer.get_full_name }} - Destinatär - 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-users text-primary me-2"></i>
Destinatär: {{ destinataer.get_full_name }}
</h1>
<div>
<a href="{% url 'stiftung:destinataer_update' pk=destinataer.pk %}" class="btn btn-warning me-2">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:destinataer_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
<div class="row">
<!-- Main Content -->
<div class="col-lg-8">
<!-- Persönliche Informationen -->
<div class="card shadow mb-4">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-user me-2"></i>Persönliche Informationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Vorname:</strong> {{ destinataer.vorname }}</p>
<p><strong>Nachname:</strong> {{ destinataer.nachname }}</p>
{% if destinataer.geburtsdatum %}
<p><strong>Geburtsdatum:</strong> {{ destinataer.geburtsdatum|date:"d.m.Y" }}</p>
{% endif %}
<p><strong>Familienzweig:</strong>
<span class="badge bg-info">{{ destinataer.get_familienzweig_display }}</span>
</p>
</div>
<div class="col-md-6">
<p><strong>Status:</strong>
{% if destinataer.aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</p>
<p><strong>Berufsgruppe:</strong>
<span class="badge bg-secondary">{{ destinataer.get_berufsgruppe_display }}</span>
</p>
</div>
</div>
</div>
</div>
<!-- Kontaktinformationen -->
<div class="card shadow mb-4">
<div class="card-header bg-info text-white">
<h5 class="card-title mb-0">
<i class="fas fa-address-book me-2"></i>Kontaktinformationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
{% if destinataer.email %}
<p><strong>E-Mail:</strong> <a href="mailto:{{ destinataer.email }}">{{ destinataer.email }}</a></p>
{% endif %}
{% if destinataer.telefon %}
<p><strong>Telefon:</strong> {{ destinataer.telefon }}</p>
{% endif %}
</div>
<div class="col-md-6">
{% if destinataer.iban %}
<p><strong>IBAN:</strong> {{ destinataer.iban }}</p>
{% endif %}
</div>
</div>
{% if destinataer.strasse or destinataer.plz or destinataer.ort %}
<p><strong>Adresse:</strong><br>
{% if destinataer.strasse %}{{ destinataer.strasse }}{% endif %}
{% if destinataer.plz or destinataer.ort %}<br>{% endif %}
{% if destinataer.plz %}{{ destinataer.plz }}{% endif %}
{% if destinataer.plz and destinataer.ort %} {% endif %}
{% if destinataer.ort %}{{ destinataer.ort }}{% endif %}
</p>
{% endif %}
</div>
</div>
<!-- Berufliche Informationen -->
<div class="card shadow mb-4">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">
<i class="fas fa-briefcase me-2"></i>Berufliche Informationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
{% if destinataer.ausbildungsstand %}
<p><strong>Ausbildungsstand:</strong> {{ destinataer.ausbildungsstand }}</p>
{% endif %}
{% if destinataer.institution %}
<p><strong>Institution/Organisation:</strong> {{ destinataer.institution }}</p>
{% endif %}
</div>
<div class="col-md-6">
{% if destinataer.projekt_beschreibung %}
<p><strong>Projektbeschreibung:</strong><br>{{ destinataer.projekt_beschreibung|linebreaks }}</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Finanzielle Informationen -->
<div class="card shadow mb-4">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-euro-sign me-2"></i>Finanzielle Informationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
{% if destinataer.jaehrliches_einkommen %}
<p><strong>Jährliches Einkommen:</strong> <span class="text-primary fw-bold">€{{ destinataer.jaehrliches_einkommen|floatformat:2 }}</span></p>
{% endif %}
{% if destinataer.monatliche_bezuege %}
<p><strong>Monatliche Bezüge:</strong> €{{ destinataer.monatliche_bezuege|floatformat:2 }}</p>
{% endif %}
{% if destinataer.vermoegen %}
<p><strong>Vermögen:</strong> €{{ destinataer.vermoegen|floatformat:2 }}</p>
{% endif %}
</div>
<div class="col-md-6">
<p><strong>Finanzielle Notlage:</strong>
{% if destinataer.finanzielle_notlage %}
<span class="badge bg-danger">
<i class="fas fa-exclamation-triangle me-1"></i>Ja
</span>
{% else %}
<span class="badge bg-success">
<i class="fas fa-check me-1"></i>Nein
</span>
{% endif %}
</p>
{% if destinataer.vierteljaehrlicher_betrag %}
<p><strong>Vierteljährlicher Betrag:</strong> <span class="fw-bold">€{{ destinataer.vierteljaehrlicher_betrag|floatformat:2 }}</span></p>
{% endif %}
<p><strong>Unterstützung bestätigt:</strong>
{% if destinataer.unterstuetzung_bestaetigt %}
<span class="badge bg-success">Ja</span>
{% else %}
<span class="badge bg-secondary">Nein</span>
{% endif %}
</p>
{% if destinataer.standard_konto %}
<p><strong>Standardkonto:</strong> {{ destinataer.standard_konto }}</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Studiennachweis / Voraussetzungen -->
<div class="card shadow mb-4">
<div class="card-header bg-light">
<h5 class="card-title mb-0">
<i class="fas fa-graduation-cap me-2"></i>Studiennachweis & Voraussetzungen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Abkömmling gem. Satzung:</strong>
{% if destinataer.ist_abkoemmling %}<span class="badge bg-success">Ja</span>{% else %}<span class="badge bg-secondary">Nein</span>{% endif %}
</p>
<p><strong>Haushaltsgröße:</strong> {{ destinataer.haushaltsgroesse }}</p>
</div>
<div class="col-md-6">
<p><strong>Studiennachweis erforderlich:</strong>
{% if destinataer.studiennachweis_erforderlich %}<span class="badge bg-info">Ja</span>{% else %}<span class="badge bg-secondary">Nein</span>{% endif %}
</p>
{% if destinataer.letzter_studiennachweis %}
<p><strong>Letzter Nachweis:</strong> {{ destinataer.letzter_studiennachweis|date:"d.m.Y" }}</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Förderungen -->
{% if foerderungen %}
<div class="card shadow mb-4">
<div class="card-header bg-secondary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-gift me-2"></i>Förderungen ({{ foerderungen.count }})
</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Jahr</th>
<th>Betrag</th>
<th>Kategorie</th>
<th>Status</th>
<th>Verwendungsnachweis</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for foerderung in foerderungen %}
<tr>
<td>{{ foerderung.jahr }}</td>
<td><span class="text-success fw-bold">€{{ foerderung.betrag|floatformat:2 }}</span></td>
<td>{{ foerderung.get_kategorie_display }}</td>
<td>
{% if foerderung.status == 'bewilligt' %}
<span class="badge bg-success">Bewilligt</span>
{% elif foerderung.status == 'abgelehnt' %}
<span class="badge bg-danger">Abgelehnt</span>
{% elif foerderung.status == 'in_bearbeitung' %}
<span class="badge bg-warning">In Bearbeitung</span>
{% else %}
<span class="badge bg-secondary">{{ foerderung.get_status_display }}</span>
{% endif %}
</td>
<td>
{% if foerderung.verwendungsnachweis %}
<span class="badge bg-success">
<i class="fas fa-check me-1"></i>Ja
</span>
{% else %}
<span class="badge bg-warning">
<i class="fas fa-times me-1"></i>Nein
</span>
{% endif %}
</td>
<td>
<a href="{% url 'stiftung:foerderung_detail' pk=foerderung.pk %}"
class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
<!-- Verknüpfte Dokumente -->
<div class="card shadow mb-4">
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">
<i class="fas fa-file-alt me-2"></i>Verknüpfte Dokumente
</h5>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-light btn-sm">
<i class="fas fa-plus me-1"></i>Dokument verknüpfen
</a>
</div>
<div class="card-body">
{% if verknuepfte_dokumente %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Dokument</th>
<th>Kontext</th>
<th>Beschreibung</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for dokument in verknuepfte_dokumente %}
<tr>
<td>
<strong>{{ dokument.titel }}</strong>
<br>
<small class="text-muted">ID: {{ dokument.paperless_document_id }}</small>
</td>
<td>
<span class="badge bg-secondary">{{ dokument.get_kontext_display }}</span>
</td>
<td>
{% if dokument.beschreibung %}
{{ dokument.beschreibung|truncatewords:10 }}
{% else %}
<span class="text-muted">Keine Beschreibung</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{{ dokument.get_paperless_url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="In Paperless öffnen">
<i class="fas fa-external-link-alt"></i>
</a>
<a href="{{ dokument.get_paperless_thumbnail_url }}" target="_blank" class="btn btn-sm btn-outline-info" title="Thumbnail anzeigen">
<i class="fas fa-image"></i>
</a>
<a href="{% url 'stiftung:dokument_update' dokument.pk %}" class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:dokument_delete' dokument.pk %}" class="btn btn-sm btn-outline-danger" title="Verknüpfung löschen">
<i class="fas fa-unlink"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-file-alt fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Dokumente verknüpft</h5>
<p class="text-muted">Verknüpfen Sie Dokumente aus Paperless mit diesem Destinatär.</p>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Erstes Dokument verknüpfen
</a>
</div>
{% endif %}
</div>
</div>
<!-- Notizen -->
<div class="card shadow mb-4">
<div class="card-header bg-light d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">
<i class="fas fa-sticky-note me-2"></i>Notizen
</h5>
<a class="btn btn-sm btn-primary" href="{% url 'stiftung:destinataer_notiz_create' pk=destinataer.pk %}">
<i class="fas fa-plus me-1"></i>Notiz hinzufügen
</a>
</div>
<div class="card-body">
{% if notizen_eintraege %}
<div class="list-group">
{% for n in notizen_eintraege %}
<div class="list-group-item">
<div class="d-flex justify-content-between">
<div>
<strong>{{ n.erstellt_am|date:"d.m.Y H:i" }}</strong>
{% if n.erstellt_von %}<span class="text-muted">— {{ n.erstellt_von.username }}</span>{% endif %}
</div>
{% if n.datei %}
<a href="{{ n.datei.url }}" target="_blank" class="btn btn-sm btn-outline-secondary"><i class="fas fa-paperclip"></i> Anhang</a>
{% endif %}
</div>
{% if n.titel %}<div class="mt-1"><em>{{ n.titel }}</em></div>{% endif %}
{% if n.text %}<div class="mt-1">{{ n.text|linebreaks }}</div>{% endif %}
</div>
{% endfor %}
</div>
{% else %}
<p class="text-muted mb-0">Keine Notizen vorhanden.</p>
{% endif %}
</div>
</div>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<!-- Statistiken -->
<div class="card shadow mb-4">
<div class="card-header bg-primary text-white">
<h6 class="card-title mb-0">
<i class="fas fa-chart-bar me-2"></i>Statistiken
</h6>
</div>
<div class="card-body">
<div class="text-center">
<div class="row">
<div class="col-6">
<div class="border-end">
<h4 class="text-primary">{{ foerderungen.count }}</h4>
<small class="text-muted">Förderungen</small>
</div>
</div>
<div class="col-6">
<h4 class="text-success">
{% if foerderungen %}
{% with total_betrag=foerderungen|length %}
€{{ total_betrag|floatformat:0 }}
{% endwith %}
{% else %}
€0
{% endif %}
</h4>
<small class="text-muted">Gesamtbetrag</small>
</div>
</div>
</div>
</div>
</div>
<!-- Aktionen -->
<div class="card shadow mb-4">
<div class="card-header bg-success text-white">
<h6 class="card-title mb-0">
<i class="fas fa-tools me-2"></i>Aktionen
</h6>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="{% url 'stiftung:destinataer_update' pk=destinataer.pk %}" class="btn btn-warning">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:destinataer_export' pk=destinataer.pk %}" class="btn btn-success">
<i class="fas fa-download me-2"></i>Export
</a>
<a href="{% url 'stiftung:destinataer_delete' pk=destinataer.pk %}" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Löschen
</a>
</div>
</div>
</div>
<!-- Informationen -->
<div class="card shadow">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">
<i class="fas fa-info-circle me-2"></i>Informationen
</h6>
</div>
<div class="card-body">
<p><strong>ID:</strong> {{ destinataer.id }}</p>
<p><strong>Erstellt:</strong> {{ destinataer.id|slice:":8" }}</p>
{% if destinataer.aktiv %}
<p><strong>Status:</strong> <span class="badge bg-success">Aktiv</span></p>
{% else %}
<p><strong>Status:</strong> <span class="badge bg-secondary">Inaktiv</span></p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,444 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3">
<i class="fas fa-users text-primary me-2"></i>
{{ title }}
</h1>
<div>
<a href="{% url 'stiftung:destinataer_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
<div class="row">
<div class="col-lg-8">
<div class="card shadow">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-edit me-2"></i>Destinatär-Daten
</h5>
</div>
<div class="card-body">
<form method="post" novalidate>
{% csrf_token %}
<!-- Persönliche Informationen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-user me-2"></i>Persönliche Informationen
</h6>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.vorname.id_for_label }}" class="form-label">
{{ form.vorname.label }} *
</label>
{{ form.vorname }}
{% if form.vorname.errors %}
<div class="invalid-feedback d-block">
{% for error in form.vorname.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.vorname.help_text %}
<div class="form-text">{{ form.vorname.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.nachname.id_for_label }}" class="form-label">
{{ form.nachname.label }} *
</label>
{{ form.nachname }}
{% if form.nachname.errors %}
<div class="invalid-feedback d-block">
{% for error in form.nachname.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.nachname.help_text %}
<div class="form-text">{{ form.nachname.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.geburtsdatum.id_for_label }}" class="form-label">
{{ form.geburtsdatum.label }}
</label>
{{ form.geburtsdatum }}
{% if form.geburtsdatum.errors %}
<div class="invalid-feedback d-block">
{% for error in form.geburtsdatum.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.geburtsdatum.help_text %}
<div class="form-text">{{ form.geburtsdatum.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.familienzweig.id_for_label }}" class="form-label">
{{ form.familienzweig.label }}
</label>
{{ form.familienzweig }}
{% if form.familienzweig.errors %}
<div class="invalid-feedback d-block">
{% for error in form.familienzweig.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.familienzweig.help_text %}
<div class="form-text">{{ form.familienzweig.help_text }}</div>
{% endif %}
</div>
</div>
<!-- Kontaktinformationen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-address-book me-2"></i>Kontaktinformationen
</h6>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.email.id_for_label }}" class="form-label">
{{ form.email.label }}
</label>
{{ form.email }}
{% if form.email.errors %}
<div class="invalid-feedback d-block">
{% for error in form.email.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.email.help_text %}
<div class="form-text">{{ form.email.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.telefon.id_for_label }}" class="form-label">
{{ form.telefon.label }}
</label>
{{ form.telefon }}
{% if form.telefon.errors %}
<div class="invalid-feedback d-block">
{% for error in form.telefon.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.telefon.help_text %}
<div class="form-text">{{ form.telefon.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.iban.id_for_label }}" class="form-label">
{{ form.iban.label }}
</label>
{{ form.iban }}
{% if form.iban.errors %}
<div class="invalid-feedback d-block">
{% for error in form.iban.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.iban.help_text %}
<div class="form-text">{{ form.iban.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.adresse.id_for_label }}" class="form-label">
{{ form.adresse.label }}
</label>
{{ form.adresse }}
{% if form.adresse.errors %}
<div class="invalid-feedback d-block">
{% for error in form.adresse.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.adresse.help_text %}
<div class="form-text">{{ form.adresse.help_text }}</div>
{% endif %}
</div>
</div>
<!-- Berufliche Informationen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-briefcase me-2"></i>Berufliche Informationen
</h6>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.berufsgruppe.id_for_label }}" class="form-label">
{{ form.berufsgruppe.label }}
</label>
{{ form.berufsgruppe }}
{% if form.berufsgruppe.errors %}
<div class="invalid-feedback d-block">
{% for error in form.berufsgruppe.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.berufsgruppe.help_text %}
<div class="form-text">{{ form.berufsgruppe.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.ausbildungsstand.id_for_label }}" class="form-label">
{{ form.ausbildungsstand.label }}
</label>
{{ form.ausbildungsstand }}
{% if form.ausbildungsstand.errors %}
<div class="invalid-feedback d-block">
{% for error in form.ausbildungsstand.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.ausbildungsstand.help_text %}
<div class="form-text">{{ form.ausbildungsstand.help_text }}</div>
{% endif %}
</div>
<div class="col-md-12 mb-3">
<label for="{{ form.institution.id_for_label }}" class="form-label">
{{ form.institution.label }}
</label>
{{ form.institution }}
{% if form.institution.errors %}
<div class="invalid-feedback d-block">
{% for error in form.institution.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.institution.help_text %}
<div class="form-text">{{ form.institution.help_text }}</div>
{% endif %}
</div>
<div class="col-md-12 mb-3">
<label for="{{ form.projekt_beschreibung.id_for_label }}" class="form-label">
{{ form.projekt_beschreibung.label }}
</label>
{{ form.projekt_beschreibung }}
{% if form.projekt_beschreibung.errors %}
<div class="invalid-feedback d-block">
{% for error in form.projekt_beschreibung.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.projekt_beschreibung.help_text %}
<div class="form-text">{{ form.projekt_beschreibung.help_text }}</div>
{% endif %}
</div>
</div>
<!-- Finanzielle Informationen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-euro-sign me-2"></i>Finanzielle Informationen
</h6>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.jaehrliches_einkommen.id_for_label }}" class="form-label">
{{ form.jaehrliches_einkommen.label }}
</label>
{{ form.jaehrliches_einkommen }}
{% if form.jaehrliches_einkommen.errors %}
<div class="invalid-feedback d-block">
{% for error in form.jaehrliches_einkommen.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.jaehrliches_einkommen.help_text %}
<div class="form-text">{{ form.jaehrliches_einkommen.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<div class="form-check">
{{ form.finanzielle_notlage }}
<label class="form-check-label" for="{{ form.finanzielle_notlage.id_for_label }}">
{{ form.finanzielle_notlage.label }}
</label>
</div>
{% if form.finanzielle_notlage.errors %}
<div class="invalid-feedback d-block">
{% for error in form.finanzielle_notlage.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.finanzielle_notlage.help_text %}
<div class="form-text">{{ form.finanzielle_notlage.help_text }}</div>
{% endif %}
</div>
</div>
<!-- Unterstützungsprüfung & Auszahlung -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-check-circle me-2"></i>Unterstützung & Auszahlung
</h6>
</div>
<div class="col-md-6 mb-3">
<div class="form-check mb-2">
{{ form.ist_abkoemmling }}
<label class="form-check-label" for="{{ form.ist_abkoemmling.id_for_label }}">{{ form.ist_abkoemmling.label }}</label>
</div>
<div class="form-check mb-3">
{{ form.unterstuetzung_bestaetigt }}
<label class="form-check-label" for="{{ form.unterstuetzung_bestaetigt.id_for_label }}">{{ form.unterstuetzung_bestaetigt.label }}</label>
</div>
<label for="{{ form.haushaltsgroesse.id_for_label }}" class="form-label">{{ form.haushaltsgroesse.label }}</label>
{{ form.haushaltsgroesse }}
<div class="mt-2">
<label for="{{ form.vierteljaehrlicher_betrag.id_for_label }}" class="form-label">Vierteljährliche Bezüge (€)</label>
{{ form.vierteljaehrlicher_betrag }}
</div>
<div class="mt-2">
<label for="{{ form.vermoegen.id_for_label }}" class="form-label">{{ form.vermoegen.label }}</label>
{{ form.vermoegen }}
</div>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.standard_konto.id_for_label }}" class="form-label">{{ form.standard_konto.label }}</label>
{{ form.standard_konto }}
<div class="form-text">Standardkonto für vierteljährliche Vorauszahlungen</div>
</div>
</div>
<!-- Studiennachweis -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-graduation-cap me-2"></i>Studiennachweis
</h6>
</div>
<div class="col-md-6 mb-3">
<div class="form-check">
{{ form.studiennachweis_erforderlich }}
<label class="form-check-label" for="{{ form.studiennachweis_erforderlich.id_for_label }}">{{ form.studiennachweis_erforderlich.label }}</label>
</div>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.letzter_studiennachweis.id_for_label }}" class="form-label">{{ form.letzter_studiennachweis.label }}</label>
{{ form.letzter_studiennachweis }}
<div class="form-text">Stichtage: 15.03 und 15.09</div>
</div>
</div>
<!-- Status und Notizen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-cog me-2"></i>Status und Notizen
</h6>
</div>
<div class="col-md-6 mb-3">
<div class="form-check">
{{ form.aktiv }}
<label class="form-check-label" for="{{ form.aktiv.id_for_label }}">
{{ form.aktiv.label }}
</label>
</div>
{% if form.aktiv.errors %}
<div class="invalid-feedback d-block">
{% for error in form.aktiv.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.aktiv.help_text %}
<div class="form-text">{{ form.aktiv.help_text }}</div>
{% endif %}
</div>
<div class="col-md-12 mb-3">
<label for="{{ form.notizen.id_for_label }}" class="form-label">
{{ form.notizen.label }}
</label>
{{ form.notizen }}
{% if form.notizen.errors %}
<div class="invalid-feedback d-block">
{% for error in form.notizen.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.notizen.help_text %}
<div class="form-text">{{ form.notizen.help_text }}</div>
{% endif %}
</div>
</div>
<!-- Form Actions -->
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:destinataer_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-2"></i>Speichern
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<div class="card shadow">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">
<i class="fas fa-info-circle me-2"></i>Hilfe
</h6>
</div>
<div class="card-body">
<div class="small">
<p><strong>Voraussetzungen für Unterstützung</strong></p>
<p>Die Stiftung kann grundsätzlich laufende Leistungen nur an Abkömmlinge der Geschwister des Stifters Hendrik van Hees und seiner Ehefrau oder im Einzelfall an weitere Personen erbringen, die als Alleinstehende(r) oder Haushaltsvorstand keine höheren Bezüge als 2.245,00 € (5× Regelsatz 563,00 €) haben und deren Vermögen 15.500 € nicht übersteigt (§53 AO). Die Sätze erhöhen sich bei weiteren Haushaltsangehörigen.</p>
<p class="text-muted">Dieser Text ist redaktionell anpassbar (Template).</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,243 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Destinatäre - 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-users text-primary me-2"></i>
Destinatäre
</h1>
<div class="d-flex gap-2">
<a href="{% url 'stiftung:unterstuetzungen_list' %}" class="btn btn-outline-primary">
<i class="fas fa-hand-holding-usd me-2"></i>Unterstützungen
</a>
<a href="{% url 'stiftung:destinataer_create' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Neuen Destinatär erstellen
</a>
</div>
</div>
<!-- Search and Filters -->
<div class="card shadow mb-4">
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-4">
<label for="search" class="form-label">Suche</label>
<input type="text" class="form-control" id="search" name="search"
value="{{ search_query }}" placeholder="Name, E-Mail oder Institution...">
</div>
<div class="col-md-2">
<label for="familienzweig" class="form-label">Familienzweig</label>
<select class="form-control" id="familienzweig" name="familienzweig">
<option value="">Alle</option>
{% for choice in familienzweig_choices %}
<option value="{{ choice.0 }}" {% if choice.0 == familienzweig_filter %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label for="berufsgruppe" class="form-label">Berufsgruppe</label>
<select class="form-control" id="berufsgruppe" name="berufsgruppe">
<option value="">Alle</option>
{% for choice in berufsgruppe_choices %}
<option value="{{ choice.0 }}" {% if choice.0 == berufsgruppe_filter %}selected{% endif %}>
{{ choice.1 }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label for="aktiv" class="form-label">Status</label>
<select class="form-control" id="aktiv" name="aktiv">
<option value="">Alle</option>
<option value="true" {% if aktiv_filter == 'true' %}selected{% endif %}>Aktiv</option>
<option value="false" {% if aktiv_filter == 'false' %}selected{% endif %}>Inaktiv</option>
</select>
</div>
<div class="col-md-2 d-flex align-items-end">
<button type="submit" class="btn btn-primary me-2">
<i class="fas fa-search me-1"></i>Suchen
</button>
<a href="{% url 'stiftung:destinataer_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Zurücksetzen
</a>
</div>
</form>
</div>
</div>
<!-- Results -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Destinatäre ({{ page_obj.paginator.count }})
</h6>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>
<a href="?sort=name&dir={% if sort == 'name' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Name</a>
</th>
<th>
<a href="?sort=familienzweig&dir={% if sort == 'familienzweig' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Familienzweig</a>
</th>
<th>
<a href="?sort=berufsgruppe&dir={% if sort == 'berufsgruppe' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Berufsgruppe</a>
</th>
<th>
<a href="?sort=institution&dir={% if sort == 'institution' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Institution</a>
</th>
<th>
<a href="?sort=email&dir={% if sort == 'email' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">E-Mail</a>
</th>
<th>
<a href="?sort=foerderungen&dir={% if sort == 'foerderungen' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Förderungen</a>
</th>
<th>
<a href="?sort=status&dir={% if sort == 'status' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Status</a>
</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for destinataer in page_obj %}
<tr>
<td>
<strong>{{ destinataer.nachname }}, {{ destinataer.vorname }}</strong>
{% if destinataer.geburtsdatum %}
<br><small class="text-muted">{{ destinataer.geburtsdatum|date:"d.m.Y" }}</small>
{% endif %}
</td>
<td>
<span class="badge bg-info">{{ destinataer.get_familienzweig_display }}</span>
</td>
<td>
<span class="badge bg-secondary">{{ destinataer.get_berufsgruppe_display }}</span>
</td>
<td>
{% if destinataer.institution %}
{{ destinataer.institution }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if destinataer.email %}
<a href="mailto:{{ destinataer.email }}">{{ destinataer.email }}</a>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if destinataer.total_foerderungen %}
<span class="text-success fw-bold">€{{ destinataer.total_foerderungen|floatformat:2 }}</span>
{% else %}
<span class="text-muted">€0.00</span>
{% endif %}
</td>
<td>
{% if destinataer.aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:destinataer_detail' pk=destinataer.pk %}"
class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:destinataer_update' pk=destinataer.pk %}"
class="btn btn-sm btn-outline-warning">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:destinataer_delete' pk=destinataer.pk %}"
class="btn btn-sm btn-outline-danger">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Destinatäre Pagination" class="mt-4">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-double-left"></i>
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-left"></i>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-right"></i>
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if berufsgruppe_filter %}&berufsgruppe={{ berufsgruppe_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-double-right"></i>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-users fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Destinatäre gefunden</h5>
<p class="text-muted">
{% if search_query or familienzweig_filter or berufsgruppe_filter or aktiv_filter %}
Versuchen Sie andere Suchkriterien oder
<a href="{% url 'stiftung:destinataer_list' %}">setzen Sie die Filter zurück</a>.
{% else %}
Erstellen Sie den ersten Destinatär mit dem Button oben.
{% endif %}
</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,38 @@
{% extends 'base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-8">
<div class="card shadow">
<div class="card-header bg-primary text-white"><h5 class="mb-0">{{ title }}</h5></div>
<div class="card-body">
<form method="post" enctype="multipart/form-data">{% csrf_token %}
{% if form.non_field_errors %}
<div class="alert alert-danger">{{ form.non_field_errors }}</div>
{% endif %}
<div class="mb-3">
<label class="form-label" for="{{ form.titel.id_for_label }}">{{ form.titel.label }}</label>
{{ form.titel }}
{{ form.titel.errors }}
</div>
<div class="mb-3">
<label class="form-label" for="{{ form.text.id_for_label }}">{{ form.text.label }}</label>
{{ form.text }}
{{ form.text.errors }}
</div>
<div class="mb-3">
<label class="form-label" for="{{ form.datei.id_for_label }}">{{ form.datei.label }}</label>
{{ form.datei }}
{{ form.datei.errors }}
</div>
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:destinataer_detail' pk=destinataer.pk %}" class="btn btn-outline-secondary">Abbrechen</a>
<button type="submit" class="btn btn-primary">Speichern</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,65 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Dokument löschen - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-6 mx-auto">
<div class="card shadow">
<div class="card-header bg-danger text-white">
<h4 class="mb-0">
<i class="fas fa-exclamation-triangle me-2"></i>Dokument löschen
</h4>
</div>
<div class="card-body">
<div class="alert alert-warning">
<h5 class="alert-heading">
<i class="fas fa-exclamation-triangle me-2"></i>Warnung!
</h5>
<p class="mb-0">
Sind Sie sicher, dass Sie das Dokument <strong>{{ dokument.titel }}</strong> löschen möchten?
</p>
</div>
<div class="card mb-3">
<div class="card-body">
<h6 class="card-title">Dokumentdetails:</h6>
<p class="card-text">
<strong>Titel:</strong> {{ dokument.titel }}<br>
<strong>Kontext:</strong> {{ dokument.get_kontext_display }}<br>
<strong>Paperless ID:</strong> {{ dokument.paperless_document_id }}<br>
{% if dokument.beschreibung %}
<strong>Beschreibung:</strong> {{ dokument.beschreibung }}
{% endif %}
</p>
</div>
</div>
<div class="alert alert-info">
<h6 class="alert-heading">
<i class="fas fa-info-circle me-2"></i>Wichtiger Hinweis
</h6>
<p class="mb-0">
Diese Aktion kann nicht rückgängig gemacht werden. Alle zugehörigen Verknüpfungen werden ebenfalls gelöscht.
</p>
</div>
<form method="post">
{% csrf_token %}
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:dokument_detail' dokument.pk %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Endgültig löschen
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,168 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - 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-file-alt text-primary me-2"></i>{{ title }}
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:dokument_update' dokument.pk %}" class="btn btn-warning">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:dokument_delete' dokument.pk %}" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Löschen
</a>
</div>
</div>
<div class="row">
<!-- Main Information -->
<div class="col-lg-8">
<!-- Dokument Details -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-info-circle me-2"></i>Dokumentdetails
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-primary">Titel</h6>
<p class="mb-3">{{ dokument.titel }}</p>
<h6 class="text-primary">Kontext</h6>
<p class="mb-3">
<span class="badge bg-secondary">{{ dokument.get_kontext_display }}</span>
</p>
</div>
<div class="col-md-6">
<h6 class="text-primary">Paperless ID</h6>
<p class="mb-3">
<code>{{ dokument.paperless_document_id }}</code>
</p>
<h6 class="text-primary">Erstellt</h6>
<p class="mb-3">{{ dokument.id }}</p>
</div>
</div>
{% if dokument.beschreibung %}
<hr class="my-3">
<h6 class="text-primary">Beschreibung</h6>
<p class="mb-0">{{ dokument.beschreibung }}</p>
{% endif %}
</div>
</div>
<!-- Verknüpfungen -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-link me-2"></i>Verknüpfungen
</h6>
</div>
<div class="card-body">
{% if dokument.foerderung_set.exists or dokument.verpachtung_set.exists %}
{% if dokument.foerderung_set.exists %}
<h6 class="text-primary">Förderungen</h6>
<div class="list-group list-group-flush mb-3">
{% for foerderung in dokument.foerderung_set.all %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<div>
<strong>{{ foerderung.person.get_full_name }}</strong> - {{ foerderung.jahr }}
<br>
<small class="text-muted">€{{ foerderung.betrag|floatformat:2 }}</small>
</div>
<a href="{% url 'stiftung:foerderung_detail' foerderung.pk %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
</div>
{% endfor %}
</div>
{% endif %}
{% if dokument.verpachtung_set.exists %}
<h6 class="text-primary">Verpachtungen</h6>
<div class="list-group list-group-flush">
{% for verpachtung in dokument.verpachtung_set.all %}
<div class="list-group-item d-flex justify-content-between align-items-center">
<div>
<strong>{{ verpachtung.vertragsnummer }}</strong> - {{ verpachtung.land.gemeinde }}
<br>
<small class="text-muted">{{ verpachtung.paechter.get_full_name }}</small>
</div>
<a href="{% url 'stiftung:verpachtung_detail' verpachtung.pk %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
</div>
{% endfor %}
</div>
{% endif %}
{% else %}
<div class="text-center py-4">
<i class="fas fa-link fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Verknüpfungen</h5>
<p class="text-muted">Dieses Dokument ist noch nicht mit Förderungen oder Verpachtungen verknüpft.</p>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<!-- Quick Stats -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-chart-pie me-2"></i>Übersicht
</h6>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-6">
<div class="border-end">
<h4 class="text-primary">{{ dokument.foerderung_set.count }}</h4>
<small class="text-muted">Förderungen</small>
</div>
</div>
<div class="col-6">
<h4 class="text-success">{{ dokument.verpachtung_set.count }}</h4>
<small class="text-muted">Verpachtungen</small>
</div>
</div>
</div>
</div>
<!-- Actions -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-bolt me-2"></i>Schnellzugriff
</h6>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="{% url 'stiftung:dokument_update' dokument.pk %}" class="btn btn-warning">
<i class="fas fa-edit me-2"></i>Dokument bearbeiten
</a>
<a href="{% url 'stiftung:dokument_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,135 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - {{ block.super }}{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-8 mx-auto">
<div class="card shadow">
<div class="card-header">
<h4 class="mb-0">
<i class="fas fa-file-alt text-primary me-2"></i>{{ title }}
</h4>
</div>
<div class="card-body">
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.paperless_document_id.id_for_label }}" class="form-label">
{{ form.paperless_document_id.label }} *
</label>
{{ form.paperless_document_id }}
{% if form.paperless_document_id.errors %}
<div class="invalid-feedback d-block">
{{ form.paperless_document_id.errors.0 }}
</div>
{% endif %}
<small class="form-text text-muted">
Die Dokument-ID aus Paperless (z.B. aus der URL: /documents/12345/)
</small>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.kontext.id_for_label }}" class="form-label">
{{ form.kontext.label }} *
</label>
{{ form.kontext }}
{% if form.kontext.errors %}
<div class="invalid-feedback d-block">
{{ form.kontext.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="mb-3">
<label for="{{ form.titel.id_for_label }}" class="form-label">
{{ form.titel.label }} *
</label>
{{ form.titel }}
{% if form.titel.errors %}
<div class="invalid-feedback d-block">
{{ form.titel.errors.0 }}
</div>
{% endif %}
</div>
<div class="mb-3">
<label for="{{ form.beschreibung.id_for_label }}" class="form-label">
{{ form.beschreibung.label }}
</label>
{{ form.beschreibung }}
{% if form.beschreibung.errors %}
<div class="invalid-feedback d-block">
{{ form.beschreibung.errors.0 }}
</div>
{% endif %}
</div>
<!-- Versteckte Verknüpfungsfelder -->
{{ form.verpachtung_id }}
{{ form.land_id }}
{{ form.paechter_id }}
{{ form.destinataer_id }}
{{ form.foerderung_id }}
<!-- Verknüpfungsinfo anzeigen -->
{% if form.verpachtung_id.value %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
<strong>Verknüpfung:</strong> Dieses Dokument wird mit einer Verpachtung verknüpft.
</div>
{% elif form.land_id.value %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
<strong>Verknüpfung:</strong> Dieses Dokument wird mit einer Länderei verknüpft.
</div>
{% elif form.paechter_id.value %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
<strong>Verknüpfung:</strong> Dieses Dokument wird mit einem Pächter verknüpft.
</div>
{% elif form.destinataer_id.value %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
<strong>Verknüpfung:</strong> Dieses Dokument wird mit einem Destinatär verknüpft.
</div>
{% elif form.foerderung_id.value %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
<strong>Verknüpfung:</strong> Dieses Dokument wird mit einer Förderung verknüpft.
</div>
{% endif %}
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:dokument_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Liste
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-1"></i>
{% if dokument %}Aktualisieren{% else %}Verknüpfen{% endif %}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_css %}
<style>
.form-control, .form-select {
border-radius: 0.375rem;
}
.form-control:focus, .form-select:focus {
border-color: #86b7fe;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}
</style>
{% endblock %}

View File

@@ -0,0 +1,146 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Alle Dokumente - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3 mb-0">
<i class="fas fa-file-alt text-primary me-2"></i>
Alle Dokumente
</h1>
<div>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-info me-2">
<i class="fas fa-external-link-alt me-1"></i>Dokumentenverwaltung
</a>
</div>
</div>
</div>
</div>
<!-- Verknüpfte Dokumente -->
<div class="row mb-4">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-link me-2"></i>Verknüpfte Dokumente ({{ dokumente|length }})
</h6>
</div>
<div class="card-body">
{% if dokumente %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Dokument</th>
<th>Kontext</th>
<th>Verknüpft mit</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for dokument in dokumente %}
<tr>
<td>
<strong>{{ dokument.titel }}</strong>
<br>
<small class="text-muted">ID: {{ dokument.paperless_document_id }}</small>
</td>
<td>
<span class="badge bg-secondary">{{ dokument.get_kontext_display }}</span>
</td>
<td>
{% if dokument.verpachtung_id %}
<span class="badge bg-info">Verpachtung</span>
{% elif dokument.land_id %}
<span class="badge bg-success">Länderei</span>
{% elif dokument.paechter_id %}
<span class="badge bg-primary">Pächter</span>
{% elif dokument.destinataer_id %}
<span class="badge bg-warning">Destinatär</span>
{% elif dokument.foerderung_id %}
<span class="badge bg-secondary">Förderung</span>
{% else %}
<span class="text-muted">Keine Verknüpfung</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{{ dokument.get_paperless_url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="In Paperless öffnen">
<i class="fas fa-external-link-alt"></i>
</a>
<a href="{% url 'stiftung:dokument_detail' dokument.pk %}" class="btn btn-sm btn-outline-info" title="Details">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:dokument_update' dokument.pk %}" class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-link fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Dokumente verknüpft</h5>
<p class="text-muted">Verknüpfen Sie Dokumente aus Paperless mit Ihren Entitäten.</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Verfügbare Paperless-Dokumente -->
{% if available_dokumente %}
<div class="row mb-4">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-info">
<i class="fas fa-plus-circle me-2"></i>Verfügbare Paperless-Dokumente ({{ available_dokumente|length }})
</h6>
</div>
<div class="card-body">
<div class="row">
{% for doc in available_dokumente %}
<div class="col-md-6 col-lg-4 mb-3">
<div class="card h-100 border-info">
<div class="card-body">
<h6 class="card-title">{{ doc.title }}</h6>
<div class="mb-2">
{% for tag in doc.tags %}
{% if tag == 'Stiftung_Destinatäre' or tag == 'Stiftung_Land_und_Pächter' or tag == 'Stiftung_Administration' %}
<span class="badge bg-primary me-1">{{ tag }}</span>
{% else %}
<span class="badge bg-light text-dark me-1">{{ tag }}</span>
{% endif %}
{% endfor %}
</div>
<div class="d-flex justify-content-between align-items-center">
<a href="{{ doc.document_url }}" target="_blank" class="btn btn-sm btn-outline-info">
<i class="fas fa-external-link-alt me-1"></i>In Paperless öffnen
</a>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-sm btn-success">
<i class="fas fa-link me-1"></i>Verknüpfen
</a>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,551 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Dokumentenverwaltung - Stiftung{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h1><i class="fas fa-folder-open me-2"></i>Dokumentenverwaltung</h1>
<div>
<a href="{% url 'stiftung:dokument_list' %}" class="btn btn-outline-primary">
<i class="fas fa-list me-1"></i>Alle Dokumente anzeigen
</a>
</div>
</div>
<div id="statusMessages"></div>
<!-- Filter -->
<div class="card mb-3">
<div class="card-header">
<i class="fas fa-filter me-2"></i>Filter
</div>
<div class="card-body">
<div class="row g-3">
<div class="col-md-3">
<label class="form-label">Kategorie</label>
<select id="filterCategory" class="form-select">
<option value="all">Alle</option>
<option value="destinaere">Destinatäre</option>
<option value="land">Ländereien</option>
<option value="admin">Administration</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label">Suche im Titel</label>
<input id="filterQuery" class="form-control" placeholder="Titel enthält..." />
</div>
<div class="col-md-3 d-flex align-items-end">
<button id="refreshDocuments" class="btn btn-primary w-100">
<i class="fas fa-sync me-1"></i>Aktualisieren
</button>
</div>
</div>
</div>
</div>
<!-- Dokumente-Liste -->
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<div><i class="fas fa-file-alt me-2"></i>Dokumente</div>
<small class="text-muted" id="counts"></small>
</div>
<div class="card-body" id="documentsContainer">
<div class="text-center py-5 text-muted" id="loadingState">
<div class="spinner-border" role="status"></div>
<p class="mt-2">Lade Dokumente...</p>
</div>
</div>
</div>
<!-- Re-Link Modal -->
<div class="modal fade" id="relinkModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Dokument neu verknüpfen</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-3"><strong id="relinkDocTitle"></strong></div>
<div id="currentLinks" class="mb-3"></div>
<div class="row g-3">
<div class="col-md-4">
<label class="form-label">Kategorie</label>
<select id="relinkCategory" class="form-select">
<option value="destinataer">Destinatäre</option>
<option value="land">Ländereien</option>
<option value="paechter">Pächter</option>
<option value="verpachtung">Verpachtungen</option>
<option value="rentmeister">Rentmeister</option>
</select>
</div>
<div class="col-md-8">
<label class="form-label">Suche</label>
<div class="input-group">
<input id="relinkQuery" class="form-control" placeholder="Name, Ort, E-Mail, Telefon, Adresse..." />
<button id="relinkSearch" class="btn btn-outline-secondary"><i class="fas fa-search"></i></button>
</div>
<small class="form-text text-muted">Durchsucht Name, Adresse, E-Mail, Telefon und weitere Felder</small>
</div>
</div>
<div class="mt-3" id="relinkResults" style="max-height: 400px; overflow-y: auto; border: 1px solid #dee2e6; border-radius: 0.375rem; padding: 0.5rem;"></div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schließen</button>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_css %}
<style>
.search-result-item:hover {
background-color: #f8f9fa !important;
border-color: #0d6efd !important;
}
#relinkResults::-webkit-scrollbar {
width: 8px;
}
#relinkResults::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
#relinkResults::-webkit-scrollbar-thumb {
background: #c1c1c1;
border-radius: 4px;
}
#relinkResults::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
}
</style>
{% endblock %}
{% block javascript %}
<script>
let allDocuments = [];
let linksByPaperlessId = new Map();
let currentRelink = { linkId: null, paperlessId: null };
function showMessage(message, type) {
const statusDiv = document.getElementById('statusMessages');
const alert = document.createElement('div');
alert.className = `alert alert-${type} alert-dismissible fade show`;
alert.innerHTML = `${message}<button type="button" class="btn-close" data-bs-dismiss="alert"></button>`;
statusDiv.appendChild(alert);
setTimeout(() => alert.remove(), 5000);
}
function fetchData() {
console.log('Fetching updated document data...'); // Debug log
const loadingState = document.getElementById('loadingState');
if (loadingState) {
loadingState.style.display = 'block';
}
console.log('Making API calls to:', [
'/api/paperless/documents/?poll=1',
'/api/link-document/list/'
]);
Promise.all([
fetch('/api/paperless/documents/?poll=1').then(r => {
console.log('Paperless API response status:', r.status, r.ok);
if (!r.ok) {
throw new Error(`Paperless API failed: ${r.status} ${r.statusText}`);
}
return r.json();
}),
fetch('/api/link-document/list/').then(r => {
console.log('Link API response status:', r.status, r.ok);
if (!r.ok) {
throw new Error(`Link API failed: ${r.status} ${r.statusText}`);
}
return r.json();
})
]).then(([docs, linksResp]) => {
console.log('Data fetched successfully:', { docs: docs.documents?.length, links: linksResp.links?.length }); // Debug log
console.log('Full docs response:', docs); // Debug the full response
console.log('Full links response:', linksResp); // Debug the full response
allDocuments = docs.documents || [];
linksByPaperlessId = new Map();
// Handle new grouped links format
(linksResp.links || []).forEach(docLinks => {
console.log(`Setting linksByPaperlessId for document ${docLinks.paperless_id}:`, docLinks);
linksByPaperlessId.set(docLinks.paperless_id, docLinks);
});
console.log('Final linksByPaperlessId Map:', linksByPaperlessId);
renderDocuments();
const countsElement = document.getElementById('counts');
if (countsElement) {
countsElement.textContent = `Gesamt: ${docs.total_all} | Destinatäre: ${docs.total_destinaere} | Land: ${docs.total_land} | Admin: ${docs.total_admin}`;
}
}).catch(err => {
console.error('Error fetching data:', err);
console.error('Error details:', {
message: err.message,
stack: err.stack,
name: err.name
});
showMessage('Fehler beim Laden der Daten: ' + err.message, 'danger');
// Show error in the container
const container = document.getElementById('documentsContainer');
if (container) {
container.innerHTML = `
<div class="alert alert-danger">
<h6><i class="fas fa-exclamation-triangle me-2"></i>Fehler beim Laden der Dokumente</h6>
<p class="mb-0">${err.message}</p>
<button class="btn btn-primary mt-2" onclick="fetchData()">
<i class="fas fa-sync me-1"></i>Erneut versuchen
</button>
</div>
`;
}
}).finally(() => {
const loadingState = document.getElementById('loadingState');
if (loadingState) {
loadingState.style.display = 'none';
}
});
}
function renderDocuments() {
const container = document.getElementById('documentsContainer');
const category = document.getElementById('filterCategory').value;
const query = document.getElementById('filterQuery').value.toLowerCase();
let filtered = allDocuments.slice();
if (category !== 'all') {
filtered = filtered.filter(d => d.tag_category === category);
}
if (query) {
filtered = filtered.filter(d => (d.title || '').toLowerCase().includes(query));
}
if (!filtered.length) {
container.innerHTML = '<p class="text-muted">Keine Dokumente gefunden.</p>';
return;
}
let html = '<div class="table-responsive"><table class="table table-striped align-middle"><thead><tr><th>Titel</th><th>Kategorie</th><th>Verknüpft mit</th><th>Aktionen</th></tr></thead><tbody>';
filtered.forEach(doc => {
const linkData = linksByPaperlessId.get(doc.id);
let linkedTo = '<span class="text-muted">nicht verknüpft</span>';
let hasLinks = false;
if (linkData && linkData.links && linkData.links.length > 0) {
console.log(`Document ${doc.id} (${doc.title}) has ${linkData.links.length} links:`, linkData.links);
hasLinks = true;
const linkItems = linkData.links.map(link => {
const obj = link.linked_object;
if (!obj) {
console.warn('Link missing linked_object:', link);
return `<div class="mb-1"><span class="badge bg-warning me-1">Fehler</span> Fehlerhafter Link</div>`;
}
// Generate the appropriate detail URL based on link type
let detailUrl = '#';
if (link.link_type === 'destinataer') {
detailUrl = `/destinataere/${obj.id}/`;
} else if (link.link_type === 'land') {
detailUrl = `/laendereien/${obj.id}/`;
} else if (link.link_type === 'paechter') {
detailUrl = `/paechter/${obj.id}/`;
} else if (link.link_type === 'verpachtung') {
detailUrl = `/verpachtungen/${obj.id}/`;
} else if (link.link_type === 'rentmeister') {
detailUrl = `/geschaeftsfuehrung/rentmeister/${obj.id}/`;
}
return `<div class="mb-1 d-flex align-items-center justify-content-between">
<div class="flex-grow-1">
<span class="badge bg-info me-1">${obj?.type || 'Unbekannt'}</span>
<a href="${detailUrl}" class="text-decoration-none small text-primary" title="Zu ${obj?.type || 'Entität'} navigieren">
${obj?.name || 'Unbekannt'}
<i class="fas fa-external-link-alt ms-1" style="font-size: 0.7em;"></i>
</a>
</div>
<button class="btn btn-sm btn-outline-danger ms-2" onclick="onDeleteLink('${link.id}')" title="Diese Verknüpfung löschen">
<i class="fas fa-times" style="font-size: 0.7em;"></i>
</button>
</div>`;
}).join('');
linkedTo = `<div class="small">${linkItems}</div>`;
console.log(`Final linkedTo HTML for doc ${doc.id}:`, linkedTo);
}
const openUrl = `/api/paperless/documents/${doc.id}/`;
html += `
<tr>
<td><strong>${doc.title || 'Ohne Titel'}</strong><br><small class="text-muted">Paperless-ID: ${doc.id}</small></td>
<td><span class="badge bg-secondary">${doc.tag_category}</span></td>
<td>${linkedTo}</td>
<td>
<a class="btn btn-sm btn-outline-primary" href="${openUrl}" target="_blank" title="In Paperless öffnen"><i class="fas fa-external-link-alt"></i></a>
${hasLinks ? `<button class="btn btn-sm btn-outline-danger" onclick="onDeleteAllLinks(${doc.id})" title="Alle Verknüpfungen löschen"><i class="fas fa-trash"></i></button>` : ''}
<button class="btn btn-sm btn-outline-success" onclick="onRelink('', ${doc.id}, '${(doc.title||'').replace(/'/g, "&#39;")}')" title="Neu verknüpfen"><i class="fas fa-link"></i></button>
</td>
</tr>`;
});
html += '</tbody></table></div>';
container.innerHTML = html;
}
function onRelink(linkId, paperlessId, title) {
currentRelink = { linkId, paperlessId };
document.getElementById('relinkDocTitle').textContent = title;
// Show current links in modal
const linkData = linksByPaperlessId.get(paperlessId);
const currentLinksDiv = document.getElementById('currentLinks');
if (linkData && linkData.links && linkData.links.length > 0) {
let currentLinksHtml = '<div class="alert alert-info"><strong>Aktuell verknüpft mit:</strong><ul class="mb-0 mt-2">';
linkData.links.forEach(link => {
const obj = link.linked_object;
currentLinksHtml += `<li><span class="badge bg-secondary me-1">${obj?.type || 'Unbekannt'}</span> ${obj?.name || 'Unbekannt'}</li>`;
});
currentLinksHtml += '</ul></div>';
currentLinksDiv.innerHTML = currentLinksHtml;
} else {
currentLinksDiv.innerHTML = '<div class="alert alert-warning">Dieses Dokument ist noch nicht verknüpft.</div>';
}
document.getElementById('relinkResults').innerHTML = '';
const modal = new bootstrap.Modal(document.getElementById('relinkModal'));
modal.show();
}
document.getElementById('relinkSearch').addEventListener('click', function() {
const category = document.getElementById('relinkCategory').value;
const q = document.getElementById('relinkQuery').value || 'all';
const target = document.getElementById('relinkResults');
target.innerHTML = '<div class="d-flex align-items-center"><div class="spinner-border spinner-border-sm me-2" role="status"></div>Suche...</div>';
fetch(`/api/link-document/search/?q=${encodeURIComponent(q)}&category=${category}`)
.then(r => r.json())
.then(data => {
let items = data[category] || [];
if (!items.length) {
target.innerHTML = '<div class="text-center py-3 text-muted"><i class="fas fa-search me-2"></i>Keine Treffer gefunden.</div>';
return;
}
let html = `<div class="mb-2"><small class="text-muted">${items.length} Treffer gefunden</small></div>`;
// Get current links for this document to mark already linked entities
const linkData = linksByPaperlessId.get(currentRelink.paperlessId);
const currentlyLinkedIds = new Set();
if (linkData && linkData.links) {
linkData.links.forEach(link => {
if (link.linked_object && link.linked_object.id) {
currentlyLinkedIds.add(link.linked_object.id);
}
});
}
items.forEach(it => {
const isLinked = currentlyLinkedIds.has(it.id);
const linkClass = isLinked ? 'border-success bg-light' : 'border';
const buttonClass = isLinked ? 'btn-success' : 'btn-outline-primary';
const buttonIcon = isLinked ? 'fas fa-check-circle' : 'fas fa-plus';
const buttonText = isLinked ? 'Bereits verknüpft' : 'Verknüpfen';
html += `<div class="d-flex justify-content-between align-items-start ${linkClass} rounded p-3 mb-2 search-result-item" style="transition: all 0.2s;">
<div class="flex-grow-1">
<div class="fw-bold mb-1">${it.name}</div>
<div class="text-muted small mb-1">${it.details || ''}</div>
${isLinked ? '<span class="badge bg-success mt-1"><i class="fas fa-check-circle me-1"></i>Aktuell verknüpft</span>' : ''}
</div>
<button class="btn btn-sm ${buttonClass} ms-3" onclick="confirmRelink('${it.id}', '${category}')" title="${buttonText}" ${isLinked ? 'disabled' : ''}>
<i class="${buttonIcon} me-1"></i>${isLinked ? 'Verknüpft' : 'Auswählen'}
</button>
</div>`;
});
target.innerHTML = html;
})
.catch(() => { target.innerHTML = '<div class="text-center py-3 text-danger"><i class="fas fa-exclamation-triangle me-2"></i>Fehler bei der Suche</div>'; });
});
function onDeleteAllLinks(paperlessId) {
const linkData = linksByPaperlessId.get(paperlessId);
if (!linkData || !linkData.links || linkData.links.length === 0) {
showMessage('Keine Verknüpfungen zum Löschen gefunden', 'warning');
return;
}
if (!confirm(`Möchten Sie wirklich alle ${linkData.links.length} Verknüpfung(en) für dieses Dokument löschen?`)) {
return;
}
console.log(`Deleting all ${linkData.links.length} links for document ${paperlessId}:`, linkData.links);
// Delete all links for this document with proper CSRF token
const deletePromises = linkData.links.map(link => {
console.log(`Deleting link ${link.id}`);
return fetch(`/api/link-document/delete/${link.id}/`, {
method: 'DELETE',
headers: { 'X-CSRFToken': getCookie('csrftoken') }
});
});
Promise.all(deletePromises).then(responses => {
console.log('All delete responses:', responses.map(r => ({ status: r.status, ok: r.ok })));
const allSuccessful = responses.every(r => r.ok);
const failedCount = responses.filter(r => !r.ok).length;
if (allSuccessful) {
showMessage('Alle Verknüpfungen erfolgreich gelöscht', 'success');
setTimeout(() => {
fetchData();
}, 300);
} else {
console.error(`${failedCount} of ${responses.length} delete requests failed`);
showMessage(`Fehler beim Löschen von ${failedCount} Verknüpfung(en)`, 'danger');
}
}).catch(err => {
console.error('Error during bulk delete:', err);
showMessage('Fehler beim Löschen der Verknüpfungen', 'danger');
});
}
// Add Enter key support for search
document.getElementById('relinkQuery').addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
document.getElementById('relinkSearch').click();
}
});
function confirmRelink(targetId, category) {
console.log('confirmRelink called:', { targetId, category, currentRelink });
const isUpdate = !!currentRelink.linkId;
const url = isUpdate ? '/api/link-document/update/' : '/api/link-document/create/';
const payload = isUpdate ? {
link_id: currentRelink.linkId,
link_type: category,
link_id_target: targetId
} : {
paperless_id: currentRelink.paperlessId,
paperless_title: document.getElementById('relinkDocTitle').textContent,
paperless_url: `/api/paperless/documents/${currentRelink.paperlessId}/`,
link_type: category,
link_id: targetId
};
console.log('Sending request:', { url, payload });
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCookie('csrftoken') },
body: JSON.stringify(payload)
}).then(async r => {
console.log('Response status:', r.status, r.ok);
let resp = {};
try {
resp = await r.json();
console.log('Response data:', resp);
} catch (e) {
console.log('No JSON response, treating as success if status OK');
if (r.ok) {
resp = { success: true };
} else {
throw new Error('Network response was not ok');
}
}
if (r.ok && (resp.success || resp.message)) {
console.log('Success! Showing message and refreshing...');
showMessage(resp.message || 'Verknüpfung gespeichert', 'success');
// Close modal first, then refresh data
const modal = bootstrap.Modal.getInstance(document.getElementById('relinkModal'));
if (modal) {
console.log('Closing modal...');
modal.hide();
}
// Clear search results to prevent confusion
document.getElementById('relinkResults').innerHTML = '';
document.getElementById('relinkQuery').value = '';
// Try immediate refresh first
console.log('Calling fetchData() immediately...');
fetchData();
// Also schedule a backup refresh to be sure
console.log('Scheduling backup refresh in 500ms...');
setTimeout(() => {
console.log('Backup fetchData() call...');
fetchData();
}, 500);
} else {
console.log('Error response:', resp);
showMessage(resp.error || 'Fehler beim Speichern', 'danger');
}
}).catch(err => {
console.error('Relink error:', err);
showMessage('Fehler beim Speichern', 'danger');
});
}
function onDeleteLink(linkId) {
if (!confirm('Diese Verknüpfung wirklich löschen?')) return;
console.log('Deleting individual link:', linkId);
fetch(`/api/link-document/delete/${linkId}/`, {
method: 'DELETE',
headers: { 'X-CSRFToken': getCookie('csrftoken') }
})
.then(async r => {
console.log('Delete response status:', r.status, r.ok);
let data = {};
try {
data = await r.json();
console.log('Delete response data:', data);
} catch (_) {
console.log('No JSON response, treating as success if status OK');
}
if (r.ok && (data.success === undefined || data.success === true)) {
showMessage('Verknüpfung gelöscht', 'success');
setTimeout(() => {
fetchData();
}, 300);
} else {
showMessage((data && data.error) || 'Fehler beim Löschen', 'danger');
}
})
.catch(err => {
console.error('Delete error:', err);
showMessage('Fehler beim Löschen', 'danger');
});
}
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
document.getElementById('refreshDocuments').addEventListener('click', fetchData);
document.getElementById('filterCategory').addEventListener('change', renderDocuments);
document.getElementById('filterQuery').addEventListener('input', () => { renderDocuments(); });
document.addEventListener('DOMContentLoaded', function() {
console.log('Dokumentenverwaltung page loaded, calling fetchData()...');
fetchData();
});
</script>
{% endblock %}

View File

@@ -0,0 +1,47 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Förderung löschen - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-6 mx-auto">
<div class="card shadow">
<div class="card-header bg-danger text-white">
<h4 class="mb-0">
<i class="fas fa-exclamation-triangle me-2"></i>Förderung löschen
</h4>
</div>
<div class="card-body">
<div class="alert alert-warning">
<h5 class="alert-heading">
<i class="fas fa-exclamation-triangle me-2"></i>Warnung!
</h5>
<p class="mb-0">
Sind Sie sicher, dass Sie die Förderung für <strong>{{ foerderung.person.get_full_name }}</strong>
({{ foerderung.jahr }}, €{{ foerderung.betrag|floatformat:2 }}) löschen möchten?
</p>
</div>
<p class="text-muted">
Diese Aktion kann nicht rückgängig gemacht werden. Alle zugehörigen Daten werden permanent gelöscht.
</p>
<form method="post">
{% csrf_token %}
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:foerderung_detail' foerderung.pk %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Endgültig löschen
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,168 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-8 mx-auto">
<div class="card shadow">
<div class="card-header d-flex justify-content-between align-items-center">
<h4 class="mb-0">
<i class="fas fa-gift text-primary me-2"></i>Förderung Details
</h4>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:foerderung_update' foerderung.pk %}" class="btn btn-warning">
<i class="fas fa-edit me-1"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:foerderung_delete' foerderung.pk %}" class="btn btn-danger">
<i class="fas fa-trash me-1"></i>Löschen
</a>
</div>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-primary">Person</h6>
<p class="mb-3">
<a href="{% url 'stiftung:destinataer_detail' foerderung.destinataer.pk %}">
{{ foerderung.person.get_full_name }}
</a>
</p>
<h6 class="text-primary">Jahr</h6>
<p class="mb-3">{{ foerderung.jahr }}</p>
<h6 class="text-primary">Betrag</h6>
<p class="mb-3">€{{ foerderung.betrag|floatformat:2 }}</p>
</div>
<div class="col-md-6">
<h6 class="text-primary">Kategorie</h6>
<p class="mb-3">
<span class="badge bg-secondary">{{ foerderung.get_kategorie_display }}</span>
</p>
<h6 class="text-primary">Status</h6>
<p class="mb-3">
<span class="badge bg-{{ foerderung.get_status_color }}">{{ foerderung.get_status_display }}</span>
</p>
<h6 class="text-primary">Antragsdatum</h6>
<p class="mb-3">{{ foerderung.antragsdatum|date:"d.m.Y" }}</p>
</div>
</div>
{% if foerderung.entscheidungsdatum %}
<div class="row">
<div class="col-md-6">
<h6 class="text-primary">Entscheidungsdatum</h6>
<p class="mb-3">{{ foerderung.entscheidungsdatum|date:"d.m.Y" }}</p>
</div>
</div>
{% endif %}
{% if foerderung.verwendungsnachweis %}
<div class="row">
<div class="col-12">
<h6 class="text-primary">Verwendungsnachweis</h6>
<p class="mb-3">
<a href="{% url 'stiftung:dokument_detail' foerderung.verwendungsnachweis.pk %}">
{{ foerderung.verwendungsnachweis.titel }}
</a>
</p>
</div>
</div>
{% endif %}
<!-- Verknüpfte Dokumente -->
<div class="row">
<div class="col-12">
<h6 class="text-primary">Verknüpfte Dokumente</h6>
{% if verknuepfte_dokumente %}
<div class="table-responsive">
<table class="table table-sm table-hover">
<thead class="table-light">
<tr>
<th>Dokument</th>
<th>Kontext</th>
<th>Beschreibung</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for dokument in verknuepfte_dokumente %}
<tr>
<td>
<strong>{{ dokument.titel }}</strong>
<br>
<small class="text-muted">ID: {{ dokument.paperless_document_id }}</small>
</td>
<td>
<span class="badge bg-secondary">{{ dokument.get_kontext_display }}</span>
</td>
<td>
{% if dokument.beschreibung %}
{{ dokument.beschreibung|truncatewords:8 }}
{% else %}
<span class="text-muted">Keine Beschreibung</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{{ dokument.get_paperless_url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="In Paperless öffnen">
<i class="fas fa-external-link-alt"></i>
</a>
<a href="{% url 'stiftung:dokument_update' dokument.pk %}" class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="mt-2">
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-sm btn-success">
<i class="fas fa-plus me-1"></i>Weiteres Dokument verknüpfen
</a>
</div>
{% else %}
<div class="text-center py-3">
<i class="fas fa-file-alt fa-2x text-muted mb-2"></i>
<p class="text-muted mb-2">Keine Dokumente verknüpft</p>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-success btn-sm">
<i class="fas fa-plus me-1"></i>Erstes Dokument verknüpfen
</a>
</div>
{% endif %}
</div>
</div>
{% if foerderung.bemerkungen %}
<div class="row">
<div class="col-12">
<h6 class="text-primary">Bemerkungen</h6>
<p class="mb-3">{{ foerderung.bemerkungen }}</p>
</div>
</div>
{% endif %}
<hr class="my-4">
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:foerderung_list' %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
<a href="{% url 'stiftung:foerderung_update' foerderung.pk %}" class="btn btn-primary">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,165 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-8 mx-auto">
<div class="card shadow">
<div class="card-header">
<h4 class="mb-0">
<i class="fas fa-gift text-primary me-2"></i>{{ title }}
</h4>
</div>
<div class="card-body">
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.person.id_for_label }}" class="form-label">
{{ form.person.label }} *
</label>
{{ form.person }}
{% if form.person.errors %}
<div class="invalid-feedback d-block">
{{ form.person.errors.0 }}
</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.jahr.id_for_label }}" class="form-label">
{{ form.jahr.label }} *
</label>
{{ form.jahr }}
{% if form.jahr.errors %}
<div class="invalid-feedback d-block">
{{ form.jahr.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.betrag.id_for_label }}" class="form-label">
{{ form.betrag.label }} *
</label>
<div class="input-group">
<span class="input-group-text"></span>
{{ form.betrag }}
</div>
{% if form.betrag.errors %}
<div class="invalid-feedback d-block">
{{ form.betrag.errors.0 }}
</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.kategorie.id_for_label }}" class="form-label">
{{ form.kategorie.label }} *
</label>
{{ form.kategorie }}
{% if form.kategorie.errors %}
<div class="invalid-feedback d-block">
{{ form.kategorie.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.status.id_for_label }}" class="form-label">
{{ form.status.label }} *
</label>
{{ form.status }}
{% if form.status.errors %}
<div class="invalid-feedback d-block">
{{ form.status.errors.0 }}
</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.antragsdatum.id_for_label }}" class="form-label">
{{ form.antragsdatum.label }} *
</label>
{{ form.antragsdatum }}
{% if form.antragsdatum.errors %}
<div class="invalid-feedback d-block">
{{ form.antragsdatum.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.entscheidungsdatum.id_for_label }}" class="form-label">
{{ form.entscheidungsdatum.label }}
</label>
{{ form.entscheidungsdatum }}
{% if form.entscheidungsdatum.errors %}
<div class="invalid-feedback d-block">
{{ form.entscheidungsdatum.errors.0 }}
</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.verwendungsnachweis.id_for_label }}" class="form-label">
{{ form.verwendungsnachweis.label }}
</label>
{{ form.verwendungsnachweis }}
{% if form.verwendungsnachweis.errors %}
<div class="invalid-feedback d-block">
{{ form.verwendungsnachweis.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="mb-3">
<label for="{{ form.bemerkungen.id_for_label }}" class="form-label">
{{ form.bemerkungen.label }}
</label>
{{ form.bemerkungen }}
{% if form.bemerkungen.errors %}
<div class="invalid-feedback d-block">
{{ form.bemerkungen.errors.0 }}
</div>
{% endif %}
</div>
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:foerderung_list' %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-2"></i>Speichern
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_css %}
<style>
.form-control, .form-select {
border-radius: 0.375rem;
}
.form-control:focus, .form-select:focus {
border-color: #86b7fe;
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}
</style>
{% endblock %}

View File

@@ -0,0 +1,203 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Förderungen - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3">
<i class="fas fa-gift text-primary me-2"></i>Förderungen
</h1>
<a href="{% url 'stiftung:foerderung_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-2"></i> Neue Förderung
</a>
</div>
<!-- Statistics Cards -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-primary text-white">
<div class="card-body">
<h5 class="card-title">Gesamtbetrag</h5>
<h3 class="card-text">€{{ total_betrag|floatformat:2 }}</h3>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body">
<h5 class="card-title">Durchschnitt</h5>
<h3 class="card-text">€{{ avg_betrag|floatformat:2 }}</h3>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-info text-white">
<div class="card-body">
<h5 class="card-title">Anzahl</h5>
<h3 class="card-text">{{ page_obj.paginator.count }}</h3>
</div>
</div>
</div>
</div>
<!-- Filters -->
<div class="card mb-4">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-filter me-2"></i>Filter
</h6>
</div>
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-2">
<label for="jahr" class="form-label">Jahr</label>
<select name="jahr" id="jahr" class="form-select">
<option value="">Alle Jahre</option>
{% for year in jahre %}
<option value="{{ year }}" {% if filter_jahr == year %}selected{% endif %}>{{ year }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label for="kategorie" class="form-label">Kategorie</label>
<select name="kategorie" id="kategorie" class="form-select">
<option value="">Alle Kategorien</option>
{% for kategorie in kategorien %}
<option value="{{ kategorie.0 }}" {% if filter_kategorie == kategorie.0 %}selected{% endif %}>{{ kategorie.1 }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label for="status" class="form-label">Status</label>
<select name="status" id="status" class="form-select">
<option value="">Alle Status</option>
{% for status in status_choices %}
<option value="{{ status.0 }}" {% if filter_status == status.0 %}selected{% endif %}>{{ status.1 }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-3">
<label for="person" class="form-label">Person</label>
<input type="text" name="person" id="person" class="form-control" value="{{ filter_person }}" placeholder="Nachname suchen">
</div>
<div class="col-md-3 d-flex align-items-end">
<button type="submit" class="btn btn-primary me-2">
<i class="fas fa-search me-2"></i>Filtern
</button>
<a href="{% url 'stiftung:foerderung_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-2"></i>Zurücksetzen
</a>
</div>
</form>
</div>
</div>
<!-- Förderungen Table -->
<div class="card">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-list me-2"></i>Förderungen
</h6>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Person</th>
<th>Jahr</th>
<th>Betrag</th>
<th>Kategorie</th>
<th>Status</th>
<th>Antragsdatum</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for foerderung in page_obj %}
<tr>
<td>
<a href="{% url 'stiftung:destinataer_detail' foerderung.destinataer.pk %}">
{{ foerderung.person.get_full_name }}
</a>
</td>
<td>{{ foerderung.jahr }}</td>
<td>€{{ foerderung.betrag|floatformat:2 }}</td>
<td>
<span class="badge bg-secondary">{{ foerderung.get_kategorie_display }}</span>
</td>
<td>
<span class="badge bg-{{ foerderung.get_status_color }}">{{ foerderung.get_status_display }}</span>
</td>
<td>{{ foerderung.antragsdatum|date:"d.m.Y" }}</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:foerderung_detail' foerderung.pk %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:foerderung_update' foerderung.pk %}" class="btn btn-sm btn-outline-warning">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:foerderung_delete' foerderung.pk %}" class="btn btn-sm btn-outline-danger">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Förderungen Pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if filter_jahr %}&jahr={{ filter_jahr }}{% endif %}{% if filter_kategorie %}&kategorie={{ filter_kategorie }}{% endif %}{% if filter_status %}&status={{ filter_status }}{% endif %}{% if filter_person %}&person={{ filter_person }}{% endif %}">
<i class="fas fa-chevron-left"></i>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}{% if filter_jahr %}&jahr={{ filter_jahr }}{% endif %}{% if filter_kategorie %}&kategorie={{ filter_kategorie }}{% endif %}{% if filter_status %}&status={{ filter_status }}{% endif %}{% if filter_person %}&person={{ filter_person }}{% endif %}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if filter_jahr %}&jahr={{ filter_jahr }}{% endif %}{% if filter_kategorie %}&kategorie={{ filter_kategorie }}{% endif %}{% if filter_status %}&status={{ filter_status }}{% endif %}{% if filter_person %}&person={{ filter_person }}{% endif %}">
<i class="fas fa-chevron-right"></i>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-gift fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Förderungen gefunden</h5>
<p class="text-muted">Erstellen Sie Ihre erste Förderung oder passen Sie die Filter an.</p>
<a href="{% url 'stiftung:foerderung_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-2"></i>Neue Förderung erstellen
</a>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,224 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Geschäftsführung - 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-briefcase me-2"></i>Geschäftsführung
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:rentmeister_list' %}" class="btn btn-primary">
<i class="fas fa-user-tie me-1"></i>Rentmeister
</a>
<a href="{% url 'stiftung:konto_list' %}" class="btn btn-outline-primary">
<i class="fas fa-university me-1"></i>Konten
</a>
<a href="{% url 'stiftung:verwaltungskosten_list' %}" class="btn btn-outline-primary">
<i class="fas fa-file-invoice-dollar me-1"></i>Verwaltungskosten
</a>
</div>
</div>
</div>
</div>
<!-- Rentmeister-Übersicht -->
<div class="row">
<div class="col-xl-12 col-lg-12">
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-user-tie me-2"></i>Aktive Rentmeister
</h6>
<a href="{% url 'stiftung:rentmeister_list' %}" class="btn btn-sm btn-outline-primary">
Alle verwalten
</a>
</div>
<div class="card-body">
{% if rentmeister %}
<div class="row">
{% for rm in rentmeister %}
<div class="col-md-6 col-lg-4 mb-3">
<div class="card border-primary">
<div class="card-body text-center">
<i class="fas fa-user-tie fa-2x text-primary mb-2"></i>
<h6>{{ rm.get_full_name }}</h6>
<small class="text-muted">seit {{ rm.seit_datum|date:"d.m.Y" }}</small>
{% if rm.email %}
<br><small><i class="fas fa-envelope me-1"></i>{{ rm.email }}</small>
{% endif %}
<div class="mt-2">
<a href="{% url 'stiftung:rentmeister_detail' rm.pk %}" class="btn btn-sm btn-primary">
Details
</a>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<p class="text-muted">Keine aktiven Rentmeister vorhanden.</p>
<a href="{% url 'stiftung:rentmeister_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Ersten Rentmeister anlegen
</a>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Konten-Übersicht -->
<div class="row">
<div class="col-xl-6 col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-university me-2"></i>Stiftungskonten
</h6>
<span class="badge bg-primary">{{ konten.count }} Konten</span>
</div>
<div class="card-body">
{% if konten %}
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Bank</th>
<th>Kontoname</th>
<th>Typ</th>
<th class="text-end">Saldo</th>
</tr>
</thead>
<tbody>
{% for konto in konten %}
<tr>
<td>{{ konto.bank_name }}</td>
<td>{{ konto.kontoname }}</td>
<td>
<span class="badge bg-secondary">{{ konto.get_konto_typ_display }}</span>
</td>
<td class="text-end">
<strong>€{{ konto.saldo|floatformat:2 }}</strong>
</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr class="table-primary">
<th colspan="3">Gesamtsaldo</th>
<th class="text-end">€{{ gesamtsaldo|floatformat:2 }}</th>
</tr>
</tfoot>
</table>
</div>
{% else %}
<p class="text-muted">Keine Konten vorhanden.</p>
{% endif %}
</div>
</div>
</div>
<!-- Kosten-Statistik -->
<div class="col-xl-6 col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-chart-pie me-2"></i>Kosten (letzte 30 Tage)
</h6>
<span class="badge bg-warning">€{{ kosten_summe_monat|floatformat:2 }}</span>
</div>
<div class="card-body">
{% if kosten_statistik %}
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Kategorie</th>
<th class="text-center">Anzahl</th>
<th class="text-end">Summe</th>
</tr>
</thead>
<tbody>
{% for stat in kosten_statistik %}
<tr>
<td>{{ stat.kategorie|capfirst }}</td>
<td class="text-center">{{ stat.anzahl }}</td>
<td class="text-end">€{{ stat.summe|floatformat:2 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="text-muted">Keine Kosten in den letzten 30 Tagen.</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Aktuelle Kosten -->
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-file-invoice-dollar me-2"></i>Aktuelle Verwaltungskosten
</h6>
<a href="{% url 'stiftung:verwaltungskosten_list' %}" class="btn btn-sm btn-outline-primary">
Alle anzeigen
</a>
</div>
<div class="card-body">
{% if aktuelle_kosten %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Datum</th>
<th>Bezeichnung</th>
<th>Kategorie</th>
<th>Lieferant</th>
<th>Status</th>
<th class="text-end">Betrag</th>
</tr>
</thead>
<tbody>
{% for kosten in aktuelle_kosten %}
<tr>
<td>{{ kosten.datum|date:"d.m.Y" }}</td>
<td>
<strong>{{ kosten.bezeichnung }}</strong>
{% if kosten.rechnungsnummer %}
<br><small class="text-muted">RG: {{ kosten.rechnungsnummer }}</small>
{% endif %}
</td>
<td>
<span class="badge bg-info">{{ kosten.get_kategorie_display }}</span>
</td>
<td>{{ kosten.lieferant_firma|default:"-" }}</td>
<td>
<span class="badge bg-{{ kosten.get_status_color }}">{{ kosten.get_status_display }}</span>
</td>
<td class="text-end">
<strong>€{{ kosten.betrag|floatformat:2 }}</strong>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="text-muted">Keine aktuellen Verwaltungskosten vorhanden.</p>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,179 @@
{% extends "base.html" %}
{% block title %}{{ title }} - Foundation Management System{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-body text-center py-5">
<h1 class="display-4 mb-4">
<i class="fas fa-landmark text-primary me-3"></i>van Hees-Theyssen-Vogel'sche Stiftung
</h1>
<p class="lead text-muted mb-5">Stiftungsverwaltung - Modern Foundation Management System</p>
<div class="row justify-content-center mb-4">
<div class="col-md-8">
<div class="card border-0 bg-light">
<div class="card-body text-center py-3">
<p class="mb-1"><i class="fas fa-map-marker-alt text-primary me-2"></i>Raesfelder Str. 3, 46499 Hamminkeln</p>
<p class="mb-0"><i class="fas fa-phone text-primary me-2"></i>+49 (0) 2852 12345</p>
</div>
</div>
</div>
</div>
<div class="row g-4 mb-5">
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<i class="fas fa-users fa-3x text-primary mb-3"></i>
<h5 class="card-title">👥 Destinatäre</h5>
<p class="card-text">Verwalten Sie Stiftungsmitglieder, Familienzweige und Kontaktdaten zentral und übersichtlich.</p>
<a href="{% url 'stiftung:destinataer_list' %}" class="btn btn-outline-primary btn-sm mt-2">
<i class="fas fa-external-link-alt me-1"></i>Öffnen
</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<i class="fas fa-gift fa-3x text-success mb-3"></i>
<h5 class="card-title">💰 Förderungsverwaltung</h5>
<p class="card-text">Erfassen und verfolgen Sie Förderungen, Beträge und Verwendungsnachweise systematisch.</p>
<a href="{% url 'stiftung:foerderung_list' %}" class="btn btn-outline-success btn-sm mt-2">
<i class="fas fa-external-link-alt me-1"></i>Öffnen
</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<i class="fas fa-file-alt fa-3x text-info mb-3"></i>
<h5 class="card-title">📄 Dokumentenverwaltung</h5>
<p class="card-text">Stiftungsdokumente und Verträge</p>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-outline-info btn-sm mt-2">
<i class="fas fa-external-link-alt me-1"></i>Öffnen
</a>
</div>
</div>
</div>
</div>
<div class="row g-4 mb-5">
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<i class="fas fa-chart-bar fa-3x text-warning mb-3"></i>
<h5 class="card-title">📊 Berichte & Auswertungen</h5>
<p class="card-text">Generieren Sie detaillierte Berichte und Auswertungen für Ihre Stiftungsarbeit.</p>
<a href="{% url 'stiftung:bericht_list' %}" class="btn btn-outline-warning btn-sm mt-2">
<i class="fas fa-external-link-alt me-1"></i>Öffnen
</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<i class="fas fa-map fa-3x text-danger mb-3"></i>
<h5 class="card-title">🗺️ Ländereiverwaltung</h5>
<p class="card-text">Verwalten Sie Grundstücke, Flächen und Verpachtungen professionell.</p>
<a href="{% url 'stiftung:land_list' %}" class="btn btn-outline-danger btn-sm mt-2">
<i class="fas fa-external-link-alt me-1"></i>Öffnen
</a>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<i class="fas fa-handshake fa-3x text-secondary mb-3"></i>
<h5 class="card-title">🤝 Verpachtungsverwaltung</h5>
<p class="card-text">Organisieren Sie Pachtverträge und deren Verwaltung effizient.</p>
<a href="{% url 'stiftung:verpachtung_list' %}" class="btn btn-outline-secondary btn-sm mt-2">
<i class="fas fa-external-link-alt me-1"></i>Öffnen
</a>
</div>
</div>
</div>
</div>
<div class="row g-4 mb-5">
<div class="col-md-6">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<i class="fas fa-link fa-3x text-purple mb-3"></i>
<h5 class="card-title">🔗 Dokumentenverknüpfung</h5>
<p class="card-text">Verknüpfen Sie Paperless-Dokumente direkt mit Destinatären, Ländereien und Verpachtungen.</p>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-outline-purple btn-sm mt-2">
<i class="fas fa-external-link-alt me-1"></i>Öffnen
</a>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-100 border-0 shadow-sm">
<div class="card-body text-center p-4">
<i class="fas fa-database fa-3x text-dark mb-3"></i>
<h5 class="card-title">🗃️ Dokumentenarchiv</h5>
<p class="card-text">Zentraler Zugriff auf alle verknüpften Dokumente und deren Metadaten.</p>
<a href="{% url 'stiftung:dokument_list' %}" class="btn btn-outline-dark btn-sm mt-2">
<i class="fas fa-external-link-alt me-1"></i>Öffnen
</a>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-center gap-3 flex-wrap">
<a href="{% url 'stiftung:destinataer_list' %}" class="btn btn-primary btn-lg">
<i class="fas fa-users me-2"></i>Destinatäre
</a>
<a href="{% url 'stiftung:land_list' %}" class="btn btn-success btn-lg">
<i class="fas fa-map me-2"></i>Ländereien
</a>
<a href="{% url 'stiftung:paechter_list' %}" class="btn btn-info btn-lg">
<i class="fas fa-user-tie me-2"></i>Pächter
</a>
<a href="{% url 'stiftung:verpachtung_list' %}" class="btn btn-secondary btn-lg">
<i class="fas fa-handshake me-2"></i>Verpachtungen
</a>
<a href="{% url 'stiftung:foerderung_list' %}" class="btn btn-warning btn-lg">
<i class="fas fa-gift me-2"></i>Förderungen
</a>
</div>
<div class="d-flex justify-content-center gap-3 flex-wrap mt-3">
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-info btn-lg">
<i class="fas fa-file-alt me-2"></i>Paperless Integration
</a>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-purple btn-lg">
<i class="fas fa-link me-2"></i>Dokumente verknüpfen
</a>
<a href="{% url 'stiftung:dokument_list' %}" class="btn btn-dark btn-lg">
<i class="fas fa-database me-2"></i>Dokumentenarchiv
</a>
</div>
</div>
</div>
<div class="text-center mt-4">
<div class="alert alert-success d-inline-block">
<i class="fas fa-check-circle me-2"></i>
<span class="fw-bold">System läuft erfolgreich</span>
<br>
<small class="text-muted">Entwickelt mit Django & Docker</small>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,227 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="utf-8">
<title>Stiftung Jahresbericht {{ jahr }}</title>
<style>
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
line-height: 1.6;
margin: 0;
padding: 20px;
color: #333;
}
.header {
text-align: center;
border-bottom: 3px solid #2c3e50;
padding-bottom: 20px;
margin-bottom: 30px;
}
.header h1 {
color: #2c3e50;
margin: 0;
font-size: 2.5em;
}
.header .subtitle {
color: #7f8c8d;
font-size: 1.2em;
margin-top: 10px;
}
.section {
margin-bottom: 30px;
page-break-inside: avoid;
}
.section h2 {
color: #34495e;
border-bottom: 2px solid #3498db;
padding-bottom: 10px;
margin-bottom: 20px;
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 20px;
}
.stat-card {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 20px;
text-align: center;
}
.stat-card .value {
font-size: 2em;
font-weight: bold;
color: #2c3e50;
}
.stat-card .label {
color: #7f8c8d;
margin-top: 5px;
}
table {
border-collapse: collapse;
width: 100%;
margin-bottom: 20px;
}
th, td {
border: 1px solid #dee2e6;
padding: 12px;
text-align: left;
}
th {
background-color: #f8f9fa;
font-weight: 600;
color: #2c3e50;
}
tr:nth-child(even) {
background-color: #f8f9fa;
}
.amount {
text-align: right;
font-family: 'Courier New', monospace;
}
.status-badge {
padding: 4px 8px;
border-radius: 4px;
font-size: 0.9em;
font-weight: 500;
}
.status-beantragt { background-color: #fff3cd; color: #856404; }
.status-genehmigt { background-color: #d1ecf1; color: #0c5460; }
.status-ausgezahlt { background-color: #d4edda; color: #155724; }
.status-abgelehnt { background-color: #f8d7da; color: #721c24; }
.status-storniert { background-color: #e2e3e5; color: #383d41; }
.footer {
margin-top: 40px;
padding-top: 20px;
border-top: 1px solid #dee2e6;
text-align: center;
color: #7f8c8d;
font-size: 0.9em;
}
@media print {
body { margin: 0; padding: 15px; }
.section { page-break-inside: avoid; }
}
</style>
</head>
<body>
<div class="header">
<h1>Stiftung Jahresbericht {{ jahr }}</h1>
<div class="subtitle">Jahresübersicht über Förderungen und Verpachtungen</div>
<div class="subtitle">Erstellt am {{ "now"|date:"d.m.Y" }}</div>
</div>
<!-- Executive Summary -->
<div class="section">
<h2>Zusammenfassung</h2>
<div class="stats-grid">
<div class="stat-card">
<div class="value">€{{ total_foerderungen|floatformat:2 }}</div>
<div class="label">Gesamtförderungen</div>
</div>
<div class="stat-card">
<div class="value">€{{ total_pachtzins|floatformat:2 }}</div>
<div class="label">Gesamtpachtzins</div>
</div>
<div class="stat-card">
<div class="value">{{ foerderungen.count }}</div>
<div class="label">Förderungen</div>
</div>
<div class="stat-card">
<div class="value">{{ verpachtungen.count }}</div>
<div class="label">Aktive Verpachtungen</div>
</div>
</div>
</div>
<!-- Förderungen Section -->
{% if foerderungen %}
<div class="section">
<h2>Förderungen im Jahr {{ jahr }}</h2>
<table>
<thead>
<tr>
<th>Begünstigter</th>
<th>Kategorie</th>
<th>Betrag</th>
<th>Status</th>
<th>Antragsdatum</th>
</tr>
</thead>
<tbody>
{% for foerderung in foerderungen %}
<tr>
<td>{{ foerderung.person.get_full_name }}</td>
<td>{{ foerderung.get_kategorie_display }}</td>
<td class="amount">€{{ foerderung.betrag|floatformat:2 }}</td>
<td>
<span class="status-badge status-{{ foerderung.status }}">
{{ foerderung.get_status_display }}
</span>
</td>
<td>{{ foerderung.antragsdatum|date:"d.m.Y" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
<!-- Verpachtungen Section -->
{% if verpachtungen %}
<div class="section">
<h2>Aktive Verpachtungen im Jahr {{ jahr }}</h2>
<table>
<thead>
<tr>
<th>Länderei</th>
<th>Pächter</th>
<th>Vertragsnummer</th>
<th>Verpachtete Fläche</th>
<th>Jährlicher Pachtzins</th>
<th>Pachtende</th>
</tr>
</thead>
<tbody>
{% for verpachtung in verpachtungen %}
<tr>
<td>{{ verpachtung.land }}</td>
<td>{{ verpachtung.paechter.get_full_name }}</td>
<td>{{ verpachtung.vertragsnummer }}</td>
<td>{{ verpachtung.verpachtete_flaeche|floatformat:2 }} qm</td>
<td class="amount">€{{ verpachtung.pachtzins_jaehrlich|floatformat:2 }}</td>
<td>{{ verpachtung.pachtende|date:"d.m.Y" }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
<!-- Financial Summary -->
<div class="section">
<h2>Finanzielle Übersicht</h2>
<div class="stats-grid">
<div class="stat-card">
<div class="value">€{{ total_foerderungen|floatformat:2 }}</div>
<div class="label">Ausgaben (Förderungen)</div>
</div>
<div class="stat-card">
<div class="value">€{{ total_pachtzins|floatformat:2 }}</div>
<div class="label">Einnahmen (Pachtzins)</div>
</div>
<div class="stat-card">
<div class="value">€{{ total_pachtzins|add:total_foerderungen|floatformat:2 }}</div>
<div class="label">Netto-Position</div>
</div>
</div>
</div>
<div class="footer">
<p>Dieser Bericht wurde automatisch generiert von der Stiftungsverwaltung.</p>
<p>Bei Fragen wenden Sie sich bitte an die Verwaltung.</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,224 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}{{ konto.kontoname }} - 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-university me-2"></i>{{ konto.kontoname }}
<small class="text-muted">{{ konto.bank_name }}</small>
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:konto_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Liste
</a>
<a href="{% url 'stiftung:konto_edit' konto.pk %}" class="btn btn-outline-warning">
<i class="fas fa-edit me-1"></i>Bearbeiten
</a>
<a href="#" class="btn btn-primary">
<i class="fas fa-upload me-1"></i>Transaktionen importieren
</a>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Kontodetails -->
<div class="col-xl-4 col-lg-5">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-info-circle me-2"></i>Kontodetails
</h6>
</div>
<div class="card-body">
<table class="table table-borderless table-sm">
<tr>
<td><strong>Kontoname:</strong></td>
<td>{{ konto.kontoname }}</td>
</tr>
<tr>
<td><strong>Bank:</strong></td>
<td>{{ konto.bank_name }}</td>
</tr>
<tr>
<td><strong>IBAN:</strong></td>
<td><code>{{ konto.iban|default:"-" }}</code></td>
</tr>
<tr>
<td><strong>BIC:</strong></td>
<td><code>{{ konto.bic|default:"-" }}</code></td>
</tr>
<tr>
<td><strong>Kontotyp:</strong></td>
<td>
<span class="badge bg-secondary">{{ konto.get_konto_typ_display }}</span>
</td>
</tr>
<tr>
<td><strong>Status:</strong></td>
<td>
{% if konto.aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</td>
</tr>
{% if konto.zinssatz %}
<tr>
<td><strong>Zinssatz:</strong></td>
<td>{{ konto.zinssatz }}%</td>
</tr>
{% endif %}
{% if konto.laufzeit_bis %}
<tr>
<td><strong>Laufzeit bis:</strong></td>
<td>{{ konto.laufzeit_bis|date:"d.m.Y" }}</td>
</tr>
{% endif %}
</table>
{% if konto.notizen %}
<div class="mt-3">
<h6 class="text-muted">Notizen:</h6>
<div class="small text-muted">
{{ konto.notizen|linebreaks }}
</div>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Saldo und Statistiken -->
<div class="col-xl-8 col-lg-7">
<!-- Aktueller Saldo -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-euro-sign me-2"></i>Aktueller Saldo
</h6>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-md-4">
<div class="mb-3">
<div class="text-muted small">Buchsaldo</div>
<h3 class="{% if konto.saldo < 0 %}text-danger{% elif konto.saldo > 1000 %}text-success{% endif %}">
€{{ konto.saldo|floatformat:2 }}
</h3>
{% if konto.saldo_datum %}
<small class="text-muted">Stand: {{ konto.saldo_datum|date:"d.m.Y" }}</small>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<div class="text-muted small">Transaktionen</div>
<h3 class="text-info">{{ transaction_stats.total_count|default:0 }}</h3>
{% if transaction_stats.last_transaction_date %}
<small class="text-muted">Letzte: {{ transaction_stats.last_transaction_date|date:"d.m.Y" }}</small>
{% else %}
<small class="text-muted">Keine Transaktionen</small>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<div class="text-muted small">Umsatz</div>
<div class="small">
<div class="text-success">
<i class="fas fa-arrow-up me-1"></i>
€{{ transaction_stats.total_eingang|default:0|floatformat:2 }}
</div>
<div class="text-danger">
<i class="fas fa-arrow-down me-1"></i>
€{{ transaction_stats.total_ausgang|default:0|floatformat:2 }}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Letzte Transaktionen -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Letzte Transaktionen
</h6>
{% if recent_transactions %}
<a href="#" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye me-1"></i>Alle anzeigen
</a>
{% endif %}
</div>
<div class="card-body">
{% if recent_transactions %}
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Datum</th>
<th>Verwendungszweck</th>
<th>Empfänger/Zahlungspflichtiger</th>
<th class="text-end">Betrag</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for transaction in recent_transactions %}
<tr>
<td>
<small>{{ transaction.datum|date:"d.m.Y" }}</small>
</td>
<td>
<div class="text-truncate" style="max-width: 200px;">
{{ transaction.verwendungszweck|truncatechars:50 }}
</div>
</td>
<td>
<small>{{ transaction.empfaenger_zahlungspflichtiger|truncatechars:30|default:"-" }}</small>
</td>
<td class="text-end">
<span class="{% if transaction.betrag > 0 %}text-success{% else %}text-danger{% endif %}">
{% if transaction.betrag > 0 %}+{% endif %}€{{ transaction.betrag|floatformat:2 }}
</span>
</td>
<td>
<span class="badge
{% if transaction.status == 'imported' %}bg-secondary
{% elif transaction.status == 'verified' %}bg-info
{% elif transaction.status == 'assigned' %}bg-success
{% elif transaction.status == 'ignored' %}bg-warning
{% else %}bg-dark{% endif %}">
{{ transaction.get_status_display }}
</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-file-invoice fa-2x text-muted mb-3"></i>
<p class="text-muted">Noch keine Transaktionen vorhanden.</p>
<a href="#" class="btn btn-primary">
<i class="fas fa-upload me-1"></i>Erste Transaktionen importieren
</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,210 @@
{% extends 'base.html' %}
{% block title %}{{ title }} - 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-university me-2"></i>{{ title }}
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:konto_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Liste
</a>
{% if konto %}
<a href="{% url 'stiftung:konto_detail' konto.pk %}" class="btn btn-outline-info" title="Transaktionen anzeigen">
<i class="fas fa-list me-1"></i>Transaktionen
</a>
{% endif %}
</div>
</div>
</div>
</div>
<form method="post" novalidate>
{% csrf_token %}
<div class="row">
<!-- Basisdaten -->
<div class="col-xl-6 col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-info-circle me-2"></i>Kontodaten
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="{{ form.kontoname.id_for_label }}" class="form-label">Kontoname *</label>
{{ form.kontoname }}
{% if form.kontoname.errors %}
<div class="text-danger small">{{ form.kontoname.errors.0 }}</div>
{% endif %}
</div>
<div class="mb-3">
<label for="{{ form.bank_name.id_for_label }}" class="form-label">Bank *</label>
{{ form.bank_name }}
{% if form.bank_name.errors %}
<div class="text-danger small">{{ form.bank_name.errors.0 }}</div>
{% endif %}
</div>
<div class="mb-3">
<label for="{{ form.konto_typ.id_for_label }}" class="form-label">Kontotyp</label>
{{ form.konto_typ }}
{% if form.konto_typ.errors %}
<div class="text-danger small">{{ form.konto_typ.errors.0 }}</div>
{% endif %}
</div>
<div class="form-check mb-3">
{{ form.aktiv }}
<label class="form-check-label" for="{{ form.aktiv.id_for_label }}">
Aktiv
</label>
{% if form.aktiv.errors %}
<div class="text-danger small">{{ form.aktiv.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Bankdaten -->
<div class="col-xl-6 col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-credit-card me-2"></i>Bankdaten
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="{{ form.iban.id_for_label }}" class="form-label">IBAN</label>
{{ form.iban }}
{% if form.iban.errors %}
<div class="text-danger small">{{ form.iban.errors.0 }}</div>
{% endif %}
<div class="form-text">Internationale Bankkontonummer</div>
</div>
<div class="mb-3">
<label for="{{ form.bic.id_for_label }}" class="form-label">BIC</label>
{{ form.bic }}
{% if form.bic.errors %}
<div class="text-danger small">{{ form.bic.errors.0 }}</div>
{% endif %}
<div class="form-text">Bank Identifier Code</div>
</div>
</div>
</div>
<!-- Saldo und Zinsen -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-euro-sign me-2"></i>Saldo & Zinsen
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.saldo.id_for_label }}" class="form-label">Aktueller Saldo</label>
<div class="input-group">
{{ form.saldo }}
<span class="input-group-text"></span>
</div>
{% if form.saldo.errors %}
<div class="text-danger small">{{ form.saldo.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.saldo_datum.id_for_label }}" class="form-label">Saldo-Datum</label>
{{ form.saldo_datum }}
{% if form.saldo_datum.errors %}
<div class="text-danger small">{{ form.saldo_datum.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.zinssatz.id_for_label }}" class="form-label">Zinssatz</label>
<div class="input-group">
{{ form.zinssatz }}
<span class="input-group-text">%</span>
</div>
{% if form.zinssatz.errors %}
<div class="text-danger small">{{ form.zinssatz.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.laufzeit_bis.id_for_label }}" class="form-label">Laufzeit bis</label>
{{ form.laufzeit_bis }}
{% if form.laufzeit_bis.errors %}
<div class="text-danger small">{{ form.laufzeit_bis.errors.0 }}</div>
{% endif %}
<div class="form-text">Für Festgeld/Sparkonten</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Notizen -->
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-sticky-note me-2"></i>Notizen
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="{{ form.notizen.id_for_label }}" class="form-label">Notizen</label>
{{ form.notizen }}
{% if form.notizen.errors %}
<div class="text-danger small">{{ form.notizen.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Form Errors -->
{% if form.non_field_errors %}
<div class="row">
<div class="col-12">
<div class="alert alert-danger">
<strong>Fehler:</strong>
{{ form.non_field_errors }}
</div>
</div>
</div>
{% endif %}
<!-- Submit Buttons -->
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-body text-end">
<a href="{% url 'stiftung:konto_list' %}" class="btn btn-secondary me-2">
<i class="fas fa-times me-1"></i>Abbrechen
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-1"></i>{{ submit_text }}
</button>
</div>
</div>
</div>
</div>
</form>
{% endblock %}

View File

@@ -0,0 +1,161 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Stiftungskonten - 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-university me-2"></i>Stiftungskonten
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:geschaeftsfuehrung' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Übersicht
</a>
<a href="{% url 'stiftung:konto_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Neues Konto
</a>
</div>
</div>
</div>
</div>
<!-- Konten Liste -->
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Alle Konten ({{ konten.count }})
</h6>
</div>
<div class="card-body">
{% if konten %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Bank</th>
<th>Kontoname</th>
<th>IBAN</th>
<th>Typ</th>
<th>Zinssatz</th>
<th>Saldo</th>
<th>Saldo-Datum</th>
<th>Status</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for konto in konten %}
<tr>
<td>
<strong>{{ konto.bank_name }}</strong>
{% if konto.bic %}
<br><small class="text-muted">BIC: {{ konto.bic }}</small>
{% endif %}
</td>
<td>{{ konto.kontoname }}</td>
<td>
<code>{{ konto.iban }}</code>
</td>
<td>
<span class="badge bg-secondary">{{ konto.get_konto_typ_display }}</span>
</td>
<td>
{% if konto.zinssatz %}
{{ konto.zinssatz }}%
{% else %}
-
{% endif %}
</td>
<td class="text-end">
<strong
class="{% if konto.saldo < 0 %}text-danger{% elif konto.saldo > 1000 %}text-success{% endif %}">
€{{ konto.saldo|floatformat:2 }}
</strong>
</td>
<td>
{% if konto.saldo_datum %}
{{ konto.saldo_datum|date:"d.m.Y" }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if konto.aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<a href="{% url 'stiftung:konto_edit' konto.pk %}" class="btn btn-outline-primary" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:konto_detail' konto.pk %}" class="btn btn-outline-info" title="Details">
<i class="fas fa-eye"></i>
</a>
{% if not konto.aktiv %}
<a href="#" class="btn btn-outline-danger" title="Löschen">
<i class="fas fa-trash"></i>
</a>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Zusammenfassung -->
<div class="row mt-4">
<div class="col-md-4">
<div class="card border-primary">
<div class="card-body text-center">
<i class="fas fa-university fa-2x text-primary mb-2"></i>
<h5>{{ konten.count }}</h5>
<small class="text-muted">Gesamt Konten</small>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-success">
<div class="card-body text-center">
<i class="fas fa-check-circle fa-2x text-success mb-2"></i>
<h5>{{ konten|length }}</h5>
<small class="text-muted">Aktive Konten</small>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-info">
<div class="card-body text-center">
<i class="fas fa-euro-sign fa-2x text-info mb-2"></i>
<h5>€{{ gesamtsaldo|floatformat:2 }}</h5>
<small class="text-muted">Gesamtsaldo</small>
</div>
</div>
</div>
</div>
{% else %}
<div class="text-center py-5">
<i class="fas fa-university fa-3x text-muted mb-3"></i>
<p class="text-muted">Noch keine Konten angelegt.</p>
<a href="{% url 'stiftung:konto_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Erstes Konto anlegen
</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,86 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Landabrechnung löschen - Stiftungsverwaltung{% endblock %}
{% block content %}
<!-- Header -->
<div class="row mb-4">
<div class="col-md-8">
<h1 class="h3">
<i class="fas fa-trash text-danger me-2"></i>
Landabrechnung löschen
</h1>
<p class="text-muted">
{{ abrechnung }}
</p>
</div>
<div class="col-md-4 text-end">
<a href="{% url 'stiftung:land_abrechnung_detail' abrechnung.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück
</a>
</div>
</div>
<!-- Warning Card -->
<div class="card shadow">
<div class="card-header bg-danger text-white py-3">
<h6 class="m-0 font-weight-bold">
<i class="fas fa-exclamation-triangle me-2"></i>Achtung: Unwiderrufliche Löschung
</h6>
</div>
<div class="card-body">
<div class="alert alert-danger" role="alert">
<h5 class="alert-heading">
<i class="fas fa-exclamation-triangle me-2"></i>Sind Sie sicher?
</h5>
<p>Sie sind dabei, die folgende Landabrechnung <strong>unwiderruflich zu löschen</strong>:</p>
<div class="bg-light p-3 rounded mt-3">
<table class="table table-sm table-borderless mb-0">
<tr>
<td><strong>Länderei:</strong></td>
<td>{{ land }}</td>
</tr>
<tr>
<td><strong>Jahr:</strong></td>
<td>{{ abrechnung.abrechnungsjahr }}</td>
</tr>
<tr>
<td><strong>Einnahmen:</strong></td>
<td class="text-success">€{{ abrechnung.einnahmen_gesamt|floatformat:2 }}</td>
</tr>
<tr>
<td><strong>Ausgaben:</strong></td>
<td class="text-danger">€{{ abrechnung.ausgaben_gesamt|floatformat:2 }}</td>
</tr>
<tr>
<td><strong>Nettoergebnis:</strong></td>
<td class="{% if abrechnung.nettoergebnis >= 0 %}text-success{% else %}text-danger{% endif %}">
€{{ abrechnung.nettoergebnis|floatformat:2 }}
</td>
</tr>
</table>
</div>
<hr>
<p class="mb-0">
<strong>Diese Aktion kann nicht rückgängig gemacht werden!</strong>
Alle zugehörigen Daten und hochgeladenen Dokumente werden ebenfalls gelöscht.
</p>
</div>
<form method="post" class="d-flex justify-content-between">
{% csrf_token %}
<a href="{% url 'stiftung:land_abrechnung_detail' abrechnung.pk %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Endgültig löschen
</button>
</form>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,360 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ abrechnung }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<!-- Header -->
<div class="row mb-4">
<div class="col-md-8">
<h1 class="h3">
<i class="fas fa-calculator text-success me-2"></i>
Landabrechnung {{ abrechnung.abrechnungsjahr }}
</h1>
<p class="text-muted">
<a href="{% url 'stiftung:land_detail' land.pk %}">{{ land }}</a>
{% if land.aktueller_paechter %} | Pächter: {{ land.aktueller_paechter.get_full_name }}{% endif %}
</p>
</div>
<div class="col-md-4 text-end">
<div class="btn-group" role="group">
<a href="{% url 'stiftung:land_abrechnung_update' abrechnung.pk %}" class="btn btn-warning">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:land_abrechnung_delete' abrechnung.pk %}" class="btn btn-danger"
onclick="return confirm('Sind Sie sicher, dass Sie diese Abrechnung löschen möchten?')">
<i class="fas fa-trash me-2"></i>Löschen
</a>
</div>
<div class="mt-2">
<a href="{% url 'stiftung:land_abrechnung_list' %}" class="btn btn-outline-secondary btn-sm">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
</div>
<!-- Ergebnis-Übersicht -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">
Einnahmen gesamt
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
€{{ abrechnung.einnahmen_gesamt|floatformat:2 }}
</div>
</div>
<div class="col-auto">
<i class="fas fa-arrow-up fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card border-left-danger shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-danger text-uppercase mb-1">
Ausgaben gesamt
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
€{{ abrechnung.ausgaben_gesamt|floatformat:2 }}
</div>
</div>
<div class="col-auto">
<i class="fas fa-arrow-down fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card border-left-{% if abrechnung.nettoergebnis >= 0 %}success{% else %}danger{% endif %} shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-{% if abrechnung.nettoergebnis >= 0 %}success{% else %}danger{% endif %} text-uppercase mb-1">
Nettoergebnis
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
€{{ abrechnung.nettoergebnis|floatformat:2 }}
</div>
</div>
<div class="col-auto">
<i class="fas fa-{% if abrechnung.nettoergebnis >= 0 %}plus{% else %}minus{% endif %} fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card border-left-info shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-info text-uppercase mb-1">
USt-Zahllast
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
€{{ abrechnung.ust_pacht_betrag|floatformat:2 }}
</div>
</div>
<div class="col-auto">
<i class="fas fa-percentage fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Left Column - Einnahmen & Ausgaben -->
<div class="col-lg-8">
<!-- Einnahmen -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-arrow-up me-2"></i>Einnahmen {{ abrechnung.abrechnungsjahr }}
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td><strong>Pacht vereinnahmt:</strong></td>
<td class="text-end">€{{ abrechnung.pacht_vereinnahmt|floatformat:2 }}</td>
</tr>
<tr>
<td><strong>Umlagen vereinnahmt:</strong></td>
<td class="text-end">€{{ abrechnung.umlagen_vereinnahmt|floatformat:2 }}</td>
</tr>
<tr>
<td><strong>Sonstige Einnahmen:</strong></td>
<td class="text-end">€{{ abrechnung.sonstige_einnahmen|floatformat:2 }}</td>
</tr>
<tr class="border-top">
<td><strong>Gesamt (netto):</strong></td>
<td class="text-end"><strong class="text-success">€{{ abrechnung.einnahmen_gesamt|floatformat:2 }}</strong></td>
</tr>
</table>
</div>
<div class="col-md-6">
{% if land.ust_option %}
<table class="table table-borderless">
<tr>
<td><strong>USt-Satz:</strong></td>
<td class="text-end">{{ land.ust_satz|floatformat:1 }}%</td>
</tr>
<tr>
<td><strong>USt auf Pacht:</strong></td>
<td class="text-end">€{{ abrechnung.ust_pacht_betrag|floatformat:2 }}</td>
</tr>
<tr class="border-top">
<td><strong>Brutto-Einnahmen:</strong></td>
<td class="text-end"><strong>€{{ abrechnung.einnahmen_gesamt|add:abrechnung.ust_pacht_betrag|floatformat:2 }}</strong></td>
</tr>
</table>
{% else %}
<div class="text-center text-muted">
<i class="fas fa-info-circle fa-2x mb-2"></i>
<p>Keine USt-Option gewählt</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Ausgaben -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-danger">
<i class="fas fa-arrow-down me-2"></i>Ausgaben {{ abrechnung.abrechnungsjahr }}
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td><strong>Grundsteuer:</strong></td>
<td class="text-end">€{{ abrechnung.grundsteuer_betrag|floatformat:2 }}</td>
</tr>
{% if abrechnung.grundsteuer_bescheid_nr %}
<tr>
<td colspan="2"><small class="text-muted">Bescheid: {{ abrechnung.grundsteuer_bescheid_nr }}</small></td>
</tr>
{% endif %}
<tr>
<td><strong>Versicherungen:</strong></td>
<td class="text-end">€{{ abrechnung.versicherungen_betrag|floatformat:2 }}</td>
</tr>
<tr>
<td><strong>Verbandsbeiträge:</strong></td>
<td class="text-end">€{{ abrechnung.verbandsbeitraege_betrag|floatformat:2 }}</td>
</tr>
<tr>
<td><strong>Sonstige Abgaben:</strong></td>
<td class="text-end">€{{ abrechnung.sonstige_abgaben_betrag|floatformat:2 }}</td>
</tr>
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td><strong>Instandhaltung:</strong></td>
<td class="text-end">€{{ abrechnung.instandhaltung_betrag|floatformat:2 }}</td>
</tr>
<tr>
<td><strong>Verwaltung/Recht:</strong></td>
<td class="text-end">€{{ abrechnung.verwaltung_recht_betrag|floatformat:2 }}</td>
</tr>
<tr>
<td><strong>Vorsteuer:</strong></td>
<td class="text-end">€{{ abrechnung.vorsteuer_aus_umlagen|floatformat:2 }}</td>
</tr>
<tr class="border-top">
<td><strong>Gesamt:</strong></td>
<td class="text-end"><strong class="text-danger">€{{ abrechnung.ausgaben_gesamt|floatformat:2 }}</strong></td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!-- Bemerkungen -->
{% if abrechnung.bemerkungen %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-sticky-note me-2"></i>Bemerkungen
</h6>
</div>
<div class="card-body">
<p class="mb-0">{{ abrechnung.bemerkungen|linebreaks }}</p>
</div>
</div>
{% endif %}
</div>
<!-- Right Column - Info & Dokumente -->
<div class="col-lg-4">
<!-- Länderei-Info -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-map me-2"></i>Länderei-Details
</h6>
</div>
<div class="card-body">
<table class="table table-sm table-borderless">
<tr>
<td><strong>Gesamtgröße:</strong></td>
<td>{{ land.groesse_qm|floatformat:0 }} qm<br><small>({{ land.groesse_hektar|floatformat:2 }} ha)</small></td>
</tr>
{% if land.pachtzins_pauschal %}
<tr>
<td><strong>Pachtzins/Jahr:</strong></td>
<td>€{{ land.pachtzins_pauschal|floatformat:2 }}</td>
</tr>
{% endif %}
<tr>
<td><strong>Zahlungsweise:</strong></td>
<td>{{ land.get_zahlungsweise_display }}</td>
</tr>
</table>
</div>
</div>
<!-- Verknüpfte Dokumente (Paperless) -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-link me-2"></i>Verknüpfte Dokumente
</h6>
</div>
<div class="card-body">
{% if land.dokumentlink_set.all %}
{% for dokument in land.dokumentlink_set.all %}
<div class="border rounded p-2 mb-2">
<div class="d-flex justify-content-between align-items-center">
<div>
<strong>{{ dokument.titel }}</strong>
<br><small class="text-muted">{{ dokument.get_kontext_display }}</small>
</div>
<a href="{{ dokument.get_paperless_url }}" target="_blank" class="btn btn-sm btn-outline-primary">
<i class="fas fa-external-link-alt"></i>
</a>
</div>
</div>
{% endfor %}
{% else %}
<p class="text-muted text-center mb-3">Keine Dokumente verknüpft</p>
{% endif %}
<div class="d-grid gap-2">
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-outline-primary btn-sm">
<i class="fas fa-link me-2"></i>Dokumente verknüpfen
</a>
<a href="mailto:paperless@vhtv-stiftung.de?subject=Dokumente für {{ land }}" class="btn btn-outline-info btn-sm">
<i class="fas fa-envelope me-2"></i>E-Mail an Paperless
</a>
</div>
</div>
</div>
<!-- Offene Posten -->
{% if abrechnung.offene_posten != 0 %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-warning">
<i class="fas fa-exclamation-triangle me-2"></i>Offene Posten
</h6>
</div>
<div class="card-body">
<div class="text-center">
<h4 class="text-warning">€{{ abrechnung.offene_posten|floatformat:2 }}</h4>
<p class="text-muted">Noch nicht bezahlte Pacht/Umlagen</p>
</div>
</div>
</div>
{% endif %}
<!-- System Information -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-cog me-2"></i>Systeminformationen
</h6>
</div>
<div class="card-body">
<table class="table table-sm table-borderless">
<tr>
<td><small class="text-muted">Erstellt:</small></td>
<td><small class="text-muted">{{ abrechnung.erstellt_am|date:"d.m.Y H:i" }}</small></td>
</tr>
<tr>
<td><small class="text-muted">Aktualisiert:</small></td>
<td><small class="text-muted">{{ abrechnung.aktualisiert_am|date:"d.m.Y H:i" }}</small></td>
</tr>
<tr>
<td><small class="text-muted">ID:</small></td>
<td><small class="text-muted font-monospace">{{ abrechnung.id }}</small></td>
</tr>
</table>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,326 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<!-- Header -->
<div class="row mb-4">
<div class="col-md-8">
<h1 class="h3">
<i class="fas fa-calculator text-success me-2"></i>
{{ title }}
</h1>
{% if land %}
<p class="text-muted">
Länderei: <a href="{% url 'stiftung:land_detail' land.pk %}">{{ land }}</a>
</p>
{% endif %}
</div>
<div class="col-md-4 text-end">
<a href="{% if abrechnung %}{% url 'stiftung:land_abrechnung_detail' abrechnung.pk %}{% else %}{% url 'stiftung:land_abrechnung_list' %}{% endif %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück
</a>
</div>
</div>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="row">
<!-- Left Column -->
<div class="col-lg-8">
<!-- Grunddaten -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-info-circle me-2"></i>Grunddaten
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.land.id_for_label }}" class="form-label">{{ form.land.label }}</label>
{{ form.land }}
{% if form.land.errors %}
<div class="text-danger">{{ form.land.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.abrechnungsjahr.id_for_label }}" class="form-label">{{ form.abrechnungsjahr.label }}</label>
{{ form.abrechnungsjahr }}
{% if form.abrechnungsjahr.errors %}
<div class="text-danger">{{ form.abrechnungsjahr.errors }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Einnahmen -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-arrow-up me-2"></i>Einnahmen
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.pacht_vereinnahmt.id_for_label }}" class="form-label">{{ form.pacht_vereinnahmt.label }}</label>
{{ form.pacht_vereinnahmt }}
{% if form.pacht_vereinnahmt.errors %}
<div class="text-danger">{{ form.pacht_vereinnahmt.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.umlagen_vereinnahmt.id_for_label }}" class="form-label">{{ form.umlagen_vereinnahmt.label }}</label>
{{ form.umlagen_vereinnahmt }}
{% if form.umlagen_vereinnahmt.errors %}
<div class="text-danger">{{ form.umlagen_vereinnahmt.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.sonstige_einnahmen.id_for_label }}" class="form-label">{{ form.sonstige_einnahmen.label }}</label>
{{ form.sonstige_einnahmen }}
{% if form.sonstige_einnahmen.errors %}
<div class="text-danger">{{ form.sonstige_einnahmen.errors }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Ausgaben -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-danger">
<i class="fas fa-arrow-down me-2"></i>Ausgaben
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.grundsteuer_bescheid_nr.id_for_label }}" class="form-label">{{ form.grundsteuer_bescheid_nr.label }}</label>
{{ form.grundsteuer_bescheid_nr }}
{% if form.grundsteuer_bescheid_nr.errors %}
<div class="text-danger">{{ form.grundsteuer_bescheid_nr.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.grundsteuer_betrag.id_for_label }}" class="form-label">{{ form.grundsteuer_betrag.label }}</label>
{{ form.grundsteuer_betrag }}
{% if form.grundsteuer_betrag.errors %}
<div class="text-danger">{{ form.grundsteuer_betrag.errors }}</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.versicherungen_betrag.id_for_label }}" class="form-label">{{ form.versicherungen_betrag.label }}</label>
{{ form.versicherungen_betrag }}
{% if form.versicherungen_betrag.errors %}
<div class="text-danger">{{ form.versicherungen_betrag.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.verbandsbeitraege_betrag.id_for_label }}" class="form-label">{{ form.verbandsbeitraege_betrag.label }}</label>
{{ form.verbandsbeitraege_betrag }}
{% if form.verbandsbeitraege_betrag.errors %}
<div class="text-danger">{{ form.verbandsbeitraege_betrag.errors }}</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.sonstige_abgaben_betrag.id_for_label }}" class="form-label">{{ form.sonstige_abgaben_betrag.label }}</label>
{{ form.sonstige_abgaben_betrag }}
{% if form.sonstige_abgaben_betrag.errors %}
<div class="text-danger">{{ form.sonstige_abgaben_betrag.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.instandhaltung_betrag.id_for_label }}" class="form-label">{{ form.instandhaltung_betrag.label }}</label>
{{ form.instandhaltung_betrag }}
{% if form.instandhaltung_betrag.errors %}
<div class="text-danger">{{ form.instandhaltung_betrag.errors }}</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.verwaltung_recht_betrag.id_for_label }}" class="form-label">{{ form.verwaltung_recht_betrag.label }}</label>
{{ form.verwaltung_recht_betrag }}
{% if form.verwaltung_recht_betrag.errors %}
<div class="text-danger">{{ form.verwaltung_recht_betrag.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.vorsteuer_aus_umlagen.id_for_label }}" class="form-label">{{ form.vorsteuer_aus_umlagen.label }}</label>
{{ form.vorsteuer_aus_umlagen }}
{% if form.vorsteuer_aus_umlagen.errors %}
<div class="text-danger">{{ form.vorsteuer_aus_umlagen.errors }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Sonstiges -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-sticky-note me-2"></i>Sonstiges
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.offene_posten.id_for_label }}" class="form-label">{{ form.offene_posten.label }}</label>
{{ form.offene_posten }}
{% if form.offene_posten.errors %}
<div class="text-danger">{{ form.offene_posten.errors }}</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3">
<label for="{{ form.bemerkungen.id_for_label }}" class="form-label">{{ form.bemerkungen.label }}</label>
{{ form.bemerkungen }}
{% if form.bemerkungen.errors %}
<div class="text-danger">{{ form.bemerkungen.errors }}</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Right Column -->
<div class="col-lg-4">
<!-- Dokumente über Paperless -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-link me-2"></i>Dokumente verknüpfen
</h6>
</div>
<div class="card-body">
<p class="text-muted mb-3">
Dokumente werden über Paperless verwaltet und verknüpft.
</p>
<div class="d-grid gap-2">
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-outline-primary btn-sm">
<i class="fas fa-link me-2"></i>Dokumente verknüpfen
</a>
<a href="mailto:paperless@vhtv-stiftung.de" class="btn btn-outline-info btn-sm">
<i class="fas fa-envelope me-2"></i>E-Mail an Paperless
</a>
</div>
{% if land %}
<hr>
<h6 class="text-muted">Verknüpfte Dokumente:</h6>
{% if land.dokumentlink_set.all %}
{% for dokument in land.dokumentlink_set.all %}
<div class="border rounded p-2 mb-2">
<strong>{{ dokument.titel }}</strong>
<br><small class="text-muted">{{ dokument.get_kontext_display }}</small>
</div>
{% endfor %}
{% else %}
<p class="text-muted">Keine Dokumente verknüpft</p>
{% endif %}
{% endif %}
</div>
</div>
<!-- Berechnungen (Preview) -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-info">
<i class="fas fa-calculator me-2"></i>Berechnungen
</h6>
</div>
<div class="card-body">
{% if abrechnung %}
<table class="table table-sm table-borderless">
<tr>
<td><strong>Einnahmen:</strong></td>
<td class="text-end text-success">€{{ abrechnung.einnahmen_gesamt|floatformat:2 }}</td>
</tr>
<tr>
<td><strong>Ausgaben:</strong></td>
<td class="text-end text-danger">€{{ abrechnung.ausgaben_gesamt|floatformat:2 }}</td>
</tr>
<tr class="border-top">
<td><strong>Nettoergebnis:</strong></td>
<td class="text-end">
<strong class="{% if abrechnung.nettoergebnis >= 0 %}text-success{% else %}text-danger{% endif %}">
€{{ abrechnung.nettoergebnis|floatformat:2 }}
</strong>
</td>
</tr>
{% if abrechnung.ust_pacht_betrag > 0 %}
<tr>
<td><strong>USt-Zahllast:</strong></td>
<td class="text-end text-info">€{{ abrechnung.ust_pacht_betrag|floatformat:2 }}</td>
</tr>
{% endif %}
</table>
{% else %}
<p class="text-muted text-center">Berechnungen werden nach dem Speichern angezeigt</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Submit Buttons -->
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-body">
<div class="d-flex justify-content-between">
<a href="{% if abrechnung %}{% url 'stiftung:land_abrechnung_detail' abrechnung.pk %}{% else %}{% url 'stiftung:land_abrechnung_list' %}{% endif %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-success">
<i class="fas fa-save me-2"></i>
{% if abrechnung %}Aktualisieren{% else %}Erstellen{% endif %}
</button>
</div>
</div>
</div>
</div>
</div>
</form>
{% endblock %}

View File

@@ -0,0 +1,260 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Landabrechnungen - Stiftungsverwaltung{% endblock %}
{% block content %}
<!-- Header -->
<div class="row mb-4">
<div class="col-md-6">
<h1 class="h3">
<i class="fas fa-calculator text-success me-2"></i>
Landabrechnungen verwalten
</h1>
</div>
<div class="col-md-6 text-end">
<a href="{% url 'stiftung:land_abrechnung_create' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Neue Abrechnung
</a>
</div>
</div>
<!-- Search and Filters -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-filter me-2"></i>Filter & Suche
</h6>
</div>
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-4">
<label for="jahr" class="form-label">Jahr</label>
<select class="form-select" id="jahr" name="jahr">
<option value="">Alle Jahre</option>
{% for jahr in jahre %}
<option value="{{ jahr }}" {% if jahr_filter == jahr|stringformat:"s" %}selected{% endif %}>
{{ jahr }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label for="land" class="form-label">Länderei</label>
<select class="form-select" id="land" name="land">
<option value="">Alle Ländereien</option>
{% for land in laendereien %}
<option value="{{ land.pk }}" {% if land_filter == land.pk|stringformat:"s" %}selected{% endif %}>
{{ land }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label for="paechter" class="form-label">Pächter</label>
<select class="form-select" id="paechter" name="paechter">
<option value="">Alle Pächter</option>
{% for paechter in paechter_list %}
<option value="{{ paechter.pk }}" {% if paechter_filter == paechter.pk|stringformat:"s" %}selected{% endif %}>
{{ paechter.get_full_name }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label class="form-label">&nbsp;</label>
<div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-search me-2"></i>Filtern
</button>
</div>
</div>
</form>
</div>
</div>
<!-- Statistics -->
{% if stats %}
<div class="row mb-4">
<div class="col-md-4">
<div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">
Gesamteinnahmen
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
€{{ stats.total_einnahmen|default:0|floatformat:2 }}
</div>
</div>
<div class="col-auto">
<i class="fas fa-euro-sign fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-left-danger shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-danger text-uppercase mb-1">
Gesamtausgaben
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
€{{ stats.total_ausgaben|default:0|floatformat:2 }}
</div>
</div>
<div class="col-auto">
<i class="fas fa-receipt fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-left-info shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-info text-uppercase mb-1">
Anzahl Abrechnungen
</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">
{{ stats.anzahl_abrechnungen|default:0 }}
</div>
</div>
<div class="col-auto">
<i class="fas fa-calculator fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Abrechnungen Liste -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Landabrechnungen
</h6>
</div>
<div class="card-body">
{% if abrechnungen %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Jahr</th>
<th>Länderei</th>
<th>Pächter</th>
<th>Einnahmen</th>
<th>Ausgaben</th>
<th>Nettoergebnis</th>
<th>USt</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for abrechnung in abrechnungen %}
<tr>
<td><strong>{{ abrechnung.abrechnungsjahr }}</strong></td>
<td>
<a href="{% url 'stiftung:land_detail' abrechnung.land.pk %}">
{{ abrechnung.land }}
</a>
</td>
<td>
{% if abrechnung.land.aktueller_paechter %}
<a href="{% url 'stiftung:paechter_detail' abrechnung.land.aktueller_paechter.pk %}">
{{ abrechnung.land.aktueller_paechter.get_full_name }}
</a>
{% else %}
<span class="text-muted">Kein Pächter</span>
{% endif %}
</td>
<td class="text-success">€{{ abrechnung.einnahmen_gesamt|floatformat:2 }}</td>
<td class="text-danger">€{{ abrechnung.ausgaben_gesamt|floatformat:2 }}</td>
<td>
<strong class="{% if abrechnung.nettoergebnis >= 0 %}text-success{% else %}text-danger{% endif %}">
€{{ abrechnung.nettoergebnis|floatformat:2 }}
</strong>
</td>
<td>
{% if abrechnung.ust_pacht_betrag > 0 %}
€{{ abrechnung.ust_pacht_betrag|floatformat:2 }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:land_abrechnung_detail' abrechnung.pk %}"
class="btn btn-sm btn-outline-primary" title="Anzeigen">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:land_abrechnung_update' abrechnung.pk %}"
class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:land_abrechnung_delete' abrechnung.pk %}"
class="btn btn-sm btn-outline-danger" title="Löschen">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if abrechnungen.has_other_pages %}
<nav aria-label="Abrechnungen Pagination">
<ul class="pagination justify-content-center">
{% if abrechnungen.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ abrechnungen.previous_page_number }}{% if jahr_filter %}&jahr={{ jahr_filter }}{% endif %}{% if land_filter %}&land={{ land_filter }}{% endif %}{% if paechter_filter %}&paechter={{ paechter_filter }}{% endif %}">Zurück</a>
</li>
{% endif %}
{% for num in abrechnungen.paginator.page_range %}
{% if abrechnungen.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > abrechnungen.number|add:'-3' and num < abrechnungen.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}{% if jahr_filter %}&jahr={{ jahr_filter }}{% endif %}{% if land_filter %}&land={{ land_filter }}{% endif %}{% if paechter_filter %}&paechter={{ paechter_filter }}{% endif %}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if abrechnungen.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ abrechnungen.next_page_number }}{% if jahr_filter %}&jahr={{ jahr_filter }}{% endif %}{% if land_filter %}&land={{ land_filter }}{% endif %}{% if paechter_filter %}&paechter={{ paechter_filter }}{% endif %}">Weiter</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-calculator fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Landabrechnungen vorhanden</h5>
<p class="text-muted">Erstellen Sie die erste Landabrechnung.</p>
<a href="{% url 'stiftung:land_abrechnung_create' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Erste Abrechnung erstellen
</a>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,64 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Länderei löschen - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-6 mx-auto">
<div class="card shadow">
<div class="card-header bg-danger text-white">
<h4 class="mb-0">
<i class="fas fa-exclamation-triangle me-2"></i>Länderei löschen
</h4>
</div>
<div class="card-body">
<div class="alert alert-warning">
<h5 class="alert-heading">
<i class="fas fa-exclamation-triangle me-2"></i>Warnung!
</h5>
<p class="mb-0">
Sind Sie sicher, dass Sie die Länderei <strong>{{ land }}</strong> löschen möchten?
</p>
</div>
<div class="card mb-3">
<div class="card-body">
<h6 class="card-title">Länderei-Details:</h6>
<p class="card-text">
<strong>Gemeinde:</strong> {{ land.gemeinde }}<br>
<strong>Gemarkung:</strong> {{ land.gemarkung }}<br>
<strong>Flur:</strong> {{ land.flur }}<br>
<strong>Flurstück:</strong> {{ land.flurstueck }}<br>
<strong>Größe:</strong> {{ land.groesse_qm|floatformat:2 }} qm
</p>
</div>
</div>
<div class="alert alert-info">
<h6 class="alert-heading">
<i class="fas fa-info-circle me-2"></i>Wichtiger Hinweis
</h6>
<p class="mb-0">
Diese Aktion kann nicht rückgängig gemacht werden. Alle zugehörigen Verpachtungen werden ebenfalls gelöscht.
</p>
</div>
<form method="post">
{% csrf_token %}
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:land_detail' land.pk %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Endgültig löschen
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,803 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ land }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<!-- Header -->
<div class="row mb-4">
<div class="col-md-8">
<h1 class="h3">
<i class="fas fa-map text-success me-2"></i>
{{ land }}
</h1>
<p class="text-muted">
Lfd. Nr. {{ land.lfd_nr }}
{% if land.ew_nummer %} | EW-Nummer: {{ land.ew_nummer }}{% endif %}
{% if land.grundbuchblatt %} | Grundbuchblatt: {{ land.grundbuchblatt }}{% endif %}
</p>
{% if land.adresse %}
<p class="text-muted">
<i class="fas fa-map-marker-alt me-1"></i>{{ land.adresse }}
</p>
{% endif %}
</div>
<div class="col-md-4 text-end">
<div class="btn-group" role="group">
<a href="{% url 'stiftung:land_update' land.pk %}" class="btn btn-warning">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:land_export' land.pk %}" class="btn btn-success">
<i class="fas fa-download me-2"></i>Export
</a>
<a href="{% url 'stiftung:land_delete' land.pk %}" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Löschen
</a>
</div>
<div class="mt-2">
<a href="{% url 'stiftung:land_list' %}" class="btn btn-outline-secondary btn-sm">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
</div>
<!-- Status Badge -->
<div class="row mb-4">
<div class="col-12">
{% if land.aktiv %}
<span class="badge bg-success fs-6">
<i class="fas fa-check-circle me-2"></i>Aktiv
</span>
{% else %}
<span class="badge bg-secondary fs-6">
<i class="fas fa-times-circle me-2"></i>Inaktiv
</span>
{% endif %}
</div>
</div>
<!-- Main Information -->
<div class="row">
<!-- Left Column - Land Details -->
<div class="col-lg-8">
<!-- Basic Information -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-info-circle me-2"></i>Grundinformationen
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td><strong>Gemeinde:</strong></td>
<td>{{ land.gemeinde }}</td>
</tr>
<tr>
<td><strong>Gemarkung:</strong></td>
<td>{{ land.gemarkung }}</td>
</tr>
<tr>
<td><strong>Flur:</strong></td>
<td>{{ land.flur }}</td>
</tr>
<tr>
<td><strong>Flurstück:</strong></td>
<td>{{ land.flurstueck }}</td>
</tr>
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td><strong>Amtsgericht:</strong></td>
<td>{{ land.amtsgericht }}</td>
</tr>
<tr>
<td><strong>Gesamtgröße:</strong></td>
<td>
<strong>{{ land.groesse_qm|floatformat:2 }} qm</strong>
<br>
<small class="text-muted">({{ land.groesse_hektar|floatformat:2 }} ha)</small>
</td>
</tr>
<tr>
<td><strong>Verpachtet:</strong></td>
<td>
{{ land.get_verpachtete_flaeche_aktuell|floatformat:2 }} qm
<br>
<small class="text-muted">({{ land.get_verpachtete_flaeche_aktuell_hektar|floatformat:2 }} ha)</small>
</td>
</tr>
<tr>
<td><strong>Verpachtungsgrad:</strong></td>
<td>
{% with verpachtungsgrad=land.get_verpachtungsgrad %}
{% if verpachtungsgrad > 90 %}
<span class="badge bg-success">{{ verpachtungsgrad|floatformat:1 }}%</span>
{% elif verpachtungsgrad > 70 %}
<span class="badge bg-warning">{{ verpachtungsgrad|floatformat:1 }}%</span>
{% else %}
<span class="badge bg-danger">{{ verpachtungsgrad|floatformat:1 }}%</span>
{% endif %}
{% endwith %}
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!-- Land Use Details -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-leaf me-2"></i>Landnutzung
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3 text-center">
<div class="border rounded p-3">
<h4 class="text-success">{{ land.gruenland_qm|floatformat:0 }}</h4>
<p class="text-muted mb-0">Grünland (qm)</p>
<small class="text-muted">({{ land.gruenland_hektar|floatformat:2 }} ha)</small>
</div>
</div>
<div class="col-md-3 text-center">
<div class="border rounded p-3">
<h4 class="text-warning">{{ land.acker_qm|floatformat:0 }}</h4>
<p class="text-muted mb-0">Ackerland (qm)</p>
<small class="text-muted">({{ land.acker_hektar|floatformat:2 }} ha)</small>
</div>
</div>
<div class="col-md-3 text-center">
<div class="border rounded p-3">
<h4 class="text-info">{{ land.wald_qm|floatformat:0 }}</h4>
<p class="text-muted mb-0">Wald (qm)</p>
<small class="text-muted">({{ land.wald_hektar|floatformat:2 }} ha)</small>
</div>
</div>
<div class="col-md-3 text-center">
<div class="border rounded p-3">
<h4 class="text-secondary">{{ land.sonstiges_qm|floatformat:0 }}</h4>
<p class="text-muted mb-0">Sonstiges (qm)</p>
<small class="text-muted">({{ land.sonstiges_hektar|floatformat:2 }} ha)</small>
</div>
</div>
</div>
</div>
</div>
<!-- Aktuelle Verpachtung -->
{% if land.aktueller_paechter %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-handshake me-2"></i>Aktuelle Verpachtung
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td><strong>Pächter:</strong></td>
<td>
<a href="{% url 'stiftung:paechter_detail' land.aktueller_paechter.pk %}">
{{ land.aktueller_paechter.get_full_name }}
</a>
{% if land.paechter_name and land.paechter_name != land.aktueller_paechter.get_full_name %}
<br><small class="text-muted">{{ land.paechter_name }}</small>
{% endif %}
</td>
</tr>
{% if land.paechter_anschrift %}
<tr>
<td><strong>Anschrift:</strong></td>
<td>{{ land.paechter_anschrift|linebreaks }}</td>
</tr>
{% endif %}
<tr>
<td><strong>Pachtbeginn:</strong></td>
<td>{{ land.pachtbeginn|date:"d.m.Y"|default:"Nicht angegeben" }}</td>
</tr>
<tr>
<td><strong>Pachtende:</strong></td>
<td>
{% if land.pachtende %}
{{ land.pachtende|date:"d.m.Y" }}
{% else %}
<span class="text-muted">Unbefristet</span>
{% endif %}
</td>
</tr>
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td><strong>Zahlungsweise:</strong></td>
<td>{{ land.get_zahlungsweise_display }}</td>
</tr>
{% if land.pachtzins_pauschal %}
<tr>
<td><strong>Pachtzins/Jahr:</strong></td>
<td><strong>€{{ land.pachtzins_pauschal|floatformat:2 }}</strong></td>
</tr>
{% endif %}
{% if land.pachtzins_pro_ha %}
<tr>
<td><strong>Pachtzins/ha:</strong></td>
<td>€{{ land.pachtzins_pro_ha|floatformat:2 }}</td>
</tr>
{% endif %}
<tr>
<td><strong>USt-Option:</strong></td>
<td>
{% if land.ust_option %}
<span class="badge bg-info">{{ land.ust_satz|floatformat:1 }}% USt</span>
{% else %}
<span class="text-muted">Keine USt</span>
{% endif %}
</td>
</tr>
<tr>
<td><strong>Autom. Verlängerung:</strong></td>
<td>
{% if land.verlaengerung_klausel %}
<span class="badge bg-success">Ja</span>
{% else %}
<span class="badge bg-secondary">Nein</span>
{% endif %}
</td>
</tr>
</table>
</div>
</div>
<!-- Umlagen -->
<div class="row mt-3">
<div class="col-12">
<h6 class="text-muted mb-3">Umlagefähige Kosten:</h6>
<div class="row">
<div class="col-md-3">
{% if land.grundsteuer_umlage %}
<span class="badge bg-success mb-1">✓ Grundsteuer</span>
{% else %}
<span class="badge bg-secondary mb-1">✗ Grundsteuer</span>
{% endif %}
</div>
<div class="col-md-3">
{% if land.versicherungen_umlage %}
<span class="badge bg-success mb-1">✓ Versicherungen</span>
{% else %}
<span class="badge bg-secondary mb-1">✗ Versicherungen</span>
{% endif %}
</div>
<div class="col-md-3">
{% if land.verbandsbeitraege_umlage %}
<span class="badge bg-success mb-1">✓ Verbandsbeiträge</span>
{% else %}
<span class="badge bg-secondary mb-1">✗ Verbandsbeiträge</span>
{% endif %}
</div>
<div class="col-md-3">
{% if land.jagdpacht_anteil_umlage %}
<span class="badge bg-success mb-1">✓ Jagdpacht</span>
{% else %}
<span class="badge bg-secondary mb-1">✗ Jagdpacht</span>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Verpachtungs-Übersicht -->
{% if land.aktueller_paechter %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-chart-line me-2"></i>Verpachtungs-Übersicht
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td><strong>Verpachtete Fläche:</strong></td>
<td>
<strong>{{ land.verp_flaeche_aktuell|floatformat:2 }} qm</strong>
<br>
<small class="text-muted">({{ land.verp_flaeche_aktuell_hektar|floatformat:2 }} ha)</small>
</td>
</tr>
<tr>
<td><strong>Verpachtungsgrad:</strong></td>
<td>
{% with verpachtungsgrad=land.get_verpachtungsgrad %}
{% if verpachtungsgrad > 90 %}
<span class="badge bg-success">{{ verpachtungsgrad|floatformat:1 }}%</span>
{% elif verpachtungsgrad > 70 %}
<span class="badge bg-warning">{{ verpachtungsgrad|floatformat:1 }}%</span>
{% else %}
<span class="badge bg-danger">{{ verpachtungsgrad|floatformat:1 }}%</span>
{% endif %}
{% endwith %}
</td>
</tr>
{% if land.pachtzins_pauschal %}
<tr>
<td><strong>Pachtzins/Jahr:</strong></td>
<td><strong>€{{ land.pachtzins_pauschal|floatformat:2 }}</strong></td>
</tr>
{% endif %}
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless">
{% if land.pachtzins_pro_ha %}
<tr>
<td><strong>Pachtzins/ha:</strong></td>
<td>€{{ land.pachtzins_pro_ha|floatformat:2 }}</td>
</tr>
{% endif %}
<tr>
<td><strong>Zahlungsweise:</strong></td>
<td>{{ land.get_zahlungsweise_display }}</td>
</tr>
<tr>
<td><strong>USt-Behandlung:</strong></td>
<td>
{% if land.ust_option %}
<span class="badge bg-warning">{{ land.ust_satz|floatformat:1 }}% USt</span>
{% else %}
<span class="text-muted">Keine USt</span>
{% endif %}
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!-- Alle Verpachtungen (Historie) -->
{% if land.neue_verpachtungen.exists %}
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-history me-2"></i>Verpachtungshistorie
</h6>
<span class="badge bg-primary">{{ land.neue_verpachtungen.count }} Verpachtung{{ land.neue_verpachtungen.count|pluralize:"en" }}</span>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Vertragsnummer</th>
<th>Pächter</th>
<th>Laufzeit</th>
<th>Fläche</th>
<th>Pachtzins</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for verpachtung in land.neue_verpachtungen.all %}
<tr>
<td>
<code>{{ verpachtung.vertragsnummer }}</code>
</td>
<td>
<a href="{% url 'stiftung:paechter_detail' verpachtung.paechter.pk %}">
{{ verpachtung.paechter.get_full_name }}
</a>
</td>
<td>
{{ verpachtung.pachtbeginn|date:"d.m.Y" }}
{% if verpachtung.pachtende %}
- {{ verpachtung.pachtende|date:"d.m.Y" }}
{% else %}
- unbefristet
{% endif %}
</td>
<td>
{{ verpachtung.verpachtete_flaeche|floatformat:2 }} qm
<br><small class="text-muted">{{ verpachtung.verpachtete_flaeche_hektar }} ha</small>
</td>
<td>
{{ verpachtung.pachtzins_pauschal|floatformat:2 }} €/Jahr
{% if verpachtung.ust_option %}
<br><small class="text-warning">zzgl. {{ verpachtung.ust_satz }}% USt</small>
{% endif %}
</td>
<td>
{% if verpachtung.status == 'aktiv' %}
<span class="badge bg-success">{{ verpachtung.get_status_display }}</span>
{% elif verpachtung.status == 'beendet' %}
<span class="badge bg-secondary">{{ verpachtung.get_status_display }}</span>
{% elif verpachtung.status == 'gekuendigt' %}
<span class="badge bg-warning">{{ verpachtung.get_status_display }}</span>
{% else %}
<span class="badge bg-info">{{ verpachtung.get_status_display }}</span>
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
{% else %}
<!-- Keine Verpachtung -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-muted">
<i class="fas fa-info-circle me-2"></i>Verpachtungs-Status
</h6>
</div>
<div class="card-body">
<div class="text-center py-3">
<i class="fas fa-exclamation-circle fa-2x text-muted mb-3"></i>
<h5 class="text-muted">Nicht verpachtet</h5>
<p class="text-muted">Diese Länderei ist aktuell nicht verpachtet.</p>
</div>
</div>
</div>
{% endif %}
<!-- Verknüpfte Dokumente -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-file-alt me-2"></i>Verknüpfte Dokumente
</h6>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-sm btn-success">
<i class="fas fa-plus me-2"></i>Dokument verknüpfen
</a>
</div>
<div class="card-body">
{% if verknuepfte_dokumente %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Dokument</th>
<th>Kontext</th>
<th>Beschreibung</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for dokument in verknuepfte_dokumente %}
<tr>
<td>
<strong>{{ dokument.titel }}</strong>
<br>
<small class="text-muted">ID: {{ dokument.paperless_document_id }}</small>
</td>
<td>
<span class="badge bg-secondary">{{ dokument.get_kontext_display }}</span>
</td>
<td>
{% if dokument.beschreibung %}
{{ dokument.beschreibung|truncatewords:10 }}
{% else %}
<span class="text-muted">Keine Beschreibung</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{{ dokument.get_paperless_url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="In Paperless öffnen">
<i class="fas fa-external-link-alt"></i>
</a>
<a href="{{ dokument.get_paperless_thumbnail_url }}" target="_blank" class="btn btn-sm btn-outline-info" title="Thumbnail anzeigen">
<i class="fas fa-image"></i>
</a>
<a href="{% url 'stiftung:dokument_update' dokument.pk %}" class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:dokument_delete' dokument.pk %}" class="btn btn-sm btn-outline-danger" title="Verknüpfung löschen">
<i class="fas fa-unlink"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-file-alt fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Dokumente verknüpft</h5>
<p class="text-muted">Verknüpfen Sie Dokumente aus Paperless mit dieser Länderei.</p>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Erstes Dokument verknüpfen
</a>
</div>
{% endif %}
</div>
</div>
<!-- Notes -->
{% if land.notizen %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-sticky-note me-2"></i>Notizen
</h6>
</div>
<div class="card-body">
<p class="mb-0">{{ land.notizen|linebreaks }}</p>
</div>
</div>
{% endif %}
<!-- Jahresabrechnungen -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-calculator me-2"></i>Jahresabrechnungen
</h6>
<a href="{% url 'stiftung:land_abrechnung_create' %}?land={{ land.pk }}" class="btn btn-sm btn-success">
<i class="fas fa-plus me-2"></i>Neue Abrechnung
</a>
</div>
<div class="card-body">
{% if land.abrechnungen.all %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Jahr</th>
<th>Einnahmen</th>
<th>Ausgaben</th>
<th>Nettoergebnis</th>
<th>USt</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for abrechnung in land.abrechnungen.all %}
<tr>
<td><strong>{{ abrechnung.abrechnungsjahr }}</strong></td>
<td class="text-success">€{{ abrechnung.einnahmen_gesamt|floatformat:2 }}</td>
<td class="text-danger">€{{ abrechnung.ausgaben_gesamt|floatformat:2 }}</td>
<td>
<strong class="{% if abrechnung.nettoergebnis >= 0 %}text-success{% else %}text-danger{% endif %}">
€{{ abrechnung.nettoergebnis|floatformat:2 }}
</strong>
</td>
<td>
{% if abrechnung.ust_pacht_betrag > 0 %}
€{{ abrechnung.ust_pacht_betrag|floatformat:2 }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:land_abrechnung_detail' abrechnung.pk %}"
class="btn btn-sm btn-outline-primary" title="Anzeigen">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:land_abrechnung_update' abrechnung.pk %}"
class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-calculator fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Abrechnungen vorhanden</h5>
<p class="text-muted">Erstellen Sie eine Jahresabrechnung für diese Länderei.</p>
<a href="{% url 'stiftung:land_abrechnung_create' %}?land={{ land.pk }}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Erste Abrechnung erstellen
</a>
</div>
{% endif %}
</div>
</div>
<!-- Verpachtungs-Management -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-handshake me-2"></i>Verpachtungs-Management
</h6>
<div class="btn-group">
{% if not land.aktueller_paechter %}
<a href="{% url 'stiftung:land_verpachtung_create' land_pk=land.pk %}" class="btn btn-sm btn-success">
<i class="fas fa-plus me-2"></i>Verpachtung erstellen
</a>
{% else %}
<a href="{% url 'stiftung:land_verpachtung_edit' land_pk=land.pk %}" class="btn btn-sm btn-warning">
<i class="fas fa-edit me-2"></i>Verpachtung bearbeiten
</a>
<a href="{% url 'stiftung:land_verpachtung_end' land_pk=land.pk %}" class="btn btn-sm btn-danger">
<i class="fas fa-stop me-2"></i>Verpachtung beenden
</a>
{% endif %}
</div>
</div>
<div class="card-body">
<!-- Neue Verpachtungen anzeigen -->
{% if land.neue_verpachtungen.all %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Vertragsnummer</th>
<th>Pächter</th>
<th>Zeitraum</th>
<th>Fläche</th>
<th>Pachtzins</th>
<th>Status</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for verpachtung in land.neue_verpachtungen.all %}
<tr>
<td><strong>{{ verpachtung.vertragsnummer }}</strong></td>
<td>
<a href="{% url 'stiftung:paechter_detail' verpachtung.paechter.pk %}">
{{ verpachtung.paechter.get_full_name }}
</a>
</td>
<td>
{{ verpachtung.pachtbeginn|date:"d.m.Y" }} -
{% if verpachtung.pachtende %}
{{ verpachtung.pachtende|date:"d.m.Y" }}
{% else %}
<span class="text-muted">Unbefristet</span>
{% endif %}
{% if verpachtung.verlaengerung_klausel %}
<br><small class="badge bg-info">Auto-Verlängerung</small>
{% endif %}
</td>
<td>
{{ verpachtung.verpachtete_flaeche|floatformat:2 }} qm
<br><small class="text-muted">({{ verpachtung.verpachtete_flaeche_hektar|floatformat:2 }} ha)</small>
</td>
<td>
€{{ verpachtung.pachtzins_pauschal|floatformat:2 }}/Jahr
{% if verpachtung.ust_option %}
<br><small class="badge bg-warning">+{{ verpachtung.ust_satz|floatformat:1 }}% USt</small>
{% endif %}
</td>
<td>
{% if verpachtung.status == 'aktiv' %}
<span class="badge bg-success">{{ verpachtung.get_status_display }}</span>
{% elif verpachtung.status == 'beendet' %}
<span class="badge bg-secondary">{{ verpachtung.get_status_display }}</span>
{% else %}
<span class="badge bg-warning">{{ verpachtung.get_status_display }}</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="#" class="btn btn-sm btn-outline-primary" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="#" class="btn btn-sm btn-outline-danger" title="Beenden">
<i class="fas fa-stop"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Verfügbare Fläche -->
<div class="row mt-3">
<div class="col-md-4 text-center">
<div class="border rounded p-3">
<h5 class="text-success">{{ land.get_verpachtete_flaeche_aktuell|floatformat:0 }} qm</h5>
<p class="text-muted mb-0">Verpachtet</p>
<small class="text-muted">({{ land.get_verpachtete_flaeche_aktuell_hektar|floatformat:2 }} ha)</small>
</div>
</div>
<div class="col-md-4 text-center">
<div class="border rounded p-3">
<h5 class="text-info">{{ land.get_verfuegbare_flaeche|floatformat:0 }} qm</h5>
<p class="text-muted mb-0">Verfügbar</p>
<small class="text-muted">(wird berechnet)</small>
</div>
</div>
<div class="col-md-4 text-center">
<div class="border rounded p-3">
<h5 class="text-warning">{{ land.get_verpachtungsgrad_neu|floatformat:1 }}%</h5>
<p class="text-muted mb-0">Verpachtungsgrad</p>
</div>
</div>
</div>
{% else %}
<div class="text-center py-5">
<i class="fas fa-handshake fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Verpachtungen</h5>
<p class="text-muted">Erstellen Sie eine neue Verpachtung für diese Länderei.</p>
<a href="{% url 'stiftung:land_verpachtung_create' land_pk=land.pk %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Erste Verpachtung erstellen
</a>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Right Column - Statistics and Actions -->
<div class="col-lg-4">
<!-- Quick Actions -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-plus-circle me-2"></i>Schnellzugriff
</h6>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="{% url 'stiftung:verpachtung_create' %}?land={{ land.pk }}" class="btn btn-info">
<i class="fas fa-handshake me-2"></i>Neue Verpachtung
</a>
<a href="{% url 'stiftung:land_update' land.pk %}" class="btn btn-warning">
<i class="fas fa-edit me-2"></i>Länderei bearbeiten
</a>
<a href="{% url 'stiftung:land_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-list me-2"></i>Alle Ländereien
</a>
</div>
</div>
</div>
<!-- System Information -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-cog me-2"></i>Systeminformationen
</h6>
</div>
<div class="card-body">
<table class="table table-sm table-borderless">
<tr>
<td><small class="text-muted">Erstellt:</small></td>
<td><small class="text-muted">{{ land.erstellt_am|date:"d.m.Y H:i" }}</small></td>
</tr>
<tr>
<td><small class="text-muted">Aktualisiert:</small></td>
<td><small class="text-muted">{{ land.aktualisiert_am|date:"d.m.Y H:i" }}</small></td>
</tr>
<tr>
<td><small class="text-muted">ID:</small></td>
<td><small class="text-muted font-monospace">{{ land.id }}</small></td>
</tr>
</table>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,443 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - 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-map text-primary me-2"></i>
{{ title }}
</h1>
<div>
<a href="{% url 'stiftung:land_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
<!-- Form -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-edit me-2"></i>Länderei-Daten eingeben
</h6>
</div>
<div class="card-body">
<form method="post" novalidate>
{% csrf_token %}
<!-- Error Messages -->
{% if form.non_field_errors %}
<div class="alert alert-danger">
<ul class="mb-0">
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<!-- Identifikation -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-fingerprint me-2"></i>Identifikation
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.lfd_nr.id_for_label }}" class="form-label">
{{ form.lfd_nr.label }} *
</label>
{{ form.lfd_nr }}
{% if form.lfd_nr.errors %}
<div class="invalid-feedback d-block">
{% for error in form.lfd_nr.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.lfd_nr.help_text %}
<div class="form-text">{{ form.lfd_nr.help_text }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.ew_nummer.id_for_label }}" class="form-label">
{{ form.ew_nummer.label }}
</label>
{{ form.ew_nummer }}
{% if form.ew_nummer.errors %}
<div class="invalid-feedback d-block">
{% for error in form.ew_nummer.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Gerichtliche Zuständigkeit -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-balance-scale me-2"></i>Gerichtliche Zuständigkeit
</h5>
</div>
<div class="col-md-12">
<div class="mb-3">
<label for="{{ form.amtsgericht.id_for_label }}" class="form-label">
{{ form.amtsgericht.label }} *
</label>
{{ form.amtsgericht }}
{% if form.amtsgericht.errors %}
<div class="invalid-feedback d-block">
{% for error in form.amtsgericht.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Verwaltungsstruktur -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-sitemap me-2"></i>Verwaltungsstruktur
</h5>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.gemeinde.id_for_label }}" class="form-label">
{{ form.gemeinde.label }} *
</label>
{{ form.gemeinde }}
{% if form.gemeinde.errors %}
<div class="invalid-feedback d-block">
{% for error in form.gemeinde.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.gemarkung.id_for_label }}" class="form-label">
{{ form.gemarkung.label }} *
</label>
{{ form.gemarkung }}
{% if form.gemarkung.errors %}
<div class="invalid-feedback d-block">
{% for error in form.gemarkung.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.flur.id_for_label }}" class="form-label">
{{ form.flur.label }} *
</label>
{{ form.flur }}
{% if form.flur.errors %}
<div class="invalid-feedback d-block">
{% for error in form.flur.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.flurstueck.id_for_label }}" class="form-label">
{{ form.flurstueck.label }} *
</label>
{{ form.flurstueck }}
{% if form.flurstueck.errors %}
<div class="invalid-feedback d-block">
{% for error in form.flurstueck.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Flächenangaben -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-ruler-combined me-2"></i>Flächenangaben
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.groesse_qm.id_for_label }}" class="form-label">
{{ form.groesse_qm.label }} *
</label>
{{ form.groesse_qm }}
{% if form.groesse_qm.errors %}
<div class="invalid-feedback d-block">
{% for error in form.groesse_qm.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.verpachtete_gesamtflaeche.id_for_label }}" class="form-label">
{{ form.verpachtete_gesamtflaeche.label }} *
</label>
{{ form.verpachtete_gesamtflaeche }}
{% if form.verpachtete_gesamtflaeche.errors %}
<div class="invalid-feedback d-block">
{% for error in form.verpachtete_gesamtflaeche.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Landnutzung -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-leaf me-2"></i>Landnutzung (Aufteilung der Gesamtfläche)
</h5>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.gruenland_qm.id_for_label }}" class="form-label">
{{ form.gruenland_qm.label }}
</label>
{{ form.gruenland_qm }}
{% if form.gruenland_qm.errors %}
<div class="invalid-feedback d-block">
{% for error in form.gruenland_qm.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.acker_qm.id_for_label }}" class="form-label">
{{ form.acker_qm.label }}
</label>
{{ form.acker_qm }}
{% if form.acker_qm.errors %}
<div class="invalid-feedback d-block">
{% for error in form.acker_qm.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.wald_qm.id_for_label }}" class="form-label">
{{ form.wald_qm.label }}
</label>
{{ form.wald_qm }}
{% if form.wald_qm.errors %}
<div class="invalid-feedback d-block">
{% for error in form.wald_qm.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-3">
<div class="mb-3">
<label for="{{ form.sonstiges_qm.id_for_label }}" class="form-label">
{{ form.sonstiges_qm.label }}
</label>
{{ form.sonstiges_qm }}
{% if form.sonstiges_qm.errors %}
<div class="invalid-feedback d-block">
{% for error in form.sonstiges_qm.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Verpachtung -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-handshake me-2"></i>Verpachtung
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.flaeche_alte_liste.id_for_label }}" class="form-label">
{{ form.flaeche_alte_liste.label }}
</label>
{{ form.flaeche_alte_liste }}
{% if form.flaeche_alte_liste.errors %}
<div class="invalid-feedback d-block">
{% for error in form.flaeche_alte_liste.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.verp_flaeche_aktuell.id_for_label }}" class="form-label">
{{ form.verp_flaeche_aktuell.label }} *
</label>
{{ form.verp_flaeche_aktuell }}
{% if form.verp_flaeche_aktuell.errors %}
<div class="invalid-feedback d-block">
{% for error in form.verp_flaeche_aktuell.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Steuern und Abgaben -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-percentage me-2"></i>Steuern und Abgaben
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.anteil_grundsteuer.id_for_label }}" class="form-label">
{{ form.anteil_grundsteuer.label }}
</label>
{{ form.anteil_grundsteuer }}
{% if form.anteil_grundsteuer.errors %}
<div class="invalid-feedback d-block">
{% for error in form.anteil_grundsteuer.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.anteil_lwk.id_for_label }}" class="form-label">
{{ form.anteil_lwk.label }}
</label>
{{ form.anteil_lwk }}
{% if form.anteil_lwk.errors %}
<div class="invalid-feedback d-block">
{% for error in form.anteil_lwk.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Status und Notizen -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-info-circle me-2"></i>Status und Notizen
</h5>
</div>
<div class="col-md-12">
<div class="mb-3">
<label for="{{ form.notizen.id_for_label }}" class="form-label">
{{ form.notizen.label }}
</label>
{{ form.notizen }}
{% if form.notizen.errors %}
<div class="invalid-feedback d-block">
{% for error in form.notizen.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-12">
<div class="form-check">
{{ form.aktiv }}
<label class="form-check-label" for="{{ form.aktiv.id_for_label }}">
{{ form.aktiv.label }}
</label>
</div>
</div>
</div>
<!-- Submit Buttons -->
<div class="row">
<div class="col-12">
<hr class="my-4">
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:land_list' %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-success">
<i class="fas fa-save me-2"></i>
{% if land %}Aktualisieren{% else %}Erstellen{% endif %}
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
// Auto-calculate total area from individual areas
function calculateTotalArea() {
const gruenland = parseFloat(document.getElementById('{{ form.gruenland_qm.id_for_label }}').value) || 0;
const acker = parseFloat(document.getElementById('{{ form.acker_qm.id_for_label }}').value) || 0;
const wald = parseFloat(document.getElementById('{{ form.wald_qm.id_for_label }}').value) || 0;
const sonstiges = parseFloat(document.getElementById('{{ form.sonstiges_qm.id_for_label }}').value) || 0;
const total = gruenland + acker + wald + sonstiges;
if (total > 0) {
document.getElementById('{{ form.groesse_qm.id_for_label }}').value = total.toFixed(2);
}
}
// Add event listeners to area fields
document.getElementById('{{ form.gruenland_qm.id_for_label }}').addEventListener('input', calculateTotalArea);
document.getElementById('{{ form.acker_qm.id_for_label }}').addEventListener('input', calculateTotalArea);
document.getElementById('{{ form.wald_qm.id_for_label }}').addEventListener('input', calculateTotalArea);
document.getElementById('{{ form.sonstiges_qm.id_for_label }}').addEventListener('input', calculateTotalArea);
</script>
{% endblock %}

View File

@@ -0,0 +1,440 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Ländereien - Stiftungsverwaltung{% endblock %}
{% block content %}
<!-- Header -->
<div class="row mb-4">
<div class="col-md-6">
<h1 class="h3">
<i class="fas fa-map text-success me-2"></i>
Ländereien verwalten
</h1>
</div>
<div class="col-md-6 text-end">
<a href="{% url 'stiftung:land_create' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Neue Länderei
</a>
</div>
</div>
<!-- Search and Filters -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-search me-2"></i>Suche & Filter
</h6>
</div>
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-4">
<label for="search" class="form-label">Suche</label>
<input type="text" class="form-control" id="search" name="search"
value="{{ search_query }}" placeholder="Lfd. Nr., Gemeinde, Gemarkung...">
</div>
<div class="col-md-3">
<label for="gemeinde" class="form-label">Gemeinde</label>
<select class="form-control" id="gemeinde" name="gemeinde">
<option value="">Alle Gemeinden</option>
{% for gemeinde in gemeinden %}
<option value="{{ gemeinde }}" {% if gemeinde == gemeinde_filter %}selected{% endif %}>
{{ gemeinde }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-3">
<label for="aktiv" class="form-label">Status</label>
<select class="form-control" id="aktiv" name="aktiv">
<option value="">Alle</option>
<option value="true" {% if aktiv_filter == 'true' %}selected{% endif %}>Aktiv</option>
<option value="false" {% if aktiv_filter == 'false' %}selected{% endif %}>Inaktiv</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label">&nbsp;</label>
<div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-search me-2"></i>Suchen
</button>
</div>
</div>
</form>
</div>
</div>
<!-- Stats and Chart -->
<div class="row mb-4">
<div class="col-lg-6 mb-3">
<div class="card shadow h-100">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-percentage me-2"></i>Flächennutzung (aktuelle Auswahl)
</h6>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-4">
<div class="h4 mb-0">{{ stats.pct_wald|default:0 }}%</div>
<div class="text-muted">Wald</div>
</div>
<div class="col-4">
<div class="h4 mb-0">{{ stats.pct_acker|default:0 }}%</div>
<div class="text-muted">Acker</div>
</div>
<div class="col-4">
<div class="h4 mb-0">{{ stats.pct_gruenland|default:0 }}%</div>
<div class="text-muted">Grünland</div>
</div>
</div>
<div class="mt-3 small text-muted text-center">
Gesamt (Nutzungsarten): {{ stats.sum_total_use_qm|floatformat:0 }} qm
</div>
<div class="mt-3" style="height:200px">
<canvas id="usageChart"></canvas>
</div>
</div>
</div>
</div>
<div class="col-lg-6 mb-3">
<div class="card shadow h-100">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-chart-bar me-2"></i>Größen der Grundstücke (Top 30)
</h6>
</div>
<div class="card-body">
<canvas id="sizesChart" height="140"></canvas>
</div>
</div>
</div>
</div>
<!-- Results -->
<div class="card shadow">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Ergebnisse
{% if page_obj %}
<span class="badge bg-secondary ms-2">{{ page_obj.paginator.count }} Ländereien</span>
{% endif %}
</h6>
<div>
<a href="{% url 'stiftung:home' %}" class="btn btn-outline-secondary btn-sm">
<i class="fas fa-arrow-left me-2"></i>Zurück zum Dashboard
</a>
</div>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th class="text-nowrap">
<a class="text-decoration-none" href="?sort=lfd_nr&dir={% if sort == 'lfd_nr' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Lfd. Nr.</a>
</th>
<th class="text-nowrap">
<a class="text-decoration-none" href="?sort=gemeinde&dir={% if sort == 'gemeinde' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Gemeinde</a>
</th>
<th class="text-nowrap">
<a class="text-decoration-none" href="?sort=gemarkung&dir={% if sort == 'gemarkung' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Gemarkung</a>
</th>
<th class="text-nowrap">
<a class="text-decoration-none" href="?sort=flur&dir={% if sort == 'flur' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Flur</a>/<a class="text-decoration-none" href="?sort=flurstueck&dir={% if sort == 'flurstueck' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Flurstück</a>
</th>
<th class="text-nowrap">
<a class="text-decoration-none" href="?sort=groesse&dir={% if sort == 'groesse' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Größe</a>
</th>
<th class="text-nowrap">
<a class="text-decoration-none" href="?sort=verp&dir={% if sort == 'verp' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Verpachtet</a>
</th>
<th class="text-nowrap">
<a class="text-decoration-none" href="?sort=grad&dir={% if sort == 'grad' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Verpachtungsgrad</a>
</th>
<th>Status</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for land in page_obj %}
<tr>
<td>
<strong>{{ land.lfd_nr }}</strong>
{% if land.ew_nummer %}
<br><small class="text-muted">{{ land.ew_nummer }}</small>
{% endif %}
</td>
<td>
<strong>{{ land.gemeinde }}</strong>
<br><small class="text-muted">{{ land.amtsgericht }}</small>
</td>
<td>{{ land.gemarkung }}</td>
<td>
Flur {{ land.flur }}<br>
Flurstück {{ land.flurstueck }}
</td>
<td>
<strong>{{ land.groesse_qm|floatformat:0 }} qm</strong>
<small class="text-muted">({{ land.groesse_hektar|floatformat:2 }} ha)</small>
<br>
<small class="text-muted">
{% if land.gruenland_qm > 0 %}G: {{ land.gruenland_qm|floatformat:0 }}{% endif %}
{% if land.acker_qm > 0 %} A: {{ land.acker_qm|floatformat:0 }}{% endif %}
{% if land.wald_qm > 0 %} W: {{ land.wald_qm|floatformat:0 }}{% endif %}
{% if land.sonstiges_qm > 0 %} S: {{ land.sonstiges_qm|floatformat:0 }}{% endif %}
</small>
</td>
<td>
{{ land.get_verpachtete_flaeche_aktuell|floatformat:0 }} qm
{% if land.flaeche_alte_liste %}
<br><small class="text-muted">Alt: {{ land.flaeche_alte_liste|floatformat:0 }} qm</small>
{% endif %}
</td>
<td>
{% with verpachtungsgrad=land.get_verpachtungsgrad %}
{% if verpachtungsgrad > 90 %}
<span class="badge bg-success">{{ verpachtungsgrad|floatformat:1 }}%</span>
{% elif verpachtungsgrad > 70 %}
<span class="badge bg-warning">{{ verpachtungsgrad|floatformat:1 }}%</span>
{% else %}
<span class="badge bg-danger">{{ verpachtungsgrad|floatformat:1 }}%</span>
{% endif %}
{% endwith %}
</td>
<td>
{% if land.aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:land_detail' land.pk %}"
class="btn btn-sm btn-outline-primary" title="Anzeigen">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:land_update' land.pk %}"
class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:land_delete' land.pk %}"
class="btn btn-sm btn-outline-danger" title="Löschen">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Ländereien Navigation">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-double-left"></i>
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-left"></i>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
{{ num }}
</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-right"></i>
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if search_query %}&search={{ search_query }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-double-right"></i>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-map fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Ländereien gefunden</h5>
<p class="text-muted">
{% if search_query or gemeinde_filter or aktiv_filter %}
Versuchen Sie andere Suchkriterien oder
<a href="{% url 'stiftung:land_list' %}">alle Ländereien anzeigen</a>.
{% else %}
Erstellen Sie Ihre erste Länderei mit dem Button oben.
{% endif %}
</p>
</div>
{% endif %}
</div>
</div>
{% endblock %}
{% block javascript %}
<script>
// Auto-submit form when filters change
document.getElementById('gemeinde').addEventListener('change', function() {
this.form.submit();
});
document.getElementById('aktiv').addEventListener('change', function() {
this.form.submit();
});
</script>
<!-- Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
try {
console.log('Initializing charts...');
// Doughnut chart for usage
const uctx = document.getElementById('usageChart');
if (uctx) {
console.log('Found usageChart canvas');
// Simple data without filtering first to test
const waldVal = parseFloat('{{ stats.sum_wald_qm|default:0|floatformat:2 }}') || 0;
const ackerVal = parseFloat('{{ stats.sum_acker_qm|default:0|floatformat:2 }}') || 0;
const gruenlandVal = parseFloat('{{ stats.sum_gruenland_qm|default:0|floatformat:2 }}') || 0;
const sonstigesVal = parseFloat('{{ stats.sum_sonstiges_qm|default:0|floatformat:2 }}') || 0;
console.log('Chart data:', {wald: waldVal, acker: ackerVal, gruenland: gruenlandVal, sonstiges: sonstigesVal});
// Only include categories with data > 0
const chartData = [];
const chartLabels = [];
const chartColors = [];
const chartBorders = [];
if (waldVal > 0) {
chartData.push(waldVal);
chartLabels.push('Wald');
chartColors.push('rgba(0, 66, 37, 0.8)');
chartBorders.push('#004225');
}
if (ackerVal > 0) {
chartData.push(ackerVal);
chartLabels.push('Acker');
chartColors.push('rgba(0, 104, 55, 0.8)');
chartBorders.push('#006837');
}
if (gruenlandVal > 0) {
chartData.push(gruenlandVal);
chartLabels.push('Grünland');
chartColors.push('rgba(253, 126, 20, 0.8)');
chartBorders.push('#fd7e14');
}
if (sonstigesVal > 0) {
chartData.push(sonstigesVal);
chartLabels.push('Sonstiges');
chartColors.push('rgba(108, 117, 125, 0.8)');
chartBorders.push('#6c757d');
}
if (chartData.length > 0) {
new Chart(uctx, {
type: 'doughnut',
data: {
labels: chartLabels,
datasets: [{
data: chartData,
backgroundColor: chartColors,
borderColor: chartBorders,
borderWidth: 2
}]
},
options: {
responsive: true,
plugins: {
legend: { position: 'bottom' },
tooltip: {
callbacks: {
label: function(context) {
return context.label + ': ' + context.raw.toLocaleString() + ' qm';
}
}
}
}
}
});
console.log('Usage chart created successfully');
} else {
console.log('No data for usage chart');
}
} else {
console.log('usageChart canvas not found');
}
// Bar chart for sizes
const ctx = document.getElementById('sizesChart');
if (ctx) {
console.log('Found sizesChart canvas');
const labels = JSON.parse('{{ size_chart_labels_json|escapejs }}');
const dataVals = JSON.parse('{{ size_chart_values_json|escapejs }}');
console.log('Bar chart data:', {labels: labels.length, values: dataVals.length});
new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Größe (qm)',
data: dataVals,
backgroundColor: 'rgba(0, 104, 55, 0.6)',
borderColor: '#006837',
borderWidth: 2
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
x: { ticks: { autoSkip: true, maxTicksLimit: 10 } },
y: { beginAtZero: true }
},
plugins: {
legend: { display: false },
tooltip: { callbacks: { label: function(ctx) { return ctx.parsed.y.toLocaleString() + ' qm'; } } }
}
}
});
console.log('Bar chart created successfully');
} else {
console.log('sizesChart canvas not found');
}
} catch (e) {
console.error('Chart initialization error:', e);
}
});
</script>
{% endblock %}

View File

@@ -0,0 +1,95 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Verpachtung beenden - {{ land }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<!-- Header -->
<div class="row mb-4">
<div class="col-md-8">
<h1 class="h3">
<i class="fas fa-stop text-warning me-2"></i>
Verpachtung beenden
</h1>
<p class="text-muted">
Länderei: <a href="{% url 'stiftung:land_detail' land.pk %}">{{ land }}</a>
</p>
</div>
<div class="col-md-4 text-end">
<a href="{% url 'stiftung:land_detail' land.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück
</a>
</div>
</div>
<!-- Warning Card -->
<div class="card shadow">
<div class="card-header bg-warning text-white py-3">
<h6 class="m-0 font-weight-bold">
<i class="fas fa-exclamation-triangle me-2"></i>Verpachtung beenden
</h6>
</div>
<div class="card-body">
<div class="alert alert-warning" role="alert">
<h5 class="alert-heading">
<i class="fas fa-handshake me-2"></i>Aktuelle Verpachtung
</h5>
<p>Sie sind dabei, die folgende Verpachtung zu beenden:</p>
<div class="bg-light p-3 rounded mt-3">
<table class="table table-sm table-borderless mb-0">
<tr>
<td><strong>Länderei:</strong></td>
<td>{{ land }}</td>
</tr>
<tr>
<td><strong>Pächter:</strong></td>
<td>{{ land.aktueller_paechter.get_full_name }}</td>
</tr>
<tr>
<td><strong>Pachtbeginn:</strong></td>
<td>{{ land.pachtbeginn|date:"d.m.Y"|default:"Nicht angegeben" }}</td>
</tr>
<tr>
<td><strong>Geplantes Ende:</strong></td>
<td>{{ land.pachtende|date:"d.m.Y"|default:"Unbefristet" }}</td>
</tr>
{% if land.pachtzins_pauschal %}
<tr>
<td><strong>Pachtzins/Jahr:</strong></td>
<td>€{{ land.pachtzins_pauschal|floatformat:2 }}</td>
</tr>
{% endif %}
<tr>
<td><strong>Fläche:</strong></td>
<td>{{ land.verp_flaeche_aktuell|floatformat:2 }} qm ({{ land.verp_flaeche_aktuell_hektar|floatformat:2 }} ha)</td>
</tr>
</table>
</div>
<hr>
<p class="mb-0">
<strong>Was passiert beim Beenden:</strong>
</p>
<ul class="mb-0">
<li>Die Pächter-Verknüpfung wird entfernt</li>
<li>Das Pachtende wird auf heute gesetzt</li>
<li>Bestehende Abrechnungen bleiben erhalten</li>
<li>Die Länderei kann neu verpachtet werden</li>
</ul>
</div>
<form method="post" class="d-flex justify-content-between">
{% csrf_token %}
<a href="{% url 'stiftung:land_detail' land.pk %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-warning">
<i class="fas fa-stop me-2"></i>Verpachtung beenden
</button>
</form>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,384 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Verpachtung erstellen - {{ land }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<!-- Header -->
<div class="row mb-4">
<div class="col-md-8">
<h1 class="h3">
<i class="fas fa-handshake text-success me-2"></i>
{% if is_edit %}Verpachtung bearbeiten{% else %}Neue Verpachtung erstellen{% endif %}
</h1>
<p class="text-muted">
Länderei: <a href="{% url 'stiftung:land_detail' land.pk %}">{{ land }}</a>
{% if is_edit and land.aktueller_paechter %} | Aktueller Pächter: {{ land.aktueller_paechter.get_full_name }}{% endif %}
</p>
</div>
<div class="col-md-4 text-end">
<a href="{% url 'stiftung:land_detail' land.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Länderei
</a>
</div>
</div>
<form method="post">
{% csrf_token %}
<div class="row">
<!-- Main Form -->
<div class="col-lg-8">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-user-tie me-2"></i>Verpachtungsdetails
</h6>
</div>
<div class="card-body">
<!-- Pächter und Grunddaten -->
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="aktueller_paechter" class="form-label">Pächter auswählen *</label>
<select class="form-select" id="aktueller_paechter" name="aktueller_paechter" required>
<option value="">Bitte wählen...</option>
{% for paechter in paechter_list %}
<option value="{{ paechter.pk }}"
{% if is_edit and land.aktueller_paechter and paechter.pk == land.aktueller_paechter.pk %}selected{% endif %}
data-name="{{ paechter.get_full_name }}"
data-anschrift="{{ paechter.strasse|default:'' }}&#10;{{ paechter.plz|default:'' }} {{ paechter.ort|default:'' }}">
{{ paechter.get_full_name }}
{% if paechter.ort %} ({{ paechter.ort }}){% endif %}
</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="verpachtete_flaeche" class="form-label">Verpachtete Fläche (qm) *</label>
<input type="number" step="0.01" class="form-control" id="verpachtete_flaeche" name="verpachtete_flaeche"
value="{% if is_edit %}{{ land.verp_flaeche_aktuell|default:verfuegbare_flaeche }}{% else %}{{ verfuegbare_flaeche|default:land.groesse_qm }}{% endif %}"
max="{{ verfuegbare_flaeche|default:land.groesse_qm }}" required>
<small class="text-muted">Verfügbar: {{ verfuegbare_flaeche|default:land.groesse_qm|floatformat:0 }} qm | Gesamt: {{ land.groesse_qm|floatformat:0 }} qm</small>
</div>
</div>
</div>
<!-- Vertragslaufzeit -->
<div class="row">
<div class="col-md-4">
<div class="mb-3">
<label for="pachtbeginn" class="form-label">Pachtbeginn *</label>
<input type="date" class="form-control" id="pachtbeginn" name="pachtbeginn"
value="{% if is_edit and land.pachtbeginn %}{{ land.pachtbeginn|date:'Y-m-d' }}{% endif %}" required>
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="pachtende" class="form-label">Pachtende</label>
<input type="date" class="form-control" id="pachtende" name="pachtende"
value="{% if is_edit and land.pachtende %}{{ land.pachtende|date:'Y-m-d' }}{% endif %}">
<small class="text-muted">Leer = unbefristet</small>
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<div class="form-check mt-4">
<input class="form-check-input" type="checkbox" id="verlaengerung_klausel" name="verlaengerung_klausel"
{% if is_edit and land.verlaengerung_klausel %}checked{% endif %}>
<label class="form-check-label" for="verlaengerung_klausel">
Automatische Verlängerung
</label>
</div>
</div>
</div>
</div>
<!-- Verpachtete Fläche -->
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="verpachtete_flaeche" class="form-label">Verpachtete Fläche (qm) *</label>
<input type="number" step="0.01" class="form-control" id="verpachtete_flaeche" name="verpachtete_flaeche"
value="{% if is_edit %}{{ land.verp_flaeche_aktuell|default:land.groesse_qm }}{% else %}{{ land.groesse_qm }}{% endif %}"
max="{{ land.groesse_qm }}" required>
<small class="text-muted">Max. verfügbar: {{ land.groesse_qm|floatformat:2 }} qm</small>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Verpachtete Fläche in Hektar</label>
<input type="text" class="form-control" id="verpachtete_flaeche_ha" readonly>
<small class="text-muted">Wird automatisch berechnet</small>
</div>
</div>
</div>
<!-- Pachtzins -->
<div class="row">
<div class="col-md-4">
<div class="mb-3">
<label for="pachtzins_pauschal" class="form-label">Pachtzins pauschal/Jahr (€) *</label>
<input type="number" step="0.01" class="form-control" id="pachtzins_pauschal" name="pachtzins_pauschal"
value="{% if is_edit %}{{ land.pachtzins_pauschal|default:'' }}{% endif %}" required>
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="pachtzins_pro_ha" class="form-label">Pachtzins pro ha (€)</label>
<input type="number" step="0.01" class="form-control" id="pachtzins_pro_ha" name="pachtzins_pro_ha"
value="{% if is_edit %}{{ land.pachtzins_pro_ha|default:'' }}{% endif %}">
<small class="text-muted">Optional für Vergleiche</small>
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="zahlungsweise" class="form-label">Zahlungsweise</label>
<select class="form-select" id="zahlungsweise" name="zahlungsweise">
<option value="jaehrlich" {% if is_edit and land.zahlungsweise == 'jaehrlich' %}selected{% endif %}>Jährlich</option>
<option value="halbjaehrlich" {% if is_edit and land.zahlungsweise == 'halbjaehrlich' %}selected{% endif %}>Halbjährlich</option>
<option value="vierteljaehrlich" {% if is_edit and land.zahlungsweise == 'vierteljaehrlich' %}selected{% endif %}>Vierteljährlich</option>
<option value="monatlich" {% if is_edit and land.zahlungsweise == 'monatlich' %}selected{% endif %}>Monatlich</option>
</select>
</div>
</div>
</div>
<!-- Umsatzsteuer -->
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="ust_option" name="ust_option"
{% if is_edit and land.ust_option %}checked{% endif %}>
<label class="form-check-label" for="ust_option">
<strong>USt-Option</strong> (Pacht mit Umsatzsteuer)
</label>
</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="ust_satz" class="form-label">USt-Satz (%)</label>
<input type="number" step="0.01" class="form-control" id="ust_satz" name="ust_satz"
value="{% if is_edit %}{{ land.ust_satz|default:'19.00' }}{% else %}19.00{% endif %}">
<small class="text-muted">Standard: 19%</small>
</div>
</div>
</div>
</div>
</div>
<!-- Umlagen und Durchreichungen -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-warning">
<i class="fas fa-exchange-alt me-2"></i>Umlagen & Durchreichungen
</h6>
</div>
<div class="card-body">
<p class="text-muted mb-3">Welche Kosten werden an den Pächter durchgereicht?</p>
<div class="row">
<div class="col-md-6">
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="grundsteuer_umlage" name="grundsteuer_umlage"
{% if is_edit %}{% if land.grundsteuer_umlage %}checked{% endif %}{% else %}checked{% endif %}>
<label class="form-check-label" for="grundsteuer_umlage">
<strong>Grundsteuer umlagefähig</strong>
<br><small class="text-muted">Grundsteuer wird an Pächter durchgereicht</small>
</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="versicherungen_umlage" name="versicherungen_umlage"
{% if is_edit %}{% if land.versicherungen_umlage %}checked{% endif %}{% else %}checked{% endif %}>
<label class="form-check-label" for="versicherungen_umlage">
<strong>Versicherungen umlagefähig</strong>
<br><small class="text-muted">Gebäude-/Haftpflichtversicherung</small>
</label>
</div>
</div>
<div class="col-md-6">
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="verbandsbeitraege_umlage" name="verbandsbeitraege_umlage"
{% if is_edit %}{% if land.verbandsbeitraege_umlage %}checked{% endif %}{% else %}checked{% endif %}>
<label class="form-check-label" for="verbandsbeitraege_umlage">
<strong>Verbandsbeiträge umlagefähig</strong>
<br><small class="text-muted">Wasser-/Bodenverbände, Deiche</small>
</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="jagdpacht_anteil_umlage" name="jagdpacht_anteil_umlage"
{% if is_edit and land.jagdpacht_anteil_umlage %}checked{% endif %}>
<label class="form-check-label" for="jagdpacht_anteil_umlage">
<strong>Jagdpachtanteile umlagefähig</strong>
<br><small class="text-muted">Sofern vertraglich geregelt</small>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Sidebar Info -->
<div class="col-lg-4">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-info-circle me-2"></i>Länderei-Info
</h6>
</div>
<div class="card-body">
<table class="table table-sm table-borderless">
<tr>
<td><strong>Gemeinde:</strong></td>
<td>{{ land.gemeinde }}</td>
</tr>
<tr>
<td><strong>Gemarkung:</strong></td>
<td>{{ land.gemarkung }}</td>
</tr>
<tr>
<td><strong>Flur/Flurstück:</strong></td>
<td>{{ land.flur }}/{{ land.flurstueck }}</td>
</tr>
<tr>
<td><strong>Größe:</strong></td>
<td>{{ land.groesse_qm|floatformat:0 }} qm<br><small>({{ land.groesse_hektar|floatformat:2 }} ha)</small></td>
</tr>
{% if land.adresse %}
<tr>
<td><strong>Adresse:</strong></td>
<td>{{ land.adresse }}</td>
</tr>
{% endif %}
</table>
{% if land.aktueller_paechter %}
<div class="alert alert-warning mt-3">
<strong>Achtung:</strong> Diese Länderei ist bereits an
<strong>{{ land.aktueller_paechter.get_full_name }}</strong> verpachtet!
</div>
{% endif %}
</div>
</div>
<div class="card shadow mt-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-lightbulb me-2"></i>Hinweise
</h6>
</div>
<div class="card-body">
<ul class="list-unstyled mb-0">
<li><i class="fas fa-check text-success me-2"></i>Pächter-Daten werden automatisch übernommen</li>
<li><i class="fas fa-check text-success me-2"></i>Umlagen können später konfiguriert werden</li>
<li><i class="fas fa-check text-success me-2"></i>Jahresabrechnungen können erstellt werden</li>
</ul>
</div>
</div>
</div>
</div>
<!-- Submit Buttons -->
<div class="row mt-4">
<div class="col-12">
<div class="card shadow">
<div class="card-body">
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:land_detail' land.pk %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-success">
<i class="fas fa-handshake me-2"></i>Verpachtung erstellen
</button>
</div>
</div>
</div>
</div>
</div>
</form>
{% endblock %}
{% block javascript %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Automatische Berechnung Pachtzins pro ha und Hektar-Anzeige
const pachtzinsPauschal = document.getElementById('pachtzins_pauschal');
const pachtzinsProHa = document.getElementById('pachtzins_pro_ha');
const verpachteteFlaeche = document.getElementById('verpachtete_flaeche');
const verpachteteFlaeheHa = document.getElementById('verpachtete_flaeche_ha');
function berechneHektar() {
const flaeche = parseFloat(verpachteteFlaeche.value) || 0;
const hektar = flaeche / 10000;
verpachteteFlaeheHa.value = hektar.toFixed(4) + ' ha';
}
function berechneProHa() {
const pauschal = parseFloat(pachtzinsPauschal.value) || 0;
const flaeche = parseFloat(verpachteteFlaeche.value) || 0;
if (pauschal > 0 && flaeche > 0) {
const hektar = flaeche / 10000;
const proHa = pauschal / hektar;
pachtzinsProHa.value = proHa.toFixed(2);
}
berechneHektar();
}
function berechnePauschal() {
const proHa = parseFloat(pachtzinsProHa.value) || 0;
const flaeche = parseFloat(verpachteteFlaeche.value) || 0;
if (proHa > 0 && flaeche > 0) {
const hektar = flaeche / 10000;
const pauschal = proHa * hektar;
pachtzinsPauschal.value = pauschal.toFixed(2);
}
}
// Event Listeners
pachtzinsPauschal.addEventListener('input', berechneProHa);
verpachteteFlaeche.addEventListener('input', function() {
berechneHektar();
berechneProHa();
});
pachtzinsProHa.addEventListener('input', berechnePauschal);
// Initiale Berechnung
berechneHektar();
// USt-Satz aktivieren/deaktivieren
const ustOption = document.getElementById('ust_option');
const ustSatz = document.getElementById('ust_satz');
function toggleUstSatz() {
ustSatz.disabled = !ustOption.checked;
if (!ustOption.checked) {
ustSatz.style.opacity = '0.5';
} else {
ustSatz.style.opacity = '1';
}
}
ustOption.addEventListener('change', toggleUstSatz);
toggleUstSatz(); // Initial state
// Pächter-Auswahl: Anschrift automatisch übernehmen
const paechterSelect = document.getElementById('aktueller_paechter');
paechterSelect.addEventListener('change', function() {
const selectedOption = this.options[this.selectedIndex];
if (selectedOption.value) {
// Hier könnten weitere automatische Übernahmen erfolgen
console.log('Pächter gewählt:', selectedOption.dataset.name);
}
});
});
</script>
{% endblock %}

View File

@@ -0,0 +1,238 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Anmeldung - van Hees-Theyssen-Vogel'sche Stiftung</title>
<!-- Custom fonts for this template-->
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet" type="text/css">
<link href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i" rel="stylesheet">
<!-- Custom styles for this template-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Nunito', sans-serif;
}
.login-card {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
border: none;
overflow: hidden;
}
.login-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 2rem;
text-align: center;
}
.login-body {
padding: 2rem;
}
.form-control {
border-radius: 10px;
border: 2px solid #e3e6f0;
padding: 0.75rem 1rem;
transition: all 0.3s ease;
}
.form-control:focus {
border-color: #667eea;
box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
}
.btn-login {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
border-radius: 10px;
padding: 0.75rem 1.5rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
transition: all 0.3s ease;
}
.btn-login:hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
}
.logo {
width: 80px;
height: 80px;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1rem;
}
.floating-shapes {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: -1;
}
.shape {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
animation: float 6s ease-in-out infinite;
}
.shape:nth-child(1) {
width: 100px;
height: 100px;
top: 20%;
left: 10%;
animation-delay: 0s;
}
.shape:nth-child(2) {
width: 150px;
height: 150px;
top: 60%;
right: 10%;
animation-delay: 2s;
}
.shape:nth-child(3) {
width: 80px;
height: 80px;
bottom: 20%;
left: 20%;
animation-delay: 4s;
}
@keyframes float {
0%, 100% {
transform: translateY(0px);
}
50% {
transform: translateY(-20px);
}
}
</style>
</head>
<body>
<div class="floating-shapes">
<div class="shape"></div>
<div class="shape"></div>
<div class="shape"></div>
</div>
<div class="container">
<div class="row justify-content-center">
<div class="col-xl-6 col-lg-8 col-md-10">
<div class="card login-card">
<div class="login-header">
<div class="logo">
<i class="fas fa-landmark fa-2x"></i>
</div>
<h2 class="h4 mb-1">van Hees-Theyssen-Vogel'sche Stiftung</h2>
<p class="mb-0">Bitte melden Sie sich an</p>
</div>
<div class="login-body">
{% if messages %}
{% for message in messages %}
<div class="alert alert-{% if message.tags == 'error' %}danger{% else %}{{ message.tags }}{% endif %} alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
</div>
{% endfor %}
{% endif %}
{% if form.errors %}
<div class="alert alert-danger">
<h6><i class="fas fa-exclamation-triangle me-2"></i>Anmeldefehler:</h6>
{% for field, errors in form.errors.items %}
{% for error in errors %}
<div>{{ error }}</div>
{% endfor %}
{% endfor %}
</div>
{% endif %}
<form method="post">
{% csrf_token %}
{% if next %}
<input type="hidden" name="next" value="{{ next }}">
{% endif %}
<div class="form-group mb-3">
<label for="{{ form.username.id_for_label }}" class="form-label">
<i class="fas fa-user me-2"></i>Benutzername
</label>
<input type="text"
class="form-control"
id="{{ form.username.id_for_label }}"
name="{{ form.username.name }}"
value="{{ form.username.value|default:'' }}"
placeholder="Ihr Benutzername"
required>
</div>
<div class="form-group mb-4">
<label for="{{ form.password.id_for_label }}" class="form-label">
<i class="fas fa-lock me-2"></i>Passwort
</label>
<input type="password"
class="form-control"
id="{{ form.password.id_for_label }}"
name="{{ form.password.name }}"
placeholder="Ihr Passwort"
required>
</div>
<button type="submit" class="btn btn-primary btn-login w-100">
<i class="fas fa-sign-in-alt me-2"></i>Anmelden
</button>
</form>
<hr class="my-4">
<div class="text-center">
<small class="text-muted">
<i class="fas fa-shield-alt me-1"></i>
Sichere Anmeldung |
<i class="fas fa-history me-1"></i>
Alle Aktivitäten werden protokolliert
</small>
</div>
</div>
</div>
<div class="text-center mt-4">
<p class="text-white">
<i class="fas fa-info-circle me-2"></i>
Bei Problemen wenden Sie sich an den Administrator
</p>
</div>
</div>
</div>
</div>
<!-- Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,50 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Pächter löschen - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row justify-content-center">
<div class="col-lg-6">
<div class="card shadow">
<div class="card-header bg-danger text-white">
<h5 class="card-title mb-0">
<i class="fas fa-exclamation-triangle me-2"></i>Pächter löschen
</h5>
</div>
<div class="card-body text-center">
<div class="mb-4">
<i class="fas fa-user-tie fa-3x text-danger mb-3"></i>
<h4>Sind Sie sicher?</h4>
<p class="text-muted">
Sie sind dabei, den Pächter <strong>"{{ paechter.get_full_name }}"</strong> zu löschen.
</p>
</div>
<div class="alert alert-warning">
<h6><i class="fas fa-exclamation-triangle me-2"></i>Wichtige Hinweise:</h6>
<ul class="list-unstyled mb-0 text-start">
<li><i class="fas fa-arrow-right me-2"></i>Alle zugehörigen Verpachtungen werden ebenfalls gelöscht</li>
<li><i class="fas fa-arrow-right me-2"></i>Diese Aktion kann nicht rückgängig gemacht werden</li>
<li><i class="fas fa-arrow-right me-2"></i>Bitte stellen Sie sicher, dass alle Daten gesichert sind</li>
</ul>
</div>
<div class="d-flex justify-content-center gap-3">
<a href="{% url 'stiftung:paechter_detail' pk=paechter.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<form method="post" class="d-inline">
{% csrf_token %}
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Ja, löschen
</button>
</form>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,450 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ paechter.get_full_name }} - Pächter - 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-user-tie text-primary me-2"></i>
Pächter: {{ paechter.get_full_name }}
</h1>
<div>
<a href="{% url 'stiftung:paechter_update' pk=paechter.pk %}" class="btn btn-warning me-2">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:paechter_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
<div class="row">
<!-- Main Content -->
<div class="col-lg-8">
<!-- Persönliche Informationen -->
<div class="card shadow mb-4">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-user me-2"></i>Persönliche Informationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Vorname:</strong> {{ paechter.vorname }}</p>
<p><strong>Nachname:</strong> {{ paechter.nachname }}</p>
{% if paechter.geburtsdatum %}
<p><strong>Geburtsdatum:</strong> {{ paechter.geburtsdatum|date:"d.m.Y" }}</p>
{% endif %}
</div>
<div class="col-md-6">
<p><strong>Status:</strong>
{% if paechter.aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</p>
{% if paechter.pachtnummer %}
<p><strong>Pachtnummer:</strong>
<span class="badge bg-secondary">{{ paechter.pachtnummer }}</span>
</p>
{% endif %}
<p><strong>Personentyp:</strong>
{% if paechter.personentyp == 'natuerlich' %}
<span class="badge bg-primary">Natürliche Person</span>
{% elif paechter.personentyp == 'gesellschaft' %}
<span class="badge bg-info">Gesellschaft</span>
{% else %}
<span class="badge bg-secondary">{{ paechter.get_personentyp_display }}</span>
{% endif %}
</p>
</div>
</div>
</div>
</div>
<!-- Kontaktinformationen -->
<div class="card shadow mb-4">
<div class="card-header bg-info text-white">
<h5 class="card-title mb-0">
<i class="fas fa-address-book me-2"></i>Kontaktinformationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
{% if paechter.email %}
<p><strong>E-Mail:</strong> <a href="mailto:{{ paechter.email }}">{{ paechter.email }}</a></p>
{% endif %}
{% if paechter.telefon %}
<p><strong>Telefon:</strong> {{ paechter.telefon }}</p>
{% endif %}
</div>
<div class="col-md-6">
{% if paechter.iban %}
<p><strong>IBAN:</strong> {{ paechter.iban }}</p>
{% endif %}
</div>
</div>
{% if paechter.strasse or paechter.plz or paechter.ort %}
<p><strong>Adresse:</strong><br>
{% if paechter.strasse %}{{ paechter.strasse }}{% endif %}
{% if paechter.plz or paechter.ort %}<br>{% endif %}
{% if paechter.plz %}{{ paechter.plz }}{% endif %}
{% if paechter.plz and paechter.ort %} {% endif %}
{% if paechter.ort %}{{ paechter.ort }}{% endif %}
</p>
{% endif %}
</div>
</div>
<!-- Pacht-spezifische Informationen -->
<div class="card shadow mb-4">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">
<i class="fas fa-tractor me-2"></i>Pacht-spezifische Informationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
{% if paechter.pachtbeginn_erste %}
<p><strong>Erster Pachtbeginn:</strong> {{ paechter.pachtbeginn_erste|date:"d.m.Y" }}</p>
{% endif %}
{% if paechter.pachtende_letzte %}
<p><strong>Letztes Pachtende:</strong> {{ paechter.pachtende_letzte|date:"d.m.Y" }}</p>
{% endif %}
</div>
<div class="col-md-6">
{% if paechter.pachtzins_aktuell %}
<p><strong>Aktueller Pachtzins:</strong> <span class="text-success fw-bold">€{{ paechter.pachtzins_aktuell|floatformat:2 }}/Jahr</span></p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Landwirtschaftliche Qualifikationen -->
<div class="card shadow mb-4">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-graduation-cap me-2"></i>Landwirtschaftliche Qualifikationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Landwirtschaftliche Ausbildung:</strong>
{% if paechter.landwirtschaftliche_ausbildung %}
<span class="badge bg-success">
<i class="fas fa-check me-1"></i>Ja
</span>
{% else %}
<span class="badge bg-warning">
<i class="fas fa-times me-1"></i>Nein
</span>
{% endif %}
</p>
{% if paechter.berufserfahrung_jahre %}
<p><strong>Berufserfahrung:</strong> {{ paechter.berufserfahrung_jahre }} Jahre</p>
{% endif %}
</div>
<div class="col-md-6">
{% if paechter.spezialisierung %}
<p><strong>Spezialisierung:</strong> {{ paechter.spezialisierung }}</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Gepachtete Ländereien (Neue Struktur) -->
{% if gepachtete_laendereien %}
<div class="card shadow mb-4">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">
<i class="fas fa-map me-2"></i>Gepachtete Ländereien ({{ gepachtete_laendereien.count }})
</h5>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Länderei</th>
<th>Pachtzeit</th>
<th>Fläche</th>
<th>Pachtzins/Jahr</th>
<th>USt-Option</th>
<th>Zahlungsweise</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for land in gepachtete_laendereien %}
<tr>
<td>
<a href="{% url 'stiftung:land_detail' pk=land.pk %}">
<strong>{{ land }}</strong>
</a>
{% if land.adresse %}
<br><small class="text-muted">{{ land.adresse }}</small>
{% endif %}
</td>
<td>
{{ land.pachtbeginn|date:"d.m.Y"|default:"Nicht angegeben" }}
{% if land.pachtende %} - {{ land.pachtende|date:"d.m.Y" }}{% else %} - <span class="text-muted">Unbefristet</span>{% endif %}
{% if land.verlaengerung_klausel %}
<br><small class="badge bg-info">Auto-Verlängerung</small>
{% endif %}
</td>
<td>
{{ land.verp_flaeche_aktuell|floatformat:2 }} qm
<br><small class="text-muted">({{ land.verp_flaeche_aktuell_hektar|floatformat:2 }} ha)</small>
</td>
<td>
{% if land.pachtzins_pauschal %}
<strong>€{{ land.pachtzins_pauschal|floatformat:2 }}</strong>
{% if land.pachtzins_pro_ha %}
<br><small class="text-muted">€{{ land.pachtzins_pro_ha|floatformat:2 }}/ha</small>
{% endif %}
{% else %}
<span class="text-muted">Nicht angegeben</span>
{% endif %}
</td>
<td>
{% if land.ust_option %}
<span class="badge bg-warning">{{ land.ust_satz|floatformat:1 }}% USt</span>
{% else %}
<span class="text-muted">Keine USt</span>
{% endif %}
</td>
<td>{{ land.get_zahlungsweise_display }}</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:land_detail' pk=land.pk %}"
class="btn btn-sm btn-outline-primary" title="Länderei anzeigen">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:land_update' pk=land.pk %}"
class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Zusammenfassung -->
<div class="row mt-3">
<div class="col-md-4 text-center">
<div class="border rounded p-3">
<h5 class="text-success">{{ total_flaeche_neu|floatformat:0 }} qm</h5>
<p class="text-muted mb-0">Gesamtfläche</p>
<small class="text-muted">({{ total_flaeche_neu_hektar|floatformat:2 }} ha)</small>
</div>
</div>
<div class="col-md-4 text-center">
<div class="border rounded p-3">
<h5 class="text-primary">€{{ total_pachtzins_neu|floatformat:0 }}</h5>
<p class="text-muted mb-0">Pachtzins/Jahr</p>
</div>
</div>
<div class="col-md-4 text-center">
<div class="border rounded p-3">
<h5 class="text-info">{{ gepachtete_laendereien.count }}</h5>
<p class="text-muted mb-0">Ländereien</p>
</div>
</div>
</div>
<!-- Link zu Abrechnungen -->
<div class="text-center mt-3">
<a href="{% url 'stiftung:land_abrechnung_list' %}?paechter={{ paechter.pk }}" class="btn btn-outline-success">
<i class="fas fa-calculator me-2"></i>Abrechnungen anzeigen
</a>
</div>
</div>
</div>
{% endif %}
<!-- Legacy Verpachtungen entfernt für saubere UI -->
<!-- Verknüpfte Dokumente -->
<div class="card shadow mb-4">
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">
<i class="fas fa-file-alt me-2"></i>Verknüpfte Dokumente
</h5>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-light btn-sm">
<i class="fas fa-plus me-1"></i>Dokument verknüpfen
</a>
</div>
<div class="card-body">
{% if verknuepfte_dokumente %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Dokument</th>
<th>Kontext</th>
<th>Beschreibung</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for dokument in verknuepfte_dokumente %}
<tr>
<td>
<strong>{{ dokument.titel }}</strong>
<br>
<small class="text-muted">ID: {{ dokument.paperless_document_id }}</small>
</td>
<td>
<span class="badge bg-secondary">{{ dokument.get_kontext_display }}</span>
</td>
<td>
{% if dokument.beschreibung %}
{{ dokument.beschreibung|truncatewords:10 }}
{% else %}
<span class="text-muted">Keine Beschreibung</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{{ dokument.get_paperless_url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="In Paperless öffnen">
<i class="fas fa-external-link-alt"></i>
</a>
<a href="{{ dokument.get_paperless_thumbnail_url }}" target="_blank" class="btn btn-sm btn-outline-info" title="Thumbnail anzeigen">
<i class="fas fa-image"></i>
</a>
<a href="{% url 'stiftung:dokument_update' dokument.pk %}" class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:dokument_delete' dokument.pk %}" class="btn btn-sm btn-outline-danger" title="Verknüpfung löschen">
<i class="fas fa-unlink"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-file-alt fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Dokumente verknüpft</h5>
<p class="text-muted">Verknüpfen Sie Dokumente aus Paperless mit diesem Pächter.</p>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Erstes Dokument verknüpfen
</a>
</div>
{% endif %}
</div>
</div>
<!-- Notizen -->
{% if paechter.notizen %}
<div class="card shadow mb-4">
<div class="card-header bg-light">
<h5 class="card-title mb-0">
<i class="fas fa-sticky-note me-2"></i>Notizen
</h5>
</div>
<div class="card-body">
{{ paechter.notizen|linebreaks }}
</div>
</div>
{% endif %}
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<!-- Statistiken -->
<div class="card shadow mb-4">
<div class="card-header bg-primary text-white">
<h6 class="card-title mb-0">
<i class="fas fa-chart-bar me-2"></i>Statistiken
</h6>
</div>
<div class="card-body">
<div class="text-center">
<div class="row">
<div class="col-6">
<div class="border-end">
<h4 class="text-primary">{{ verpachtungen.count }}</h4>
<small class="text-muted">Verpachtungen</small>
</div>
</div>
<div class="col-6">
<h4 class="text-success">
{% if verpachtungen %}
{% with total_flaeche=verpachtungen|length %}
{{ total_flaeche|floatformat:0 }}
{% endwith %}
{% else %}
0
{% endif %}
</h4>
<small class="text-muted">Aktive Verträge</small>
</div>
</div>
</div>
</div>
</div>
<!-- Aktionen -->
<div class="card shadow mb-4">
<div class="card-header bg-success text-white">
<h6 class="card-title mb-0">
<i class="fas fa-tools me-2"></i>Aktionen
</h6>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="{% url 'stiftung:paechter_update' pk=paechter.pk %}" class="btn btn-warning">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:paechter_export' pk=paechter.pk %}" class="btn btn-success">
<i class="fas fa-download me-2"></i>Export
</a>
<a href="{% url 'stiftung:paechter_delete' pk=paechter.pk %}" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Löschen
</a>
</div>
</div>
</div>
<!-- Informationen -->
<div class="card shadow">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">
<i class="fas fa-info-circle me-2"></i>Informationen
</h6>
</div>
<div class="card-body">
<p><strong>ID:</strong> {{ paechter.id }}</p>
<p><strong>Erstellt:</strong> {{ paechter.id|slice:":8" }}</p>
{% if paechter.aktiv %}
<p><strong>Status:</strong> <span class="badge bg-success">Aktiv</span></p>
{% else %}
<p><strong>Status:</strong> <span class="badge bg-secondary">Inaktiv</span></p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,451 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3">
<i class="fas fa-user-tie text-primary me-2"></i>
{{ title }}
</h1>
<div>
<a href="{% url 'stiftung:paechter_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
<div class="row">
<div class="col-lg-8">
<div class="card shadow">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-edit me-2"></i>Pächter-Daten
</h5>
</div>
<div class="card-body">
<form method="post" novalidate>
{% csrf_token %}
<!-- Persönliche Informationen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-user me-2"></i>Persönliche Informationen
</h6>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.vorname.id_for_label }}" class="form-label">
{{ form.vorname.label }} *
</label>
{{ form.vorname }}
{% if form.vorname.errors %}
<div class="invalid-feedback d-block">
{% for error in form.vorname.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.vorname.help_text %}
<div class="form-text">{{ form.vorname.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.nachname.id_for_label }}" class="form-label">
{{ form.nachname.label }} *
</label>
{{ form.nachname }}
{% if form.nachname.errors %}
<div class="invalid-feedback d-block">
{% for error in form.nachname.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.nachname.help_text %}
<div class="form-text">{{ form.nachname.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.geburtsdatum.id_for_label }}" class="form-label">
{{ form.geburtsdatum.label }}
</label>
{{ form.geburtsdatum }}
{% if form.geburtsdatum.errors %}
<div class="invalid-feedback d-block">
{% for error in form.geburtsdatum.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.geburtsdatum.help_text %}
<div class="form-text">{{ form.geburtsdatum.help_text }}</div>
{% endif %}
</div>
</div>
</div>
<!-- Kontaktinformationen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-address-book me-2"></i>Kontaktinformationen
</h6>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.email.id_for_label }}" class="form-label">
{{ form.email.label }}
</label>
{{ form.email }}
{% if form.email.errors %}
<div class="invalid-feedback d-block">
{% for error in form.email.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.email.help_text %}
<div class="form-text">{{ form.email.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.telefon.id_for_label }}" class="form-label">
{{ form.telefon.label }}
</label>
{{ form.telefon }}
{% if form.telefon.errors %}
<div class="invalid-feedback d-block">
{% for error in form.telefon.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.telefon.help_text %}
<div class="form-text">{{ form.telefon.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.iban.id_for_label }}" class="form-label">
{{ form.iban.label }}
</label>
{{ form.iban }}
{% if form.iban.errors %}
<div class="invalid-feedback d-block">
{% for error in form.iban.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.iban.help_text %}
<div class="form-text">{{ form.iban.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.strasse.id_for_label }}" class="form-label">
{{ form.strasse.label }}
</label>
{{ form.strasse }}
{% if form.strasse.errors %}
<div class="invalid-feedback d-block">
{% for error in form.strasse.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.strasse.help_text %}
<div class="form-text">{{ form.strasse.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.plz.id_for_label }}" class="form-label">
{{ form.plz.label }}
</label>
{{ form.plz }}
{% if form.plz.errors %}
<div class="invalid-feedback d-block">
{% for error in form.plz.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.plz.help_text %}
<div class="form-text">{{ form.plz.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.ort.id_for_label }}" class="form-label">
{{ form.ort.label }}
</label>
{{ form.ort }}
{% if form.ort.errors %}
<div class="invalid-feedback d-block">
{% for error in form.ort.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.ort.help_text %}
<div class="form-text">{{ form.ort.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.personentyp.id_for_label }}" class="form-label">
{{ form.personentyp.label }}
</label>
{{ form.personentyp }}
{% if form.personentyp.errors %}
<div class="invalid-feedback d-block">
{% for error in form.personentyp.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.personentyp.help_text %}
<div class="form-text">{{ form.personentyp.help_text }}</div>
{% endif %}
</div>
</div>
<!-- Pacht-spezifische Informationen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-tractor me-2"></i>Pacht-spezifische Informationen
</h6>
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.pachtnummer.id_for_label }}" class="form-label">
{{ form.pachtnummer.label }}
</label>
{{ form.pachtnummer }}
{% if form.pachtnummer.errors %}
<div class="invalid-feedback d-block">
{% for error in form.pachtnummer.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.pachtnummer.help_text %}
<div class="form-text">{{ form.pachtnummer.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.pachtzins_aktuell.id_for_label }}" class="form-label">
{{ form.pachtzins_aktuell.label }}
</label>
{{ form.pachtzins_aktuell }}
{% if form.pachtzins_aktuell.errors %}
<div class="invalid-feedback d-block">
{% for error in form.pachtzins_aktuell.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.pachtzins_aktuell.help_text %}
<div class="form-text">{{ form.pachtzins_aktuell.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.pachtbeginn_erste.id_for_label }}" class="form-label">
{{ form.pachtbeginn_erste.label }}
</label>
{{ form.pachtbeginn_erste }}
{% if form.pachtbeginn_erste.errors %}
<div class="invalid-feedback d-block">
{% for error in form.pachtbeginn_erste.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.pachtbeginn_erste.help_text %}
<div class="form-text">{{ form.pachtbeginn_erste.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.pachtende_letzte.id_for_label }}" class="form-label">
{{ form.pachtende_letzte.label }}
</label>
{{ form.pachtende_letzte }}
{% if form.pachtende_letzte.errors %}
<div class="invalid-feedback d-block">
{% for error in form.pachtende_letzte.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.pachtende_letzte.help_text %}
<div class="form-text">{{ form.pachtende_letzte.help_text }}</div>
{% endif %}
</div>
</div>
<!-- Landwirtschaftliche Qualifikationen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-graduation-cap me-2"></i>Landwirtschaftliche Qualifikationen
</h6>
</div>
<div class="col-md-6 mb-3">
<div class="form-check">
{{ form.landwirtschaftliche_ausbildung }}
<label class="form-check-label" for="{{ form.landwirtschaftliche_ausbildung.id_for_label }}">
{{ form.landwirtschaftliche_ausbildung.label }}
</label>
</div>
{% if form.landwirtschaftliche_ausbildung.errors %}
<div class="invalid-feedback d-block">
{% for error in form.landwirtschaftliche_ausbildung.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.landwirtschaftliche_ausbildung.help_text %}
<div class="form-text">{{ form.landwirtschaftliche_ausbildung.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.berufserfahrung_jahre.id_for_label }}" class="form-label">
{{ form.berufserfahrung_jahre.label }}
</label>
{{ form.berufserfahrung_jahre }}
{% if form.berufserfahrung_jahre.errors %}
<div class="invalid-feedback d-block">
{% for error in form.berufserfahrung_jahre.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.berufserfahrung_jahre.help_text %}
<div class="form-text">{{ form.berufserfahrung_jahre.help_text }}</div>
{% endif %}
</div>
<div class="col-md-12 mb-3">
<label for="{{ form.spezialisierung.id_for_label }}" class="form-label">
{{ form.spezialisierung.label }}
</label>
{{ form.spezialisierung }}
{% if form.spezialisierung.errors %}
<div class="invalid-feedback d-block">
{% for error in form.spezialisierung.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.spezialisierung.help_text %}
<div class="form-text">{{ form.spezialisierung.help_text }}</div>
{% endif %}
</div>
</div>
<!-- Status und Notizen -->
<div class="row mb-4">
<div class="col-12">
<h6 class="text-primary border-bottom pb-2 mb-3">
<i class="fas fa-cog me-2"></i>Status und Notizen
</h6>
</div>
<div class="col-md-6 mb-3">
<div class="form-check">
{{ form.aktiv }}
<label class="form-check-label" for="{{ form.aktiv.id_for_label }}">
{{ form.aktiv.label }}
</label>
</div>
{% if form.aktiv.errors %}
<div class="invalid-feedback d-block">
{% for error in form.aktiv.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.aktiv.help_text %}
<div class="form-text">{{ form.aktiv.help_text }}</div>
{% endif %}
</div>
<div class="col-md-12 mb-3">
<label for="{{ form.notizen.id_for_label }}" class="form-label">
{{ form.notizen.label }}
</label>
{{ form.notizen }}
{% if form.notizen.errors %}
<div class="invalid-feedback d-block">
{% for error in form.notizen.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
{% if form.notizen.help_text %}
<div class="form-text">{{ form.notizen.help_text }}</div>
{% endif %}
</div>
</div>
<!-- Form Actions -->
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:paechter_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-2"></i>Speichern
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<div class="card shadow">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">
<i class="fas fa-info-circle me-2"></i>Hilfe
</h6>
</div>
<div class="card-body">
<h6>Pflichtfelder:</h6>
<ul class="list-unstyled small">
<li><i class="fas fa-asterisk text-danger me-1"></i>Vorname</li>
<li><i class="fas fa-asterisk text-danger me-1"></i>Nachname</li>
</ul>
<hr>
<h6>Wichtige Hinweise:</h6>
<ul class="list-unstyled small">
<li><i class="fas fa-lightbulb text-warning me-1"></i>Die Pachtnummer dient zur eindeutigen Identifikation</li>
<li><i class="fas fa-lightbulb text-warning me-1"></i>Landwirtschaftliche Ausbildung wird für die Pachtbewertung benötigt</li>
<li><i class="fas fa-lightbulb text-warning me-1"></i>Berufserfahrung und Spezialisierung helfen bei der Flächenzuweisung</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,239 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Pächter - 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-user-tie text-primary me-2"></i>
Pächter
</h1>
<div>
<a href="{% url 'stiftung:paechter_create' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Neuen Pächter erstellen
</a>
</div>
</div>
<!-- Search and Filters -->
<div class="card shadow mb-4">
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-3">
<label for="search" class="form-label">Suche</label>
<input type="text" class="form-control" id="search" name="search"
value="{{ search_query }}" placeholder="Name, E-Mail oder Pachtnummer...">
</div>
<div class="col-md-2">
<label for="ausbildung" class="form-label">Ausbildung</label>
<select class="form-control" id="ausbildung" name="ausbildung">
<option value="">Alle</option>
<option value="true" {% if ausbildung_filter == 'true' %}selected{% endif %}>Mit Ausbildung</option>
<option value="false" {% if ausbildung_filter == 'false' %}selected{% endif %}>Ohne Ausbildung</option>
</select>
</div>
<div class="col-md-2">
<label for="aktiv" class="form-label">Status</label>
<select class="form-control" id="aktiv" name="aktiv">
<option value="">Alle</option>
<option value="true" {% if aktiv_filter == 'true' %}selected{% endif %}>Aktiv</option>
<option value="false" {% if aktiv_filter == 'false' %}selected{% endif %}>Inaktiv</option>
</select>
</div>
<div class="col-md-3 d-flex align-items-end">
<button type="submit" class="btn btn-primary me-2">
<i class="fas fa-search me-1"></i>Suchen
</button>
<a href="{% url 'stiftung:paechter_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Zurücksetzen
</a>
</div>
</form>
</div>
</div>
<!-- Results -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Pächter ({{ page_obj.paginator.count }})
</h6>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>
<a href="?sort=name&dir={% if sort == 'name' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Name</a>
</th>
<th>
<a href="?sort=pachtnummer&dir={% if sort == 'pachtnummer' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Pachtnummer</a>
</th>
<th>
<a href="?sort=ausbildung&dir={% if sort == 'ausbildung' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Ausbildung</a>
</th>
<th>
<a href="?sort=spezialisierung&dir={% if sort == 'spezialisierung' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Spezialisierung</a>
</th>
<th>
<a href="?sort=flaeche&dir={% if sort == 'flaeche' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Verpachtete Fläche</a>
</th>
<th>
<a href="?sort=pachtzins&dir={% if sort == 'pachtzins' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Pachtzins</a>
</th>
<th>
<a href="?sort=status&dir={% if sort == 'status' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">Status</a>
</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for paechter in page_obj %}
<tr>
<td>
<strong>{{ paechter.nachname }}, {{ paechter.vorname }}</strong>
{% if paechter.geburtsdatum %}
<br><small class="text-muted">{{ paechter.geburtsdatum|date:"d.m.Y" }}</small>
{% endif %}
</td>
<td>
{% if paechter.pachtnummer %}
<span class="badge bg-secondary">{{ paechter.pachtnummer }}</span>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if paechter.landwirtschaftliche_ausbildung %}
<span class="badge bg-success">
<i class="fas fa-graduation-cap me-1"></i>Ja
</span>
{% else %}
<span class="badge bg-warning">
<i class="fas fa-times me-1"></i>Nein
</span>
{% endif %}
</td>
<td>
{% if paechter.spezialisierung %}
{{ paechter.spezialisierung }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if paechter.gesamt_flaeche %}
<span class="text-success fw-bold">{{ paechter.gesamt_flaeche|floatformat:2 }} qm</span>
{% else %}
<span class="text-muted">0.00 qm</span>
{% endif %}
</td>
<td>
{% if paechter.gesamt_pachtzins %}
<span class="text-primary fw-bold">€{{ paechter.gesamt_pachtzins|floatformat:2 }}/Jahr</span>
{% else %}
<span class="text-muted">€0.00/Jahr</span>
{% endif %}
</td>
<td>
{% if paechter.aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:paechter_detail' pk=paechter.pk %}"
class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:paechter_update' pk=paechter.pk %}"
class="btn btn-sm btn-outline-warning">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:paechter_delete' pk=paechter.pk %}"
class="btn btn-sm btn-outline-danger">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Pächter Pagination" class="mt-4">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-double-left"></i>
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-left"></i>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-right"></i>
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if ausbildung_filter %}&ausbildung={{ ausbildung_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-angle-double-right"></i>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-user-tie fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Pächter gefunden</h5>
<p class="text-muted">
{% if search_query or familienzweig_filter or ausbildung_filter or aktiv_filter %}
Versuchen Sie andere Suchkriterien oder
<a href="{% url 'stiftung:paechter_list' %}">setzen Sie die Filter zurück</a>.
{% else %}
Erstellen Sie den ersten Pächter mit dem Button oben.
{% endif %}
</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,68 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Person löschen - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-6 mx-auto">
<div class="card shadow">
<div class="card-header bg-danger text-white">
<h4 class="mb-0">
<i class="fas fa-exclamation-triangle me-2"></i>Person löschen
</h4>
</div>
<div class="card-body">
<div class="alert alert-warning">
<h5 class="alert-heading">
<i class="fas fa-exclamation-triangle me-2"></i>Warnung!
</h5>
<p class="mb-0">
Sind Sie sicher, dass Sie <strong>{{ person.get_full_name }}</strong> löschen möchten?
</p>
</div>
<div class="card mb-3">
<div class="card-body">
<h6 class="card-title">Personendaten:</h6>
<p class="card-text">
<strong>Name:</strong> {{ person.vorname }} {{ person.nachname }}<br>
<strong>Familienzweig:</strong> {{ person.get_familienzweig_display }}<br>
{% if person.geburtsdatum %}
<strong>Geboren:</strong> {{ person.geburtsdatum|date:"d.m.Y" }}<br>
{% endif %}
{% if person.email %}
<strong>E-Mail:</strong> {{ person.email }}
{% endif %}
</p>
</div>
</div>
<div class="alert alert-info">
<h6 class="alert-heading">
<i class="fas fa-info-circle me-2"></i>Wichtiger Hinweis
</h6>
<p class="mb-0">
Diese Aktion kann nicht rückgängig gemacht werden. Alle zugehörigen Förderungen
und Verpachtungen werden ebenfalls gelöscht.
</p>
</div>
<form method="post">
{% csrf_token %}
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:destinataer_list' %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Endgültig löschen
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,188 @@
{% extends "base.html" %}
{% block title %}{{ person.get_full_name }} - 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-user text-primary me-2"></i>{{ person.get_full_name }}
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:person_update' person.id %}" class="btn btn-warning">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:person_delete' person.id %}" class="btn btn-danger">
<i class="fas fa-trash me-1"></i>Löschen
</a>
</div>
</div>
<!-- Person Information -->
<div class="row">
<div class="col-lg-8">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-info-circle me-2"></i>Persönliche Informationen
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-primary">Name</h6>
<p class="mb-3">{{ person.vorname }} {{ person.nachname }}</p>
<h6 class="text-primary">Geburtsdatum</h6>
<p class="mb-3">{{ person.geburtsdatum|date:"d.m.Y" }}</p>
<h6 class="text-primary">Familienzweig</h6>
<p class="mb-3">
<span class="badge bg-secondary">{{ person.get_familienzweig_display }}</span>
</p>
</div>
<div class="col-md-6">
<h6 class="text-primary">Adresse</h6>
<p class="mb-3">
{{ person.strasse }} {{ person.hausnummer }}<br>
{{ person.plz }} {{ person.ort }}
</p>
<h6 class="text-primary">Kontakt</h6>
<p class="mb-3">
{% if person.telefon %}
<i class="fas fa-phone me-2"></i>{{ person.telefon }}<br>
{% endif %}
{% if person.email %}
<i class="fas fa-envelope me-2"></i>{{ person.email }}
{% endif %}
</p>
</div>
</div>
{% if person.bemerkungen %}
<hr class="my-3">
<h6 class="text-primary">Bemerkungen</h6>
<p class="mb-0">{{ person.bemerkungen }}</p>
{% endif %}
</div>
</div>
<!-- Förderungen -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-gift me-2"></i>Förderungen
</h6>
<a href="{% url 'stiftung:foerderung_create' %}?person={{ person.id }}" class="btn btn-sm btn-success">
<i class="fas fa-plus me-2"></i>Neue Förderung
</a>
</div>
<div class="card-body">
{% if foerderungen %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Jahr</th>
<th>Betrag</th>
<th>Kategorie</th>
<th>Status</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for foerderung in foerderungen %}
<tr>
<td>{{ foerderung.jahr }}</td>
<td>€{{ foerderung.betrag|floatformat:2 }}</td>
<td>
<span class="badge bg-secondary">{{ foerderung.get_kategorie_display }}</span>
</td>
<td>
<span class="badge bg-{{ foerderung.get_status_color }}">{{ foerderung.get_status_display }}</span>
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:foerderung_detail' foerderung.pk %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:foerderung_update' foerderung.pk %}" class="btn btn-sm btn-outline-warning">
<i class="fas fa-edit"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-gift fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Förderungen vorhanden</h5>
<p class="text-muted">Erstellen Sie die erste Förderung für diese Person.</p>
<a href="{% url 'stiftung:foerderung_create' %}?person={{ person.id }}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Förderung erstellen
</a>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<!-- Quick Stats -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-chart-pie me-2"></i>Übersicht
</h6>
</div>
<div class="card-body">
<div class="row text-center">
<div class="col-6">
<div class="border-end">
<h4 class="text-primary">{{ foerderungen|length }}</h4>
<small class="text-muted">Förderungen</small>
</div>
</div>
<div class="col-6">
<h4 class="text-success">€{{ total_foerderungen|floatformat:2 }}</h4>
<small class="text-muted">Gesamtbetrag</small>
</div>
</div>
</div>
</div>
<!-- Actions -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-bolt me-2"></i>Schnellzugriff
</h6>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="{% url 'stiftung:person_update' person.id %}" class="btn btn-warning">
<i class="fas fa-edit me-2"></i>Person bearbeiten
</a>
<a href="{% url 'stiftung:foerderung_create' %}?person={{ person.id }}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Neue Förderung
</a>
<a href="{% url 'stiftung:person_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,317 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - 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-user text-primary me-2"></i>
{{ title }}
</h1>
<div>
<a href="{% url 'stiftung:person_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
<!-- Form -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-edit me-2"></i>Personendaten eingeben
</h6>
</div>
<div class="card-body">
<form method="post" novalidate>
{% csrf_token %}
<!-- Error Messages -->
{% if form.non_field_errors %}
<div class="alert alert-danger">
<ul class="mb-0">
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<!-- Persönliche Daten -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-user me-2"></i>Persönliche Daten
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.vorname.id_for_label }}" class="form-label">
{{ form.vorname.label }} *
</label>
{{ form.vorname }}
{% if form.vorname.errors %}
<div class="invalid-feedback d-block">
{% for error in form.vorname.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.nachname.id_for_label }}" class="form-label">
{{ form.nachname.label }} *
</label>
{{ form.nachname }}
{% if form.nachname.errors %}
<div class="invalid-feedback d-block">
{% for error in form.nachname.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Geburtsdatum und Familienzweig -->
<div class="row mb-4">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.geburtsdatum.id_for_label }}" class="form-label">
{{ form.geburtsdatum.label }}
</label>
{{ form.geburtsdatum }}
{% if form.geburtsdatum.errors %}
<div class="invalid-feedback d-block">
{% for error in form.geburtsdatum.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.familienzweig.id_for_label }}" class="form-label">
{{ form.familienzweig.label }} *
</label>
{{ form.familienzweig }}
{% if form.familienzweig.errors %}
<div class="invalid-feedback d-block">
{% for error in form.familienzweig.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Adresse -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-map-marker-alt me-2"></i>Adresse
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.strasse.id_for_label }}" class="form-label">
{{ form.strasse.label }} *
</label>
{{ form.strasse }}
{% if form.strasse.errors %}
<div class="invalid-feedback d-block">
{% for error in form.strasse.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-2">
<div class="mb-3">
<label for="{{ form.hausnummer.id_for_label }}" class="form-label">
{{ form.hausnummer.label }} *
</label>
{{ form.hausnummer }}
{% if form.hausnummer.errors %}
<div class="invalid-feedback d-block">
{% for error in form.hausnummer.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-2">
<div class="mb-3">
<label for="{{ form.plz.id_for_label }}" class="form-label">
{{ form.plz.label }} *
</label>
{{ form.plz }}
{% if form.plz.errors %}
<div class="invalid-feedback d-block">
{% for error in form.plz.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-2">
<div class="mb-3">
<label for="{{ form.ort.id_for_label }}" class="form-label">
{{ form.ort.label }} *
</label>
{{ form.ort }}
{% if form.ort.errors %}
<div class="invalid-feedback d-block">
{% for error in form.ort.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Kontaktdaten -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-phone me-2"></i>Kontaktdaten
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.telefon.id_for_label }}" class="form-label">
{{ form.telefon.label }}
</label>
{{ form.telefon }}
{% if form.telefon.errors %}
<div class="invalid-feedback d-block">
{% for error in form.telefon.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.email.id_for_label }}" class="form-label">
{{ form.email.label }}
</label>
{{ form.email }}
{% if form.email.errors %}
<div class="invalid-feedback d-block">
{% for error in form.email.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Bankdaten -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-university me-2"></i>Bankdaten
</h5>
</div>
<div class="col-md-12">
<div class="mb-3">
<label for="{{ form.iban.id_for_label }}" class="form-label">
{{ form.iban.label }}
</label>
{{ form.iban }}
{% if form.iban.errors %}
<div class="invalid-feedback d-block">
{% for error in form.iban.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Status und Notizen -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-info-circle me-2"></i>Status und Notizen
</h5>
</div>
<div class="col-md-12">
<div class="mb-3">
<label for="{{ form.bemerkungen.id_for_label }}" class="form-label">
{{ form.bemerkungen.label }}
</label>
{{ form.bemerkungen }}
{% if form.bemerkungen.errors %}
<div class="invalid-feedback d-block">
{% for error in form.bemerkungen.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-12">
<div class="form-check">
{{ form.aktiv }}
<label class="form-check-label" for="{{ form.aktiv.id_for_label }}">
{{ form.aktiv.label }}
</label>
</div>
</div>
</div>
<!-- Submit Buttons -->
<div class="row">
<div class="col-12">
<hr class="my-4">
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:person_list' %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-success">
<i class="fas fa-save me-2"></i>
{% if person %}Aktualisieren{% else %}Erstellen{% endif %}
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
// Auto-format IBAN input
document.getElementById('{{ form.iban.id_for_label }}').addEventListener('input', function(e) {
let value = e.target.value.replace(/\s/g, '').toUpperCase();
if (value.length > 0) {
// Add spaces every 4 characters
value = value.match(/.{1,4}/g).join(' ');
}
e.target.value = value;
});
</script>
{% endblock %}

View File

@@ -0,0 +1,246 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Personen - Stiftungsverwaltung{% endblock %}
{% block content %}
<!-- Header -->
<div class="row mb-4">
<div class="col-md-6">
<h1 class="h3">
<i class="fas fa-users text-primary me-2"></i>
Personenverwaltung
</h1>
<p class="text-muted">Verwalten Sie alle Stiftungsmitglieder und deren Informationen</p>
</div>
<div class="col-md-6 text-end">
<a href="{% url 'stiftung:person_create' %}" class="btn btn-primary">
<i class="fas fa-user-plus me-2"></i>Neue Person
</a>
</div>
</div>
<!-- Search and Filters -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-search me-2"></i>Suche & Filter
</h6>
</div>
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-4">
<label for="search" class="form-label">Suche</label>
<input type="text" class="form-control" id="search" name="search"
value="{{ search_query }}" placeholder="Nach Namen, E-Mail oder Familienzweig suchen...">
</div>
<div class="col-md-3">
<label for="familienzweig" class="form-label">Familienzweig</label>
<select class="form-control" id="familienzweig" name="familienzweig">
<option value="">Alle Familienzweige</option>
{% for value, label in familienzweig_choices %}
<option value="{{ value }}" {% if value == familienzweig_filter %}selected{% endif %}>
{{ label }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-3">
<label for="aktiv" class="form-label">Status</label>
<select class="form-control" id="aktiv" name="aktiv">
<option value="">Alle</option>
<option value="true" {% if aktiv_filter == 'true' %}selected{% endif %}>Nur Aktive</option>
<option value="false" {% if aktiv_filter == 'false' %}selected{% endif %}>Nur Inaktive</option>
</select>
</div>
<div class="col-md-2">
<label class="form-label">&nbsp;</label>
<div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-search me-2"></i>Suchen
</button>
</div>
</div>
</form>
</div>
</div>
<!-- Results -->
<div class="card shadow">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Ergebnisse
{% if page_obj %}
<span class="badge bg-secondary ms-2">{{ page_obj.paginator.count }} Personen</span>
{% endif %}
</h6>
<div>
<a href="{% url 'stiftung:home' %}" class="btn btn-outline-secondary btn-sm">
<i class="fas fa-arrow-left me-2"></i>Zurück zum Dashboard
</a>
</div>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Name</th>
<th>Familienzweig</th>
<th>Geburtsdatum</th>
<th>E-Mail</th>
<th>Telefon</th>
<th>Status</th>
<th>Förderungen</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for person in page_obj %}
<tr>
<td>
<strong>{{ person.get_full_name }}</strong>
{% if person.iban %}
<br><small class="text-muted font-monospace">{{ person.iban }}</small>
{% endif %}
</td>
<td>
<span class="badge bg-info">{{ person.get_familienzweig_display }}</span>
</td>
<td>
{% if person.geburtsdatum %}
{{ person.geburtsdatum|date:"d.m.Y" }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if person.email %}
<a href="mailto:{{ person.email }}">{{ person.email }}</a>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if person.telefon %}
{{ person.telefon }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if person.aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</td>
<td>
{% if person.total_foerderungen %}
<strong class="text-success">€{{ person.total_foerderungen|floatformat:2 }}</strong>
{% else %}
<span class="text-muted">€0.00</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:destinataer_detail' person.pk %}"
class="btn btn-sm btn-outline-primary" title="Anzeigen">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:person_update' person.pk %}"
class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:person_delete' person.pk %}"
class="btn btn-sm btn-outline-danger" title="Löschen">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Personen Navigation">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">
<i class="fas fa-angle-double-left"></i>
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">
<i class="fas fa-angle-left"></i>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">
{{ num }}
</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">
<i class="fas fa-angle-right"></i>
</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}{% if search_query %}&search={{ search_query }}{% endif %}{% if familienzweig_filter %}&familienzweig={{ familienzweig_filter }}{% endif %}{% if aktiv_filter %}&aktiv={{ aktiv_filter }}{% endif %}">
<i class="fas fa-angle-double-right"></i>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-users fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Personen gefunden</h5>
<p class="text-muted">
{% if search_query or familienzweig_filter or aktiv_filter %}
Versuchen Sie andere Suchkriterien oder
<a href="{% url 'stiftung:person_list' %}">alle Personen anzeigen</a>.
{% else %}
Erstellen Sie Ihre erste Person mit dem Button oben.
{% endif %}
</p>
</div>
{% endif %}
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
// Auto-submit form when filters change
document.getElementById('familienzweig').addEventListener('change', function() {
this.form.submit();
});
document.getElementById('aktiv').addEventListener('change', function() {
this.form.submit();
});
</script>
{% endblock %}

View File

@@ -0,0 +1,406 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Ausgaben - {{ rentmeister.get_full_name }} - 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-file-invoice-dollar me-2"></i>Ausgaben - {{ rentmeister.get_full_name }}
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:rentmeister_detail' rentmeister.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zu Details
</a>
<a href="{% url 'stiftung:verwaltungskosten_create' %}?rentmeister={{ rentmeister.pk }}" class="btn btn-success">
<i class="fas fa-plus me-1"></i>Neue Ausgabe
</a>
</div>
</div>
</div>
</div>
<!-- Statistiken -->
<div class="row mb-4">
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-secondary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-secondary text-uppercase mb-1">Gesamt</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.total_count|default:0 }}</div>
<div class="small text-success">€{{ stats.total_amount|default:0|floatformat:2 }}</div>
</div>
<div class="col-auto">
<i class="fas fa-file-invoice fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-warning shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Geplant</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.geplant_count|default:0 }}</div>
<div class="small text-warning">€{{ stats.geplant_amount|default:0|floatformat:2 }}</div>
</div>
<div class="col-auto">
<i class="fas fa-clock fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">In Bearbeitung</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.in_bearbeitung_count|default:0 }}</div>
<div class="small text-primary">€{{ stats.in_bearbeitung_amount|default:0|floatformat:2 }}</div>
</div>
<div class="col-auto">
<i class="fas fa-cogs fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Bezahlt</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.bezahlt_count|default:0 }}</div>
<div class="small text-success">€{{ stats.bezahlt_amount|default:0|floatformat:2 }}</div>
</div>
<div class="col-auto">
<i class="fas fa-check-circle fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<form method="post" id="expenseForm">
{% csrf_token %}
<!-- Geplante Ausgaben -->
{% if ausgaben_by_status.geplant.ausgaben %}
<div class="row mb-4">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-warning">
<i class="fas fa-clock me-2"></i>Geplante Ausgaben ({{ ausgaben_by_status.geplant.ausgaben.count }})
</h6>
<div>
<span class="badge bg-warning">€{{ ausgaben_by_status.geplant.total|floatformat:2 }}</span>
<button type="button" class="btn btn-sm btn-outline-warning ms-2" onclick="toggleSection('geplant')">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
<div class="card-body" id="section-geplant">
<div class="mb-3 d-flex justify-content-between align-items-center">
<div>
<button type="button" class="btn btn-sm btn-outline-primary" onclick="selectAll('geplant')">
<i class="fas fa-check-square me-1"></i>Alle auswählen
</button>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="deselectAll('geplant')">
<i class="fas fa-square me-1"></i>Abwählen
</button>
</div>
<button type="submit" name="export_pdf" class="btn btn-primary" onclick="return validateSelection()">
<i class="fas fa-file-pdf me-1"></i>Ausgewählte für Zahlung exportieren
</button>
</div>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th width="30">
<input type="checkbox" class="form-check-input" onchange="toggleAllInStatus('geplant', this.checked)">
</th>
<th>Datum</th>
<th>Bezeichnung</th>
<th>Kategorie</th>
<th>Betrag</th>
<th>Lieferant</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for ausgabe in ausgaben_by_status.geplant.ausgaben %}
<tr>
<td>
<input type="checkbox" name="selected_expenses" value="{{ ausgabe.pk }}"
class="form-check-input expense-checkbox status-geplant">
</td>
<td>{{ ausgabe.datum|date:"d.m.Y" }}</td>
<td>
<strong>{{ ausgabe.bezeichnung }}</strong>
{% if ausgabe.beschreibung %}
<br><small class="text-muted">{{ ausgabe.beschreibung|truncatechars:50 }}</small>
{% endif %}
</td>
<td>
<span class="badge bg-secondary">{{ ausgabe.get_kategorie_display }}</span>
</td>
<td class="text-end">
<strong>€{{ ausgabe.betrag|floatformat:2 }}</strong>
</td>
<td>{{ ausgabe.lieferant_firma|default:"-" }}</td>
<td>
<div class="btn-group btn-group-sm">
<a href="{% url 'stiftung:verwaltungskosten_edit' ausgabe.pk %}"
class="btn btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- In Bearbeitung -->
{% if ausgaben_by_status.in_bearbeitung.ausgaben %}
<div class="row mb-4">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-cogs me-2"></i>In Bearbeitung ({{ ausgaben_by_status.in_bearbeitung.ausgaben.count }})
</h6>
<div>
<span class="badge bg-primary">€{{ ausgaben_by_status.in_bearbeitung.total|floatformat:2 }}</span>
<button type="button" class="btn btn-sm btn-outline-primary ms-2" onclick="toggleSection('in_bearbeitung')">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
<div class="card-body" id="section-in_bearbeitung" style="display: none;">
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
Diese Ausgaben wurden bereits für die Zahlung exportiert und befinden sich in Bearbeitung.
</div>
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Datum</th>
<th>Bezeichnung</th>
<th>Kategorie</th>
<th>Betrag</th>
<th>Status</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for ausgabe in ausgaben_by_status.in_bearbeitung.ausgaben %}
<tr>
<td>{{ ausgabe.datum|date:"d.m.Y" }}</td>
<td>
<strong>{{ ausgabe.bezeichnung }}</strong>
{% if ausgabe.beschreibung %}
<br><small class="text-muted">{{ ausgabe.beschreibung|truncatechars:50 }}</small>
{% endif %}
</td>
<td>
<span class="badge bg-secondary">{{ ausgabe.get_kategorie_display }}</span>
</td>
<td class="text-end">
<strong>€{{ ausgabe.betrag|floatformat:2 }}</strong>
</td>
<td>
<span class="badge bg-primary">In Bearbeitung</span>
</td>
<td>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-outline-success"
onclick="markAsPaid('{{ ausgabe.pk }}')"
title="Als bezahlt markieren">
<i class="fas fa-check"></i>
</button>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Bezahlte Ausgaben -->
{% if ausgaben_by_status.bezahlt.ausgaben %}
<div class="row mb-4">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-success">
<i class="fas fa-check-circle me-2"></i>Bezahlte Ausgaben ({{ ausgaben_by_status.bezahlt.ausgaben.count }})
</h6>
<div>
<span class="badge bg-success">€{{ ausgaben_by_status.bezahlt.total|floatformat:2 }}</span>
<button type="button" class="btn btn-sm btn-outline-success ms-2" onclick="toggleSection('bezahlt')">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
<div class="card-body" id="section-bezahlt" style="display: none;">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Datum</th>
<th>Bezeichnung</th>
<th>Kategorie</th>
<th>Betrag</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{% for ausgabe in ausgaben_by_status.bezahlt.ausgaben %}
<tr>
<td>{{ ausgabe.datum|date:"d.m.Y" }}</td>
<td>
<strong>{{ ausgabe.bezeichnung }}</strong>
{% if ausgabe.beschreibung %}
<br><small class="text-muted">{{ ausgabe.beschreibung|truncatechars:50 }}</small>
{% endif %}
</td>
<td>
<span class="badge bg-secondary">{{ ausgabe.get_kategorie_display }}</span>
</td>
<td class="text-end">
<strong>€{{ ausgabe.betrag|floatformat:2 }}</strong>
</td>
<td>
<span class="badge bg-success">Bezahlt</span>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Keine Ausgaben -->
{% if not ausgaben_by_status.geplant.ausgaben and not ausgaben_by_status.in_bearbeitung.ausgaben and not ausgaben_by_status.bezahlt.ausgaben %}
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-body text-center py-5">
<i class="fas fa-file-invoice fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Noch keine Ausgaben vorhanden</h5>
<p class="text-muted">Legen Sie die erste Ausgabe für {{ rentmeister.get_full_name }} an.</p>
<a href="{% url 'stiftung:verwaltungskosten_create' %}?rentmeister={{ rentmeister.pk }}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Erste Ausgabe anlegen
</a>
</div>
</div>
</div>
</div>
{% endif %}
</form>
<script>
function toggleSection(statusId) {
const section = document.getElementById('section-' + statusId);
if (section.style.display === 'none') {
section.style.display = 'block';
} else {
section.style.display = 'none';
}
}
function selectAll(status) {
const checkboxes = document.querySelectorAll('.status-' + status);
checkboxes.forEach(cb => cb.checked = true);
}
function deselectAll(status) {
const checkboxes = document.querySelectorAll('.status-' + status);
checkboxes.forEach(cb => cb.checked = false);
}
function toggleAllInStatus(status, checked) {
const checkboxes = document.querySelectorAll('.status-' + status);
checkboxes.forEach(cb => cb.checked = checked);
}
function validateSelection() {
const selected = document.querySelectorAll('input[name="selected_expenses"]:checked');
if (selected.length === 0) {
alert('Bitte wählen Sie mindestens eine Ausgabe für den Export aus.');
return false;
}
const confirmed = confirm(`${selected.length} Ausgaben werden für die Zahlung exportiert und auf "In Bearbeitung" gesetzt. Fortfahren?`);
return confirmed;
}
function markAsPaid(expenseId) {
if (confirm('Diese Ausgabe als bezahlt markieren?')) {
// Create a form to mark as paid
const form = document.createElement('form');
form.method = 'POST';
form.action = '{% url "stiftung:mark_expense_paid" %}';
const csrfToken = document.createElement('input');
csrfToken.type = 'hidden';
csrfToken.name = 'csrfmiddlewaretoken';
csrfToken.value = document.querySelector('[name=csrfmiddlewaretoken]').value;
const expenseInput = document.createElement('input');
expenseInput.type = 'hidden';
expenseInput.name = 'expense_id';
expenseInput.value = expenseId;
form.appendChild(csrfToken);
form.appendChild(expenseInput);
document.body.appendChild(form);
form.submit();
}
}
// Show geplant section by default
document.addEventListener('DOMContentLoaded', function() {
const geplantSection = document.getElementById('section-geplant');
if (geplantSection) {
geplantSection.style.display = 'block';
}
});
</script>
{% endblock %}

View File

@@ -0,0 +1,372 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}{{ rentmeister.get_full_name }} - Rentmeister{% 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-user-tie me-2"></i>{{ rentmeister }}
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:rentmeister_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Liste
</a>
<a href="{% url 'stiftung:rentmeister_edit' rentmeister.pk %}" class="btn btn-outline-warning">
<i class="fas fa-edit me-1"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:verwaltungskosten_create' %}?rentmeister={{ rentmeister.pk }}" class="btn btn-success">
<i class="fas fa-plus me-1"></i>Neue Ausgabe
</a>
<a href="{% url 'stiftung:rentmeister_ausgaben' rentmeister.pk %}" class="btn btn-primary">
<i class="fas fa-file-invoice-dollar me-1"></i>Alle Ausgaben
</a>
</div>
</div>
</div>
</div>
<!-- Persönliche Informationen -->
<div class="row">
<div class="col-xl-4 col-lg-5">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-user me-2"></i>Persönliche Daten
</h6>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-sm-4"><strong>Name:</strong></div>
<div class="col-sm-8">{{ rentmeister.get_full_name }}</div>
</div>
{% if rentmeister.anrede %}
<div class="row mb-3">
<div class="col-sm-4"><strong>Anrede:</strong></div>
<div class="col-sm-8">{{ rentmeister.get_anrede_display }}</div>
</div>
{% endif %}
{% if rentmeister.titel %}
<div class="row mb-3">
<div class="col-sm-4"><strong>Titel:</strong></div>
<div class="col-sm-8">{{ rentmeister.titel }}</div>
</div>
{% endif %}
<div class="row mb-3">
<div class="col-sm-4"><strong>Im Amt seit:</strong></div>
<div class="col-sm-8">{{ rentmeister.seit_datum|date:"d.m.Y" }}</div>
</div>
{% if rentmeister.bis_datum %}
<div class="row mb-3">
<div class="col-sm-4"><strong>Im Amt bis:</strong></div>
<div class="col-sm-8">{{ rentmeister.bis_datum|date:"d.m.Y" }}</div>
</div>
{% endif %}
<div class="row mb-3">
<div class="col-sm-4"><strong>Status:</strong></div>
<div class="col-sm-8">
{% if rentmeister.aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-secondary">Inaktiv</span>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Kontaktdaten -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-address-book me-2"></i>Kontaktdaten
</h6>
</div>
<div class="card-body">
{% if rentmeister.email %}
<div class="row mb-3">
<div class="col-sm-4"><strong>E-Mail:</strong></div>
<div class="col-sm-8">
<a href="mailto:{{ rentmeister.email }}">{{ rentmeister.email }}</a>
</div>
</div>
{% endif %}
{% if rentmeister.telefon %}
<div class="row mb-3">
<div class="col-sm-4"><strong>Telefon:</strong></div>
<div class="col-sm-8">
<a href="tel:{{ rentmeister.telefon }}">{{ rentmeister.telefon }}</a>
</div>
</div>
{% endif %}
{% if rentmeister.mobil %}
<div class="row mb-3">
<div class="col-sm-4"><strong>Mobil:</strong></div>
<div class="col-sm-8">
<a href="tel:{{ rentmeister.mobil }}">{{ rentmeister.mobil }}</a>
</div>
</div>
{% endif %}
{% if rentmeister.get_address %}
<div class="row mb-3">
<div class="col-sm-4"><strong>Adresse:</strong></div>
<div class="col-sm-8">{{ rentmeister.get_address }}</div>
</div>
{% endif %}
</div>
</div>
<!-- Vergütung -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-euro-sign me-2"></i>Vergütung
</h6>
</div>
<div class="card-body">
{% if rentmeister.monatliche_verguetung %}
<div class="row mb-3">
<div class="col-sm-6"><strong>Monatlich:</strong></div>
<div class="col-sm-6">€{{ rentmeister.monatliche_verguetung|floatformat:2 }}</div>
</div>
{% endif %}
<div class="row mb-3">
<div class="col-sm-6"><strong>KM-Pauschale:</strong></div>
<div class="col-sm-6">€{{ rentmeister.km_pauschale|floatformat:2 }}/km</div>
</div>
{% if rentmeister.iban %}
<div class="row mb-3">
<div class="col-sm-4"><strong>IBAN:</strong></div>
<div class="col-sm-8"><code>{{ rentmeister.iban }}</code></div>
</div>
{% endif %}
{% if rentmeister.bank_name %}
<div class="row mb-3">
<div class="col-sm-4"><strong>Bank:</strong></div>
<div class="col-sm-8">{{ rentmeister.bank_name }}</div>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Ausgaben und Statistiken -->
<div class="col-xl-8 col-lg-7">
<!-- Statistiken -->
<div class="row">
<div class="col-md-3 mb-4">
<div class="card border-primary">
<div class="card-body text-center">
<i class="fas fa-file-invoice-dollar fa-2x text-primary mb-2"></i>
<h4>{{ stats.anzahl_ausgaben }}</h4>
<small class="text-muted">Ausgaben gesamt</small>
</div>
</div>
</div>
<div class="col-md-3 mb-4">
<div class="card border-success">
<div class="card-body text-center">
<i class="fas fa-euro-sign fa-2x text-success mb-2"></i>
<h4>€{{ stats.gesamt_ausgaben|floatformat:0 }}</h4>
<small class="text-muted">Summe gesamt</small>
</div>
</div>
</div>
<div class="col-md-3 mb-4">
<div class="card border-info">
<div class="card-body text-center">
<i class="fas fa-calendar-alt fa-2x text-info mb-2"></i>
<h4>€{{ stats.jahr_ausgaben|floatformat:0 }}</h4>
<small class="text-muted">Dieses Jahr</small>
</div>
</div>
</div>
<div class="col-md-3 mb-4">
<div class="card border-warning">
<div class="card-body text-center">
<i class="fas fa-clock fa-2x text-warning mb-2"></i>
<h4>{{ stats.offene_ausgaben }}</h4>
<small class="text-muted">Offen</small>
</div>
</div>
</div>
</div>
<!-- Kategorie-Aufschlüsselung -->
{% if kategorie_stats %}
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-chart-pie me-2"></i>Ausgaben nach Kategorien
</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-sm">
<thead>
<tr>
<th>Kategorie</th>
<th class="text-center">Anzahl</th>
<th class="text-end">Summe</th>
</tr>
</thead>
<tbody>
{% for stat in kategorie_stats %}
<tr>
<td>{{ stat.kategorie|capfirst }}</td>
<td class="text-center">{{ stat.anzahl }}</td>
<td class="text-end">€{{ stat.summe|floatformat:2 }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endif %}
<!-- Aktuelle Ausgaben -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-history me-2"></i>Aktuelle Ausgaben (letzte 30 Tage)
</h6>
<a href="{% url 'stiftung:rentmeister_ausgaben' rentmeister.pk %}" class="btn btn-sm btn-outline-primary">
Alle Ausgaben
</a>
</div>
<div class="card-body">
{% if aktuelle_ausgaben %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Datum</th>
<th>Bezeichnung</th>
<th>Kategorie</th>
<th>Status</th>
<th class="text-end">Betrag</th>
</tr>
</thead>
<tbody>
{% for ausgabe in aktuelle_ausgaben %}
<tr>
<td>{{ ausgabe.datum|date:"d.m.Y" }}</td>
<td>
<strong>{{ ausgabe.bezeichnung }}</strong>
{% if ausgabe.kategorie == 'fahrtkosten' and ausgabe.km_anzahl %}
<br><small class="text-info">
<i class="fas fa-route me-1"></i>{{ ausgabe.km_anzahl }} km
</small>
{% endif %}
</td>
<td>
<span class="badge bg-info">{{ ausgabe.get_kategorie_display }}</span>
</td>
<td>
<span class="badge bg-{{ ausgabe.get_status_color }}">{{ ausgabe.get_status_display }}</span>
</td>
<td class="text-end">
<strong>€{{ ausgabe.betrag|floatformat:2 }}</strong>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<p class="text-muted">Keine Ausgaben in den letzten 30 Tagen.</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Verknüpfte Dokumente -->
<div class="row mb-4">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-file-alt me-2"></i>Verknüpfte Dokumente
{% if verknuepfte_dokumente %}
<span class="badge bg-primary ms-2">{{ verknuepfte_dokumente.count }}</span>
{% endif %}
</h6>
<a href="/dokumente/verwaltung/" class="btn btn-outline-primary btn-sm">
<i class="fas fa-link me-1"></i>Dokumentenverwaltung
</a>
</div>
<div class="card-body">
{% if verknuepfte_dokumente %}
<div class="list-group list-group-flush">
{% for dokument in verknuepfte_dokumente %}
<div class="list-group-item d-flex justify-content-between align-items-start">
<div class="ms-2 me-auto">
<div class="fw-bold">
<i class="fas fa-file-pdf text-danger me-1"></i>
{{ dokument.titel }}
</div>
<small class="text-muted">
Kontext: {{ dokument.get_kontext_display }}
{% if dokument.beschreibung %}
• {{ dokument.beschreibung|truncatechars:100 }}
{% endif %}
</small>
</div>
<div class="d-flex gap-2">
<a href="/api/paperless/documents/{{ dokument.paperless_document_id }}/"
class="btn btn-outline-primary btn-sm" target="_blank" title="In Paperless öffnen">
<i class="fas fa-external-link-alt"></i>
</a>
</div>
</div>
{% endfor %}
</div>
{% if verknuepfte_dokumente.count == 10 %}
<div class="text-center mt-3">
<small class="text-muted">
<i class="fas fa-info-circle me-1"></i>
Es werden nur die neuesten 10 Dokumente angezeigt.
<a href="/dokumente/verwaltung/" class="text-decoration-none">Alle Dokumente anzeigen</a>
</small>
</div>
{% endif %}
{% else %}
<div class="text-center py-4">
<i class="fas fa-file-alt fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Dokumente verknüpft</h5>
<p class="text-muted">
Verknüpfen Sie Dokumente über die
<a href="/dokumente/verwaltung/" class="text-decoration-none">Dokumentenverwaltung</a>.
</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Notizen -->
{% if rentmeister.notizen %}
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-sticky-note me-2"></i>Notizen
</h6>
</div>
<div class="card-body">
<p>{{ rentmeister.notizen|linebreaks }}</p>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,310 @@
{% extends 'base.html' %}
{% block title %}{{ title }} - 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-user-tie me-2"></i>{{ title }}
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:rentmeister_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Liste
</a>
{% if rentmeister %}
<a href="{% url 'stiftung:rentmeister_detail' rentmeister.pk %}" class="btn btn-outline-info">
<i class="fas fa-eye me-1"></i>Details ansehen
</a>
{% endif %}
</div>
</div>
</div>
</div>
<form method="post" novalidate>
{% csrf_token %}
<div class="row">
<!-- Persönliche Daten -->
<div class="col-xl-6 col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-user me-2"></i>Persönliche Daten
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4 mb-3">
<label for="{{ form.anrede.id_for_label }}" class="form-label">{{ form.anrede.label }}</label>
{{ form.anrede }}
{% if form.anrede.errors %}
<div class="text-danger small">{{ form.anrede.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-4 mb-3">
<label for="{{ form.vorname.id_for_label }}" class="form-label">{{ form.vorname.label }}</label>
{{ form.vorname }}
{% if form.vorname.errors %}
<div class="text-danger small">{{ form.vorname.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-4 mb-3">
<label for="{{ form.nachname.id_for_label }}" class="form-label">{{ form.nachname.label }}</label>
{{ form.nachname }}
{% if form.nachname.errors %}
<div class="text-danger small">{{ form.nachname.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="mb-3">
<label for="{{ form.titel.id_for_label }}" class="form-label">{{ form.titel.label }}</label>
{{ form.titel }}
{% if form.titel.errors %}
<div class="text-danger small">{{ form.titel.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
<!-- Kontaktdaten -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-address-book me-2"></i>Kontaktdaten
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="{{ form.email.id_for_label }}" class="form-label">{{ form.email.label }}</label>
{{ form.email }}
{% if form.email.errors %}
<div class="text-danger small">{{ form.email.errors.0 }}</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.telefon.id_for_label }}" class="form-label">{{ form.telefon.label }}</label>
{{ form.telefon }}
{% if form.telefon.errors %}
<div class="text-danger small">{{ form.telefon.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.mobil.id_for_label }}" class="form-label">{{ form.mobil.label }}</label>
{{ form.mobil }}
{% if form.mobil.errors %}
<div class="text-danger small">{{ form.mobil.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="mb-3">
<label for="{{ form.strasse.id_for_label }}" class="form-label">{{ form.strasse.label }}</label>
{{ form.strasse }}
{% if form.strasse.errors %}
<div class="text-danger small">{{ form.strasse.errors.0 }}</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label for="{{ form.plz.id_for_label }}" class="form-label">{{ form.plz.label }}</label>
{{ form.plz }}
{% if form.plz.errors %}
<div class="text-danger small">{{ form.plz.errors.0 }}</div>
{% endif %}
{% if form.plz.help_text %}
<div class="form-text">{{ form.plz.help_text }}</div>
{% endif %}
</div>
<div class="col-md-8 mb-3">
<label for="{{ form.ort.id_for_label }}" class="form-label">{{ form.ort.label }}</label>
{{ form.ort }}
{% if form.ort.errors %}
<div class="text-danger small">{{ form.ort.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Stiftungsdaten und Vergütung -->
<div class="col-xl-6 col-lg-6">
<!-- Stiftungsdaten -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-calendar-alt me-2"></i>Stiftungsdaten
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.seit_datum.id_for_label }}" class="form-label">{{ form.seit_datum.label }}</label>
{{ form.seit_datum }}
{% if form.seit_datum.errors %}
<div class="text-danger small">{{ form.seit_datum.errors.0 }}</div>
{% endif %}
{% if form.seit_datum.help_text %}
<div class="form-text">{{ form.seit_datum.help_text }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.bis_datum.id_for_label }}" class="form-label">{{ form.bis_datum.label }}</label>
{{ form.bis_datum }}
{% if form.bis_datum.errors %}
<div class="text-danger small">{{ form.bis_datum.errors.0 }}</div>
{% endif %}
{% if form.bis_datum.help_text %}
<div class="form-text">{{ form.bis_datum.help_text }}</div>
{% endif %}
</div>
</div>
<div class="form-check mb-3">
{{ form.aktiv }}
<label class="form-check-label" for="{{ form.aktiv.id_for_label }}">
{{ form.aktiv.label }}
</label>
{% if form.aktiv.errors %}
<div class="text-danger small">{{ form.aktiv.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
<!-- Vergütung -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-euro-sign me-2"></i>Vergütung
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.monatliche_verguetung.id_for_label }}" class="form-label">{{ form.monatliche_verguetung.label }}</label>
<div class="input-group">
{{ form.monatliche_verguetung }}
<span class="input-group-text"></span>
</div>
{% if form.monatliche_verguetung.errors %}
<div class="text-danger small">{{ form.monatliche_verguetung.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.km_pauschale.id_for_label }}" class="form-label">{{ form.km_pauschale.label }}</label>
<div class="input-group">
{{ form.km_pauschale }}
<span class="input-group-text">€/km</span>
</div>
{% if form.km_pauschale.errors %}
<div class="text-danger small">{{ form.km_pauschale.errors.0 }}</div>
{% endif %}
{% if form.km_pauschale.help_text %}
<div class="form-text">{{ form.km_pauschale.help_text }}</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Bankdaten -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-university me-2"></i>Bankdaten
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="{{ form.iban.id_for_label }}" class="form-label">{{ form.iban.label }}</label>
{{ form.iban }}
{% if form.iban.errors %}
<div class="text-danger small">{{ form.iban.errors.0 }}</div>
{% endif %}
{% if form.iban.help_text %}
<div class="form-text">{{ form.iban.help_text }}</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label for="{{ form.bic.id_for_label }}" class="form-label">{{ form.bic.label }}</label>
{{ form.bic }}
{% if form.bic.errors %}
<div class="text-danger small">{{ form.bic.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-8 mb-3">
<label for="{{ form.bank_name.id_for_label }}" class="form-label">{{ form.bank_name.label }}</label>
{{ form.bank_name }}
{% if form.bank_name.errors %}
<div class="text-danger small">{{ form.bank_name.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Notizen -->
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-sticky-note me-2"></i>Notizen
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="{{ form.notizen.id_for_label }}" class="form-label">{{ form.notizen.label }}</label>
{{ form.notizen }}
{% if form.notizen.errors %}
<div class="text-danger small">{{ form.notizen.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
<!-- Form Errors -->
{% if form.non_field_errors %}
<div class="row">
<div class="col-12">
<div class="alert alert-danger">
<strong>Fehler:</strong>
{{ form.non_field_errors }}
</div>
</div>
</div>
{% endif %}
<!-- Submit Buttons -->
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-body text-end">
<a href="{% url 'stiftung:rentmeister_list' %}" class="btn btn-secondary me-2">
<i class="fas fa-times me-1"></i>Abbrechen
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-1"></i>{{ submit_text }}
</button>
</div>
</div>
</div>
</div>
</form>
{% endblock %}

View File

@@ -0,0 +1,224 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Rentmeister - 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-user-tie me-2"></i>Rentmeister
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:geschaeftsfuehrung' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Übersicht
</a>
<a href="{% url 'stiftung:rentmeister_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Neuen Rentmeister anlegen
</a>
</div>
</div>
</div>
</div>
<!-- Aktive Rentmeister -->
{% if aktive_rentmeister %}
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-user-check me-2"></i>Aktive Rentmeister ({{ aktive_rentmeister.count }})
</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Kontakt</th>
<th>Adresse</th>
<th>Im Amt seit</th>
<th>Vergütung</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for rentmeister in aktive_rentmeister %}
<tr>
<td>
<strong>{{ rentmeister }}</strong>
{% if rentmeister.titel %}
<br><small class="text-muted">{{ rentmeister.titel }}</small>
{% endif %}
</td>
<td>
{% if rentmeister.email %}
<i class="fas fa-envelope me-1"></i>{{ rentmeister.email }}<br>
{% endif %}
{% if rentmeister.telefon %}
<i class="fas fa-phone me-1"></i>{{ rentmeister.telefon }}<br>
{% endif %}
{% if rentmeister.mobil %}
<i class="fas fa-mobile-alt me-1"></i>{{ rentmeister.mobil }}
{% endif %}
</td>
<td>
{% if rentmeister.get_address %}
{{ rentmeister.get_address }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>{{ rentmeister.seit_datum|date:"d.m.Y" }}</td>
<td>
{% if rentmeister.monatliche_verguetung %}
€{{ rentmeister.monatliche_verguetung|floatformat:2 }}/Monat<br>
{% endif %}
<small class="text-muted">KM: €{{ rentmeister.km_pauschale|floatformat:2 }}/km</small>
</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<a href="{% url 'stiftung:rentmeister_detail' rentmeister.pk %}" class="btn btn-outline-primary" title="Details ansehen">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:rentmeister_edit' rentmeister.pk %}" class="btn btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:rentmeister_ausgaben' rentmeister.pk %}" class="btn btn-outline-info" title="Ausgaben">
<i class="fas fa-file-invoice-dollar"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Ehemalige Rentmeister -->
{% if ehemalige_rentmeister %}
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-secondary">
<i class="fas fa-user-times me-2"></i>Ehemalige Rentmeister ({{ ehemalige_rentmeister.count }})
</h6>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Zeitraum</th>
<th>Kontakt</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for rentmeister in ehemalige_rentmeister %}
<tr class="table-light">
<td>
<strong>{{ rentmeister }}</strong>
{% if rentmeister.titel %}
<br><small class="text-muted">{{ rentmeister.titel }}</small>
{% endif %}
</td>
<td>
{{ rentmeister.seit_datum|date:"d.m.Y" }} -
{% if rentmeister.bis_datum %}
{{ rentmeister.bis_datum|date:"d.m.Y" }}
{% else %}
<span class="text-muted">offen</span>
{% endif %}
</td>
<td>
{% if rentmeister.email %}
<i class="fas fa-envelope me-1"></i>{{ rentmeister.email }}
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<a href="{% url 'stiftung:rentmeister_detail' rentmeister.pk %}" class="btn btn-outline-secondary" title="Details ansehen">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:rentmeister_ausgaben' rentmeister.pk %}" class="btn btn-outline-info" title="Ausgaben">
<i class="fas fa-file-invoice-dollar"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Wenn keine Rentmeister vorhanden -->
{% if not aktive_rentmeister and not ehemalige_rentmeister %}
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-body text-center py-5">
<i class="fas fa-user-tie fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Noch keine Rentmeister angelegt</h5>
<p class="text-muted">Legen Sie die ersten Rentmeister der Stiftung an, um Ausgaben und Abrechnungen zu verwalten.</p>
<a href="{% url 'stiftung:rentmeister_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Ersten Rentmeister anlegen
</a>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Statistiken -->
{% if total_count > 0 %}
<div class="row">
<div class="col-md-4">
<div class="card border-primary">
<div class="card-body text-center">
<i class="fas fa-user-tie fa-2x text-primary mb-2"></i>
<h4>{{ total_count }}</h4>
<small class="text-muted">Gesamt Rentmeister</small>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-success">
<div class="card-body text-center">
<i class="fas fa-user-check fa-2x text-success mb-2"></i>
<h4>{{ aktive_rentmeister.count }}</h4>
<small class="text-muted">Aktive Rentmeister</small>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card border-secondary">
<div class="card-body text-center">
<i class="fas fa-user-times fa-2x text-secondary mb-2"></i>
<h4>{{ ehemalige_rentmeister.count }}</h4>
<small class="text-muted">Ehemalige Rentmeister</small>
</div>
</div>
</div>
</div>
{% endif %}
{% endblock %}

View File

@@ -0,0 +1,15 @@
{% extends 'base.html' %}
{% block title %}Unterstützung löschen{% endblock %}
{% block content %}
<div class="card shadow">
<div class="card-body">
<h5>Möchten Sie diese Unterstützung wirklich löschen?</h5>
<p><strong>{{ obj.destinataer.get_full_name }}</strong>, €{{ obj.betrag|floatformat:2 }}, fällig am {{ obj.faellig_am|date:"d.m.Y" }}</p>
<form method="post">{% csrf_token %}
<a href="{% url 'stiftung:unterstuetzungen_list' %}" class="btn btn-outline-secondary">Abbrechen</a>
<button type="submit" class="btn btn-danger">Löschen</button>
</form>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,46 @@
{% extends 'base.html' %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-8">
<div class="card shadow">
<div class="card-header bg-primary text-white"><h5 class="mb-0">{{ title }}</h5></div>
<div class="card-body">
<form method="post">{% csrf_token %}
<div class="mb-3">
<label class="form-label" for="{{ form.destinataer.id_for_label }}">{{ form.destinataer.label }}</label>
{{ form.destinataer }}
</div>
<div class="mb-3">
<label class="form-label" for="{{ form.konto.id_for_label }}">{{ form.konto.label }}</label>
{{ form.konto }}
</div>
<div class="row">
<div class="col-md-4 mb-3">
<label class="form-label" for="{{ form.betrag.id_for_label }}">{{ form.betrag.label }}</label>
{{ form.betrag }}
</div>
<div class="col-md-4 mb-3">
<label class="form-label" for="{{ form.faellig_am.id_for_label }}">{{ form.faellig_am.label }}</label>
{{ form.faellig_am }}
</div>
<div class="col-md-4 mb-3">
<label class="form-label" for="{{ form.status.id_for_label }}">{{ form.status.label }}</label>
{{ form.status }}
</div>
</div>
<div class="mb-3">
<label class="form-label" for="{{ form.beschreibung.id_for_label }}">{{ form.beschreibung.label }}</label>
{{ form.beschreibung }}
</div>
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:unterstuetzungen_list' %}" class="btn btn-outline-secondary">Abbrechen</a>
<button class="btn btn-primary" type="submit">Speichern</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,55 @@
{% extends 'base.html' %}
{% block title %}Destinatärunterstützungen - Administration{% endblock %}
{% block content %}
<div class="d-flex justify-content-between align-items-center mb-4">
<h1 class="h3"><i class="fas fa-hand-holding-usd me-2"></i>Destinatärunterstützungen</h1>
<div class="btn-group">
<a class="btn btn-outline-primary" href="?format=csv"><i class="fas fa-file-csv me-2"></i>CSV exportieren</a>
<a class="btn btn-outline-danger" href="?format=pdf"><i class="fas fa-file-pdf me-2"></i>PDF exportieren</a>
</div>
</div>
<div class="card shadow">
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover">
<thead class="table-light">
<tr>
<th>Destinatär</th>
<th>Bank</th>
<th>IBAN</th>
<th>Betrag</th>
<th>Konto</th>
<th>Fällig am</th>
<th>Status</th>
<th>Beschreibung</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for u in unterstuetzungen %}
<tr>
<td>{{ u.destinataer.get_full_name }}</td>
<td>{{ u.konto.bank_name }}</td>
<td>{{ u.konto.iban }}</td>
<td>€{{ u.betrag|floatformat:2 }}</td>
<td>{{ u.konto }}</td>
<td>{{ u.faellig_am|date:"d.m.Y" }}</td>
<td><span class="badge bg-secondary">{{ u.get_status_display }}</span></td>
<td>{{ u.beschreibung }}</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<a href="{% url 'stiftung:unterstuetzung_edit' pk=u.pk %}" class="btn btn-outline-warning"><i class="fas fa-edit"></i></a>
<a href="{% url 'stiftung:unterstuetzung_delete' pk=u.pk %}" class="btn btn-outline-danger"><i class="fas fa-trash"></i></a>
</div>
</td>
</tr>
{% empty %}
<tr><td colspan="6" class="text-center text-muted">Keine Einträge</td></tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,31 @@
<!doctype html>
<html><head><meta charset="utf-8"><style>
body{font-family:DejaVu Sans, Arial, sans-serif;font-size:12px}
table{width:100%;border-collapse:collapse}
th,td{border:1px solid #999;padding:6px;text-align:left}
h1{font-size:18px;margin-bottom:10px}
</style></head>
<body>
<h1>Destinatärunterstützungen geplante Zahlungen</h1>
<table>
<thead>
<tr>
<th>Destinatär</th><th>Bank</th><th>IBAN</th><th>Betrag</th><th>Fällig am</th><th>Status</th><th>Beschreibung</th>
</tr>
</thead>
<tbody>
{% for u in unterstuetzungen %}
<tr>
<td>{{ u.destinataer.get_full_name }}</td>
<td>{{ u.konto.bank_name }}</td>
<td>{{ u.konto.iban }}</td>
<td>€{{ u.betrag|floatformat:2 }}</td>
<td>{{ u.faellig_am|date:"d.m.Y" }}</td>
<td>{{ u.get_status_display }}</td>
<td>{{ u.beschreibung }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body></html>

View File

@@ -0,0 +1,105 @@
{% extends 'base.html' %}
{% block title %}{{ title }} - Benutzerverwaltung - 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-key me-2"></i>{{ title }}
</h1>
<a href="{% url 'stiftung:user_detail' user_obj.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zum Benutzer
</a>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-lg-6">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-lock me-2"></i>Neues Passwort festlegen
</h6>
</div>
<div class="card-body">
{% if form.errors %}
<div class="alert alert-danger">
<h6><i class="fas fa-exclamation-triangle me-2"></i>Fehler beim Speichern:</h6>
{% for field, errors in form.errors.items %}
{% for error in errors %}
<div>{{ error }}</div>
{% endfor %}
{% endfor %}
</div>
{% endif %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
<strong>Hinweis:</strong> Das neue Passwort wird sofort wirksam. Der Benutzer wird beim nächsten Login das neue Passwort verwenden müssen.
</div>
<form method="post">
{% csrf_token %}
<div class="form-group mb-3">
<label for="{{ form.new_password1.id_for_label }}" class="form-label">
{{ form.new_password1.label }}
<span class="text-danger">*</span>
</label>
{{ form.new_password1 }}
{% if form.new_password1.help_text %}
<div class="form-text">{{ form.new_password1.help_text }}</div>
{% endif %}
</div>
<div class="form-group mb-3">
<label for="{{ form.new_password2.id_for_label }}" class="form-label">
{{ form.new_password2.label }}
<span class="text-danger">*</span>
</label>
{{ form.new_password2 }}
{% if form.new_password2.help_text %}
<div class="form-text">{{ form.new_password2.help_text }}</div>
{% endif %}
</div>
<hr>
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:user_detail' user_obj.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Abbrechen
</a>
<button type="submit" class="btn btn-warning">
<i class="fas fa-key me-1"></i>Passwort ändern
</button>
</div>
</form>
</div>
</div>
<!-- Passwort-Sicherheitshinweise -->
<div class="card shadow mt-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-shield-alt me-2"></i>Passwort-Sicherheit
</h6>
</div>
<div class="card-body">
<h6>Richtlinien für sichere Passwörter:</h6>
<ul class="list-unstyled">
<li><i class="fas fa-check text-success me-2"></i>Mindestens 8 Zeichen lang</li>
<li><i class="fas fa-check text-success me-2"></i>Kombination aus Groß- und Kleinbuchstaben</li>
<li><i class="fas fa-check text-success me-2"></i>Mindestens eine Zahl</li>
<li><i class="fas fa-check text-success me-2"></i>Mindestens ein Sonderzeichen</li>
<li><i class="fas fa-check text-success me-2"></i>Keine persönlichen Informationen</li>
<li><i class="fas fa-check text-success me-2"></i>Nicht in anderen Systemen verwendet</li>
</ul>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,160 @@
{% extends 'base.html' %}
{% block title %}{{ title }} - Benutzerverwaltung - 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-trash me-2 text-danger"></i>{{ title }}
</h1>
<a href="{% url 'stiftung:user_detail' user_obj.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zum Benutzer
</a>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card shadow border-danger">
<div class="card-header bg-danger text-white">
<h6 class="m-0 font-weight-bold">
<i class="fas fa-exclamation-triangle me-2"></i>Benutzer löschen
</h6>
</div>
<div class="card-body">
<div class="alert alert-danger">
<h5><i class="fas fa-exclamation-triangle me-2"></i>Warnung!</h5>
<p class="mb-0">
Sie sind dabei, den Benutzer <strong>"{{ user_obj.username }}"</strong> permanent zu löschen.
Diese Aktion kann nicht rückgängig gemacht werden.
</p>
</div>
<!-- Benutzerinformationen -->
<div class="card mb-4">
<div class="card-header">
<h6 class="mb-0">Benutzerinformationen</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless table-sm">
<tr>
<td class="fw-bold">Benutzername:</td>
<td>{{ user_obj.username }}</td>
</tr>
<tr>
<td class="fw-bold">E-Mail:</td>
<td>{{ user_obj.email|default:"Nicht angegeben" }}</td>
</tr>
<tr>
<td class="fw-bold">Name:</td>
<td>
{% if user_obj.first_name or user_obj.last_name %}
{{ user_obj.first_name }} {{ user_obj.last_name }}
{% else %}
Nicht angegeben
{% endif %}
</td>
</tr>
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless table-sm">
<tr>
<td class="fw-bold">Status:</td>
<td>
{% if user_obj.is_active %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-danger">Inaktiv</span>
{% endif %}
{% if user_obj.is_staff %}
<span class="badge bg-warning ms-1">Staff</span>
{% endif %}
{% if user_obj.is_superuser %}
<span class="badge bg-danger ms-1">Superuser</span>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Letzte Anmeldung:</td>
<td>
{% if user_obj.last_login %}
{{ user_obj.last_login|date:"d.m.Y H:i" }}
{% else %}
Nie angemeldet
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Mitglied seit:</td>
<td>{{ user_obj.date_joined|date:"d.m.Y H:i" }}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!-- Auswirkungen der Löschung -->
<div class="card mb-4">
<div class="card-header bg-warning text-dark">
<h6 class="mb-0"><i class="fas fa-info-circle me-2"></i>Auswirkungen der Löschung</h6>
</div>
<div class="card-body">
<ul class="mb-0">
<li>Der Benutzer kann sich nicht mehr anmelden</li>
<li>Alle Berechtigungen werden entfernt</li>
<li>Audit-Log-Einträge bleiben zur Nachverfolgung erhalten</li>
<li>Verknüpfte Daten (z.B. erstellte Einträge) bleiben bestehen</li>
<li>E-Mail-Adresse und Benutzername werden für neue Benutzer wieder verfügbar</li>
</ul>
</div>
</div>
<!-- Bestätigung -->
<form method="post">
{% csrf_token %}
<div class="alert alert-warning">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="confirmDeletion" required>
<label class="form-check-label" for="confirmDeletion">
<strong>Ich bestätige, dass ich den Benutzer "{{ user_obj.username }}" permanent löschen möchte.</strong>
</label>
</div>
</div>
<hr>
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:user_detail' user_obj.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Abbrechen
</a>
<button type="submit" class="btn btn-danger" id="deleteButton" disabled>
<i class="fas fa-trash me-1"></i>Benutzer endgültig löschen
</button>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
document.getElementById('confirmDeletion').addEventListener('change', function() {
document.getElementById('deleteButton').disabled = !this.checked;
});
// Additional confirmation on form submission
document.querySelector('form').addEventListener('submit', function(e) {
if (!confirm('Sind Sie absolut sicher? Diese Aktion kann nicht rückgängig gemacht werden!')) {
e.preventDefault();
}
});
</script>
{% endblock %}

View File

@@ -0,0 +1,227 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}{{ user_obj.username }} - Benutzerverwaltung - 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-user me-2"></i>{{ user_obj.username }}
{% if user_obj.is_superuser %}
<span class="badge bg-danger ms-2">Superuser</span>
{% endif %}
{% if user_obj.is_staff %}
<span class="badge bg-warning ms-2">Staff</span>
{% endif %}
{% if not user_obj.is_active %}
<span class="badge bg-danger ms-2">Inaktiv</span>
{% endif %}
</h1>
<div>
<a href="{% url 'stiftung:user_edit' user_obj.pk %}" class="btn btn-primary">
<i class="fas fa-edit me-1"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:user_management' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Übersicht
</a>
</div>
</div>
</div>
</div>
<div class="row">
<!-- Benutzerinformationen -->
<div class="col-lg-8">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-info-circle me-2"></i>Benutzerinformationen
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td class="fw-bold">Benutzername:</td>
<td>{{ user_obj.username }}</td>
</tr>
<tr>
<td class="fw-bold">E-Mail:</td>
<td>
{% if user_obj.email %}
<a href="mailto:{{ user_obj.email }}">{{ user_obj.email }}</a>
{% else %}
<span class="text-muted">Keine E-Mail angegeben</span>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Vollständiger Name:</td>
<td>
{% if user_obj.first_name or user_obj.last_name %}
{{ user_obj.first_name }} {{ user_obj.last_name }}
{% else %}
<span class="text-muted">Kein Name angegeben</span>
{% endif %}
</td>
</tr>
</table>
</div>
<div class="col-md-6">
<table class="table table-borderless">
<tr>
<td class="fw-bold">Status:</td>
<td>
{% if user_obj.is_active %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-danger">Inaktiv</span>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Letzte Anmeldung:</td>
<td>
{% if user_obj.last_login %}
{{ user_obj.last_login|date:"d.m.Y H:i" }}
<br><small class="text-muted">{{ user_obj.last_login|naturaltime }}</small>
{% else %}
<span class="text-muted">Nie angemeldet</span>
{% endif %}
</td>
</tr>
<tr>
<td class="fw-bold">Mitglied seit:</td>
<td>
{{ user_obj.date_joined|date:"d.m.Y H:i" }}
<br><small class="text-muted">{{ user_obj.date_joined|naturaltime }}</small>
</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<!-- Berechtigungen -->
<div class="card shadow mb-4">
<div class="card-header py-3 d-flex justify-content-between align-items-center">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-shield-alt me-2"></i>Berechtigungen
{% if stiftung_permissions %}
<span class="badge bg-primary ms-2">{{ stiftung_permissions|length }}</span>
{% endif %}
</h6>
<a href="{% url 'stiftung:user_permissions' user_obj.pk %}" class="btn btn-outline-primary btn-sm">
<i class="fas fa-edit me-1"></i>Berechtigungen verwalten
</a>
</div>
<div class="card-body">
{% if stiftung_permissions %}
<div class="row">
{% for permission in stiftung_permissions %}
<div class="col-md-6 mb-2">
<div class="d-flex align-items-center">
<i class="fas fa-check-circle text-success me-2"></i>
<span>{{ permission|slice:"9:" }}</span>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-shield-alt fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Berechtigungen zugewiesen</h5>
<p class="text-muted">Diesem Benutzer wurden noch keine Berechtigungen zugewiesen.</p>
<a href="{% url 'stiftung:user_permissions' user_obj.pk %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Berechtigungen zuweisen
</a>
</div>
{% endif %}
</div>
</div>
<!-- Aktivitätsverlauf -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-history me-2"></i>Letzte Aktivitäten
{% if recent_activity %}
<span class="badge bg-primary ms-2">{{ recent_activity|length }}</span>
{% endif %}
</h6>
</div>
<div class="card-body">
{% if recent_activity %}
<div class="timeline">
{% for activity in recent_activity %}
<div class="d-flex mb-3">
<div class="flex-shrink-0">
<div class="bg-{% if activity.action == 'create' %}success{% elif activity.action == 'update' %}warning{% elif activity.action == 'delete' %}danger{% elif activity.action == 'login' %}info{% else %}secondary{% endif %} rounded-circle d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
<i class="fas fa-{% if activity.action == 'create' %}plus{% elif activity.action == 'update' %}edit{% elif activity.action == 'delete' %}trash{% elif activity.action == 'login' %}sign-in-alt{% elif activity.action == 'logout' %}sign-out-alt{% else %}circle{% endif %} text-white"></i>
</div>
</div>
<div class="flex-grow-1 ms-3">
<div class="fw-bold">{{ activity.get_action_display }}</div>
<div class="text-muted small">{{ activity.description }}</div>
<div class="text-muted small">
<i class="fas fa-clock me-1"></i>{{ activity.timestamp|naturaltime }}
{% if activity.ip_address %}
<i class="fas fa-map-marker-alt me-1"></i>{{ activity.ip_address }}
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-history fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Aktivitäten</h5>
<p class="text-muted">Für diesen Benutzer sind noch keine Aktivitäten aufgezeichnet.</p>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Aktionen -->
<div class="col-lg-4">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-tools me-2"></i>Aktionen
</h6>
</div>
<div class="card-body">
<div class="d-grid gap-2">
<a href="{% url 'stiftung:user_edit' user_obj.pk %}" class="btn btn-outline-primary">
<i class="fas fa-edit me-2"></i>Benutzer bearbeiten
</a>
<a href="{% url 'stiftung:user_change_password' user_obj.pk %}" class="btn btn-outline-warning">
<i class="fas fa-key me-2"></i>Passwort ändern
</a>
<a href="{% url 'stiftung:user_permissions' user_obj.pk %}" class="btn btn-outline-info">
<i class="fas fa-shield-alt me-2"></i>Berechtigungen verwalten
</a>
<hr>
{% if user_obj != request.user %}
<a href="{% url 'stiftung:user_delete' user_obj.pk %}" class="btn btn-outline-danger" onclick="return confirm('Sind Sie sicher, dass Sie diesen Benutzer löschen möchten?')">
<i class="fas fa-trash me-2"></i>Benutzer löschen
</a>
{% else %}
<button class="btn btn-outline-danger" disabled title="Sie können sich nicht selbst löschen">
<i class="fas fa-trash me-2"></i>Benutzer löschen
</button>
{% endif %}
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,213 @@
{% extends 'base.html' %}
{% block title %}{{ title }} - Benutzerverwaltung - 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-user-edit me-2"></i>{{ title }}
</h1>
<a href="{% url 'stiftung:user_management' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Übersicht
</a>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-user me-2"></i>Benutzerdaten
</h6>
</div>
<div class="card-body">
{% if form.errors %}
<div class="alert alert-danger">
<h6><i class="fas fa-exclamation-triangle me-2"></i>Fehler beim Speichern:</h6>
{% for field, errors in form.errors.items %}
{% for error in errors %}
<div>{{ error }}</div>
{% endfor %}
{% endfor %}
</div>
{% endif %}
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-md-6">
<div class="form-group mb-3">
<label for="{{ form.username.id_for_label }}" class="form-label">
{{ form.username.label }}
<span class="text-danger">*</span>
</label>
{{ form.username }}
{% if form.username.help_text %}
<div class="form-text">{{ form.username.help_text }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="form-group mb-3">
<label for="{{ form.email.id_for_label }}" class="form-label">
{{ form.email.label }}
<span class="text-danger">*</span>
</label>
{{ form.email }}
{% if form.email.help_text %}
<div class="form-text">{{ form.email.help_text }}</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group mb-3">
<label for="{{ form.first_name.id_for_label }}" class="form-label">{{ form.first_name.label }}</label>
{{ form.first_name }}
</div>
</div>
<div class="col-md-6">
<div class="form-group mb-3">
<label for="{{ form.last_name.id_for_label }}" class="form-label">{{ form.last_name.label }}</label>
{{ form.last_name }}
</div>
</div>
</div>
{% if form.password1 %}
<hr>
<h6 class="text-primary mb-3">
<i class="fas fa-lock me-2"></i>Passwort
</h6>
<div class="row">
<div class="col-md-6">
<div class="form-group mb-3">
<label for="{{ form.password1.id_for_label }}" class="form-label">
{{ form.password1.label }}
<span class="text-danger">*</span>
</label>
{{ form.password1 }}
{% if form.password1.help_text %}
<div class="form-text">{{ form.password1.help_text }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="form-group mb-3">
<label for="{{ form.password2.id_for_label }}" class="form-label">
{{ form.password2.label }}
<span class="text-danger">*</span>
</label>
{{ form.password2 }}
{% if form.password2.help_text %}
<div class="form-text">{{ form.password2.help_text }}</div>
{% endif %}
</div>
</div>
</div>
{% endif %}
<hr>
<h6 class="text-primary mb-3">
<i class="fas fa-cog me-2"></i>Benutzereinstellungen
</h6>
<div class="row">
<div class="col-md-6">
<div class="form-check mb-3">
{{ form.is_active }}
<label class="form-check-label" for="{{ form.is_active.id_for_label }}">
{{ form.is_active.label }}
</label>
{% if form.is_active.help_text %}
<div class="form-text">{{ form.is_active.help_text }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="form-check mb-3">
{{ form.is_staff }}
<label class="form-check-label" for="{{ form.is_staff.id_for_label }}">
{{ form.is_staff.label }}
</label>
{% if form.is_staff.help_text %}
<div class="form-text">{{ form.is_staff.help_text }}</div>
{% endif %}
</div>
</div>
</div>
{% if form.send_welcome_email %}
<div class="row">
<div class="col-md-6">
<div class="form-check mb-3">
{{ form.send_welcome_email }}
<label class="form-check-label" for="{{ form.send_welcome_email.id_for_label }}">
{{ form.send_welcome_email.label }}
</label>
{% if form.send_welcome_email.help_text %}
<div class="form-text">{{ form.send_welcome_email.help_text }}</div>
{% endif %}
</div>
</div>
</div>
{% endif %}
<hr>
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:user_management' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Abbrechen
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-1"></i>Speichern
</button>
</div>
</form>
</div>
</div>
{% if user_obj %}
<!-- Additional Actions for Existing Users -->
<div class="card shadow mt-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-tools me-2"></i>Weitere Aktionen
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-4 mb-3">
<a href="{% url 'stiftung:user_change_password' user_obj.pk %}" class="btn btn-outline-warning w-100">
<i class="fas fa-key d-block mb-2 fa-2x"></i>
<span>Passwort ändern</span>
</a>
</div>
<div class="col-md-4 mb-3">
<a href="{% url 'stiftung:user_permissions' user_obj.pk %}" class="btn btn-outline-info w-100">
<i class="fas fa-shield-alt d-block mb-2 fa-2x"></i>
<span>Berechtigungen verwalten</span>
</a>
</div>
<div class="col-md-4 mb-3">
<a href="{% url 'stiftung:user_detail' user_obj.pk %}" class="btn btn-outline-primary w-100">
<i class="fas fa-user d-block mb-2 fa-2x"></i>
<span>Benutzerdetails</span>
</a>
</div>
</div>
</div>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,271 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Benutzerverwaltung - Administration - 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-users me-2"></i>Benutzerverwaltung
</h1>
<div>
<a href="{% url 'stiftung:user_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Neuen Benutzer erstellen
</a>
<a href="{% url 'stiftung:administration' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Administration
</a>
</div>
</div>
</div>
</div>
<!-- Statistiken -->
<div class="row mb-4">
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-primary shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-primary text-uppercase mb-1">Benutzer Gesamt</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.total_users }}</div>
</div>
<div class="col-auto">
<i class="fas fa-users fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-success shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-success text-uppercase mb-1">Aktive Benutzer</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.active_users }}</div>
</div>
<div class="col-auto">
<i class="fas fa-user-check fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-warning shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-warning text-uppercase mb-1">Staff Benutzer</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.staff_users }}</div>
</div>
<div class="col-auto">
<i class="fas fa-user-shield fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6 mb-4">
<div class="card border-left-danger shadow h-100 py-2">
<div class="card-body">
<div class="row no-gutters align-items-center">
<div class="col mr-2">
<div class="text-xs font-weight-bold text-danger text-uppercase mb-1">Inaktive Benutzer</div>
<div class="h5 mb-0 font-weight-bold text-gray-800">{{ stats.inactive_users }}</div>
</div>
<div class="col-auto">
<i class="fas fa-user-times fa-2x text-gray-300"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Filter und Suche -->
<div class="card mb-4">
<div class="card-header">
<i class="fas fa-filter me-2"></i>Filter und Suche
</div>
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-4">
<label class="form-label">Suche</label>
<input type="text" class="form-control" name="search" value="{{ search }}" placeholder="Benutzername, E-Mail, Name...">
</div>
<div class="col-md-3">
<label class="form-label">Status</label>
<select class="form-select" name="status">
<option value="">Alle Status</option>
<option value="active" {% if status_filter == 'active' %}selected{% endif %}>Aktiv</option>
<option value="inactive" {% if status_filter == 'inactive' %}selected{% endif %}>Inaktiv</option>
<option value="staff" {% if status_filter == 'staff' %}selected{% endif %}>Staff</option>
</select>
</div>
<div class="col-md-3 d-flex align-items-end">
<div class="btn-group w-100">
<button type="submit" class="btn btn-primary">
<i class="fas fa-search me-1"></i>Filtern
</button>
<a href="{% url 'stiftung:user_management' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Reset
</a>
</div>
</div>
</form>
</div>
</div>
<!-- Benutzer Liste -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Benutzer
<span class="badge bg-primary ms-2">{{ page_obj.paginator.count|intcomma }}</span>
</h6>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Benutzer</th>
<th>E-Mail</th>
<th>Name</th>
<th>Status</th>
<th>Letzte Anmeldung</th>
<th>Mitglied seit</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for user in page_obj %}
<tr>
<td>
<div class="d-flex align-items-center">
<div class="avatar avatar-sm me-2">
<i class="fas fa-user-circle fa-2x text-muted"></i>
</div>
<div>
<strong>{{ user.username }}</strong>
{% if user.is_superuser %}
<span class="badge bg-danger ms-1">Superuser</span>
{% endif %}
{% if user.is_staff %}
<span class="badge bg-warning ms-1">Staff</span>
{% endif %}
</div>
</div>
</td>
<td>
{% if user.email %}
<a href="mailto:{{ user.email }}">{{ user.email }}</a>
{% else %}
<span class="text-muted">Keine E-Mail</span>
{% endif %}
</td>
<td>
{% if user.first_name or user.last_name %}
{{ user.first_name }} {{ user.last_name }}
{% else %}
<span class="text-muted">Kein Name</span>
{% endif %}
</td>
<td>
{% if user.is_active %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-danger">Inaktiv</span>
{% endif %}
</td>
<td>
{% if user.last_login %}
<span title="{{ user.last_login|date:'d.m.Y H:i:s' }}">
{{ user.last_login|naturaltime }}
</span>
{% else %}
<span class="text-muted">Nie angemeldet</span>
{% endif %}
</td>
<td>
<span title="{{ user.date_joined|date:'d.m.Y H:i:s' }}">
{{ user.date_joined|naturaltime }}
</span>
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:user_detail' user.pk %}" class="btn btn-outline-primary btn-sm" title="Details">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:user_edit' user.pk %}" class="btn btn-outline-secondary btn-sm" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:user_permissions' user.pk %}" class="btn btn-outline-warning btn-sm" title="Berechtigungen">
<i class="fas fa-key"></i>
</a>
{% if user != request.user %}
<a href="{% url 'stiftung:user_delete' user.pk %}" class="btn btn-outline-danger btn-sm" title="Löschen">
<i class="fas fa-trash"></i>
</a>
{% endif %}
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="User Pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ page_obj.previous_page_number }}">Vorherige</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ page_obj.next_page_number }}">Nächste</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-users fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Benutzer gefunden</h5>
<p class="text-muted">Passen Sie die Filter an oder erstellen Sie den ersten Benutzer.</p>
<a href="{% url 'stiftung:user_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Ersten Benutzer erstellen
</a>
</div>
{% endif %}
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,169 @@
{% extends 'base.html' %}
{% block title %}{{ title }} - Benutzerverwaltung - 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-shield-alt me-2"></i>{{ title }}
</h1>
<a href="{% url 'stiftung:user_detail' user_obj.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zum Benutzer
</a>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-key me-2"></i>Berechtigungen verwalten
</h6>
</div>
<div class="card-body">
{% if form.errors %}
<div class="alert alert-danger">
<h6><i class="fas fa-exclamation-triangle me-2"></i>Fehler beim Speichern:</h6>
{% for field, errors in form.errors.items %}
{% for error in errors %}
<div>{{ error }}</div>
{% endfor %}
{% endfor %}
</div>
{% endif %}
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
<strong>Hinweis:</strong> Wählen Sie die Berechtigungen aus, die diesem Benutzer gewährt werden sollen. Änderungen werden sofort wirksam.
</div>
<form method="post" id="permissionsForm">
{% csrf_token %}
<!-- Permission Groups -->
{% for group_key, group_data in permission_groups.items %}
{% if group_data.permissions %}
<div class="card mb-4">
<div class="card-header">
<div class="d-flex justify-content-between align-items-center">
<h6 class="mb-0">
<i class="{{ group_data.icon }} me-2"></i>{{ group_data.name }}
</h6>
<div>
<button type="button" class="btn btn-outline-primary btn-sm" onclick="toggleGroupPermissions('{{ group_key }}', true)">
<i class="fas fa-check-square me-1"></i>Alle auswählen
</button>
<button type="button" class="btn btn-outline-secondary btn-sm" onclick="toggleGroupPermissions('{{ group_key }}', false)">
<i class="fas fa-square me-1"></i>Alle abwählen
</button>
</div>
</div>
</div>
<div class="card-body">
<div class="row">
{% for permission_data in group_data.permissions %}
{% if permission_data|length == 3 %}
{% with field_name=permission_data.0 field=permission_data.1 permission=permission_data.2 %}
<div class="col-md-6 mb-3">
<div class="form-check">
{{ field }}
<label class="form-check-label" for="{{ field.id_for_label }}">
{% if permission %}
{{ permission.name }}
{% else %}
{{ field.label }}
{% endif %}
</label>
</div>
</div>
{% endwith %}
{% else %}
{% with field_name=permission_data.0 field=permission_data.1 %}
<div class="col-md-6 mb-3">
<div class="form-check">
{{ field }}
<label class="form-check-label" for="{{ field.id_for_label }}">
{{ field.label }}
</label>
</div>
</div>
{% endwith %}
{% endif %}
{% endfor %}
</div>
</div>
</div>
{% endif %}
{% endfor %}
<hr>
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:user_detail' user_obj.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Abbrechen
</a>
<div>
<button type="button" class="btn btn-outline-primary me-2" onclick="selectAllPermissions()">
<i class="fas fa-check-square me-1"></i>Alle auswählen
</button>
<button type="button" class="btn btn-outline-secondary me-2" onclick="clearAllPermissions()">
<i class="fas fa-square me-1"></i>Alle abwählen
</button>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-1"></i>Berechtigungen speichern
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<script>
function toggleGroupPermissions(groupKey, select) {
const checkboxes = document.querySelectorAll(`input[type="checkbox"][id*="perm_"]`);
const groupCard = document.querySelector(`[onclick*="${groupKey}"]`).closest('.card');
const groupCheckboxes = groupCard.querySelectorAll('input[type="checkbox"]');
groupCheckboxes.forEach(checkbox => {
checkbox.checked = select;
});
}
function selectAllPermissions() {
const checkboxes = document.querySelectorAll('input[type="checkbox"][id*="perm_"]');
checkboxes.forEach(checkbox => {
checkbox.checked = true;
});
}
function clearAllPermissions() {
const checkboxes = document.querySelectorAll('input[type="checkbox"][id*="perm_"]');
checkboxes.forEach(checkbox => {
checkbox.checked = false;
});
}
// Show confirmation for changes
document.getElementById('permissionsForm').addEventListener('submit', function(e) {
const checkedCount = document.querySelectorAll('input[type="checkbox"][id*="perm_"]:checked').length;
const totalCount = document.querySelectorAll('input[type="checkbox"][id*="perm_"]').length;
if (checkedCount === 0) {
if (!confirm('Sie haben keine Berechtigungen ausgewählt. Der Benutzer hat dann nur sehr eingeschränkte Zugriffsrechte. Fortfahren?')) {
e.preventDefault();
}
} else if (checkedCount === totalCount) {
if (!confirm('Sie haben alle Berechtigungen ausgewählt. Der Benutzer hat dann vollständigen Zugriff auf alle Funktionen. Fortfahren?')) {
e.preventDefault();
}
}
});
</script>
{% endblock %}

View File

@@ -0,0 +1,64 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Verpachtung löschen - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-6 mx-auto">
<div class="card shadow">
<div class="card-header bg-danger text-white">
<h4 class="mb-0">
<i class="fas fa-exclamation-triangle me-2"></i>Verpachtung löschen
</h4>
</div>
<div class="card-body">
<div class="alert alert-warning">
<h5 class="alert-heading">
<i class="fas fa-exclamation-triangle me-2"></i>Warnung!
</h5>
<p class="mb-0">
Sind Sie sicher, dass Sie die Verpachtung <strong>{{ verpachtung.vertragsnummer }}</strong> löschen möchten?
</p>
</div>
<div class="card mb-3">
<div class="card-body">
<h6 class="card-title">Verpachtungsdetails:</h6>
<p class="card-text">
<strong>Länderei:</strong> {{ verpachtung.land.gemeinde }} - {{ verpachtung.land.gemarkung }}<br>
<strong>Pächter:</strong> {{ verpachtung.paechter.get_full_name }}<br>
<strong>Zeitraum:</strong> {{ verpachtung.pachtbeginn|date:"d.m.Y" }} - {{ verpachtung.pachtende|date:"d.m.Y" }}<br>
<strong>Fläche:</strong> {{ verpachtung.verpachtete_flaeche|floatformat:2 }} qm<br>
<strong>Jährlicher Pachtzins:</strong> €{{ verpachtung.pachtzins_jaehrlich|floatformat:2 }}
</p>
</div>
</div>
<div class="alert alert-info">
<h6 class="alert-heading">
<i class="fas fa-info-circle me-2"></i>Wichtiger Hinweis
</h6>
<p class="mb-0">
Diese Aktion kann nicht rückgängig gemacht werden. Alle zugehörigen Daten werden permanent gelöscht.
</p>
</div>
<form method="post">
{% csrf_token %}
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:verpachtung_detail' verpachtung.pk %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-danger">
<i class="fas fa-trash me-2"></i>Endgültig löschen
</button>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,304 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ verpachtung }} - Verpachtung - 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-handshake text-primary me-2"></i>
Verpachtung: {{ verpachtung }}
</h1>
<div>
<a href="{% url 'stiftung:verpachtung_update' pk=verpachtung.pk %}" class="btn btn-warning me-2">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:verpachtung_export' pk=verpachtung.pk %}" class="btn btn-success me-2">
<i class="fas fa-download me-2"></i>Export
</a>
<a href="{% url 'stiftung:verpachtung_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
<div class="row">
<!-- Main Content -->
<div class="col-lg-8">
<!-- Verpachtungs-Informationen -->
<div class="card shadow mb-4">
<div class="card-header bg-primary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-info-circle me-2"></i>Verpachtungs-Informationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Status:</strong>
{% if verpachtung.status == 'aktiv' %}
<span class="badge bg-success">Aktiv</span>
{% elif verpachtung.status == 'beendet' %}
<span class="badge bg-secondary">Beendet</span>
{% elif verpachtung.status == 'gekündigt' %}
<span class="badge bg-danger">Gekündigt</span>
{% else %}
<span class="badge bg-warning">{{ verpachtung.get_status_display }}</span>
{% endif %}
</p>
<p><strong>Pachtbeginn:</strong> {{ verpachtung.pachtbeginn|date:"d.m.Y" }}</p>
<p><strong>Pachtende:</strong>
{% if verpachtung.pachtende %}
{{ verpachtung.pachtende|date:"d.m.Y" }}
{% else %}
<span class="text-muted">Unbefristet</span>
{% endif %}
</p>
</div>
<div class="col-md-6">
<p><strong>Verpachtete Fläche:</strong> {{ verpachtung.verpachtete_flaeche|floatformat:2 }} qm
<small class="text-muted">({{ verpachtung.verpachtete_flaeche_hektar|floatformat:2 }} ha)</small></p>
<p><strong>Pachtzins (jährlich):</strong> €{{ verpachtung.pachtzins_jaehrlich|floatformat:2 }}</p>
<p><strong>Kündigungsfrist:</strong> {{ verpachtung.kuendigungsfrist }} Monate</p>
</div>
</div>
</div>
</div>
<!-- Pächter-Informationen -->
<div class="card shadow mb-4">
<div class="card-header bg-info text-white">
<h5 class="card-title mb-0">
<i class="fas fa-user-tie me-2"></i>Pächter-Informationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Name:</strong>
<a href="{% url 'stiftung:paechter_detail' pk=verpachtung.paechter.pk %}">
{{ verpachtung.paechter.get_full_name }}
</a>
</p>
<p><strong>Pachtnummer:</strong>
{% if verpachtung.paechter.pachtnummer %}
{{ verpachtung.paechter.pachtnummer }}
{% else %}
<span class="text-muted">Nicht vergeben</span>
{% endif %}
</p>
<p><strong>Landwirtschaftliche Ausbildung:</strong>
{% if verpachtung.paechter.landwirtschaftliche_ausbildung %}
<span class="badge bg-success">Ja</span>
{% else %}
<span class="badge bg-warning">Nein</span>
{% endif %}
</p>
</div>
<div class="col-md-6">
<p><strong>Berufserfahrung:</strong>
{% if verpachtung.paechter.berufserfahrung_jahre %}
{{ verpachtung.paechter.berufserfahrung_jahre }} Jahre
{% else %}
<span class="text-muted">Nicht angegeben</span>
{% endif %}
</p>
<p><strong>Kontakt:</strong>
{% if verpachtung.paechter.telefon %}
<i class="fas fa-phone me-1"></i>{{ verpachtung.paechter.telefon }}<br>
{% endif %}
{% if verpachtung.paechter.email %}
<i class="fas fa-envelope me-1"></i>{{ verpachtung.paechter.email }}
{% endif %}
</p>
</div>
</div>
</div>
</div>
<!-- Verknüpfte Dokumente -->
<div class="card shadow mb-4">
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
<h5 class="card-title mb-0">
<i class="fas fa-file-alt me-2"></i>Verknüpfte Dokumente
</h5>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-light btn-sm">
<i class="fas fa-plus me-1"></i>Dokument verknüpfen
</a>
</div>
<div class="card-body">
{% if verknuepfte_dokumente %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>Dokument</th>
<th>Kontext</th>
<th>Beschreibung</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for dokument in verknuepfte_dokumente %}
<tr>
<td>
<strong>{{ dokument.titel }}</strong>
<br>
<small class="text-muted">ID: {{ dokument.paperless_document_id }}</small>
</td>
<td>
<span class="badge bg-secondary">{{ dokument.get_kontext_display }}</span>
</td>
<td>
{% if dokument.beschreibung %}
{{ dokument.beschreibung|truncatewords:10 }}
{% else %}
<span class="text-muted">Keine Beschreibung</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{{ dokument.get_paperless_url }}" target="_blank" class="btn btn-sm btn-outline-primary" title="In Paperless öffnen">
<i class="fas fa-external-link-alt"></i>
</a>
<a href="{{ dokument.get_paperless_thumbnail_url }}" target="_blank" class="btn btn-sm btn-outline-info" title="Thumbnail anzeigen">
<i class="fas fa-image"></i>
</a>
<a href="{% url 'stiftung:dokument_update' dokument.pk %}" class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:dokument_delete' dokument.pk %}" class="btn btn-sm btn-outline-danger" title="Verknüpfung löschen">
<i class="fas fa-unlink"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% else %}
<div class="text-center py-4">
<i class="fas fa-file-alt fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Dokumente verknüpft</h5>
<p class="text-muted">Verknüpfen Sie Dokumente aus Paperless mit dieser Verpachtung.</p>
<a href="{% url 'stiftung:dokument_management' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Erstes Dokument verknüpfen
</a>
</div>
{% endif %}
</div>
</div>
<!-- Länderei-Informationen -->
<div class="card shadow mb-4">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">
<i class="fas fa-map me-2"></i>Länderei-Informationen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Lfd. Nr.:</strong>
<a href="{% url 'stiftung:land_detail' pk=verpachtung.land.pk %}">
{{ verpachtung.land.lfd_nr }}
</a>
</p>
<p><strong>Gemeinde:</strong> {{ verpachtung.land.gemeinde }}</p>
<p><strong>Gemarkung:</strong> {{ verpachtung.land.gemarkung }}</p>
</div>
<div class="col-md-6">
<p><strong>Flur:</strong> {{ verpachtung.land.flur }}</p>
<p><strong>Flurstück:</strong> {{ verpachtung.land.flurstueck }}</p>
<p><strong>Gesamtgröße:</strong> {{ verpachtung.land.groesse_qm|floatformat:2 }} qm</p>
</div>
</div>
</div>
</div>
<!-- Notizen -->
{% if verpachtung.notizen %}
<div class="card shadow mb-4">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-sticky-note me-2"></i>Notizen
</h5>
</div>
<div class="card-body">
{{ verpachtung.notizen|linebreaks }}
</div>
</div>
{% endif %}
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<!-- Statistiken -->
<div class="card shadow mb-4">
<div class="card-header bg-primary text-white">
<h6 class="card-title mb-0">
<i class="fas fa-chart-bar me-2"></i>Statistiken
</h6>
</div>
<div class="card-body">
<p><strong>Verpachtungsgrad:</strong>
{% if verpachtung.land.groesse_qm > 0 %}
{% widthratio verpachtung.verpachtete_flaeche verpachtung.land.groesse_qm 100 %}%
{% else %}
0%
{% endif %}
</p>
<p><strong>Flächenanteil:</strong>
{% if verpachtung.land.groesse_qm > 0 %}
{% widthratio verpachtung.verpachtete_flaeche verpachtung.land.groesse_qm 100 %}%
{% else %}
0%
{% endif %}
</p>
</div>
</div>
<!-- Aktionen -->
<div class="card shadow mb-4">
<div class="card-header bg-success text-white">
<h6 class="card-title mb-0">
<i class="fas fa-tools me-2"></i>Aktionen
</h6>
</div>
<div class="card-body">
<a href="{% url 'stiftung:verpachtung_update' pk=verpachtung.pk %}" class="btn btn-warning btn-sm w-100 mb-2">
<i class="fas fa-edit me-2"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:verpachtung_export' pk=verpachtung.pk %}" class="btn btn-success btn-sm w-100 mb-2">
<i class="fas fa-download me-2"></i>Export
</a>
<a href="{% url 'stiftung:verpachtung_delete' pk=verpachtung.pk %}" class="btn btn-danger btn-sm w-100">
<i class="fas fa-trash me-2"></i>Löschen
</a>
</div>
</div>
<!-- Informationen -->
<div class="card shadow">
<div class="card-header bg-info text-white">
<h6 class="card-title mb-0">
<i class="fas fa-info-circle me-2"></i>Informationen
</h6>
</div>
<div class="card-body">
<p><strong>ID:</strong> <small class="text-muted">{{ verpachtung.pk }}</small></p>
<p><strong>Erstellt:</strong> <small class="text-muted">{{ verpachtung.created_at|date:"d.m.Y H:i" }}</small></p>
<p><strong>Zuletzt aktualisiert:</strong> <small class="text-muted">{{ verpachtung.updated_at|date:"d.m.Y H:i" }}</small></p>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,334 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - 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-handshake text-primary me-2"></i>
{{ title }}
</h1>
<div>
<a href="{% url 'stiftung:verpachtung_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
</div>
</div>
<!-- Form -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-edit me-2"></i>Verpachtungsdaten eingeben
</h6>
</div>
<div class="card-body">
<form method="post" novalidate>
{% csrf_token %}
<!-- Error Messages -->
{% if form.non_field_errors %}
<div class="alert alert-danger">
<ul class="mb-0">
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
<!-- Vertragsdaten -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-file-contract me-2"></i>Vertragsdaten
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.vertragsnummer.id_for_label }}" class="form-label">
{{ form.vertragsnummer.label }} *
</label>
{{ form.vertragsnummer }}
{% if form.vertragsnummer.errors %}
<div class="invalid-feedback d-block">
{% for error in form.vertragsnummer.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.status.id_for_label }}" class="form-label">
{{ form.status.label }} *
</label>
{{ form.status }}
{% if form.status.errors %}
<div class="invalid-feedback d-block">
{% for error in form.status.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Länderei und Pächter -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-map me-2"></i>Länderei und Pächter
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.land.id_for_label }}" class="form-label">
{{ form.land.label }} *
</label>
{{ form.land }}
{% if form.land.errors %}
<div class="invalid-feedback d-block">
{% for error in form.land.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.paechter.id_for_label }}" class="form-label">
{{ form.paechter.label }} *
</label>
{{ form.paechter }}
{% if form.paechter.errors %}
<div class="invalid-feedback d-block">
{% for error in form.paechter.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Zeitraum -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-calendar me-2"></i>Zeitraum
</h5>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.pachtbeginn.id_for_label }}" class="form-label">
{{ form.pachtbeginn.label }} *
</label>
<input type="date"
name="{{ form.pachtbeginn.name }}"
value="{% if form.pachtbeginn.value %}{{ form.pachtbeginn.value|date:'Y-m-d' }}{% endif %}"
class="form-control"
id="{{ form.pachtbeginn.id_for_label }}">
{% if form.pachtbeginn.errors %}
<div class="invalid-feedback d-block">
{% for error in form.pachtbeginn.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.pachtende.id_for_label }}" class="form-label">
{{ form.pachtende.label }} *
</label>
<input type="date"
name="{{ form.pachtende.name }}"
value="{% if form.pachtende.value %}{{ form.pachtende.value|date:'Y-m-d' }}{% endif %}"
class="form-control"
id="{{ form.pachtende.id_for_label }}">
{% if form.pachtende.errors %}
<div class="invalid-feedback d-block">
{% for error in form.pachtende.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.verlaengerung.id_for_label }}" class="form-label">
{{ form.verlaengerung.label }}
</label>
<input type="date"
name="{{ form.verlaengerung.name }}"
value="{% if form.verlaengerung.value %}{{ form.verlaengerung.value|date:'Y-m-d' }}{% endif %}"
class="form-control"
id="{{ form.verlaengerung.id_for_label }}">
{% if form.verlaengerung.errors %}
<div class="invalid-feedback d-block">
{% for error in form.verlaengerung.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Finanzielle Bedingungen -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-euro-sign me-2"></i>Finanzielle Bedingungen
</h5>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.pachtzins_pro_qm.id_for_label }}" class="form-label">
{{ form.pachtzins_pro_qm.label }} *
</label>
{{ form.pachtzins_pro_qm }}
{% if form.pachtzins_pro_qm.errors %}
<div class="invalid-feedback d-block">
{% for error in form.pachtzins_pro_qm.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.pachtzins_jaehrlich.id_for_label }}" class="form-label">
{{ form.pachtzins_jaehrlich.label }} *
</label>
{{ form.pachtzins_jaehrlich }}
{% if form.pachtzins_jaehrlich.errors %}
<div class="invalid-feedback d-block">
{% for error in form.pachtzins_jaehrlich.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-4">
<div class="mb-3">
<label for="{{ form.verpachtete_flaeche.id_for_label }}" class="form-label">
{{ form.verpachtete_flaeche.label }} *
</label>
{{ form.verpachtete_flaeche }}
{% if form.verpachtete_flaeche.errors %}
<div class="invalid-feedback d-block">
{% for error in form.verpachtete_flaeche.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Dokumentation -->
<div class="row mb-4">
<div class="col-12">
<h5 class="text-primary mb-3">
<i class="fas fa-file-alt me-2"></i>Dokumentation
</h5>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.verwendungsnachweis.id_for_label }}" class="form-label">
{{ form.verwendungsnachweis.label }}
</label>
{{ form.verwendungsnachweis }}
{% if form.verwendungsnachweis.errors %}
<div class="invalid-feedback d-block">
{% for error in form.verwendungsnachweis.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.bemerkungen.id_for_label }}" class="form-label">
{{ form.bemerkungen.label }}
</label>
{{ form.bemerkungen }}
{% if form.bemerkungen.errors %}
<div class="invalid-feedback d-block">
{% for error in form.bemerkungen.errors %}
{{ error }}
{% endfor %}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Submit Buttons -->
<div class="row">
<div class="col-12">
<hr class="my-4">
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:verpachtung_list' %}" class="btn btn-secondary">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
<button type="submit" class="btn btn-success">
<i class="fas fa-save me-2"></i>
{% if verpachtung %}Aktualisieren{% else %}Erstellen{% endif %}
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
// Auto-calculate annual rent from area and per-square-meter rate
function calculateAnnualRent() {
const area = parseFloat(document.getElementById('{{ form.verpachtete_flaeche.id_for_label }}').value) || 0;
const ratePerSqm = parseFloat(document.getElementById('{{ form.pachtzins_pro_qm.id_for_label }}').value) || 0;
if (area > 0 && ratePerSqm > 0) {
const annualRent = area * ratePerSqm;
document.getElementById('{{ form.pachtzins_jaehrlich.id_for_label }}').value = annualRent.toFixed(2);
}
}
// Auto-calculate per-square-meter rate from annual rent and area
function calculateRatePerSqm() {
const area = parseFloat(document.getElementById('{{ form.verpachtete_flaeche.id_for_label }}').value) || 0;
const annualRent = parseFloat(document.getElementById('{{ form.pachtzins_jaehrlich.id_for_label }}').value) || 0;
if (area > 0 && annualRent > 0) {
const ratePerSqm = annualRent / area;
document.getElementById('{{ form.pachtzins_pro_qm.id_for_label }}').value = ratePerSqm.toFixed(4);
}
}
// Add event listeners
document.getElementById('{{ form.verpachtete_flaeche.id_for_label }}').addEventListener('input', calculateAnnualRent);
document.getElementById('{{ form.pachtzins_pro_qm.id_for_label }}').addEventListener('input', calculateAnnualRent);
document.getElementById('{{ form.pachtzins_jaehrlich.id_for_label }}').addEventListener('input', calculateRatePerSqm);
</script>
{% endblock %}

View File

@@ -0,0 +1,238 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Verpachtungen - 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-handshake text-primary me-2"></i>Verpachtungen
</h1>
<a href="{% url 'stiftung:verpachtung_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-2"></i>Neue Verpachtung
</a>
</div>
<!-- Statistics Cards -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-primary text-white">
<div class="card-body">
<h5 class="card-title">Aktive Verpachtungen</h5>
<h3 class="card-text">{{ aktive_verpachtungen|default:"0" }}</h3>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body">
<h5 class="card-title">Gesamtfläche</h5>
<h3 class="card-text">{{ gesamt_flaeche|default:"0"|floatformat:0 }} qm</h3>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-info text-white">
<div class="card-body">
<h5 class="card-title">Jährlicher Pachtzins</h5>
<h3 class="card-text">€{{ jaehrlicher_pachtzins|default:"0"|floatformat:0 }}</h3>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-white">
<div class="card-body">
<h5 class="card-title">Anzahl</h5>
<h3 class="card-text">{{ page_obj.paginator.count|default:"0" }}</h3>
</div>
</div>
</div>
</div>
<!-- Filters -->
<div class="card mb-4">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-filter me-2"></i>Filter
</h6>
</div>
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-3">
<label for="search" class="form-label">Suche</label>
<input type="text" name="search" id="search" class="form-control" value="{{ search_query }}" placeholder="Vertragsnummer, Gemeinde, Pächter">
</div>
<div class="col-md-2">
<label for="status" class="form-label">Status</label>
<select name="status" id="status" class="form-select">
<option value="">Alle Status</option>
{% for status in status_choices %}
<option value="{{ status.0 }}" {% if status_filter == status.0 %}selected{% endif %}>{{ status.1 }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-3">
<label for="gemeinde" class="form-label">Gemeinde</label>
<select name="gemeinde" id="gemeinde" class="form-select">
<option value="">Alle Gemeinden</option>
{% for gemeinde in gemeinden %}
<option value="{{ gemeinde }}" {% if gemeinde_filter == gemeinde %}selected{% endif %}>{{ gemeinde }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4 d-flex align-items-end">
<button type="submit" class="btn btn-primary me-2">
<i class="fas fa-search me-2"></i>Filtern
</button>
<a href="{% url 'stiftung:verpachtung_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-2"></i>Zurücksetzen
</a>
</div>
</form>
</div>
</div>
<!-- Verpachtungen Table -->
<div class="card">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-list me-2"></i>Verpachtungen
</h6>
</div>
<div class="card-body">
{% if page_obj %}
<div class="table-responsive">
<table class="table table-hover">
<thead>
<tr>
<th>
<a href="?sort=vertragsnummer&dir={% if sort == 'vertragsnummer' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}">Vertragsnummer</a>
</th>
<th>
<a href="?sort=land&dir={% if sort == 'land' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}">Länderei</a>
</th>
<th>
<a href="?sort=paechter&dir={% if sort == 'paechter' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}">Pächter</a>
</th>
<th>
<a href="?sort=beginn&dir={% if sort == 'beginn' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}">Beginn</a>/<a href="?sort=ende&dir={% if sort == 'ende' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}">Ende</a>
</th>
<th>
<a href="?sort=flaeche&dir={% if sort == 'flaeche' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}">Fläche</a>
</th>
<th>
<a href="?sort=pachtzins&dir={% if sort == 'pachtzins' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}">Pachtzins</a>
</th>
<th>
<a href="?sort=status&dir={% if sort == 'status' and dir != 'desc' %}desc{% else %}asc{% endif %}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}">Status</a>
</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for verpachtung in page_obj %}
<tr>
<td>
<strong>{{ verpachtung.vertragsnummer }}</strong>
</td>
<td>
<a href="{% url 'stiftung:land_detail' verpachtung.land.pk %}">
{{ verpachtung.land.gemeinde }}
</a>
</td>
<td>
<a href="{% url 'stiftung:paechter_detail' verpachtung.paechter.pk %}">
{{ verpachtung.paechter.get_full_name }}
</a>
</td>
<td>
{{ verpachtung.pachtbeginn|date:"d.m.Y" }} - {{ verpachtung.pachtende|date:"d.m.Y" }}
{% if verpachtung.verlaengerung %}
<br><small class="text-muted">Verlängert bis: {{ verpachtung.verlaengerung|date:"d.m.Y" }}</small>
{% endif %}
</td>
<td>
{{ verpachtung.verpachtete_flaeche|floatformat:2 }} qm
<br>
<small class="text-muted">({{ verpachtung.verpachtete_flaeche_hektar|floatformat:2 }} ha)</small>
</td>
<td>€{{ verpachtung.pachtzins_jaehrlich|floatformat:2 }}/Jahr</td>
<td>
<span class="badge bg-{% if verpachtung.status == 'aktiv' %}success{% elif verpachtung.status == 'beendet' %}secondary{% elif verpachtung.status == 'gekuendigt' %}danger{% else %}warning{% endif %}">
{{ verpachtung.get_status_display }}
</span>
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:verpachtung_detail' verpachtung.pk %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:verpachtung_update' verpachtung.pk %}" class="btn btn-sm btn-outline-warning">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:verpachtung_delete' verpachtung.pk %}" class="btn btn-sm btn-outline-danger">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Verpachtungen Pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-chevron-left"></i>
</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if search_query %}&search={{ search_query }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}{% if gemeinde_filter %}&gemeinde={{ gemeinde_filter }}{% endif %}{% if sort %}&sort={{ sort }}&dir={{ dir }}{% endif %}">
<i class="fas fa-chevron-right"></i>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-handshake fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Verpachtungen gefunden</h5>
<p class="text-muted">Erstellen Sie Ihre erste Verpachtung oder passen Sie die Filter an.</p>
<a href="{% url 'stiftung:verpachtung_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-2"></i>Neue Verpachtung erstellen
</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@@ -0,0 +1,324 @@
{% extends 'base.html' %}
{% block title %}{{ title }} - 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-file-invoice-dollar me-2"></i>{{ title }}
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:verwaltungskosten_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Liste
</a>
{% if verwaltungskosten %}
<a href="#" class="btn btn-outline-info">
<i class="fas fa-eye me-1"></i>Details ansehen
</a>
{% endif %}
</div>
</div>
</div>
</div>
<form method="post" novalidate>
{% csrf_token %}
<div class="row">
<!-- Basisdaten -->
<div class="col-xl-6 col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-info-circle me-2"></i>Grunddaten
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="{{ form.bezeichnung.id_for_label }}" class="form-label">Bezeichnung *</label>
{{ form.bezeichnung }}
{% if form.bezeichnung.errors %}
<div class="text-danger small">{{ form.bezeichnung.errors.0 }}</div>
{% endif %}
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.kategorie.id_for_label }}" class="form-label">Kategorie *</label>
{{ form.kategorie }}
{% if form.kategorie.errors %}
<div class="text-danger small">{{ form.kategorie.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.status.id_for_label }}" class="form-label">Status</label>
{{ form.status }}
{% if form.status.errors %}
<div class="text-danger small">{{ form.status.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.betrag.id_for_label }}" class="form-label">Betrag *</label>
<div class="input-group">
{{ form.betrag }}
<span class="input-group-text"></span>
</div>
{% if form.betrag.errors %}
<div class="text-danger small">{{ form.betrag.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.datum.id_for_label }}" class="form-label">Datum *</label>
{{ form.datum }}
{% if form.datum.errors %}
<div class="text-danger small">{{ form.datum.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Lieferant/Rechnung -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-building me-2"></i>Lieferant & Rechnung
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="{{ form.lieferant_firma.id_for_label }}" class="form-label">Lieferant/Firma</label>
{{ form.lieferant_firma }}
{% if form.lieferant_firma.errors %}
<div class="text-danger small">{{ form.lieferant_firma.errors.0 }}</div>
{% endif %}
</div>
<div class="mb-3">
<label for="{{ form.rechnungsnummer.id_for_label }}" class="form-label">Rechnungsnummer</label>
{{ form.rechnungsnummer }}
{% if form.rechnungsnummer.errors %}
<div class="text-danger small">{{ form.rechnungsnummer.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Zuständigkeit und Zahlung -->
<div class="col-xl-6 col-lg-6">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-user-tie me-2"></i>Zuständigkeit & Zahlung
</h6>
</div>
<div class="card-body">
<div class="mb-3">
<label for="{{ form.rentmeister.id_for_label }}" class="form-label">Zuständiger Rentmeister</label>
{{ form.rentmeister }}
{% if form.rentmeister.errors %}
<div class="text-danger small">{{ form.rentmeister.errors.0 }}</div>
{% endif %}
<div class="form-text">Rentmeister der für diese Ausgabe verantwortlich ist</div>
</div>
<div class="mb-3">
<label for="{{ form.zahlungskonto.id_for_label }}" class="form-label">Zahlungskonto</label>
{{ form.zahlungskonto }}
{% if form.zahlungskonto.errors %}
<div class="text-danger small">{{ form.zahlungskonto.errors.0 }}</div>
{% endif %}
<div class="form-text">Konto über das die Zahlung abgewickelt wird</div>
</div>
<div class="mb-3">
<label for="{{ form.quellkonto.id_for_label }}" class="form-label">Quellkonto</label>
{{ form.quellkonto }}
{% if form.quellkonto.errors %}
<div class="text-danger small">{{ form.quellkonto.errors.0 }}</div>
{% endif %}
<div class="form-text">Konto von dem das Geld stammt (falls unterschiedlich)</div>
</div>
</div>
</div>
<!-- Fahrtkosten (wird per JavaScript ein-/ausgeblendet) -->
<div class="card shadow mb-4" id="fahrtkostenCard" style="display: none;">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-car me-2"></i>Fahrtkosten Details
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.km_anzahl.id_for_label }}" class="form-label">Kilometer</label>
<div class="input-group">
{{ form.km_anzahl }}
<span class="input-group-text">km</span>
</div>
{% if form.km_anzahl.errors %}
<div class="text-danger small">{{ form.km_anzahl.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.km_satz.id_for_label }}" class="form-label">€/km</label>
<div class="input-group">
{{ form.km_satz }}
<span class="input-group-text">€/km</span>
</div>
{% if form.km_satz.errors %}
<div class="text-danger small">{{ form.km_satz.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.von_ort.id_for_label }}" class="form-label">Von (Ort)</label>
{{ form.von_ort }}
{% if form.von_ort.errors %}
<div class="text-danger small">{{ form.von_ort.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.nach_ort.id_for_label }}" class="form-label">Nach (Ort)</label>
{{ form.nach_ort }}
{% if form.nach_ort.errors %}
<div class="text-danger small">{{ form.nach_ort.errors.0 }}</div>
{% endif %}
</div>
</div>
<div class="mb-3">
<label for="{{ form.zweck.id_for_label }}" class="form-label">Zweck der Fahrt</label>
{{ form.zweck }}
{% if form.zweck.errors %}
<div class="text-danger small">{{ form.zweck.errors.0 }}</div>
{% endif %}
</div>
<div class="alert alert-info">
<i class="fas fa-calculator me-2"></i>
<span id="fahrtkostenResult">Bitte Kilometer und Satz eingeben für automatische Berechnung</span>
</div>
</div>
</div>
</div>
</div>
<!-- Beschreibung und Notizen -->
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-sticky-note me-2"></i>Zusätzliche Informationen
</h6>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6 mb-3">
<label for="{{ form.beschreibung.id_for_label }}" class="form-label">Beschreibung</label>
{{ form.beschreibung }}
{% if form.beschreibung.errors %}
<div class="text-danger small">{{ form.beschreibung.errors.0 }}</div>
{% endif %}
</div>
<div class="col-md-6 mb-3">
<label for="{{ form.notizen.id_for_label }}" class="form-label">Interne Notizen</label>
{{ form.notizen }}
{% if form.notizen.errors %}
<div class="text-danger small">{{ form.notizen.errors.0 }}</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Form Errors -->
{% if form.non_field_errors %}
<div class="row">
<div class="col-12">
<div class="alert alert-danger">
<strong>Fehler:</strong>
{{ form.non_field_errors }}
</div>
</div>
</div>
{% endif %}
<!-- Submit Buttons -->
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-body text-end">
<a href="{% url 'stiftung:verwaltungskosten_list' %}" class="btn btn-secondary me-2">
<i class="fas fa-times me-1"></i>Abbrechen
</a>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-1"></i>{{ submit_text }}
</button>
</div>
</div>
</div>
</div>
</form>
<script>
document.addEventListener('DOMContentLoaded', function() {
const kategorieSelect = document.getElementById('{{ form.kategorie.id_for_label }}');
const fahrtkostenCard = document.getElementById('fahrtkostenCard');
const kmAnzahlInput = document.getElementById('{{ form.km_anzahl.id_for_label }}');
const kmSatzInput = document.getElementById('{{ form.km_satz.id_for_label }}');
const betragInput = document.getElementById('{{ form.betrag.id_for_label }}');
const fahrtkostenResult = document.getElementById('fahrtkostenResult');
// Fahrtkosten-Bereich ein-/ausblenden
function toggleFahrtkosten() {
if (kategorieSelect.value === 'fahrtkosten') {
fahrtkostenCard.style.display = 'block';
} else {
fahrtkostenCard.style.display = 'none';
}
}
// Fahrtkosten automatisch berechnen
function calculateFahrtkosten() {
const km = parseFloat(kmAnzahlInput.value) || 0;
const satz = parseFloat(kmSatzInput.value) || 0;
if (km > 0 && satz > 0) {
const total = km * satz;
fahrtkostenResult.innerHTML = `<strong>${km} km × ${satz}€ = ${total.toFixed(2)}€</strong>`;
// Betrag automatisch setzen wenn leer
if (!betragInput.value || betragInput.value === '0') {
betragInput.value = total.toFixed(2);
}
} else {
fahrtkostenResult.innerHTML = 'Bitte Kilometer und Satz eingeben für automatische Berechnung';
}
}
// Event Listeners
kategorieSelect.addEventListener('change', toggleFahrtkosten);
kmAnzahlInput.addEventListener('input', calculateFahrtkosten);
kmSatzInput.addEventListener('input', calculateFahrtkosten);
// Initial setup
toggleFahrtkosten();
calculateFahrtkosten();
});
</script>
{% endblock %}

View File

@@ -0,0 +1,210 @@
{% extends 'base.html' %}
{% load humanize %}
{% block title %}Verwaltungskosten - 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-file-invoice-dollar me-2"></i>Verwaltungskosten
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:geschaeftsfuehrung' %}" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-1"></i>Zurück zur Übersicht
</a>
<a href="{% url 'stiftung:verwaltungskosten_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Neue Ausgabe
</a>
</div>
</div>
</div>
</div>
<!-- Filter -->
<div class="row mb-3">
<div class="col-12">
<div class="card">
<div class="card-body">
<form method="get" class="row g-3">
<div class="col-md-4">
<label for="kategorie" class="form-label">Kategorie</label>
<select name="kategorie" id="kategorie" class="form-select">
<option value="">Alle Kategorien</option>
{% for key, value in kategorien %}
<option value="{{ key }}" {% if kategorie_filter == key %}selected{% endif %}>
{{ value }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label for="status" class="form-label">Status</label>
<select name="status" id="status" class="form-select">
<option value="">Alle Status</option>
{% for key, value in status_choices %}
<option value="{{ key }}" {% if status_filter == key %}selected{% endif %}>
{{ value }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label">&nbsp;</label>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">
<i class="fas fa-filter me-1"></i>Filtern
</button>
<a href="{% url 'stiftung:verwaltungskosten_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Zurücksetzen
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- Kosten Liste -->
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-list me-2"></i>Verwaltungskosten
{% if page_obj.paginator.count %}
({{ page_obj.paginator.count }} Einträge)
{% endif %}
</h6>
</div>
<div class="card-body">
{% if page_obj.object_list %}
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Datum</th>
<th>Bezeichnung</th>
<th>Kategorie</th>
<th>Lieferant/Firma</th>
<th>Status</th>
<th>Konto</th>
<th class="text-end">Betrag</th>
<th>Aktionen</th>
</tr>
</thead>
<tbody>
{% for kosten in page_obj %}
<tr>
<td>{{ kosten.datum|date:"d.m.Y" }}</td>
<td>
<strong>{{ kosten.bezeichnung }}</strong>
{% if kosten.rechnungsnummer %}
<br><small class="text-muted">RG: {{ kosten.rechnungsnummer }}</small>
{% endif %}
{% if kosten.kategorie == 'fahrtkosten' and kosten.km_anzahl %}
<br><small class="text-info">
<i class="fas fa-route me-1"></i>
{{ kosten.km_anzahl }} km
{% if kosten.von_ort and kosten.nach_ort %}
({{ kosten.von_ort }} → {{ kosten.nach_ort }})
{% endif %}
</small>
{% endif %}
</td>
<td>
<span class="badge bg-info">{{ kosten.get_kategorie_display }}</span>
</td>
<td>{{ kosten.lieferant_firma|default:"-" }}</td>
<td>
<span class="badge bg-{{ kosten.get_status_color }}">{{ kosten.get_status_display }}</span>
</td>
<td>
{% if kosten.konto %}
<small>{{ kosten.konto.bank_name }}</small><br>
<small class="text-muted">{{ kosten.konto.kontoname }}</small>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td class="text-end">
<strong>€{{ kosten.betrag|floatformat:2 }}</strong>
{% if kosten.kategorie == 'fahrtkosten' and kosten.km_satz %}
<br><small class="text-muted">{{ kosten.km_satz }}€/km</small>
{% endif %}
</td>
<td>
<div class="btn-group btn-group-sm" role="group">
<a href="#" class="btn btn-outline-primary" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="#" class="btn btn-outline-info" title="Details">
<i class="fas fa-eye"></i>
</a>
<a href="#" class="btn btn-outline-danger" title="Löschen">
<i class="fas fa-trash"></i>
</a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if page_obj.has_other_pages %}
<nav aria-label="Seitennavigation">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}{% if kategorie_filter %}&kategorie={{ kategorie_filter }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}">Vorherige</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?page={{ num }}{% if kategorie_filter %}&kategorie={{ kategorie_filter }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}{% if kategorie_filter %}&kategorie={{ kategorie_filter }}{% endif %}{% if status_filter %}&status={{ status_filter }}{% endif %}">Nächste</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fas fa-file-invoice-dollar fa-3x text-muted mb-3"></i>
{% if kategorie_filter or status_filter %}
<p class="text-muted">Keine Verwaltungskosten mit den gewählten Filtern gefunden.</p>
<a href="{% url 'stiftung:verwaltungskosten_list' %}" class="btn btn-outline-secondary">
<i class="fas fa-times me-1"></i>Filter zurücksetzen
</a>
{% else %}
<p class="text-muted">Noch keine Verwaltungskosten angelegt.</p>
<a href="#" class="btn btn-primary">
<i class="fas fa-plus me-1"></i>Erste Ausgabe anlegen
</a>
{% endif %}
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}