- Display linked PDFs/documents in the edit form with download links - Fix "Details ansehen" button to link to detail page - Redirect edit save to detail page instead of list Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
377 lines
19 KiB
HTML
377 lines
19 KiB
HTML
{% 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="{% url 'stiftung:verwaltungskosten_detail' verwaltungskosten.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">
|
||
<!-- 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>
|
||
|
||
<!-- Verknüpfte Dokumente (nur bei Bearbeitung) -->
|
||
{% if dms_dokumente %}
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<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-file-alt me-2"></i>Verknüpfte Dokumente ({{ dms_dokumente.count }})
|
||
</h6>
|
||
<a href="{% url 'stiftung:dms_upload' %}?kontext=rechnung" class="btn btn-sm btn-outline-primary">
|
||
<i class="fas fa-upload me-1"></i>Weiteres Dokument hochladen
|
||
</a>
|
||
</div>
|
||
<div class="card-body p-0">
|
||
<div class="list-group list-group-flush">
|
||
{% for dok in dms_dokumente %}
|
||
<div class="list-group-item d-flex justify-content-between align-items-center">
|
||
<div>
|
||
{% if dok.is_pdf %}<i class="fas fa-file-pdf text-danger me-2"></i>{% else %}<i class="fas fa-file text-primary me-2"></i>{% endif %}
|
||
<a href="{% url 'stiftung:dms_detail' pk=dok.pk %}"><strong>{{ dok.titel }}</strong></a>
|
||
<br><small class="text-muted ms-4">{{ dok.dateiname_original }} · {{ dok.get_human_size }} · {{ dok.erstellt_am|date:"d.m.Y" }}</small>
|
||
</div>
|
||
<a href="{% url 'stiftung:dms_download' dok.pk %}" class="btn btn-sm btn-outline-success" title="Herunterladen">
|
||
<i class="fas fa-download"></i>
|
||
</a>
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% elif verwaltungskosten %}
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<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-file-alt me-2"></i>Verknüpfte Dokumente
|
||
</h6>
|
||
<a href="{% url 'stiftung:dms_upload' %}?kontext=rechnung" class="btn btn-sm btn-outline-primary">
|
||
<i class="fas fa-upload me-1"></i>Dokument hochladen
|
||
</a>
|
||
</div>
|
||
<div class="card-body">
|
||
<p class="text-muted small mb-0">Keine Dokumente verknüpft. Laden Sie die Rechnung als PDF im DMS hoch.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
<!-- 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 %}
|