Batch-Lizenzen
Dieser Commit ist enthalten in:
@@ -981,6 +981,140 @@ def create_license():
|
||||
|
||||
return render_template("index.html", username=session.get('username'))
|
||||
|
||||
@app.route("/batch", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def batch_licenses():
|
||||
"""Batch-Generierung mehrerer Lizenzen für einen Kunden"""
|
||||
if request.method == "POST":
|
||||
# Formulardaten
|
||||
name = request.form["customer_name"]
|
||||
email = request.form["email"]
|
||||
license_type = request.form["license_type"]
|
||||
quantity = int(request.form["quantity"])
|
||||
valid_from = request.form["valid_from"]
|
||||
valid_until = request.form["valid_until"]
|
||||
|
||||
# Sicherheitslimit
|
||||
if quantity < 1 or quantity > 100:
|
||||
flash('Anzahl muss zwischen 1 und 100 liegen!', 'error')
|
||||
return redirect(url_for('batch_licenses'))
|
||||
|
||||
conn = get_connection()
|
||||
cur = conn.cursor()
|
||||
|
||||
try:
|
||||
# Kunde einfügen (falls nicht vorhanden)
|
||||
cur.execute("""
|
||||
INSERT INTO customers (name, email, created_at)
|
||||
VALUES (%s, %s, NOW())
|
||||
ON CONFLICT (name, email) DO UPDATE SET name=EXCLUDED.name
|
||||
RETURNING id
|
||||
""", (name, email))
|
||||
customer_id = cur.fetchone()[0]
|
||||
|
||||
# Lizenzen generieren und speichern
|
||||
generated_licenses = []
|
||||
for i in range(quantity):
|
||||
# Eindeutigen Key generieren
|
||||
attempts = 0
|
||||
while attempts < 10:
|
||||
license_key = generate_license_key(license_type)
|
||||
cur.execute("SELECT 1 FROM licenses WHERE license_key = %s", (license_key,))
|
||||
if not cur.fetchone():
|
||||
break
|
||||
attempts += 1
|
||||
|
||||
# Lizenz einfügen
|
||||
cur.execute("""
|
||||
INSERT INTO licenses (license_key, customer_id, license_type,
|
||||
valid_from, valid_until, is_active, created_at)
|
||||
VALUES (%s, %s, %s, %s, %s, true, NOW())
|
||||
RETURNING id
|
||||
""", (license_key, customer_id, license_type, valid_from, valid_until))
|
||||
license_id = cur.fetchone()[0]
|
||||
|
||||
generated_licenses.append({
|
||||
'id': license_id,
|
||||
'key': license_key,
|
||||
'type': license_type
|
||||
})
|
||||
|
||||
conn.commit()
|
||||
|
||||
# Audit-Log
|
||||
log_audit('CREATE_BATCH', 'license',
|
||||
new_values={'customer': name, 'quantity': quantity, 'type': license_type},
|
||||
additional_info=f"Batch-Generierung von {quantity} Lizenzen")
|
||||
|
||||
# Session für Export speichern
|
||||
session['batch_export'] = {
|
||||
'customer': name,
|
||||
'email': email,
|
||||
'licenses': generated_licenses,
|
||||
'valid_from': valid_from,
|
||||
'valid_until': valid_until,
|
||||
'timestamp': datetime.now().isoformat()
|
||||
}
|
||||
|
||||
flash(f'{quantity} Lizenzen erfolgreich generiert!', 'success')
|
||||
return render_template("batch_result.html",
|
||||
customer=name,
|
||||
email=email,
|
||||
licenses=generated_licenses,
|
||||
valid_from=valid_from,
|
||||
valid_until=valid_until)
|
||||
|
||||
except Exception as e:
|
||||
conn.rollback()
|
||||
logging.error(f"Fehler bei Batch-Generierung: {str(e)}")
|
||||
flash('Fehler bei der Batch-Generierung!', 'error')
|
||||
return redirect(url_for('batch_licenses'))
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
# GET Request
|
||||
return render_template("batch_form.html")
|
||||
|
||||
@app.route("/batch/export")
|
||||
@login_required
|
||||
def export_batch():
|
||||
"""Exportiert die zuletzt generierten Batch-Lizenzen"""
|
||||
batch_data = session.get('batch_export')
|
||||
if not batch_data:
|
||||
flash('Keine Batch-Daten zum Exportieren vorhanden!', 'error')
|
||||
return redirect(url_for('batch_licenses'))
|
||||
|
||||
# CSV generieren
|
||||
output = io.StringIO()
|
||||
output.write('\ufeff') # UTF-8 BOM für Excel
|
||||
|
||||
# Header
|
||||
output.write(f"Kunde: {batch_data['customer']}\n")
|
||||
output.write(f"E-Mail: {batch_data['email']}\n")
|
||||
output.write(f"Generiert am: {datetime.fromisoformat(batch_data['timestamp']).strftime('%d.%m.%Y %H:%M')}\n")
|
||||
output.write(f"Gültig von: {batch_data['valid_from']} bis {batch_data['valid_until']}\n")
|
||||
output.write("\n")
|
||||
output.write("Nr;Lizenzschlüssel;Typ\n")
|
||||
|
||||
# Lizenzen
|
||||
for i, license in enumerate(batch_data['licenses'], 1):
|
||||
typ_text = "Vollversion" if license['type'] == 'full' else "Testversion"
|
||||
output.write(f"{i};{license['key']};{typ_text}\n")
|
||||
|
||||
output.seek(0)
|
||||
|
||||
# Audit-Log
|
||||
log_audit('EXPORT', 'batch_licenses',
|
||||
additional_info=f"Export von {len(batch_data['licenses'])} Batch-Lizenzen")
|
||||
|
||||
return send_file(
|
||||
io.BytesIO(output.getvalue().encode('utf-8-sig')),
|
||||
mimetype='text/csv',
|
||||
as_attachment=True,
|
||||
download_name=f"batch_licenses_{batch_data['customer'].replace(' ', '_')}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
|
||||
)
|
||||
|
||||
@app.route("/licenses")
|
||||
@login_required
|
||||
def licenses():
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren