Refactoring - Fix1

Dieser Commit ist enthalten in:
2025-06-17 22:59:34 +02:00
Ursprung dbc8904b2c
Commit 0ec0d2c267
13 geänderte Dateien mit 553 neuen und 168 gelöschten Zeilen

Binäre Datei nicht angezeigt.

Binäre Datei nicht angezeigt.

Datei anzeigen

@@ -20,8 +20,9 @@ admin_bp = Blueprint('admin', __name__)
@login_required
def dashboard():
try:
with get_db_connection() as conn:
with get_db_cursor(conn) as cur:
conn = get_connection()
cur = conn.cursor()
try:
# Hole Statistiken mit sicheren Defaults
# Anzahl aktiver Lizenzen
cur.execute("SELECT COUNT(*) FROM licenses WHERE is_active = true")
@@ -123,6 +124,9 @@ def dashboard():
hourly_sessions=hourly_sessions,
resource_stats=resource_stats,
username=session.get('username'))
finally:
cur.close()
conn.close()
except Exception as e:
current_app.logger.error(f"Dashboard error: {str(e)}")

Datei anzeigen

@@ -1,3 +1,4 @@
import os
import logging
from datetime import datetime
from zoneinfo import ZoneInfo
@@ -12,6 +13,11 @@ from models import get_customers, get_customer_by_id
# Create Blueprint
customer_bp = Blueprint('customers', __name__)
# Test route
@customer_bp.route("/test-customers")
def test_customers():
return "Customer blueprint is working!"
@customer_bp.route("/customers")
@login_required
@@ -23,9 +29,6 @@ def customers():
@customer_bp.route("/customer/edit/<int:customer_id>", methods=["GET", "POST"])
@login_required
def edit_customer(customer_id):
conn = get_connection()
cur = conn.cursor()
if request.method == "POST":
try:
# Get current customer data for comparison
@@ -34,51 +37,44 @@ def edit_customer(customer_id):
flash('Kunde nicht gefunden!', 'error')
return redirect(url_for('customers.customers'))
# Update customer data
new_values = {
'name': request.form['name'],
'email': request.form['email'],
'phone': request.form.get('phone', ''),
'address': request.form.get('address', ''),
'notes': request.form.get('notes', '')
}
cur.execute("""
UPDATE customers
SET name = %s, email = %s, phone = %s, address = %s, notes = %s
WHERE id = %s
""", (
new_values['name'],
new_values['email'],
new_values['phone'],
new_values['address'],
new_values['notes'],
customer_id
))
conn.commit()
# Log changes
log_audit('UPDATE', 'customer', customer_id,
old_values={
'name': current_customer['name'],
'email': current_customer['email'],
'phone': current_customer.get('phone', ''),
'address': current_customer.get('address', ''),
'notes': current_customer.get('notes', '')
},
new_values=new_values)
flash('Kunde erfolgreich aktualisiert!', 'success')
return redirect(url_for('customers.customers'))
with get_db_connection() as conn:
cur = conn.cursor()
try:
# Update customer data (nur name und email existieren in der DB)
new_values = {
'name': request.form['name'],
'email': request.form['email']
}
cur.execute("""
UPDATE customers
SET name = %s, email = %s
WHERE id = %s
""", (
new_values['name'],
new_values['email'],
customer_id
))
conn.commit()
# Log changes
log_audit('UPDATE', 'customer', customer_id,
old_values={
'name': current_customer['name'],
'email': current_customer['email']
},
new_values=new_values)
flash('Kunde erfolgreich aktualisiert!', 'success')
return redirect(url_for('customers.customers'))
finally:
cur.close()
except Exception as e:
conn.rollback()
logging.error(f"Fehler beim Aktualisieren des Kunden: {str(e)}")
flash('Fehler beim Aktualisieren des Kunden!', 'error')
finally:
cur.close()
conn.close()
return redirect(url_for('customers.customers'))
# GET request
customer_data = get_customer_by_id(customer_id)
@@ -100,15 +96,12 @@ def create_customer():
# Insert new customer
name = request.form['name']
email = request.form['email']
phone = request.form.get('phone', '')
address = request.form.get('address', '')
notes = request.form.get('notes', '')
cur.execute("""
INSERT INTO customers (name, email, phone, address, notes, created_at)
VALUES (%s, %s, %s, %s, %s, %s)
INSERT INTO customers (name, email, created_at)
VALUES (%s, %s, %s)
RETURNING id
""", (name, email, phone, address, notes, datetime.now()))
""", (name, email, datetime.now()))
customer_id = cur.fetchone()[0]
conn.commit()
@@ -117,10 +110,7 @@ def create_customer():
log_audit('CREATE', 'customer', customer_id,
new_values={
'name': name,
'email': email,
'phone': phone,
'address': address,
'notes': notes
'email': email
})
flash(f'Kunde {name} erfolgreich erstellt!', 'success')
@@ -187,49 +177,69 @@ def delete_customer(customer_id):
@login_required
def customers_licenses():
"""Zeigt die Übersicht von Kunden und deren Lizenzen"""
conn = get_connection()
cur = conn.cursor()
import logging
import psycopg2
logging.info("=== CUSTOMERS-LICENSES ROUTE CALLED ===")
try:
# Hole alle Kunden mit ihren Lizenzen
cur.execute("""
SELECT
c.id as customer_id,
c.name as customer_name,
c.email as customer_email,
c.created_at as customer_created,
COUNT(l.id) as license_count,
COUNT(CASE WHEN l.active = true THEN 1 END) as active_licenses,
COUNT(CASE WHEN l.is_test = true THEN 1 END) as test_licenses,
MAX(l.created_at) as last_license_created
FROM customers c
LEFT JOIN licenses l ON c.id = l.customer_id
GROUP BY c.id, c.name, c.email, c.created_at
ORDER BY c.name
""")
# Direkte Verbindung ohne Helper-Funktionen
conn = psycopg2.connect(
host=os.getenv("POSTGRES_HOST", "postgres"),
port=os.getenv("POSTGRES_PORT", "5432"),
dbname=os.getenv("POSTGRES_DB"),
user=os.getenv("POSTGRES_USER"),
password=os.getenv("POSTGRES_PASSWORD")
)
conn.set_client_encoding('UTF8')
cur = conn.cursor()
customers = []
for row in cur.fetchall():
customers.append({
'id': row[0],
'name': row[1],
'email': row[2],
'created_at': row[3],
'license_count': row[4],
'active_licenses': row[5],
'test_licenses': row[6],
'last_license_created': row[7]
})
return render_template("customers_licenses.html", customers=customers)
try:
# Hole alle Kunden mit ihren Lizenzen
cur.execute("""
SELECT
c.id,
c.name,
c.email,
c.created_at,
COUNT(l.id),
COUNT(CASE WHEN l.is_active = true THEN 1 END),
COUNT(CASE WHEN l.is_test = true THEN 1 END),
MAX(l.created_at)
FROM customers c
LEFT JOIN licenses l ON c.id = l.customer_id
GROUP BY c.id, c.name, c.email, c.created_at
ORDER BY c.name
""")
customers = []
results = cur.fetchall()
logging.info(f"=== QUERY RETURNED {len(results)} ROWS ===")
for idx, row in enumerate(results):
logging.info(f"Row {idx}: Type={type(row)}, Length={len(row) if hasattr(row, '__len__') else 'N/A'}")
customers.append({
'id': row[0],
'name': row[1],
'email': row[2],
'created_at': row[3],
'license_count': row[4],
'active_licenses': row[5],
'test_licenses': row[6],
'last_license_created': row[7]
})
return render_template("customers_licenses.html", customers=customers)
finally:
cur.close()
conn.close()
except Exception as e:
logging.error(f"Fehler beim Laden der Kunden-Lizenz-Übersicht: {str(e)}")
flash('Fehler beim Laden der Daten!', 'error')
import traceback
error_details = f"Fehler beim Laden der Kunden-Lizenz-Übersicht: {str(e)}\nType: {type(e)}\nTraceback: {traceback.format_exc()}"
logging.error(error_details)
flash(f'Datenbankfehler: {str(e)}', 'error')
return redirect(url_for('admin.dashboard'))
finally:
cur.close()
conn.close()
@customer_bp.route("/api/customer/<int:customer_id>/licenses")
@@ -251,17 +261,17 @@ def api_customer_licenses(customer_id):
l.id,
l.license_key,
l.license_type,
l.active,
l.is_active,
l.is_test,
l.valid_from,
l.valid_until,
l.device_limit,
l.created_at,
(SELECT COUNT(*) FROM sessions s WHERE s.license_key = l.license_key AND s.active = true) as active_sessions,
(SELECT COUNT(DISTINCT device_id) FROM sessions s WHERE s.license_key = l.license_key) as registered_devices,
(SELECT COUNT(*) FROM sessions s WHERE s.license_key = l.license_key AND s.is_active = true) as active_sessions,
(SELECT COUNT(DISTINCT hardware_id) FROM sessions s WHERE s.license_key = l.license_key) as registered_devices,
CASE
WHEN l.valid_until < CURRENT_DATE THEN 'expired'
WHEN l.active = false THEN 'inactive'
WHEN l.is_active = false THEN 'inactive'
ELSE 'active'
END as status
FROM licenses l
@@ -314,7 +324,7 @@ def api_customer_quick_stats(customer_id):
cur.execute("""
SELECT
COUNT(l.id) as total_licenses,
COUNT(CASE WHEN l.active = true THEN 1 END) as active_licenses,
COUNT(CASE WHEN l.is_active = true THEN 1 END) as active_licenses,
COUNT(CASE WHEN l.is_test = true THEN 1 END) as test_licenses,
SUM(l.device_limit) as total_device_limit
FROM licenses l

