diff --git a/community/community/widgets/Avatar.html b/community/community/widgets/Avatar.html index 862419a4..59f59a91 100644 --- a/community/community/widgets/Avatar.html +++ b/community/community/widgets/Avatar.html @@ -1,5 +1,5 @@ {% set color = member.get_palette() %} - + {% if member.user_image %} diff --git a/community/hooks.py b/community/hooks.py index 60d8eaf5..5b2ef4c1 100644 --- a/community/hooks.py +++ b/community/hooks.py @@ -176,6 +176,7 @@ whitelist = [ "/exhibitor-registration", "/discussions", "/propose-talk", + ] whitelist_rules = [{"from_route": p, "to_route": p[1:]} for p in whitelist] diff --git a/community/lms/doctype/lesson/lesson.py b/community/lms/doctype/lesson/lesson.py index 3b66ac0c..736fa6bd 100644 --- a/community/lms/doctype/lesson/lesson.py +++ b/community/lms/doctype/lesson/lesson.py @@ -91,7 +91,8 @@ def save_progress(lesson, course, status): "lesson": lesson, "status": status, }).save(ignore_permissions=True) - return "OK" + course_details = frappe.get_doc("LMS Course", course) + return course_details.get_course_progress() def update_progress(lesson): user = frappe.session.user diff --git a/community/lms/doctype/lms_certification/__init__.py b/community/lms/doctype/lms_certification/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/community/lms/doctype/lms_certification/lms_certification.js b/community/lms/doctype/lms_certification/lms_certification.js new file mode 100644 index 00000000..7a264e1e --- /dev/null +++ b/community/lms/doctype/lms_certification/lms_certification.js @@ -0,0 +1,14 @@ +// Copyright (c) 2021, FOSS United and contributors +// For license information, please see license.txt + +frappe.ui.form.on('LMS Certification', { + onload: function (frm) { + frm.set_query("student", function (doc) { + return { + filters: { + "ignore_user_type": 1, + } + }; + }); + } +}); diff --git a/community/lms/doctype/lms_certification/lms_certification.json b/community/lms/doctype/lms_certification/lms_certification.json new file mode 100644 index 00000000..fc6e58fa --- /dev/null +++ b/community/lms/doctype/lms_certification/lms_certification.json @@ -0,0 +1,70 @@ +{ + "actions": [], + "creation": "2021-08-16 15:47:19.494055", + "doctype": "DocType", + "editable_grid": 1, + "engine": "InnoDB", + "field_order": [ + "student", + "issue_date", + "column_break_3", + "course", + "expiry_date" + ], + "fields": [ + { + "fieldname": "student", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Student", + "options": "User" + }, + { + "fieldname": "issue_date", + "fieldtype": "Date", + "label": "Issue Date" + }, + { + "fieldname": "column_break_3", + "fieldtype": "Column Break" + }, + { + "fieldname": "course", + "fieldtype": "Link", + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Course", + "options": "LMS Course" + }, + { + "fieldname": "expiry_date", + "fieldtype": "Date", + "label": "Expiry Date" + } + ], + "index_web_pages_for_search": 1, + "links": [], + "modified": "2021-08-16 15:47:19.494055", + "modified_by": "Administrator", + "module": "LMS", + "name": "LMS Certification", + "owner": "Administrator", + "permissions": [ + { + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "share": 1, + "write": 1 + } + ], + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1 +} \ No newline at end of file diff --git a/community/lms/doctype/lms_certification/lms_certification.py b/community/lms/doctype/lms_certification/lms_certification.py new file mode 100644 index 00000000..3ca4d4ce --- /dev/null +++ b/community/lms/doctype/lms_certification/lms_certification.py @@ -0,0 +1,41 @@ +# Copyright (c) 2021, FOSS United and contributors +# For license information, please see license.txt + +import frappe +from frappe.model.document import Document +from frappe.utils import nowdate, add_years +from frappe import _ +from frappe.utils.pdf import get_pdf + +class LMSCertification(Document): + + def validate(self): + certificates = frappe.get_all("LMS Certification", { + "student": self.student, + "course": self.course, + "expiry_date": [">", nowdate()] + }) + if len(certificates): + full_name = frappe.db.get_value("User", self.student, "full_name") + course_name = frappe.db.get_value("LMS Course", self.course, "title") + frappe.throw(_("There is already a valid certificate for user {0} for the course {1}").format(full_name, course_name)) + +@frappe.whitelist() +def create_certificate(course): + course_details = frappe.get_doc("LMS Course", course) + certificate = course_details.is_certified() + + if certificate: + return certificate + + else: + expires_after_yrs = course_details.expiry + certificate = frappe.get_doc({ + "doctype": "LMS Certification", + "student": frappe.session.user, + "course": course, + "issue_date": nowdate(), + "expiry_date": add_years(nowdate(), int(expires_after_yrs)) + }) + certificate.save(ignore_permissions=True) + return certificate.name diff --git a/community/lms/doctype/lms_certification/test_lms_certification.py b/community/lms/doctype/lms_certification/test_lms_certification.py new file mode 100644 index 00000000..62df184a --- /dev/null +++ b/community/lms/doctype/lms_certification/test_lms_certification.py @@ -0,0 +1,8 @@ +# Copyright (c) 2021, FOSS United and Contributors +# See license.txt + +# import frappe +import unittest + +class TestLMSCertification(unittest.TestCase): + pass diff --git a/community/lms/doctype/lms_course/lms_course.json b/community/lms/doctype/lms_course/lms_course.json index cf2521b2..81f00238 100644 --- a/community/lms/doctype/lms_course/lms_course.json +++ b/community/lms/doctype/lms_course/lms_course.json @@ -25,7 +25,10 @@ "section_break_5", "short_introduction", "description", - "chapters" + "chapters", + "certification_section", + "enable_certification", + "expiry" ], "fields": [ { @@ -94,6 +97,25 @@ "fieldtype": "Table", "label": "Chapters", "options": "Chapters" + }, + { + "fieldname": "certification_section", + "fieldtype": "Section Break", + "label": "Certification" + }, + { + "default": "0", + "fieldname": "enable_certification", + "fieldtype": "Check", + "label": "Enable Certification" + }, + { + "default": "0", + "depends_on": "enable_certification", + "fieldname": "expiry", + "fieldtype": "Select", + "label": "Certification Expires After Years", + "options": "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10" } ], "index_web_pages_for_search": 1, @@ -115,7 +137,7 @@ "link_fieldname": "course" } ], - "modified": "2021-07-28 19:01:50.677445", + "modified": "2021-08-18 18:02:12.623807", "modified_by": "Administrator", "module": "LMS", "name": "LMS Course", diff --git a/community/lms/doctype/lms_course/lms_course.py b/community/lms/doctype/lms_course/lms_course.py index 47b2f92d..126f6504 100644 --- a/community/lms/doctype/lms_course/lms_course.py +++ b/community/lms/doctype/lms_course/lms_course.py @@ -347,6 +347,16 @@ class LMSCourse(Document): "next": numbers[index+1] if index+1 < len(numbers) else None } + def is_certified(self): + certificate = frappe.get_all("LMS Certification", + { + "student": frappe.session.user, + "course": self.name + }) + if len(certificate): + return certificate[0].name + return + @frappe.whitelist() def reindex_exercises(doc): course_data = json.loads(doc) diff --git a/community/lms/web_form/profile/profile.js b/community/lms/web_form/profile/profile.js index 286ed9b5..c9869a5c 100644 --- a/community/lms/web_form/profile/profile.js +++ b/community/lms/web_form/profile/profile.js @@ -8,7 +8,7 @@ frappe.ready(function () { frappe.web_form.after_save = () => { setTimeout(() => { - window.location.href = `/${frappe.web_form.get_value(["username"])}`; + window.location.href = `/user/${frappe.web_form.get_value(["username"])}`; }) } }) diff --git a/community/lms/widgets/CourseTeaser.html b/community/lms/widgets/CourseTeaser.html index 64ecb5ec..2b7b54ec 100644 --- a/community/lms/widgets/CourseTeaser.html +++ b/community/lms/widgets/CourseTeaser.html @@ -12,7 +12,7 @@ {% endif %}
{% with author = course.get_instructor() %} - {{ widgets.Avatar(member=author, avatar_class="avatar-medium") }} {{ author.full_name }} + {{ widgets.Avatar(member=author, avatar_class="avatar-medium") }} {{ author.full_name }} {% endwith %}
diff --git a/community/lms/widgets/InstructorSection.html b/community/lms/widgets/InstructorSection.html index 367148dd..9c96c294 100644 --- a/community/lms/widgets/InstructorSection.html +++ b/community/lms/widgets/InstructorSection.html @@ -1,6 +1,6 @@
{{ widgets.Avatar(member=instructor, avatar_class="avatar-medium") }} - {{ instructor.full_name }} + {{ instructor.full_name }}
Course Creator
diff --git a/community/lms/widgets/MemberCard.html b/community/lms/widgets/MemberCard.html index d780eb34..77f00556 100644 --- a/community/lms/widgets/MemberCard.html +++ b/community/lms/widgets/MemberCard.html @@ -11,5 +11,5 @@ Created {{ course_count }} {{ suffix }} {% endif %} - + diff --git a/community/lms/widgets/Reviews.html b/community/lms/widgets/Reviews.html index 73073f8d..b5302ca3 100644 --- a/community/lms/widgets/Reviews.html +++ b/community/lms/widgets/Reviews.html @@ -18,7 +18,7 @@