feat: Add complete Verpachtung management system

- Add LandVerpachtung model with Land and Paechter relationships
- Implement full CRUD operations for Verpachtungen
- Add responsive Bootstrap templates with JavaScript calculations
- Integrate document linking functionality similar to other entities
- Add navigation links and URL patterns
- Include CSV import support for Paechter data
- Fix template encoding issues for proper UTF-8 support
- Enhance administration interface with Verpachtung CSV import

This implements the complete Verpachtung management feature requested,
allowing users to manage land lease agreements with proper relationships
to properties (Laenderei) and tenants (Paechter), following the same
patterns as Foerderung/Destinataer relationships.
This commit is contained in:
Stiftung Development
2025-09-15 21:18:01 +02:00
parent c8bef800c8
commit 4be6be203e
14 changed files with 1743 additions and 127 deletions

View File

@@ -229,6 +229,12 @@
<span>Backup & Restore</span>
</a>
</div>
<div class="col-md-3 mb-3">
<a href="{% url 'stiftung:csv_import_list' %}" class="btn btn-outline-info w-100">
<i class="fas fa-upload d-block mb-2 fa-2x"></i>
<span>CSV Import</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>

View File

@@ -1,125 +1,129 @@
{% extends 'base.html' %}
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - {{ block.super }}{% endblock %}
{% block title %}{{ title }} - Stiftung Management{% 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 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 %}
<!-- Verknüpfungsanzeigen -->
{% if form.land_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.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 (Legacy) 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="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="mb-3">
<label for="{{ form.titel.id_for_label }}" class="form-label">
{{ form.titel.label }} *
<div class="col-md-6 mb-3">
<label for="{{ form.kontext.id_for_label }}" class="form-label">
{{ form.kontext.label }} *
</label>
{{ form.titel }}
{% if form.titel.errors %}
{{ form.kontext }}
{% if form.kontext.errors %}
<div class="invalid-feedback d-block">
{{ form.titel.errors.0 }}
{{ form.kontext.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>
<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 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>
<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>
</form>
</div>
{% endif %}
</div>
<!-- Versteckte Verknüpfungsfelder -->
{{ form.land_verpachtung_id }}
{{ form.verpachtung_id }}
{{ form.land_id }}
{{ form.paechter_id }}
{{ form.destinataer_id }}
{{ form.foerderung_id }}
<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 %}
@@ -132,4 +136,4 @@
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
}
</style>
{% endblock %}
{% endblock %}

View File

@@ -0,0 +1,81 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - 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 text-primary">
<i class="fas fa-info-circle me-2"></i>Verpachtungsdetails
</h6>
<div class="row">
<div class="col-md-6">
<p><strong>Vertragsnummer:</strong><br>{{ verpachtung.vertragsnummer }}</p>
<p><strong>Land:</strong><br>{{ verpachtung.land.bezeichnung }}</p>
<p><strong>Pächter:</strong><br>{{ verpachtung.paechter.get_full_name }}</p>
</div>
<div class="col-md-6">
<p><strong>Pachtzeit:</strong><br>
{{ verpachtung.pachtbeginn|date:"d.m.Y" }}
{% if verpachtung.pachtende %} - {{ verpachtung.pachtende|date:"d.m.Y" }}{% else %} (unbefristet){% endif %}
</p>
<p><strong>Pachtzins:</strong><br>€{{ verpachtung.pachtzins_pauschal|floatformat:2 }} / Jahr</p>
<p><strong>Status:</strong><br>{{ verpachtung.get_status_display }}</p>
</div>
</div>
</div>
</div>
<div class="alert alert-info">
<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 verknüpften Dokumente bleiben erhalten</li>
<li><i class="fas fa-arrow-right me-2"></i>Abrechnungsdaten werden entsprechend aktualisiert</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>
<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: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,378 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}{{ title }} - Stiftungsverwaltung{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-10 mx-auto">
<!-- 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.vertragsnummer }}
</h1>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:verpachtung_update' verpachtung.pk %}" class="btn btn-warning">
<i class="fas fa-edit me-1"></i>Bearbeiten
</a>
<a href="{% url 'stiftung:verpachtung_delete' verpachtung.pk %}" class="btn btn-danger">
<i class="fas fa-trash me-1"></i>Löschen
</a>
</div>
</div>
<!-- Status Badge -->
<div class="row mb-4">
<div class="col-12">
{% if verpachtung.status == 'aktiv' %}
{% if verpachtung.is_aktiv %}
<span class="badge bg-success fs-6 me-2">
<i class="fas fa-check me-1"></i>Aktiv
</span>
{% else %}
<span class="badge bg-warning fs-6 me-2">
<i class="fas fa-clock me-1"></i>Inaktiv
</span>
{% endif %}
{% elif verpachtung.status == 'beendet' %}
<span class="badge bg-secondary fs-6 me-2">
<i class="fas fa-stop me-1"></i>Beendet
</span>
{% elif verpachtung.status == 'gekuendigt' %}
<span class="badge bg-danger fs-6 me-2">
<i class="fas fa-times me-1"></i>Gekündigt
</span>
{% elif verpachtung.status == 'verlaengert' %}
<span class="badge bg-info fs-6 me-2">
<i class="fas fa-refresh me-1"></i>Verlängert
</span>
{% endif %}
{% if verpachtung.verlaengerung_klausel %}
<span class="badge bg-info fs-6 me-2">
<i class="fas fa-sync me-1"></i>Auto-Verlängerung
</span>
{% endif %}
{% if verpachtung.ust_option %}
<span class="badge bg-warning fs-6">
<i class="fas fa-percent me-1"></i>USt-Option
</span>
{% endif %}
</div>
</div>
<div class="row">
<!-- Grunddaten -->
<div class="col-lg-6">
<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>Grunddaten
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Vertragsnummer:</strong><br>{{ verpachtung.vertragsnummer }}</p>
<p><strong>Status:</strong><br>{{ verpachtung.get_status_display }}</p>
</div>
<div class="col-md-6">
<p><strong>Erstellt:</strong><br>{{ verpachtung.erstellt_am|date:"d.m.Y H:i" }}</p>
<p><strong>Aktualisiert:</strong><br>{{ verpachtung.aktualisiert_am|date:"d.m.Y H:i" }}</p>
</div>
</div>
</div>
</div>
<!-- Land -->
<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-marked-alt me-2"></i>Länderei
</h5>
</div>
<div class="card-body">
<h6 class="text-primary">
<a href="{% url 'stiftung:land_detail' verpachtung.land.pk %}"
class="text-decoration-none">
{{ verpachtung.land.bezeichnung }}
</a>
</h6>
<div class="row">
<div class="col-md-6">
{% if verpachtung.land.flur %}
<p><strong>Flur:</strong> {{ verpachtung.land.flur }}</p>
{% endif %}
{% if verpachtung.land.flurstueck %}
<p><strong>Flurstück:</strong> {{ verpachtung.land.flurstueck }}</p>
{% endif %}
</div>
<div class="col-md-6">
<p><strong>Gesamtfläche:</strong><br>{{ verpachtung.land.groesse_qm|floatformat:0 }} qm ({{ verpachtung.land.groesse_hektar|floatformat:2 }} ha)</p>
</div>
</div>
{% if verpachtung.land.lage %}
<p><strong>Lage:</strong><br>{{ verpachtung.land.lage }}</p>
{% endif %}
</div>
</div>
</div>
<!-- Pächter -->
<div class="col-lg-6">
<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 me-2"></i>Pächter
</h5>
</div>
<div class="card-body">
<h6 class="text-primary">
<a href="{% url 'stiftung:paechter_detail' verpachtung.paechter.pk %}"
class="text-decoration-none">
{{ verpachtung.paechter.get_full_name }}
</a>
</h6>
<div class="row">
<div class="col-md-6">
{% if verpachtung.paechter.email %}
<p><strong>E-Mail:</strong><br>
<a href="mailto:{{ verpachtung.paechter.email }}">{{ verpachtung.paechter.email }}</a>
</p>
{% endif %}
{% if verpachtung.paechter.telefon %}
<p><strong>Telefon:</strong><br>{{ verpachtung.paechter.telefon }}</p>
{% endif %}
</div>
<div class="col-md-6">
{% if verpachtung.paechter.strasse or verpachtung.paechter.plz or verpachtung.paechter.ort %}
<p><strong>Adresse:</strong><br>
{% if verpachtung.paechter.strasse %}{{ verpachtung.paechter.strasse }}<br>{% endif %}
{% if verpachtung.paechter.plz %}{{ verpachtung.paechter.plz }} {% endif %}{{ verpachtung.paechter.ort }}
</p>
{% endif %}
</div>
</div>
<p><strong>Typ:</strong> {{ verpachtung.paechter.get_personentyp_display }}</p>
</div>
</div>
<!-- Pachtzeit -->
<div class="card shadow mb-4">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-calendar me-2"></i>Pachtzeit
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Pachtbeginn:</strong><br>{{ verpachtung.pachtbeginn|date:"d.m.Y" }}</p>
{% if verpachtung.pachtende %}
<p><strong>Pachtende:</strong><br>{{ verpachtung.pachtende|date:"d.m.Y" }}</p>
{% else %}
<p><strong>Pachtende:</strong><br><span class="text-success">Unbefristet</span></p>
{% endif %}
</div>
<div class="col-md-6">
<p><strong>Auto-Verlängerung:</strong><br>
{% if verpachtung.verlaengerung_klausel %}
<span class="badge bg-success">Ja</span>
{% else %}
<span class="badge bg-secondary">Nein</span>
{% endif %}
</p>
{% if verpachtung.get_restlaufzeit_tage %}
<p><strong>Restlaufzeit:</strong><br>{{ verpachtung.get_restlaufzeit_tage }} Tage</p>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Finanzielle Details -->
<div class="row">
<div class="col-lg-6">
<div class="card shadow mb-4">
<div class="card-header bg-secondary text-white">
<h5 class="card-title mb-0">
<i class="fas fa-euro-sign me-2"></i>Pachtzins
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>Pachtzins pauschal:</strong><br>
<span class="text-success fw-bold fs-5">€{{ verpachtung.pachtzins_pauschal|floatformat:2 }}</span> / Jahr
</p>
{% if verpachtung.pachtzins_pro_ha %}
<p><strong>Pachtzins pro ha:</strong><br>€{{ verpachtung.pachtzins_pro_ha|floatformat:2 }} / ha</p>
{% endif %}
</div>
<div class="col-md-6">
<p><strong>Zahlungsweise:</strong><br>{{ verpachtung.get_zahlungsweise_display }}</p>
<p><strong>Verpachtete Fläche:</strong><br>
{{ verpachtung.verpachtete_flaeche|floatformat:0 }} qm<br>
<small class="text-muted">({{ verpachtung.verpachtete_flaeche_hektar|floatformat:2 }} ha)</small>
</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="card shadow mb-4">
<div class="card-header bg-warning text-dark">
<h5 class="card-title mb-0">
<i class="fas fa-percent me-2"></i>Steuern & Umlagen
</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<p><strong>USt-Option:</strong><br>
{% if verpachtung.ust_option %}
<span class="badge bg-warning">Ja ({{ verpachtung.ust_satz }}%)</span>
{% if verpachtung.ust_pacht_betrag %}
<br><small class="text-muted">USt-Betrag: €{{ verpachtung.ust_pacht_betrag|floatformat:2 }}</small>
{% endif %}
{% else %}
<span class="badge bg-secondary">Nein</span>
{% endif %}
</p>
</div>
<div class="col-md-6">
<p><strong>Umlagefähig:</strong></p>
<ul class="list-unstyled">
<li>
<i class="fas fa-{% if verpachtung.grundsteuer_umlage %}check text-success{% else %}times text-danger{% endif %} me-1"></i>
Grundsteuer
</li>
<li>
<i class="fas fa-{% if verpachtung.versicherungen_umlage %}check text-success{% else %}times text-danger{% endif %} me-1"></i>
Versicherungen
</li>
<li>
<i class="fas fa-{% if verpachtung.verbandsbeitraege_umlage %}check text-success{% else %}times text-danger{% endif %} me-1"></i>
Verbandsbeiträge
</li>
<li>
<i class="fas fa-{% if verpachtung.jagdpacht_anteil_umlage %}check text-success{% else %}times text-danger{% endif %} me-1"></i>
Jagdpachtanteile
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Bemerkungen -->
{% if verpachtung.bemerkungen %}
<div class="row">
<div class="col-12">
<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>Bemerkungen
</h5>
</div>
<div class="card-body">
<p>{{ verpachtung.bemerkungen|linebreaks }}</p>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Verknüpfte Dokumente -->
{% if verknuepfte_dokumente %}
<div class="row">
<div class="col-12">
<div class="card shadow mb-4">
<div class="card-header bg-success text-white">
<h5 class="card-title mb-0">
<i class="fas fa-file-alt me-2"></i>Verknüpfte Dokumente ({{ verknuepfte_dokumente.count }})
</h5>
</div>
<div class="card-body">
<div class="row">
{% for dokument in verknuepfte_dokumente %}
<div class="col-md-6 mb-3">
<div class="card border-left-success">
<div class="card-body py-2">
<div class="d-flex justify-content-between align-items-center">
<div>
<h6 class="mb-1">{{ dokument.titel }}</h6>
<small class="text-muted">{{ dokument.kontext }}</small>
</div>
<div>
<a href="{{ dokument.paperless_url }}" target="_blank"
class="btn btn-sm btn-outline-success">
<i class="fas fa-external-link-alt"></i>
</a>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
{% endif %}
<!-- Dokument Management Section -->
<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-paperclip me-2"></i>Dokumente verwalten
</h6>
<a href="{% url 'stiftung:dokument_create' %}?land_verpachtung_id={{ verpachtung.pk }}"
class="btn btn-sm btn-success">
<i class="fas fa-plus me-1"></i>Dokument verknüpfen
</a>
</div>
<div class="card-body">
{% if verknuepfte_dokumente %}
<p class="text-muted mb-3">{{ verknuepfte_dokumente.count }} Dokument{{ verknuepfte_dokumente.count|pluralize:"e" }} verknüpft</p>
{% else %}
<p class="text-muted mb-0">
<i class="fas fa-info-circle me-2"></i>
Noch keine Dokumente mit dieser Verpachtung verknüpft.
Klicken Sie auf "Dokument verknüpfen", um Dokumente aus dem Paperless-System zu verknüpfen.
</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- Navigation -->
<div class="row">
<div class="col-12">
<div class="d-flex justify-content-between">
<a href="{% url 'stiftung:verpachtung_list' %}" class="btn btn-secondary">
<i class="fas fa-arrow-left me-2"></i>Zurück zur Liste
</a>
<a href="{% url 'stiftung:verpachtung_update' verpachtung.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,421 @@
{% 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-handshake text-success me-2"></i>
{{ title }}
</h1>
<p class="text-muted">
{% if form.instance.land %}Länderei: {{ form.instance.land }}{% endif %}
{% if form.instance.paechter %} | Pächter: {{ form.instance.paechter.get_full_name }}{% endif %}
</p>
</div>
<div class="col-md-4 text-end">
<a href="{% if form.instance.pk %}{% url 'stiftung:verpachtung_detail' form.instance.pk %}{% else %}{% url 'stiftung:verpachtung_list' %}{% endif %}"
class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>Abbrechen
</a>
</div>
</div>
<form method="post" enctype="multipart/form-data">
{% 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="{{ form.land.id_for_label }}" class="form-label">
<i class="fas fa-map-marked-alt me-1"></i>Länderei *
</label>
{{ form.land }}
{% if form.land.errors %}
<div class="invalid-feedback d-block">
{{ form.land.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.paechter.id_for_label }}" class="form-label">
<i class="fas fa-user me-1"></i>Pächter *
</label>
{{ form.paechter }}
{% if form.paechter.errors %}
<div class="invalid-feedback d-block">
{{ form.paechter.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Vertragsnummer und Status -->
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.vertragsnummer.id_for_label }}" class="form-label">
<i class="fas fa-file-contract me-1"></i>Vertragsnummer *
</label>
{{ form.vertragsnummer }}
{% if form.vertragsnummer.errors %}
<div class="invalid-feedback d-block">
{{ form.vertragsnummer.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.status.id_for_label }}" class="form-label">
<i class="fas fa-flag me-1"></i>Status
</label>
{{ form.status }}
{% if form.status.errors %}
<div class="invalid-feedback d-block">
{{ form.status.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Pachtzeiten -->
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.pachtbeginn.id_for_label }}" class="form-label">
<i class="fas fa-calendar me-1"></i>Pachtbeginn *
</label>
{{ form.pachtbeginn }}
{% if form.pachtbeginn.errors %}
<div class="invalid-feedback d-block">
{{ form.pachtbeginn.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.pachtende.id_for_label }}" class="form-label">
<i class="fas fa-calendar-times me-1"></i>Pachtende
</label>
{{ form.pachtende }}
{% if form.pachtende.errors %}
<div class="invalid-feedback d-block">
{{ form.pachtende.errors.0 }}
</div>
{% endif %}
<div class="form-text">Leer lassen für unbefristete Verpachtung</div>
</div>
</div>
</div>
<!-- Automatische Verlängerung -->
<div class="row">
<div class="col-md-12">
<div class="mb-3">
<div class="form-check">
{{ form.verlaengerung_klausel }}
<label class="form-check-label" for="{{ form.verlaengerung_klausel.id_for_label }}">
<i class="fas fa-refresh me-1"></i>Automatische Verlängerung
</label>
</div>
{% if form.verlaengerung_klausel.errors %}
<div class="invalid-feedback d-block">
{{ form.verlaengerung_klausel.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Flächeninformationen -->
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.verpachtete_flaeche.id_for_label }}" class="form-label">
<i class="fas fa-expand-arrows-alt me-1"></i>Verpachtete Fläche (qm) *
</label>
{{ form.verpachtete_flaeche }}
{% if form.verpachtete_flaeche.errors %}
<div class="invalid-feedback d-block">
{{ form.verpachtete_flaeche.errors.0 }}
</div>
{% endif %}
<div class="form-text">
<span id="verpachtete_flaeche_ha">0,00 ha</span>
</div>
</div>
</div>
</div>
<!-- Pachtzins -->
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.pachtzins_pauschal.id_for_label }}" class="form-label">
<i class="fas fa-euro-sign me-1"></i>Pachtzins pauschal/Jahr (€) *
</label>
{{ form.pachtzins_pauschal }}
{% if form.pachtzins_pauschal.errors %}
<div class="invalid-feedback d-block">
{{ form.pachtzins_pauschal.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.pachtzins_pro_ha.id_for_label }}" class="form-label">
<i class="fas fa-euro-sign me-1"></i>Pachtzins pro ha (€)
</label>
{{ form.pachtzins_pro_ha }}
{% if form.pachtzins_pro_ha.errors %}
<div class="invalid-feedback d-block">
{{ form.pachtzins_pro_ha.errors.0 }}
</div>
{% endif %}
<div class="form-text">Wird automatisch berechnet</div>
</div>
</div>
</div>
<!-- Zahlungsweise -->
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.zahlungsweise.id_for_label }}" class="form-label">
<i class="fas fa-calendar-check me-1"></i>Zahlungsweise
</label>
{{ form.zahlungsweise }}
{% if form.zahlungsweise.errors %}
<div class="invalid-feedback d-block">
{{ form.zahlungsweise.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Umsatzsteuer -->
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<div class="form-check">
{{ form.ust_option }}
<label class="form-check-label" for="{{ form.ust_option.id_for_label }}">
<i class="fas fa-percent me-1"></i>USt-Option
</label>
</div>
{% if form.ust_option.errors %}
<div class="invalid-feedback d-block">
{{ form.ust_option.errors.0 }}
</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label for="{{ form.ust_satz.id_for_label }}" class="form-label">
<i class="fas fa-percent me-1"></i>USt-Satz (%)
</label>
{{ form.ust_satz }}
{% if form.ust_satz.errors %}
<div class="invalid-feedback d-block">
{{ form.ust_satz.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
<!-- Umlagen -->
<h6 class="mt-4 mb-3">
<i class="fas fa-share-alt me-2"></i>Umlagefähige Kosten
</h6>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<div class="form-check">
{{ form.grundsteuer_umlage }}
<label class="form-check-label" for="{{ form.grundsteuer_umlage.id_for_label }}">
<i class="fas fa-home me-1"></i>Grundsteuer umlagefähig
</label>
</div>
</div>
<div class="mb-3">
<div class="form-check">
{{ form.versicherungen_umlage }}
<label class="form-check-label" for="{{ form.versicherungen_umlage.id_for_label }}">
<i class="fas fa-shield-alt me-1"></i>Versicherungen umlagefähig
</label>
</div>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<div class="form-check">
{{ form.verbandsbeitraege_umlage }}
<label class="form-check-label" for="{{ form.verbandsbeitraege_umlage.id_for_label }}">
<i class="fas fa-users me-1"></i>Verbandsbeiträge umlagefähig
</label>
</div>
</div>
<div class="mb-3">
<div class="form-check">
{{ form.jagdpacht_anteil_umlage }}
<label class="form-check-label" for="{{ form.jagdpacht_anteil_umlage.id_for_label }}">
<i class="fas fa-tree me-1"></i>Jagdpachtanteile umlagefähig
</label>
</div>
</div>
</div>
</div>
<!-- Bemerkungen -->
<div class="row">
<div class="col-md-12">
<div class="mb-3">
<label for="{{ form.bemerkungen.id_for_label }}" class="form-label">
<i class="fas fa-sticky-note me-1"></i>Bemerkungen
</label>
{{ form.bemerkungen }}
{% if form.bemerkungen.errors %}
<div class="invalid-feedback d-block">
{{ form.bemerkungen.errors.0 }}
</div>
{% endif %}
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Sidebar -->
<div class="col-lg-4">
<!-- Aktionen -->
<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-cogs me-2"></i>Aktionen
</h6>
</div>
<div class="card-body">
<button type="submit" class="btn btn-primary btn-block mb-2">
<i class="fas fa-save me-2"></i>Verpachtung speichern
</button>
<a href="{% if form.instance.pk %}{% url 'stiftung:verpachtung_detail' form.instance.pk %}{% else %}{% url 'stiftung:verpachtung_list' %}{% endif %}"
class="btn btn-outline-secondary btn-block">
<i class="fas fa-times me-2"></i>Abbrechen
</a>
</div>
</div>
{% if form.instance.pk %}
<!-- Dokumente -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">
<i class="fas fa-paperclip me-2"></i>Dokumente verknüpfen
</h6>
</div>
<div class="card-body">
<p class="text-muted small">Dokumente können nach dem Speichern der Verpachtung verknüpft werden.</p>
<a href="{% url 'stiftung:dokument_create' %}?land_verpachtung_id={{ form.instance.pk }}"
class="btn btn-outline-primary btn-sm">
<i class="fas fa-plus me-1"></i>Neues Dokument
</a>
</div>
</div>
{% else %}
<!-- Info Card -->
<div class="card shadow">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-info">
<i class="fas fa-info-circle me-2"></i>Hinweis
</h6>
</div>
<div class="card-body">
<p class="text-muted small">
Nach dem Erstellen der Verpachtung können Dokumente verknüpft und weitere Details bearbeitet werden.
</p>
</div>
</div>
{% endif %}
</div>
</div>
</form>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Auto-calculate Pachtzins pro Hektar and Fläche in Hektar
const pachtzinsPauschal = document.getElementById('{{ form.pachtzins_pauschal.id_for_label }}');
const pachtzinsProHa = document.getElementById('{{ form.pachtzins_pro_ha.id_for_label }}');
const verpachteteFlaeche = document.getElementById('{{ form.verpachtete_flaeche.id_for_label }}');
const verpachteteFlaeheHa = document.getElementById('verpachtete_flaeche_ha');
function updateCalculations() {
const flaeche = parseFloat(verpachteteFlaeche.value) || 0;
const pachtzins = parseFloat(pachtzinsPauschal.value) || 0;
// Update Hektar display
const hektar = flaeche / 10000;
verpachteteFlaeheHa.textContent = hektar.toFixed(2) + ' ha';
// Calculate Pachtzins pro Hektar
if (hektar > 0) {
const pachtzinsPerHa = pachtzins / hektar;
pachtzinsProHa.value = pachtzinsPerHa.toFixed(2);
} else {
pachtzinsProHa.value = '';
}
}
// Attach event listeners
if (verpachteteFlaeche) verpachteteFlaeche.addEventListener('input', updateCalculations);
if (pachtzinsPauschal) pachtzinsPauschal.addEventListener('input', updateCalculations);
// Initial calculation
updateCalculations();
// USt-Satz handling
const ustOption = document.getElementById('{{ form.ust_option.id_for_label }}');
const ustSatz = document.getElementById('{{ form.ust_satz.id_for_label }}');
function toggleUstSatz() {
if (ustSatz) {
ustSatz.disabled = !ustOption.checked;
if (!ustOption.checked) {
ustSatz.value = '19.00';
}
}
}
if (ustOption) {
ustOption.addEventListener('change', toggleUstSatz);
toggleUstSatz(); // Initial state
}
});
</script>
{% endblock %}

View File

@@ -0,0 +1,244 @@
{% 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>
<a href="{% url 'stiftung:verpachtung_create' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Neue Verpachtung
</a>
</div>
<!-- Filters -->
<div class="card shadow mb-4">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-filter me-2"></i>Filter und Suche
</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="Vertragsnummer, Land, Pächter...">
</div>
<div class="col-md-3">
<label for="status" class="form-label">Status</label>
<select class="form-select" id="status" name="status">
<option value="">Alle Status</option>
{% for value, label in status_choices %}
<option value="{{ value }}" {% if status_filter == value %}selected{% endif %}>
{{ label }}
</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<label for="year" class="form-label">Jahr</label>
<input type="number" class="form-control" id="year" name="year"
value="{{ year_filter }}"
placeholder="2024" min="1900" max="2100">
</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: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 shadow">
<div class="card-header">
<h6 class="mb-0">
<i class="fas fa-list me-2"></i>Verpachtungen ({{ 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>Vertragsnummer</th>
<th>Land</th>
<th>Pächter</th>
<th>Pachtzeit</th>
<th>Fläche</th>
<th>Pachtzins</th>
<th>Status</th>
<th width="120">Aktionen</th>
</tr>
</thead>
<tbody>
{% for verpachtung in page_obj %}
<tr>
<td>
<a href="{% url 'stiftung:verpachtung_detail' verpachtung.pk %}"
class="text-decoration-none fw-bold">
{{ verpachtung.vertragsnummer }}
</a>
</td>
<td>
<a href="{% url 'stiftung:land_detail' verpachtung.land.pk %}"
class="text-decoration-none">
{{ verpachtung.land.bezeichnung }}
</a>
{% if verpachtung.land.flur %}
<br><small class="text-muted">Flur {{ verpachtung.land.flur }}</small>
{% endif %}
</td>
<td>
<a href="{% url 'stiftung:paechter_detail' verpachtung.paechter.pk %}"
class="text-decoration-none">
{{ verpachtung.paechter.get_full_name }}
</a>
{% if verpachtung.paechter.ort %}
<br><small class="text-muted">{{ verpachtung.paechter.ort }}</small>
{% endif %}
</td>
<td>
{{ verpachtung.pachtbeginn|date:"d.m.Y" }}
{% if verpachtung.pachtende %}
<br><small class="text-muted">bis {{ verpachtung.pachtende|date:"d.m.Y" }}</small>
{% else %}
<br><small class="text-success">Unbefristet</small>
{% endif %}
{% if verpachtung.verlaengerung_klausel %}
<br><small class="badge bg-info">Auto-Verlängerung</small>
{% endif %}
</td>
<td>
{{ verpachtung.verpachtete_flaeche|floatformat:0 }} qm
<br><small class="text-muted">({{ verpachtung.verpachtete_flaeche_hektar|floatformat:2 }} ha)</small>
</td>
<td>
<strong class="text-success">€{{ verpachtung.pachtzins_pauschal|floatformat:2 }}</strong>
{% if verpachtung.pachtzins_pro_ha %}
<br><small class="text-muted">€{{ verpachtung.pachtzins_pro_ha|floatformat:2 }}/ha</small>
{% endif %}
{% if verpachtung.ust_option %}
<br><small class="badge bg-warning">+ {{ verpachtung.ust_satz }}% USt</small>
{% endif %}
</td>
<td>
{% if verpachtung.status == 'aktiv' %}
{% if verpachtung.is_aktiv %}
<span class="badge bg-success">Aktiv</span>
{% else %}
<span class="badge bg-warning">Inaktiv</span>
{% endif %}
{% elif verpachtung.status == 'beendet' %}
<span class="badge bg-secondary">Beendet</span>
{% elif verpachtung.status == 'gekuendigt' %}
<span class="badge bg-danger">Gekündigt</span>
{% elif verpachtung.status == 'verlaengert' %}
<span class="badge bg-info">Verlängert</span>
{% else %}
<span class="badge bg-secondary">{{ verpachtung.get_status_display }}</span>
{% endif %}
</td>
<td>
<div class="btn-group" role="group">
<a href="{% url 'stiftung:verpachtung_detail' verpachtung.pk %}"
class="btn btn-sm btn-outline-primary" title="Details">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'stiftung:verpachtung_update' verpachtung.pk %}"
class="btn btn-sm btn-outline-warning" title="Bearbeiten">
<i class="fas fa-edit"></i>
</a>
<a href="{% url 'stiftung:verpachtung_delete' verpachtung.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="Verpachtungen Pagination">
<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 status_filter %}&status={{ status_filter }}{% endif %}{% if year_filter %}&year={{ year_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 status_filter %}&status={{ status_filter }}{% endif %}{% if year_filter %}&year={{ year_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 status_filter %}&status={{ status_filter }}{% endif %}{% if year_filter %}&year={{ year_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 status_filter %}&status={{ status_filter }}{% endif %}{% if year_filter %}&year={{ year_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 status_filter %}&status={{ status_filter }}{% endif %}{% if year_filter %}&year={{ year_filter }}{% endif %}">
<i class="fas fa-angle-double-right"></i>
</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-4">
<i class="fas fa-handshake fa-3x text-muted mb-3"></i>
<h5 class="text-muted">Keine Verpachtungen gefunden</h5>
<p class="text-muted">
{% if search_query or status_filter or year_filter %}
Keine Verpachtungen entsprechen den angegebenen Filterkriterien.
{% else %}
Es sind noch keine Verpachtungen erfasst.
{% endif %}
</p>
<a href="{% url 'stiftung:verpachtung_create' %}" class="btn btn-success">
<i class="fas fa-plus me-2"></i>Erste Verpachtung erstellen
</a>
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}