feat: content navigation and activity tracking working
This commit is contained in:
parent
3336fb595c
commit
e94e9d2b06
@ -62,8 +62,9 @@ class CourseEnrollment(Document):
|
|||||||
}).insert()
|
}).insert()
|
||||||
|
|
||||||
def add_activity(self, content_type, content):
|
def add_activity(self, content_type, content):
|
||||||
if check_activity_exists(self.name, content_type, content):
|
activity = check_activity_exists(self.name, content_type, content)
|
||||||
pass
|
if activity:
|
||||||
|
return activity
|
||||||
else:
|
else:
|
||||||
activity = frappe.get_doc({
|
activity = frappe.get_doc({
|
||||||
"doctype": "Course Activity",
|
"doctype": "Course Activity",
|
||||||
@ -71,9 +72,14 @@ class CourseEnrollment(Document):
|
|||||||
"content_type": content_type,
|
"content_type": content_type,
|
||||||
"content": content,
|
"content": content,
|
||||||
"activity_date": frappe.utils.datetime.datetime.now()
|
"activity_date": frappe.utils.datetime.datetime.now()
|
||||||
})
|
})
|
||||||
activity.insert()
|
|
||||||
|
activity.insert(ignore_permissions=True)
|
||||||
|
return activity.name
|
||||||
|
|
||||||
def check_activity_exists(enrollment, content_type, content):
|
def check_activity_exists(enrollment, content_type, content):
|
||||||
activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content})
|
activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content})
|
||||||
return bool(activity)
|
if activity:
|
||||||
|
return activity[0].name
|
||||||
|
else:
|
||||||
|
return None
|
@ -77,7 +77,7 @@ def get_portal_programs():
|
|||||||
is_published and (student_is_enrolled or student_can_self_enroll)
|
is_published and (student_is_enrolled or student_can_self_enroll)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list of objects: List of all programs and to be displayed on the portal along with enrollment status
|
list of dictionary: List of all programs and to be displayed on the portal along with access rights
|
||||||
"""
|
"""
|
||||||
published_programs = frappe.get_all("Program", filters={"is_published": True})
|
published_programs = frappe.get_all("Program", filters={"is_published": True})
|
||||||
if not published_programs:
|
if not published_programs:
|
||||||
@ -170,40 +170,34 @@ def enroll_in_program(program_name, student=None):
|
|||||||
return program_enrollment.name
|
return program_enrollment.name
|
||||||
|
|
||||||
def has_super_access():
|
def has_super_access():
|
||||||
|
"""Check if user has a role that allows full access to LMS
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: true if user has access to all lms content
|
||||||
|
"""
|
||||||
current_user = frappe.get_doc('User', frappe.session.user)
|
current_user = frappe.get_doc('User', frappe.session.user)
|
||||||
roles = set([role.role for role in current_user.roles])
|
roles = set([role.role for role in current_user.roles])
|
||||||
return bool(roles & {'Administrator', 'Instructor', 'Education Manager', 'System Manager', 'Academic User'})
|
return bool(roles & {'Administrator', 'Instructor', 'Education Manager', 'System Manager', 'Academic User'})
|
||||||
|
|
||||||
# def get_program_enrollment(program_name):
|
@frappe.whitelist()
|
||||||
# """
|
def add_activity(course, content_type, content):
|
||||||
# Function to get program enrollments for a particular student for a program
|
if has_super_access():
|
||||||
# """
|
return None
|
||||||
# student get_current_student()
|
|
||||||
# if not student:
|
|
||||||
# return None
|
|
||||||
# else:
|
|
||||||
# enrollment = frappe.get_all("Program Enrollment", filters={'student':student.name, 'program': program_name})
|
|
||||||
# if enrollment:
|
|
||||||
# return enrollment[0].name
|
|
||||||
# else:
|
|
||||||
# return None
|
|
||||||
|
|
||||||
# def get_program_and_enrollment_status(program_name):
|
student = get_current_student()
|
||||||
# program = frappe.get_doc('Program', program_name)
|
if not student:
|
||||||
# is_enrolled = bool(get_program_enrollment(program_name)) or check_super_access()
|
return frappe.throw("Student with email {0} does not exist".format(frappe.session.user), frappe.DoesNotExistError)
|
||||||
# return {'program': program, 'is_enrolled': is_enrolled}
|
|
||||||
|
|
||||||
# def get_course_enrollment(course_name):
|
course_enrollment = get_enrollment("course", course, student.name)
|
||||||
# student = get_current_student()
|
print(course_enrollment)
|
||||||
# if not student:
|
if not course_enrollment:
|
||||||
# return None
|
return None
|
||||||
# enrollment_name = frappe.get_all("Course Enrollment", filters={'student': student.name, 'course':course_name})
|
|
||||||
# try:
|
enrollment = frappe.get_doc('Course Enrollment', course_enrollment)
|
||||||
# name = enrollment_name[0].name
|
if content_type == 'Quiz':
|
||||||
# enrollment = frappe.get_doc("Course Enrollment", name)
|
return
|
||||||
# return enrollment
|
else:
|
||||||
# except:
|
return enrollment.add_activity(content_type, content)
|
||||||
# return None
|
|
||||||
|
|
||||||
def create_student_from_current_user():
|
def create_student_from_current_user():
|
||||||
user = frappe.get_doc("User", frappe.session.user)
|
user = frappe.get_doc("User", frappe.session.user)
|
||||||
|
@ -34,19 +34,19 @@
|
|||||||
{% macro navigation() %}
|
{% macro navigation() %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-7">
|
<div class="col-md-7">
|
||||||
<h1>{{ content.name }}</h1>
|
<h1>{{ content.name }} <span class="small text-muted">({{ position + 1 }}/{{length}})</span></h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-5 text-right">
|
<div class="col-md-5 text-right">
|
||||||
{% if previous %}
|
{% if previous %}
|
||||||
<a href="/lms/content?course={{ course }}&topic={{ topic }}&type={{ previous.content_type }}&content={{ previous.content }}" class='btn btn-outline-secondary'>Previous</a>
|
<a href="/lms/content?program={{ program }}&course={{ course }}&topic={{ topic }}&type={{ previous.content_type }}&content={{ previous.content }}" class='btn btn-outline-secondary'>Previous</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="/lms/course?name={{ course }}" class='btn btn-outline-secondary'>Back to Course</a>
|
<a href="/lms/course?name={{ course }}&program={{ program }}" class='btn btn-outline-secondary'>Back to Course</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if next %}
|
{% if next %}
|
||||||
<button id="nextButton" onclick="handle('/lms/content?course={{ course }}&topic={{ topic }}&type={{ next.content_type }}&content={{ next.content }}')" class='btn btn-primary' disabled="true">Next</button>
|
<button id="nextButton" onclick="handle('/lms/content?program={{ program }}&course={{ course }}&topic={{ topic }}&type={{ next.content_type }}&content={{ next.content }}')" class='btn btn-primary' disabled="true">Next</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
<button id="nextButton" onclick="handle('/lms/course?name={{ course }}')" class='btn btn-primary' disabled="true">Finish Topic</button>
|
<button id="nextButton" onclick="handle('/lms/course?name={{ course }}&program={{ program }}')" class='btn btn-primary' disabled="true">Finish Topic</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -126,13 +126,18 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
function handle(url) {
|
function handle(url) {
|
||||||
frappe.call("add_activity",
|
|
||||||
{
|
opts = {
|
||||||
|
method: "erpnext.education.utils.add_activity",
|
||||||
|
args: {
|
||||||
course: "{{ course }}",
|
course: "{{ course }}",
|
||||||
content_type: "{{ content_type }}",
|
content_type: "{{ content_type }}",
|
||||||
content: "{{ content.name }}",
|
content: "{{ content.name }}"
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
frappe.call(opts).then(res => {
|
||||||
|
window.location.href = url;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -5,10 +5,19 @@ import frappe
|
|||||||
no_cache = 1
|
no_cache = 1
|
||||||
|
|
||||||
def get_context(context):
|
def get_context(context):
|
||||||
program = frappe.form_dict['program']
|
# Load Query Parameters
|
||||||
content = frappe.form_dict['content']
|
try:
|
||||||
content_type = frappe.form_dict['type']
|
program = frappe.form_dict['program']
|
||||||
|
content = frappe.form_dict['content']
|
||||||
|
content_type = frappe.form_dict['type']
|
||||||
|
course = frappe.form_dict['course']
|
||||||
|
topic = frappe.form_dict['topic']
|
||||||
|
except KeyError:
|
||||||
|
frappe.local.flags.redirect_location = '/lms'
|
||||||
|
raise frappe.Redirect
|
||||||
|
|
||||||
|
|
||||||
|
# Check if user has access to the content
|
||||||
has_program_access = utils.allowed_program_access(program)
|
has_program_access = utils.allowed_program_access(program)
|
||||||
has_content_access = allowed_content_access(program, content, content_type)
|
has_content_access = allowed_content_access(program, content, content_type)
|
||||||
|
|
||||||
@ -16,46 +25,38 @@ def get_context(context):
|
|||||||
frappe.local.flags.redirect_location = '/lms'
|
frappe.local.flags.redirect_location = '/lms'
|
||||||
raise frappe.Redirect
|
raise frappe.Redirect
|
||||||
|
|
||||||
|
|
||||||
|
# Set context for content to be displayer
|
||||||
context.content = frappe.get_doc(content_type, content)
|
context.content = frappe.get_doc(content_type, content)
|
||||||
context.content_type = content_type
|
context.content_type = content_type
|
||||||
|
context.program = program
|
||||||
|
context.course = course
|
||||||
|
context.topic = topic
|
||||||
|
|
||||||
context.course = frappe.form_dict['course']
|
|
||||||
context.topic = frappe.form_dict['topic']
|
|
||||||
|
|
||||||
context.previous = get_previous_content(context.topic, context.course, context.content, context.content_type)
|
|
||||||
context.next = get_next_content(context.topic, context.course, context.content, context.content_type)
|
|
||||||
|
|
||||||
|
|
||||||
def get_next_content(topic, course, content, content_type):
|
|
||||||
if frappe.session.user == "Guest":
|
|
||||||
return None
|
|
||||||
topic = frappe.get_doc("Topic", topic)
|
topic = frappe.get_doc("Topic", topic)
|
||||||
content_list = [{'content_type':item.doctype, 'content':item.name} for item in topic.get_contents()]
|
content_list = [{'content_type':item.doctype, 'content':item.name} for item in topic.get_contents()]
|
||||||
current_index = content_list.index({'content': content.name, 'content_type': content_type})
|
|
||||||
|
# Set context for progress numbers
|
||||||
|
context.position = content_list.index({'content': content, 'content_type': content_type})
|
||||||
|
context.length = len(content_list)
|
||||||
|
|
||||||
|
# Set context for navigation
|
||||||
|
context.previous = get_previous_content(content_list, context.position)
|
||||||
|
context.next = get_next_content(content_list, context.position)
|
||||||
|
|
||||||
|
def get_next_content(content_list, current_index):
|
||||||
try:
|
try:
|
||||||
return content_list[current_index + 1]
|
return content_list[current_index + 1]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_previous_content(topic, course, content, content_type):
|
def get_previous_content(content_list, current_index):
|
||||||
if frappe.session.user == "Guest":
|
|
||||||
return None
|
|
||||||
topic = frappe.get_doc("Topic", topic)
|
|
||||||
content_list = [{'content_type':item.doctype, 'content':item.name} for item in topic.get_contents()]
|
|
||||||
current_index = content_list.index({'content': content.name, 'content_type': content_type})
|
|
||||||
if current_index == 0:
|
if current_index == 0:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
return content_list[current_index - 1]
|
return content_list[current_index - 1]
|
||||||
|
|
||||||
def allowed_content_access(program, content, content_type):
|
def allowed_content_access(program, content, content_type):
|
||||||
# Get all content in program
|
|
||||||
|
|
||||||
# Using ORM
|
|
||||||
# course_in_program = [course.course for course in frappe.get_all('Program Course', fields=['course'], filters={'parent': program})]
|
|
||||||
# topics_in_course = [topic.topic for topic in frappe.get_all("Course Topic", fields=['topic'], filters=[['parent','in', course_in_program]])]
|
|
||||||
# contents_of_program = [[c.content, c.content_type] for c in frappe.get_all('Topic Content', fields=['content', 'content_type'], filters=[['parent','in', topics_in_course]])]
|
|
||||||
|
|
||||||
contents_of_program = frappe.db.sql("""select `tabtopic content`.content, `tabtopic content`.content_type
|
contents_of_program = frappe.db.sql("""select `tabtopic content`.content, `tabtopic content`.content_type
|
||||||
from `tabcourse topic`,
|
from `tabcourse topic`,
|
||||||
`tabprogram course`,
|
`tabprogram course`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user