diff --git a/app/flask-postgres/app/app.py b/app/flask-postgres/app/app.py index e872ae3..b4a6cd4 100644 --- a/app/flask-postgres/app/app.py +++ b/app/flask-postgres/app/app.py @@ -346,7 +346,7 @@ def login(): cur = conn.cursor() cur.execute(""" - SELECT id, email, name, mandant_id, password_hash, status + SELECT id, email, name, mandant_id, password_hash, status, level FROM app_user WHERE lower(email) = %s """, (email,)) @@ -355,7 +355,7 @@ def login(): if not row: error_message = "Benutzer nicht gefunden." else: - user_id, user_email, user_name, mandant_id, password_hash, status = row + user_id, user_email, user_name, mandant_id, password_hash, status, user_level = row if status == 0: error_message = "Benutzer ist noch nicht aktiviert." @@ -370,6 +370,7 @@ def login(): session["user_email"] = user_email session["user_name"] = user_name session["mandant_id"] = mandant_id + session["user_level"] = user_level cur.execute(""" UPDATE app_user @@ -461,6 +462,7 @@ def profil(): u.email, u.name, u.mandant_id, + u.level AS user_level, m.name AS mandant_name, m.kontakt_email AS mandant_email, m.level AS mandant_level @@ -500,6 +502,7 @@ def profil(): groups=groups, certificates=certificates, mandant_level_label=format_level(profile["mandant_level"]), + user_level_label=format_level(profile["user_level"]), **get_current_user() ) @@ -715,7 +718,8 @@ def useradmin_mandant(): u.id, u.email, u.name, - u.status + u.status, + u.level FROM app_user u WHERE u.mandant_id = %s ORDER BY u.name, u.email @@ -725,6 +729,8 @@ def useradmin_mandant(): for user in users: user["status_label"] = format_user_status(user["status"]) user["can_delete"] = user["id"] != current_user_id + user["level_label"] = format_level(user["level"]) + cur.close() conn.close() @@ -743,11 +749,23 @@ def useradmin_mandant(): @app.route("/useradmin/mandant/new", methods=["GET", "POST"]) @user_admin_required def useradmin_user_new(): + import re + current_mandant_id = session.get("mandant_id") conn = get_connection() cur = conn.cursor() + # Mandanten-Level laden + cur.execute(""" + SELECT level + FROM mandant + WHERE id = %s + """, (current_mandant_id,)) + mandant_row = cur.fetchone() + mandant_level = mandant_row[0] if mandant_row else 3 + + # Gruppen des Mandanten laden cur.execute(""" SELECT id, group_name FROM app_group @@ -757,26 +775,31 @@ def useradmin_user_new(): gruppen = fetchall_dict(cur) form_error = None + success_message = None + form_values = { "email": "", "name": "", "status": "1", - "selected_groups": [] + "level": str(mandant_level), + "selected_groups": [], } if request.method == "POST": email = request.form.get("email", "").strip().lower() name = request.form.get("name", "").strip() + status = request.form.get("status", "1").strip() + level = request.form.get("level", str(mandant_level)).strip() password = request.form.get("password", "") password2 = request.form.get("password2", "") - status = request.form.get("status", "1").strip() selected_groups = request.form.getlist("group_ids") form_values = { "email": email, "name": name, "status": status, - "selected_groups": selected_groups + "level": level, + "selected_groups": selected_groups, } email_pattern = r"^[^@\s]+@[^@\s]+\.[^@\s]+$" @@ -787,6 +810,12 @@ def useradmin_user_new(): form_error = "Bitte eine gültige E-Mail-Adresse eingeben." elif not name: form_error = "Name ist ein Pflichtfeld." + elif status not in ("0", "1"): + form_error = "Status muss 0 oder 1 sein." + elif level not in ("1", "2", "3"): + form_error = "Bitte ein gültiges User-Level wählen." + elif int(level) < int(mandant_level): + form_error = "Der User-Level darf nicht höher als der Mandanten-Level sein." elif not password: form_error = "Passwort ist ein Pflichtfeld." elif not password2: @@ -805,51 +834,58 @@ def useradmin_user_new(): if existing_user: form_error = "Ein Benutzer mit dieser E-Mail existiert bereits." - else: - password_hash = generate_password_hash(password) + if not form_error: + password_hash = generate_password_hash(password) + + cur.execute(""" + INSERT INTO app_user (email, name, mandant_id, password_hash, status, level) + VALUES (%s, %s, %s, %s, %s, %s) + RETURNING id + """, ( + email, + name, + current_mandant_id, + password_hash, + int(status), + int(level) + )) + new_user_id = cur.fetchone()[0] + + selected_group_ids = [] + for gid in selected_groups: + try: + selected_group_ids.append(int(gid)) + except ValueError: + pass + + if selected_group_ids: cur.execute(""" - INSERT INTO app_user ( - email, - name, - mandant_id, - password_hash, - status - ) - VALUES (%s, %s, %s, %s, %s) - RETURNING id - """, ( - email, - name, - current_mandant_id, - password_hash, - int(status or 1) - )) - new_user_id = cur.fetchone()[0] - - if selected_groups: - selected_group_ids = [int(gid) for gid in selected_groups] + 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(""" - SELECT id - FROM app_group - WHERE mandant_id = %s - AND id = ANY(%s) - """, (current_mandant_id, selected_group_ids)) - valid_groups = cur.fetchall() + INSERT INTO user_group (user_id, group_id, mandant_id) + VALUES (%s, %s, %s) + """, (new_user_id, group_id, current_mandant_id)) - 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) - """, (new_user_id, group_id, current_mandant_id)) + conn.commit() + success_message = "Benutzer wurde erfolgreich angelegt." - conn.commit() - cur.close() - conn.close() - - return redirect(url_for("useradmin_mandant")) + # Formular leeren / auf Defaults zurücksetzen + form_values = { + "email": "", + "name": "", + "status": "1", + "level": str(mandant_level), + "selected_groups": [], + } cur.close() conn.close() @@ -859,8 +895,11 @@ def useradmin_user_new(): page_title="Neuer User", active_page="useradmin", gruppen=gruppen, - form_error=form_error, form_values=form_values, + form_error=form_error, + success_message=success_message, + mandant_level=mandant_level, + mandant_level_label=format_level(mandant_level), **get_current_user() ) @@ -885,8 +924,18 @@ def useradmin_user_edit(user_id): conn = get_connection() cur = conn.cursor() + # Mandanten-Level laden cur.execute(""" - SELECT id, email, name, mandant_id, status + SELECT level + FROM mandant + WHERE id = %s + """, (current_mandant_id,)) + mandant_row = cur.fetchone() + mandant_level = mandant_row[0] if mandant_row else None + + # User laden + cur.execute(""" + SELECT id, email, name, mandant_id, status, level FROM app_user WHERE id = %s AND mandant_id = %s @@ -898,6 +947,7 @@ def useradmin_user_edit(user_id): conn.close() abort(404) + # Gruppen des Mandanten cur.execute(""" SELECT id, group_name FROM app_group @@ -906,6 +956,7 @@ def useradmin_user_edit(user_id): """, (current_mandant_id,)) gruppen = fetchall_dict(cur) + # Zugeordnete Gruppen des Users cur.execute(""" SELECT group_id FROM user_group @@ -922,6 +973,7 @@ def useradmin_user_edit(user_id): "email": user["email"], "name": user["name"], "status": str(user["status"]), + "level": str(user["level"] if user.get("level") is not None else 1), "selected_groups": assigned_group_ids, } @@ -929,6 +981,7 @@ def useradmin_user_edit(user_id): email = request.form.get("email", "").strip().lower() name = request.form.get("name", "").strip() status = request.form.get("status", "1").strip() + level = request.form.get("level", "1").strip() password = request.form.get("password", "") password2 = request.form.get("password2", "") selected_groups = request.form.getlist("group_ids") @@ -937,6 +990,7 @@ def useradmin_user_edit(user_id): "email": email, "name": name, "status": status, + "level": level, "selected_groups": selected_groups, } @@ -948,6 +1002,12 @@ def useradmin_user_edit(user_id): form_error = "Bitte eine gültige E-Mail-Adresse eingeben." elif not name: form_error = "Name ist ein Pflichtfeld." + elif status not in ("0", "1"): + form_error = "Status muss 0 oder 1 sein." + elif level not in ("1", "2", "3"): + form_error = "Bitte ein gültiges User-Level wählen." + elif mandant_level is not None and int(level) < int(mandant_level): + form_error = "Der User-Level darf nicht höher als der Mandanten-Level sein." else: cur.execute(""" SELECT id @@ -975,10 +1035,18 @@ def useradmin_user_edit(user_id): UPDATE app_user SET email = %s, name = %s, - status = %s + status = %s, + level = %s WHERE id = %s AND mandant_id = %s - """, (email, name, int(status or 1), user_id, current_mandant_id)) + """, ( + email, + name, + int(status), + int(level), + user_id, + current_mandant_id + )) if password: password_hash = generate_password_hash(password) @@ -1021,6 +1089,7 @@ def useradmin_user_edit(user_id): conn.commit() success_message = "Benutzer wurde erfolgreich aktualisiert." + # Formularwerte nach dem Speichern neu laden cur.execute(""" SELECT group_id FROM user_group @@ -1030,6 +1099,16 @@ def useradmin_user_edit(user_id): assigned_rows = cur.fetchall() form_values["selected_groups"] = [str(row[0]) for row in assigned_rows] + # edit_user für Anzeige aktualisieren + user["email"] = email + user["name"] = name + user["status"] = int(status) + user["level"] = int(level) + + # Falls der aktuell eingeloggte User sich selbst geändert hat: Session-Level aktualisieren + if session.get("user_id") == user_id: + session["user_level"] = int(level) + cur.close() conn.close() @@ -1042,6 +1121,8 @@ def useradmin_user_edit(user_id): form_values=form_values, form_error=form_error, success_message=success_message, + mandant_level=mandant_level, + mandant_level_label=format_level(mandant_level) if mandant_level is not None else "-", **get_current_user() ) @@ -1050,6 +1131,7 @@ def useradmin_user_edit(user_id): def course_list(): user_id = session.get("user_id") mandant_level = session.get("mandant_level", 0) + user_level = session.get("user_level", 3) conn = get_connection() cur = conn.cursor() @@ -1066,7 +1148,7 @@ def course_list(): # Filter nach Level available_courses = [ c for c in all_courses - if is_course_allowed_for_level(c["code"], mandant_level) + if is_course_allowed_for_level(c["code"], user_level) ] # Bestandene Assessments laden @@ -1870,6 +1952,9 @@ def admin_questions_course(course_id): @login_required def course_assessment(course_id): mandant_level = session.get("mandant_level", 0) + user_level = session.get("user_level", 3) + if not is_course_allowed_for_level(course["code"], user_level): + abort(403) conn = get_connection() cur = conn.cursor() @@ -1996,6 +2081,10 @@ def course_assessment(course_id): @app.route("/useradmin/mandant/upload", methods=["GET", "POST"]) @user_admin_required def useradmin_user_upload(): + import csv + import io + import re + current_mandant_id = session.get("mandant_id") form_error = None success_message = None @@ -2004,13 +2093,15 @@ def useradmin_user_upload(): conn = get_connection() cur = conn.cursor() + # Mandant + Mandanten-Level laden cur.execute(""" - SELECT name + SELECT name, level FROM mandant WHERE id = %s """, (current_mandant_id,)) mandant_row = cur.fetchone() mandant_name = mandant_row[0] if mandant_row else f"Mandant {current_mandant_id}" + mandant_level = mandant_row[1] if mandant_row else 3 if request.method == "POST": uploaded_file = request.files.get("csv_file") @@ -2020,10 +2111,14 @@ def useradmin_user_upload(): else: file_bytes = uploaded_file.read() - try: - content = file_bytes.decode("utf-8-sig") - except UnicodeDecodeError: - form_error = "Die Datei ist nicht im UTF-8 Format. Bitte als UTF-8 CSV speichern." + if not file_bytes: + form_error = "Die Datei ist leer." + + if not form_error: + try: + content = file_bytes.decode("utf-8-sig") + except UnicodeDecodeError: + form_error = "Die Datei ist nicht im UTF-8 Format. Bitte als UTF-8 CSV speichern." if not form_error: reader = csv.reader(io.StringIO(content), delimiter=";") @@ -2032,7 +2127,8 @@ def useradmin_user_upload(): if not rows: form_error = "Die Datei ist leer." - # Nur echte Datenzeilen zählen (keine leeren) + if not form_error: + # Nur echte Datenzeilen zählen data_rows = [ row for row in rows if row and any(str(col).strip() for col in row) @@ -2048,9 +2144,6 @@ def useradmin_user_upload(): seen_emails_in_file = set() for line_no, row in enumerate(data_rows, start=1): - if not row or all(not str(col).strip() for col in row): - continue - if len(row) != 4: row_errors.append(f"Zeile {line_no}: Es müssen genau 4 Felder vorhanden sein.") continue @@ -2064,14 +2157,17 @@ def useradmin_user_upload(): if not name: line_problems.append("Name fehlt") + if not email: line_problems.append("E-Mail fehlt") elif not re.match(email_pattern, email): line_problems.append("E-Mail ungültig") + if not status: line_problems.append("Status fehlt") elif status not in ("0", "1"): line_problems.append("Status muss 0 oder 1 sein") + if not password: line_problems.append("Passwort fehlt") elif ";" in password: @@ -2102,6 +2198,7 @@ def useradmin_user_upload(): "email": email, "status": int(status), "password_hash": generate_password_hash(password), + "level": mandant_level, # 👈 neu }) if row_errors: @@ -2109,14 +2206,15 @@ def useradmin_user_upload(): else: for u in parsed_users: cur.execute(""" - INSERT INTO app_user (email, name, mandant_id, password_hash, status) - VALUES (%s, %s, %s, %s, %s) + INSERT INTO app_user (email, name, mandant_id, password_hash, status, level) + VALUES (%s, %s, %s, %s, %s, %s) """, ( u["email"], u["name"], current_mandant_id, u["password_hash"], - u["status"] + u["status"], + u["level"] )) conn.commit() @@ -2133,6 +2231,7 @@ def useradmin_user_upload(): success_message=success_message, row_errors=row_errors, mandant_name=mandant_name, + mandant_level_label=format_level(mandant_level), **get_current_user() ) @@ -2221,59 +2320,93 @@ def pwdchange(): @user_admin_required def reporting_assessments(): current_mandant_id = session.get("mandant_id") - mandant_level = session.get("mandant_level") conn = get_connection() cur = conn.cursor() - # Mandant - cur.execute("SELECT name, level FROM mandant WHERE id = %s", (current_mandant_id,)) - mandant_row = cur.fetchone() - mandant_name = mandant_row[0] - mandant_level_value = mandant_row[1] - - # User + # Mandant laden cur.execute(""" - SELECT id, name, email, status + SELECT name, level + FROM mandant + WHERE id = %s + """, (current_mandant_id,)) + mandant_row = cur.fetchone() + + if not mandant_row: + cur.close() + conn.close() + abort(404) + + mandant_name = mandant_row[0] + mandant_level = mandant_row[1] + + # User des Mandanten + cur.execute(""" + SELECT id, name, email, status, level FROM app_user WHERE mandant_id = %s + ORDER BY name, email """, (current_mandant_id,)) users = fetchall_dict(cur) - # Kurse + # Alle aktiven Kurse cur.execute(""" - SELECT id, code, title, min_level + SELECT id, code, title, min_level, sort_order FROM course WHERE is_active = TRUE + ORDER BY code, sort_order, id """) all_courses = fetchall_dict(cur) + # Reporting basiert auf Mandanten-Level, NICHT auf User-Level available_courses = [ c for c in all_courses if is_course_allowed_for_level(c["code"], mandant_level) ] - # Assessments (nur bestanden) + # Erfolgreiche Assessments cur.execute(""" - SELECT user_id, course_id, score, created_at + SELECT user_id, course_id, score, passed, created_at FROM user_assessment WHERE passed = TRUE """) - assessments = fetchall_dict(cur) + assessment_rows = fetchall_dict(cur) cur.close() conn.close() - passed_map = {(a["user_id"], a["course_id"]): a for a in assessments} + # Letzten erfolgreichen Abschluss je User/Kurs merken + passed_map = {} + for row in assessment_rows: + key = (row["user_id"], row["course_id"]) + if key not in passed_map or row["created_at"] > passed_map[key]["created_at"]: + passed_map[key] = row + + # Filterlisten + available_courses = sorted(available_courses, key=lambda c: c["code"] or "") + user_list = sorted( + [{"id": u["id"], "name": u["name"]} for u in users], + key=lambda x: (x["name"] or "").lower() + ) + + # Detaildaten + detail_rows = [] + completed_count = 0 + open_count = 0 detail_rows = [] completed_count = 0 open_count = 0 - for u in users: - for c in available_courses: - a = passed_map.get((u["id"], c["id"])) - done = a is not None + for user in users: + user_allowed_courses = [ + c for c in all_courses + if is_course_allowed_for_level(c["code"], user["level"]) + ] + + for course in user_allowed_courses: + passed_row = passed_map.get((user["id"], course["id"])) + done = passed_row is not None if done: completed_count += 1 @@ -2281,37 +2414,39 @@ def reporting_assessments(): open_count += 1 detail_rows.append({ - "user_name": u["name"], - "user_email": u["email"], - "course_code": c["code"], - "course_title": c["title"], + "user_id": user["id"], + "user_name": user["name"], + "user_email": user["email"], + "user_status": user["status"], + "user_level": user["level"], + "user_level_label": format_level(user["level"]), + "course_id": course["id"], + "course_code": course["code"], + "course_title": course["title"], "done": done, "done_label": "erledigt" if done else "offen", - "completed_at": a["created_at"] if done else None, - "score": a["score"] if done else None, + "completed_at": passed_row["created_at"] if done else None, + "score": passed_row["score"] if done else None, }) total_expected = len(users) * len(available_courses) - progress_percent = int((completed_count / total_expected) * 100) if total_expected else 0 - - users = sorted(users, key=lambda u: (u["name"] or "", u["email"] or "")) - available_courses = sorted(available_courses, key=lambda c: c["code"]) - - user_list = sorted( - [{"id": u["id"], "name": u["name"]} for u in users], - key=lambda x: x["name"] or "" - ) + progress_percent = int((completed_count / total_expected) * 100) if total_expected > 0 else 0 return render_template( "reporting_assessments.html", + page_title="Assessment Reporting", + active_page="reporting_assessments", mandant_name=mandant_name, - mandant_level_label=format_level(mandant_level_value), + mandant_level=mandant_level, + mandant_level_label=format_level(mandant_level), available_courses=available_courses, user_list=user_list, detail_rows=detail_rows, + dashboard_total_users=len(users), + dashboard_total_courses=len(available_courses), + dashboard_total_expected=total_expected, dashboard_completed=completed_count, dashboard_open=open_count, - dashboard_total_expected=total_expected, dashboard_progress_percent=progress_percent, **get_current_user() ) diff --git a/app/flask-postgres/app/certificates.py b/app/flask-postgres/app/certificates.py index f9ee5bd..6e4bb92 100644 --- a/app/flask-postgres/app/certificates.py +++ b/app/flask-postgres/app/certificates.py @@ -146,8 +146,10 @@ def generate_certificate_pdf_for_user(user_id, module_code): reference_url = f"https://cert.compliance-verification.info/verification/{guid_value}" pdf_path = os.path.join(CERT_OUTPUT_DIR, f"{guid_value}.pdf") + template_name = get_certificate_template_for_module(data["module_code"]) + html = render_template( - "certificate_template.html", + template_name, user_name=data["user_name"], mandant_name=data["mandant_name"], module_code=data["module_code"], @@ -281,4 +283,15 @@ def ensure_certificate_for_user_module(user_id, module_code): return guid_value def is_module_completed_for_user(user_id, module_code): - return get_user_module_completion(user_id, module_code) is not None \ No newline at end of file + return get_user_module_completion(user_id, module_code) is not None + +def get_certificate_template_for_module(module_code): + module_code = (module_code or "").upper() + + mapping = { + "A": "certificates/certificate_A.html", + "B": "certificates/certificate_B.html", + "C": "certificates/certificate_C.html", + } + + return mapping.get(module_code, "certificates/certificate_A.html") \ No newline at end of file diff --git a/app/flask-postgres/app/permissions.py b/app/flask-postgres/app/permissions.py index 9de5c3e..c520845 100644 --- a/app/flask-postgres/app/permissions.py +++ b/app/flask-postgres/app/permissions.py @@ -28,27 +28,20 @@ def is_video_allowed_for_level(filename: str, mandant_level: int | None) -> bool -def is_course_allowed_for_level(code: str, mandant_level: int | None) -> bool: - if mandant_level is None: +def is_course_allowed_for_level(course_code, level): + if level is None: return False - prefix = (code or "")[:1].upper() + first_char = (course_code or "")[:1].upper() - # 0 = Admin = alles - if mandant_level == 0: + if level == 0: return True - - # 1 = Gold = A + B + C - if mandant_level == 1: - return prefix in ("A", "B", "C") - - # 2 = Silber = A + B - if mandant_level == 2: - return prefix in ("A", "B") - - # 3 = Bronze = A - if mandant_level == 3: - return prefix == "A" + if level == 1: + return first_char in ("A", "B", "C") + if level == 2: + return first_char in ("A", "B") + if level == 3: + return first_char == "A" return False diff --git a/app/flask-postgres/app/security.py b/app/flask-postgres/app/security.py index 3e09bcd..4486cc6 100644 --- a/app/flask-postgres/app/security.py +++ b/app/flask-postgres/app/security.py @@ -67,6 +67,7 @@ def get_current_user(): "user_name": session.get("user_name"), "user_email": session.get("user_email"), "mandant_id": session.get("mandant_id"), + "user_level": session.get("user_level"), "is_logged_in": bool(session.get("user_id")), "is_admin": user_is_admin() if session.get("user_id") else False, "is_user_admin": user_is_user_admin() if session.get("user_id") else False, diff --git a/app/flask-postgres/app/templates/base.html b/app/flask-postgres/app/templates/base.html index b853437..9ff368d 100644 --- a/app/flask-postgres/app/templates/base.html +++ b/app/flask-postgres/app/templates/base.html @@ -66,7 +66,7 @@ Userverwaltung Zertifikate - Reporting + Reporting {% endif %} diff --git a/app/flask-postgres/app/templates/certificates/certificate_A.html b/app/flask-postgres/app/templates/certificates/certificate_A.html new file mode 100644 index 0000000..6a5a5e9 --- /dev/null +++ b/app/flask-postgres/app/templates/certificates/certificate_A.html @@ -0,0 +1,299 @@ + + +
+ ++ erfolgreich absolviert und alle vorgesehenen Prüfungen bestanden hat. +
+ ++ Im Rahmen der Schulung wurden strukturierte Kenntnisse im Bereich des Einsatzes + von Künstlicher Intelligenz in Organisationen vermittelt. +
+ ++ Dieser Nachweis dokumentiert ausschließlich die erfolgreiche Teilnahme an der Schulung + sowie das Bestehen der innerhalb der Plattform vorgesehenen Prüfungen. +
+ ++ Er stellt keine Prüfung, Bewertung oder Bestätigung der tatsächlichen Umsetzung + im Unternehmen dar. +
+ ++ Ebenso handelt es sich nicht um eine Bestätigung rechtlicher Konformität, + keine behördliche Anerkennung und keinen Nachweis im Sinne gesetzlicher + oder normativer Anforderungen. +
+ ++ erfolgreich absolviert und alle vorgesehenen Prüfungen bestanden hat. +
+ ++ Im Rahmen der Schulung wurden strukturierte Kenntnisse im Bereich des Einsatzes + von Künstlicher Intelligenz in Organisationen vermittelt. +
+ ++ Dieser Nachweis dokumentiert ausschließlich die erfolgreiche Teilnahme an der Schulung + sowie das Bestehen der innerhalb der Plattform vorgesehenen Prüfungen. +
+ ++ Er stellt keine Prüfung, Bewertung oder Bestätigung der tatsächlichen Umsetzung + im Unternehmen dar. +
+ ++ Ebenso handelt es sich nicht um eine Bestätigung rechtlicher Konformität, + keine behördliche Anerkennung und keinen Nachweis im Sinne gesetzlicher + oder normativer Anforderungen. +
+ ++ erfolgreich absolviert und alle vorgesehenen Prüfungen bestanden hat. +
+ ++ Im Rahmen der Schulung wurden strukturierte Kenntnisse im Bereich des Einsatzes + von Künstlicher Intelligenz in Organisationen vermittelt. +
+ ++ Dieser Nachweis dokumentiert ausschließlich die erfolgreiche Teilnahme an der Schulung + sowie das Bestehen der innerhalb der Plattform vorgesehenen Prüfungen. +
+ ++ Er stellt keine Prüfung, Bewertung oder Bestätigung der tatsächlichen Umsetzung + im Unternehmen dar. +
+ ++ Ebenso handelt es sich nicht um eine Bestätigung rechtlicher Konformität, + keine behördliche Anerkennung und keinen Nachweis im Sinne gesetzlicher + oder normativer Anforderungen. +
+ +- Benutzer des aktuellen Mandanten ({{ mandant_name }}). -
+Benutzer des aktuellen Mandanten.
- Level des Mandanten: {{ mandant_level_label }} -
-| ID | -Name | -Status | -Aktionen | -|
|---|---|---|---|---|
| {{ user.id }} | -{{ user.name }} | -{{ user.email }} | -{{ user.status_label }} | -
-
- Bearbeiten
-
- {% if user.can_delete %}
-
- {% else %}
-
- {% endif %}
-
- |
-
| ID | +Name | +Status | +Level | ++ | |
|---|---|---|---|---|---|
| {{ user.id }} | + +{{ user.name }} | + +{{ user.email }} | + ++ {% if user.status == 1 %} + Aktiv + {% else %} + Deaktiviert + {% endif %} + | + ++ + {{ user.level_label }} + + | + ++ + + ✏️ + + + {% if user.id != session.user_id %} + + {% endif %} + + | +
Benutzer im aktuellen Mandanten ändern, Gruppen zuweisen und Passwort zurücksetzen.
++ Benutzer im aktuellen Mandanten ändern, Gruppen zuweisen und Passwort zurücksetzen. +