From 3f7d1b1e8330996322a00729bbab92fe9ad18590 Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Thu, 19 Oct 2023 22:15:30 +0530 Subject: [PATCH] feat: add questions from LMS Portal --- lms/lms/doctype/lms_quiz/lms_quiz.py | 68 +++++++++++++++++++++++----- lms/www/batch/quiz.html | 17 ++----- lms/www/batch/quiz.js | 37 ++++++++++++--- 3 files changed, 92 insertions(+), 30 deletions(-) diff --git a/lms/lms/doctype/lms_quiz/lms_quiz.py b/lms/lms/doctype/lms_quiz/lms_quiz.py index 92057ea1..13075e6f 100644 --- a/lms/lms/doctype/lms_quiz/lms_quiz.py +++ b/lms/lms/doctype/lms_quiz/lms_quiz.py @@ -17,7 +17,7 @@ from lms.lms.utils import ( class LMSQuiz(Document): def validate(self): self.validate_duplicate_questions() - self.set_total_marks() + self.total_marks = set_total_marks(self.name, self.questions) def validate_duplicate_questions(self): questions = [row.question for row in self.questions] @@ -27,13 +27,6 @@ class LMSQuiz(Document): _("Rows {0} have the duplicate questions.").format(frappe.bold(comma_and(rows))) ) - def set_total_marks(self): - marks = 0 - for question in self.questions: - marks += question.marks - - self.total_marks = marks - def autoname(self): if not self.name: self.name = generate_slug(self.title, "LMS Quiz") @@ -56,6 +49,13 @@ class LMSQuiz(Document): return result[0] +def set_total_marks(quiz, questions): + marks = 0 + for question in questions: + marks += question.get("marks") + return marks + + @frappe.whitelist() def quiz_summary(quiz, results): score = 0 @@ -116,6 +116,7 @@ def quiz_summary(quiz, results): def save_quiz( quiz_title, passing_percentage, + questions, max_attempts=0, quiz=None, show_answers=1, @@ -134,18 +135,64 @@ def save_quiz( if quiz: frappe.db.set_value("LMS Quiz", quiz, values) + update_questions(quiz, questions) return quiz else: doc = frappe.new_doc("LMS Quiz") doc.update(values) doc.save() + update_questions(doc.name, questions) return doc.name +def update_questions(quiz, questions): + questions = json.loads(questions) + + delete_questions(quiz, questions) + add_questions(quiz, questions) + frappe.db.set_value("LMS Quiz", quiz, "total_marks", set_total_marks(quiz, questions)) + + +def delete_questions(quiz, questions): + existing_questions = frappe.get_all( + "LMS Quiz Question", + { + "parent": quiz, + }, + pluck="name", + ) + + current_questions = [question.get("question_name") for question in questions] + + for question in existing_questions: + if question not in current_questions: + frappe.db.delete("LMS Quiz Question", question) + + +def add_questions(quiz, questions): + for index, question in enumerate(questions): + question = frappe._dict(question) + if question.question_name: + doc = frappe.get_doc("LMS Quiz Question", question.question_name) + else: + doc = frappe.new_doc("LMS Quiz Question") + doc.update( + { + "parent": quiz, + "parenttype": "LMS Quiz", + "parentfield": "questions", + "idx": index + 1, + } + ) + + doc.update({"question": question.question, "marks": question.marks}) + + doc.save() + + @frappe.whitelist() def save_question(quiz, values, index): values = frappe._dict(json.loads(values)) - validate_correct_answers(values) if values.get("name"): doc = frappe.get_doc("LMS Question", values.get("name")) @@ -182,8 +229,7 @@ def save_question(quiz, values, index): } ) - doc.save() - + doc.save() return doc.name diff --git a/lms/www/batch/quiz.html b/lms/www/batch/quiz.html index 456aca84..953e3496 100644 --- a/lms/www/batch/quiz.html +++ b/lms/www/batch/quiz.html @@ -16,18 +16,9 @@ {% macro QuizForm(quiz) %}
{{ QuizDetails(quiz) }} - {% if quiz.questions %} -
-
- -
- {% endif %} - - {% if quiz.name and not quiz.questions | length %} - {{ EmptyState() }} - {% endif %} +
+
+
{% endmacro %} @@ -153,7 +144,7 @@ {{ super() }} {% if has_course_instructor_role() or has_course_moderator_role() %} {% endif %} {% endblock %} \ No newline at end of file diff --git a/lms/www/batch/quiz.js b/lms/www/batch/quiz.js index ce7c93e9..6a0fc2ff 100644 --- a/lms/www/batch/quiz.js +++ b/lms/www/batch/quiz.js @@ -13,10 +13,6 @@ frappe.ready(() => { edit_question(e); }); - /* $(".btn-add-question").click((e) => { - show_question_modal(); - }); */ - $(document).on("click", ".questions-table .link-btn", (e) => { e.preventDefault(); fetch_question_data(e); @@ -131,6 +127,8 @@ const edit_question = (e) => { const save_quiz = (values) => { validate_mandatory(); + validate_questions(); + frappe.call({ method: "lms.lms.doctype.lms_quiz.lms_quiz.save_quiz", args: { @@ -138,6 +136,7 @@ const save_quiz = (values) => { max_attempts: $("#max-attempts").val(), passing_percentage: $("#passing-percentage").val(), quiz: $("#quiz-form").data("name") || "", + questions: this.table.get_value("questions"), show_answers: $("#show-answers").is(":checked") ? 1 : 0, show_submission_history: $("#show-submission-history").is( ":checked" @@ -171,6 +170,24 @@ const validate_mandatory = () => { }); }; +const validate_questions = () => { + let questions = this.table.get_value("questions"); + + if (!questions.length) { + frappe.throw(__("Please add a question.")); + } + + questions.forEach((question, index) => { + if (!question.question) { + frappe.throw(__("Please add question in row ") + (index + 1)); + } + + if (!question.marks) { + frappe.throw(__("Please add marks in row ") + (index + 1)); + } + }); +}; + const scroll_to_element = (element) => { if ($(element).length) { $([document.documentElement, document.body]).animate( @@ -224,16 +241,24 @@ const create_questions_table = () => { { fieldname: "question", fieldtype: "Link", - label: "Question", + label: __("Question"), options: "LMS Question", in_list_view: 1, only_select: 1, + reqd: 1, }, { fieldname: "marks", fieldtype: "Int", - label: "Marks", + label: __("Marks"), in_list_view: 1, + reqd: 1, + }, + { + fieldname: "question_name", + fieldname: "Link", + options: "LMS Quiz Question", + label: __("Question Name"), }, ], },