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

@@ -6,7 +6,7 @@ from django.utils import timezone
from .models import (BankTransaction, Destinataer, DestinataerNotiz,
DestinataerUnterstuetzung, DokumentLink, Foerderung, Land,
LandAbrechnung, Paechter, Person, Rentmeister,
LandAbrechnung, LandVerpachtung, Paechter, Person, Rentmeister,
StiftungsKonto, UnterstuetzungWiederkehrend,
Verwaltungskosten)
@@ -534,6 +534,53 @@ class LandForm(forms.ModelForm):
}
class LandVerpachtungForm(forms.ModelForm):
"""Form für das Erstellen und Bearbeiten von Verpachtungen"""
class Meta:
model = LandVerpachtung
fields = [
'land',
'paechter',
'vertragsnummer',
'pachtbeginn',
'pachtende',
'verlaengerung_klausel',
'verpachtete_flaeche',
'pachtzins_pauschal',
'pachtzins_pro_ha',
'zahlungsweise',
'ust_option',
'ust_satz',
'grundsteuer_umlage',
'versicherungen_umlage',
'verbandsbeitraege_umlage',
'jagdpacht_anteil_umlage',
'status',
'bemerkungen'
]
widgets = {
'land': forms.Select(attrs={'class': 'form-select'}),
'paechter': forms.Select(attrs={'class': 'form-select'}),
'vertragsnummer': forms.TextInput(attrs={'class': 'form-control'}),
'pachtbeginn': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
'pachtende': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
'verlaengerung_klausel': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'verpachtete_flaeche': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
'pachtzins_pauschal': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
'pachtzins_pro_ha': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
'zahlungsweise': forms.Select(attrs={'class': 'form-select'}),
'ust_option': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'ust_satz': forms.NumberInput(attrs={'class': 'form-control', 'step': '0.01'}),
'grundsteuer_umlage': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'versicherungen_umlage': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'verbandsbeitraege_umlage': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'jagdpacht_anteil_umlage': forms.CheckboxInput(attrs={'class': 'form-check-input'}),
'status': forms.Select(attrs={'class': 'form-select'}),
'bemerkungen': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
}
class LandAbrechnungForm(forms.ModelForm):
"""Form für das Erstellen und Bearbeiten von Landabrechnungen"""

View File

@@ -109,6 +109,20 @@ urlpatterns = [
views.land_verpachtung_end_direct,
name="land_verpachtung_end_direct",
),
# Verpachtung URLs (Management Overview)
path("verpachtungen/", views.verpachtung_list, name="verpachtung_list"),
path("verpachtungen/<uuid:pk>/", views.verpachtung_detail, name="verpachtung_detail"),
path("verpachtungen/neu/", views.verpachtung_create, name="verpachtung_create"),
path(
"verpachtungen/<uuid:pk>/bearbeiten/",
views.verpachtung_update,
name="verpachtung_update",
),
path(
"verpachtungen/<uuid:pk>/loeschen/",
views.verpachtung_delete,
name="verpachtung_delete",
),
# Förderung URLs
path("foerderungen/", views.foerderung_list, name="foerderung_list"),
path("foerderungen/<uuid:pk>/", views.foerderung_detail, name="foerderung_detail"),

View File

