diff --git a/lms/lms/doctype/course_evaluator/course_evaluator.py b/lms/lms/doctype/course_evaluator/course_evaluator.py
index 282881e4..33b5ed1c 100644
--- a/lms/lms/doctype/course_evaluator/course_evaluator.py
+++ b/lms/lms/doctype/course_evaluator/course_evaluator.py
@@ -33,6 +33,18 @@ class CourseEvaluator(Document):
frappe.throw(_("Slot Times are overlapping for some schedules."))
@frappe.whitelist()
-def get_schedule(course):
+def get_schedule(course, date):
evaluator = frappe.db.get_value("LMS Course", course, "evaluator")
- return frappe.get_all("Evaluator Schedule", filters={"parent": evaluator}, fields=["day", "start_time", "end_time"])
+ all_slots = frappe.get_all("Evaluator Schedule",
+ filters = { "parent": evaluator },
+ fields = ["day", "start_time", "end_time"])
+ booked_slots = frappe.get_all("LMS Certificate Request",
+ filters = {"course": course, "date": date},
+ fields = ["start_time"])
+
+ for slot in booked_slots:
+ same_slot = list(filter(lambda x: x.start_time == slot.start_time, all_slots))
+ if len(same_slot):
+ all_slots.remove(same_slot[0])
+
+ return all_slots
diff --git a/lms/lms/doctype/lms_course/lms_course.json b/lms/lms/doctype/lms_course/lms_course.json
index 76cfcb11..8aa9b069 100644
--- a/lms/lms/doctype/lms_course/lms_course.json
+++ b/lms/lms/doctype/lms_course/lms_course.json
@@ -191,6 +191,7 @@
"fieldname": "evaluator",
"fieldtype": "Link",
"label": "Evaluator",
+ "mandatory_depends_on": "eval: doc.grant_certificate_after == \"Evaluation\"",
"options": "Course Evaluator"
},
{
@@ -236,7 +237,7 @@
"link_fieldname": "course"
}
],
- "modified": "2022-04-07 12:27:05.353788",
+ "modified": "2022-04-08 14:36:22.254656",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Course",
diff --git a/lms/public/css/style.css b/lms/public/css/style.css
index 1d953fee..9c1b0986 100644
--- a/lms/public/css/style.css
+++ b/lms/public/css/style.css
@@ -1410,3 +1410,7 @@ pre {
.course-content-parent .course-details-outline .course-home-headings {
display: none;
}
+
+.btn-outline-primary {
+ border: 1px solid var(--primary-color);
+}
diff --git a/lms/www/batch/learn.html b/lms/www/batch/learn.html
index a9924c1d..9b218b71 100644
--- a/lms/www/batch/learn.html
+++ b/lms/www/batch/learn.html
@@ -34,11 +34,11 @@
{% macro BreadCrumb(course, lesson) %}
{% endmacro %}
@@ -94,7 +94,7 @@
{{ render_html(lesson.body) }}
{% else %}
-
{{ _("Start Learning") }}
+
{{ _("Start Learning") }}
{{ _("This lesson is not available for preview. Please join the course to access it.") }}
{% endif %}
diff --git a/lms/www/batch/learn.js b/lms/www/batch/learn.js
index 21521e2f..5520e8f6 100644
--- a/lms/www/batch/learn.js
+++ b/lms/www/batch/learn.js
@@ -1,49 +1,53 @@
frappe.ready(() => {
- localStorage.removeItem($("#quiz-title").text());
- fetch_assignments();
+ localStorage.removeItem($("#quiz-title").text());
+ fetch_assignments();
- save_current_lesson();
+ save_current_lesson();
- $(".option").click((e) => {
- enable_check(e);
- })
+ $(".option").click((e) => {
+ enable_check(e);
+ })
- $(".mark-progress").click((e) => {
- mark_progress(e);
- });
+ $(".mark-progress").click((e) => {
+ mark_progress(e);
+ });
- $(".next").click((e) => {
- mark_progress(e);
- });
+ $(".next").click((e) => {
+ mark_progress(e);
+ });
- $("#summary").click((e) => {
- quiz_summary(e);
- });
+ $("#summary").click((e) => {
+ quiz_summary(e);
+ });
- $("#check").click((e) => {
- check_answer(e);
- });
+ $("#check").click((e) => {
+ check_answer(e);
+ });
- $("#next").click((e) => {
- mark_active_question(e);
- });
+ $("#next").click((e) => {
+ mark_active_question(e);
+ });
- $("#try-again").click((e) => {
- try_quiz_again(e);
- });
+ $("#try-again").click((e) => {
+ try_quiz_again(e);
+ });
- $("#certification").click((e) => {
- create_certificate(e);
- });
+ $("#certification").click((e) => {
+ create_certificate(e);
+ });
- $(".submit-work").click((e) => {
- attach_work(e);
- });
+ $(".submit-work").click((e) => {
+ attach_work(e);
+ });
- $(".clear-work").click((e) => {
- clear_work(e);
- });
+ $(".clear-work").click((e) => {
+ clear_work(e);
+ });
+
+ $(".join-batch").click((e) => {
+ join_course(e)
+ });
});
@@ -240,6 +244,36 @@ const add_to_local_storage = (quiz_name, current_index, answer, is_correct) => {
localStorage.setItem(quiz_name, JSON.stringify(quiz_stored))
};
+const join_course = (e) => {
+ e.preventDefault();
+ let course = $(e.currentTarget).attr("data-course")
+ if (frappe.session.user == "Guest") {
+ window.location.href = `/login?redirect-to=/courses/${course}`;
+ return;
+ }
+
+ let batch = $(e.currentTarget).attr("data-batch");
+ batch = batch ? decodeURIComponent(batch) : "";
+ frappe.call({
+ "method": "lms.lms.doctype.lms_batch_membership.lms_batch_membership.create_membership",
+ "args": {
+ "batch": batch ? batch : "",
+ "course": course
+ },
+ "callback": (data) => {
+ if (data.message == "OK") {
+ frappe.msgprint({
+ "title": __("Successfully Enrolled"),
+ "message": __("You are now a student of this course.")
+ });
+ setTimeout(function () {
+ window.location.href = `/courses/${course}/learn/1.1`;
+ }, 2000);
+ }
+ }
+ });
+};
+
const create_certificate = (e) => {
e.preventDefault();
course = $(".title").attr("data-course");
diff --git a/lms/www/courses/course.html b/lms/www/courses/course.html
index 418156d2..fff5f929 100644
--- a/lms/www/courses/course.html
+++ b/lms/www/courses/course.html
@@ -105,7 +105,7 @@
{{ _("You have opted to be notified for this course. You will receive an email when the course becomes available.") }}
- {% if certificate_request %}
+ {% if certificate_request and not certificate %}
{{ _("Evaluation On: ") }}
{{ _("{0} at {1}").format(frappe.utils.format_date(certificate_request.date, "medium"),
frappe.utils.format_time(certificate_request.start_time, "short")) }}
@@ -199,7 +199,6 @@
{% endif %}
- {% set certificate = is_certified(course.name) %}
{% set progress = frappe.utils.cint(membership.progress) %}
{% if membership and course.enable_certification %}
{% if certificate %}
@@ -225,7 +224,7 @@
@@ -238,8 +237,8 @@
@@ -256,6 +255,10 @@
{{ _("There are no slots available on this day.") }}
+
diff --git a/lms/www/courses/course.js b/lms/www/courses/course.js
index bed20644..dd6b102b 100644
--- a/lms/www/courses/course.js
+++ b/lms/www/courses/course.js
@@ -7,7 +7,7 @@ frappe.ready(() => {
});
$(".join-batch").click((e) => {
- join_course(e)
+ join_course(e);
});
$(".view-all-mentors").click((e) => {
@@ -46,10 +46,18 @@ frappe.ready(() => {
display_slots(e);
});
- $(document).on("click", ".slot", (e) => {
+ $("#submit-slot").click((e) => {
submit_slot(e);
});
+ $(".close-slot-modal").click((e) => {
+ close_slot_modal(e);
+ });
+
+ $(document).on("click", ".slot", (e) => {
+ select_slot(e);
+ });
+
$(document).scroll(function() {
let timer;
clearTimeout(timer);
@@ -93,31 +101,35 @@ var cancel_mentor_request = (e) => {
})
}
-var join_course = (e) => {
- e.preventDefault();
- var course = $(e.currentTarget).attr("data-course")
- if (frappe.session.user == "Guest") {
- window.location.href = `/login?redirect-to=/courses/${course}`;
- return;
- }
- var batch = $(e.currentTarget).attr("data-batch");
- batch = batch ? decodeURIComponent(batch) : "";
- frappe.call({
- "method": "lms.lms.doctype.lms_batch_membership.lms_batch_membership.create_membership",
- "args": {
- "batch": batch ? batch : "",
- "course": course
- },
- "callback": (data) => {
- if (data.message == "OK") {
- frappe.msgprint(__("You are now a student of this course."));
- setTimeout(function () {
- window.location.href = `/courses/${course}/learn/1.1`;
- }, 2000);
- }
+const join_course = (e) => {
+ e.preventDefault();
+ let course = $(e.currentTarget).attr("data-course");
+ if (frappe.session.user == "Guest") {
+ window.location.href = `/login?redirect-to=/courses/${course}`;
+ return;
}
- })
-}
+
+ let batch = $(e.currentTarget).attr("data-batch");
+ batch = batch ? decodeURIComponent(batch) : "";
+ frappe.call({
+ "method": "lms.lms.doctype.lms_batch_membership.lms_batch_membership.create_membership",
+ "args": {
+ "batch": batch ? batch : "",
+ "course": course
+ },
+ "callback": (data) => {
+ if (data.message == "OK") {
+ frappe.msgprint({
+ "title": __("Successfully Enrolled"),
+ "message": __("You are now a student of this course.")
+ });
+ setTimeout(function () {
+ window.location.href = `/courses/${course}/learn/1.1`;
+ }, 2000);
+ }
+ }
+ })
+};
var view_all_mentors = (e) => {
$(".wrapped").each((i, element) => {
@@ -251,29 +263,14 @@ const submit_for_review = (e) => {
};
const apply_cetificate = (e) => {
- frappe.call({
- method: "lms.lms.doctype.course_evaluator.course_evaluator.get_schedule",
- args: {
- "course": $(e.currentTarget).data("course")
- },
- callback: (data) => {
- let options = "";
- data.message.forEach((obj) => {
- options += ``;
- });
- e.preventDefault();
- $("#slot-modal .slots").html(options);
- $("#slot-modal").modal("show");
- }
- })
+ $("#slot-modal").modal("show");
+
+
};
const submit_slot = (e) => {
e.preventDefault();
- const slot = $(e.currentTarget);
+ const slot = window.selected_slot;
frappe.call({
method: "lms.lms.doctype.lms_certificate_request.lms_certificate_request.create_certificate_request",
args: {
@@ -294,17 +291,51 @@ const submit_slot = (e) => {
};
const display_slots = (e) => {
- const weekday = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
- const day = weekday[new Date($(e.currentTarget).val()).getDay()]
+ frappe.call({
+ method: "lms.lms.doctype.course_evaluator.course_evaluator.get_schedule",
+ args: {
+ "course": $(e.currentTarget).data("course"),
+ "date": $(e.currentTarget).val()
+ },
+ callback: (data) => {
+ let options = "";
+ data.message.forEach((obj) => {
+ options += ``;
+ });
+ e.preventDefault();
+ $("#slot-modal .slots").html(options);
+ const weekday = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
+ const day = weekday[new Date($(e.currentTarget).val()).getDay()]
- $(".slot").addClass("hide");
- $(".slot-label").addClass("hide");
+ $(".slot").addClass("hide");
+ $(".slot-label").addClass("hide");
- if ($(`[data-day='${day}']`).length) {
- $(".slot-label").removeClass("hide");
- $(`[data-day='${day}']`).removeClass("hide");
- $("#no-slots-message").addClass("hide");
- } else {
- $("#no-slots-message").removeClass("hide");
- }
+ if ($(`[data-day='${day}']`).length) {
+ $(".slot-label").removeClass("hide");
+ $(`[data-day='${day}']`).removeClass("hide");
+ $("#no-slots-message").addClass("hide");
+ } else {
+ $("#no-slots-message").removeClass("hide");
+ }
+ }
+ });
};
+
+const select_slot = (e) => {
+ $(".slot").removeClass("btn-outline-primary");
+ $(e.currentTarget).addClass("btn-outline-primary");
+ window.selected_slot = $(e.currentTarget);
+};
+
+const format_time = (time) => {
+ let date = moment(new Date()).format("ddd MMM DD YYYY");
+ return moment(`${date} ${time}`).format("HH:mm a");
+};
+
+const close_slot_modal = (e) => {
+ $("#slot-date").val("");
+ $(".slot-label").addClass("hide");
+}
diff --git a/lms/www/courses/course.py b/lms/www/courses/course.py
index 8bb55ffb..23598ba1 100644
--- a/lms/www/courses/course.py
+++ b/lms/www/courses/course.py
@@ -1,6 +1,6 @@
import frappe
from lms.lms.doctype.lms_settings.lms_settings import check_profile_restriction
-from lms.lms.utils import get_membership, is_instructor
+from lms.lms.utils import get_membership, is_instructor, is_certified
def get_context(context):
context.no_cache = 1
@@ -32,6 +32,7 @@ def get_context(context):
context.membership = membership
context.restriction = check_profile_restriction()
context.show_start_learing_cta = show_start_learing_cta(course, membership, context.restriction)
+ context.certificate = is_certified(course.name)
context.certificate_request = frappe.db.get_value("LMS Certificate Request",
{
"course": course.name,
diff --git a/lms/www/courses/index.py b/lms/www/courses/index.py
index f35b3cc7..d7fda57d 100644
--- a/lms/www/courses/index.py
+++ b/lms/www/courses/index.py
@@ -14,9 +14,9 @@ def get_context(context):
def get_courses():
courses = frappe.get_all("LMS Course",
- filters={"published": True},
- fields=["name", "upcoming", "title", "image", "enable_certification",
- "paid_certificate", "price_certificate", "currency"])
+ filters={"published": True},
+ fields=["name", "upcoming", "title", "image", "enable_certification",
+ "paid_certificate", "price_certificate", "currency"])
live_courses, upcoming_courses = [], []
for course in courses: