From 68b2dd61473589fd4688ba4a9e95404de80d5d5c Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Wed, 18 Oct 2023 23:21:49 +0530 Subject: [PATCH] feat: quiz question from UI --- .../doctype/lms_question/lms_question.json | 26 +++- lms/lms/doctype/lms_question/lms_question.py | 16 +++ lms/lms/doctype/lms_quiz/lms_quiz.json | 14 ++- lms/lms/doctype/lms_quiz/lms_quiz.py | 33 +++-- lms/public/css/style.css | 4 + lms/www/batch/quiz.html | 33 +++-- lms/www/batch/quiz.js | 116 +++++++++++++----- lms/www/batch/quiz.py | 9 +- 8 files changed, 178 insertions(+), 73 deletions(-) diff --git a/lms/lms/doctype/lms_question/lms_question.json b/lms/lms/doctype/lms_question/lms_question.json index a7852390..90f820c7 100644 --- a/lms/lms/doctype/lms_question/lms_question.json +++ b/lms/lms/doctype/lms_question/lms_question.json @@ -194,7 +194,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2023-10-16 11:39:39.757008", + "modified": "2023-10-18 21:58:42.653317", "modified_by": "Administrator", "module": "LMS", "name": "LMS Question", @@ -212,6 +212,30 @@ "role": "System Manager", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Moderator", + "share": 1, + "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Course Creator", + "share": 1, + "write": 1 } ], "sort_field": "modified", diff --git a/lms/lms/doctype/lms_question/lms_question.py b/lms/lms/doctype/lms_question/lms_question.py index ede8a070..414baf02 100644 --- a/lms/lms/doctype/lms_question/lms_question.py +++ b/lms/lms/doctype/lms_question/lms_question.py @@ -4,6 +4,7 @@ import frappe from frappe import _ from frappe.model.document import Document +from lms.lms.utils import has_course_instructor_role, has_course_moderator_role class LMSQuestion(Document): @@ -46,3 +47,18 @@ def get_correct_options(question): "is_correct_4", ] return list(filter(lambda x: question.get(x) == 1, correct_option_fields)) + + +@frappe.whitelist() +def get_question_details(question): + if not has_course_instructor_role() or not has_course_moderator_role(): + return + + fields = ["question", "type", "name"] + for i in range(1, 5): + fields.append(f"option_{i}") + fields.append(f"is_correct_{i}") + fields.append(f"explanation_{i}") + fields.append(f"possibility_{i}") + + return frappe.db.get_value("LMS Question", question, fields, as_dict=1) diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.json b/lms/lms/doctype/lms_quiz/lms_quiz.json index 202667f5..04f16894 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.json +++ b/lms/lms/doctype/lms_quiz/lms_quiz.json @@ -121,7 +121,7 @@ ], "index_web_pages_for_search": 1, "links": [], - "modified": "2023-10-17 15:25:25.830927", + "modified": "2023-10-18 22:50:58.252350", "modified_by": "Administrator", "module": "LMS", "name": "LMS Quiz", @@ -150,6 +150,18 @@ "role": "Moderator", "share": 1, "write": 1 + }, + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "Course Creator", + "share": 1, + "write": 1 } ], "show_title_field_in_link": 1, diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.py b/lms/lms/doctype/lms_quiz/lms_quiz.py index fa1fe0e8..92057ea1 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.py +++ b/lms/lms/doctype/lms_quiz/lms_quiz.py @@ -114,13 +114,19 @@ def quiz_summary(quiz, results): @frappe.whitelist() def save_quiz( - quiz_title, max_attempts=1, quiz=None, show_answers=1, show_submission_history=0 + quiz_title, + passing_percentage, + max_attempts=0, + quiz=None, + show_answers=1, + show_submission_history=0, ): if not has_course_moderator_role() or not has_course_instructor_role(): return values = { "title": quiz_title, + "passing_percentage": passing_percentage, "max_attempts": max_attempts, "show_answers": show_answers, "show_submission_history": show_submission_history, @@ -132,38 +138,27 @@ def save_quiz( else: doc = frappe.new_doc("LMS Quiz") doc.update(values) - doc.save(ignore_permissions=True) + doc.save() return doc.name @frappe.whitelist() def save_question(quiz, values, index): values = frappe._dict(json.loads(values)) - for value in values: - validate_correct_answers(value) + validate_correct_answers(values) if values.get("name"): - doc = frappe.get_doc("LMS Quiz Question", values.get("name")) + doc = frappe.get_doc("LMS Question", values.get("name")) else: - doc = frappe.new_doc("LMS Quiz Question") + doc = frappe.new_doc("LMS Question") doc.update( { - "question": values["question"], + "question": values.question, "type": values["type"], } ) - if not values.get("name"): - doc.update( - { - "parent": quiz, - "parenttype": "LMS Quiz", - "parentfield": "questions", - "idx": index, - } - ) - for num in range(1, 5): if values.get(f"option_{num}"): doc.update( @@ -187,9 +182,9 @@ def save_question(quiz, values, index): } ) - doc.save(ignore_permissions=True) + doc.save() - return quiz + return doc.name @frappe.whitelist() diff --git a/lms/public/css/style.css b/lms/public/css/style.css index aa02192b..acc05bee 100644 --- a/lms/public/css/style.css +++ b/lms/public/css/style.css @@ -2474,4 +2474,8 @@ select { .modal-body .ql-container { max-height: unset !important; +} + +.questions-table .row-index { + display: none; } \ No newline at end of file diff --git a/lms/www/batch/quiz.html b/lms/www/batch/quiz.html index 6c829989..456aca84 100644 --- a/lms/www/batch/quiz.html +++ b/lms/www/batch/quiz.html @@ -18,18 +18,10 @@ {{ QuizDetails(quiz) }} {% if quiz.questions %}
-
- {{ _("Questions") }} -
- - +
{% endif %} @@ -60,11 +52,6 @@
- {% if quiz.name %} - - {% endif %} @@ -99,11 +86,23 @@ {{ _("Enter the maximum number of times a user can attempt this quiz") }}
- {% set max_attempts = quiz.max_attempts if quiz.name else 1 %} + {% set max_attempts = quiz.max_attempts if quiz.name else 0 %}
+
+
+ {{ _("Passing Percentage") }} +
+
+ {{ _("Minimum percentage required to pass this quiz.") }} +
+
+ +
+
+
{% set show_answers = quiz.show_answers or not quiz.name %}