diff --git a/app/flask-postgres/app/app.py b/app/flask-postgres/app/app.py
index 5c86edd..45a1c42 100644
--- a/app/flask-postgres/app/app.py
+++ b/app/flask-postgres/app/app.py
@@ -16,7 +16,7 @@ from flask import (
)
from werkzeug.security import check_password_hash, generate_password_hash
-from config import Config
+from config import Config, COUNTRY_VAT_LABELS
from db import get_connection, fetchone_dict, fetchall_dict
from auth import login_required
from permissions import is_video_allowed_for_level
@@ -28,6 +28,7 @@ from security import (
)
from logging_config import setup_logging
+
app = Flask(__name__)
app.config.from_object(Config)
app.secret_key = app.config["SECRET_KEY"]
@@ -243,6 +244,7 @@ def preise():
"preise2.html",
page_title="Preise",
active_page="preise",
+ vat_label=COUNTRY_VAT_LABELS.get(session.get("country", "DE")),
**get_current_user()
)
@@ -769,4 +771,174 @@ def set_country():
session["country"] = country
next_url = request.args.get("next") or request.referrer or url_for("home")
- return redirect(next_url)
\ No newline at end of file
+ return redirect(next_url)
+
+@app.route("/useradmin/mandant/user/", methods=["GET", "POST"])
+@user_admin_required
+def useradmin_user_edit(user_id):
+ import re
+
+ current_mandant_id = session.get("mandant_id")
+
+ conn = get_connection()
+ cur = conn.cursor()
+
+ cur.execute("""
+ SELECT id, email, name, mandant_id, status
+ FROM app_user
+ WHERE id = %s
+ AND mandant_id = %s
+ """, (user_id, current_mandant_id))
+ user = fetchone_dict(cur)
+
+ if not user:
+ cur.close()
+ conn.close()
+ abort(404)
+
+ cur.execute("""
+ SELECT id, group_name
+ FROM app_group
+ WHERE mandant_id = %s
+ ORDER BY group_name
+ """, (current_mandant_id,))
+ gruppen = fetchall_dict(cur)
+
+ cur.execute("""
+ SELECT group_id
+ FROM user_group
+ WHERE user_id = %s
+ AND mandant_id = %s
+ """, (user_id, current_mandant_id))
+ assigned_rows = cur.fetchall()
+ assigned_group_ids = [str(row[0]) for row in assigned_rows]
+
+ form_error = None
+ success_message = None
+
+ form_values = {
+ "email": user["email"],
+ "name": user["name"],
+ "status": str(user["status"]),
+ "selected_groups": assigned_group_ids,
+ }
+
+ if request.method == "POST":
+ email = request.form.get("email", "").strip().lower()
+ name = request.form.get("name", "").strip()
+ status = request.form.get("status", "1").strip()
+ password = request.form.get("password", "")
+ password2 = request.form.get("password2", "")
+ selected_groups = request.form.getlist("group_ids")
+
+ form_values = {
+ "email": email,
+ "name": name,
+ "status": status,
+ "selected_groups": selected_groups,
+ }
+
+ email_pattern = r"^[^@\s]+@[^@\s]+\.[^@\s]+$"
+
+ if not email:
+ form_error = "E-Mail ist ein Pflichtfeld."
+ elif not re.match(email_pattern, email):
+ form_error = "Bitte eine gültige E-Mail-Adresse eingeben."
+ elif not name:
+ form_error = "Name ist ein Pflichtfeld."
+ else:
+ cur.execute("""
+ SELECT id
+ FROM app_user
+ WHERE lower(email) = %s
+ AND id <> %s
+ """, (email, user_id))
+ existing_user = cur.fetchone()
+
+ if existing_user:
+ form_error = "Ein anderer Benutzer mit dieser E-Mail existiert bereits."
+
+ if not form_error and (password or password2):
+ if not password:
+ form_error = "Bitte neues Passwort eingeben."
+ elif not password2:
+ form_error = "Bitte neues Passwort bestätigen."
+ elif password != password2:
+ form_error = "Die beiden Passwörter stimmen nicht überein."
+ elif len(password) < 8:
+ form_error = "Das Passwort muss mindestens 8 Zeichen lang sein."
+
+ if not form_error:
+ cur.execute("""
+ UPDATE app_user
+ SET email = %s,
+ name = %s,
+ status = %s
+ WHERE id = %s
+ AND mandant_id = %s
+ """, (email, name, int(status or 1), user_id, current_mandant_id))
+
+ if password:
+ password_hash = generate_password_hash(password)
+ cur.execute("""
+ UPDATE app_user
+ SET password_hash = %s
+ WHERE id = %s
+ AND mandant_id = %s
+ """, (password_hash, user_id, current_mandant_id))
+
+ cur.execute("""
+ DELETE FROM user_group
+ WHERE user_id = %s
+ AND mandant_id = %s
+ """, (user_id, current_mandant_id))
+
+ selected_group_ids = []
+ for gid in selected_groups:
+ try:
+ selected_group_ids.append(int(gid))
+ except ValueError:
+ pass
+
+ if selected_group_ids:
+ cur.execute("""
+ SELECT id
+ FROM app_group
+ WHERE mandant_id = %s
+ AND id = ANY(%s)
+ """, (current_mandant_id, selected_group_ids))
+ valid_groups = cur.fetchall()
+
+ for row in valid_groups:
+ group_id = row[0]
+ cur.execute("""
+ INSERT INTO user_group (user_id, group_id, mandant_id)
+ VALUES (%s, %s, %s)
+ """, (user_id, group_id, current_mandant_id))
+
+ conn.commit()
+ success_message = "Benutzer wurde erfolgreich aktualisiert."
+
+ cur.execute("""
+ SELECT group_id
+ FROM user_group
+ WHERE user_id = %s
+ AND mandant_id = %s
+ """, (user_id, current_mandant_id))
+ assigned_rows = cur.fetchall()
+ form_values["selected_groups"] = [str(row[0]) for row in assigned_rows]
+
+ cur.close()
+ conn.close()
+
+ return render_template(
+ "useradmin_user_edit.html",
+ page_title="User bearbeiten",
+ active_page="useradmin",
+ edit_user=user,
+ gruppen=gruppen,
+ form_values=form_values,
+ form_error=form_error,
+ success_message=success_message,
+ **get_current_user()
+ )
\ No newline at end of file
diff --git a/app/flask-postgres/app/config.py b/app/flask-postgres/app/config.py
index 25536dd..e434d4e 100644
--- a/app/flask-postgres/app/config.py
+++ b/app/flask-postgres/app/config.py
@@ -10,4 +10,10 @@ class Config:
DB_PASSWORD = os.getenv("DB_PASSWORD", "CertPWD")
DB_PORT = os.getenv("DB_PORT", "5432")
- LOG_DIR = os.getenv("LOG_DIR", "./logs")
\ No newline at end of file
+ LOG_DIR = os.getenv("LOG_DIR", "./logs")
+
+ COUNTRY_VAT_LABELS = {
+ "DE": "inkl. 19% USt",
+ "AT": "inkl. 20% USt",
+ "CH": "exkl. MwSt",
+ }
\ No newline at end of file
diff --git a/app/flask-postgres/app/templates/preise2.html b/app/flask-postgres/app/templates/preise2.html
index 0b11618..4ebe6aa 100644
--- a/app/flask-postgres/app/templates/preise2.html
+++ b/app/flask-postgres/app/templates/preise2.html
@@ -17,13 +17,7 @@
Alle Preise verstehen sich
- {% if country == "DE" %}
- inkl. 19% USt
- {% elif country == "AT" %}
- inkl. 20% USt
- {% elif country == "CH" %}
- exkl. MwSt
- {% endif %}.
+ {{ vat_label }}.
diff --git a/app/flask-postgres/app/templates/useradmin_mandant.html b/app/flask-postgres/app/templates/useradmin_mandant.html
index 1eeb804..302802a 100644
--- a/app/flask-postgres/app/templates/useradmin_mandant.html
+++ b/app/flask-postgres/app/templates/useradmin_mandant.html
@@ -13,6 +13,10 @@
Benutzerübersicht
+
+
@@ -24,6 +28,7 @@
| Letzter Login |
Mandant |
Level |
+ Aktionen |
@@ -36,6 +41,11 @@
{{ user.last_login or "-" }} |
{{ user.mandant_name }} |
{{ user.mandant_level }} |
+
+
+ |
{% endfor %}
diff --git a/app/flask-postgres/app/templates/useradmin_user_edit.html b/app/flask-postgres/app/templates/useradmin_user_edit.html
new file mode 100644
index 0000000..110923d
--- /dev/null
+++ b/app/flask-postgres/app/templates/useradmin_user_edit.html
@@ -0,0 +1,157 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+
+
+
+
+
+ {% if form_error %}
+
{{ form_error }}
+ {% endif %}
+
+ {% if success_message %}
+
{{ success_message }}
+ {% endif %}
+
+
+
+
+
+
+
+{% endblock %}
\ No newline at end of file