Merge pull request #17592 from scmmishra/acad-fixes

fix: bug fixes in LMS
diff --git a/erpnext/education/doctype/course/course.py b/erpnext/education/doctype/course/course.py
index 987823a..0747a22 100644
--- a/erpnext/education/doctype/course/course.py
+++ b/erpnext/education/doctype/course/course.py
@@ -20,9 +20,9 @@
 				frappe.throw(_("Total Weightage of all Assessment Criteria must be 100%"))
 
 	def get_topics(self):
-		try:
-			topic_list = self.get_all_children()
-			topic_data = [frappe.get_doc("Topic", topic.topic) for topic in topic_list]
-		except frappe.DoesNotExistError:
-			return None
+		topic_data= []
+		for topic in self.topics:
+			topic_doc = frappe.get_doc("Topic", topic.topic)
+			if topic_doc.topic_content:
+				topic_data.append(topic_doc)
 		return topic_data
\ No newline at end of file
diff --git a/erpnext/education/doctype/course/test_course.py b/erpnext/education/doctype/course/test_course.py
index a24ba8a..4667ac4 100644
--- a/erpnext/education/doctype/course/test_course.py
+++ b/erpnext/education/doctype/course/test_course.py
@@ -3,6 +3,7 @@
 # See license.txt
 from __future__ import unicode_literals
 from erpnext.education.doctype.topic.test_topic import make_topic
+from erpnext.education.doctype.topic.test_topic import make_topic_and_linked_content
 
 import frappe
 import unittest
@@ -11,6 +12,8 @@
 
 class TestCourse(unittest.TestCase):
 	def setUp(self):
+		make_topic_and_linked_content("_Test Topic 1", [{"type":"Article", "name": "_Test Article 1"}])
+		make_topic_and_linked_content("_Test Topic 2", [{"type":"Article", "name": "_Test Article 2"}])
 		make_course_and_linked_topic("_Test Course 1", ["_Test Topic 1", "_Test Topic 2"])
 
 	def test_get_topics(self):
diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.py b/erpnext/education/doctype/course_enrollment/course_enrollment.py
index 9508636..6f2bb0d 100644
--- a/erpnext/education/doctype/course_enrollment/course_enrollment.py
+++ b/erpnext/education/doctype/course_enrollment/course_enrollment.py
@@ -21,7 +21,10 @@
 		progress = []
 		for topic in topics:
 			progress.append(student.get_topic_progress(self.name, topic))
-		return reduce(lambda x,y: x+y, progress) # Flatten out the List
+		if progress:
+			return reduce(lambda x,y: x+y, progress) # Flatten out the List
+		else:
+			return []
 
 	def validate_duplication(self):
 		enrollment = frappe.get_all("Course Enrollment", filters={
diff --git a/erpnext/education/doctype/program/program.py b/erpnext/education/doctype/program/program.py
index dbeda40..d24df5d 100644
--- a/erpnext/education/doctype/program/program.py
+++ b/erpnext/education/doctype/program/program.py
@@ -9,6 +9,6 @@
 class Program(Document):
 
 	def get_course_list(self):
-		program_course_list = self.get_all_children()
+		program_course_list = self.courses
 		course_list = [frappe.get_doc("Course", program_course.course) for program_course in program_course_list]
 		return course_list
\ No newline at end of file
diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py
index cf8407c..529f78d 100644
--- a/erpnext/education/doctype/student/student.py
+++ b/erpnext/education/doctype/student/student.py
@@ -90,13 +90,14 @@
 		"""
 		contents = topic.get_contents()
 		progress = []
-		for content in contents:
-			if content.doctype in ('Article', 'Video'):
-				status = check_content_completion(content.name, content.doctype, course_enrollment_name)
-				progress.append({'content': content.name, 'content_type': content.doctype, 'is_complete': status})
-			elif content.doctype == 'Quiz':
-				status, score, result = check_quiz_completion(content, course_enrollment_name)
-				progress.append({'content': content.name, 'content_type': content.doctype, 'is_complete': status, 'score': score, 'result': result})
+		if contents:
+			for content in contents:
+				if content.doctype in ('Article', 'Video'):
+					status = check_content_completion(content.name, content.doctype, course_enrollment_name)
+					progress.append({'content': content.name, 'content_type': content.doctype, 'is_complete': status})
+				elif content.doctype == 'Quiz':
+					status, score, result = check_quiz_completion(content, course_enrollment_name)
+					progress.append({'content': content.name, 'content_type': content.doctype, 'is_complete': status, 'score': score, 'result': result})
 		return progress
 
 	def enroll_in_program(self, program_name):
diff --git a/erpnext/education/doctype/topic/topic.py b/erpnext/education/doctype/topic/topic.py
index 339fc7d..7e5da32 100644
--- a/erpnext/education/doctype/topic/topic.py
+++ b/erpnext/education/doctype/topic/topic.py
@@ -9,7 +9,7 @@
 class Topic(Document):
 	def get_contents(self):
 		try:
-			topic_content_list = self.get_all_children()
+			topic_content_list = self.topic_content
 			content_data = [frappe.get_doc(topic_content.content_type, topic_content.content) for topic_content in topic_content_list]
 		except Exception as e:
 			frappe.log_error(frappe.get_traceback())
diff --git a/erpnext/education/doctype/topic_content/topic_content.json b/erpnext/education/doctype/topic_content/topic_content.json
index 5220788..444fd1d 100644
--- a/erpnext/education/doctype/topic_content/topic_content.json
+++ b/erpnext/education/doctype/topic_content/topic_content.json
@@ -1,140 +1,44 @@
 {
- "allow_copy": 0,
- "allow_events_in_timeline": 0,
- "allow_guest_to_view": 0,
- "allow_import": 0,
- "allow_rename": 0,
- "beta": 0,
  "creation": "2018-12-12 11:42:57.987434",
- "custom": 0,
- "docstatus": 0,
  "doctype": "DocType",
- "document_type": "",
  "editable_grid": 1,
  "engine": "InnoDB",
+ "field_order": [
+  "content_type",
+  "column_break_2",
+  "content"
+ ],
  "fields": [
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "content_type",
    "fieldtype": "Select",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
    "in_list_view": 1,
-   "in_standard_filter": 0,
    "label": "Content Type",
-   "length": 0,
-   "no_copy": 0,
    "options": "\nArticle\nVideo\nQuiz",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "reqd": 1
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "column_break_2",
-   "fieldtype": "Column Break",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
-   "in_list_view": 0,
-   "in_standard_filter": 0,
-   "length": 0,
-   "no_copy": 0,
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "fieldtype": "Column Break"
   },
   {
-   "allow_bulk_edit": 0,
-   "allow_in_quick_entry": 0,
-   "allow_on_submit": 0,
-   "bold": 0,
-   "collapsible": 0,
-   "columns": 0,
    "fieldname": "content",
    "fieldtype": "Dynamic Link",
-   "hidden": 0,
-   "ignore_user_permissions": 0,
-   "ignore_xss_filter": 0,
-   "in_filter": 0,
-   "in_global_search": 0,
    "in_list_view": 1,
-   "in_standard_filter": 0,
    "label": "Content",
-   "length": 0,
-   "no_copy": 0,
    "options": "content_type",
-   "permlevel": 0,
-   "precision": "",
-   "print_hide": 0,
-   "print_hide_if_no_value": 0,
-   "read_only": 0,
-   "remember_last_selected_value": 0,
-   "report_hide": 0,
-   "reqd": 0,
-   "search_index": 0,
-   "set_only_once": 0,
-   "translatable": 0,
-   "unique": 0
+   "reqd": 1
   }
  ],
- "has_web_view": 0,
- "hide_heading": 0,
- "hide_toolbar": 0,
- "idx": 0,
- "image_view": 0,
- "in_create": 0,
- "is_submittable": 0,
- "issingle": 0,
  "istable": 1,
- "max_attachments": 0,
- "modified": "2018-12-12 11:46:46.112018",
+ "modified": "2019-05-14 11:12:49.153771",
  "modified_by": "Administrator",
  "module": "Education",
  "name": "Topic Content",
- "name_case": "",
  "owner": "Administrator",
  "permissions": [],
  "quick_entry": 1,
- "read_only": 0,
- "read_only_onload": 0,
- "show_name_in_global_search": 0,
  "sort_field": "modified",
  "sort_order": "DESC",
- "track_changes": 1,
- "track_seen": 0,
- "track_views": 0
+ "track_changes": 1
 }
\ No newline at end of file
diff --git a/erpnext/public/js/education/lms/components/CourseCard.vue b/erpnext/public/js/education/lms/components/CourseCard.vue
index 16f8873..dff896f 100644
--- a/erpnext/public/js/education/lms/components/CourseCard.vue
+++ b/erpnext/public/js/education/lms/components/CourseCard.vue
@@ -8,12 +8,7 @@
             <div class='card-body'>
                 <h5 class="card-title">{{ course.course_name }}</h5>
                 <span class="course-list text-muted" id="getting-started">
-                    Topics
-                    <ul class="mb-0 mt-1" style="padding-left: 1.5em;">
-                        <li v-for="topic in course.topics" :key="topic.name">
-                            <div>{{ topic.topic_name }}</div>
-                        </li>
-                    </ul>
+                    {{ course.course_intro }}
                 </span>
             </div>
             <div class='p-3' style="display: flex; justify-content: space-between;">
diff --git a/erpnext/public/js/education/lms/components/Video.vue b/erpnext/public/js/education/lms/components/Video.vue
index 27f922f..ec7b0c0 100644
--- a/erpnext/public/js/education/lms/components/Video.vue
+++ b/erpnext/public/js/education/lms/components/Video.vue
@@ -6,8 +6,7 @@
             <div class="col-md-8">
                 <h2>{{ contentData.name }}</h2>
                 <span class="text-muted">
-                    <i class="octicon octicon-clock" title="Duration"></i> {{ contentData.duration }} Mins
-                    &mdash; Published on {{ contentData.publish_date }}.
+                    <i class="octicon octicon-clock" title="Duration"></i> <span v-if="contentData.duration"> {{ contentData.duration }} Mins &mdash; </span><span v-if="contentData.publish_date"> Published on {{ contentData.publish_date }}. </span>
                 </span>
             </div>
             <div class="col-md-4 text-right">