Kurse eingetragen und assessments
This commit is contained in:
parent
3f47532e2d
commit
7b97575c5f
@ -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()
|
||||||
|
)
|
||||||
Loading…
Reference in New Issue
Block a user