Files
Key-service-Server/Website/templates/admin_invoices.html
T
2026-08-28 15:32:34 +02:00

121 lines
7.1 KiB
HTML

{% extends "base.html" %}
{% block title %}Admin | Rechnungsverwaltung{% endblock %}
{% block content %}
<section class="panel" style="display:flex; align-items:center; justify-content:space-between; gap:1rem;">
<div>
<h1>Rechnungsverwaltung</h1>
<p style="margin:0">Rechnungen für Nutzer erstellen, aktualisieren und löschen. Neue Rechnungen starten mit dem Status „Zu prüfen“, damit der Admin sie zuerst kontrolliert. Direktbuchungen werden hier automatisch mit zugewiesenem Admin und Buchungsunterlagen angezeigt.</p>
</div>
<div class="no-print">
<button class="print-btn" type="button" onclick="printDocument()">Seite drucken</button>
</div>
</section>
<section class="layout">
<form method="post" class="form-card" enctype="multipart/form-data">
<h3>Neue Rechnung</h3>
<input type="hidden" name="action" value="create">
<select name="username" required>
<option value="">Benutzer auswählen</option>
{% for user in users %}
<option value="{{ user.username }}">{{ user.username }} ({{ user.display_name }})</option>
{% endfor %}
</select>
<input type="text" name="invoice_number" placeholder="Rechnungsnummer (optional, eigener Wert möglich)">
<input type="text" name="period" placeholder="Zeitraum (MM/YYYY)" required>
<input type="text" name="amount_eur" placeholder="Betrag in EUR" required>
<input type="text" name="due_date" placeholder="Fälligkeit (YYYY-MM-DD)">
<!-- NEU: Dropdown für Status beim Erstellen -->
<select name="status">
<option value="Zu prüfen">Zu prüfen</option>
<option value="In Bearbeitung">In Bearbeitung</option>
<option value="Geprüft">Vertrag verifiziert</option>
<option value="Bezahlt">Bezahlt</option>
<option value="Storniert">Storniert</option>
</select>
<input type="file" name="invoice_pdf" accept="application/pdf">
<button type="submit">Rechnung anlegen</button>
</form>
<div class="list">
{% for item in invoices %}
<article class="entry">
<h3>{{ item.invoice_number }}</h3>
<p><strong>Nutzer:</strong> {{ item.username }} | <strong>Zeitraum:</strong> {{ item.period }}</p>
<p><strong>Betrag:</strong> {{ '%.2f'|format(item.amount_eur) }} EUR | <strong>Status:</strong> {{ item.status }} | <strong>Fälligkeit:</strong> {{ item.due_date }}</p>
{% if item.source == 'booking_payment' %}
<p><strong>Buchung:</strong> {{ item.booking_package_label or item.booking_package }} | <strong>Flow:</strong> {{ item.booking_flow }}</p>
<p><strong>Unterlagen:</strong> {{ item.paperwork_status or 'Offen' }}{% if item.consent_accepted %} | Einwilligung bestätigt{% endif %}</p>
<p><strong>Kontaktdaten:</strong> {{ item.booking_data.get('contact_person', '-') }} | {{ item.booking_data.get('contact_email', '-') }} | {{ item.booking_data.get('billing_city', '-') }}</p>
{% endif %}
<div style="margin: 0.5rem 0; padding: 0.5rem; background: #f4f8fa; border-radius: 8px;">
{% if item.pdf_path %}
<p style="margin:0.2rem 0;"><strong>Rechnungs-PDF:</strong>
<a href="{{ url_for('static', filename=item.pdf_path) }}" target="_blank" rel="noopener">Ansehen</a>
</p>
{% endif %}
{% if item.hauptvertrag_data is defined or item.get('hauptvertrag_filename') %}
<p style="margin:0.2rem 0;"><strong>Hauptvertrag:</strong>
<a href="{{ url_for('view_hauptvertrag', invoice_id=item.id) }}" target="_blank" rel="noopener">
{{ item.hauptvertrag_filename or 'Hauptvertrag öffnen' }}
</a>
</p>
{% else %}
<p style="margin:0.2rem 0; color: #777;"><strong>Hauptvertrag:</strong> Noch nicht hochgeladen</p>
{% endif %}
</div>
<form method="post" class="inline-form" enctype="multipart/form-data">
<input type="hidden" name="action" value="update">
<input type="hidden" name="invoice_id" value="{{ item.id }}">
<input type="text" name="invoice_number" value="{{ item.invoice_number }}" placeholder="Rechnungsnummer">
<input type="text" name="period" value="{{ item.period }}" placeholder="Zeitraum">
<input type="text" name="amount_eur" value="{{ item.amount_eur }}" placeholder="Betrag">
<input type="text" name="due_date" value="{{ item.due_date }}" placeholder="Fälligkeit">
<!-- NEU: Dropdown für Status beim Aktualisieren (mit dynamischer Vorauswahl) -->
<select name="status">
<option value="Zu prüfen" {% if item.status == 'Zu prüfen' %}selected{% endif %}>Zu prüfen</option>
<option value="In Bearbeitung" {% if item.status == 'In Bearbeitung' %}selected{% endif %}>In Bearbeitung</option>
<option value="Geprüft" {% if item.status == 'Geprüft' %}selected{% endif %}>Geprüft</option>
<option value="Bezahlt" {% if item.status == 'Bezahlt' %}selected{% endif %}>Bezahlt</option>
<option value="Storniert" {% if item.status == 'Storniert' %}selected{% endif %}>Storniert</option>
</select>
<input type="file" name="invoice_pdf" accept="application/pdf">
<button type="submit">Aktualisieren</button>
</form>
<form method="post">
<input type="hidden" name="action" value="delete">
<input type="hidden" name="invoice_id" value="{{ item.id }}">
<button type="submit" class="danger">Löschen</button>
</form>
</article>
{% else %}
<article class="entry"><p>Noch keine Rechnungen vorhanden.</p></article>
{% endfor %}
</div>
</section>
<style>
.panel { margin-bottom: 1rem; }
.layout { display: grid; grid-template-columns: 320px 1fr; gap: 1rem; }
.form-card, .entry { background: #fff; border: 1px solid #d8e1e8; border-radius: 14px; padding: 1rem; }
.form-card { display: grid; gap: 0.6rem; align-self: start; }
.list { display: grid; gap: 0.8rem; }
.inline-form { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 0.45rem; margin-top: 0.6rem; }
input, select { width: 100%; border: 1px solid #c9d8e3; border-radius: 10px; padding: 0.52rem; font: inherit; background: #fff; }
a { color: #0a4c74; font-weight: 700; }
button { border: 1px solid #0a4c74; background: linear-gradient(120deg, #0c5a86 0%, #08486c 100%); color: #fff; padding: 0.45rem 0.8rem; border-radius: 999px; font-weight: 700; cursor: pointer; }
button.danger { border-color: #d04a49; background: #fff; color: #922e2e; margin-top: 0.55rem; }
@media (max-width: 980px) { .layout { grid-template-columns: 1fr; } .inline-form { grid-template-columns: 1fr; } }
</style>
{% endblock %}