fix: batch switch with query parameters
This commit is contained in:
@@ -19,7 +19,7 @@ class LMSBatch(Document):
|
||||
frappe.throw(_("You are not a mentor of the course {0}").format(course.title))
|
||||
|
||||
def after_insert(self):
|
||||
create_membership(batch=self.name, member_type="Mentor")
|
||||
create_membership(batch=self.name, course=self.course, member_type="Mentor")
|
||||
|
||||
def is_member(self, email, member_type=None):
|
||||
"""Checks if a person is part of a batch.
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
"course",
|
||||
"member_type",
|
||||
"role",
|
||||
"current_lesson",
|
||||
"is_current"
|
||||
"current_lesson"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -81,19 +80,11 @@
|
||||
"fieldtype": "Data",
|
||||
"label": "Memeber Username",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "is_current",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 1,
|
||||
"label": "Is Currently Being Used",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2021-06-14 10:24:35.425498",
|
||||
"modified": "2021-06-21 12:10:28.808803",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Batch Membership",
|
||||
|
||||
@@ -14,18 +14,22 @@ class LMSBatchMembership(Document):
|
||||
self.validate_membership_in_different_batch_same_course()
|
||||
|
||||
def validate_membership_in_same_batch(self):
|
||||
filters={
|
||||
"member": self.member,
|
||||
"course": self.course,
|
||||
"name": ["!=", self.name]
|
||||
}
|
||||
if self.batch:
|
||||
filters["batch"] = self.batch
|
||||
previous_membership = frappe.db.get_value("LMS Batch Membership",
|
||||
filters={
|
||||
"member": self.member,
|
||||
"batch": self.batch,
|
||||
"name": ["!=", self.name]
|
||||
},
|
||||
filters,
|
||||
fieldname=["member_type","member"],
|
||||
as_dict=1)
|
||||
|
||||
if previous_membership:
|
||||
member_name = frappe.db.get_value("User", self.member, "full_name")
|
||||
frappe.throw(_("{0} is already a {1} of {2}").format(member_name, previous_membership.member_type, self.batch))
|
||||
course_title = frappe.db.get_value("LMS Course", self.course, "title")
|
||||
frappe.throw(_("{0} is already a {1} of the course {2}").format(member_name, previous_membership.member_type, course_title))
|
||||
|
||||
def validate_membership_in_different_batch_same_course(self):
|
||||
course = frappe.db.get_value("LMS Batch", self.batch, "course")
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"field_order": [
|
||||
"title",
|
||||
"is_published",
|
||||
"disable_self_learning",
|
||||
"column_break_3",
|
||||
"short_code",
|
||||
"video_link",
|
||||
@@ -73,6 +74,12 @@
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Short Introduction",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "disable_self_learning",
|
||||
"fieldtype": "Check",
|
||||
"label": "Disable Self Learning"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
@@ -99,7 +106,7 @@
|
||||
"link_fieldname": "course"
|
||||
}
|
||||
],
|
||||
"modified": "2021-06-01 04:36:45.696776",
|
||||
"modified": "2021-06-21 11:34:04.552376",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Course",
|
||||
|
||||
@@ -192,16 +192,17 @@ class LMSCourse(Document):
|
||||
return
|
||||
return f"/courses/{self.name}/learn/{lesson_number}"
|
||||
|
||||
def get_current_membership(self, member):
|
||||
current_membership = frappe.get_all("LMS Batch Membership", {"member": member, "course": self.name, "is_current": 1}, ["name", "batch"])
|
||||
if len(current_membership):
|
||||
return current_membership[0]
|
||||
return frappe.db.get_value("LMS Batch Membership", {"member": member, "course": self.name}, ["name","batch"], as_dict=True)
|
||||
def get_membership(self, member, batch):
|
||||
filters = {
|
||||
"member": member,
|
||||
"course": self.name
|
||||
}
|
||||
if batch:
|
||||
filters["batch"] = batch
|
||||
return frappe.db.get_value("LMS Batch Membership", filters, ["name","batch", "current_lesson"], as_dict=True)
|
||||
|
||||
def get_all_memberships(self, member=frappe.session.user):
|
||||
print(member, frappe.session.user)
|
||||
all_memberships = frappe.get_all("LMS Batch Membership", {"member": member, "course": self.name}, ["batch", "is_current"])
|
||||
print(all_memberships)
|
||||
all_memberships = frappe.get_all("LMS Batch Membership", {"member": member, "course": self.name}, ["batch"])
|
||||
for membership in all_memberships:
|
||||
membership.batch_title = frappe.db.get_value("LMS Batch", membership.batch, "title")
|
||||
return all_memberships
|
||||
@@ -214,7 +215,6 @@ class LMSCourse(Document):
|
||||
if batch:
|
||||
filters["batch"] = batch
|
||||
|
||||
print(filters)
|
||||
memberships = frappe.get_all(
|
||||
"LMS Batch Membership",
|
||||
filters,
|
||||
|
||||
@@ -4,14 +4,14 @@
|
||||
{{ course.title }}</span> {% endif %}
|
||||
{% set all_memberships = course.get_all_memberships() %}
|
||||
{% if all_memberships | length > 1 %}
|
||||
<a class="nav-link pull-right" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true"
|
||||
<a class="nav-link pull-right" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="false">
|
||||
Switch Batch
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
{% for membership in all_memberships %}
|
||||
{% if not membership.is_current %}
|
||||
<a class="dropdown-item switch-batch" href="#" data-batch="{{ membership.batch | urlencode }}" data-course="{{ course.name | urlencode }}">{{ membership.batch_title }}</a>
|
||||
{% for data in all_memberships %}
|
||||
{% if data.batch != membership.batch %}
|
||||
<a class="dropdown-item switch-batch" href="/courses/{{ course.name }}/home?batch={{ data.batch }}">{{ data.batch_title }}</a>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
@@ -22,18 +22,21 @@
|
||||
{% else %}
|
||||
{% set display_class = "" %}
|
||||
{% endif %}
|
||||
|
||||
<ul class="nav nav-tabs mt-4">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="home" href="/courses/{{course.name}}/home">Home</a>
|
||||
<a class="nav-link" id="home" href="/courses/{{course.name}}/home{{ course.query_parameter }}">Home</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="learn" href="/courses/{{course.name}}/learn">Lessons</a>
|
||||
{% set lesson_index = course.get_lesson_index(membership.current_lesson) if membership.current_lesson else '1.1' %}
|
||||
<a class="nav-link" id="learn"
|
||||
href="{{ course.get_learn_url(lesson_index) }}{{ course.query_parameter }}">Lessons</a>
|
||||
</li>
|
||||
<!-- <li class="nav-item">
|
||||
<a class="nav-link" id="schedule" href="/courses/{{course.name}}/schedule">Schedule</a>
|
||||
</li> -->
|
||||
<li class="nav-item {{ display_class }}">
|
||||
<a class="nav-link" id="members" href="/courses/{{course.name}}/members">Members</a>
|
||||
<a class="nav-link" id="members" href="/courses/{{course.name}}/members{{ course.query_parameter }}">Members</a>
|
||||
</li>
|
||||
<!-- <li class="nav-item {{ display_class }}">
|
||||
<a class="nav-link" id="discussion" href="/courses/{{course.name}}/discuss">Discussion</a>
|
||||
@@ -41,37 +44,22 @@
|
||||
<!-- <li class="nav-item">
|
||||
<a class="nav-link" id="about" href="/courses/{{course.name}}/about">About</a>
|
||||
</li> -->
|
||||
{% if batch and batch.is_member(frappe.session.user, member_type="Mentor") %}
|
||||
{% if membership.batch and course.is_mentor(frappe.session.user) %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="progress" href="/courses/{{course.name}}/progress">Progress</a>
|
||||
<a class="nav-link" id="progress" href="/courses/{{course.name}}/progress{{ course.query_parameter }}">Progress</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% block script %}
|
||||
<script>
|
||||
frappe.ready(() => {
|
||||
var selector = document.querySelector(`a[href="${decodeURIComponent(window.location.pathname)}"]`)
|
||||
var selector = document.querySelector(`a[href="${decodeURIComponent(window.location.pathname)}{{ course.query_parameter }}"]`)
|
||||
if (selector) {
|
||||
selector.classList.add('active');
|
||||
}
|
||||
else {
|
||||
$("#learn").addClass('active')
|
||||
}
|
||||
|
||||
$(".switch-batch").click((e) => {
|
||||
e.preventDefault();
|
||||
var batch = decodeURIComponent($(e.currentTarget).attr("data-batch"));
|
||||
var course = decodeURIComponent($(e.currentTarget).attr("data-course"));
|
||||
frappe.call({
|
||||
method: "community.lms.doctype.lms_batch_membership.lms_batch_membership.update_current_membership",
|
||||
args: {
|
||||
batch: batch,
|
||||
course: course,
|
||||
member: frappe.session.user
|
||||
},
|
||||
callback: (data) => {
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
{% for lesson in chapter.get_lessons() %}
|
||||
<div class="lesson-teaser">
|
||||
<a {% if show_link or lesson.include_in_preview %}
|
||||
href="{{ course.get_learn_url(course.get_lesson_index(lesson.name)) }}" {% else %} href="" class="no-preview"
|
||||
href="{{ course.get_learn_url(course.get_lesson_index(lesson.name)) }}{{course.query_parameter}}" {% else %} href="" class="no-preview"
|
||||
{% endif %} data-course="{{ course.name }}">{{ lesson.title }}</a>
|
||||
{% if show_progress and not course.is_mentor(frappe.session.user) and lesson.get_progress() %}
|
||||
<span class="ml-5 badge p-2 {{ lesson.get_slugified_class() }}"> {{ lesson.get_progress() }}</span>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<div class="cta">
|
||||
<div class="">
|
||||
{% if can_manage %}
|
||||
<a href="" class="btn btn-primary manage-batch" data-batch="{{ batch.name | urlencode }}"
|
||||
<a href="/courses/{{ course.name }}/home?batch={{ batch.name }}" class="btn btn-primary manage-batch" data-batch="{{ batch.name | urlencode }}"
|
||||
data-course="{{ course.name | urlencode }}">Manage</a>
|
||||
{% elif can_join %}
|
||||
<button class="join-batch btn btn-secondary" data-batch="{{ batch.name | urlencode }}"
|
||||
|
||||
@@ -51,7 +51,8 @@ frappe.ready(() => {
|
||||
frappe.call({
|
||||
"method": "community.lms.doctype.lms_batch_membership.lms_batch_membership.create_membership",
|
||||
"args": {
|
||||
"batch": "{{ batch.name }}"
|
||||
"batch": {{ batch.name }},
|
||||
"course": {{ batch.course }}
|
||||
},
|
||||
"callback": (data) => {
|
||||
if (data.message == "OK") {
|
||||
@@ -66,20 +67,6 @@ frappe.ready(() => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
$("#batch-home").click((e) => {
|
||||
frappe.call({
|
||||
method: "community.lms.doctype.lms_batch_membership.lms_batch_membership.update_current_membership",
|
||||
args: {
|
||||
"batch": "{{ batch.name }}",
|
||||
"course": "{{ batch.course}}",
|
||||
"member": frappe.session.user
|
||||
},
|
||||
callback: (data) => {
|
||||
window.location.href = "/courses/{{ batch.course }}/home"
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -65,9 +65,9 @@
|
||||
{{ ext.render_footer() }}
|
||||
{% endfor %}
|
||||
<script>
|
||||
var membership = {{ membership }};
|
||||
var membership = "{{ membership.name }}";
|
||||
var is_mentor = {{ course.is_mentor(frappe.session.user) }};
|
||||
console.log(is_mentor)
|
||||
console.log(membership)
|
||||
if (membership && !is_mentor) {
|
||||
frappe.call({
|
||||
method: "community.lms.doctype.lesson.lesson.save_progress",
|
||||
@@ -78,9 +78,12 @@
|
||||
})
|
||||
}
|
||||
if (membership) {
|
||||
frappe.call("community.lms.api.save_current_lesson", {
|
||||
"course_name": "{{ course.name }}",
|
||||
"lesson_name": "{{ lesson.name }}"
|
||||
frappe.call({
|
||||
method: "community.lms.api.save_current_lesson",
|
||||
args: {
|
||||
"course_name": "{{ course.name }}",
|
||||
"lesson_name": "{{ lesson.name }}"
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -18,7 +18,7 @@ def get_context(context):
|
||||
index_ = get_lesson_index(context.course, context.batch, frappe.session.user) or "1.1"
|
||||
else:
|
||||
index_ = "1.1"
|
||||
frappe.local.flags.redirect_location = context.course.get_learn_url(index_)
|
||||
frappe.local.flags.redirect_location = context.course.get_learn_url(index_) + context.course.query_parameter
|
||||
raise frappe.Redirect
|
||||
|
||||
context.lesson = context.course.get_lesson(chapter_index, lesson_index)
|
||||
@@ -30,8 +30,8 @@ def get_context(context):
|
||||
next_ = outline.get_next(lesson_number)
|
||||
context.prev_chap = get_chapter_title(course_name, prev_)
|
||||
context.next_chap = get_chapter_title(course_name, next_)
|
||||
context.next_url = context.course.get_learn_url(next_)
|
||||
context.prev_url = context.course.get_learn_url(prev_)
|
||||
context.next_url = context.course.get_learn_url(next_) + context.course.query_parameter
|
||||
context.prev_url = context.course.get_learn_url(prev_) + context.course.query_parameter
|
||||
|
||||
context.page_extensions = get_page_extensions()
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
{% block content %}
|
||||
|
||||
<div class="container">
|
||||
{{ widgets.BatchTabs(course=course, batch=batch) }}
|
||||
{{ widgets.BatchTabs(course=course, membership=membership) }}
|
||||
<div class="mentor-dashboard">
|
||||
<h3>Batch Progress</h3>
|
||||
{% for exercise in report.exercises %}
|
||||
|
||||
@@ -17,7 +17,7 @@ def get_context(context):
|
||||
|
||||
class BatchReport:
|
||||
def __init__(self, course, batch):
|
||||
self.submissions = get_submissions(batch)
|
||||
self.submissions = get_submissions(course, batch)
|
||||
self.exercises = self.get_exercises(course.name)
|
||||
self.submissions_by_exercise = defaultdict(list)
|
||||
for s in self.submissions:
|
||||
@@ -29,8 +29,10 @@ class BatchReport:
|
||||
def get_submissions_of_exercise(self, exercise_name):
|
||||
return self.submissions_by_exercise[exercise_name]
|
||||
|
||||
def get_submissions(batch):
|
||||
students = batch.get_students()
|
||||
def get_submissions(course, batch):
|
||||
students = course.get_students(batch.name)
|
||||
if not len(students):
|
||||
return []
|
||||
students_map = {s.email: s for s in students}
|
||||
names, values = nparams("s", students_map.keys())
|
||||
sql = """
|
||||
|
||||
@@ -5,14 +5,18 @@ def get_common_context(context):
|
||||
context.no_cache = 1
|
||||
|
||||
course_name = frappe.form_dict["course"]
|
||||
try:
|
||||
batch_name = frappe.form_dict["batch"]
|
||||
except KeyError:
|
||||
batch_name = None
|
||||
|
||||
course = Course.find(course_name)
|
||||
if not course:
|
||||
context.template = "www/404.html"
|
||||
return
|
||||
context.course = course
|
||||
|
||||
membership = course.get_current_membership(frappe.session.user)
|
||||
|
||||
membership = course.get_membership(frappe.session.user, batch_name)
|
||||
if membership:
|
||||
context.membership = membership
|
||||
batch = course.get_batch(membership.batch)
|
||||
@@ -22,14 +26,13 @@ def get_common_context(context):
|
||||
|
||||
context.members = course.get_mentors(membership.batch) + course.get_students(membership.batch)
|
||||
context.member_count = len(context.members)
|
||||
|
||||
|
||||
context.course = course
|
||||
context.course.query_parameter = "?batch=" + batch.name if batch else ""
|
||||
print(context.membership)
|
||||
context.livecode_url = get_livecode_url()
|
||||
|
||||
def get_livecode_url():
|
||||
return frappe.db.get_single_value("LMS Settings", "livecode_url")
|
||||
|
||||
def redirect_to_lesson(course, index_="1.1"):
|
||||
frappe.local.flags.redirect_location = course.get_learn_url(index_)
|
||||
frappe.local.flags.redirect_location = course.get_learn_url(index_) + course.query_parameter
|
||||
raise frappe.Redirect
|
||||
|
||||
@@ -14,9 +14,11 @@
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-end">
|
||||
<h2 id="course-title" data-course="{{course.name}}">{{course.title}}</h2>
|
||||
{% if not course.disable_self_learning and not course.is_mentor(frappe.session.user) %}
|
||||
<div>
|
||||
<button class="btn btn-primary join-batch" data-course="{{ course.name | urlencode }}"> Join the Course</button>
|
||||
<button class="btn btn-primary join-batch" data-course="{{ course.name | urlencode }}"> Start Learning </button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="course-short-intro">{{ course.short_introduction }}</div>
|
||||
</div>
|
||||
|
||||
@@ -75,21 +75,4 @@ frappe.ready(() => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
$(".manage-batch").click((e) => {
|
||||
e.preventDefault();
|
||||
var batch = decodeURIComponent($(e.currentTarget).attr("data-batch"));
|
||||
var course = decodeURIComponent($(e.currentTarget).attr("data-course"));
|
||||
frappe.call({
|
||||
method: "community.lms.doctype.lms_batch_membership.lms_batch_membership.update_current_membership",
|
||||
args: {
|
||||
batch: batch,
|
||||
course: course,
|
||||
member: frappe.session.user
|
||||
},
|
||||
callback: (data) => {
|
||||
window.location.href = `/courses/${course}/home`;
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -16,9 +16,8 @@ def get_context(context):
|
||||
raise frappe.Redirect
|
||||
|
||||
context.course = course
|
||||
|
||||
batch = course.get_student_batch(frappe.session.user)
|
||||
if batch:
|
||||
frappe.local.flags.redirect_location = f"/courses/{course.name}/learn"
|
||||
raise frappe.Redirect
|
||||
|
||||
if not course.is_mentor(frappe.session.user):
|
||||
batch = course.get_membership(frappe.session.user)
|
||||
if batch:
|
||||
frappe.local.flags.redirect_location = f"/courses/{course.name}/learn"
|
||||
raise frappe.Redirect
|
||||
|
||||
Reference in New Issue
Block a user