Neuer Kunde anlegen ohne Lizenz
Dieser Commit ist enthalten in:
@@ -2185,6 +2185,61 @@ def edit_customer(customer_id):
|
||||
|
||||
return render_template("edit_customer.html", customer=customer, licenses=licenses, username=session.get('username'))
|
||||
|
||||
@app.route("/customer/create", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def create_customer():
|
||||
"""Erstellt einen neuen Kunden ohne Lizenz"""
|
||||
if request.method == "POST":
|
||||
name = request.form.get('name')
|
||||
email = request.form.get('email')
|
||||
is_test = request.form.get('is_test') == 'on'
|
||||
|
||||
if not name or not email:
|
||||
flash("Name und E-Mail sind Pflichtfelder!", "error")
|
||||
return render_template("create_customer.html", username=session.get('username'))
|
||||
|
||||
conn = get_connection()
|
||||
cur = conn.cursor()
|
||||
|
||||
try:
|
||||
# Prüfen ob E-Mail bereits existiert
|
||||
cur.execute("SELECT id, name FROM customers WHERE email = %s", (email,))
|
||||
existing = cur.fetchone()
|
||||
if existing:
|
||||
flash(f"Ein Kunde mit der E-Mail '{email}' existiert bereits: {existing[1]}", "error")
|
||||
return render_template("create_customer.html", username=session.get('username'))
|
||||
|
||||
# Kunde erstellen
|
||||
cur.execute("""
|
||||
INSERT INTO customers (name, email, created_at, is_test)
|
||||
VALUES (%s, %s, %s, %s) RETURNING id
|
||||
""", (name, email, datetime.now(), is_test))
|
||||
|
||||
customer_id = cur.fetchone()[0]
|
||||
conn.commit()
|
||||
|
||||
# Audit-Log
|
||||
log_audit('CREATE', 'customer', customer_id,
|
||||
new_values={
|
||||
'name': name,
|
||||
'email': email,
|
||||
'is_test': is_test
|
||||
})
|
||||
|
||||
flash(f"Kunde '{name}' wurde erfolgreich angelegt!", "success")
|
||||
return redirect(f"/customer/edit/{customer_id}")
|
||||
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
flash(f"Fehler beim Anlegen des Kunden: {str(e)}", "error")
|
||||
return render_template("create_customer.html", username=session.get('username'))
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
# GET Request - Formular anzeigen
|
||||
return render_template("create_customer.html", username=session.get('username'))
|
||||
|
||||
@app.route("/customer/delete/<int:customer_id>", methods=["POST"])
|
||||
@login_required
|
||||
def delete_customer(customer_id):
|
||||
|
||||
74
v2_adminpanel/templates/create_customer.html
Normale Datei
74
v2_adminpanel/templates/create_customer.html
Normale Datei
@@ -0,0 +1,74 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Neuer Kunde{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container py-5">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2>👤 Neuer Kunde anlegen</h2>
|
||||
<div>
|
||||
<a href="/" class="btn btn-secondary">📊 Dashboard</a>
|
||||
<a href="/customers" class="btn btn-secondary">👥 Zurück zur Übersicht</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<form method="post" action="/customer/create" accept-charset="UTF-8">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label for="name" class="form-label">Kundenname <span class="text-danger">*</span></label>
|
||||
<input type="text" class="form-control" id="name" name="name"
|
||||
placeholder="Firmenname oder Vor- und Nachname"
|
||||
accept-charset="UTF-8" required autofocus>
|
||||
<div class="form-text">Der Name des Kunden oder der Firma</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label for="email" class="form-label">E-Mail <span class="text-danger">*</span></label>
|
||||
<input type="email" class="form-control" id="email" name="email"
|
||||
placeholder="kunde@beispiel.de"
|
||||
accept-charset="UTF-8" required>
|
||||
<div class="form-text">Kontakt-E-Mail-Adresse des Kunden</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-check mt-3">
|
||||
<input class="form-check-input" type="checkbox" id="isTest" name="is_test">
|
||||
<label class="form-check-label" for="isTest">
|
||||
<i class="fas fa-flask"></i> Als Testdaten markieren
|
||||
<small class="text-muted">(Kunde wird von der Software ignoriert)</small>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-info mt-4" role="alert">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
<strong>Hinweis:</strong> Nach dem Anlegen des Kunden können Sie direkt Lizenzen für diesen Kunden erstellen.
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<button type="submit" class="btn btn-primary">💾 Kunde anlegen</button>
|
||||
<a href="/customers" class="btn btn-secondary">Abbrechen</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Flash Messages -->
|
||||
{% with messages = get_flashed_messages(with_categories=true) %}
|
||||
{% if messages %}
|
||||
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
|
||||
{% for category, message in messages %}
|
||||
<div class="toast show align-items-center text-white bg-{{ 'danger' if category == 'error' else 'success' }} border-0" role="alert">
|
||||
<div class="d-flex">
|
||||
<div class="toast-body">
|
||||
{{ message }}
|
||||
</div>
|
||||
<button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
@@ -32,6 +32,7 @@
|
||||
<i class="bi bi-layout-split"></i> Kombinierte Ansicht
|
||||
</a>
|
||||
<a href="/" class="btn btn-secondary">📊 Dashboard</a>
|
||||
<a href="/customer/create" class="btn btn-primary">👤 Neuer Kunde</a>
|
||||
<a href="/create" class="btn btn-primary">➕ Neue Lizenz</a>
|
||||
<a href="/batch" class="btn btn-primary">🔑 Batch-Lizenzen</a>
|
||||
<div class="btn-group">
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h2>👥 Kunden & Lizenzen</h2>
|
||||
<div>
|
||||
<a href="/customer/create" class="btn btn-primary">👤 Neuer Kunde</a>
|
||||
<a href="/create" class="btn btn-success">➕ Neue Lizenz</a>
|
||||
<a href="/batch" class="btn btn-primary">🔑 Batch-Lizenzen</a>
|
||||
<div class="btn-group">
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren