feat: add questions from LMS Portal
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -16,18 +16,9 @@
|
||||
{% macro QuizForm(quiz) %}
|
||||
<div id="quiz-form" {% if quiz.name %} data-name="{{ quiz.name }}" data-index="{{ quiz.questions | length }}" {% endif %}>
|
||||
{{ QuizDetails(quiz) }}
|
||||
{% if quiz.questions %}
|
||||
<div class="field-group">
|
||||
<div class="questions-table"></div>
|
||||
<!-- <button class="btn btn-secondary btn-sm btn-add-question mt-4">
|
||||
{{ _("New Question") }}
|
||||
</button> -->
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if quiz.name and not quiz.questions | length %}
|
||||
{{ EmptyState() }}
|
||||
{% endif %}
|
||||
<div class="field-group">
|
||||
<div class="questions-table"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
@@ -153,7 +144,7 @@
|
||||
{{ super() }}
|
||||
{% if has_course_instructor_role() or has_course_moderator_role() %}
|
||||
<script>
|
||||
const quiz_questions = {{ quiz.questions }}
|
||||
const quiz_questions = {{ quiz.questions or [] }}
|
||||
</script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -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"),
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user