Merge pull request #654 from pateljannat/timetable-milestones
feat: timetable milestones
This commit is contained in:
@@ -52,6 +52,7 @@ const set_timetable = (frm) => {
|
||||
"start_time",
|
||||
"end_time",
|
||||
"duration",
|
||||
"milestone",
|
||||
],
|
||||
filters: {
|
||||
parent: frm.doc.timetable_template,
|
||||
@@ -82,6 +83,7 @@ const add_timetable_rows = (frm, timetable) => {
|
||||
.format("HH:mm")
|
||||
: null;
|
||||
child.duration = row.duration;
|
||||
child.milestone = row.milestone;
|
||||
});
|
||||
frm.refresh_field("timetable");
|
||||
|
||||
|
||||
@@ -12,9 +12,6 @@ from frappe.utils import (
|
||||
cint,
|
||||
format_date,
|
||||
format_datetime,
|
||||
add_to_date,
|
||||
getdate,
|
||||
get_datetime,
|
||||
)
|
||||
from lms.lms.utils import get_lessons, get_lesson_index, get_lesson_url
|
||||
from lms.www.utils import get_quiz_details, get_assignment_details
|
||||
@@ -325,7 +322,17 @@ def get_batch_timetable(batch):
|
||||
timetable = frappe.get_all(
|
||||
"LMS Batch Timetable",
|
||||
filters={"parent": batch},
|
||||
fields=["reference_doctype", "reference_docname", "date", "start_time", "end_time"],
|
||||
fields=[
|
||||
"reference_doctype",
|
||||
"reference_docname",
|
||||
"date",
|
||||
"start_time",
|
||||
"end_time",
|
||||
"milestone",
|
||||
"name",
|
||||
"idx",
|
||||
"parent",
|
||||
],
|
||||
order_by="date",
|
||||
)
|
||||
|
||||
@@ -362,20 +369,26 @@ def get_timetable_details(timetable):
|
||||
assessment = frappe._dict({"assessment_name": entry.reference_docname})
|
||||
|
||||
if entry.reference_doctype == "Course Lesson":
|
||||
entry.icon = "icon-list"
|
||||
course = frappe.db.get_value(
|
||||
entry.reference_doctype, entry.reference_docname, "course"
|
||||
)
|
||||
entry.url = get_lesson_url(course, get_lesson_index(entry.reference_docname))
|
||||
|
||||
entry.completed = (
|
||||
True
|
||||
if frappe.db.exists(
|
||||
"LMS Course Progress",
|
||||
{"lesson": entry.reference_docname, "member": frappe.session.user},
|
||||
)
|
||||
else False
|
||||
)
|
||||
|
||||
elif entry.reference_doctype == "LMS Quiz":
|
||||
entry.icon = "icon-quiz"
|
||||
entry.url = "/quizzes"
|
||||
details = get_quiz_details(assessment, frappe.session.user)
|
||||
entry.update(details)
|
||||
|
||||
elif entry.reference_doctype == "LMS Assignment":
|
||||
entry.icon = "icon-quiz"
|
||||
details = get_assignment_details(assessment, frappe.session.user)
|
||||
entry.update(details)
|
||||
|
||||
@@ -390,3 +403,40 @@ def send_email_to_students(batch, subject, reply_to, message):
|
||||
frappe.sendmail(
|
||||
recipients=students, subject=subject, reply_to=reply_to, message=message
|
||||
)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def is_milestone_complete(idx, batch):
|
||||
previous_rows = frappe.get_all(
|
||||
"LMS Batch Timetable",
|
||||
filters={"parent": batch, "idx": ["<", cint(idx)]},
|
||||
fields=["reference_doctype", "reference_docname", "idx"],
|
||||
order_by="idx",
|
||||
)
|
||||
|
||||
for row in previous_rows:
|
||||
if row.reference_doctype == "Course Lesson":
|
||||
if not frappe.db.exists(
|
||||
"LMS Course Progress",
|
||||
{"member": frappe.session.user, "lesson": row.reference_docname},
|
||||
):
|
||||
return False
|
||||
|
||||
if row.reference_doctype == "LMS Quiz":
|
||||
passing_percentage = frappe.db.get_value(
|
||||
row.reference_doctype, row.reference_docname, "passing_percentage"
|
||||
)
|
||||
if not frappe.db.exists(
|
||||
"LMS Quiz Submission",
|
||||
{"quiz": row.reference_docname, "member": frappe.session.user},
|
||||
):
|
||||
return False
|
||||
|
||||
if row.reference_doctype == "LMS Assignment":
|
||||
if not frappe.db.exists(
|
||||
"LMS Assignment Submission",
|
||||
{"assignment": row.reference_docname, "member": frappe.session.user},
|
||||
):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
"column_break_merq",
|
||||
"start_time",
|
||||
"end_time",
|
||||
"duration"
|
||||
"duration",
|
||||
"milestone"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -69,12 +70,17 @@
|
||||
"fieldname": "day",
|
||||
"fieldtype": "Int",
|
||||
"label": "Day"
|
||||
},
|
||||
{
|
||||
"fieldname": "milestone",
|
||||
"fieldtype": "Check",
|
||||
"label": "Milestone"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2023-10-03 17:40:31.530181",
|
||||
"modified": "2023-10-20 11:58:01.782921",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Batch Timetable",
|
||||
|
||||
@@ -65,7 +65,6 @@ def quiz_summary(quiz, results):
|
||||
correct = result["is_correct"][0]
|
||||
for point in result["is_correct"]:
|
||||
correct = correct and point
|
||||
|
||||
result["is_correct"] = correct
|
||||
|
||||
question_details = frappe.db.get_value(
|
||||
@@ -100,6 +99,8 @@ def quiz_summary(quiz, results):
|
||||
"score": score,
|
||||
"score_out_of": score_out_of,
|
||||
"member": frappe.session.user,
|
||||
"percentage": percentage,
|
||||
"passing_percentage": quiz_details.passing_percentage,
|
||||
}
|
||||
)
|
||||
submission.save(ignore_permissions=True)
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"score_out_of",
|
||||
"column_break_gkip",
|
||||
"percentage",
|
||||
"passing_percentage",
|
||||
"section_break_6",
|
||||
"result"
|
||||
],
|
||||
@@ -96,12 +97,20 @@
|
||||
"non_negative": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "passing_percentage",
|
||||
"fieldtype": "Int",
|
||||
"label": "Passing Percentage",
|
||||
"non_negative": 1,
|
||||
"read_only": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"in_create": 1,
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2023-10-17 13:07:27.979974",
|
||||
"modified": "2023-10-17 13:07:27.979975",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz Submission",
|
||||
|
||||
@@ -7,7 +7,8 @@ from frappe.model.document import Document
|
||||
|
||||
class LMSQuizSubmission(Document):
|
||||
def before_insert(self):
|
||||
self.set_percentage()
|
||||
if not self.percentage:
|
||||
self.set_percentage()
|
||||
|
||||
def set_percentage(self):
|
||||
if self.score and self.score_out_of:
|
||||
|
||||
@@ -686,7 +686,9 @@ const get_calendar_options = (element, calendar_id) => {
|
||||
],
|
||||
template: {
|
||||
time: function (event) {
|
||||
let hide = event.raw.completed ? "" : "hide";
|
||||
return `<div class="calendar-event-time">
|
||||
<img class='icon icon-sm pull-right ${hide}' src="/assets/lms/icons/check.svg">
|
||||
<div> ${frappe.datetime.get_time(event.start.d.d)} -
|
||||
${frappe.datetime.get_time(event.end.d.d)} </div>
|
||||
<div class="calendar-event-title"> ${event.title} </div>
|
||||
@@ -717,6 +719,11 @@ const create_events = (calendar, events, calendar_id) => {
|
||||
},
|
||||
raw: {
|
||||
url: event.url,
|
||||
milestone: event.milestone,
|
||||
name: event.name,
|
||||
idx: event.idx,
|
||||
parent: event.parent,
|
||||
completed: event.completed,
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -730,9 +737,28 @@ const add_links_to_events = (calendar) => {
|
||||
event_date = moment(event_date).format("YYYY-MM-DD");
|
||||
|
||||
let current_date = moment().format("YYYY-MM-DD");
|
||||
if (allow_future || moment(event_date).isSameOrBefore(current_date)) {
|
||||
window.open(event.raw.url, "_blank");
|
||||
}
|
||||
|
||||
if (!moment(event_date).isSameOrBefore(current_date) && !allow_future)
|
||||
return;
|
||||
|
||||
if (event.raw.milestone) {
|
||||
frappe.call({
|
||||
method: "lms.lms.doctype.lms_batch.lms_batch.is_milestone_complete",
|
||||
args: {
|
||||
idx: event.raw.idx,
|
||||
batch: event.raw.parent,
|
||||
},
|
||||
callback: (data) => {
|
||||
if (data.message) window.open(event.raw.url, "_blank");
|
||||
else
|
||||
frappe.show_alert({
|
||||
message:
|
||||
"Please complete all previous activities to proceed.",
|
||||
indicator: "red",
|
||||
});
|
||||
},
|
||||
});
|
||||
} else window.open(event.raw.url, "_blank");
|
||||
});
|
||||
};
|
||||
|
||||
@@ -755,17 +781,13 @@ const set_calendar_range = (calendar, events) => {
|
||||
).format("DD MMMM YYYY")}`
|
||||
);
|
||||
|
||||
if (week_start.diff(moment(events[0].date), "days") <= 0) {
|
||||
if (week_start.diff(moment(events[0].date), "days") <= 0)
|
||||
$("#prev-week").hide();
|
||||
} else {
|
||||
$("#prev-week").show();
|
||||
}
|
||||
else $("#prev-week").show();
|
||||
|
||||
if (week_end.diff(moment(events.slice(-1)[0].date), "days") > 0) {
|
||||
if (week_end.diff(moment(events.slice(-1)[0].date), "days") > 0)
|
||||
$("#next-week").hide();
|
||||
} else {
|
||||
$("#next-week").show();
|
||||
}
|
||||
else $("#next-week").show();
|
||||
};
|
||||
|
||||
const get_background_color = (doctype) => {
|
||||
|
||||
@@ -93,7 +93,7 @@ def get_assignment_details(assessment, member):
|
||||
"assignment": assessment.assessment_name,
|
||||
}
|
||||
)
|
||||
|
||||
assessment.completed = False
|
||||
if existing_submission:
|
||||
assessment.submission = frappe.db.get_value(
|
||||
"LMS Assignment Submission",
|
||||
@@ -101,6 +101,7 @@ def get_assignment_details(assessment, member):
|
||||
["name", "status", "comments"],
|
||||
as_dict=True,
|
||||
)
|
||||
assessment.completed = True
|
||||
|
||||
assessment.edit_url = f"/assignments/{assessment.assessment_name}"
|
||||
submission_name = existing_submission if existing_submission else "new-submission"
|
||||
@@ -112,7 +113,10 @@ def get_assignment_details(assessment, member):
|
||||
|
||||
|
||||
def get_quiz_details(assessment, member):
|
||||
assessment.title = frappe.db.get_value("LMS Quiz", assessment.assessment_name, "title")
|
||||
assessment_details = frappe.db.get_value(
|
||||
"LMS Quiz", assessment.assessment_name, ["title", "passing_percentage"], as_dict=1
|
||||
)
|
||||
assessment.title = assessment_details.title
|
||||
|
||||
existing_submission = frappe.get_all(
|
||||
"LMS Quiz Submission",
|
||||
@@ -120,13 +124,17 @@ def get_quiz_details(assessment, member):
|
||||
"member": member,
|
||||
"quiz": assessment.assessment_name,
|
||||
},
|
||||
["name", "score"],
|
||||
order_by="creation desc",
|
||||
["name", "score", "percentage"],
|
||||
order_by="percentage desc",
|
||||
)
|
||||
|
||||
if len(existing_submission):
|
||||
assessment.submission = existing_submission[0]
|
||||
|
||||
assessment.completed = False
|
||||
if assessment.submission:
|
||||
assessment.completed = True
|
||||
|
||||
assessment.edit_url = f"/quizzes/{assessment.assessment_name}"
|
||||
submission_name = (
|
||||
existing_submission[0].name if len(existing_submission) else "new-submission"
|
||||
|
||||
Reference in New Issue
Block a user