fix: conflicts
This commit is contained in:
@@ -83,4 +83,4 @@
|
|||||||
"sort_order": "DESC",
|
"sort_order": "DESC",
|
||||||
"title_field": "title",
|
"title_field": "title",
|
||||||
"track_changes": 1
|
"track_changes": 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,14 +13,14 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Chapter",
|
"label": "Chapter",
|
||||||
"options": "Chapter",
|
"options": "Course Chapter",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-07-27 16:25:02.903245",
|
"modified": "2021-09-30 10:35:30.014950",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "Chapter Reference",
|
"name": "Chapter Reference",
|
||||||
|
|||||||
0
community/lms/doctype/course_chapter/__init__.py
Normal file
0
community/lms/doctype/course_chapter/__init__.py
Normal file
14
community/lms/doctype/course_chapter/course_chapter.js
Normal file
14
community/lms/doctype/course_chapter/course_chapter.js
Normal file
@@ -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,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
86
community/lms/doctype/course_chapter/course_chapter.json
Normal file
86
community/lms/doctype/course_chapter/course_chapter.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
8
community/lms/doctype/course_chapter/course_chapter.py
Normal file
8
community/lms/doctype/course_chapter/course_chapter.py
Normal file
@@ -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
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2021, FOSS United and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestCourseChapter(unittest.TestCase):
|
||||||
|
pass
|
||||||
0
community/lms/doctype/course_lesson/__init__.py
Normal file
0
community/lms/doctype/course_lesson/__init__.py
Normal file
57
community/lms/doctype/course_lesson/course_lesson.js
Normal file
57
community/lms/doctype/course_lesson/course_lesson.js
Normal file
@@ -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(`
|
||||||
|
<p>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.</p>
|
||||||
|
<div class="row font-weight-bold mb-3">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
Content Type
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
Syntax
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
Video
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
{{ Video("url_of_source") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
YouTube Video
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
{{ YouTubeVideo("unique_embed_id") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
Exercise
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
{{ Exercise("exercise_name") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col-sm-4">
|
||||||
|
Quiz
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
{{ Quiz("lms_quiz_name") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
});
|
||||||
97
community/lms/doctype/course_lesson/course_lesson.json
Normal file
97
community/lms/doctype/course_lesson/course_lesson.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
96
community/lms/doctype/course_lesson/course_lesson.py
Normal file
96
community/lms/doctype/course_lesson/course_lesson.py
Normal file
@@ -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()
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
# Copyright (c) 2021, FOSS United and Contributors
|
||||||
|
# See license.txt
|
||||||
|
|
||||||
|
# import frappe
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
class TestCourseLesson(unittest.TestCase):
|
||||||
|
pass
|
||||||
@@ -78,7 +78,7 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Lesson",
|
"label": "Lesson",
|
||||||
"options": "Lesson"
|
"options": "Course Lesson"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "index_",
|
"fieldname": "index_",
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-06-01 05:22:15.656013",
|
"modified": "2021-09-29 15:27:55.585874",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "Exercise",
|
"name": "Exercise",
|
||||||
|
|||||||
@@ -53,7 +53,7 @@
|
|||||||
"fieldname": "lesson",
|
"fieldname": "lesson",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Lesson",
|
"label": "Lesson",
|
||||||
"options": "Lesson"
|
"options": "Course Lesson"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "image",
|
"fieldname": "image",
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-06-24 16:22:50.570845",
|
"modified": "2021-09-29 15:27:57.273879",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "Exercise Submission",
|
"name": "Exercise Submission",
|
||||||
|
|||||||
@@ -55,7 +55,8 @@ class Lesson(Document):
|
|||||||
return [frappe.get_doc("Exercise", name) for name in exercises]
|
return [frappe.get_doc("Exercise", name) for name in exercises]
|
||||||
|
|
||||||
def get_progress(self):
|
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):
|
def get_slugified_class(self):
|
||||||
if self.get_progress():
|
if self.get_progress():
|
||||||
|
|||||||
@@ -13,14 +13,14 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Lesson",
|
"label": "Lesson",
|
||||||
"options": "Lesson",
|
"options": "Course Lesson",
|
||||||
"reqd": 1
|
"reqd": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"istable": 1,
|
"istable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-08-31 10:44:42.048232",
|
"modified": "2021-09-30 10:35:47.832547",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "Lesson Reference",
|
"name": "Lesson Reference",
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
"fieldname": "current_lesson",
|
"fieldname": "current_lesson",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Current Lesson",
|
"label": "Current Lesson",
|
||||||
"options": "Lesson"
|
"options": "Course Lesson"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fetch_from": "member.username",
|
"fetch_from": "member.username",
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-08-04 17:10:42.708479",
|
"modified": "2021-09-29 15:27:58.765399",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Batch Membership",
|
"name": "LMS Batch Membership",
|
||||||
|
|||||||
@@ -148,7 +148,7 @@
|
|||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
"group": "Chapters",
|
"group": "Chapters",
|
||||||
"link_doctype": "Chapter",
|
"link_doctype": "Course Chapter",
|
||||||
"link_fieldname": "course"
|
"link_fieldname": "course"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
"link_fieldname": "course"
|
"link_fieldname": "course"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"modified": "2021-09-20 12:00:18.325579",
|
"modified": "2021-09-30 10:36:48.759994",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Course",
|
"name": "LMS Course",
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ class LMSCourse(Document):
|
|||||||
"""
|
"""
|
||||||
chapters = []
|
chapters = []
|
||||||
for row in self.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"],
|
["name", "title", "description"],
|
||||||
as_dict=True)
|
as_dict=True)
|
||||||
chapter_details.idx = row.idx
|
chapter_details.idx = row.idx
|
||||||
@@ -179,7 +179,7 @@ class LMSCourse(Document):
|
|||||||
lesson_list = frappe.get_all("Lesson Reference", {"parent": chapter.name},
|
lesson_list = frappe.get_all("Lesson Reference", {"parent": chapter.name},
|
||||||
["lesson", "idx"], order_by="idx")
|
["lesson", "idx"], order_by="idx")
|
||||||
for row in lesson_list:
|
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))
|
lesson_details.number = flt("{}.{}".format(chapter.idx, row.idx))
|
||||||
lessons.append(lesson_details)
|
lessons.append(lesson_details)
|
||||||
return lessons
|
return lessons
|
||||||
@@ -217,7 +217,7 @@ class LMSCourse(Document):
|
|||||||
if not lesson:
|
if not lesson:
|
||||||
return None
|
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:
|
if not chapter:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -329,6 +329,8 @@ class LMSCourse(Document):
|
|||||||
def get_course_progress(self, member=None):
|
def get_course_progress(self, member=None):
|
||||||
""" Returns the course progress of the session user """
|
""" Returns the course progress of the session user """
|
||||||
lesson_count = len(self.get_lessons())
|
lesson_count = len(self.get_lessons())
|
||||||
|
if not lesson_count:
|
||||||
|
return 0
|
||||||
completed_lessons = frappe.db.count("LMS Course Progress",
|
completed_lessons = frappe.db.count("LMS Course Progress",
|
||||||
{
|
{
|
||||||
"course": self.name,
|
"course": self.name,
|
||||||
@@ -336,8 +338,6 @@ class LMSCourse(Document):
|
|||||||
"status": "Complete"
|
"status": "Complete"
|
||||||
})
|
})
|
||||||
precision = cint(frappe.db.get_default("float_precision")) or 3
|
precision = cint(frappe.db.get_default("float_precision")) or 3
|
||||||
if not lesson_count:
|
|
||||||
return 0
|
|
||||||
return flt(((completed_lessons/lesson_count) * 100), precision)
|
return flt(((completed_lessons/lesson_count) * 100), precision)
|
||||||
|
|
||||||
def get_neighbours(self, current, lessons):
|
def get_neighbours(self, current, lessons):
|
||||||
|
|||||||
@@ -9,9 +9,11 @@ class LMSCourseInterest(Document):
|
|||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def capture_interest(course):
|
def capture_interest(course):
|
||||||
frappe.get_doc({
|
data = {
|
||||||
"doctype": "LMS Course Interest",
|
"doctype": "LMS Course Interest",
|
||||||
"course": course,
|
"course": course,
|
||||||
"user": frappe.session.user
|
"user": frappe.session.user
|
||||||
}).save(ignore_permissions=True)
|
}
|
||||||
|
if not frappe.db.exists(data):
|
||||||
|
frappe.get_doc(data).save(ignore_permissions=True)
|
||||||
return "OK"
|
return "OK"
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Chapter",
|
"label": "Chapter",
|
||||||
"options": "Chapter",
|
"options": "Course Chapter",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"in_list_view": 1,
|
"in_list_view": 1,
|
||||||
"label": "Lesson",
|
"label": "Lesson",
|
||||||
"options": "Lesson"
|
"options": "Course Lesson"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fieldname": "status",
|
"fieldname": "status",
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-06-02 13:05:31.114939",
|
"modified": "2021-09-30 13:07:54.246863",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Course Progress",
|
"name": "LMS Course Progress",
|
||||||
|
|||||||
@@ -28,13 +28,13 @@
|
|||||||
"fieldname": "lesson",
|
"fieldname": "lesson",
|
||||||
"fieldtype": "Link",
|
"fieldtype": "Link",
|
||||||
"label": "Lesson",
|
"label": "Lesson",
|
||||||
"options": "Lesson",
|
"options": "Course Lesson",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2021-09-20 10:44:15.930892",
|
"modified": "2021-09-30 13:10:06.929357",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Quiz",
|
"name": "LMS Quiz",
|
||||||
|
|||||||
0
community/lms/report/__init__.py
Normal file
0
community/lms/report/__init__.py
Normal file
@@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"is_query_report": 0,
|
"is_query_report": 0,
|
||||||
"label": "Chapter",
|
"label": "Chapter",
|
||||||
"link_to": "Chapter",
|
"link_to": "Course Chapter",
|
||||||
"link_type": "DocType",
|
"link_type": "DocType",
|
||||||
"onboard": 0,
|
"onboard": 0,
|
||||||
"type": "Link"
|
"type": "Link"
|
||||||
@@ -166,4 +166,4 @@
|
|||||||
"type": "DocType"
|
"type": "DocType"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,3 +12,4 @@ community.patches.v0_0.course_instructor_update
|
|||||||
execute:frappe.delete_doc("DocType", "Discussion Message")
|
execute:frappe.delete_doc("DocType", "Discussion Message")
|
||||||
execute:frappe.delete_doc("DocType", "Discussion Thread")
|
execute:frappe.delete_doc("DocType", "Discussion Thread")
|
||||||
community.patches.v0_0.rename_chapters_and_lessons_doctype
|
community.patches.v0_0.rename_chapters_and_lessons_doctype
|
||||||
|
community.patches.v0_0.rename_chapter_and_lesson_doctype #29-09-2021
|
||||||
|
|||||||
40
community/patches/v0_0/rename_chapter_and_lesson_doctype.py
Normal file
40
community/patches/v0_0/rename_chapter_and_lesson_doctype.py
Normal file
@@ -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")
|
||||||
@@ -111,7 +111,7 @@
|
|||||||
{% macro Discussions() %}
|
{% macro Discussions() %}
|
||||||
{% set is_instructor = frappe.session.user == course.instructor %}
|
{% set is_instructor = frappe.session.user == course.instructor %}
|
||||||
{% set condition = is_instructor if is_instructor else membership %}
|
{% 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 title = "Questions" %}
|
||||||
{% set cta_title = "New Question" %}
|
{% set cta_title = "New Question" %}
|
||||||
{% set button_name = "Start Learning" %}
|
{% set button_name = "Start Learning" %}
|
||||||
|
|||||||
@@ -48,15 +48,6 @@ def get_current_lesson_details(lesson_number, context):
|
|||||||
def get_learn_url(lesson_number, course):
|
def get_learn_url(lesson_number, course):
|
||||||
return course.get_learn_url(lesson_number) and course.get_learn_url(lesson_number) + course.query_parameter
|
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):
|
def get_lesson_index(course, batch, user):
|
||||||
lesson = batch.get_current_lesson(user)
|
lesson = batch.get_current_lesson(user)
|
||||||
return lesson and course.get_lesson_index(lesson)
|
return lesson and course.get_lesson_index(lesson)
|
||||||
|
|||||||
Reference in New Issue
Block a user