Kurse eingetragen und assessments

This commit is contained in:
Bkolb 2026-04-09 20:53:49 +02:00
parent 3f47532e2d
commit 7b97575c5f

View File

@ -564,7 +564,7 @@ def admin_mandanten():
"level": level, "level": level,
"admin_name": admin_name, "admin_name": admin_name,
"admin_email": admin_email, "admin_email": admin_email,
"groups": selected_groups, "groups": selected_groups
} }
**get_current_user() **get_current_user()
@ -1612,3 +1612,315 @@ def impressum():
@app.route("/datenschutz") @app.route("/datenschutz")
def datenschutz(): def datenschutz():
return render_template("datenschutz.html", **get_current_user()) return render_template("datenschutz.html", **get_current_user())
@app.route("/admin/questions")
@admin_required
def admin_questions():
conn = get_connection()
cur = conn.cursor()
cur.execute("""
SELECT id, code, title
FROM course
ORDER BY min_level, sort_order, code
""")
courses = fetchall_dict(cur)
cur.close()
conn.close()
return render_template(
"admin_questions.html",
page_title="Assessment-Verwaltung",
active_page="admin_questions",
courses=courses,
**get_current_user()
)
@app.route("/admin/questions/<int:course_id>", methods=["GET", "POST"])
@admin_required
def admin_questions_course(course_id):
conn = get_connection()
cur = conn.cursor()
cur.execute("""
SELECT id, code, title
FROM course
WHERE id = %s
""", (course_id,))
course = fetchone_dict(cur)
if not course:
cur.close()
conn.close()
abort(404)
form_error = None
if request.method == "POST":
action = request.form.get("action")
if action == "create_question":
title = request.form.get("title", "").strip()
question_text = request.form.get("question_text", "").strip()
sort_order = request.form.get("sort_order", "0").strip()
answers = [
request.form.get("answer_1", "").strip(),
request.form.get("answer_2", "").strip(),
request.form.get("answer_3", "").strip(),
]
correct_index = request.form.get("correct_index", "").strip()
if not question_text:
form_error = "Fragetext ist Pflicht."
elif not all(answers):
form_error = "Alle drei Antwortmöglichkeiten müssen ausgefüllt sein."
elif correct_index not in ("1", "2", "3"):
form_error = "Bitte die richtige Antwort auswählen."
else:
cur.execute("""
INSERT INTO question (course_id, title, question_text, sort_order)
VALUES (%s, %s, %s, %s)
RETURNING id
""", (
course_id,
title or None,
question_text,
int(sort_order or 0)
))
question_id = cur.fetchone()[0]
for idx, answer_text in enumerate(answers, start=1):
cur.execute("""
INSERT INTO answer (question_id, answer_text, is_correct)
VALUES (%s, %s, %s)
""", (
question_id,
answer_text,
str(idx) == correct_index
))
conn.commit()
elif action == "delete_question":
question_id = int(request.form.get("question_id"))
cur.execute("""
DELETE FROM question
WHERE id = %s
AND course_id = %s
""", (question_id, course_id))
conn.commit()
elif action == "update_question":
question_id = int(request.form.get("question_id"))
title = request.form.get("title", "").strip()
question_text = request.form.get("question_text", "").strip()
sort_order = request.form.get("sort_order", "0").strip()
answers = [
request.form.get("answer_1", "").strip(),
request.form.get("answer_2", "").strip(),
request.form.get("answer_3", "").strip(),
]
correct_index = request.form.get("correct_index", "").strip()
if not question_text:
form_error = "Fragetext ist Pflicht."
elif not all(answers):
form_error = "Alle drei Antwortmöglichkeiten müssen ausgefüllt sein."
elif correct_index not in ("1", "2", "3"):
form_error = "Bitte die richtige Antwort auswählen."
else:
# Frage aktualisieren
cur.execute("""
UPDATE question
SET title = %s,
question_text = %s,
sort_order = %s
WHERE id = %s
AND course_id = %s
""", (
title or None,
question_text,
int(sort_order or 0),
question_id,
course_id
))
# Bestehende Antworten in stabiler Reihenfolge laden
cur.execute("""
SELECT id
FROM answer
WHERE question_id = %s
ORDER BY id
""", (question_id,))
existing_answers = cur.fetchall()
if len(existing_answers) == 3:
for idx, row in enumerate(existing_answers, start=1):
answer_id = row[0]
cur.execute("""
UPDATE answer
SET answer_text = %s,
is_correct = %s
WHERE id = %s
AND question_id = %s
""", (
answers[idx - 1],
str(idx) == correct_index,
answer_id,
question_id
))
else:
# Falls inkonsistent, Antworten neu aufbauen
cur.execute("""
DELETE FROM answer
WHERE question_id = %s
""", (question_id,))
for idx, answer_text in enumerate(answers, start=1):
cur.execute("""
INSERT INTO answer (question_id, answer_text, is_correct)
VALUES (%s, %s, %s)
""", (
question_id,
answer_text,
str(idx) == correct_index
))
conn.commit()
cur.execute("""
SELECT id, title, question_text, sort_order
FROM question
WHERE course_id = %s
ORDER BY sort_order, id
""", (course_id,))
questions = fetchall_dict(cur)
for q in questions:
cur.execute("""
SELECT id, answer_text, is_correct
FROM answer
WHERE question_id = %s
ORDER BY id
""", (q["id"],))
q["answers"] = fetchall_dict(cur)
cur.close()
conn.close()
return render_template(
"admin_questions_course.html",
page_title="Fragen verwalten",
active_page="admin_questions",
course=course,
questions=questions,
form_error=form_error,
**get_current_user()
)
@app.route("/course/<int:course_id>/assessment", methods=["GET", "POST"])
@login_required
def course_assessment(course_id):
mandant_level = session.get("mandant_level", 0)
conn = get_connection()
cur = conn.cursor()
cur.execute("""
SELECT id, code, title
FROM course
WHERE id = %s
""", (course_id,))
course = fetchone_dict(cur)
if not course:
cur.close()
conn.close()
abort(404)
if not is_course_allowed_for_level(course["code"], mandant_level):
cur.close()
conn.close()
abort(403)
if request.method == "GET":
cur.execute("""
SELECT id, title, question_text
FROM question
WHERE course_id = %s
ORDER BY RANDOM()
""", (course_id,))
questions = fetchall_dict(cur)
for q in questions:
cur.execute("""
SELECT id, answer_text
FROM answer
WHERE question_id = %s
ORDER BY RANDOM()
""", (q["id"],))
q["answers"] = fetchall_dict(cur)
cur.close()
conn.close()
return render_template(
"course_assessment.html",
page_title="Assessment",
active_page="courses",
course=course,
questions=questions,
**get_current_user()
)
# POST = Auswertung
cur.execute("""
SELECT id
FROM question
WHERE course_id = %s
""", (course_id,))
questions = fetchall_dict(cur)
total_questions = len(questions)
correct_answers = 0
for q in questions:
selected_answer_id = request.form.get(f"question_{q['id']}")
if not selected_answer_id:
continue
cur.execute("""
SELECT is_correct
FROM answer
WHERE id = %s
AND question_id = %s
""", (int(selected_answer_id), q["id"]))
row = cur.fetchone()
if row and row[0] is True:
correct_answers += 1
score = correct_answers
passed = total_questions > 0 and correct_answers == total_questions
cur.execute("""
INSERT INTO user_assessment (user_id, course_id, score, passed)
VALUES (%s, %s, %s, %s)
""", (session["user_id"], course_id, score, passed))
conn.commit()
cur.close()
conn.close()
return render_template(
"course_assessment_result.html",
page_title="Assessment Ergebnis",
active_page="courses",
course=course,
score=score,
total_questions=total_questions,
passed=passed,
**get_current_user()
)