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