feat: add comprehensive GitHub workflow and development tools

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

View File

@@ -0,0 +1,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 %}