diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.py b/erpnext/education/doctype/course_enrollment/course_enrollment.py index 6f2bb0db1f..064b075709 100644 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.py +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.py @@ -62,8 +62,9 @@ class CourseEnrollment(Document): }).insert() def add_activity(self, content_type, content): - if check_activity_exists(self.name, content_type, content): - pass + activity = check_activity_exists(self.name, content_type, content) + if activity: + return activity else: activity = frappe.get_doc({ "doctype": "Course Activity", @@ -71,9 +72,14 @@ class CourseEnrollment(Document): "content_type": content_type, "content": content, "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): activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content}) - return bool(activity) \ No newline at end of file + if activity: + return activity[0].name + else: + return None \ No newline at end of file diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index c19bd19879..a4b71e310e 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -77,7 +77,7 @@ def get_portal_programs(): is_published and (student_is_enrolled or student_can_self_enroll) 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}) if not published_programs: @@ -170,40 +170,34 @@ def enroll_in_program(program_name, student=None): return program_enrollment.name 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) roles = set([role.role for role in current_user.roles]) return bool(roles & {'Administrator', 'Instructor', 'Education Manager', 'System Manager', 'Academic User'}) -# def get_program_enrollment(program_name): -# """ -# Function to get program enrollments for a particular student for a program -# """ -# 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 +@frappe.whitelist() +def add_activity(course, content_type, content): + if has_super_access(): + return None -# def get_program_and_enrollment_status(program_name): -# program = frappe.get_doc('Program', program_name) -# is_enrolled = bool(get_program_enrollment(program_name)) or check_super_access() -# return {'program': program, 'is_enrolled': is_enrolled} + student = get_current_student() + if not student: + return frappe.throw("Student with email {0} does not exist".format(frappe.session.user), frappe.DoesNotExistError) -# def get_course_enrollment(course_name): -# student = get_current_student() -# if not student: -# return None -# enrollment_name = frappe.get_all("Course Enrollment", filters={'student': student.name, 'course':course_name}) -# try: -# name = enrollment_name[0].name -# enrollment = frappe.get_doc("Course Enrollment", name) -# return enrollment -# except: -# return None + course_enrollment = get_enrollment("course", course, student.name) + print(course_enrollment) + if not course_enrollment: + return None + + enrollment = frappe.get_doc('Course Enrollment', course_enrollment) + if content_type == 'Quiz': + return + else: + return enrollment.add_activity(content_type, content) def create_student_from_current_user(): user = frappe.get_doc("User", frappe.session.user) diff --git a/erpnext/www/lms/content.html b/erpnext/www/lms/content.html index 68fb9f32fe..a02b2c7500 100644 --- a/erpnext/www/lms/content.html +++ b/erpnext/www/lms/content.html @@ -34,19 +34,19 @@ {% macro navigation() %}
-

{{ content.name }}

+

{{ content.name }} ({{ position + 1 }}/{{length}})

{% if previous %} - Previous + Previous {% else %} - Back to Course + Back to Course {% endif %} {% if next %} - + {% else %} - + {% endif %}
@@ -126,13 +126,18 @@ }) function handle(url) { - frappe.call("add_activity", - { + + opts = { + method: "erpnext.education.utils.add_activity", + args: { course: "{{ course }}", content_type: "{{ content_type }}", - content: "{{ content.name }}", + content: "{{ content.name }}" } - ) + } + frappe.call(opts).then(res => { + window.location.href = url; + }) } {% endblock %} \ No newline at end of file diff --git a/erpnext/www/lms/content.py b/erpnext/www/lms/content.py index 25d5bc7e7f..51a8e32bad 100644 --- a/erpnext/www/lms/content.py +++ b/erpnext/www/lms/content.py @@ -5,10 +5,19 @@ import frappe no_cache = 1 def get_context(context): - program = frappe.form_dict['program'] - content = frappe.form_dict['content'] - content_type = frappe.form_dict['type'] + # Load Query Parameters + try: + 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_content_access = allowed_content_access(program, content, content_type) @@ -16,46 +25,38 @@ def get_context(context): frappe.local.flags.redirect_location = '/lms' raise frappe.Redirect + + # Set context for content to be displayer context.content = frappe.get_doc(content_type, content) 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) 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: return content_list[current_index + 1] except IndexError: return None -def get_previous_content(topic, course, content, content_type): - 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}) +def get_previous_content(content_list, current_index): if current_index == 0: return None else: return content_list[current_index - 1] 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 from `tabcourse topic`, `tabprogram course`,