Files

139 lines
8.8 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)">
<input type="text" name="status" placeholder="Status (Zu prüfen, Geprüft, Bezahlt)">
<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>Zugewiesener Admin:</strong> {{ item.assigned_admin_display_name or item.assigned_admin_username or 'Nicht gesetzt' }}{% if item.assigned_admin_email %} | <strong>E-Mail:</strong> {{ item.assigned_admin_email }}{% endif %}</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.contact_person }} | {{ item.booking_data.contact_email }} | {{ item.booking_data.billing_city }}</p>
{% endif %}
{% if item.pdf_path %}
<p><strong>PDF:</strong> <a href="{{ url_for('static', filename=item.pdf_path) }}" target="_blank" rel="noopener">Ansehen</a>
<button class="print-btn" type="button" onclick="printPdf('{{ url_for('static', filename=item.pdf_path) }}')">PDF drucken</button>
</p>
{% endif %}
<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">
<input type="text" name="status" value="{{ item.status }}" placeholder="Status">
<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 %}
{% if provision_requests %}
<h2>Instanz-Anfragen</h2>
{% for prov in provision_requests %}
<article class="entry">
<h3>{{ prov.booking_number or prov.booking_number }}</h3>
<p><strong>Nutzer:</strong> {{ prov.username }} | <strong>Subdomain:</strong> {{ prov.subdomain }}</p>
<p><strong>Paket:</strong> {{ prov.package_label or prov.package }} | <strong>Betrag:</strong> {{ '%.2f'|format(prov.amount_eur or 0) }} EUR</p>
<p><strong>Status:</strong> {{ prov.provision_status or 'not_started' }}{% if prov.provision_error %} | <strong>Fehler:</strong> {{ prov.provision_error }}{% endif %}</p>
<p><strong>Kontaktdaten:</strong> {{ prov.booking_data.contact_person }} | {{ prov.booking_data.contact_email }} | {{ prov.booking_data.billing_city }}</p>
<form method="post" style="display:inline-block; margin-right:0.6rem;">
<input type="hidden" name="action" value="create_from_provision">
<input type="hidden" name="prov_id" value="{{ prov.id }}">
<input type="text" name="period" placeholder="Zeitraum (optional)">
<input type="text" name="due_date" placeholder="Fälligkeit (YYYY-MM-DD)">
<button type="submit">Rechnung erzeugen</button>
</form>
<form method="post" style="display:inline-block; margin-right:0.6rem;">
<input type="hidden" name="action" value="update_provision">
<input type="hidden" name="prov_id" value="{{ prov.id }}">
<select name="prov_status">
<option value="accepted">accepted</option>
<option value="rejected">rejected</option>
<option value="completed">completed</option>
</select>
<button type="submit">Status setzen</button>
</form>
<form method="post" style="display:inline-block; margin-right:0.6rem;">
<input type="hidden" name="action" value="run_provision">
<input type="hidden" name="prov_id" value="{{ prov.id }}">
<button type="submit">Provision starten</button>
</form>
<form method="post" style="display:inline-block; margin-right:0.6rem;">
<input type="hidden" name="action" value="retry_provision">
<input type="hidden" name="prov_id" value="{{ prov.id }}">
<button type="submit">Provision wiederholen</button>
</form>
<form method="post" style="display:inline-block; margin-right:0.6rem;">
<input type="hidden" name="action" value="configure_provision">
<input type="hidden" name="prov_id" value="{{ prov.id }}">
<button type="submit">Konfiguration ausführen</button>
</form>
<form method="post" style="display:inline-block; margin-right:0.6rem;">
<input type="hidden" name="action" value="delete_instance_request">
<input type="hidden" name="prov_id" value="{{ prov.id }}">
<button type="submit" class="danger">Löschen</button>
</form>
</article>
{% endfor %}
{% endif %}
</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; }
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 %}