Datei anzeigen

@@ -133,54 +133,55 @@ def resources():
def add_resource():
"""Neue Ressource hinzufügen"""
if request.method == 'POST':
conn = get_connection()
cur = conn.cursor()
try:
resource_type = request.form['resource_type']
resource_value = request.form['resource_value'].strip()
is_test = 'is_test' in request.form
# Prüfe ob Ressource bereits existiert
cur.execute("""
SELECT id FROM resource_pools
WHERE resource_type = %s AND resource_value = %s
""", (resource_type, resource_value))
if cur.fetchone():
flash(f'Ressource {resource_value} existiert bereits!', 'error')
return redirect(url_for('resources.add_resource'))
# Füge neue Ressource hinzu
cur.execute("""
INSERT INTO resource_pools (resource_type, resource_value, status, is_test, created_by)
VALUES (%s, %s, 'available', %s, %s)
RETURNING id
""", (resource_type, resource_value, is_test, session['username']))
resource_id = cur.fetchone()[0]
conn.commit()
# Audit-Log
log_audit('CREATE', 'resource', resource_id,
new_values={
'resource_type': resource_type,
'resource_value': resource_value,
'is_test': is_test
})
flash(f'Ressource {resource_value} erfolgreich hinzugefügt!', 'success')
return redirect(url_for('resources.resources'))
with get_db_connection() as conn:
cur = conn.cursor()
try:
resource_type = request.form['resource_type']
resource_value = request.form['resource_value'].strip()
is_test = 'is_test' in request.form
# Prüfe ob Ressource bereits existiert
cur.execute("""
SELECT id FROM resource_pools
WHERE resource_type = %s AND resource_value = %s
""", (resource_type, resource_value))
if cur.fetchone():
flash(f'Ressource {resource_value} existiert bereits!', 'error')
return redirect(url_for('resources.add_resource'))
# Füge neue Ressource hinzu (ohne created_by)
cur.execute("""
INSERT INTO resource_pools (resource_type, resource_value, status, is_test, status_changed_by)
VALUES (%s, %s, 'available', %s, %s)
RETURNING id
""", (resource_type, resource_value, is_test, session.get('username', 'system')))
resource_id = cur.fetchone()[0]
conn.commit()
# Audit-Log
log_audit('CREATE', 'resource', resource_id,
new_values={
'resource_type': resource_type,
'resource_value': resource_value,
'is_test': is_test
})
flash(f'Ressource {resource_value} erfolgreich hinzugefügt!', 'success')
return redirect(url_for('resources.resources'))
finally:
cur.close()
except Exception as e:
conn.rollback()
import traceback
logging.error(f"Fehler beim Hinzufügen der Ressource: {str(e)}")
flash('Fehler beim Hinzufügen der Ressource!', 'error')
finally:
cur.close()
conn.close()
logging.error(f"Traceback: {traceback.format_exc()}")
flash(f'Fehler: {str(e)}', 'error')
return redirect(url_for('resources.resources'))
return render_template('add_resource.html')
return render_template('add_resources.html')
@resource_bp.route('/resources/quarantine/<int:resource_id>', methods=['POST'])