@@ -1689,7 +1689,7 @@ def verpachtung_list(request):
"beginn": ["pachtbeginn"],
"ende": ["pachtende"],
"flaeche": ["verpachtete_flaeche"],
"pachtzins": ["pachtzins_jaehrlich"],
"pachtzins": ["pachtzins_pauschal"],
"status": ["status"],
}
if sort in sort_map:
@@ -1723,7 +1723,7 @@ def verpachtung_list(request):
# Total annual rent (only active verpachtungen)
jaehrlicher_pachtzins_result = all_verpachtungen.filter(status="aktiv").aggregate(
total=Sum("pachtzins_jaehrlich")
total=Sum("pachtzins_pauschal")
)
jaehrlicher_pachtzins = (
jaehrlicher_pachtzins_result["total"]
@@ -1787,7 +1787,7 @@ def land_verpachtung_update(request, pk):
vertragsnummer = request.POST.get("vertragsnummer")
pachtbeginn = request.POST.get("pachtbeginn")
pachtende = request.POST.get("pachtende")
pachtzins_jaehrlich = request.POST.get("pachtzins_jaehrlich")
pachtzins_pauschal = request.POST.get("pachtzins_pauschal")
if vertragsnummer:
verpachtung.vertragsnummer = vertragsnummer
@@ -1795,8 +1795,8 @@ def land_verpachtung_update(request, pk):
verpachtung.pachtbeginn = pachtbeginn
if pachtende:
verpachtung.pachtende = pachtende
if pachtzins_jaehrlich:
verpachtung.pachtzins_jaehrlich = pachtzins_jaehrlich
if pachtzins_pauschal:
verpachtung.pachtzins_pauschal = pachtzins_pauschal
verpachtung.save()
messages.success(request, "Verpachtung wurde erfolgreich aktualisiert.")
@@ -2130,7 +2130,11 @@ def dokument_create(request):
)
# Zurück zur verknüpften Entität leiten
if dokument.verpachtung_id:
if dokument.land_verpachtung_id:
return redirect(
"stiftung:verpachtung_detail", pk=dokument.land_verpachtung_id
)
elif dokument.verpachtung_id:
return redirect(
"stiftung:verpachtung_detail", pk=dokument.verpachtung_id
)
@@ -2149,6 +2153,8 @@ def dokument_create(request):
else:
# Initial-Werte aus GET-Parametern setzen
initial_data = {}
if request.GET.get("land_verpachtung_id"):
initial_data["land_verpachtung_id"] = request.GET.get("land_verpachtung_id")
if request.GET.get("verpachtung"):
initial_data["verpachtung_id"] = request.GET.get("verpachtung")
if request.GET.get("land"):
@@ -5435,7 +5441,7 @@ def verpachtung_export(request, pk):
else None
),
"pachtzins_pro_qm": str(verpachtung.pachtzins_pro_qm),
"pachtzins_jaehrlich": str(verpachtung.pachtzins_jaehrlich),
"pachtzins_jaehrlich": str(verpachtung.pachtzins_pauschal),
"verpachtete_flaeche": str(verpachtung.verpachtete_flaeche),
"status": verpachtung.get_status_display(),
"verwendungsnachweis": (
@@ -6914,3 +6920,126 @@ def edit_help_box(request):
"title": "Hilfs-Infoboxen verwalten",
}
return render(request, "stiftung/help_boxes_admin.html", context)
# =============================================================================
# Verpachtung Management Views (Standalone CRUD)
# =============================================================================
@login_required
def verpachtung_detail(request, pk):
"""Standalone detail view for verpachtung"""
verpachtung = get_object_or_404(LandVerpachtung, pk=pk)
# Alle mit dieser Verpachtung verknüpften Dokumente laden
verknuepfte_dokumente = DokumentLink.objects.filter(
land_verpachtung_id=verpachtung.pk
).order_by("kontext", "titel")
context = {
"verpachtung": verpachtung,
"landverpachtung": verpachtung, # Template compatibility
"verknuepfte_dokumente": verknuepfte_dokumente,
"title": f"Verpachtung {verpachtung.vertragsnummer}",
}
return render(request, "stiftung/verpachtung_detail.html", context)
@login_required
def verpachtung_create(request):
"""Standalone create view for verpachtung"""
from .forms import LandVerpachtungForm
from datetime import datetime as dt
if request.method == 'POST':
form = LandVerpachtungForm(request.POST, request.FILES)
if form.is_valid():
verpachtung = form.save()
# Update the Land model to reflect this verpachtung
land = verpachtung.land
land.aktueller_paechter = verpachtung.paechter
land.paechter_name = verpachtung.paechter.get_full_name()
land.paechter_anschrift = f"{verpachtung.paechter.strasse or ''}\n{verpachtung.paechter.plz or ''} {verpachtung.paechter.ort or ''}".strip()
land.pachtbeginn = verpachtung.pachtbeginn
land.pachtende = verpachtung.pachtende
land.pachtzins_pauschal = verpachtung.pachtzins_pauschal
land.zahlungsweise = verpachtung.zahlungsweise
land.ust_option = verpachtung.ust_option
land.verpachtete_gesamtflaeche = verpachtung.verpachtete_flaeche
land.verp_flaeche_aktuell = verpachtung.verpachtete_flaeche
land.save()
# Create automatic abrechnung
current_year = dt.now().year
expected_annual_rent = verpachtung.pachtzins_pauschal if verpachtung.pachtzins_pauschal else 0
abrechnung, created = LandAbrechnung.objects.get_or_create(
land=land,
abrechnungsjahr=current_year,
defaults={
"pacht_vereinnahmt": expected_annual_rent,
"umlagen_vereinnahmt": 0,
"grundsteuer_betrag": 0,
"versicherungen_betrag": 0,
},
)
if not created and expected_annual_rent > abrechnung.pacht_vereinnahmt:
abrechnung.pacht_vereinnahmt = expected_annual_rent
abrechnung.save()
success_msg = f'Verpachtung "{verpachtung.vertragsnummer}" wurde erfolgreich erstellt.'
if created:
success_msg += f" Abrechnung für {current_year} wurde automatisch angelegt"
if expected_annual_rent > 0:
success_msg += f" (Erwartete Jahrespacht: {expected_annual_rent}€)"
success_msg += "."
elif expected_annual_rent > 0:
success_msg += f" Erwartete Jahrespacht in Abrechnung {current_year} wurde aktualisiert ({expected_annual_rent}€)."
messages.success(request, success_msg)
return redirect('stiftung:verpachtung_detail', pk=verpachtung.pk)
else:
form = LandVerpachtungForm()
# Get available Länder and Pächter for the template
laender_list = Land.objects.all().order_by('lfd_nr')
paechter_list = Paechter.objects.filter(aktiv=True).order_by('nachname', 'vorname')
context = {
'form': form,
'title': 'Neue Verpachtung erstellen',
'laender_list': laender_list,
'paechter_list': paechter_list,
'current_year': dt.now().year,
'is_edit': False,
}
return render(request, 'stiftung/verpachtung_form.html', context)
@login_required
def verpachtung_update(request, pk):
"""Standalone update view for verpachtung"""
return land_verpachtung_update(request, pk)
@login_required
def verpachtung_delete(request, pk):
"""Standalone delete view for verpachtung"""
verpachtung = get_object_or_404(LandVerpachtung, pk=pk)
if request.method == 'POST':
vertragsnummer = verpachtung.vertragsnummer
verpachtung.delete()
messages.success(
request,
f'Verpachtung "{vertragsnummer}" wurde erfolgreich gelöscht.'
)
return redirect('stiftung:verpachtung_list')
context = {
'verpachtung': verpachtung,
'title': f'Verpachtung {verpachtung.vertragsnummer} löschen',
}
return render(request, 'stiftung/verpachtung_confirm_delete.html', context)

View File

@@ -331,6 +331,13 @@
<i class="fas fa-plus me-2"></i>Neue Länderei
</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="{% url 'stiftung:verpachtung_list' %}">
<i class="fas fa-handshake me-2"></i>Alle Verpachtungen
</a></li>
<li><a class="dropdown-item" href="{% url 'stiftung:verpachtung_create' %}">
<i class="fas fa-plus me-2"></i>Neue Verpachtung
</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="{% url 'stiftung:land_abrechnung_list' %}">
<i class="fas fa-calculator me-2"></i>Abrechnungen
</a></li>

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 %}