feat: quiz refactor
This commit is contained in:
@@ -98,7 +98,6 @@ override_doctype_class = {
|
||||
|
||||
doc_events = {
|
||||
"Discussion Reply": {"after_insert": "lms.lms.utils.create_notification_log"},
|
||||
"Course Lesson": {"on_update": "lms.lms.doctype.lms_quiz.lms_quiz.update_lesson_info"},
|
||||
}
|
||||
|
||||
# Scheduled Tasks
|
||||
|
||||
0
lms/lms/doctype/lms_question/__init__.py
Normal file
0
lms/lms/doctype/lms_question/__init__.py
Normal file
8
lms/lms/doctype/lms_question/lms_question.js
Normal file
8
lms/lms/doctype/lms_question/lms_question.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2023, Frappe and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
// frappe.ui.form.on("LMS Question", {
|
||||
// refresh(frm) {
|
||||
|
||||
// },
|
||||
// });
|
||||
221
lms/lms/doctype/lms_question/lms_question.json
Normal file
221
lms/lms/doctype/lms_question/lms_question.json
Normal file
@@ -0,0 +1,221 @@
|
||||
{
|
||||
"actions": [],
|
||||
"allow_rename": 1,
|
||||
"autoname": "format:QTS-{YYYY}-{#####}",
|
||||
"creation": "2023-10-10 10:24:14.035772",
|
||||
"default_view": "List",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"question",
|
||||
"type",
|
||||
"multiple",
|
||||
"section_break_ytxi",
|
||||
"option_1",
|
||||
"is_correct_1",
|
||||
"column_break_fpvl",
|
||||
"explanation_1",
|
||||
"section_break_eiaa",
|
||||
"option_2",
|
||||
"is_correct_2",
|
||||
"column_break_akwy",
|
||||
"explanation_2",
|
||||
"section_break_cwqv",
|
||||
"option_3",
|
||||
"is_correct_3",
|
||||
"column_break_atpl",
|
||||
"explanation_3",
|
||||
"section_break_yqel",
|
||||
"option_4",
|
||||
"is_correct_4",
|
||||
"column_break_lknb",
|
||||
"explanation_4",
|
||||
"section_break_hkfe",
|
||||
"possible_answer_1",
|
||||
"possible_answer_3",
|
||||
"column_break_wpjr",
|
||||
"possible_answer_2",
|
||||
"possible_answer_4"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "question",
|
||||
"fieldtype": "Text Editor",
|
||||
"in_list_view": 1,
|
||||
"label": "Question"
|
||||
},
|
||||
{
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Type",
|
||||
"options": "Choices\nUser Input"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.type == \"Choices\";",
|
||||
"fieldname": "section_break_ytxi",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "option_1",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Option 1",
|
||||
"mandatory_depends_on": "eval: doc.type == 'Choices'"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_correct_1",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Correct"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_fpvl",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "explanation_1",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Explanation"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval:doc.type == \"Choices\";",
|
||||
"fieldname": "section_break_eiaa",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "option_2",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Option 2",
|
||||
"mandatory_depends_on": "eval: doc.type == 'Choices'"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_correct_2",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Correct"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_akwy",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "explanation_2",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Explanation "
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.type == 'Choices'",
|
||||
"fieldname": "section_break_cwqv",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "option_3",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Option 3"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_correct_3",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Correct"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_atpl",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "explanation_3",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Explanation"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.type == 'Choices'",
|
||||
"fieldname": "section_break_yqel",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "option_4",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Option 4"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_correct_4",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Correct"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_lknb",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "explanation_4",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Explanation"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "multiple",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 1,
|
||||
"label": "Multiple Correct Answers"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.type == 'User Input'",
|
||||
"fieldname": "section_break_hkfe",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "possible_answer_1",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 1",
|
||||
"mandatory_depends_on": "eval: doc.type == 'User Input'"
|
||||
},
|
||||
{
|
||||
"fieldname": "possible_answer_3",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 3"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_wpjr",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "possible_answer_2",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 2"
|
||||
},
|
||||
{
|
||||
"fieldname": "possible_answer_4",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 4"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2023-10-10 16:03:38.776125",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Question",
|
||||
"naming_rule": "Expression",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"share": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"title_field": "question"
|
||||
}
|
||||
48
lms/lms/doctype/lms_question/lms_question.py
Normal file
48
lms/lms/doctype/lms_question/lms_question.py
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright (c) 2023, Frappe and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class LMSQuestion(Document):
|
||||
def validate(self):
|
||||
self.validate_correct_answers()
|
||||
|
||||
|
||||
def validate_correct_answers(question):
|
||||
if question.type == "Choices":
|
||||
validate_duplicate_options(question)
|
||||
validate_correct_options(question)
|
||||
|
||||
|
||||
def validate_duplicate_options(question):
|
||||
options = []
|
||||
|
||||
for num in range(1, 5):
|
||||
if question.get(f"option_{num}"):
|
||||
options.append(question.get(f"option_{num}"))
|
||||
|
||||
if len(set(options)) != len(options):
|
||||
frappe.throw(_("Duplicate options found for this question."))
|
||||
|
||||
|
||||
def validate_correct_options(question):
|
||||
correct_options = get_correct_options(question)
|
||||
|
||||
if len(correct_options) > 1:
|
||||
question.multiple = 1
|
||||
|
||||
if not len(correct_options):
|
||||
frappe.throw(_("At least one option must be correct for this question."))
|
||||
|
||||
|
||||
def get_correct_options(question):
|
||||
correct_option_fields = [
|
||||
"is_correct_1",
|
||||
"is_correct_2",
|
||||
"is_correct_3",
|
||||
"is_correct_4",
|
||||
]
|
||||
return list(filter(lambda x: question.get(x) == 1, correct_option_fields))
|
||||
9
lms/lms/doctype/lms_question/test_lms_question.py
Normal file
9
lms/lms/doctype/lms_question/test_lms_question.py
Normal file
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2023, Frappe and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestLMSQuestion(FrappeTestCase):
|
||||
pass
|
||||
@@ -7,6 +7,7 @@ from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cstr
|
||||
from lms.lms.utils import generate_slug, has_course_moderator_role, can_create_courses
|
||||
from lms.lms.doctype.lms_question.lms_question import validate_correct_answers
|
||||
|
||||
|
||||
class LMSQuiz(Document):
|
||||
@@ -14,9 +15,6 @@ class LMSQuiz(Document):
|
||||
if not self.name:
|
||||
self.name = generate_slug(self.title, "LMS Quiz")
|
||||
|
||||
def validate(self):
|
||||
validate_correct_answers(self.questions)
|
||||
|
||||
def get_last_submission_details(self):
|
||||
"""Returns the latest submission for this user."""
|
||||
user = frappe.session.user
|
||||
@@ -35,78 +33,6 @@ class LMSQuiz(Document):
|
||||
return result[0]
|
||||
|
||||
|
||||
def get_correct_options(question):
|
||||
correct_option_fields = [
|
||||
"is_correct_1",
|
||||
"is_correct_2",
|
||||
"is_correct_3",
|
||||
"is_correct_4",
|
||||
]
|
||||
return list(filter(lambda x: question.get(x) == 1, correct_option_fields))
|
||||
|
||||
|
||||
def validate_correct_answers(questions):
|
||||
for question in questions:
|
||||
if question.type == "Choices":
|
||||
validate_duplicate_options(question)
|
||||
validate_correct_options(question)
|
||||
else:
|
||||
validate_possible_answer(question)
|
||||
|
||||
|
||||
def validate_duplicate_options(question):
|
||||
options = []
|
||||
|
||||
for num in range(1, 5):
|
||||
if question.get(f"option_{num}"):
|
||||
options.append(question.get(f"option_{num}"))
|
||||
|
||||
if len(set(options)) != len(options):
|
||||
frappe.throw(
|
||||
_("Duplicate options found for this question: {0}").format(
|
||||
frappe.bold(question.question)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def validate_correct_options(question):
|
||||
correct_options = get_correct_options(question)
|
||||
|
||||
if len(correct_options) > 1:
|
||||
question.multiple = 1
|
||||
|
||||
if not len(correct_options):
|
||||
frappe.throw(
|
||||
_("At least one option must be correct for this question: {0}").format(
|
||||
frappe.bold(question.question)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def validate_possible_answer(question):
|
||||
possible_answers_fields = [
|
||||
"possibility_1",
|
||||
"possibility_2",
|
||||
"possibility_3",
|
||||
"possibility_4",
|
||||
]
|
||||
possible_answers = list(filter(lambda x: question.get(x), possible_answers_fields))
|
||||
|
||||
if not len(possible_answers):
|
||||
frappe.throw(
|
||||
_("Add at least one possible answer for this question: {0}").format(
|
||||
frappe.bold(question.question)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def update_lesson_info(doc, method):
|
||||
if doc.quiz_id:
|
||||
frappe.db.set_value(
|
||||
"LMS Quiz", doc.quiz_id, {"lesson": doc.name, "course": doc.course}
|
||||
)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def quiz_summary(quiz, results):
|
||||
score = 0
|
||||
@@ -171,7 +97,8 @@ def save_quiz(
|
||||
@frappe.whitelist()
|
||||
def save_question(quiz, values, index):
|
||||
values = frappe._dict(json.loads(values))
|
||||
validate_correct_answers([values])
|
||||
for value in values:
|
||||
validate_correct_answers(value)
|
||||
|
||||
if values.get("name"):
|
||||
doc = frappe.get_doc("LMS Quiz Question", values.get("name"))
|
||||
|
||||
@@ -5,209 +5,22 @@
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"question",
|
||||
"type",
|
||||
"options_section",
|
||||
"option_1",
|
||||
"is_correct_1",
|
||||
"column_break_5",
|
||||
"explanation_1",
|
||||
"section_break_5",
|
||||
"option_2",
|
||||
"is_correct_2",
|
||||
"column_break_10",
|
||||
"explanation_2",
|
||||
"column_break_4",
|
||||
"option_3",
|
||||
"is_correct_3",
|
||||
"column_break_15",
|
||||
"explanation_3",
|
||||
"section_break_11",
|
||||
"option_4",
|
||||
"is_correct_4",
|
||||
"column_break_20",
|
||||
"explanation_4",
|
||||
"section_break_mnhr",
|
||||
"possibility_1",
|
||||
"possibility_3",
|
||||
"column_break_vnaj",
|
||||
"possibility_2",
|
||||
"possibility_4",
|
||||
"section_break_c1lf",
|
||||
"multiple"
|
||||
"question"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "question",
|
||||
"fieldtype": "Text Editor",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"label": "Question",
|
||||
"options": "LMS Question",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "option_1",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Option 1",
|
||||
"mandatory_depends_on": "eval: doc.type == 'Choices'"
|
||||
},
|
||||
{
|
||||
"fieldname": "option_2",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Option 2",
|
||||
"mandatory_depends_on": "eval: doc.type == 'Choices'"
|
||||
},
|
||||
{
|
||||
"fieldname": "option_3",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Option 3"
|
||||
},
|
||||
{
|
||||
"fieldname": "option_4",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Option 4"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "option_1",
|
||||
"fieldname": "is_correct_1",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Correct"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "option_2",
|
||||
"fieldname": "is_correct_2",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Correct"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "option_3",
|
||||
"fieldname": "is_correct_3",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Correct"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"depends_on": "option_4",
|
||||
"fieldname": "is_correct_4",
|
||||
"fieldtype": "Check",
|
||||
"label": "Is Correct"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "multiple",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 1,
|
||||
"label": "Multiple Correct Answers",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.type == 'Choices'",
|
||||
"fieldname": "options_section",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.type == 'Choices'",
|
||||
"fieldname": "column_break_4",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.type == 'Choices'",
|
||||
"fieldname": "section_break_5",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.type == 'Choices'",
|
||||
"fieldname": "section_break_11",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"depends_on": "option_1",
|
||||
"fieldname": "explanation_1",
|
||||
"fieldtype": "Data",
|
||||
"label": "Explanation"
|
||||
},
|
||||
{
|
||||
"depends_on": "option_2",
|
||||
"fieldname": "explanation_2",
|
||||
"fieldtype": "Data",
|
||||
"label": "Explanation"
|
||||
},
|
||||
{
|
||||
"depends_on": "option_3",
|
||||
"fieldname": "explanation_3",
|
||||
"fieldtype": "Data",
|
||||
"label": "Explanation"
|
||||
},
|
||||
{
|
||||
"depends_on": "option_4",
|
||||
"fieldname": "explanation_4",
|
||||
"fieldtype": "Data",
|
||||
"label": "Explanation"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_5",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_10",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_15",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_20",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Select",
|
||||
"in_list_view": 1,
|
||||
"label": "Type",
|
||||
"options": "Choices\nUser Input"
|
||||
},
|
||||
{
|
||||
"depends_on": "eval: doc.type == 'User Input'",
|
||||
"fieldname": "section_break_mnhr",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "possibility_1",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 1",
|
||||
"mandatory_depends_on": "eval: doc.type == 'User Input'"
|
||||
},
|
||||
{
|
||||
"fieldname": "possibility_2",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 2"
|
||||
},
|
||||
{
|
||||
"fieldname": "possibility_3",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 3"
|
||||
},
|
||||
{
|
||||
"fieldname": "possibility_4",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 4"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_c1lf",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_vnaj",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2023-07-04 16:43:49.837134",
|
||||
"modified": "2023-10-10 15:42:51.791902",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz Question",
|
||||
|
||||
@@ -71,4 +71,6 @@ lms.patches.v1_0.publish_batches
|
||||
lms.patches.v1_0.publish_certificates
|
||||
lms.patches.v1_0.change_naming_for_batch_course #14-09-2023
|
||||
execute:frappe.permissions.reset_perms("LMS Enrollment")
|
||||
lms.patches.v1_0.create_student_role
|
||||
lms.patches.v1_0.create_student_role
|
||||
lms.patches.v1_0.mark_confirmation_for_batch_students
|
||||
lms.patches.v1_0.create_quiz_questions
|
||||
52
lms/patches/v1_0/create_quiz_questions.py
Normal file
52
lms/patches/v1_0/create_quiz_questions.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("lms", "doctype", "lms_question")
|
||||
frappe.reload_doc("lms", "doctype", "lms_quiz_question")
|
||||
|
||||
questions = frappe.get_all(
|
||||
"LMS Quiz Question",
|
||||
fields=[
|
||||
"name",
|
||||
"question",
|
||||
"type",
|
||||
"multiple",
|
||||
"option_1",
|
||||
"is_correct_1",
|
||||
"explanation_1",
|
||||
"option_2",
|
||||
"is_correct_2",
|
||||
"explanation_2",
|
||||
"option_3",
|
||||
"is_correct_3",
|
||||
"explanation_3",
|
||||
"option_4",
|
||||
"is_correct_4",
|
||||
"explanation_4",
|
||||
],
|
||||
)
|
||||
|
||||
for question in questions:
|
||||
doc = frappe.new_doc("LMS Question")
|
||||
doc.update(
|
||||
{
|
||||
"question": question.question,
|
||||
"type": question.type,
|
||||
"multiple": question.multiple,
|
||||
}
|
||||
)
|
||||
|
||||
for num in range(1, 5):
|
||||
if question.get(f"option_{num}"):
|
||||
doc.update(
|
||||
{
|
||||
f"option_{num}": question[f"option_{num}"],
|
||||
f"is_correct_{num}": question[f"is_correct_{num}"],
|
||||
f"explanation_{num}": question[f"explanation_{num}"],
|
||||
}
|
||||
)
|
||||
|
||||
doc.save()
|
||||
|
||||
frappe.db.set_value("LMS Quiz Question", question.name, "question", doc.name)
|
||||
9
lms/patches/v1_0/mark_confirmation_for_batch_students.py
Normal file
9
lms/patches/v1_0/mark_confirmation_for_batch_students.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("lms", "doctype", "batch_student")
|
||||
students = frappe.get_all("Batch Student", pluck="name")
|
||||
|
||||
for student in students:
|
||||
frappe.db.set_value("Batch Student", student, "confirmation_email_sent", 1)
|
||||
@@ -653,7 +653,7 @@ const setup_calendar = (events) => {
|
||||
const options = get_calendar_options(element, calendar_id);
|
||||
const calendar = new Calendar(container, options);
|
||||
this.calendar_ = calendar;
|
||||
console.log(options);
|
||||
|
||||
create_events(calendar, events);
|
||||
add_links_to_events(calendar, events);
|
||||
scroll_to_date(calendar, events);
|
||||
|
||||
Reference in New Issue
Block a user