diff --git a/app/flask-postgres/app/app.py b/app/flask-postgres/app/app.py index dc4074b..a34057e 100644 --- a/app/flask-postgres/app/app.py +++ b/app/flask-postgres/app/app.py @@ -2126,4 +2126,103 @@ def pwdchange(): form_error=form_error, success_message=success_message, **get_current_user() + ) + +@app.route("/reporting/assessments") +@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 + cur.execute(""" + SELECT id, name, email, status + FROM app_user + WHERE mandant_id = %s + """, (current_mandant_id,)) + users = fetchall_dict(cur) + + # Kurse + cur.execute(""" + SELECT id, code, title, min_level + FROM course + WHERE is_active = TRUE + """) + all_courses = fetchall_dict(cur) + + available_courses = [ + c for c in all_courses + if is_course_allowed_for_level(c["code"], mandant_level) + ] + + # Assessments (nur bestanden) + cur.execute(""" + SELECT user_id, course_id, score, created_at + FROM user_assessment + WHERE passed = TRUE + """) + assessments = fetchall_dict(cur) + + cur.close() + conn.close() + + passed_map = {(a["user_id"], a["course_id"]): a for a in assessments} + + 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 + + if done: + completed_count += 1 + else: + open_count += 1 + + detail_rows.append({ + "user_name": u["name"], + "user_email": u["email"], + "course_code": c["code"], + "course_title": c["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, + }) + + 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 "" + ) + + return render_template( + "reporting_assessments.html", + mandant_name=mandant_name, + mandant_level_label=format_level(mandant_level_value), + available_courses=available_courses, + user_list=user_list, + detail_rows=detail_rows, + dashboard_completed=completed_count, + dashboard_open=open_count, + dashboard_total_expected=total_expected, + dashboard_progress_percent=progress_percent, + **get_current_user() ) \ No newline at end of file diff --git a/app/flask-postgres/app/templates/base.html b/app/flask-postgres/app/templates/base.html index b22e8de..e6201e5 100644 --- a/app/flask-postgres/app/templates/base.html +++ b/app/flask-postgres/app/templates/base.html @@ -42,6 +42,7 @@ {% endif %} {% if is_user_admin %} Useradministration + Reporting {% endif %} {% if is_contentmanager %} Dokumente diff --git a/app/flask-postgres/app/templates/reporting_assessments.html b/app/flask-postgres/app/templates/reporting_assessments.html new file mode 100644 index 0000000..822aa57 --- /dev/null +++ b/app/flask-postgres/app/templates/reporting_assessments.html @@ -0,0 +1,112 @@ +{% extends "base.html" %} + +{% block content %} + +
Mandant: {{ mandant_name }} ({{ mandant_level_label }})
+ + +| User | +Kurs | +Status | +Datum | +
|---|---|---|---|
| {{ r.user_name }} | +{{ r.course_code }} - {{ r.course_title }} | +{{ r.done_label }} | ++ {% if r.completed_at %} + {{ r.completed_at.strftime("%d.%m.%Y") }} + {% else %} + - + {% endif %} + | +