diff --git a/community/lms/doctype/chapter/chapter.json b/community/lms/doctype/chapter/chapter.json
index 9bc525ed..5e0559dd 100644
--- a/community/lms/doctype/chapter/chapter.json
+++ b/community/lms/doctype/chapter/chapter.json
@@ -83,4 +83,4 @@
"sort_order": "DESC",
"title_field": "title",
"track_changes": 1
-}
\ No newline at end of file
+}
diff --git a/community/lms/doctype/chapter_reference/chapter_reference.json b/community/lms/doctype/chapter_reference/chapter_reference.json
index 7c63fbcf..a251b1a4 100644
--- a/community/lms/doctype/chapter_reference/chapter_reference.json
+++ b/community/lms/doctype/chapter_reference/chapter_reference.json
@@ -13,14 +13,14 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Chapter",
- "options": "Chapter",
+ "options": "Course Chapter",
"reqd": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2021-07-27 16:25:02.903245",
+ "modified": "2021-09-30 10:35:30.014950",
"modified_by": "Administrator",
"module": "LMS",
"name": "Chapter Reference",
diff --git a/community/lms/doctype/course_chapter/__init__.py b/community/lms/doctype/course_chapter/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/community/lms/doctype/course_chapter/course_chapter.js b/community/lms/doctype/course_chapter/course_chapter.js
new file mode 100644
index 00000000..9e24b54d
--- /dev/null
+++ b/community/lms/doctype/course_chapter/course_chapter.js
@@ -0,0 +1,14 @@
+// Copyright (c) 2021, FOSS United and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Course Chapter', {
+ onload: function (frm) {
+ frm.set_query("lesson", "lessons", function () {
+ return {
+ filters: {
+ "chapter": frm.doc.name,
+ }
+ };
+ });
+ }
+});
diff --git a/community/lms/doctype/course_chapter/course_chapter.json b/community/lms/doctype/course_chapter/course_chapter.json
new file mode 100644
index 00000000..7ebf90b4
--- /dev/null
+++ b/community/lms/doctype/course_chapter/course_chapter.json
@@ -0,0 +1,86 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "format:{####} {title}",
+ "creation": "2021-05-03 05:49:08.383058",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "course",
+ "title",
+ "column_break_3",
+ "description",
+ "section_break_5",
+ "lessons"
+ ],
+ "fields": [
+ {
+ "fieldname": "course",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Course",
+ "options": "LMS Course",
+ "reqd": 1
+ },
+ {
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Title",
+ "reqd": 1
+ },
+ {
+ "fieldname": "column_break_3",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "description",
+ "fieldtype": "Small Text",
+ "label": "Description"
+ },
+ {
+ "fieldname": "section_break_5",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "lessons",
+ "fieldtype": "Table",
+ "label": "Lessons",
+ "options": "Lesson Reference"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "links": [
+ {
+ "group": "Lessons",
+ "link_doctype": "Course Lesson",
+ "link_fieldname": "chapter"
+ }
+ ],
+ "modified": "2021-09-29 15:33:44.611228",
+ "modified_by": "Administrator",
+ "module": "LMS",
+ "name": "Course Chapter",
+ "naming_rule": "Expression",
+ "owner": "Administrator",
+ "permissions": [
+ {
+ "create": 1,
+ "delete": 1,
+ "email": 1,
+ "export": 1,
+ "print": 1,
+ "read": 1,
+ "report": 1,
+ "role": "System Manager",
+ "share": 1,
+ "write": 1
+ }
+ ],
+ "search_fields": "title",
+ "sort_field": "modified",
+ "sort_order": "DESC",
+ "title_field": "title",
+ "track_changes": 1
+}
diff --git a/community/lms/doctype/course_chapter/course_chapter.py b/community/lms/doctype/course_chapter/course_chapter.py
new file mode 100644
index 00000000..9556f2ae
--- /dev/null
+++ b/community/lms/doctype/course_chapter/course_chapter.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, FOSS United and contributors
+# For license information, please see license.txt
+
+# import frappe
+from frappe.model.document import Document
+
+class CourseChapter(Document):
+ pass
diff --git a/community/lms/doctype/course_chapter/test_course_chapter.py b/community/lms/doctype/course_chapter/test_course_chapter.py
new file mode 100644
index 00000000..d14cd9fd
--- /dev/null
+++ b/community/lms/doctype/course_chapter/test_course_chapter.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, FOSS United and Contributors
+# See license.txt
+
+# import frappe
+import unittest
+
+class TestCourseChapter(unittest.TestCase):
+ pass
diff --git a/community/lms/doctype/course_lesson/__init__.py b/community/lms/doctype/course_lesson/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/community/lms/doctype/course_lesson/course_lesson.js b/community/lms/doctype/course_lesson/course_lesson.js
new file mode 100644
index 00000000..bb4fa5a6
--- /dev/null
+++ b/community/lms/doctype/course_lesson/course_lesson.js
@@ -0,0 +1,57 @@
+// Copyright (c) 2021, FOSS United and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Lesson', {
+ setup: function (frm) {
+ frm.trigger('setup_help');
+ },
+ setup_help(frm) {
+ frm.get_field('help').html(`
+
You can add some more additional content to the lesson using a special syntax. The table below mentions all types of dynamic content that you can add to the lessons and the syntax for the same.
+
+
+ Content Type
+
+
+ Syntax
+
+
+
+
+
+ Video
+
+
+ {{ Video("url_of_source") }}
+
+
+
+
+
+ YouTube Video
+
+
+ {{ YouTubeVideo("unique_embed_id") }}
+
+
+
+
+
+ Exercise
+
+
+ {{ Exercise("exercise_name") }}
+
+
+
+
+
+ Quiz
+
+
+ {{ Quiz("lms_quiz_name") }}
+
+
+`);
+ }
+});
diff --git a/community/lms/doctype/course_lesson/course_lesson.json b/community/lms/doctype/course_lesson/course_lesson.json
new file mode 100644
index 00000000..c154c620
--- /dev/null
+++ b/community/lms/doctype/course_lesson/course_lesson.json
@@ -0,0 +1,97 @@
+{
+ "actions": [],
+ "allow_rename": 1,
+ "autoname": "format:{####} {title}",
+ "creation": "2021-05-03 06:21:12.995984",
+ "doctype": "DocType",
+ "editable_grid": 1,
+ "engine": "InnoDB",
+ "field_order": [
+ "chapter",
+ "include_in_preview",
+ "column_break_4",
+ "title",
+ "index_label",
+ "section_break_6",
+ "body",
+ "help_section",
+ "help"
+ ],
+ "fields": [
+ {
+ "fieldname": "chapter",
+ "fieldtype": "Link",
+ "in_list_view": 1,
+ "label": "Course Chapter",
+ "options": "Course Chapter",
+ "reqd": 1
+ },
+ {
+ "default": "0",
+ "fieldname": "include_in_preview",
+ "fieldtype": "Check",
+ "label": "Include In Preview"
+ },
+ {
+ "fieldname": "column_break_4",
+ "fieldtype": "Column Break"
+ },
+ {
+ "fieldname": "title",
+ "fieldtype": "Data",
+ "in_list_view": 1,
+ "label": "Title",
+ "reqd": 1
+ },
+ {
+ "fieldname": "index_label",
+ "fieldtype": "Data",
+ "label": "Index Label",
+ "read_only": 1
+ },
+ {
+ "fieldname": "section_break_6",
+ "fieldtype": "Section Break"
+ },
+ {
+ "fieldname": "body",
+ "fieldtype": "Markdown Editor",
+ "label": "Body",
+ "reqd": 1
+ },
+ {
+ "fieldname": "help_section",
+ "fieldtype": "Section Break",
+ "label": "Help"
+ },
+ {
+ "fieldname": "help",
+ "fieldtype": "HTML"
+ }
+ ],
+ "index_web_pages_for_search": 1,
+ "links": [],
+ "modified": "2021-09-29 15:28:51.418015",
+ "modified_by": "Administrator",
+ "module": "LMS",
+ "name": "Course Lesson",
+ "naming_rule": "Expression",
+ "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
+}
diff --git a/community/lms/doctype/course_lesson/course_lesson.py b/community/lms/doctype/course_lesson/course_lesson.py
new file mode 100644
index 00000000..25427c87
--- /dev/null
+++ b/community/lms/doctype/course_lesson/course_lesson.py
@@ -0,0 +1,96 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2021, FOSS United and contributors
+# For license information, please see license.txt
+
+from __future__ import unicode_literals
+import frappe
+from frappe.model.document import Document
+from ...md import markdown_to_html, find_macros
+
+class CourseLesson(Document):
+ def on_update(self):
+ dynamic_documents = ["Exercise", "Quiz"]
+ for section in dynamic_documents:
+ self.update_lesson_name_in_document(section)
+
+ def update_lesson_name_in_document(self, section):
+ doctype_map= {
+ "Exercise": "Exercise",
+ "Quiz": "LMS Quiz"
+ }
+ macros = find_macros(self.body)
+ documents = [value for name, value in macros if name == section]
+ index = 1
+ for name in documents:
+ e = frappe.get_doc(doctype_map[section], name)
+ e.lesson = self.name
+ e.index_ = index
+ e.save()
+ index += 1
+ self.update_orphan_documents(doctype_map[section], documents)
+
+ def update_orphan_documents(self, doctype, documents):
+ """Updates the documents that were previously part of this lesson,
+ but not any more.
+ """
+ linked_documents = {row['name'] for row in frappe.get_all(doctype, {"lesson": self.name})}
+ active_documents = set(documents)
+ orphan_documents = linked_documents - active_documents
+ for name in orphan_documents:
+ ex = frappe.get_doc(doctype, name)
+ ex.lesson = None
+ ex.index_ = 0
+ ex.index_label = ""
+ ex.save()
+
+ def render_html(self):
+ print(self.body)
+ return markdown_to_html(self.body)
+
+ def get_exercises(self):
+ if not self.body:
+ return []
+
+ macros = find_macros(self.body)
+ exercises = [value for name, value in macros if name == "Exercise"]
+ return [frappe.get_doc("Exercise", name) for name in exercises]
+
+ def get_progress(self):
+ return frappe.db.get_value("LMS Course Progress", {"lesson": self.name, "owner": frappe.session.user}, "status")
+
+ def get_slugified_class(self):
+ if self.get_progress():
+ return ("").join([ s for s in self.get_progress().lower().split() ])
+ return
+
+@frappe.whitelist()
+def save_progress(lesson, course, status):
+ if not frappe.db.exists("LMS Batch Membership",
+ {
+ "member": frappe.session.user,
+ "course": course
+ }):
+ return
+
+ if frappe.db.exists("LMS Course Progress",
+ {
+ "lesson": lesson,
+ "owner": frappe.session.user,
+ "course": course
+ }):
+ doc = frappe.get_doc("LMS Course Progress",
+ {
+ "lesson": lesson,
+ "owner": frappe.session.user,
+ "course": course
+ })
+ doc.status = status
+ doc.save(ignore_permissions=True)
+ else:
+ frappe.get_doc({
+ "doctype": "LMS Course Progress",
+ "lesson": lesson,
+ "status": status,
+ }).save(ignore_permissions=True)
+ course_details = frappe.get_doc("LMS Course", course)
+ return course_details.get_course_progress()
diff --git a/community/lms/doctype/course_lesson/test_course_lesson.py b/community/lms/doctype/course_lesson/test_course_lesson.py
new file mode 100644
index 00000000..c5c40a94
--- /dev/null
+++ b/community/lms/doctype/course_lesson/test_course_lesson.py
@@ -0,0 +1,8 @@
+# Copyright (c) 2021, FOSS United and Contributors
+# See license.txt
+
+# import frappe
+import unittest
+
+class TestCourseLesson(unittest.TestCase):
+ pass
diff --git a/community/lms/doctype/exercise/exercise.json b/community/lms/doctype/exercise/exercise.json
index e7f0ea7c..67530594 100644
--- a/community/lms/doctype/exercise/exercise.json
+++ b/community/lms/doctype/exercise/exercise.json
@@ -78,7 +78,7 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Lesson",
- "options": "Lesson"
+ "options": "Course Lesson"
},
{
"fieldname": "index_",
@@ -96,7 +96,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2021-06-01 05:22:15.656013",
+ "modified": "2021-09-29 15:27:55.585874",
"modified_by": "Administrator",
"module": "LMS",
"name": "Exercise",
diff --git a/community/lms/doctype/exercise_submission/exercise_submission.json b/community/lms/doctype/exercise_submission/exercise_submission.json
index 125af148..229e9de6 100644
--- a/community/lms/doctype/exercise_submission/exercise_submission.json
+++ b/community/lms/doctype/exercise_submission/exercise_submission.json
@@ -53,7 +53,7 @@
"fieldname": "lesson",
"fieldtype": "Link",
"label": "Lesson",
- "options": "Lesson"
+ "options": "Course Lesson"
},
{
"fieldname": "image",
@@ -94,7 +94,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2021-06-24 16:22:50.570845",
+ "modified": "2021-09-29 15:27:57.273879",
"modified_by": "Administrator",
"module": "LMS",
"name": "Exercise Submission",
diff --git a/community/lms/doctype/lesson/lesson.py b/community/lms/doctype/lesson/lesson.py
index 9fe2de50..75f00576 100644
--- a/community/lms/doctype/lesson/lesson.py
+++ b/community/lms/doctype/lesson/lesson.py
@@ -55,7 +55,8 @@ class Lesson(Document):
return [frappe.get_doc("Exercise", name) for name in exercises]
def get_progress(self):
- return frappe.db.get_value("LMS Course Progress", {"lesson": self.name, "owner": frappe.session.user}, "status")
+ return frappe.db.get_value("LMS Course Progress",
+ {"lesson": self.name, "owner": frappe.session.user}, "status")
def get_slugified_class(self):
if self.get_progress():
diff --git a/community/lms/doctype/lesson_reference/lesson_reference.json b/community/lms/doctype/lesson_reference/lesson_reference.json
index d7a0dc3a..a3e77ebb 100644
--- a/community/lms/doctype/lesson_reference/lesson_reference.json
+++ b/community/lms/doctype/lesson_reference/lesson_reference.json
@@ -13,14 +13,14 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Lesson",
- "options": "Lesson",
+ "options": "Course Lesson",
"reqd": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
- "modified": "2021-08-31 10:44:42.048232",
+ "modified": "2021-09-30 10:35:47.832547",
"modified_by": "Administrator",
"module": "LMS",
"name": "Lesson Reference",
diff --git a/community/lms/doctype/lms_batch_membership/lms_batch_membership.json b/community/lms/doctype/lms_batch_membership/lms_batch_membership.json
index 3a0bfa0c..7a6a8497 100644
--- a/community/lms/doctype/lms_batch_membership/lms_batch_membership.json
+++ b/community/lms/doctype/lms_batch_membership/lms_batch_membership.json
@@ -72,7 +72,7 @@
"fieldname": "current_lesson",
"fieldtype": "Link",
"label": "Current Lesson",
- "options": "Lesson"
+ "options": "Course Lesson"
},
{
"fetch_from": "member.username",
@@ -84,7 +84,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2021-08-04 17:10:42.708479",
+ "modified": "2021-09-29 15:27:58.765399",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Batch Membership",
diff --git a/community/lms/doctype/lms_course/lms_course.json b/community/lms/doctype/lms_course/lms_course.json
index 30a8475b..d2718857 100644
--- a/community/lms/doctype/lms_course/lms_course.json
+++ b/community/lms/doctype/lms_course/lms_course.json
@@ -148,7 +148,7 @@
"links": [
{
"group": "Chapters",
- "link_doctype": "Chapter",
+ "link_doctype": "Course Chapter",
"link_fieldname": "course"
},
{
@@ -167,7 +167,7 @@
"link_fieldname": "course"
}
],
- "modified": "2021-09-20 12:00:18.325579",
+ "modified": "2021-09-30 10:36:48.759994",
"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 56330d77..5a60f38c 100644
--- a/community/lms/doctype/lms_course/lms_course.py
+++ b/community/lms/doctype/lms_course/lms_course.py
@@ -153,7 +153,7 @@ class LMSCourse(Document):
"""
chapters = []
for row in self.chapters:
- chapter_details = frappe.db.get_value("Chapter", row.chapter,
+ chapter_details = frappe.db.get_value("Course Chapter", row.chapter,
["name", "title", "description"],
as_dict=True)
chapter_details.idx = row.idx
@@ -179,7 +179,7 @@ class LMSCourse(Document):
lesson_list = frappe.get_all("Lesson Reference", {"parent": chapter.name},
["lesson", "idx"], order_by="idx")
for row in lesson_list:
- lesson_details = frappe.get_doc("Lesson", row.lesson)
+ lesson_details = frappe.get_doc("Course Lesson", row.lesson)
lesson_details.number = flt("{}.{}".format(chapter.idx, row.idx))
lessons.append(lesson_details)
return lessons
@@ -217,7 +217,7 @@ class LMSCourse(Document):
if not lesson:
return None
- chapter = frappe.db.get_value("Chapters", {"chapter": lesson.parent}, ["idx"], as_dict=True)
+ chapter = frappe.db.get_value("Chapter Reference", {"chapter": lesson.parent}, ["idx"], as_dict=True)
if not chapter:
return None
@@ -329,6 +329,8 @@ class LMSCourse(Document):
def get_course_progress(self, member=None):
""" Returns the course progress of the session user """
lesson_count = len(self.get_lessons())
+ if not lesson_count:
+ return 0
completed_lessons = frappe.db.count("LMS Course Progress",
{
"course": self.name,
@@ -336,8 +338,6 @@ class LMSCourse(Document):
"status": "Complete"
})
precision = cint(frappe.db.get_default("float_precision")) or 3
- if not lesson_count:
- return 0
return flt(((completed_lessons/lesson_count) * 100), precision)
def get_neighbours(self, current, lessons):
diff --git a/community/lms/doctype/lms_course_interest/lms_course_interest.py b/community/lms/doctype/lms_course_interest/lms_course_interest.py
index 7aed3232..66817f19 100644
--- a/community/lms/doctype/lms_course_interest/lms_course_interest.py
+++ b/community/lms/doctype/lms_course_interest/lms_course_interest.py
@@ -9,9 +9,11 @@ class LMSCourseInterest(Document):
@frappe.whitelist()
def capture_interest(course):
- frappe.get_doc({
+ data = {
"doctype": "LMS Course Interest",
"course": course,
"user": frappe.session.user
- }).save(ignore_permissions=True)
+ }
+ if not frappe.db.exists(data):
+ frappe.get_doc(data).save(ignore_permissions=True)
return "OK"
diff --git a/community/lms/doctype/lms_course_progress/lms_course_progress.json b/community/lms/doctype/lms_course_progress/lms_course_progress.json
index 33d785f6..78452c69 100644
--- a/community/lms/doctype/lms_course_progress/lms_course_progress.json
+++ b/community/lms/doctype/lms_course_progress/lms_course_progress.json
@@ -28,7 +28,7 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Chapter",
- "options": "Chapter",
+ "options": "Course Chapter",
"read_only": 1
},
{
@@ -36,7 +36,7 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Lesson",
- "options": "Lesson"
+ "options": "Course Lesson"
},
{
"fieldname": "status",
@@ -53,7 +53,7 @@
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2021-06-02 13:05:31.114939",
+ "modified": "2021-09-30 13:07:54.246863",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Course Progress",
diff --git a/community/lms/doctype/lms_quiz/lms_quiz.json b/community/lms/doctype/lms_quiz/lms_quiz.json
index a1af03f2..837e8ead 100644
--- a/community/lms/doctype/lms_quiz/lms_quiz.json
+++ b/community/lms/doctype/lms_quiz/lms_quiz.json
@@ -28,13 +28,13 @@
"fieldname": "lesson",
"fieldtype": "Link",
"label": "Lesson",
- "options": "Lesson",
+ "options": "Course Lesson",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"links": [],
- "modified": "2021-09-20 10:44:15.930892",
+ "modified": "2021-09-30 13:10:06.929357",
"modified_by": "Administrator",
"module": "LMS",
"name": "LMS Quiz",
diff --git a/community/lms/report/__init__.py b/community/lms/report/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/community/lms/report/course_progress_summary/__init__.py b/community/lms/report/course_progress_summary/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/community/lms/report/course_progress_summary/course_progress_summary.js b/community/lms/report/course_progress_summary/course_progress_summary.js
new file mode 100644
index 00000000..668e5000
--- /dev/null
+++ b/community/lms/report/course_progress_summary/course_progress_summary.js
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, FOSS United and contributors
+// For license information, please see license.txt
+/* eslint-disable */
+
+frappe.query_reports["Course Progress Summary"] = {
+ "filters": [
+ {
+ "fieldname": "course",
+ "label": __("Course"),
+ "fieldtype": "Link",
+ "options": "LMS Course"
+ }
+ ]
+};
diff --git a/community/lms/report/course_progress_summary/course_progress_summary.json b/community/lms/report/course_progress_summary/course_progress_summary.json
new file mode 100644
index 00000000..c3e85f54
--- /dev/null
+++ b/community/lms/report/course_progress_summary/course_progress_summary.json
@@ -0,0 +1,26 @@
+{
+ "add_total_row": 0,
+ "columns": [],
+ "creation": "2021-09-28 15:31:27.205036",
+ "disable_prepared_report": 0,
+ "disabled": 0,
+ "docstatus": 0,
+ "doctype": "Report",
+ "filters": [],
+ "idx": 0,
+ "is_standard": "Yes",
+ "modified": "2021-09-28 17:09:40.761819",
+ "modified_by": "Administrator",
+ "module": "LMS",
+ "name": "Course Progress Summary",
+ "owner": "Administrator",
+ "prepared_report": 0,
+ "ref_doctype": "LMS Batch Membership",
+ "report_name": "Course Progress Summary",
+ "report_type": "Script Report",
+ "roles": [
+ {
+ "role": "System Manager"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/community/lms/report/course_progress_summary/course_progress_summary.py b/community/lms/report/course_progress_summary/course_progress_summary.py
new file mode 100644
index 00000000..efda989f
--- /dev/null
+++ b/community/lms/report/course_progress_summary/course_progress_summary.py
@@ -0,0 +1,116 @@
+# Copyright (c) 2013, FOSS United and contributors
+# License: MIT. See LICENSE
+
+import frappe
+from frappe.utils import rounded
+from frappe import _
+
+def execute(filters=None):
+ columns, data = [], []
+ columns = get_columns()
+ data = get_data(filters)
+ charts = get_charts(data)
+ return columns, data, [], charts
+
+def get_data(filters=None):
+ summary = []
+ query_filter = {}
+ if filters:
+ query_filter = {
+ "course": filters.course
+ }
+
+ memberships = frappe.get_all(
+ "LMS Batch Membership",
+ query_filter,
+ ["name", "course", "member", "member_name"],
+ order_by="course")
+
+ current_course = memberships[0].course
+ for membership in memberships:
+ if current_course != membership.course:
+ current_course = membership.course
+
+ course_details = frappe.get_doc("LMS Course", current_course)
+ summary.append(frappe._dict({
+ "course": course_details.name,
+ "course_name": course_details.title,
+ "member": membership.member,
+ "member_name": membership.member_name,
+ "progress": rounded(course_details.get_course_progress(membership.member))
+ }))
+
+ return summary
+
+def get_columns():
+ return [
+ {
+ "fieldname": "course",
+ "fieldtype": "Link",
+ "label": _("Course"),
+ "options": "LMS Course",
+ "width": 200
+ },
+ {
+ "fieldname": "course_name",
+ "fieldtype": "Data",
+ "label": _("Course Name"),
+ "width": 300
+ },
+ {
+ "fieldname": "member",
+ "fieldtype": "Link",
+ "label": _("Member"),
+ "options": "User",
+ "width": 200
+ },
+ {
+ "fieldname": "member_name",
+ "fieldtype": "Data",
+ "label": _("Member Name"),
+ "width": 150
+ },
+ {
+ "fieldname": "progress",
+ "fieldtype": "Data",
+ "label": _("Progress (%)"),
+ "width": 120
+ }
+ ]
+
+def get_charts(data):
+ if not data:
+ return None
+
+ completed = 0
+ less_than_hundred = 0
+ less_than_seventy = 0
+ less_than_forty = 0
+ less_than_ten = 0
+
+ for row in data:
+ if row.progress == 100:
+ completed += 1
+ elif row.progress < 100 and row.progress > 70:
+ less_than_hundred += 1
+ elif row.progress < 70 and row.progress > 40:
+ less_than_seventy += 1
+ elif row.progress < 40 and row.progress > 10:
+ less_than_forty += 1
+ elif row.progress < 10:
+ less_than_ten += 1
+
+ charts = {
+ "data": {
+ "labels": ["0-10", "10-40", "40-70", "70-99", "100"],
+ "datasets": [
+ {
+ "name": "Progress (%)",
+ "values": [less_than_ten, less_than_forty, less_than_seventy, less_than_hundred, completed]
+ }
+ ]
+ },
+ "type": "pie",
+ "colors": ["#ff0e0e", "#ff9966", "#ffcc00", "#99cc33", "#339900"]
+ }
+ return charts
diff --git a/community/lms/workspace/lms/lms.json b/community/lms/workspace/lms/lms.json
index 3bbe5663..4f3bf870 100644
--- a/community/lms/workspace/lms/lms.json
+++ b/community/lms/workspace/lms/lms.json
@@ -79,7 +79,7 @@
"hidden": 0,
"is_query_report": 0,
"label": "Chapter",
- "link_to": "Chapter",
+ "link_to": "Course Chapter",
"link_type": "DocType",
"onboard": 0,
"type": "Link"
@@ -166,4 +166,4 @@
"type": "DocType"
}
]
-}
\ No newline at end of file
+}
diff --git a/community/patches.txt b/community/patches.txt
index 0ab8479a..e6d2fcb5 100644
--- a/community/patches.txt
+++ b/community/patches.txt
@@ -12,3 +12,4 @@ community.patches.v0_0.course_instructor_update
execute:frappe.delete_doc("DocType", "Discussion Message")
execute:frappe.delete_doc("DocType", "Discussion Thread")
community.patches.v0_0.rename_chapters_and_lessons_doctype
+community.patches.v0_0.rename_chapter_and_lesson_doctype #29-09-2021
diff --git a/community/patches/v0_0/rename_chapter_and_lesson_doctype.py b/community/patches/v0_0/rename_chapter_and_lesson_doctype.py
new file mode 100644
index 00000000..4dd3bdca
--- /dev/null
+++ b/community/patches/v0_0/rename_chapter_and_lesson_doctype.py
@@ -0,0 +1,40 @@
+import frappe
+
+def execute():
+ frappe.reload_doc("lms", "doctype", "course_chapter")
+ frappe.reload_doc("lms", "doctype", "course_lesson")
+
+ if not frappe.db.count("Course Chapter"):
+ move_chapters()
+
+ if not frappe.db.count("Course Lesson"):
+ move_lessons()
+
+ change_parent_for_lesson_reference()
+
+def move_chapters():
+ docs = frappe.get_all("Chapter", fields=["*"])
+ for doc in docs:
+ if frappe.db.exists("LMS Course", doc.course):
+ name = doc.name
+ doc.update({"doctype": "Course Chapter"})
+ del doc["name"]
+ new_doc = frappe.get_doc(doc)
+ new_doc.save()
+ frappe.rename_doc("Course Chapter", new_doc.name, name)
+
+def move_lessons():
+ docs = frappe.get_all("Lesson", fields=["*"])
+ for doc in docs:
+ if frappe.db.exists("Chapter", doc.chapter):
+ name = doc.name
+ doc.update({"doctype": "Course Lesson"})
+ del doc["name"]
+ new_doc = frappe.get_doc(doc)
+ new_doc.save()
+ frappe.rename_doc("Course Lesson", new_doc.name, name)
+
+def change_parent_for_lesson_reference():
+ lesson_reference = frappe.get_all("Lesson Reference", fields=["name", "parent"])
+ for reference in lesson_reference:
+ frappe.db.set_value("Lesson Reference", reference.name, "parenttype", "Course Chapter")
diff --git a/community/www/batch/learn.html b/community/www/batch/learn.html
index b7ce324a..fca12fa8 100644
--- a/community/www/batch/learn.html
+++ b/community/www/batch/learn.html
@@ -111,7 +111,7 @@
{% macro Discussions() %}
{% set is_instructor = frappe.session.user == course.instructor %}
{% set condition = is_instructor if is_instructor else membership %}
-{% set doctype, docname = "Lesson", lesson.name %}
+{% set doctype, docname = "Course Lesson", lesson.name %}
{% set title = "Questions" %}
{% set cta_title = "New Question" %}
{% set button_name = "Start Learning" %}
diff --git a/community/www/batch/learn.py b/community/www/batch/learn.py
index 52fdddaf..fd48f30c 100644
--- a/community/www/batch/learn.py
+++ b/community/www/batch/learn.py
@@ -48,15 +48,6 @@ def get_current_lesson_details(lesson_number, context):
def get_learn_url(lesson_number, course):
return course.get_learn_url(lesson_number) and course.get_learn_url(lesson_number) + course.query_parameter
-def get_chapter_title(course_name, lesson_number):
- if not lesson_number:
- return
- lesson_split = cstr(lesson_number).split(".")
- chapter_index = lesson_split[0]
- lesson_index = lesson_split[1]
- chapter_name = frappe.db.get_value("Chapter", {"course": course_name, "index_": chapter_index}, "name")
- return frappe.db.get_value("Lesson", {"chapter": chapter_name, "index_": lesson_index}, "title")
-
def get_lesson_index(course, batch, user):
lesson = batch.get_current_lesson(user)
return lesson and course.get_lesson_index(lesson)