From abd1d209fbb7a6bf229cef96ef5fcf188012b742 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 1 Oct 2018 15:24:36 +0530 Subject: [PATCH 001/314] Added Content Doctype --- erpnext/education/doctype/content/__init__.py | 0 erpnext/education/doctype/content/content.js | 8 + .../education/doctype/content/content.json | 570 ++++++++++++++++++ erpnext/education/doctype/content/content.py | 10 + .../education/doctype/content/test_content.js | 23 + .../education/doctype/content/test_content.py | 10 + erpnext/education/doctype/course/course.json | 65 +- .../doctype/course_content/__init__.py | 0 .../doctype/course_content/course_content.js | 8 + .../course_content/course_content.json | 140 +++++ .../doctype/course_content/course_content.py | 10 + .../course_content/test_course_content.js | 23 + .../course_content/test_course_content.py | 10 + 13 files changed, 872 insertions(+), 5 deletions(-) create mode 100644 erpnext/education/doctype/content/__init__.py create mode 100644 erpnext/education/doctype/content/content.js create mode 100644 erpnext/education/doctype/content/content.json create mode 100644 erpnext/education/doctype/content/content.py create mode 100644 erpnext/education/doctype/content/test_content.js create mode 100644 erpnext/education/doctype/content/test_content.py create mode 100644 erpnext/education/doctype/course_content/__init__.py create mode 100644 erpnext/education/doctype/course_content/course_content.js create mode 100644 erpnext/education/doctype/course_content/course_content.json create mode 100644 erpnext/education/doctype/course_content/course_content.py create mode 100644 erpnext/education/doctype/course_content/test_course_content.js create mode 100644 erpnext/education/doctype/course_content/test_course_content.py diff --git a/erpnext/education/doctype/content/__init__.py b/erpnext/education/doctype/content/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/content/content.js b/erpnext/education/doctype/content/content.js new file mode 100644 index 0000000000..ae3e411c9a --- /dev/null +++ b/erpnext/education/doctype/content/content.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Content', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/content/content.json b/erpnext/education/doctype/content/content.json new file mode 100644 index 0000000000..28867566d8 --- /dev/null +++ b/erpnext/education/doctype/content/content.json @@ -0,0 +1,570 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 1, + "allow_rename": 1, + "autoname": "format:{content_type}-{title}", + "beta": 0, + "creation": "2018-10-01 13:17:45.939706", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "Document", + "editable_grid": 1, + "engine": "InnoDB", + "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": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "content_type", + "fieldname": "details_section", + "fieldtype": "Section 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, + "label": "Details", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "", + "fieldname": "title", + "fieldtype": "Data", + "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, + "label": "Title", + "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": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "is_published", + "fieldtype": "Check", + "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, + "label": "Is Published", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_5", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.content_type != \"Quiz\"", + "fieldname": "author", + "fieldtype": "Link", + "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, + "label": "Author", + "length": 0, + "no_copy": 0, + "options": "User", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "content_publish_date", + "fieldtype": "Date", + "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, + "label": "Content Publish Date", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.content_type == \"Quiz\"", + "fieldname": "quiz_section", + "fieldtype": "Section 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, + "label": "Quiz", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "quiz", + "fieldtype": "Data", + "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, + "label": "Quiz", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.content_type == \"Article\"", + "fieldname": "article_section", + "fieldtype": "Section 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, + "label": "Article", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "article_content", + "fieldtype": "Text Editor", + "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, + "label": "Article Content", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:doc.content_type == \"Video\"", + "fieldname": "video", + "fieldtype": "Section 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, + "label": "Video", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "video_url", + "fieldtype": "Data", + "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, + "label": "Video URL", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "video_duration", + "fieldtype": "Data", + "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, + "label": "Video Duration", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "video_description", + "fieldtype": "Text Editor", + "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, + "label": "Video Description", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-10-01 15:21:41.418754", + "modified_by": "Administrator", + "module": "Education", + "name": "Content", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Academics User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "restrict_to_domain": "Education", + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 1, + "track_seen": 0, + "track_views": 0 +} \ No newline at end of file diff --git a/erpnext/education/doctype/content/content.py b/erpnext/education/doctype/content/content.py new file mode 100644 index 0000000000..5c83892e9d --- /dev/null +++ b/erpnext/education/doctype/content/content.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class Content(Document): + pass diff --git a/erpnext/education/doctype/content/test_content.js b/erpnext/education/doctype/content/test_content.js new file mode 100644 index 0000000000..a275a0d7f5 --- /dev/null +++ b/erpnext/education/doctype/content/test_content.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Content", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Content + () => frappe.tests.make('Content', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/content/test_content.py b/erpnext/education/doctype/content/test_content.py new file mode 100644 index 0000000000..6e3091dd43 --- /dev/null +++ b/erpnext/education/doctype/content/test_content.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestContent(unittest.TestCase): + pass diff --git a/erpnext/education/doctype/course/course.json b/erpnext/education/doctype/course/course.json index 15360f8d58..3effd86eba 100644 --- a/erpnext/education/doctype/course/course.json +++ b/erpnext/education/doctype/course/course.json @@ -15,6 +15,7 @@ "fields": [ { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -41,10 +42,12 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -72,10 +75,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -102,10 +107,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -131,10 +138,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -161,10 +170,12 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, - "unique": 0 + "translatable": 0, + "unique": 1 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -191,10 +202,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -208,6 +221,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, + "label": "Course Details", "length": 0, "no_copy": 0, "permlevel": 0, @@ -220,10 +234,45 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "course_content", + "fieldtype": "Table", + "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, + "label": "Course Content", + "length": 0, + "no_copy": 0, + "options": "Course Content", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -250,10 +299,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -280,10 +331,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -311,10 +364,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -342,6 +397,7 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 } ], @@ -356,7 +412,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-11-10 19:06:28.909585", + "modified": "2018-10-01 15:05:22.653467", "modified_by": "Administrator", "module": "Education", "name": "Course", @@ -365,7 +421,6 @@ "permissions": [ { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 1, "delete": 1, @@ -385,7 +440,6 @@ }, { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 1, "delete": 1, @@ -413,5 +467,6 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 0, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/education/doctype/course_content/__init__.py b/erpnext/education/doctype/course_content/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/course_content/course_content.js b/erpnext/education/doctype/course_content/course_content.js new file mode 100644 index 0000000000..b9faf99aaf --- /dev/null +++ b/erpnext/education/doctype/course_content/course_content.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Course Content', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/course_content/course_content.json b/erpnext/education/doctype/course_content/course_content.json new file mode 100644 index 0000000000..084078b868 --- /dev/null +++ b/erpnext/education/doctype/course_content/course_content.json @@ -0,0 +1,140 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-01 13:04:09.313771", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "content", + "fieldtype": "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", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "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, + "label": "", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "content.content_type", + "fieldname": "content_type", + "fieldtype": "Data", + "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, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + } + ], + "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-10-01 14:19:58.403724", + "modified_by": "Administrator", + "module": "Education", + "name": "Course 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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/course_content/course_content.py b/erpnext/education/doctype/course_content/course_content.py new file mode 100644 index 0000000000..0d2f85ab50 --- /dev/null +++ b/erpnext/education/doctype/course_content/course_content.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class CourseContent(Document): + pass diff --git a/erpnext/education/doctype/course_content/test_course_content.js b/erpnext/education/doctype/course_content/test_course_content.js new file mode 100644 index 0000000000..786e67e9a3 --- /dev/null +++ b/erpnext/education/doctype/course_content/test_course_content.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Course Content", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Course Content + () => frappe.tests.make('Course Content', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/course_content/test_course_content.py b/erpnext/education/doctype/course_content/test_course_content.py new file mode 100644 index 0000000000..9be4b1f5ce --- /dev/null +++ b/erpnext/education/doctype/course_content/test_course_content.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestCourseContent(unittest.TestCase): + pass From f05837a895366637cdd45ffce7588a2f177837a5 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 1 Oct 2018 15:37:09 +0530 Subject: [PATCH 002/314] Updated Content Doctype --- .../education/doctype/content/content.json | 37 +------------------ 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/erpnext/education/doctype/content/content.json b/erpnext/education/doctype/content/content.json index 28867566d8..e80a7f723e 100644 --- a/erpnext/education/doctype/content/content.json +++ b/erpnext/education/doctype/content/content.json @@ -182,40 +182,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "eval:doc.content_type != \"Quiz\"", - "fieldname": "author", - "fieldtype": "Link", - "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, - "label": "Author", - "length": 0, - "no_copy": 0, - "options": "User", - "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 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, + "default": "Today", "fieldname": "content_publish_date", "fieldtype": "Date", "hidden": 0, @@ -511,7 +478,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-01 15:21:41.418754", + "modified": "2018-10-01 15:36:14.509871", "modified_by": "Administrator", "module": "Education", "name": "Content", From 84a49d5ea778e5c8c9bc70ea79c5ff5408d2d29d Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 1 Oct 2018 16:19:40 +0530 Subject: [PATCH 003/314] Modified Content doctype, added question child table for quiz --- .../education/doctype/content/content.json | 12 +- .../education/doctype/question/__init__.py | 0 .../education/doctype/question/question.json | 235 ++++++++++++++++++ .../education/doctype/question/question.py | 10 + 4 files changed, 252 insertions(+), 5 deletions(-) create mode 100644 erpnext/education/doctype/question/__init__.py create mode 100644 erpnext/education/doctype/question/question.json create mode 100644 erpnext/education/doctype/question/question.py diff --git a/erpnext/education/doctype/content/content.json b/erpnext/education/doctype/content/content.json index e80a7f723e..c3840a45db 100644 --- a/erpnext/education/doctype/content/content.json +++ b/erpnext/education/doctype/content/content.json @@ -42,7 +42,7 @@ "report_hide": 0, "reqd": 1, "search_index": 0, - "set_only_once": 0, + "set_only_once": 1, "translatable": 0, "unique": 0 }, @@ -53,7 +53,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "depends_on": "content_type", + "depends_on": "", "fieldname": "details_section", "fieldtype": "Section Break", "hidden": 0, @@ -183,6 +183,7 @@ "collapsible": 0, "columns": 0, "default": "Today", + "depends_on": "eval:doc.content_type != \"Quiz\" ", "fieldname": "content_publish_date", "fieldtype": "Date", "hidden": 0, @@ -249,7 +250,7 @@ "collapsible": 0, "columns": 0, "fieldname": "quiz", - "fieldtype": "Data", + "fieldtype": "Table", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -257,9 +258,10 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Quiz", + "label": "Questions", "length": 0, "no_copy": 0, + "options": "Question", "permlevel": 0, "precision": "", "print_hide": 0, @@ -478,7 +480,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-01 15:36:14.509871", + "modified": "2018-10-01 16:09:29.505488", "modified_by": "Administrator", "module": "Education", "name": "Content", diff --git a/erpnext/education/doctype/question/__init__.py b/erpnext/education/doctype/question/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json new file mode 100644 index 0000000000..28cbb5f976 --- /dev/null +++ b/erpnext/education/doctype/question/question.json @@ -0,0 +1,235 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-01 15:58:00.696815", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "question", + "fieldtype": "Text Editor", + "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": "Question", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "option_1", + "fieldtype": "Data", + "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, + "label": "Option 1", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "option_2", + "fieldtype": "Data", + "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, + "label": "Option 2", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "option_3", + "fieldtype": "Data", + "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, + "label": "Option 3", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "option_4", + "fieldtype": "Data", + "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, + "label": "Option 4", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "description": "For multiple correct options, write each option number separated by comma (Example: 1,3)", + "fieldname": "correct_options", + "fieldtype": "Data", + "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, + "label": "Correct Options", + "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 + } + ], + "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-10-01 16:17:14.877309", + "modified_by": "Administrator", + "module": "Education", + "name": "Question", + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/question/question.py b/erpnext/education/doctype/question/question.py new file mode 100644 index 0000000000..1608fddd8b --- /dev/null +++ b/erpnext/education/doctype/question/question.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class Question(Document): + pass From 8c41abc2df25e11331b5851f8e61618284b32631 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 2 Oct 2018 15:41:23 +0530 Subject: [PATCH 004/314] Modified education menu items --- erpnext/config/education.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/erpnext/config/education.py b/erpnext/config/education.py index 96e7e8118e..b845537b06 100644 --- a/erpnext/config/education.py +++ b/erpnext/config/education.py @@ -32,6 +32,10 @@ def get_data(): "type": "doctype", "name": "Student Applicant" }, + { + "type": "doctype", + "name": "Web Academy Applicant" + }, { "type": "doctype", "name": "Student Admission" @@ -179,13 +183,17 @@ def get_data(): { "label": _("Masters"), "items": [ + { + "type": "doctype", + "name": "Program" + }, { "type": "doctype", "name": "Course" }, { "type": "doctype", - "name": "Program" + "name": "Content" }, { "type": "doctype", From 4e208e99bceb182b0499a27da4c88adbb1889522 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 2 Oct 2018 15:43:47 +0530 Subject: [PATCH 005/314] Added Student Course Acitivity doctype --- .../student_course_activity/__init__.py | 0 .../student_course_activity.js | 8 ++ .../student_course_activity.json | 93 +++++++++++++++++++ .../student_course_activity.py | 10 ++ .../test_student_course_activity.js | 23 +++++ .../test_student_course_activity.py | 10 ++ 6 files changed, 144 insertions(+) create mode 100644 erpnext/education/doctype/student_course_activity/__init__.py create mode 100644 erpnext/education/doctype/student_course_activity/student_course_activity.js create mode 100644 erpnext/education/doctype/student_course_activity/student_course_activity.json create mode 100644 erpnext/education/doctype/student_course_activity/student_course_activity.py create mode 100644 erpnext/education/doctype/student_course_activity/test_student_course_activity.js create mode 100644 erpnext/education/doctype/student_course_activity/test_student_course_activity.py diff --git a/erpnext/education/doctype/student_course_activity/__init__.py b/erpnext/education/doctype/student_course_activity/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.js b/erpnext/education/doctype/student_course_activity/student_course_activity.js new file mode 100644 index 0000000000..101abeff2d --- /dev/null +++ b/erpnext/education/doctype/student_course_activity/student_course_activity.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Student Course Activity', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.json b/erpnext/education/doctype/student_course_activity/student_course_activity.json new file mode 100644 index 0000000000..96041c89ad --- /dev/null +++ b/erpnext/education/doctype/student_course_activity/student_course_activity.json @@ -0,0 +1,93 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-01 17:35:54.391413", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "data_1", + "fieldtype": "Data", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-10-01 17:35:54.391413", + "modified_by": "Administrator", + "module": "Education", + "name": "Student Course Activity", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.py b/erpnext/education/doctype/student_course_activity/student_course_activity.py new file mode 100644 index 0000000000..92d26822d1 --- /dev/null +++ b/erpnext/education/doctype/student_course_activity/student_course_activity.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class StudentCourseActivity(Document): + pass diff --git a/erpnext/education/doctype/student_course_activity/test_student_course_activity.js b/erpnext/education/doctype/student_course_activity/test_student_course_activity.js new file mode 100644 index 0000000000..df6ce3745e --- /dev/null +++ b/erpnext/education/doctype/student_course_activity/test_student_course_activity.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Student Course Activity", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Student Course Activity + () => frappe.tests.make('Student Course Activity', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/student_course_activity/test_student_course_activity.py b/erpnext/education/doctype/student_course_activity/test_student_course_activity.py new file mode 100644 index 0000000000..9045a9ce9b --- /dev/null +++ b/erpnext/education/doctype/student_course_activity/test_student_course_activity.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestStudentCourseActivity(unittest.TestCase): + pass From 43da645be0827624d43e385d117466fdc9fdf3b8 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Wed, 3 Oct 2018 09:30:56 +0530 Subject: [PATCH 006/314] Added Web Academy Applicant doctype --- .../doctype/web_academy_applicant/__init__.py | 0 .../test_web_academy_applicant.js | 23 ++ .../test_web_academy_applicant.py | 10 + .../web_academy_applicant.js | 8 + .../web_academy_applicant.json | 320 ++++++++++++++++++ .../web_academy_applicant.py | 48 +++ 6 files changed, 409 insertions(+) create mode 100644 erpnext/education/doctype/web_academy_applicant/__init__.py create mode 100644 erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.js create mode 100644 erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.py create mode 100644 erpnext/education/doctype/web_academy_applicant/web_academy_applicant.js create mode 100644 erpnext/education/doctype/web_academy_applicant/web_academy_applicant.json create mode 100644 erpnext/education/doctype/web_academy_applicant/web_academy_applicant.py diff --git a/erpnext/education/doctype/web_academy_applicant/__init__.py b/erpnext/education/doctype/web_academy_applicant/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.js b/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.js new file mode 100644 index 0000000000..025a5131c1 --- /dev/null +++ b/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Web Academy Applicant", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Web Academy Applicant + () => frappe.tests.make('Web Academy Applicant', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.py b/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.py new file mode 100644 index 0000000000..1d856749e3 --- /dev/null +++ b/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestWebAcademyApplicant(unittest.TestCase): + pass diff --git a/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.js b/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.js new file mode 100644 index 0000000000..f498509915 --- /dev/null +++ b/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Web Academy Applicant', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.json b/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.json new file mode 100644 index 0000000000..e8ff98783b --- /dev/null +++ b/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.json @@ -0,0 +1,320 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "EDU-LMS-.YYYY.-.#####", + "beta": 0, + "creation": "2018-10-02 13:41:00.788521", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "first_name", + "fieldtype": "Data", + "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": "First Name", + "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": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "middle_name", + "fieldtype": "Data", + "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, + "label": "Middle Name", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "last_name", + "fieldtype": "Data", + "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, + "label": "Last Name", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "program", + "fieldtype": "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": "Program", + "length": 0, + "no_copy": 0, + "options": "Program", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "account_details_section", + "fieldtype": "Section 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, + "label": "Account Details", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "student_email_address", + "fieldtype": "Data", + "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": "Student Email Address", + "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": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, + "unique": 1 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "password", + "fieldtype": "Password", + "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, + "label": "Password", + "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": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "payment_status", + "fieldtype": "Data", + "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, + "label": "Payment Status", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-10-02 15:01:59.632345", + "modified_by": "Administrator", + "module": "Education", + "name": "Web Academy Applicant", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.py b/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.py new file mode 100644 index 0000000000..a6a94c9733 --- /dev/null +++ b/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import print_function, unicode_literals +import frappe +from frappe import _ +from frappe.model.document import Document +from frappe.utils import getdate +from frappe.utils.password import get_decrypted_password + +class WebAcademyApplicant(Document): + def before_insert(self): + # Before a new document is saved + self.check_if_student_account_already_exists(self.student_email_address) + + def after_insert(self): + # After the application is inserted in the database, create a new student + self.create_new_student() + + def check_if_student_account_already_exists(self, email): + # Check if a student account alread exists, if it does, throw an error + get_accounts = frappe.get_all('Student', filters={'student_email_id': email}) + if len(get_accounts) != 0: + frappe.throw('Student with Email {0} already Exists.'.format(self.student_email_address)) + + def create_new_student(self): + student = frappe.get_doc({ + 'doctype': 'Student', + 'student_email_id': self.student_email_address, + 'first_name': self.first_name, + 'last_name': self.last_name, + 'middle_name': self.middle_name + }) + student_user_account = frappe.get_doc({ + 'doctype': 'User', + 'email': self.student_email_address, + 'first_name': self.first_name, + 'last_name': self.last_name, + 'new_passsword': get_decrypted_password(self.doctype, self.name, 'password') + + }) + student.save() + if(self.lms_user == 1): + student_user_account.add_roles("LMS User") + else: + student_user_account.add_roles("Student", "LMS User") + student_user_account.save() \ No newline at end of file From 55e7c1a866b7071e4c77ac7ef99a6a17de7c23c8 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 8 Oct 2018 15:20:45 +0530 Subject: [PATCH 007/314] api: create user account for student Co-authored-by: Chinmay Pai --- erpnext/education/api.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/erpnext/education/api.py b/erpnext/education/api.py index 30d5588073..b75635ee23 100644 --- a/erpnext/education/api.py +++ b/erpnext/education/api.py @@ -38,7 +38,18 @@ def enroll_student(source_name): program_enrollment.student = student.name program_enrollment.student_name = student.title program_enrollment.program = frappe.db.get_value("Student Applicant", source_name, "program") - frappe.publish_realtime('enroll_student_progress', {"progress": [4, 4]}, user=frappe.session.user) + frappe.publish_realtime('enroll_student_progress', {"progress": [4, 4]}, user=frappe.session.user) + student_user = frappe.get_doc({ + 'doctype':'User', + 'first_name': student.first_name, + 'email': student.student_email_id, + 'send_welcome_email': 1, + 'user_type': 'Website User' + }) + student_user.add_roles("Student", "LMS User") + student_user.save() + update_password_link = student_user.reset_password() + print(update_password_link) return program_enrollment From b3b003f51817be129606b1f88b6c02e7fcffa1bb Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 8 Oct 2018 15:24:10 +0530 Subject: [PATCH 008/314] course_activity: create doctype for tracking student course activity Co-authored-by: Chinmay Pai --- .../student_course_activity.json | 75 ++++++++++++++++++- .../student_course_activity.py | 17 ++++- 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.json b/erpnext/education/doctype/student_course_activity/student_course_activity.json index 96041c89ad..1d8f98d0b1 100644 --- a/erpnext/education/doctype/student_course_activity/student_course_activity.json +++ b/erpnext/education/doctype/student_course_activity/student_course_activity.json @@ -3,6 +3,7 @@ "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, + "autoname": "format:{student_name}-{program_name}", "beta": 0, "creation": "2018-10-01 17:35:54.391413", "custom": 0, @@ -19,8 +20,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "data_1", - "fieldtype": "Data", + "fieldname": "student_name", + "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -28,8 +29,76 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, + "label": "Student Name", "length": 0, "no_copy": 0, + "options": "Student", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "program_name", + "fieldtype": "Link", + "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, + "label": "Program Name", + "length": 0, + "no_copy": 0, + "options": "Program", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "lms_activity", + "fieldtype": "Table", + "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, + "label": "LMS Activity", + "length": 0, + "no_copy": 0, + "options": "LMS Activity", "permlevel": 0, "precision": "", "print_hide": 0, @@ -54,7 +123,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-01 17:35:54.391413", + "modified": "2018-10-08 12:10:28.602848", "modified_by": "Administrator", "module": "Education", "name": "Student Course Activity", diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.py b/erpnext/education/doctype/student_course_activity/student_course_activity.py index 92d26822d1..bf5778fc36 100644 --- a/erpnext/education/doctype/student_course_activity/student_course_activity.py +++ b/erpnext/education/doctype/student_course_activity/student_course_activity.py @@ -7,4 +7,19 @@ import frappe from frappe.model.document import Document class StudentCourseActivity(Document): - pass + def validate(self): + self.check_if_enrolled() + # self.check_if_course_present() + + def check_if_enrolled(self): + programs_list = frappe.get_list("Program Enrollment", filters={'student': self.student_name}, fields=['program']) + programs_enrolled_by_student = [item.program for item in programs_list] + if self.program_name not in programs_enrolled_by_student: + frappe.throw("Student {0} is not enrolled in program {1} ".format(self.student_name, self.program_name)) + + # def check_if_course_present(self): + # """ Get set of unique courses from lms_activity child table and make a list of it as assign it to course_list""" + # course_list = list(set([activity.course_name for activity in self.lms_activity])) + # current_program = frappe.get_doc('Program', self.program_name) + # courses_in_current_program = [course.course_name for course in current_program.courses] + # if len(set(courses_in_current_program) - set(course_list)) == 0: \ No newline at end of file From 836a4b5e541420382a13eebdaffbdef769ab2160 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 8 Oct 2018 15:26:05 +0530 Subject: [PATCH 009/314] lms: add activity child table and create frontend Co-authored-by: Chinmay Pai --- .../doctype/lms_activity/__init__.py | 0 .../doctype/lms_activity/lms_activity.json | 208 ++++++++++++++++++ .../doctype/lms_activity/lms_activity.py | 10 + erpnext/www/lms/__init__.py | 0 erpnext/www/lms/course.html | 63 ++++++ erpnext/www/lms/course.py | 2 + erpnext/www/lms/index.css | 101 +++++++++ erpnext/www/lms/index.html | 87 ++++++++ erpnext/www/lms/index.js | 30 +++ erpnext/www/lms/index.py | 5 + erpnext/www/lms/program.html | 70 ++++++ erpnext/www/lms/program.py | 20 ++ .../lms/templates/includes/footer/footer.html | 60 +++++ .../lms/templates/includes/highlights.html | 41 ++++ 14 files changed, 697 insertions(+) create mode 100644 erpnext/education/doctype/lms_activity/__init__.py create mode 100644 erpnext/education/doctype/lms_activity/lms_activity.json create mode 100644 erpnext/education/doctype/lms_activity/lms_activity.py create mode 100644 erpnext/www/lms/__init__.py create mode 100644 erpnext/www/lms/course.html create mode 100644 erpnext/www/lms/course.py create mode 100644 erpnext/www/lms/index.css create mode 100644 erpnext/www/lms/index.html create mode 100644 erpnext/www/lms/index.js create mode 100644 erpnext/www/lms/index.py create mode 100644 erpnext/www/lms/program.html create mode 100644 erpnext/www/lms/program.py create mode 100644 erpnext/www/lms/templates/includes/footer/footer.html create mode 100644 erpnext/www/lms/templates/includes/highlights.html diff --git a/erpnext/education/doctype/lms_activity/__init__.py b/erpnext/education/doctype/lms_activity/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/lms_activity/lms_activity.json b/erpnext/education/doctype/lms_activity/lms_activity.json new file mode 100644 index 0000000000..f7bc30b10a --- /dev/null +++ b/erpnext/education/doctype/lms_activity/lms_activity.json @@ -0,0 +1,208 @@ +{ + "allow_copy": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-08 10:59:58.325210", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "course_name", + "fieldtype": "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": "Course Name", + "length": 0, + "no_copy": 0, + "options": "Course", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "", + "fieldname": "lesson_name", + "fieldtype": "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": "Lesson Name", + "length": 0, + "no_copy": 0, + "options": "Content", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "quiz_score", + "fieldtype": "Data", + "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, + "label": "Quiz Score", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "Unattempted", + "fieldname": "quiz_status", + "fieldtype": "Select", + "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, + "label": "Quiz Status", + "length": 0, + "no_copy": 0, + "options": "\nUnattempted\nPassed\nFailed", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "lesson_status", + "fieldtype": "Select", + "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, + "label": "Lesson Status", + "length": 0, + "no_copy": 0, + "options": "\nOngoing\nCompleted", + "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 + } + ], + "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-10-08 12:48:34.394511", + "modified_by": "Administrator", + "module": "Education", + "name": "LMS Activity", + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/lms_activity/lms_activity.py b/erpnext/education/doctype/lms_activity/lms_activity.py new file mode 100644 index 0000000000..cff70cbd8b --- /dev/null +++ b/erpnext/education/doctype/lms_activity/lms_activity.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class LMSActivity(Document): + pass diff --git a/erpnext/www/lms/__init__.py b/erpnext/www/lms/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/www/lms/course.html b/erpnext/www/lms/course.html new file mode 100644 index 0000000000..4538b9f573 --- /dev/null +++ b/erpnext/www/lms/course.html @@ -0,0 +1,63 @@ +{% extends "frappe_theme/templates/base.html" %} +{% block title %}ERPNext Academy{% endblock %} + +{% from "templates/includes/media.html" import media %} + +{% block head_include %} + + +{% endblock %} + +{% macro video(id) %} +
+ +
+{% endmacro %} + +{% block content %} +
+
+ {% if lesson.video_url is defined %} + {{ video("lesson,video") }} + {% endif %} +
+
+

{{ lesson.name }}

+ + 49 Mins + — Published on 28th October 2018. + +
+
+ Previous + Next +
+
+
+
+
+{% for lesson in lesson_list %} + {{ lesson }} +{% endfor %} +
+
+
+ {{ lesson.content }} +
+ + +
+ +
+ + +{% endblock %} \ No newline at end of file diff --git a/erpnext/www/lms/course.py b/erpnext/www/lms/course.py new file mode 100644 index 0000000000..453c9c7905 --- /dev/null +++ b/erpnext/www/lms/course.py @@ -0,0 +1,2 @@ +# current_module = frappe.get_doc("Course", frappe.form_dict["lesson"]) +# current_lesson = frappe.get_doc("Lesson", frappe.form_dict["lesson"]) \ No newline at end of file diff --git a/erpnext/www/lms/index.css b/erpnext/www/lms/index.css new file mode 100644 index 0000000000..22be3be59e --- /dev/null +++ b/erpnext/www/lms/index.css @@ -0,0 +1,101 @@ +.page-content { + padding-bottom: 0px !important; +} + +.dashboard-section { + margin: auto; + max-width: 90%; +} + +.dashboard-section h1 { + font-size: 1.5em; +} + +@media(min-width: 768px) { + .dashboard-section { + max-width: 80%; + } +} + +@media(min-width: 992px) { + .dashboard-section { + max-width: 65%; + } +} + +.hero-content h1 { + font-size: 1.85em; + font-weight: 300; +} + +.hero { + border-bottom: 0px; +} + +.erp-hero { + border-bottom: 1px solid #e1e9f0; +} + +.hero-content p { + margin-bottom: 100px; +} + +.navbar { + border-bottom: 0px; +} + +.main-illustration { + margin: -90px 0 -60px -32px; + min-height: 420px; +} + +.hero-title { + font-size: 32px; +} + +@media screen and (max-width: 750px) { + .main-illustration { + min-height: inherit; + } +} + +@media screen and (max-width: 480px) { + .main-illustration { + margin: -60px 0 -20px -16px; + } + + .hero-title { + font-size: 26px; + } + + .hero-title+p { + font-size: 16px; + } +} + + +.modal-dialog { + max-width: 800px; + margin: 30px auto; +} + +.modal-body { + position: relative; + padding: 0px; + background-color: black; +} + +.close { + position: absolute; + right: -30px; + top: 0; + z-index: 999; + font-size: 2rem; + font-weight: normal; + color: #fff; + opacity: 1; +} + +.video-btn { + color: white !important; +} \ No newline at end of file diff --git a/erpnext/www/lms/index.html b/erpnext/www/lms/index.html new file mode 100644 index 0000000000..1974d4f569 --- /dev/null +++ b/erpnext/www/lms/index.html @@ -0,0 +1,87 @@ +{% extends "frappe_theme/templates/base.html" %} +{% block title %}ERPNext Academy{% endblock %} + +{% from "templates/includes/media.html" import media %} + +{% block head_include %} + + +{% endblock %} + +{% macro featured_card(program_name, description, hero_image, code) %} +
+
+ +
+ +
{{ program_name }}
+
+
{{ description }}
+
+ +
+
+{% endmacro %} + +{% block content %} +
+
+
+ +
+

Become an ERPNext Expert

+
    +
+

+ A platform for enterpreneurs, developers and implementors to learn the world's leading 100% Open + Source ERP

+

+ + Enroll Now +

+
+ +
+
+

Featured Programs

+

Master ERPNext with our Expert Learning Paths

+ {% for program in featured %} + {{ featured_card(program.program_name, program.description, program.hero_image, program.program_code) }} + {% endfor %} +
+ View All +
+
+
+ +{% include "www/lms/templates/includes/highlights.html" %} +
+ + +
+ + +{% endblock %} \ No newline at end of file diff --git a/erpnext/www/lms/index.js b/erpnext/www/lms/index.js new file mode 100644 index 0000000000..8fcda6e1e0 --- /dev/null +++ b/erpnext/www/lms/index.js @@ -0,0 +1,30 @@ +$(function () { + setTimeout(function () { + $(".later").fadeIn(); + }, 1000); +}); + +$(document).ready(function () { + + var $videoSrc; + // Gets the video src from the data-src on each button + $('.video-btn').click(function () { + $videoSrc = $(this).attr("data-src"); + console.log($videoSrc); + }); + console.log($videoSrc); + + + // when the modal is opened autoplay it + $('#myModal').on('shown.bs.modal', function (e) { + + // set the video src to autoplay and not to show related video. Youtube related video is like a box of chocolates... you never know what you're gonna get + $("#ytplayer").attr('src', "https://www.youtube.com/embed/" + $videoSrc + "?autoplay=0"); + }) + // stop playing the youtube video when I close the modal + $('#myModal').on('hide.bs.modal', function (e) { + // a poor man's stop video + $("#ytplayer").attr('src', $videoSrc); + }) + // document ready +}); \ No newline at end of file diff --git a/erpnext/www/lms/index.py b/erpnext/www/lms/index.py new file mode 100644 index 0000000000..16772a4f5d --- /dev/null +++ b/erpnext/www/lms/index.py @@ -0,0 +1,5 @@ +from __future__ import unicode_literals +import frappe + +def get_context(context): + context.featured = frappe.get_all('Program', filters={'is_featured': 1}, fields=['program_name', 'program_code', 'description', 'hero_image']) \ No newline at end of file diff --git a/erpnext/www/lms/program.html b/erpnext/www/lms/program.html new file mode 100644 index 0000000000..e079b4155a --- /dev/null +++ b/erpnext/www/lms/program.html @@ -0,0 +1,70 @@ +{% extends "frappe_theme/templates/base.html" %} +{% block title %}ERPNext Academy{% endblock %} + +{% block head_include %} + + +{% endblock %} + +{% macro course_card(name) %} +
+
+
+
+
{{ name }}
+ + Course Content +
    + {% for content in course_data[name] %} +
  • {{ content }}
  • + {% endfor %} +
+
+
+ +
+
+
+{% endmacro %} + +{% block content %} +
+
+
+ +
+

{{ program.program_name }}

+

{{ program.description }}

+

+ + Continue with Course 2 +

+
+ +
+
+

Courses

+

Master ERPNext with our Expert Learning Paths

+ {% for course_item in course_list %} + {{ course_card(course_item) }} + {% endfor %} +
+
+ +{% include "www/lms/templates/includes/highlights.html" %} + + + +{% endblock %} \ No newline at end of file diff --git a/erpnext/www/lms/program.py b/erpnext/www/lms/program.py new file mode 100644 index 0000000000..809e6cdd2d --- /dev/null +++ b/erpnext/www/lms/program.py @@ -0,0 +1,20 @@ +from __future__ import unicode_literals +import frappe + + +# Get the classroom's route parameter from the url +url_param = frappe.form_dict["code"] +# Get classroom from classroom_name +current_program = frappe.get_doc("Program", url_param) + +def get_context(context): + context.program = current_program + context.course_list, context.course_data = get_courses() + +def get_courses(): + course_data = {} + course_names = [program.course_name for program in current_program.courses] + program_courses = [frappe.get_doc('Course', name) for name in course_names] + for course_item in program_courses: + course_data[course_item.name] = [content_item.content for content_item in course_item.course_content if content_item.content_type in ('Video', 'Article')] + return course_names, course_data diff --git a/erpnext/www/lms/templates/includes/footer/footer.html b/erpnext/www/lms/templates/includes/footer/footer.html new file mode 100644 index 0000000000..62aabea234 --- /dev/null +++ b/erpnext/www/lms/templates/includes/footer/footer.html @@ -0,0 +1,60 @@ +
+
+
+
+ +
+
+ © Frappe Technologies Pvt. Ltd. +
+
+
+
+
Social
+ +
+ +
+
Company
+ +
+
+ +
"Be the change, you wish to see in the world ~ M. K. Gandhi" + +
+
+ \ No newline at end of file diff --git a/erpnext/www/lms/templates/includes/highlights.html b/erpnext/www/lms/templates/includes/highlights.html new file mode 100644 index 0000000000..a97d699537 --- /dev/null +++ b/erpnext/www/lms/templates/includes/highlights.html @@ -0,0 +1,41 @@ +
+
+

Highlights

+
+
+
+
Curated Courses
+
Learning paths specifically designed for the your use cases, whether you are a user, developer + or an + implementer
+
+ +
+ +
+
+
Comprehensive Content
+
Content designed to cover all the fundamentals as well as expert tips and techniques to make + the most out of ERPNext.
+
+ +
+ +
+
+
Certification
+
ERPNext is open source and infinitely extensible. Customize it, build upon it, add your own + apps built with + Frappe Framework.
+
+ +
+
+
+
\ No newline at end of file From de36e13db7b2d1bbf0225d03c1d38a14e7d80ccb Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 8 Oct 2018 15:28:52 +0530 Subject: [PATCH 010/314] modified doctypes for lms Co-authored-by: Chinmay Pai --- .../education/doctype/content/content.json | 6 +- .../course_content/course_content.json | 2 +- .../education/doctype/program/program.json | 151 ++++++++- .../student_applicant/student_applicant.json | 37 +- .../doctype/web_academy_applicant/__init__.py | 0 .../test_web_academy_applicant.js | 23 -- .../test_web_academy_applicant.py | 10 - .../web_academy_applicant.js | 8 - .../web_academy_applicant.json | 320 ------------------ .../web_academy_applicant.py | 48 --- 10 files changed, 186 insertions(+), 419 deletions(-) delete mode 100644 erpnext/education/doctype/web_academy_applicant/__init__.py delete mode 100644 erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.js delete mode 100644 erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.py delete mode 100644 erpnext/education/doctype/web_academy_applicant/web_academy_applicant.js delete mode 100644 erpnext/education/doctype/web_academy_applicant/web_academy_applicant.json delete mode 100644 erpnext/education/doctype/web_academy_applicant/web_academy_applicant.py diff --git a/erpnext/education/doctype/content/content.json b/erpnext/education/doctype/content/content.json index c3840a45db..35db445af0 100644 --- a/erpnext/education/doctype/content/content.json +++ b/erpnext/education/doctype/content/content.json @@ -3,7 +3,7 @@ "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, - "autoname": "format:{content_type}-{title}", + "autoname": "field:title", "beta": 0, "creation": "2018-10-01 13:17:45.939706", "custom": 0, @@ -110,7 +110,7 @@ "search_index": 0, "set_only_once": 0, "translatable": 0, - "unique": 0 + "unique": 1 }, { "allow_bulk_edit": 0, @@ -480,7 +480,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-01 16:09:29.505488", + "modified": "2018-10-08 14:15:06.001140", "modified_by": "Administrator", "module": "Education", "name": "Content", diff --git a/erpnext/education/doctype/course_content/course_content.json b/erpnext/education/doctype/course_content/course_content.json index 084078b868..fb3c1de3bd 100644 --- a/erpnext/education/doctype/course_content/course_content.json +++ b/erpnext/education/doctype/course_content/course_content.json @@ -121,7 +121,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-10-01 14:19:58.403724", + "modified": "2018-10-08 14:34:07.400616", "modified_by": "Administrator", "module": "Education", "name": "Course Content", diff --git a/erpnext/education/doctype/program/program.json b/erpnext/education/doctype/program/program.json index 05e35a2a53..0b68e232de 100644 --- a/erpnext/education/doctype/program/program.json +++ b/erpnext/education/doctype/program/program.json @@ -15,6 +15,7 @@ "fields": [ { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -41,10 +42,12 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -72,10 +75,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -101,10 +106,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -131,10 +138,12 @@ "reqd": 1, "search_index": 0, "set_only_once": 0, - "unique": 0 + "translatable": 0, + "unique": 1 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -161,10 +170,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -191,10 +202,12 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, "unique": 0 }, { "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, @@ -222,6 +235,136 @@ "reqd": 0, "search_index": 0, "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "is_featured", + "fieldtype": "Check", + "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, + "label": "Is Featured", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "description", + "fieldtype": "Data", + "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, + "label": "Description", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "intro_video", + "fieldtype": "Data", + "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, + "label": "Intro Video", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "hero_image", + "fieldtype": "Attach Image", + "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, + "label": "Hero Image", + "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 } ], @@ -236,7 +379,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-11-10 18:56:18.413911", + "modified": "2018-10-08 13:04:46.741926", "modified_by": "Administrator", "module": "Education", "name": "Program", @@ -245,7 +388,6 @@ "permissions": [ { "amend": 0, - "apply_user_permissions": 0, "cancel": 0, "create": 1, "delete": 1, @@ -273,5 +415,6 @@ "sort_field": "modified", "sort_order": "DESC", "track_changes": 0, - "track_seen": 0 + "track_seen": 0, + "track_views": 0 } \ No newline at end of file diff --git a/erpnext/education/doctype/student_applicant/student_applicant.json b/erpnext/education/doctype/student_applicant/student_applicant.json index 297821f753..71134e0907 100644 --- a/erpnext/education/doctype/student_applicant/student_applicant.json +++ b/erpnext/education/doctype/student_applicant/student_applicant.json @@ -143,6 +143,39 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "lms_only", + "fieldtype": "Check", + "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, + "label": "LMS Only", + "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 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -627,7 +660,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "translatable": 0, @@ -1160,7 +1193,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-08-21 14:44:30.146264", + "modified": "2018-10-05 13:15:59.283862", "modified_by": "Administrator", "module": "Education", "name": "Student Applicant", diff --git a/erpnext/education/doctype/web_academy_applicant/__init__.py b/erpnext/education/doctype/web_academy_applicant/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.js b/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.js deleted file mode 100644 index 025a5131c1..0000000000 --- a/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.js +++ /dev/null @@ -1,23 +0,0 @@ -/* eslint-disable */ -// rename this file from _test_[name] to test_[name] to activate -// and remove above this line - -QUnit.test("test: Web Academy Applicant", function (assert) { - let done = assert.async(); - - // number of asserts - assert.expect(1); - - frappe.run_serially([ - // insert a new Web Academy Applicant - () => frappe.tests.make('Web Academy Applicant', [ - // values to be set - {key: 'value'} - ]), - () => { - assert.equal(cur_frm.doc.key, 'value'); - }, - () => done() - ]); - -}); diff --git a/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.py b/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.py deleted file mode 100644 index 1d856749e3..0000000000 --- a/erpnext/education/doctype/web_academy_applicant/test_web_academy_applicant.py +++ /dev/null @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors -# See license.txt -from __future__ import unicode_literals - -import frappe -import unittest - -class TestWebAcademyApplicant(unittest.TestCase): - pass diff --git a/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.js b/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.js deleted file mode 100644 index f498509915..0000000000 --- a/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.js +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -// For license information, please see license.txt - -frappe.ui.form.on('Web Academy Applicant', { - refresh: function(frm) { - - } -}); diff --git a/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.json b/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.json deleted file mode 100644 index e8ff98783b..0000000000 --- a/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.json +++ /dev/null @@ -1,320 +0,0 @@ -{ - "allow_copy": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "EDU-LMS-.YYYY.-.#####", - "beta": 0, - "creation": "2018-10-02 13:41:00.788521", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", - "fields": [ - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "first_name", - "fieldtype": "Data", - "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": "First Name", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "middle_name", - "fieldtype": "Data", - "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, - "label": "Middle Name", - "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 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "last_name", - "fieldtype": "Data", - "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, - "label": "Last Name", - "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 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "program", - "fieldtype": "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": "Program", - "length": 0, - "no_copy": 0, - "options": "Program", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "account_details_section", - "fieldtype": "Section 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, - "label": "Account Details", - "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 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_email_address", - "fieldtype": "Data", - "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": "Student Email Address", - "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": 1, - "search_index": 0, - "set_only_once": 1, - "translatable": 0, - "unique": 1 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "password", - "fieldtype": "Password", - "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, - "label": "Password", - "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": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "payment_status", - "fieldtype": "Data", - "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, - "label": "Payment Status", - "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 - } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-10-02 15:01:59.632345", - "modified_by": "Administrator", - "module": "Education", - "name": "Web Academy Applicant", - "name_case": "", - "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], - "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 -} \ No newline at end of file diff --git a/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.py b/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.py deleted file mode 100644 index a6a94c9733..0000000000 --- a/erpnext/education/doctype/web_academy_applicant/web_academy_applicant.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors -# For license information, please see license.txt - -from __future__ import print_function, unicode_literals -import frappe -from frappe import _ -from frappe.model.document import Document -from frappe.utils import getdate -from frappe.utils.password import get_decrypted_password - -class WebAcademyApplicant(Document): - def before_insert(self): - # Before a new document is saved - self.check_if_student_account_already_exists(self.student_email_address) - - def after_insert(self): - # After the application is inserted in the database, create a new student - self.create_new_student() - - def check_if_student_account_already_exists(self, email): - # Check if a student account alread exists, if it does, throw an error - get_accounts = frappe.get_all('Student', filters={'student_email_id': email}) - if len(get_accounts) != 0: - frappe.throw('Student with Email {0} already Exists.'.format(self.student_email_address)) - - def create_new_student(self): - student = frappe.get_doc({ - 'doctype': 'Student', - 'student_email_id': self.student_email_address, - 'first_name': self.first_name, - 'last_name': self.last_name, - 'middle_name': self.middle_name - }) - student_user_account = frappe.get_doc({ - 'doctype': 'User', - 'email': self.student_email_address, - 'first_name': self.first_name, - 'last_name': self.last_name, - 'new_passsword': get_decrypted_password(self.doctype, self.name, 'password') - - }) - student.save() - if(self.lms_user == 1): - student_user_account.add_roles("LMS User") - else: - student_user_account.add_roles("Student", "LMS User") - student_user_account.save() \ No newline at end of file From 6660a675f16887491645b29a8804e1606f99e4f0 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 8 Oct 2018 17:18:11 +0530 Subject: [PATCH 011/314] templates: add templates for LMS content Co-authored-by: Chinmay Pai --- erpnext/www/lms/course.html | 65 ++++++------------- erpnext/www/lms/course.py | 10 ++- erpnext/www/lms/program.html | 2 +- erpnext/www/lms/program.py | 13 ++-- .../www/lms/templates/includes/article.html | 33 ++++++++++ erpnext/www/lms/templates/includes/quiz.html | 56 ++++++++++++++++ erpnext/www/lms/templates/includes/video.html | 36 ++++++++++ 7 files changed, 159 insertions(+), 56 deletions(-) create mode 100644 erpnext/www/lms/templates/includes/article.html create mode 100644 erpnext/www/lms/templates/includes/quiz.html create mode 100644 erpnext/www/lms/templates/includes/video.html diff --git a/erpnext/www/lms/course.html b/erpnext/www/lms/course.html index 4538b9f573..3acc76e5d0 100644 --- a/erpnext/www/lms/course.html +++ b/erpnext/www/lms/course.html @@ -8,56 +8,33 @@ {% endblock %} -{% macro video(id) %} -
- -
-{% endmacro %} {% block content %} -
-
- {% if lesson.video_url is defined %} - {{ video("lesson,video") }} - {% endif %} -
-
-

{{ lesson.name }}

- - 49 Mins - — Published on 28th October 2018. - -
-
- Previous - Next -
-
-
-
-
-{% for lesson in lesson_list %} - {{ lesson }} -{% endfor %} -
-
-
- {{ lesson.content }} -
- - -
- -
+{% with current_content = current_content %} +{% include "www/lms/templates/includes/" + current_content.content_type.lower() + ".html" %} +{% endwith %} {% endblock %} \ No newline at end of file diff --git a/erpnext/www/lms/course.py b/erpnext/www/lms/course.py index 453c9c7905..ff7073dc9c 100644 --- a/erpnext/www/lms/course.py +++ b/erpnext/www/lms/course.py @@ -1,2 +1,8 @@ -# current_module = frappe.get_doc("Course", frappe.form_dict["lesson"]) -# current_lesson = frappe.get_doc("Lesson", frappe.form_dict["lesson"]) \ No newline at end of file +from __future__ import unicode_literals +import frappe + + +def get_context(context): + context.current_course = frappe.get_doc("Course", frappe.form_dict["course"]) + context.current_content = frappe.get_doc("Content", frappe.form_dict["content"]) + next_content = get_next_content() \ No newline at end of file diff --git a/erpnext/www/lms/program.html b/erpnext/www/lms/program.html index e079b4155a..449c040c42 100644 --- a/erpnext/www/lms/program.html +++ b/erpnext/www/lms/program.html @@ -22,7 +22,7 @@ diff --git a/erpnext/www/lms/program.py b/erpnext/www/lms/program.py index 809e6cdd2d..b6ebcf44d2 100644 --- a/erpnext/www/lms/program.py +++ b/erpnext/www/lms/program.py @@ -2,18 +2,13 @@ from __future__ import unicode_literals import frappe -# Get the classroom's route parameter from the url -url_param = frappe.form_dict["code"] -# Get classroom from classroom_name -current_program = frappe.get_doc("Program", url_param) - def get_context(context): - context.program = current_program - context.course_list, context.course_data = get_courses() + context.program = frappe.get_doc("Program", frappe.form_dict["code"]) + context.course_list, context.course_data = get_courses(context) -def get_courses(): +def get_courses(context): course_data = {} - course_names = [program.course_name for program in current_program.courses] + course_names = [program.course_name for program in context.program.courses] program_courses = [frappe.get_doc('Course', name) for name in course_names] for course_item in program_courses: course_data[course_item.name] = [content_item.content for content_item in course_item.course_content if content_item.content_type in ('Video', 'Article')] diff --git a/erpnext/www/lms/templates/includes/article.html b/erpnext/www/lms/templates/includes/article.html new file mode 100644 index 0000000000..f9fd6e0036 --- /dev/null +++ b/erpnext/www/lms/templates/includes/article.html @@ -0,0 +1,33 @@ +
+
+
+
+

{{ current_content.name }}

+ + 49 Mins + — Published on 28th October 2018. + +
+
+ Previous + Next +
+
+
+
+
+
+
+
+ {{ current_content.article_content }} +
+ + +
+
\ No newline at end of file diff --git a/erpnext/www/lms/templates/includes/quiz.html b/erpnext/www/lms/templates/includes/quiz.html new file mode 100644 index 0000000000..97a2e6828c --- /dev/null +++ b/erpnext/www/lms/templates/includes/quiz.html @@ -0,0 +1,56 @@ +{% macro quiz(question, opt1, opt2, opt3, opt4) %} +
+
{{ question }}
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+{% endmacro %} + +
+
+
+
+

Quiz — Accounting with ERPNext

+
+
+
+
+
+ {{ quiz('1. What is a Sales Invoice?','The bills that you raise to your Customers for the products or services you provide.','Bills that your Suppliers give you for their products or services.','The bills for accounting entries, like payments, credit and other types.','The bills that were recovered from an oblivion of files and folders stacked in a old and rusty closet.') }} + {{ quiz('2. How to create a Sales Invoice?','Accounts > Billing > Sales Invoice > New Sales Invoice','Accounts > Buying > New Sales Invoice','Accounts > CRM > New Sales Invoice','Accounts > Purchases > New Sales Invoice') }} + {{ quiz('3. The long term assets that have no physical existence but are rights that have value is known as','Current Assets','Fixed Assets','Intangible Assets','Investments') }} +
+ + +
+
+
+ +
+
\ No newline at end of file diff --git a/erpnext/www/lms/templates/includes/video.html b/erpnext/www/lms/templates/includes/video.html new file mode 100644 index 0000000000..77a4e6cc97 --- /dev/null +++ b/erpnext/www/lms/templates/includes/video.html @@ -0,0 +1,36 @@ +
+
+
+ +
+
+
+

{{ current_content.name }}

+ + 49 Mins + — Published on 28th October 2018. + +
+
+ Previous + Next +
+
+
+
+
+
+
+
+ {{ current_content.video_description }} +
+ + +
+
\ No newline at end of file From eab0b833a1b29155849361b28c23139dfdbb9423 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 12 Oct 2018 15:12:04 +0530 Subject: [PATCH 012/314] Modified Student Course Activity Doctype Co-authored-by: Chinmay Pai --- .../doctype/lms_activity/lms_activity.json | 128 ++++++++++++++++-- .../student_course_activity.json | 33 ++++- .../student_course_activity.py | 9 +- 3 files changed, 144 insertions(+), 26 deletions(-) diff --git a/erpnext/education/doctype/lms_activity/lms_activity.json b/erpnext/education/doctype/lms_activity/lms_activity.json index f7bc30b10a..494b0ac17f 100644 --- a/erpnext/education/doctype/lms_activity/lms_activity.json +++ b/erpnext/education/doctype/lms_activity/lms_activity.json @@ -36,7 +36,41 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "content_name.content_type", + "fieldname": "content_type", + "fieldtype": "Data", + "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": "", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -53,7 +87,7 @@ "collapsible": 0, "columns": 0, "fetch_from": "", - "fieldname": "lesson_name", + "fieldname": "content_name", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -62,7 +96,7 @@ "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, - "label": "Lesson Name", + "label": "Content Name", "length": 0, "no_copy": 0, "options": "Content", @@ -70,6 +104,73 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "status", + "fieldtype": "Select", + "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, + "label": "Status", + "length": 0, + "no_copy": 0, + "options": "\nCompleted\nPassed\nFailed", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "collapsible_depends_on": "", + "columns": 0, + "depends_on": "eval:doc.content_type == \"Quiz\"", + "fieldname": "quiz_section_section", + "fieldtype": "Section 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, + "label": "Quiz Section", + "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, @@ -102,12 +203,12 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, - "set_only_once": 0, + "set_only_once": 1, "translatable": 0, "unique": 0 }, @@ -118,9 +219,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "default": "Unattempted", - "fieldname": "quiz_status", - "fieldtype": "Select", + "fieldname": "selected_options", + "fieldtype": "Data", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -128,10 +228,9 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Quiz Status", + "label": "Selected Options", "length": 0, "no_copy": 0, - "options": "\nUnattempted\nPassed\nFailed", "permlevel": 0, "precision": "", "print_hide": 0, @@ -152,8 +251,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "lesson_status", - "fieldtype": "Select", + "fieldname": "result", + "fieldtype": "Data", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -161,10 +260,9 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Lesson Status", + "label": "Result", "length": 0, "no_copy": 0, - "options": "\nOngoing\nCompleted", "permlevel": 0, "precision": "", "print_hide": 0, @@ -189,7 +287,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-10-08 12:48:34.394511", + "modified": "2018-10-12 13:06:17.568571", "modified_by": "Administrator", "module": "Education", "name": "LMS Activity", diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.json b/erpnext/education/doctype/student_course_activity/student_course_activity.json index 1d8f98d0b1..c957be7a01 100644 --- a/erpnext/education/doctype/student_course_activity/student_course_activity.json +++ b/erpnext/education/doctype/student_course_activity/student_course_activity.json @@ -3,7 +3,7 @@ "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, - "autoname": "format:{student_name}-{program_name}", + "autoname": "format:{student_id}-{program_name}", "beta": 0, "creation": "2018-10-01 17:35:54.391413", "custom": 0, @@ -20,8 +20,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "student_name", - "fieldtype": "Link", + "fieldname": "student_id", + "fieldtype": "Data", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -29,7 +29,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Student Name", + "label": "Student ID", "length": 0, "no_copy": 0, "options": "Student", @@ -42,7 +42,7 @@ "report_hide": 0, "reqd": 0, "search_index": 0, - "set_only_once": 0, + "set_only_once": 1, "translatable": 0, "unique": 0 }, @@ -75,7 +75,7 @@ "report_hide": 0, "reqd": 0, "search_index": 0, - "set_only_once": 0, + "set_only_once": 1, "translatable": 0, "unique": 0 }, @@ -123,7 +123,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-08 12:10:28.602848", + "modified": "2018-10-12 13:51:08.729074", "modified_by": "Administrator", "module": "Education", "name": "Student Course Activity", @@ -148,6 +148,25 @@ "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 } ], "quick_entry": 1, diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.py b/erpnext/education/doctype/student_course_activity/student_course_activity.py index bf5778fc36..478e309122 100644 --- a/erpnext/education/doctype/student_course_activity/student_course_activity.py +++ b/erpnext/education/doctype/student_course_activity/student_course_activity.py @@ -12,10 +12,11 @@ class StudentCourseActivity(Document): # self.check_if_course_present() def check_if_enrolled(self): - programs_list = frappe.get_list("Program Enrollment", filters={'student': self.student_name}, fields=['program']) - programs_enrolled_by_student = [item.program for item in programs_list] - if self.program_name not in programs_enrolled_by_student: - frappe.throw("Student {0} is not enrolled in program {1} ".format(self.student_name, self.program_name)) + pass + # programs_list = frappe.get_list("Program Enrollment", filters={'student': self.student_id}, fields=['program']) + # programs_enrolled_by_student = [item.program for item in programs_list] + # if self.program_name not in programs_enrolled_by_student: + # frappe.throw("Student {0} is not enrolled in program {1} ".format(self.student_id, self.program_name)) # def check_if_course_present(self): # """ Get set of unique courses from lms_activity child table and make a list of it as assign it to course_list""" From 4ae11f4d74aad17c56097e22c4b66b64823d8af1 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 12 Oct 2018 15:18:26 +0530 Subject: [PATCH 013/314] LMS: added python functions to evaulate quiz and save student activity Co-authored-by: Chinmay Pai --- erpnext/education/utils.py | 87 +++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index 1b93c9d71e..e0c96d7b7f 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -2,7 +2,7 @@ # Copyright (c) 2015, Frappe Technologies and contributors # For lice -from __future__ import unicode_literals +from __future__ import unicode_literals, division import frappe from frappe import _ @@ -51,3 +51,88 @@ def validate_duplicate_student(students): .format(stud.student, stud.student_name, unique_students.index(stud.student)+1, stud.idx)) else: unique_students.append(stud.student) + +def get_student_name(email=None): + """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series). + + :param user: a user email address + """ + try: + return frappe.get_all('Student', filters={'student_email_id': email}, fields=['name'])[0].name + except IndexError: + return None + +@frappe.whitelist() +def evaluate_quiz(quiz_response, **kwargs): + """LMS Function: Evaluates a simple multiple choice quiz. It recieves arguments from `www/lms/course.js` as dictionary using FormData[1]. + + + :param quiz_response: contains user selected choices for a quiz in the form of a string formatted as a dictionary. The function uses `json.loads()` to convert it to a python dictionary. + [1]: https://developer.mozilla.org/en-US/docs/Web/API/FormData + """ + import json + quiz_response = json.loads(quiz_response) + correct_answers = [frappe.get_value('Question', name, 'correct_options') for name in quiz_response.keys()] + selected_options = quiz_response.values() + result = [selected == correct for selected, correct in zip(selected_options, correct_answers)] + try: + score = int((result.count(True)/len(selected_options))*100) + except ZeroDivisionError: + score = 0 + + kwargs['selected_options'] = selected_options + kwargs['result'] = result + kwargs['score'] = score + add_activity('Quiz', **kwargs) + return score + +@frappe.whitelist() +def add_activity(content_type, **kwargs): + activity_does_not_exists, activity = check_entry_exists(kwargs.get('program')) + if activity_does_not_exists: + current_activity = frappe.get_doc({ + "doctype": "Student Course Activity", + "student_id": frappe.session.user, + "program_name": kwargs.get('program'), + "lms_activity": [{ + "course_name": kwargs.get('course'), + "content_name": kwargs.get('content'), + "status": "Completed" + }] + }) + if content_type == "Quiz": + activity = current_activity.lms_activity[-1] + activity.quiz_score = kwargs.get('score') + activity.selected_options = ", ".join(kwargs.get('selected_options')) + activity.result = ", ".join([str(item) for item in kwargs.get('result')]), + activity.status = "Passed" + current_activity.save() + frappe.db.commit() + else: + if content_type in ("Article", "Video"): + lms_activity_list = [[data.course_name, data.content_name] for data in activity.lms_activity] + if not [kwargs.get('course'), kwargs.get('content')] in lms_activity_list: + activity.append("lms_activity", { + "course_name": kwargs.get('course'), + "content_name": kwargs.get('content'), + "status": "Completed" + }) + else: + activity.append("lms_activity", { + "course_name": kwargs.get('course'), + "content_name": kwargs.get('content'), + "status": "Passed", + "quiz_score": kwargs.get('score'), + "selected_options": ", ".join(kwargs.get('selected_options')), + "result": ", ".join([str(item) for item in kwargs.get('result')]) + }) + activity.save() + frappe.db.commit() + +def check_entry_exists(program): + try: + activity_name = frappe.get_all("Student Course Activity", filters={"student_id": frappe.session.user, "program_name": program})[0] + except IndexError: + return True, None + else: + return None, frappe.get_doc("Student Course Activity", activity_name) \ No newline at end of file From 9335593b5634fd09d0d11e1e9a0877e2ada8cbb7 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 12 Oct 2018 15:22:03 +0530 Subject: [PATCH 014/314] LMS: JS Script to send quiz and activity data --- erpnext/www/lms/course.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 erpnext/www/lms/course.js diff --git a/erpnext/www/lms/course.js b/erpnext/www/lms/course.js new file mode 100644 index 0000000000..e8f1dd5d0f --- /dev/null +++ b/erpnext/www/lms/course.js @@ -0,0 +1,37 @@ +function submitQuiz() { + formData = new FormData(quiz); + var form_object = {}; + formData.forEach(function (value, key) { + form_object[key] = value; + }); + frappe.call({ + method: "erpnext.education.utils.evaluate_quiz", + args: { + "quiz_response": form_object, + "content": $('#content-holder').data('content'), + "course": $('#content-holder').data('course'), + "program": $('#content-holder').data('program') + }, + async: false, + callback: function (r) { + if (r) { + $("input[type=radio]").attr('disabled', true); + $("#quiz-actions").attr('hidden', true); + $("#post-quiz-actions").attr('hidden', false); + $("#result").html(r.message); + } + } + }); +} + +function addActivity() { + frappe.call({ + method: "erpnext.education.utils.add_activity", + args: { + "content_type": $('#content-holder').data('type'), + "content": $('#content-holder').data('content'), + "course": $('#content-holder').data('course'), + "program": $('#content-holder').data('program'), + } + }) +} \ No newline at end of file From 38c1baf7195f0e62bd0293fc42f8b6966da23d3f Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 12 Oct 2018 15:22:16 +0530 Subject: [PATCH 015/314] Templates: modified routing logic, added data attributes in template Co-authored-by: Chinmay Pai --- erpnext/www/lms/course.html | 9 +- erpnext/www/lms/course.py | 17 ++- erpnext/www/lms/index.html | 2 +- erpnext/www/lms/program.html | 2 +- erpnext/www/lms/program.py | 4 +- .../www/lms/templates/includes/article.html | 8 +- erpnext/www/lms/templates/includes/quiz.html | 106 +++++++++--------- erpnext/www/lms/templates/includes/video.html | 6 +- 8 files changed, 93 insertions(+), 61 deletions(-) diff --git a/erpnext/www/lms/course.html b/erpnext/www/lms/course.html index 3acc76e5d0..182efab7d6 100644 --- a/erpnext/www/lms/course.html +++ b/erpnext/www/lms/course.html @@ -8,11 +8,12 @@ {% endblock %} - {% block content %} -{% with current_content = current_content %} +
+{% with current_content = current_content, next_content = next_content, course_name = current_course.name, program=current_program%} {% include "www/lms/templates/includes/" + current_content.content_type.lower() + ".html" %} {% endwith %} +
{% endblock %} \ No newline at end of file diff --git a/erpnext/www/lms/course.py b/erpnext/www/lms/course.py index ff7073dc9c..0276102462 100644 --- a/erpnext/www/lms/course.py +++ b/erpnext/www/lms/course.py @@ -3,6 +3,17 @@ import frappe def get_context(context): - context.current_course = frappe.get_doc("Course", frappe.form_dict["course"]) - context.current_content = frappe.get_doc("Content", frappe.form_dict["content"]) - next_content = get_next_content() \ No newline at end of file + if frappe.form_dict['course']: + context.current_course = frappe.get_doc("Course", frappe.form_dict["course"]) + context.current_content = frappe.get_doc("Content", frappe.form_dict["content"]) + context.current_program = frappe.form_dict["program"] + context.next_content = get_next_content(context) + + +def get_next_content(context): + if context.current_course: + course_data = [content_item.content for content_item in context.current_course.course_content] + try: + return course_data[course_data.index(context.current_content.name) + 1] + except IndexError: + return None \ No newline at end of file diff --git a/erpnext/www/lms/index.html b/erpnext/www/lms/index.html index 1974d4f569..444bbde093 100644 --- a/erpnext/www/lms/index.html +++ b/erpnext/www/lms/index.html @@ -13,7 +13,7 @@
- +
{{ program_name }}
{{ description }}
diff --git a/erpnext/www/lms/program.html b/erpnext/www/lms/program.html index 449c040c42..23f2e5c528 100644 --- a/erpnext/www/lms/program.html +++ b/erpnext/www/lms/program.html @@ -22,7 +22,7 @@
diff --git a/erpnext/www/lms/program.py b/erpnext/www/lms/program.py index b6ebcf44d2..c61aee53f6 100644 --- a/erpnext/www/lms/program.py +++ b/erpnext/www/lms/program.py @@ -1,9 +1,11 @@ from __future__ import unicode_literals +from erpnext.education.utils import get_student_name import frappe def get_context(context): - context.program = frappe.get_doc("Program", frappe.form_dict["code"]) + print(get_student_name(frappe.session.user)) + context.program = frappe.get_doc("Program", frappe.form_dict["program"]) context.course_list, context.course_data = get_courses(context) def get_courses(context): diff --git a/erpnext/www/lms/templates/includes/article.html b/erpnext/www/lms/templates/includes/article.html index f9fd6e0036..2ca93fa43b 100644 --- a/erpnext/www/lms/templates/includes/article.html +++ b/erpnext/www/lms/templates/includes/article.html @@ -10,7 +10,11 @@
Previous - Next + {% if next_content != None %} + Next + {% else %} + Finish Course + {% endif %}

@@ -23,7 +27,7 @@
Report a diff --git a/erpnext/www/lms/templates/includes/quiz.html b/erpnext/www/lms/templates/includes/quiz.html index 97a2e6828c..280a17baae 100644 --- a/erpnext/www/lms/templates/includes/quiz.html +++ b/erpnext/www/lms/templates/includes/quiz.html @@ -1,56 +1,62 @@ -{% macro quiz(question, opt1, opt2, opt3, opt4) %} -
-
{{ question }}
-
-
- - -
-
- - -
-
- - -
-
- - -
+{% macro quiz(loop_index, question_id, question, options) %} +
+
{{ loop_index }}{{ question }}
+
+ + {% for option in options %} +
+ + +
+ {% endfor %}
+
{% endmacro %} -
-
\ No newline at end of file diff --git a/erpnext/www/lms/templates/includes/video.html b/erpnext/www/lms/templates/includes/video.html index 77a4e6cc97..6727321dec 100644 --- a/erpnext/www/lms/templates/includes/video.html +++ b/erpnext/www/lms/templates/includes/video.html @@ -13,7 +13,11 @@
Previous - Next + {% if next_content != None %} + Next + {% else %} + Finish Course + {% endif %}

From 17294e703eb7512e3ec0728d58460e84071388dc Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 15 Oct 2018 11:45:17 +0530 Subject: [PATCH 016/314] Course Activity linked to Student ID --- .../doctype/lms_activity/lms_activity.json | 9 ++++---- .../education/doctype/student/student.json | 22 ++++++++++++++++++- erpnext/education/utils.py | 18 ++++++++++++--- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/erpnext/education/doctype/lms_activity/lms_activity.json b/erpnext/education/doctype/lms_activity/lms_activity.json index 494b0ac17f..f120ad6b64 100644 --- a/erpnext/education/doctype/lms_activity/lms_activity.json +++ b/erpnext/education/doctype/lms_activity/lms_activity.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, @@ -235,12 +236,12 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, "search_index": 0, - "set_only_once": 0, + "set_only_once": 1, "translatable": 0, "unique": 0 }, @@ -267,7 +268,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 0, @@ -287,7 +288,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-10-12 13:06:17.568571", + "modified": "2018-10-12 16:14:21.510581", "modified_by": "Administrator", "module": "Education", "name": "LMS Activity", diff --git a/erpnext/education/doctype/student/student.json b/erpnext/education/doctype/student/student.json index af6c8b16bc..cdb66b033f 100644 --- a/erpnext/education/doctype/student/student.json +++ b/erpnext/education/doctype/student/student.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, @@ -1187,7 +1188,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-08-21 14:44:35.278833", + "modified": "2018-10-12 16:46:31.504987", "modified_by": "Administrator", "module": "Education", "name": "Student", @@ -1231,6 +1232,25 @@ "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Student", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 0, diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index e0c96d7b7f..d55bd1d316 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -92,7 +92,7 @@ def add_activity(content_type, **kwargs): if activity_does_not_exists: current_activity = frappe.get_doc({ "doctype": "Student Course Activity", - "student_id": frappe.session.user, + "student_id": get_student_id(frappe.session.user), "program_name": kwargs.get('program'), "lms_activity": [{ "course_name": kwargs.get('course'), @@ -131,8 +131,20 @@ def add_activity(content_type, **kwargs): def check_entry_exists(program): try: - activity_name = frappe.get_all("Student Course Activity", filters={"student_id": frappe.session.user, "program_name": program})[0] + activity_name = frappe.get_all("Student Course Activity", filters={"student_id": get_student_id(frappe.session.user), "program_name": program})[0] except IndexError: + print("------ Got No Doc ------") return True, None else: - return None, frappe.get_doc("Student Course Activity", activity_name) \ No newline at end of file + print("------ Got A Doc ------") + return None, frappe.get_doc("Student Course Activity", activity_name) + +def get_student_id(email): + """Returns Student ID, example EDU-STU-2018-00001 from email address + + :params email: email address of the student""" + try: + student = frappe.get_list('Student', filters={'student_email_id': email})[0].name + return student + except IndexError: + frappe.throw("Student Account with email:{0} does not exist".format(email)) \ No newline at end of file From e7308125b42cf29ffca814e0a9d0a42f87092304 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 15 Oct 2018 16:00:04 +0530 Subject: [PATCH 017/314] Replaced Student Course Activity with Course Activity --- .../__init__.py | 0 .../course_activity.js} | 2 +- .../course_activity.json} | 86 +++++++++---------- .../course_activity.py} | 2 +- .../test_course_activity.js} | 6 +- .../test_course_activity.py} | 2 +- 6 files changed, 49 insertions(+), 49 deletions(-) rename erpnext/education/doctype/{student_course_activity => course_activity}/__init__.py (100%) rename erpnext/education/doctype/{student_course_activity/student_course_activity.js => course_activity/course_activity.js} (76%) rename erpnext/education/doctype/{student_course_activity/student_course_activity.json => course_activity/course_activity.json} (87%) rename erpnext/education/doctype/{student_course_activity/student_course_activity.py => course_activity/course_activity.py} (96%) rename erpnext/education/doctype/{student_course_activity/test_student_course_activity.js => course_activity/test_course_activity.js} (67%) rename erpnext/education/doctype/{student_course_activity/test_student_course_activity.py => course_activity/test_course_activity.py} (78%) diff --git a/erpnext/education/doctype/student_course_activity/__init__.py b/erpnext/education/doctype/course_activity/__init__.py similarity index 100% rename from erpnext/education/doctype/student_course_activity/__init__.py rename to erpnext/education/doctype/course_activity/__init__.py diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.js b/erpnext/education/doctype/course_activity/course_activity.js similarity index 76% rename from erpnext/education/doctype/student_course_activity/student_course_activity.js rename to erpnext/education/doctype/course_activity/course_activity.js index 101abeff2d..5115fc415e 100644 --- a/erpnext/education/doctype/student_course_activity/student_course_activity.js +++ b/erpnext/education/doctype/course_activity/course_activity.js @@ -1,7 +1,7 @@ // Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors // For license information, please see license.txt -frappe.ui.form.on('Student Course Activity', { +frappe.ui.form.on('Course Activity', { refresh: function(frm) { } diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.json b/erpnext/education/doctype/course_activity/course_activity.json similarity index 87% rename from erpnext/education/doctype/student_course_activity/student_course_activity.json rename to erpnext/education/doctype/course_activity/course_activity.json index c957be7a01..0f7fcb7c31 100644 --- a/erpnext/education/doctype/student_course_activity/student_course_activity.json +++ b/erpnext/education/doctype/course_activity/course_activity.json @@ -1,9 +1,10 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, - "autoname": "format:{student_id}-{program_name}", + "autoname": "field:enrollment", "beta": 0, "creation": "2018-10-01 17:35:54.391413", "custom": 0, @@ -20,40 +21,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "student_id", - "fieldtype": "Data", - "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, - "label": "Student ID", - "length": 0, - "no_copy": 0, - "options": "Student", - "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": 1, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "program_name", + "fieldname": "enrollment", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -62,10 +30,43 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Program Name", + "label": "Enrollment", "length": 0, "no_copy": 0, - "options": "Program", + "options": "Course Enrollment", + "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": 1, + "translatable": 0, + "unique": 1 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "content", + "fieldtype": "Link", + "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, + "label": "Content", + "length": 0, + "no_copy": 0, + "options": "Content", "permlevel": 0, "precision": "", "print_hide": 0, @@ -86,8 +87,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "lms_activity", - "fieldtype": "Table", + "fieldname": "activity_date", + "fieldtype": "Datetime", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -95,10 +96,9 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "LMS Activity", + "label": "Activity Date", "length": 0, "no_copy": 0, - "options": "LMS Activity", "permlevel": 0, "precision": "", "print_hide": 0, @@ -123,10 +123,10 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-12 13:51:08.729074", + "modified": "2018-10-15 15:47:11.824446", "modified_by": "Administrator", "module": "Education", - "name": "Student Course Activity", + "name": "Course Activity", "name_case": "", "owner": "Administrator", "permissions": [ diff --git a/erpnext/education/doctype/student_course_activity/student_course_activity.py b/erpnext/education/doctype/course_activity/course_activity.py similarity index 96% rename from erpnext/education/doctype/student_course_activity/student_course_activity.py rename to erpnext/education/doctype/course_activity/course_activity.py index 478e309122..c890fade3e 100644 --- a/erpnext/education/doctype/student_course_activity/student_course_activity.py +++ b/erpnext/education/doctype/course_activity/course_activity.py @@ -6,7 +6,7 @@ from __future__ import unicode_literals import frappe from frappe.model.document import Document -class StudentCourseActivity(Document): +class CourseActivity(Document): def validate(self): self.check_if_enrolled() # self.check_if_course_present() diff --git a/erpnext/education/doctype/student_course_activity/test_student_course_activity.js b/erpnext/education/doctype/course_activity/test_course_activity.js similarity index 67% rename from erpnext/education/doctype/student_course_activity/test_student_course_activity.js rename to erpnext/education/doctype/course_activity/test_course_activity.js index df6ce3745e..c89c89e5d3 100644 --- a/erpnext/education/doctype/student_course_activity/test_student_course_activity.js +++ b/erpnext/education/doctype/course_activity/test_course_activity.js @@ -2,15 +2,15 @@ // rename this file from _test_[name] to test_[name] to activate // and remove above this line -QUnit.test("test: Student Course Activity", function (assert) { +QUnit.test("test: Course Activity", function (assert) { let done = assert.async(); // number of asserts assert.expect(1); frappe.run_serially([ - // insert a new Student Course Activity - () => frappe.tests.make('Student Course Activity', [ + // insert a new Course Activity + () => frappe.tests.make('Course Activity', [ // values to be set {key: 'value'} ]), diff --git a/erpnext/education/doctype/student_course_activity/test_student_course_activity.py b/erpnext/education/doctype/course_activity/test_course_activity.py similarity index 78% rename from erpnext/education/doctype/student_course_activity/test_student_course_activity.py rename to erpnext/education/doctype/course_activity/test_course_activity.py index 9045a9ce9b..f014b16441 100644 --- a/erpnext/education/doctype/student_course_activity/test_student_course_activity.py +++ b/erpnext/education/doctype/course_activity/test_course_activity.py @@ -6,5 +6,5 @@ from __future__ import unicode_literals import frappe import unittest -class TestStudentCourseActivity(unittest.TestCase): +class TestCourseActivity(unittest.TestCase): pass From 06d175a2bda24075e31b21d0bf0f5cc09faae2fd Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 15 Oct 2018 16:01:11 +0530 Subject: [PATCH 018/314] Added Quiz Activity doctype --- .../doctype/quiz_activity/__init__.py | 0 .../doctype/quiz_activity/quiz_activity.js | 8 + .../doctype/quiz_activity/quiz_activity.json | 194 ++++++++++++++++++ .../doctype/quiz_activity/quiz_activity.py | 10 + .../quiz_activity/test_quiz_activity.js | 23 +++ .../quiz_activity/test_quiz_activity.py | 10 + .../education/doctype/quiz_result/__init__.py | 0 .../doctype/quiz_result/quiz_result.js | 8 + .../doctype/quiz_result/quiz_result.json | 161 +++++++++++++++ .../doctype/quiz_result/quiz_result.py | 10 + .../doctype/quiz_result/test_quiz_result.js | 23 +++ .../doctype/quiz_result/test_quiz_result.py | 10 + 12 files changed, 457 insertions(+) create mode 100644 erpnext/education/doctype/quiz_activity/__init__.py create mode 100644 erpnext/education/doctype/quiz_activity/quiz_activity.js create mode 100644 erpnext/education/doctype/quiz_activity/quiz_activity.json create mode 100644 erpnext/education/doctype/quiz_activity/quiz_activity.py create mode 100644 erpnext/education/doctype/quiz_activity/test_quiz_activity.js create mode 100644 erpnext/education/doctype/quiz_activity/test_quiz_activity.py create mode 100644 erpnext/education/doctype/quiz_result/__init__.py create mode 100644 erpnext/education/doctype/quiz_result/quiz_result.js create mode 100644 erpnext/education/doctype/quiz_result/quiz_result.json create mode 100644 erpnext/education/doctype/quiz_result/quiz_result.py create mode 100644 erpnext/education/doctype/quiz_result/test_quiz_result.js create mode 100644 erpnext/education/doctype/quiz_result/test_quiz_result.py diff --git a/erpnext/education/doctype/quiz_activity/__init__.py b/erpnext/education/doctype/quiz_activity/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.js b/erpnext/education/doctype/quiz_activity/quiz_activity.js new file mode 100644 index 0000000000..f6ba12ca4d --- /dev/null +++ b/erpnext/education/doctype/quiz_activity/quiz_activity.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Quiz Activity', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.json b/erpnext/education/doctype/quiz_activity/quiz_activity.json new file mode 100644 index 0000000000..32f35abd7d --- /dev/null +++ b/erpnext/education/doctype/quiz_activity/quiz_activity.json @@ -0,0 +1,194 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-15 15:48:40.482821", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "enrollment", + "fieldtype": "Link", + "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, + "label": "Enrollment", + "length": 0, + "no_copy": 0, + "options": "Course Enrollment", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "quiz", + "fieldtype": "Link", + "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, + "label": "Quiz", + "length": 0, + "no_copy": 0, + "options": "Content", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "result", + "fieldtype": "Table", + "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, + "label": "Result", + "length": 0, + "no_copy": 0, + "options": "Quiz Result", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "date", + "fieldtype": "Data", + "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, + "label": "Date", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-10-15 15:52:45.980055", + "modified_by": "Administrator", + "module": "Education", + "name": "Student Quiz Activity", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.py b/erpnext/education/doctype/quiz_activity/quiz_activity.py new file mode 100644 index 0000000000..24c7175397 --- /dev/null +++ b/erpnext/education/doctype/quiz_activity/quiz_activity.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class QuizActivity(Document): + pass diff --git a/erpnext/education/doctype/quiz_activity/test_quiz_activity.js b/erpnext/education/doctype/quiz_activity/test_quiz_activity.js new file mode 100644 index 0000000000..94b5ab796a --- /dev/null +++ b/erpnext/education/doctype/quiz_activity/test_quiz_activity.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Quiz Activity", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Quiz Activity + () => frappe.tests.make('Quiz Activity', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/quiz_activity/test_quiz_activity.py b/erpnext/education/doctype/quiz_activity/test_quiz_activity.py new file mode 100644 index 0000000000..fb0425d809 --- /dev/null +++ b/erpnext/education/doctype/quiz_activity/test_quiz_activity.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestQuizActivity(unittest.TestCase): + pass diff --git a/erpnext/education/doctype/quiz_result/__init__.py b/erpnext/education/doctype/quiz_result/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/quiz_result/quiz_result.js b/erpnext/education/doctype/quiz_result/quiz_result.js new file mode 100644 index 0000000000..a018749e69 --- /dev/null +++ b/erpnext/education/doctype/quiz_result/quiz_result.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Quiz Result', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/quiz_result/quiz_result.json b/erpnext/education/doctype/quiz_result/quiz_result.json new file mode 100644 index 0000000000..3e965d447e --- /dev/null +++ b/erpnext/education/doctype/quiz_result/quiz_result.json @@ -0,0 +1,161 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-15 15:52:25.766374", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "question", + "fieldtype": "Link", + "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, + "label": "Question", + "length": 0, + "no_copy": 0, + "options": "Question", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "selected_option", + "fieldtype": "Data", + "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, + "label": "Selected Option", + "length": 0, + "no_copy": 0, + "options": "", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "correct_option", + "fieldtype": "Data", + "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, + "label": "Correct Option", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-10-15 15:52:25.766374", + "modified_by": "Administrator", + "module": "Education", + "name": "Quiz Result", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/quiz_result/quiz_result.py b/erpnext/education/doctype/quiz_result/quiz_result.py new file mode 100644 index 0000000000..4a6323c775 --- /dev/null +++ b/erpnext/education/doctype/quiz_result/quiz_result.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class quiz_result(Document): + pass diff --git a/erpnext/education/doctype/quiz_result/test_quiz_result.js b/erpnext/education/doctype/quiz_result/test_quiz_result.js new file mode 100644 index 0000000000..43f53a1dc7 --- /dev/null +++ b/erpnext/education/doctype/quiz_result/test_quiz_result.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Quiz Result", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Quiz Result + () => frappe.tests.make('Quiz Result', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/quiz_result/test_quiz_result.py b/erpnext/education/doctype/quiz_result/test_quiz_result.py new file mode 100644 index 0000000000..86ee52d87d --- /dev/null +++ b/erpnext/education/doctype/quiz_result/test_quiz_result.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestQuizResult(unittest.TestCase): + pass From 1fc45c547be6cf821efb5dddafbb36dcd85ee4ae Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 15 Oct 2018 16:01:48 +0530 Subject: [PATCH 019/314] Added Course Enrollment doctype --- .../doctype/course_enrollment/__init__.py | 0 .../course_enrollment/course_enrollment.js | 8 + .../course_enrollment/course_enrollment.json | 195 ++++++++++++++++++ .../course_enrollment/course_enrollment.py | 10 + .../test_course_enrollment.js | 23 +++ .../test_course_enrollment.py | 10 + 6 files changed, 246 insertions(+) create mode 100644 erpnext/education/doctype/course_enrollment/__init__.py create mode 100644 erpnext/education/doctype/course_enrollment/course_enrollment.js create mode 100644 erpnext/education/doctype/course_enrollment/course_enrollment.json create mode 100644 erpnext/education/doctype/course_enrollment/course_enrollment.py create mode 100644 erpnext/education/doctype/course_enrollment/test_course_enrollment.js create mode 100644 erpnext/education/doctype/course_enrollment/test_course_enrollment.py diff --git a/erpnext/education/doctype/course_enrollment/__init__.py b/erpnext/education/doctype/course_enrollment/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.js b/erpnext/education/doctype/course_enrollment/course_enrollment.js new file mode 100644 index 0000000000..b5d3cc56e5 --- /dev/null +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Course Enrollment', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.json b/erpnext/education/doctype/course_enrollment/course_enrollment.json new file mode 100644 index 0000000000..91d5221dce --- /dev/null +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.json @@ -0,0 +1,195 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "format:EDU-CE-{YYYY}-{#####}", + "beta": 0, + "creation": "2018-10-15 15:35:39.375161", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "program_enrollment", + "fieldtype": "Link", + "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, + "label": "Program Enrollment", + "length": 0, + "no_copy": 0, + "options": "Program Enrollment", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "student_id", + "fieldtype": "Link", + "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, + "label": "Student ID", + "length": 0, + "no_copy": 0, + "options": "Student", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "course_name", + "fieldtype": "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": "Course Name", + "length": 0, + "no_copy": 0, + "options": "Course", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "enrollment_date", + "fieldtype": "Date", + "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, + "label": "Enrollment Date", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-10-15 15:40:03.510180", + "modified_by": "Administrator", + "module": "Education", + "name": "Course Enrollment", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.py b/erpnext/education/doctype/course_enrollment/course_enrollment.py new file mode 100644 index 0000000000..09ffade7d8 --- /dev/null +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class CourseEnrollment(Document): + pass diff --git a/erpnext/education/doctype/course_enrollment/test_course_enrollment.js b/erpnext/education/doctype/course_enrollment/test_course_enrollment.js new file mode 100644 index 0000000000..216cc30799 --- /dev/null +++ b/erpnext/education/doctype/course_enrollment/test_course_enrollment.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Course Enrollment", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Course Enrollment + () => frappe.tests.make('Course Enrollment', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/course_enrollment/test_course_enrollment.py b/erpnext/education/doctype/course_enrollment/test_course_enrollment.py new file mode 100644 index 0000000000..2df0f30db3 --- /dev/null +++ b/erpnext/education/doctype/course_enrollment/test_course_enrollment.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestCourseEnrollment(unittest.TestCase): + pass From d1650b9f630af8391608aaf46deaad86f5d59ec0 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 15 Oct 2018 16:03:09 +0530 Subject: [PATCH 020/314] Modified Question doctype for a better design --- .../doctype/content_question/__init__.py | 0 .../content_question/content_question.js | 8 + .../content_question/content_question.json | 76 ++++++++ .../content_question/content_question.py | 10 + .../content_question/test_content_question.js | 23 +++ .../content_question/test_content_question.py | 10 + erpnext/education/doctype/options/__init__.py | 0 .../education/doctype/options/options.json | 107 +++++++++++ erpnext/education/doctype/options/options.py | 10 + .../education/doctype/question/question.js | 8 + .../education/doctype/question/question.json | 177 ++++-------------- .../doctype/question/test_question.js | 23 +++ .../doctype/question/test_question.py | 10 + 13 files changed, 321 insertions(+), 141 deletions(-) create mode 100644 erpnext/education/doctype/content_question/__init__.py create mode 100644 erpnext/education/doctype/content_question/content_question.js create mode 100644 erpnext/education/doctype/content_question/content_question.json create mode 100644 erpnext/education/doctype/content_question/content_question.py create mode 100644 erpnext/education/doctype/content_question/test_content_question.js create mode 100644 erpnext/education/doctype/content_question/test_content_question.py create mode 100644 erpnext/education/doctype/options/__init__.py create mode 100644 erpnext/education/doctype/options/options.json create mode 100644 erpnext/education/doctype/options/options.py create mode 100644 erpnext/education/doctype/question/question.js create mode 100644 erpnext/education/doctype/question/test_question.js create mode 100644 erpnext/education/doctype/question/test_question.py diff --git a/erpnext/education/doctype/content_question/__init__.py b/erpnext/education/doctype/content_question/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/content_question/content_question.js b/erpnext/education/doctype/content_question/content_question.js new file mode 100644 index 0000000000..7615f5efcf --- /dev/null +++ b/erpnext/education/doctype/content_question/content_question.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Content Question', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/content_question/content_question.json b/erpnext/education/doctype/content_question/content_question.json new file mode 100644 index 0000000000..d390e8ef70 --- /dev/null +++ b/erpnext/education/doctype/content_question/content_question.json @@ -0,0 +1,76 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-15 14:35:40.728454", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "question_link", + "fieldtype": "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": "Question Link", + "length": 0, + "no_copy": 0, + "options": "Question", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + } + ], + "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-10-15 14:41:31.729083", + "modified_by": "Administrator", + "module": "Education", + "name": "Content Question", + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/content_question/content_question.py b/erpnext/education/doctype/content_question/content_question.py new file mode 100644 index 0000000000..b239d211a3 --- /dev/null +++ b/erpnext/education/doctype/content_question/content_question.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class ContentQuestion(Document): + pass diff --git a/erpnext/education/doctype/content_question/test_content_question.js b/erpnext/education/doctype/content_question/test_content_question.js new file mode 100644 index 0000000000..cc869a87fc --- /dev/null +++ b/erpnext/education/doctype/content_question/test_content_question.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Content Question", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Content Question + () => frappe.tests.make('Content Question', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/content_question/test_content_question.py b/erpnext/education/doctype/content_question/test_content_question.py new file mode 100644 index 0000000000..268b9be2e7 --- /dev/null +++ b/erpnext/education/doctype/content_question/test_content_question.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestContentQuestion(unittest.TestCase): + pass diff --git a/erpnext/education/doctype/options/__init__.py b/erpnext/education/doctype/options/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/options/options.json b/erpnext/education/doctype/options/options.json new file mode 100644 index 0000000000..59deab7837 --- /dev/null +++ b/erpnext/education/doctype/options/options.json @@ -0,0 +1,107 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-15 14:05:28.601274", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "option", + "fieldtype": "Small Text", + "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": "Option", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "is_correct", + "fieldtype": "Check", + "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": "Is Correct", + "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 + } + ], + "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-10-15 14:16:18.303156", + "modified_by": "Administrator", + "module": "Education", + "name": "Options", + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/options/options.py b/erpnext/education/doctype/options/options.py new file mode 100644 index 0000000000..a11d77afb2 --- /dev/null +++ b/erpnext/education/doctype/options/options.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class Options(Document): + pass diff --git a/erpnext/education/doctype/question/question.js b/erpnext/education/doctype/question/question.js new file mode 100644 index 0000000000..01b3091b58 --- /dev/null +++ b/erpnext/education/doctype/question/question.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Question', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json index 28cbb5f976..2dcf1eb1f0 100644 --- a/erpnext/education/doctype/question/question.json +++ b/erpnext/education/doctype/question/question.json @@ -1,8 +1,10 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, + "autoname": "format:{question}", "beta": 0, "creation": "2018-10-01 15:58:00.696815", "custom": 0, @@ -14,20 +16,20 @@ "fields": [ { "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, + "allow_in_quick_entry": 1, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "fieldname": "question", - "fieldtype": "Text Editor", + "fieldtype": "Text", "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, + "in_standard_filter": 1, "label": "Question", "length": 0, "no_copy": 0, @@ -38,7 +40,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "translatable": 0, @@ -51,8 +53,9 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "option_1", - "fieldtype": "Data", + "description": "Write each option on a new line", + "fieldname": "options", + "fieldtype": "Table", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -60,9 +63,10 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Option 1", + "label": "Options", "length": 0, "no_copy": 0, + "options": "Options", "permlevel": 0, "precision": "", "print_hide": 0, @@ -70,136 +74,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, - "unique": 0 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "option_2", - "fieldtype": "Data", - "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, - "label": "Option 2", - "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 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "option_3", - "fieldtype": "Data", - "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, - "label": "Option 3", - "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 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "option_4", - "fieldtype": "Data", - "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, - "label": "Option 4", - "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 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "description": "For multiple correct options, write each option number separated by comma (Example: 1,3)", - "fieldname": "correct_options", - "fieldtype": "Data", - "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, - "label": "Correct Options", - "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, + "reqd": 1, "search_index": 0, "set_only_once": 0, "translatable": 0, @@ -214,22 +89,42 @@ "in_create": 0, "is_submittable": 0, "issingle": 0, - "istable": 1, + "istable": 0, "max_attachments": 0, - "modified": "2018-10-01 16:17:14.877309", + "modified": "2018-10-15 14:39:40.576374", "modified_by": "Administrator", "module": "Education", "name": "Question", "name_case": "", "owner": "Administrator", - "permissions": [], + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Administrator", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], "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_changes": 0, "track_seen": 0, "track_views": 0 } \ No newline at end of file diff --git a/erpnext/education/doctype/question/test_question.js b/erpnext/education/doctype/question/test_question.js new file mode 100644 index 0000000000..509939c6b5 --- /dev/null +++ b/erpnext/education/doctype/question/test_question.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Question", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Question + () => frappe.tests.make('Question', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/question/test_question.py b/erpnext/education/doctype/question/test_question.py new file mode 100644 index 0000000000..552872e15f --- /dev/null +++ b/erpnext/education/doctype/question/test_question.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestQuestion(unittest.TestCase): + pass From 31cbe3c0dc8686e29fd30af67323ce717fc78050 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 15 Oct 2018 16:04:14 +0530 Subject: [PATCH 021/314] Added function to retrieve quiz data as JSON --- erpnext/education/utils.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index d55bd1d316..809fa9e573 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -91,7 +91,7 @@ def add_activity(content_type, **kwargs): activity_does_not_exists, activity = check_entry_exists(kwargs.get('program')) if activity_does_not_exists: current_activity = frappe.get_doc({ - "doctype": "Student Course Activity", + "doctype": "Course Activity", "student_id": get_student_id(frappe.session.user), "program_name": kwargs.get('program'), "lms_activity": [{ @@ -131,13 +131,13 @@ def add_activity(content_type, **kwargs): def check_entry_exists(program): try: - activity_name = frappe.get_all("Student Course Activity", filters={"student_id": get_student_id(frappe.session.user), "program_name": program})[0] + activity_name = frappe.get_all("Course Activity", filters={"student_id": get_student_id(frappe.session.user), "program_name": program})[0] except IndexError: print("------ Got No Doc ------") return True, None else: print("------ Got A Doc ------") - return None, frappe.get_doc("Student Course Activity", activity_name) + return None, frappe.get_doc("Course Activity", activity_name) def get_student_id(email): """Returns Student ID, example EDU-STU-2018-00001 from email address @@ -147,4 +147,25 @@ def get_student_id(email): student = frappe.get_list('Student', filters={'student_email_id': email})[0].name return student except IndexError: - frappe.throw("Student Account with email:{0} does not exist".format(email)) \ No newline at end of file + frappe.throw("Student Account with email:{0} does not exist".format(email)) + +def get_quiz(content): + """Helper Function to get questions for a quiz + + :params content: name of a Content doctype with content_type quiz""" + try: + quiz_doc = frappe.get_doc("Content", content) + if quiz_doc.content_type == "Quiz": + import json + quiz = [frappe.get_doc("Question", item.question_link) for item in quiz_doc.questions] + data = [] + for question in quiz: + d = {} + d['Options'] = [{'option':item.option,'is_correct':item.is_correct} for item in quiz[0].options] + d['Question'] = question.question + data.append(d) + return json.dumps(data) + else: + frappe.throw("{0} is not a Quiz".format(content)) + except frappe.DoesNotExistError: + return None \ No newline at end of file From 5311e3898c91826aae3952a054a9b9722b3cdb97 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 15 Oct 2018 16:04:25 +0530 Subject: [PATCH 022/314] General Changes --- erpnext/config/education.py | 17 +++++++++++++++++ erpnext/education/doctype/content/content.json | 7 ++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/erpnext/config/education.py b/erpnext/config/education.py index b845537b06..2553c265be 100644 --- a/erpnext/config/education.py +++ b/erpnext/config/education.py @@ -195,6 +195,10 @@ def get_data(): "type": "doctype", "name": "Content" }, + { + "type": "doctype", + "name": "Question" + }, { "type": "doctype", "name": "Instructor" @@ -205,6 +209,19 @@ def get_data(): } ] }, + { + "label": _("LMS Activity"), + "items": [ + { + "type": "doctype", + "name": "Course Enrollment" + }, + { + "type": "doctype", + "name": "Course Activity" + } + ] + }, { "label": _("Settings"), "items": [ diff --git a/erpnext/education/doctype/content/content.json b/erpnext/education/doctype/content/content.json index 35db445af0..1d3221f3bb 100644 --- a/erpnext/education/doctype/content/content.json +++ b/erpnext/education/doctype/content/content.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, @@ -249,7 +250,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "quiz", + "fieldname": "questions", "fieldtype": "Table", "hidden": 0, "ignore_user_permissions": 0, @@ -261,7 +262,7 @@ "label": "Questions", "length": 0, "no_copy": 0, - "options": "Question", + "options": "Content Question", "permlevel": 0, "precision": "", "print_hide": 0, @@ -480,7 +481,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-08 14:15:06.001140", + "modified": "2018-10-15 14:36:42.894519", "modified_by": "Administrator", "module": "Education", "name": "Content", From f9cef33e41eea21185032752da5d4f4dd894b78b Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 15 Oct 2018 17:58:07 +0530 Subject: [PATCH 023/314] Dashboard changes for student and program --- .../doctype/program/program_dashboard.py | 20 +++++++++++++++++++ .../doctype/student/student_dashboard.py | 6 +++++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 erpnext/education/doctype/program/program_dashboard.py diff --git a/erpnext/education/doctype/program/program_dashboard.py b/erpnext/education/doctype/program/program_dashboard.py new file mode 100644 index 0000000000..cb8f74207e --- /dev/null +++ b/erpnext/education/doctype/program/program_dashboard.py @@ -0,0 +1,20 @@ +from frappe import _ + +def get_data(): + return { + 'fieldname': 'program', + 'transactions': [ + { + 'label': _('Admission and Enrollment'), + 'items': ['Student Applicant', 'Program Enrollment'] + }, + { + 'label': _('Student Activity'), + 'items': ['Student Group' ] + }, + { + 'label': _('Fee'), + 'items': ['Fees','Fee Structure'] + } + ] + } \ No newline at end of file diff --git a/erpnext/education/doctype/student/student_dashboard.py b/erpnext/education/doctype/student/student_dashboard.py index d86f4f231c..fa67d21155 100644 --- a/erpnext/education/doctype/student/student_dashboard.py +++ b/erpnext/education/doctype/student/student_dashboard.py @@ -9,7 +9,7 @@ def get_data(): 'transactions': [ { 'label': _('Admission'), - 'items': ['Program Enrollment'] + 'items': ['Program Enrollment', 'Course Enrollment'] }, { 'label': _('Student Activity'), @@ -19,6 +19,10 @@ def get_data(): 'label': _('Assessment'), 'items': ['Assessment Result'] }, + { + 'label': _('Student Portal Activity'), + 'items': ['Course Activity', 'Quiz Activity' ] + }, { 'label': _('Attendance'), 'items': ['Student Attendance', 'Student Leave Application'] From 3cbb9795a460a16ceab10266f776ec44ae2926fb Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 16 Oct 2018 13:04:11 +0530 Subject: [PATCH 024/314] Minor changes to doctypes --- erpnext/config/education.py | 4 + .../education/doctype/content/content.json | 69 +++++- erpnext/education/doctype/course/course.json | 68 +++++- .../course_activity/course_activity.json | 74 ++++++- .../course_enrollment/course_enrollment.json | 12 +- erpnext/education/doctype/program/program.js | 37 +--- .../education/doctype/program/program.json | 111 +++++++++- .../doctype/quiz_activity/quiz_activity.json | 200 +++++++++++++++++- .../doctype/quiz_result/quiz_result.json | 43 ++-- .../doctype/student/student_dashboard.py | 2 +- 10 files changed, 532 insertions(+), 88 deletions(-) diff --git a/erpnext/config/education.py b/erpnext/config/education.py index 2553c265be..ba6aa888b6 100644 --- a/erpnext/config/education.py +++ b/erpnext/config/education.py @@ -219,6 +219,10 @@ def get_data(): { "type": "doctype", "name": "Course Activity" + }, + { + "type": "doctype", + "name": "Quiz Activity" } ] }, diff --git a/erpnext/education/doctype/content/content.json b/erpnext/education/doctype/content/content.json index 1d3221f3bb..ff87d0bed1 100644 --- a/erpnext/education/doctype/content/content.json +++ b/erpnext/education/doctype/content/content.json @@ -120,6 +120,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "default": "0", "fieldname": "is_published", "fieldtype": "Check", "hidden": 0, @@ -276,6 +277,72 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "max_attempts", + "fieldtype": "Int", + "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, + "label": "Max Attempts", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "75", + "description": "Percentage (0-100)", + "fieldname": "passing_score", + "fieldtype": "Int", + "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, + "label": "Passing Score", + "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 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -481,7 +548,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-15 14:36:42.894519", + "modified": "2018-10-16 13:03:35.328063", "modified_by": "Administrator", "module": "Education", "name": "Content", diff --git a/erpnext/education/doctype/course/course.json b/erpnext/education/doctype/course/course.json index 3effd86eba..00a408ee22 100644 --- a/erpnext/education/doctype/course/course.json +++ b/erpnext/education/doctype/course/course.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, @@ -205,6 +206,38 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "portal_settings_section", + "fieldtype": "Section 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, + "label": "Portal Settings", + "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 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -302,6 +335,39 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "is_published", + "fieldtype": "Check", + "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, + "label": "Is Published", + "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 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -412,7 +478,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-10-01 15:05:22.653467", + "modified": "2018-10-16 13:03:09.310985", "modified_by": "Administrator", "module": "Education", "name": "Course", diff --git a/erpnext/education/doctype/course_activity/course_activity.json b/erpnext/education/doctype/course_activity/course_activity.json index 0f7fcb7c31..27089748bb 100644 --- a/erpnext/education/doctype/course_activity/course_activity.json +++ b/erpnext/education/doctype/course_activity/course_activity.json @@ -4,7 +4,7 @@ "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, - "autoname": "field:enrollment", + "autoname": "format:EDU-CA-{YYYY}-{#####}", "beta": 0, "creation": "2018-10-01 17:35:54.391413", "custom": 0, @@ -47,6 +47,74 @@ "translatable": 0, "unique": 1 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "enrollment.course", + "fieldname": "course", + "fieldtype": "Data", + "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, + "label": "Course", + "length": 0, + "no_copy": 0, + "options": "", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "enrollment.student", + "fieldname": "student", + "fieldtype": "Data", + "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, + "label": "Student", + "length": 0, + "no_copy": 0, + "options": "", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -108,7 +176,7 @@ "report_hide": 0, "reqd": 0, "search_index": 0, - "set_only_once": 0, + "set_only_once": 1, "translatable": 0, "unique": 0 } @@ -123,7 +191,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-15 15:47:11.824446", + "modified": "2018-10-15 17:49:09.157437", "modified_by": "Administrator", "module": "Education", "name": "Course Activity", diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.json b/erpnext/education/doctype/course_enrollment/course_enrollment.json index 91d5221dce..303cb0da33 100644 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.json +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.json @@ -54,7 +54,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "student_id", + "fieldname": "student", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -63,7 +63,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Student ID", + "label": "Student", "length": 0, "no_copy": 0, "options": "Student", @@ -74,7 +74,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "translatable": 0, @@ -87,7 +87,7 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "course_name", + "fieldname": "course", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, @@ -96,7 +96,7 @@ "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, - "label": "Course Name", + "label": "Course", "length": 0, "no_copy": 0, "options": "Course", @@ -156,7 +156,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-15 15:40:03.510180", + "modified": "2018-10-15 16:26:39.216071", "modified_by": "Administrator", "module": "Education", "name": "Course Enrollment", diff --git a/erpnext/education/doctype/program/program.js b/erpnext/education/doctype/program/program.js index 5146a19322..98263b55a1 100644 --- a/erpnext/education/doctype/program/program.js +++ b/erpnext/education/doctype/program/program.js @@ -4,40 +4,5 @@ cur_frm.add_fetch('fee_structure', 'total_amount', 'amount'); frappe.ui.form.on("Program", "refresh", function(frm) { - if(!frm.doc.__islocal) { - frm.add_custom_button(__("Student Applicant"), function() { - frappe.route_options = { - program: frm.doc.name - } - frappe.set_route("List", "Student Applicant"); - }); - - frm.add_custom_button(__("Program Enrollment"), function() { - frappe.route_options = { - program: frm.doc.name - } - frappe.set_route("List", "Program Enrollment"); - }); - - frm.add_custom_button(__("Student Group"), function() { - frappe.route_options = { - program: frm.doc.name - } - frappe.set_route("List", "Student Group"); - }); - - frm.add_custom_button(__("Fee Structure"), function() { - frappe.route_options = { - program: frm.doc.name - } - frappe.set_route("List", "Fee Structure"); - }); - - frm.add_custom_button(__("Fees"), function() { - frappe.route_options = { - program: frm.doc.name - } - frappe.set_route("List", "Fees"); - }); - } + }); \ No newline at end of file diff --git a/erpnext/education/doctype/program/program.json b/erpnext/education/doctype/program/program.json index 0b68e232de..5dd364700a 100644 --- a/erpnext/education/doctype/program/program.json +++ b/erpnext/education/doctype/program/program.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 1, @@ -180,6 +181,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "depends_on": "", "fieldname": "section_break_5", "fieldtype": "Section Break", "hidden": 0, @@ -189,7 +191,7 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Course", + "label": "Portal Settings", "length": 0, "no_copy": 0, "permlevel": 0, @@ -245,9 +247,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "default": "0", - "fieldname": "is_featured", - "fieldtype": "Check", + "fieldname": "section_break_9", + "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -255,7 +256,6 @@ "in_global_search": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Is Featured", "length": 0, "no_copy": 0, "permlevel": 0, @@ -279,7 +279,7 @@ "collapsible": 0, "columns": 0, "fieldname": "description", - "fieldtype": "Data", + "fieldtype": "Small Text", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -366,6 +366,103 @@ "set_only_once": 0, "translatable": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_11", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "is_published", + "fieldtype": "Check", + "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, + "label": "Is Published", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "is_featured", + "fieldtype": "Check", + "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, + "label": "Is Featured", + "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 } ], "has_web_view": 0, @@ -379,7 +476,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-10-08 13:04:46.741926", + "modified": "2018-10-16 13:03:22.002322", "modified_by": "Administrator", "module": "Education", "name": "Program", diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.json b/erpnext/education/doctype/quiz_activity/quiz_activity.json index 32f35abd7d..53a213d11f 100644 --- a/erpnext/education/doctype/quiz_activity/quiz_activity.json +++ b/erpnext/education/doctype/quiz_activity/quiz_activity.json @@ -4,6 +4,7 @@ "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, + "autoname": "format:EDU-QA-{YYYY}-{#####}", "beta": 0, "creation": "2018-10-15 15:48:40.482821", "custom": 0, @@ -46,6 +47,136 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "enrollment.student", + "fieldname": "student", + "fieldtype": "Link", + "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, + "label": "Student", + "length": 0, + "no_copy": 0, + "options": "Student", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_3", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "enrollment.course", + "fieldname": "course", + "fieldtype": "Link", + "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, + "label": "Course", + "length": 0, + "no_copy": 0, + "options": "Course", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "section_break_5", + "fieldtype": "Section 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 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -79,6 +210,39 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "status", + "fieldtype": "Select", + "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, + "label": "Status", + "length": 0, + "no_copy": 0, + "options": "\nPass\nFail", + "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 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -143,6 +307,38 @@ "set_only_once": 0, "translatable": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "score", + "fieldtype": "Data", + "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, + "label": "Score", + "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": 1, + "translatable": 0, + "unique": 0 } ], "has_web_view": 0, @@ -155,10 +351,10 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-15 15:52:45.980055", + "modified": "2018-10-15 17:51:34.273703", "modified_by": "Administrator", "module": "Education", - "name": "Student Quiz Activity", + "name": "Quiz Activity", "name_case": "", "owner": "Administrator", "permissions": [ diff --git a/erpnext/education/doctype/quiz_result/quiz_result.json b/erpnext/education/doctype/quiz_result/quiz_result.json index 3e965d447e..7b32694871 100644 --- a/erpnext/education/doctype/quiz_result/quiz_result.json +++ b/erpnext/education/doctype/quiz_result/quiz_result.json @@ -27,7 +27,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Question", "length": 0, @@ -40,7 +40,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "translatable": 0, @@ -60,7 +60,7 @@ "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, "label": "Selected Option", "length": 0, @@ -73,7 +73,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "translatable": 0, @@ -87,17 +87,18 @@ "collapsible": 0, "columns": 0, "fieldname": "correct_option", - "fieldtype": "Data", + "fieldtype": "Select", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, - "in_list_view": 0, + "in_list_view": 1, "in_standard_filter": 0, - "label": "Correct Option", + "label": "Result", "length": 0, "no_copy": 0, + "options": "\nCorrect\nWrong", "permlevel": 0, "precision": "", "print_hide": 0, @@ -105,7 +106,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "translatable": 0, @@ -120,35 +121,15 @@ "in_create": 0, "is_submittable": 0, "issingle": 0, - "istable": 0, + "istable": 1, "max_attachments": 0, - "modified": "2018-10-15 15:52:25.766374", + "modified": "2018-10-15 16:17:35.779634", "modified_by": "Administrator", "module": "Education", "name": "Quiz Result", "name_case": "", "owner": "Administrator", - "permissions": [ - { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, - "write": 1 - } - ], + "permissions": [], "quick_entry": 1, "read_only": 0, "read_only_onload": 0, diff --git a/erpnext/education/doctype/student/student_dashboard.py b/erpnext/education/doctype/student/student_dashboard.py index fa67d21155..0cbd17b8a4 100644 --- a/erpnext/education/doctype/student/student_dashboard.py +++ b/erpnext/education/doctype/student/student_dashboard.py @@ -20,7 +20,7 @@ def get_data(): 'items': ['Assessment Result'] }, { - 'label': _('Student Portal Activity'), + 'label': _('Student LMS Activity'), 'items': ['Course Activity', 'Quiz Activity' ] }, { From 82df4378de785ae67ca21e82e59f61fc3081377b Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 16 Oct 2018 13:04:40 +0530 Subject: [PATCH 025/314] Changes to get_quiz function --- erpnext/education/utils.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index 809fa9e573..493a876a29 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -155,17 +155,17 @@ def get_quiz(content): :params content: name of a Content doctype with content_type quiz""" try: quiz_doc = frappe.get_doc("Content", content) - if quiz_doc.content_type == "Quiz": - import json - quiz = [frappe.get_doc("Question", item.question_link) for item in quiz_doc.questions] - data = [] - for question in quiz: - d = {} - d['Options'] = [{'option':item.option,'is_correct':item.is_correct} for item in quiz[0].options] - d['Question'] = question.question - data.append(d) - return json.dumps(data) - else: + if quiz_doc.content_type != "Quiz": frappe.throw("{0} is not a Quiz".format(content)) + + import json + quiz = [frappe.get_doc("Question", item.question_link) for item in quiz_doc.questions] + data = [] + for question in quiz: + d = {} + d['Question'] = question.question + d['Options'] = [item.option for item in quiz[0].options] + data.append(d) + return data except frappe.DoesNotExistError: - return None \ No newline at end of file + frappe.throw("The quiz \"{0}\" does not exist".format(content)) From fa2db3c41bceb6d610054ce099c11a036fa7609c Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 16 Oct 2018 16:46:27 +0530 Subject: [PATCH 026/314] LMS: Added functions to get LMS contents Co-authored-by: Chinmay Pai --- .../education/doctype/content/content.json | 35 +----------- erpnext/education/utils.py | 57 +++++++++++++++++-- 2 files changed, 54 insertions(+), 38 deletions(-) diff --git a/erpnext/education/doctype/content/content.json b/erpnext/education/doctype/content/content.json index ff87d0bed1..053372ff21 100644 --- a/erpnext/education/doctype/content/content.json +++ b/erpnext/education/doctype/content/content.json @@ -113,39 +113,6 @@ "translatable": 0, "unique": 1 }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fieldname": "is_published", - "fieldtype": "Check", - "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, - "label": "Is Published", - "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 - }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -548,7 +515,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-16 13:03:35.328063", + "modified": "2018-10-16 15:50:59.193504", "modified_by": "Administrator", "module": "Education", "name": "Content", diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index 493a876a29..9314da2c17 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -133,19 +133,68 @@ def check_entry_exists(program): try: activity_name = frappe.get_all("Course Activity", filters={"student_id": get_student_id(frappe.session.user), "program_name": program})[0] except IndexError: - print("------ Got No Doc ------") return True, None else: - print("------ Got A Doc ------") return None, frappe.get_doc("Course Activity", activity_name) +def get_contents_in_course(course_name): + try: + course_doc = frappe.get_doc("Course", {"name":course_name, "is_published": True}) + return [frappe.get_doc("Content", content.content) for content in course_doc.get_all_children()] + except frappe.DoesNotExistError: + return None + +def get_courses_in_program(program): + try: + program_doc = frappe.get_doc("Program", program) + if program_doc.is_published: + course_list = [frappe.get_doc("Course", course.course_name) for course in program_doc.get_all_children()] + return [course for course in course_list if course.is_published == True] + else: + return None + except frappe.DoesNotExistError: + return None + +def get_program(): + program_list = frappe.get_list("Program", filters={"is_published": is_published}) + if program_list: + return program_list + else: + return None + +def get_featured_program(): + featured_list = frappe.get_list("Program", filters={"is_published": True, "is_featured": True}) + if featured_list: + return featured_list + else: + return None + +@frappe.whitelist() +def add_course_enrollment(course, email): + student_id = get_student_id(email) + if not get_course_enrollment(course, email): + enrollment = frappe.get_doc({ + "doctype": "Course Enrollment", + "student": student_id, + "course": course + }) + enrollment.save() + frappe.db.commit() + return enrollment + +def get_course_enrollment(course, email): + student_id = get_student_id(email) + try: + return frappe.get_list("Course Enrollment", filters={'course':course, 'student':student_id})[0] + except IndexError: + return None + def get_student_id(email): """Returns Student ID, example EDU-STU-2018-00001 from email address :params email: email address of the student""" try: - student = frappe.get_list('Student', filters={'student_email_id': email})[0].name - return student + return frappe.get_list('Student', filters={'student_email_id': email})[0].name except IndexError: frappe.throw("Student Account with email:{0} does not exist".format(email)) From 3757a4eab8b2b2bc818a77d272887f648b048620 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 16 Oct 2018 17:54:18 +0530 Subject: [PATCH 027/314] Modified program and index view Co-authored-by: Chinmay Pai --- erpnext/education/utils.py | 5 +++-- erpnext/www/lms/index.py | 3 ++- erpnext/www/lms/program.html | 10 +++++----- erpnext/www/lms/program.py | 13 ++----------- 4 files changed, 12 insertions(+), 19 deletions(-) diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index 9314da2c17..b12ad0c71d 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -162,8 +162,9 @@ def get_program(): else: return None -def get_featured_program(): - featured_list = frappe.get_list("Program", filters={"is_published": True, "is_featured": True}) +def get_featured_programs(): + featured_programs_name = frappe.get_list("Program", filters={"is_published": True, "is_featured": True}) + featured_list = [frappe.get_doc("Program", program["name"]) for program in featured_programs_name] if featured_list: return featured_list else: diff --git a/erpnext/www/lms/index.py b/erpnext/www/lms/index.py index 16772a4f5d..1bba69f470 100644 --- a/erpnext/www/lms/index.py +++ b/erpnext/www/lms/index.py @@ -1,5 +1,6 @@ from __future__ import unicode_literals import frappe +import erpnext.education.utils as utils def get_context(context): - context.featured = frappe.get_all('Program', filters={'is_featured': 1}, fields=['program_name', 'program_code', 'description', 'hero_image']) \ No newline at end of file + context.featured = utils.get_featured_programs() \ No newline at end of file diff --git a/erpnext/www/lms/program.html b/erpnext/www/lms/program.html index 23f2e5c528..5c1f15994c 100644 --- a/erpnext/www/lms/program.html +++ b/erpnext/www/lms/program.html @@ -6,23 +6,23 @@ {% endblock %} -{% macro course_card(name) %} +{% macro course_card(course) %}
-
{{ name }}
+
{{ course.name }}
Course Content
    - {% for content in course_data[name] %} -
  • {{ content }}
  • + {% for content in course.course_content %} +
  • {{ content.content }}
  • {% endfor %}
diff --git a/erpnext/www/lms/program.py b/erpnext/www/lms/program.py index c61aee53f6..c5bf018878 100644 --- a/erpnext/www/lms/program.py +++ b/erpnext/www/lms/program.py @@ -1,17 +1,8 @@ from __future__ import unicode_literals -from erpnext.education.utils import get_student_name +import erpnext.education.utils as utils import frappe def get_context(context): - print(get_student_name(frappe.session.user)) context.program = frappe.get_doc("Program", frappe.form_dict["program"]) - context.course_list, context.course_data = get_courses(context) - -def get_courses(context): - course_data = {} - course_names = [program.course_name for program in context.program.courses] - program_courses = [frappe.get_doc('Course', name) for name in course_names] - for course_item in program_courses: - course_data[course_item.name] = [content_item.content for content_item in course_item.course_content if content_item.content_type in ('Video', 'Article')] - return course_names, course_data + context.course_list = utils.get_courses_in_program(frappe.form_dict["program"]) \ No newline at end of file From 685584bf560bd07163bd654bd98c1857224cd01a Mon Sep 17 00:00:00 2001 From: scmmishra Date: Wed, 17 Oct 2018 12:41:50 +0530 Subject: [PATCH 028/314] Quiz: Quiz now displays correctly on the portal Co-authored-by: Chinmay Pai --- .../education/doctype/question/question.json | 4 +- erpnext/education/utils.py | 39 ++++++++++++------- erpnext/www/lms/course.html | 4 +- erpnext/www/lms/course.py | 10 +++-- erpnext/www/lms/templates/includes/quiz.html | 30 +++++++------- 5 files changed, 50 insertions(+), 37 deletions(-) diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json index 2dcf1eb1f0..c62d4a9aff 100644 --- a/erpnext/education/doctype/question/question.json +++ b/erpnext/education/doctype/question/question.json @@ -4,7 +4,7 @@ "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, - "autoname": "format:{question}", + "autoname": "format:QUESTION-{#####}", "beta": 0, "creation": "2018-10-01 15:58:00.696815", "custom": 0, @@ -91,7 +91,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-15 14:39:40.576374", + "modified": "2018-10-17 12:08:05.649254", "modified_by": "Administrator", "module": "Education", "name": "Question", diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index b12ad0c71d..6d9c8e21c7 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -10,19 +10,19 @@ class OverlapError(frappe.ValidationError): pass def validate_overlap_for(doc, doctype, fieldname, value=None): """Checks overlap for specified field. - - :param fieldname: Checks Overlap for this field + + :param fieldname: Checks Overlap for this field """ - + existing = get_overlap_for(doc, doctype, fieldname, value) if existing: frappe.throw(_("This {0} conflicts with {1} for {2} {3}").format(doc.doctype, existing.name, doc.meta.get_label(fieldname) if not value else fieldname , value or doc.get(fieldname)), OverlapError) - + def get_overlap_for(doc, doctype, fieldname, value=None): """Returns overlaping document for specified field. - - :param fieldname: Checks Overlap for this field + + :param fieldname: Checks Overlap for this field """ existing = frappe.db.sql("""select name, from_time, to_time from `tab{0}` @@ -42,7 +42,7 @@ def get_overlap_for(doc, doctype, fieldname, value=None): }, as_dict=True) return existing[0] if existing else None - + def validate_duplicate_student(students): unique_students= [] for stud in students: @@ -54,7 +54,7 @@ def validate_duplicate_student(students): def get_student_name(email=None): """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series). - + :param user: a user email address """ try: @@ -65,7 +65,7 @@ def get_student_name(email=None): @frappe.whitelist() def evaluate_quiz(quiz_response, **kwargs): """LMS Function: Evaluates a simple multiple choice quiz. It recieves arguments from `www/lms/course.js` as dictionary using FormData[1]. - + :param quiz_response: contains user selected choices for a quiz in the form of a string formatted as a dictionary. The function uses `json.loads()` to convert it to a python dictionary. [1]: https://developer.mozilla.org/en-US/docs/Web/API/FormData @@ -192,7 +192,7 @@ def get_course_enrollment(course, email): def get_student_id(email): """Returns Student ID, example EDU-STU-2018-00001 from email address - + :params email: email address of the student""" try: return frappe.get_list('Student', filters={'student_email_id': email})[0].name @@ -200,21 +200,32 @@ def get_student_id(email): frappe.throw("Student Account with email:{0} does not exist".format(email)) def get_quiz(content): + try: + quiz_doc = frappe.get_doc("Content", content) + if quiz_doc.content_type != "Quiz": + frappe.throw("{0} is not a Quiz".format(content)) + quiz = [frappe.get_doc("Question", item.question_link) for item in quiz_doc.questions] + return quiz + except frappe.DoesNotExistError: + frappe.throw("The quiz \"{0}\" does not exist".format(content)) + +def get_quiz_as_dict(content): """Helper Function to get questions for a quiz - + :params content: name of a Content doctype with content_type quiz""" try: quiz_doc = frappe.get_doc("Content", content) if quiz_doc.content_type != "Quiz": frappe.throw("{0} is not a Quiz".format(content)) - + import json quiz = [frappe.get_doc("Question", item.question_link) for item in quiz_doc.questions] data = [] for question in quiz: d = {} - d['Question'] = question.question - d['Options'] = [item.option for item in quiz[0].options] + d['id'] = question.name + d['question'] = question.question + d['options'] = [item.option for item in quiz[0].options] data.append(d) return data except frappe.DoesNotExistError: diff --git a/erpnext/www/lms/course.html b/erpnext/www/lms/course.html index 182efab7d6..5e2e393ffa 100644 --- a/erpnext/www/lms/course.html +++ b/erpnext/www/lms/course.html @@ -10,7 +10,7 @@ {% block content %}
-{% with current_content = current_content, next_content = next_content, course_name = current_course.name, program=current_program%} +{% with quiz = quiz, current_content = current_content, next_content = next_content, course_name = course_name, program=current_program%} {% include "www/lms/templates/includes/" + current_content.content_type.lower() + ".html" %} {% endwith %}
@@ -23,7 +23,7 @@ padding-top: 3rem !important; padding-bottom: 1rem !important; } - + .video-description-section { padding-top: 0em !important; } diff --git a/erpnext/www/lms/course.py b/erpnext/www/lms/course.py index 0276102462..19e495fab3 100644 --- a/erpnext/www/lms/course.py +++ b/erpnext/www/lms/course.py @@ -1,19 +1,23 @@ from __future__ import unicode_literals +import erpnext.education.utils as utils import frappe def get_context(context): if frappe.form_dict['course']: - context.current_course = frappe.get_doc("Course", frappe.form_dict["course"]) context.current_content = frappe.get_doc("Content", frappe.form_dict["content"]) + context.course_name = frappe.form_dict["course"] + context.current_course = utils.get_contents_in_course(context.course_name) context.current_program = frappe.form_dict["program"] context.next_content = get_next_content(context) + if context.current_content.content_type == "Quiz": + context.questions = utils.get_quiz_as_dict(context.current_content.name) def get_next_content(context): if context.current_course: - course_data = [content_item.content for content_item in context.current_course.course_content] - try: + course_data = [content.name for content in context.current_course] + try: return course_data[course_data.index(context.current_content.name) + 1] except IndexError: return None \ No newline at end of file diff --git a/erpnext/www/lms/templates/includes/quiz.html b/erpnext/www/lms/templates/includes/quiz.html index 280a17baae..8d20a26f01 100644 --- a/erpnext/www/lms/templates/includes/quiz.html +++ b/erpnext/www/lms/templates/includes/quiz.html @@ -1,13 +1,13 @@ -{% macro quiz(loop_index, question_id, question, options) %} -
-
{{ loop_index }}{{ question }}
+{% macro quiz(loop_index, question) %} +
+
{{ loop_index }}{{ question['question'] }}
- {% for option in options %} + {% for option in question['options'] %}
- + @@ -16,7 +16,6 @@
{% endmacro %} -
@@ -28,9 +27,8 @@
- {% for quiz_item in current_content.quiz %} - {{ quiz(loop.index|str +". ", quiz_item.name, quiz_item.question, [ quiz_item.option_1, quiz_item.option_2, - quiz_item.option_3, quiz_item.option_4]) }} + {% for q in questions %} + {{ quiz(loop.index|str +". ", q) }} {% endfor %}
@@ -43,12 +41,12 @@

Your Score:

- Previous - {% if next_content != None %} - Next - {% else %} - Finish Course - {% endif %} + Previous + {% if next_content != None %} + Next + {% else %} + Finish Course + {% endif %}
From 1869419bdcdbc87161c21ae3ea852f01b2463da2 Mon Sep 17 00:00:00 2001 From: Chinmay Pai Date: Wed, 17 Oct 2018 23:57:21 +0530 Subject: [PATCH 029/314] lms: refactor entire course model each course item now has its own doctype. Co-authored-by: Shivam Mishra Signed-off-by: Chinmay Pai --- erpnext/education/doctype/article/__init__.py | 0 erpnext/education/doctype/article/article.js | 8 + .../education/doctype/article/article.json | 192 +++++++++++++++ erpnext/education/doctype/article/article.py | 15 ++ .../education/doctype/article/test_article.js | 23 ++ .../education/doctype/article/test_article.py | 10 + .../doctype/content_activity/__init__.py | 0 .../content_activity/content_activity.json | 141 +++++++++++ .../content_activity/content_activity.py | 10 + erpnext/education/doctype/course/course.py | 18 +- .../course_content/course_content.json | 22 +- erpnext/education/doctype/quiz/__init__.py | 0 erpnext/education/doctype/quiz/quiz.js | 8 + erpnext/education/doctype/quiz/quiz.json | 193 +++++++++++++++ erpnext/education/doctype/quiz/quiz.py | 22 ++ erpnext/education/doctype/quiz/test_quiz.js | 23 ++ erpnext/education/doctype/quiz/test_quiz.py | 10 + .../doctype/quiz_question/__init__.py | 0 .../doctype/quiz_question/quiz_question.json | 76 ++++++ .../doctype/quiz_question/quiz_question.py | 10 + erpnext/education/doctype/video/__init__.py | 0 erpnext/education/doctype/video/test_video.js | 23 ++ erpnext/education/doctype/video/test_video.py | 10 + erpnext/education/doctype/video/video.js | 8 + erpnext/education/doctype/video/video.json | 224 ++++++++++++++++++ erpnext/education/doctype/video/video.py | 13 + 26 files changed, 1048 insertions(+), 11 deletions(-) create mode 100644 erpnext/education/doctype/article/__init__.py create mode 100644 erpnext/education/doctype/article/article.js create mode 100644 erpnext/education/doctype/article/article.json create mode 100644 erpnext/education/doctype/article/article.py create mode 100644 erpnext/education/doctype/article/test_article.js create mode 100644 erpnext/education/doctype/article/test_article.py create mode 100644 erpnext/education/doctype/content_activity/__init__.py create mode 100644 erpnext/education/doctype/content_activity/content_activity.json create mode 100644 erpnext/education/doctype/content_activity/content_activity.py create mode 100644 erpnext/education/doctype/quiz/__init__.py create mode 100644 erpnext/education/doctype/quiz/quiz.js create mode 100644 erpnext/education/doctype/quiz/quiz.json create mode 100644 erpnext/education/doctype/quiz/quiz.py create mode 100644 erpnext/education/doctype/quiz/test_quiz.js create mode 100644 erpnext/education/doctype/quiz/test_quiz.py create mode 100644 erpnext/education/doctype/quiz_question/__init__.py create mode 100644 erpnext/education/doctype/quiz_question/quiz_question.json create mode 100644 erpnext/education/doctype/quiz_question/quiz_question.py create mode 100644 erpnext/education/doctype/video/__init__.py create mode 100644 erpnext/education/doctype/video/test_video.js create mode 100644 erpnext/education/doctype/video/test_video.py create mode 100644 erpnext/education/doctype/video/video.js create mode 100644 erpnext/education/doctype/video/video.json create mode 100644 erpnext/education/doctype/video/video.py diff --git a/erpnext/education/doctype/article/__init__.py b/erpnext/education/doctype/article/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/article/article.js b/erpnext/education/doctype/article/article.js new file mode 100644 index 0000000000..4c9c6f01f0 --- /dev/null +++ b/erpnext/education/doctype/article/article.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Article', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/article/article.json b/erpnext/education/doctype/article/article.json new file mode 100644 index 0000000000..e879731160 --- /dev/null +++ b/erpnext/education/doctype/article/article.json @@ -0,0 +1,192 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "field:title", + "beta": 0, + "creation": "2018-10-17 05:45:38.471670", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "title", + "fieldtype": "Data", + "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, + "label": "Title", + "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": 1 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "author", + "fieldtype": "Data", + "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, + "label": "Author", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "content", + "fieldtype": "Text Editor", + "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, + "label": "Content", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "publish_date", + "fieldtype": "Date", + "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, + "label": "Publish Date", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-10-17 06:56:50.621421", + "modified_by": "Administrator", + "module": "Education", + "name": "Article", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/article/article.py b/erpnext/education/doctype/article/article.py new file mode 100644 index 0000000000..7dc850be37 --- /dev/null +++ b/erpnext/education/doctype/article/article.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class Article(Document): + + + def get_article(self): + pass + + diff --git a/erpnext/education/doctype/article/test_article.js b/erpnext/education/doctype/article/test_article.js new file mode 100644 index 0000000000..9dbf063e84 --- /dev/null +++ b/erpnext/education/doctype/article/test_article.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Article", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Article + () => frappe.tests.make('Article', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/article/test_article.py b/erpnext/education/doctype/article/test_article.py new file mode 100644 index 0000000000..2fce07f82c --- /dev/null +++ b/erpnext/education/doctype/article/test_article.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestArticle(unittest.TestCase): + pass diff --git a/erpnext/education/doctype/content_activity/__init__.py b/erpnext/education/doctype/content_activity/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/content_activity/content_activity.json b/erpnext/education/doctype/content_activity/content_activity.json new file mode 100644 index 0000000000..b4c95dad9c --- /dev/null +++ b/erpnext/education/doctype/content_activity/content_activity.json @@ -0,0 +1,141 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-16 03:55:53.283893", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "content", + "fieldtype": "Link", + "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, + "label": "Content", + "length": 0, + "no_copy": 0, + "options": "Content", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "content.content_type", + "fieldname": "content_type", + "fieldtype": "Data", + "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, + "label": "Content Type", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "last_activity", + "fieldtype": "Datetime", + "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, + "label": "Last Activity ", + "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 + } + ], + "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-10-16 03:55:58.202436", + "modified_by": "Administrator", + "module": "Education", + "name": "Content Activity", + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/content_activity/content_activity.py b/erpnext/education/doctype/content_activity/content_activity.py new file mode 100644 index 0000000000..2ae7a5c94c --- /dev/null +++ b/erpnext/education/doctype/content_activity/content_activity.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class ContentActivity(Document): + pass diff --git a/erpnext/education/doctype/course/course.py b/erpnext/education/doctype/course/course.py index 69d2fca63e..68d666c5d0 100644 --- a/erpnext/education/doctype/course/course.py +++ b/erpnext/education/doctype/course/course.py @@ -10,7 +10,7 @@ from frappe import _ class Course(Document): def validate(self): self.validate_assessment_criteria() - + def validate_assessment_criteria(self): if self.assessment_criteria: total_weightage = 0 @@ -18,3 +18,19 @@ class Course(Document): total_weightage += criteria.weightage or 0 if total_weightage != 100: frappe.throw(_("Total Weightage of all Assessment Criteria must be 100%")) + + def get_content_data(self, data): + try: + course_content_list = self.get_all_children() + content_data = [frappe.get_value(course_content.content_type, course_content.content, data) for course_content in course_content_list] + except Exception as e: + print(e) + return None + return content_data + + def get_content_title(self): + ''' + returns all the course content for the given course object. + ''' + content_title = self.get_content_data("title") + return content_title diff --git a/erpnext/education/doctype/course_content/course_content.json b/erpnext/education/doctype/course_content/course_content.json index fb3c1de3bd..378e56005f 100644 --- a/erpnext/education/doctype/course_content/course_content.json +++ b/erpnext/education/doctype/course_content/course_content.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 0, @@ -19,8 +20,9 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "content", - "fieldtype": "Link", + "fetch_from": "", + "fieldname": "content_type", + "fieldtype": "Select", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -28,10 +30,10 @@ "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, - "label": "Content", + "label": "Content Type", "length": 0, "no_copy": 0, - "options": "Content", + "options": "\nArticle\nVideo\nQuiz", "permlevel": 0, "precision": "", "print_hide": 0, @@ -84,9 +86,8 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fetch_from": "content.content_type", - "fieldname": "content_type", - "fieldtype": "Data", + "fieldname": "content", + "fieldtype": "Dynamic Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -94,14 +95,15 @@ "in_global_search": 0, "in_list_view": 1, "in_standard_filter": 0, - "label": "Content Type", + "label": "Content", "length": 0, "no_copy": 0, + "options": "content_type", "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 1, + "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, @@ -121,7 +123,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-10-08 14:34:07.400616", + "modified": "2018-10-17 07:36:04.029818", "modified_by": "Administrator", "module": "Education", "name": "Course Content", diff --git a/erpnext/education/doctype/quiz/__init__.py b/erpnext/education/doctype/quiz/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/quiz/quiz.js b/erpnext/education/doctype/quiz/quiz.js new file mode 100644 index 0000000000..122cf37818 --- /dev/null +++ b/erpnext/education/doctype/quiz/quiz.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Quiz', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/quiz/quiz.json b/erpnext/education/doctype/quiz/quiz.json new file mode 100644 index 0000000000..6284d92f71 --- /dev/null +++ b/erpnext/education/doctype/quiz/quiz.json @@ -0,0 +1,193 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "field:title", + "beta": 0, + "creation": "2018-10-17 05:52:50.149904", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "title", + "fieldtype": "Data", + "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, + "label": "Title", + "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": 1 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "question", + "fieldtype": "Table", + "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, + "label": "Question", + "length": 0, + "no_copy": 0, + "options": "Quiz Question", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "max_attempts", + "fieldtype": "Int", + "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, + "label": "Max Attempts", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "passing_score", + "fieldtype": "Float", + "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, + "label": "Passing Score", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-10-17 06:57:18.235274", + "modified_by": "Administrator", + "module": "Education", + "name": "Quiz", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/quiz/quiz.py b/erpnext/education/doctype/quiz/quiz.py new file mode 100644 index 0000000000..a7d76d5dc3 --- /dev/null +++ b/erpnext/education/doctype/quiz/quiz.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class Quiz(Document): + + + def get_quiz(self): + pass + + + def evaluate_quiz(self): + pass + + + def get_question(self): + pass + diff --git a/erpnext/education/doctype/quiz/test_quiz.js b/erpnext/education/doctype/quiz/test_quiz.js new file mode 100644 index 0000000000..147d13952a --- /dev/null +++ b/erpnext/education/doctype/quiz/test_quiz.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Quiz", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Quiz + () => frappe.tests.make('Quiz', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/quiz/test_quiz.py b/erpnext/education/doctype/quiz/test_quiz.py new file mode 100644 index 0000000000..344fd544ee --- /dev/null +++ b/erpnext/education/doctype/quiz/test_quiz.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestQuiz(unittest.TestCase): + pass diff --git a/erpnext/education/doctype/quiz_question/__init__.py b/erpnext/education/doctype/quiz_question/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/quiz_question/quiz_question.json b/erpnext/education/doctype/quiz_question/quiz_question.json new file mode 100644 index 0000000000..8cdb3e44af --- /dev/null +++ b/erpnext/education/doctype/quiz_question/quiz_question.json @@ -0,0 +1,76 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2018-10-17 06:13:00.098883", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "question_link", + "fieldtype": "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": "Question Link", + "length": 0, + "no_copy": 0, + "options": "Question", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + } + ], + "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-10-17 06:13:00.098883", + "modified_by": "Administrator", + "module": "Education", + "name": "Quiz Question", + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/quiz_question/quiz_question.py b/erpnext/education/doctype/quiz_question/quiz_question.py new file mode 100644 index 0000000000..317e75b2cb --- /dev/null +++ b/erpnext/education/doctype/quiz_question/quiz_question.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class QuizQuestion(Document): + pass diff --git a/erpnext/education/doctype/video/__init__.py b/erpnext/education/doctype/video/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/education/doctype/video/test_video.js b/erpnext/education/doctype/video/test_video.js new file mode 100644 index 0000000000..a82a221319 --- /dev/null +++ b/erpnext/education/doctype/video/test_video.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: Video", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new Video + () => frappe.tests.make('Video', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/erpnext/education/doctype/video/test_video.py b/erpnext/education/doctype/video/test_video.py new file mode 100644 index 0000000000..ecb09a2f9e --- /dev/null +++ b/erpnext/education/doctype/video/test_video.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors +# See license.txt +from __future__ import unicode_literals + +import frappe +import unittest + +class TestVideo(unittest.TestCase): + pass diff --git a/erpnext/education/doctype/video/video.js b/erpnext/education/doctype/video/video.js new file mode 100644 index 0000000000..c35c19b0c1 --- /dev/null +++ b/erpnext/education/doctype/video/video.js @@ -0,0 +1,8 @@ +// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +frappe.ui.form.on('Video', { + refresh: function(frm) { + + } +}); diff --git a/erpnext/education/doctype/video/video.json b/erpnext/education/doctype/video/video.json new file mode 100644 index 0000000000..d10f196872 --- /dev/null +++ b/erpnext/education/doctype/video/video.json @@ -0,0 +1,224 @@ +{ + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "field:title", + "beta": 0, + "creation": "2018-10-17 05:47:13.087395", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "title", + "fieldtype": "Data", + "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, + "label": "Title", + "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": 1 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "description", + "fieldtype": "Data", + "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, + "label": "Description", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "duration", + "fieldtype": "Data", + "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, + "label": "Duration", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "url", + "fieldtype": "Data", + "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, + "label": "URL", + "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 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "publish_date", + "fieldtype": "Date", + "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, + "label": "Publish Date", + "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 + } + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-10-17 06:57:00.219252", + "modified_by": "Administrator", + "module": "Education", + "name": "Video", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "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 +} \ No newline at end of file diff --git a/erpnext/education/doctype/video/video.py b/erpnext/education/doctype/video/video.py new file mode 100644 index 0000000000..b19f81258c --- /dev/null +++ b/erpnext/education/doctype/video/video.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class Video(Document): + + + def get_video(self): + pass From 541a522b26bc2c5fedf050fd63755fb7ee3dd1b5 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Thu, 18 Oct 2018 15:41:50 +0530 Subject: [PATCH 030/314] LMS:Added class methods for course, program and student doctypes Co-authored-by: Chinmay Pai --- erpnext/education/doctype/course/course.py | 15 ++++++++++++--- erpnext/education/doctype/program/program.py | 6 +++++- erpnext/education/doctype/student/student.py | 10 ++++++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/erpnext/education/doctype/course/course.py b/erpnext/education/doctype/course/course.py index 68d666c5d0..1e4270954d 100644 --- a/erpnext/education/doctype/course/course.py +++ b/erpnext/education/doctype/course/course.py @@ -19,7 +19,7 @@ class Course(Document): if total_weightage != 100: frappe.throw(_("Total Weightage of all Assessment Criteria must be 100%")) - def get_content_data(self, data): + def get_content_value(self, data): try: course_content_list = self.get_all_children() content_data = [frappe.get_value(course_content.content_type, course_content.content, data) for course_content in course_content_list] @@ -28,9 +28,18 @@ class Course(Document): return None return content_data + def get_content_info(self): + try: + course_content_list = self.get_all_children() + content_data = [[course_content.content_type, course_content.content] for course_content in course_content_list] + except Exception as e: + print(e) + return None + return content_data + def get_content_title(self): ''' returns all the course content for the given course object. ''' - content_title = self.get_content_data("title") - return content_title + content_title = self.get_content_value("title") + return content_title \ No newline at end of file diff --git a/erpnext/education/doctype/program/program.py b/erpnext/education/doctype/program/program.py index f626880b2a..38bdb8129b 100644 --- a/erpnext/education/doctype/program/program.py +++ b/erpnext/education/doctype/program/program.py @@ -7,4 +7,8 @@ import frappe from frappe.model.document import Document class Program(Document): - pass \ No newline at end of file + + def get_course_list(self): + course_content_list = self.get_all_children() + course_list = [frappe.get_doc("Course", course_item.course) for course_item in course_content_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 53bf6f7273..59c1a498e4 100644 --- a/erpnext/education/doctype/student/student.py +++ b/erpnext/education/doctype/student/student.py @@ -44,6 +44,16 @@ class Student(Document): if self.student_applicant: frappe.db.set_value("Student Applicant", self.student_applicant, "application_status", "Admitted") + def get_course_enrollments(self): + """Returns a list of course enrollments linked with the current student""" + enrollments_name_list = frappe.get_list("Course Enrollment", filters={"student": self.name}, fields=['name']) + if not enrollments_name_list: + frappe.throw("Student {0} has not enrolled in any course".format(self.name)) + return None + else: + enrollments= [frappe.get_doc("Course Enrollment", enrollment.name) for enrollment in enrollments_name_list] + return enrollments + def get_timeline_data(doctype, name): '''Return timeline for attendance''' return dict(frappe.db.sql('''select unix_timestamp(`date`), count(*) From 18baff5fecbd5e65e0ffa7ebb237453db638d544 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Thu, 18 Oct 2018 15:43:03 +0530 Subject: [PATCH 031/314] Minor changes to question doctype Co-authored-by: Chinmay Pai --- erpnext/config/education.py | 6 ++-- .../education/doctype/question/question.json | 8 ++--- .../doctype/quiz_question/quiz_question.json | 36 ++++++++++++++++++- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/erpnext/config/education.py b/erpnext/config/education.py index ba6aa888b6..96f660a971 100644 --- a/erpnext/config/education.py +++ b/erpnext/config/education.py @@ -193,15 +193,15 @@ def get_data(): }, { "type": "doctype", - "name": "Content" + "name": "Article" }, { "type": "doctype", - "name": "Question" + "name": "Video" }, { "type": "doctype", - "name": "Instructor" + "name": "Quiz" }, { "type": "doctype", diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json index c62d4a9aff..cca89cff50 100644 --- a/erpnext/education/doctype/question/question.json +++ b/erpnext/education/doctype/question/question.json @@ -16,20 +16,20 @@ "fields": [ { "allow_bulk_edit": 0, - "allow_in_quick_entry": 1, + "allow_in_quick_entry": 0, "allow_on_submit": 0, "bold": 0, "collapsible": 0, "columns": 0, "fieldname": "question", - "fieldtype": "Text", + "fieldtype": "Small Text", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_global_search": 0, "in_list_view": 1, - "in_standard_filter": 1, + "in_standard_filter": 0, "label": "Question", "length": 0, "no_copy": 0, @@ -91,7 +91,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-17 12:08:05.649254", + "modified": "2018-10-18 15:31:28.471650", "modified_by": "Administrator", "module": "Education", "name": "Question", diff --git a/erpnext/education/doctype/quiz_question/quiz_question.json b/erpnext/education/doctype/quiz_question/quiz_question.json index 8cdb3e44af..3857c5ca8d 100644 --- a/erpnext/education/doctype/quiz_question/quiz_question.json +++ b/erpnext/education/doctype/quiz_question/quiz_question.json @@ -45,6 +45,40 @@ "set_only_once": 0, "translatable": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "question_link.question", + "fieldname": "question", + "fieldtype": "Data", + "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": "Question", + "length": 0, + "no_copy": 0, + "options": "", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 } ], "has_web_view": 0, @@ -57,7 +91,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-10-17 06:13:00.098883", + "modified": "2018-10-18 15:35:12.195250", "modified_by": "Administrator", "module": "Education", "name": "Quiz Question", From 590227b107b11b767c00a8001b71d9c250f25096 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Thu, 18 Oct 2018 15:44:08 +0530 Subject: [PATCH 032/314] LMS: Fixed views for article and video --- erpnext/education/doctype/video/video.json | 4 +- erpnext/www/lms/course.html | 52 +++++++++---------- erpnext/www/lms/course.js | 2 +- erpnext/www/lms/course.py | 36 ++++++++----- erpnext/www/lms/program.html | 4 +- erpnext/www/lms/program.py | 7 ++- .../www/lms/templates/includes/article.html | 23 ++++---- .../www/lms/templates/includes/lms-nav.html | 6 +++ erpnext/www/lms/templates/includes/video.html | 19 +++---- 9 files changed, 80 insertions(+), 73 deletions(-) create mode 100644 erpnext/www/lms/templates/includes/lms-nav.html diff --git a/erpnext/education/doctype/video/video.json b/erpnext/education/doctype/video/video.json index d10f196872..d8c3368d93 100644 --- a/erpnext/education/doctype/video/video.json +++ b/erpnext/education/doctype/video/video.json @@ -54,7 +54,7 @@ "collapsible": 0, "columns": 0, "fieldname": "description", - "fieldtype": "Data", + "fieldtype": "Text Editor", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, @@ -185,7 +185,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-17 06:57:00.219252", + "modified": "2018-10-18 12:26:47.709081", "modified_by": "Administrator", "module": "Education", "name": "Video", diff --git a/erpnext/www/lms/course.html b/erpnext/www/lms/course.html index 5e2e393ffa..9896b017aa 100644 --- a/erpnext/www/lms/course.html +++ b/erpnext/www/lms/course.html @@ -1,45 +1,41 @@ {% extends "frappe_theme/templates/base.html" %} {% block title %}ERPNext Academy{% endblock %} - {% from "templates/includes/media.html" import media %} - {% block head_include %} {% endblock %} - {% block content %} -
-{% with quiz = quiz, current_content = current_content, next_content = next_content, course_name = course_name, program=current_program%} -{% include "www/lms/templates/includes/" + current_content.content_type.lower() + ".html" %} -{% endwith %} +
+ {% with content = current_content, next_content = next_content, course_name = course_name, program_name = program_name %} + {% include "www/lms/templates/includes/" + content_type.lower() + ".html" %} + {% endwith %}
- {% endblock %} \ No newline at end of file diff --git a/erpnext/www/lms/course.js b/erpnext/www/lms/course.js index e8f1dd5d0f..a25d00e471 100644 --- a/erpnext/www/lms/course.js +++ b/erpnext/www/lms/course.js @@ -34,4 +34,4 @@ function addActivity() { "program": $('#content-holder').data('program'), } }) -} \ No newline at end of file +} diff --git a/erpnext/www/lms/course.py b/erpnext/www/lms/course.py index 19e495fab3..9e874273ee 100644 --- a/erpnext/www/lms/course.py +++ b/erpnext/www/lms/course.py @@ -1,23 +1,31 @@ from __future__ import unicode_literals import erpnext.education.utils as utils +from urlparse import urlparse, parse_qs import frappe def get_context(context): if frappe.form_dict['course']: - context.current_content = frappe.get_doc("Content", frappe.form_dict["content"]) - context.course_name = frappe.form_dict["course"] - context.current_course = utils.get_contents_in_course(context.course_name) - context.current_program = frappe.form_dict["program"] - context.next_content = get_next_content(context) - if context.current_content.content_type == "Quiz": - context.questions = utils.get_quiz_as_dict(context.current_content.name) + # Save form_dict variables + program_name = frappe.form_dict["program"] + course_name = frappe.form_dict["course"] + content_name = frappe.form_dict["content"] + content_type = frappe.form_dict["type"] + # Get the required doctypes + current_course = frappe.get_doc("Course", course_name) + current_content = frappe.get_doc(content_type, content_name) -def get_next_content(context): - if context.current_course: - course_data = [content.name for content in context.current_course] - try: - return course_data[course_data.index(context.current_content.name) + 1] - except IndexError: - return None \ No newline at end of file + # Saving context variables for Jinja + context.current_content = current_content + context.course_name = course_name + context.program_name = program_name + context.content_type = content_type + context.next_content_type, context.next_content = get_next_content(content_name, content_type, current_course.get_content_info()) + +def get_next_content(c_name, c_type, content_list): + try: + next = content_list[content_list.index([c_type, c_name]) + 1] + return next[0], next[1] + except IndexError: + return None, None \ No newline at end of file diff --git a/erpnext/www/lms/program.html b/erpnext/www/lms/program.html index 5c1f15994c..00e13cb0ca 100644 --- a/erpnext/www/lms/program.html +++ b/erpnext/www/lms/program.html @@ -11,7 +11,7 @@
-
{{ course.name }}
+
{{ course.course_name }}
Course Content
    @@ -22,7 +22,7 @@
diff --git a/erpnext/www/lms/program.py b/erpnext/www/lms/program.py index c5bf018878..10bdd6b187 100644 --- a/erpnext/www/lms/program.py +++ b/erpnext/www/lms/program.py @@ -4,5 +4,8 @@ import frappe def get_context(context): - context.program = frappe.get_doc("Program", frappe.form_dict["program"]) - context.course_list = utils.get_courses_in_program(frappe.form_dict["program"]) \ No newline at end of file + program = frappe.get_doc("Program", frappe.form_dict["program"]) + course_list = program.get_course_list() + + context.program = program + context.course_list = course_list \ No newline at end of file diff --git a/erpnext/www/lms/templates/includes/article.html b/erpnext/www/lms/templates/includes/article.html index 2ca93fa43b..15835b816f 100644 --- a/erpnext/www/lms/templates/includes/article.html +++ b/erpnext/www/lms/templates/includes/article.html @@ -2,19 +2,15 @@
-

{{ current_content.name }}

+

{{ content.title }}

- 49 Mins - — Published on 28th October 2018. + Published on {{ content.publish_date }}, by {{ content.author }}
- Previous - {% if next_content != None %} - Next - {% else %} - Finish Course - {% endif %} + {% with next_content = next_content, course_name = course_name, program_name = program_name %} + {% include "www/lms/templates/includes/lms-nav.html" %} + {% endwith %}

@@ -23,11 +19,12 @@
- {{ current_content.article_content }} + {{ content.content }}
-
@@ -18,7 +18,10 @@ \ No newline at end of file diff --git a/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue b/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue index 2af1eaf117..35579896d1 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue @@ -1,5 +1,6 @@ \ No newline at end of file From 15012c08a4bcfd68f9313087da3d359f639dad6f Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 3 Nov 2018 18:03:01 +0530 Subject: [PATCH 070/314] UI Fixes --- .../components/AcademyCourseCardButton.vue | 1 - .../components/AcademyTopSection.vue | 7 ++--- .../components/AcademyTopSectionButton.vue | 27 +++++++++++++++---- .../web-academy/pages/AcademyHome.vue | 10 +++++-- .../web-academy/pages/AcademyProgramPage.vue | 8 ++++-- 5 files changed, 38 insertions(+), 15 deletions(-) diff --git a/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue b/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue index a6e6f56bd0..10e52e4ccf 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue @@ -13,7 +13,6 @@ export default { }, mounted() { if(this.$root.$data.checkCourseCompletion(this.course)){ - console.log('Completed', this.course) this.buttonName = 'Completed' this.className = 'btn-success' } diff --git a/erpnext/public/js/education/web-academy/components/AcademyTopSection.vue b/erpnext/public/js/education/web-academy/components/AcademyTopSection.vue index 8ef11133d8..abbce3a3ce 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyTopSection.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyTopSection.vue @@ -10,18 +10,15 @@

- +

\ No newline at end of file diff --git a/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue b/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue index 35579896d1..e1df97e79e 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue @@ -1,5 +1,5 @@ diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py index dd2a7d003d..a589b798e8 100644 --- a/erpnext/www/academy.py +++ b/erpnext/www/academy.py @@ -1,6 +1,5 @@ from __future__ import unicode_literals import frappe -import erpnext.education.utils as utils # Functions to get homepage details @frappe.whitelist(allow_guest=True) @@ -107,4 +106,42 @@ def evaluate_quiz(quiz_response, quiz_name): @frappe.whitelist() def get_completed_courses(): - return ['ECP-001', 'ECP-002'] \ No newline at end of file + return ['ECP-001', 'ECP-002'] + +@frappe.whitelist() +def get_continue_data(program_name): + program = frappe.get_doc("Program", program_name) + courses = program.get_all_children() + continue_data = get_starting_content(courses[0].course) + continue_data['course'] = courses[0].course + return continue_data + +def create_student(student_name=frappe.session.user): + student = frappe.get_doc({ + "doctype": "Student", + "first_name": student_name, + "student_email_id": student_name, + }) + student.save() + frappe.db.commit() + return student_name + +@frappe.whitelist() +def enroll(type, name, student_email_id): + if(not get_student_id(student_email_id)): + create_student(student_email_id) + student = frappe.get_doc("Student", get_student_id(student_email_id)) + if type == "Program": + student.enroll_in_program(name) + if type == "Course": + pass + +def get_student_id(email=None): + """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series). + + :param user: a user email address + """ + try: + return frappe.get_all('Student', filters={'student_email_id': email}, fields=['name'])[0].name + except IndexError: + return None \ No newline at end of file From 734d3e084c883f8d42b3dc49259a70d601e136ba Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 3 Nov 2018 18:03:35 +0530 Subject: [PATCH 072/314] Set home page for LMS User --- erpnext/hooks.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/erpnext/hooks.py b/erpnext/hooks.py index e527c588f0..63b897a354 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -11,6 +11,7 @@ app_email = "info@erpnext.com" app_license = "GNU General Public License (v3)" source_link = "https://github.com/frappe/erpnext" + develop_version = '12.x.x-develop' error_report_email = "support@erpnext.com" @@ -168,6 +169,10 @@ default_roles = [ {'role': 'Student', 'doctype':'Student', 'email_field': 'student_email_id'}, ] +role_home_page = { + "LMS User": "academy" +} + has_website_permission = { "Sales Order": "erpnext.controllers.website_list_for_contact.has_website_permission", "Quotation": "erpnext.controllers.website_list_for_contact.has_website_permission", From 91aa0e07c87b49a4aad558005444187a0987423f Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 3 Nov 2018 18:04:19 +0530 Subject: [PATCH 073/314] Added class function for student enrollment --- erpnext/education/doctype/student/student.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py index 59c1a498e4..d40f0cd813 100644 --- a/erpnext/education/doctype/student/student.py +++ b/erpnext/education/doctype/student/student.py @@ -54,6 +54,18 @@ class Student(Document): enrollments= [frappe.get_doc("Course Enrollment", enrollment.name) for enrollment in enrollments_name_list] return enrollments + def enroll_in_program(self, program_name): + enrollment = frappe.get_doc({ + "doctype": "Program Enrollment", + "student": self.name, + "academic_year": frappe.get_last_doc("Academic Year").name, + "program": program_name, + "enrollment_date": frappe.utils.datetime.datetime.now() + }) + enrollment.save() + enrollment.submit() + frappe.db.commit() + def get_timeline_data(doctype, name): '''Return timeline for attendance''' return dict(frappe.db.sql('''select unix_timestamp(`date`), count(*) From 73a31ec7bbdfbbdb5f36eeef8070045bbd961f8a Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 3 Nov 2018 19:31:53 +0530 Subject: [PATCH 074/314] Added functions to query Student enrollments --- erpnext/education/doctype/student/student.py | 37 ++++++++++++++++-- erpnext/www/academy.py | 40 ++++++++++++++++---- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py index d40f0cd813..f7bce3a5eb 100644 --- a/erpnext/education/doctype/student/student.py +++ b/erpnext/education/doctype/student/student.py @@ -46,14 +46,31 @@ class Student(Document): def get_course_enrollments(self): """Returns a list of course enrollments linked with the current student""" - enrollments_name_list = frappe.get_list("Course Enrollment", filters={"student": self.name}, fields=['name']) - if not enrollments_name_list: - frappe.throw("Student {0} has not enrolled in any course".format(self.name)) + course_enrollments = frappe.get_list("Course Enrollment", filters={"student": self.name}, fields=['name']) + if not course_enrollments: return None else: - enrollments= [frappe.get_doc("Course Enrollment", enrollment.name) for enrollment in enrollments_name_list] + enrollments = [item['name'] for item in course_enrollments] return enrollments + def get_program_enrollments(self): + """Returns a list of course enrollments linked with the current student""" + program_enrollments = frappe.get_list("Program Enrollment", filters={"student": self.name}, fields=['program']) + if not program_enrollments: + return None + else: + enrollments = [item['program'] for item in program_enrollments] + return enrollments + + def get_completed_courses(self): + """Returns a list of course enrollments linked with the current student""" + completed_courses = frappe.get_list("Course Enrollment", filters={"student": self.name, "completed":1}, fields=['course']) + if not completed_courses: + return None + else: + courses = [item['course'] for item in completed_courses] + return courses + def enroll_in_program(self, program_name): enrollment = frappe.get_doc({ "doctype": "Program Enrollment", @@ -65,6 +82,18 @@ class Student(Document): enrollment.save() enrollment.submit() frappe.db.commit() + return enrollment + + def enroll_in_course(self, course_name, program_enrollment, enrollment_date=frappe.utils.datetime.datetime.now()): + enrollment = frappe.get_doc({ + "doctype": "Course Enrollment", + "student": self.name, + "course": course_name, + "program_enrollment": program_enrollment, + "enrollment_date": enrollment_date + }) + enrollment.save() + frappe.db.commit() def get_timeline_data(doctype, name): '''Return timeline for attendance''' diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py index a589b798e8..66874c62e5 100644 --- a/erpnext/www/academy.py +++ b/erpnext/www/academy.py @@ -105,8 +105,13 @@ def evaluate_quiz(quiz_response, quiz_name): # return None @frappe.whitelist() -def get_completed_courses(): - return ['ECP-001', 'ECP-002'] +def get_completed_courses(email=frappe.session.user): + try: + print(email) + student = frappe.get_doc("Student", get_student_id(email)) + return student.get_completed_courses() + except: + return None @frappe.whitelist() def get_continue_data(program_name): @@ -127,15 +132,20 @@ def create_student(student_name=frappe.session.user): return student_name @frappe.whitelist() -def enroll(type, name, student_email_id): +def enroll_all_courses_in_program(program_enrollment, student): + course_list = [course.name for course in get_courses(program_enrollment.program)] + for course_name in course_list: + student.enroll_in_course(course_name=course_name, program_enrollment=program_enrollment.name) + +@frappe.whitelist() +def enroll_in_program(program_name, student_email_id): if(not get_student_id(student_email_id)): create_student(student_email_id) student = frappe.get_doc("Student", get_student_id(student_email_id)) - if type == "Program": - student.enroll_in_program(name) - if type == "Course": - pass + program_enrollment = student.enroll_in_program(program_name) + enroll_all_courses_in_program(program_enrollment, student) +@frappe.whitelist() def get_student_id(email=None): """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series). @@ -144,4 +154,20 @@ def get_student_id(email=None): try: return frappe.get_all('Student', filters={'student_email_id': email}, fields=['name'])[0].name except IndexError: + return None + +@frappe.whitelist() +def get_program_enrollments(email=frappe.session.user): + try: + student = frappe.get_doc("Student", get_student_id(email)) + return student.get_program_enrollments() + except: + return None + +@frappe.whitelist() +def get_course_enrollments(email=frappe.session.user): + try: + student = frappe.get_doc("Student", get_student_id(email)) + return student.get_course_enrollments() + except: return None \ No newline at end of file From 90722e3a9b5cc131dedc6abb539ca4d57b6c9ad3 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 3 Nov 2018 19:32:29 +0530 Subject: [PATCH 075/314] Fixed Permissions for LMS User --- .../education/doctype/program/program.json | 22 ++++++++++++++++++- .../program_enrollment.json | 22 ++++++++++++++++++- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/erpnext/education/doctype/program/program.json b/erpnext/education/doctype/program/program.json index 492c568748..b2777afc7c 100644 --- a/erpnext/education/doctype/program/program.json +++ b/erpnext/education/doctype/program/program.json @@ -476,7 +476,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-11-01 18:05:06.781030", + "modified": "2018-11-03 13:03:08.480261", "modified_by": "Administrator", "module": "Education", "name": "Program", @@ -501,12 +501,32 @@ "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Guest", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 0, "read_only": 0, "read_only_onload": 0, "restrict_to_domain": "Education", + "route": "", "search_fields": "program_name", "show_name_in_global_search": 1, "sort_field": "modified", diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.json b/erpnext/education/doctype/program_enrollment/program_enrollment.json index 5f4621f368..6e1a0c34fd 100644 --- a/erpnext/education/doctype/program_enrollment/program_enrollment.json +++ b/erpnext/education/doctype/program_enrollment/program_enrollment.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 1, "allow_rename": 0, @@ -714,7 +715,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-08-21 16:15:35.014952", + "modified": "2018-11-03 17:52:44.017627", "modified_by": "Administrator", "module": "Education", "name": "Program Enrollment", @@ -739,6 +740,25 @@ "share": 1, "submit": 1, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 1, + "write": 1 } ], "quick_entry": 0, From a054655442edfec08d41abf7cec1a46bc6eb4250 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 3 Nov 2018 19:33:04 +0530 Subject: [PATCH 076/314] Updated state functions for session management --- erpnext/public/js/education/web-academy.js | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/erpnext/public/js/education/web-academy.js b/erpnext/public/js/education/web-academy.js index 2d6a1b909d..282a5883d5 100644 --- a/erpnext/public/js/education/web-academy.js +++ b/erpnext/public/js/education/web-academy.js @@ -20,6 +20,7 @@ var store = { state: { completedCourses: new Set(), enrolledPrograms: new Set(), + enrolledCourses: new Set(), currentEnrollment: '', student: '', isLogin: false @@ -48,10 +49,29 @@ var store = { return this.state.enrolledPrograms.has(programName) }, + updateEnrolledPrograms (){ + if (this.debug) console.log('Updating enrolledPrograms') + frappe.call("erpnext.www.academy.get_program_enrollments").then( r => { + for(var ii=0; ii < r.message.length; ii++){ + this.state.enrolledPrograms.add(r.message[ii]) + } + }) + if (this.debug) console.log('Updated State', this.state.enrolledPrograms) + }, + + updateEnrolledCourses (){ + if (this.debug) console.log('Updating enrolledCourses') + frappe.call("erpnext.www.academy.get_course_enrollments").then( r => { + for(var ii=0; ii < r.message.length; ii++){ + this.state.enrolledCourses.add(r.message[ii]) + } + }) + if (this.debug) console.log('Updated State', this.state.enrolledCourses) + }, + updateCompletedCourses (){ if (this.debug) console.log('Updating States') frappe.call("erpnext.www.academy.get_completed_courses").then( r => { - this.state.completedCourses.clear() for(var ii=0; ii < r.message.length; ii++){ this.state.completedCourses.add(r.message[ii]) } @@ -73,6 +93,8 @@ var store = { updateState (){ this.updateCompletedCourses() + this.updateEnrolledPrograms() + this.updateEnrolledCourses() this.checkLogin() }, From ed5892c7a51a6747cf052d40c231f7d962a1d661 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 3 Nov 2018 19:33:51 +0530 Subject: [PATCH 077/314] UI: Components rendered based on student progress --- .../web-academy/components/AcademyProgramCard.vue | 8 ++++---- .../js/education/web-academy/pages/AcademyProgramPage.vue | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue b/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue index 9b33a983ee..99320793c1 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue @@ -10,7 +10,8 @@
@@ -37,10 +38,9 @@ export default { methods: { enroll() { frappe.call({ - method: "erpnext.www.academy.enroll", + method: "erpnext.www.academy.enroll_in_program", args:{ - type: "Program", - name: this.program_code, + program_name: this.program_code, student_email_id: frappe.session.user } }) diff --git a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue b/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue index 560aee5142..c5a1751098 100644 --- a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue +++ b/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue @@ -30,6 +30,7 @@ export default { } }, mounted() { + this.$root.$data.updateCompletedCourses() frappe.call({ method: "erpnext.www.academy.get_program_details", args: { From 7d5e218155a4479cd4c872ebf5498680855666f5 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 3 Nov 2018 19:34:27 +0530 Subject: [PATCH 078/314] Modified Quiz Evaluation --- erpnext/education/doctype/quiz/quiz.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/education/doctype/quiz/quiz.py b/erpnext/education/doctype/quiz/quiz.py index fdff16de02..a1cc36d9e4 100644 --- a/erpnext/education/doctype/quiz/quiz.py +++ b/erpnext/education/doctype/quiz/quiz.py @@ -23,8 +23,8 @@ class Quiz(Document): pass - def evaluate(self, response_dict, enrollment, quiz_name): - self.validate_quiz_attempts(enrollment, quiz_name) + def evaluate(self, response_dict, quiz_name): + # self.validate_quiz_attempts(enrollment, quiz_name) self.get_questions() answers = {q.name:q.get_answer() for q in self.get_questions()} correct_answers = {question: (answers[question] == response_dict[question]) for question in response_dict.keys()} From 1a04f774d7d8467c5d206cc1c9ac7ca193d93ba1 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 3 Nov 2018 20:43:59 +0530 Subject: [PATCH 079/314] LMS: Saving Course Activity --- erpnext/education/doctype/student/student.py | 4 +- erpnext/public/js/education/web-academy.js | 47 +++++++------------ .../components/ContentNavigation.vue | 17 ++++++- erpnext/www/academy.py | 14 +++++- 4 files changed, 48 insertions(+), 34 deletions(-) diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py index f7bce3a5eb..69959ea784 100644 --- a/erpnext/education/doctype/student/student.py +++ b/erpnext/education/doctype/student/student.py @@ -46,11 +46,11 @@ class Student(Document): def get_course_enrollments(self): """Returns a list of course enrollments linked with the current student""" - course_enrollments = frappe.get_list("Course Enrollment", filters={"student": self.name}, fields=['name']) + course_enrollments = frappe.get_list("Course Enrollment", filters={"student": self.name}, fields=['course', 'name']) if not course_enrollments: return None else: - enrollments = [item['name'] for item in course_enrollments] + enrollments = {item['course']:item['name'] for item in course_enrollments} return enrollments def get_program_enrollments(self): diff --git a/erpnext/public/js/education/web-academy.js b/erpnext/public/js/education/web-academy.js index 282a5883d5..8608680648 100644 --- a/erpnext/public/js/education/web-academy.js +++ b/erpnext/public/js/education/web-academy.js @@ -17,66 +17,55 @@ const routes = [ var store = { debug: true, - state: { - completedCourses: new Set(), - enrolledPrograms: new Set(), - enrolledCourses: new Set(), - currentEnrollment: '', - student: '', - isLogin: false - }, - - setCurrentEnrollment (enrollment) { - if (this.debug) console.log('setCourseEnrollment triggered with', enrollment) - this.state.currentEnrollment = enrollment - }, - - getCurrentEnrollment () { - if (this.debug) console.log('getCourseEnrollment triggered') - return this.state.currentEnrollment - }, + isLogin: false, + completedCourses: new Set(), + enrolledPrograms: new Set(), + enrolledCourses: {}, addCompletedCourses (courseName){ if (this.debug) console.log('addCompletedCourses triggered with', courseName) - this.state.completedCourses.add(courseName) + this.completedCourses.add(courseName) }, checkCourseCompletion (courseName){ - return this.state.completedCourses.has(courseName) + return this.completedCourses.has(courseName) }, checkProgramEnrollment (programName){ - return this.state.enrolledPrograms.has(programName) + return this.enrolledPrograms.has(programName) + }, + + checkCourseEnrollment (courseName){ + course = new Set(Object.keys(enrolledCourses)) + return course.has(courseName) }, updateEnrolledPrograms (){ if (this.debug) console.log('Updating enrolledPrograms') frappe.call("erpnext.www.academy.get_program_enrollments").then( r => { for(var ii=0; ii < r.message.length; ii++){ - this.state.enrolledPrograms.add(r.message[ii]) + this.enrolledPrograms.add(r.message[ii]) } }) - if (this.debug) console.log('Updated State', this.state.enrolledPrograms) + if (this.debug) console.log('Updated State', this.enrolledPrograms) }, updateEnrolledCourses (){ if (this.debug) console.log('Updating enrolledCourses') frappe.call("erpnext.www.academy.get_course_enrollments").then( r => { - for(var ii=0; ii < r.message.length; ii++){ - this.state.enrolledCourses.add(r.message[ii]) - } + this.enrolledCourses = r.message }) - if (this.debug) console.log('Updated State', this.state.enrolledCourses) + if (this.debug) console.log('Updated State', this.enrolledCourses) }, updateCompletedCourses (){ if (this.debug) console.log('Updating States') frappe.call("erpnext.www.academy.get_completed_courses").then( r => { for(var ii=0; ii < r.message.length; ii++){ - this.state.completedCourses.add(r.message[ii]) + this.completedCourses.add(r.message[ii]) } }) - if (this.debug) console.log('Updated State', this.state.completedCourses) + if (this.debug) console.log('Updated State', this.completedCourses) }, checkLogin (){ diff --git a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue index 87db221452..a281f14fb9 100644 --- a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue +++ b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue @@ -1,7 +1,7 @@ @@ -9,7 +9,20 @@ diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py index 66874c62e5..9162b71136 100644 --- a/erpnext/www/academy.py +++ b/erpnext/www/academy.py @@ -170,4 +170,16 @@ def get_course_enrollments(email=frappe.session.user): student = frappe.get_doc("Student", get_student_id(email)) return student.get_course_enrollments() except: - return None \ No newline at end of file + return None + +@frappe.whitelist() +def add_activity(enrollment, content_type, content): + activity = frappe.get_doc({ + "doctype": "Course Activity", + "enrollment": enrollment, + "content_type": content_type, + "content": content, + "activity_date": frappe.utils.datetime.datetime.now() + }) + activity.save() + frappe.db.commit() \ No newline at end of file From 6de9cbb52d42fabfca4a67581a2a2f2016dca6dc Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 11:01:05 +0530 Subject: [PATCH 080/314] Solved minor issue (Last activity not being saved) --- .../web-academy/components/ContentNavigation.vue | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue index a281f14fb9..61e3988c58 100644 --- a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue +++ b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue @@ -2,7 +2,7 @@ @@ -21,6 +21,19 @@ export default { } }) this.$router.push({ name: 'content', params: { course: this.$route.params.course, type:this.nextContentType, content:this.nextContent }}) + }, + finish() { + if(this.$route.params.type != "Quiz"){ + frappe.call({ + method: "erpnext.www.academy.add_activity", + args: { + enrollment: this.$root.$data.enrolledCourses[this.$route.params.course], + content_type: this.$route.params.type, + content: this.$route.params.content + } + }) + } + this.$router.push({ name: 'program', params: { code: this.$route.params.code}}) } } }; From 1f4835b3b450e67b8dd74683fbd75785a5c48c57 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 11:01:27 +0530 Subject: [PATCH 081/314] Added Video UI --- .../web-academy/components/ContentVideo.vue | 69 +++++++++++++++---- 1 file changed, 54 insertions(+), 15 deletions(-) diff --git a/erpnext/public/js/education/web-academy/components/ContentVideo.vue b/erpnext/public/js/education/web-academy/components/ContentVideo.vue index 4fd0b773d1..e3dbad7d14 100644 --- a/erpnext/public/js/education/web-academy/components/ContentVideo.vue +++ b/erpnext/public/js/education/web-academy/components/ContentVideo.vue @@ -1,21 +1,60 @@ - - - From cfce153ed4220f72a139da11328226fdda067449 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 11:01:37 +0530 Subject: [PATCH 082/314] Minor UI changes --- .../education/web-academy/components/AcademyCourseCard.vue | 2 +- .../education/web-academy/components/AcademyProgramCard.vue | 5 +++-- .../js/education/web-academy/pages/AcademyProgramPage.vue | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue b/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue index 4110cd9d1c..426b9877cb 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue @@ -11,7 +11,7 @@
-
+
diff --git a/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue b/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue index 99320793c1..6ddf152a49 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue @@ -10,8 +10,9 @@ diff --git a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue b/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue index c5a1751098..b357302146 100644 --- a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue +++ b/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue @@ -30,7 +30,7 @@ export default { } }, mounted() { - this.$root.$data.updateCompletedCourses() + if(this.$root.$data.isLogin) this.$root.$data.updateCompletedCourses() frappe.call({ method: "erpnext.www.academy.get_program_details", args: { From a3afe2a998e93750189c59d94fff2ad7ca4aa043 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 11:01:54 +0530 Subject: [PATCH 083/314] Sending session data explicitly --- erpnext/public/js/education/web-academy.js | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/erpnext/public/js/education/web-academy.js b/erpnext/public/js/education/web-academy.js index 8608680648..e6b48ecb28 100644 --- a/erpnext/public/js/education/web-academy.js +++ b/erpnext/public/js/education/web-academy.js @@ -42,7 +42,12 @@ var store = { updateEnrolledPrograms (){ if (this.debug) console.log('Updating enrolledPrograms') - frappe.call("erpnext.www.academy.get_program_enrollments").then( r => { + frappe.call({ + method: "erpnext.www.academy.get_program_enrollments", + args:{ + email: frappe.session.user + } + }).then( r => { for(var ii=0; ii < r.message.length; ii++){ this.enrolledPrograms.add(r.message[ii]) } @@ -52,7 +57,12 @@ var store = { updateEnrolledCourses (){ if (this.debug) console.log('Updating enrolledCourses') - frappe.call("erpnext.www.academy.get_course_enrollments").then( r => { + frappe.call({ + method: "erpnext.www.academy.get_course_enrollments", + args:{ + email: frappe.session.user + } + }).then( r => { this.enrolledCourses = r.message }) if (this.debug) console.log('Updated State', this.enrolledCourses) @@ -60,7 +70,12 @@ var store = { updateCompletedCourses (){ if (this.debug) console.log('Updating States') - frappe.call("erpnext.www.academy.get_completed_courses").then( r => { + frappe.call({ + method: "erpnext.www.academy.get_completed_courses", + args:{ + email: frappe.session.user + } + }).then( r => { for(var ii=0; ii < r.message.length; ii++){ this.completedCourses.add(r.message[ii]) } From 76222f7acc832e816617da4ba7fbbb6944f4d33e Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 11:02:14 +0530 Subject: [PATCH 084/314] Modified add-activity, no duplicates will be saved now --- erpnext/www/academy.py | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py index 9162b71136..339830dbe6 100644 --- a/erpnext/www/academy.py +++ b/erpnext/www/academy.py @@ -106,8 +106,8 @@ def evaluate_quiz(quiz_response, quiz_name): @frappe.whitelist() def get_completed_courses(email=frappe.session.user): + print("Get completed course ", email) try: - print(email) student = frappe.get_doc("Student", get_student_id(email)) return student.get_completed_courses() except: @@ -174,12 +174,26 @@ def get_course_enrollments(email=frappe.session.user): @frappe.whitelist() def add_activity(enrollment, content_type, content): - activity = frappe.get_doc({ - "doctype": "Course Activity", - "enrollment": enrollment, - "content_type": content_type, - "content": content, - "activity_date": frappe.utils.datetime.datetime.now() - }) - activity.save() - frappe.db.commit() \ No newline at end of file + if(check_activity_exists(enrollment, content_type, content)): + pass + else: + activity = frappe.get_doc({ + "doctype": "Course Activity", + "enrollment": enrollment, + "content_type": content_type, + "content": content, + "activity_date": frappe.utils.datetime.datetime.now() + }) + activity.save() + frappe.db.commit() + +def check_activity_exists(enrollment, content_type, content): + activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content}) + if activity: + return True + else: + return False + +@frappe.whitelist() +def add_quiz_activity(enrollment, quiz, score, answers): + pass \ No newline at end of file From 0187b18c06900f772d8dfb223378a69e4e5bdcbd Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 12:16:02 +0530 Subject: [PATCH 085/314] Added methods to saving Quiz attempts --- erpnext/education/doctype/quiz/quiz.py | 15 +++++- .../web-academy/components/ContentQuiz.vue | 1 + erpnext/www/academy.py | 53 ++++++++++++------- 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/erpnext/education/doctype/quiz/quiz.py b/erpnext/education/doctype/quiz/quiz.py index a1cc36d9e4..232ee0e9ad 100644 --- a/erpnext/education/doctype/quiz/quiz.py +++ b/erpnext/education/doctype/quiz/quiz.py @@ -27,8 +27,19 @@ class Quiz(Document): # self.validate_quiz_attempts(enrollment, quiz_name) self.get_questions() answers = {q.name:q.get_answer() for q in self.get_questions()} - correct_answers = {question: (answers[question] == response_dict[question]) for question in response_dict.keys()} - return correct_answers, (sum(correct_answers.values()) * 100 ) / len(answers) + correct_answers = {} + for key in answers: + try: + result = (response_dict[key] == answers[key]) + except: + result = False + correct_answers[key] = result + score = (sum(correct_answers.values()) * 100 ) / len(answers) + if score >= self.passing_score: + status = "Pass" + else: + status = "Fail" + return correct_answers, score, status def get_questions(self): diff --git a/erpnext/public/js/education/web-academy/components/ContentQuiz.vue b/erpnext/public/js/education/web-academy/components/ContentQuiz.vue index e2ea31ed06..7044d76494 100644 --- a/erpnext/public/js/education/web-academy/components/ContentQuiz.vue +++ b/erpnext/public/js/education/web-academy/components/ContentQuiz.vue @@ -72,6 +72,7 @@ export default { frappe.call({ method: "erpnext.www.academy.evaluate_quiz", args: { + enrollment: this.$root.$data.enrolledCourses[this.$route.params.course], quiz_response: this.quizResponse, quiz_name: this.content } diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py index 339830dbe6..69faeba85d 100644 --- a/erpnext/www/academy.py +++ b/erpnext/www/academy.py @@ -81,7 +81,7 @@ def get_quiz_without_answers(quiz_name): return None @frappe.whitelist() -def evaluate_quiz(quiz_response, quiz_name): +def evaluate_quiz(enrollment, quiz_response, quiz_name): """LMS Function: Evaluates a simple multiple choice quiz. @@ -89,20 +89,27 @@ def evaluate_quiz(quiz_response, quiz_name): """ import json quiz_response = json.loads(quiz_response) + print(quiz_response) quiz = frappe.get_doc("Quiz", quiz_name) - answers, score = quiz.evaluate(quiz_response, quiz_name) + answers, score, status = quiz.evaluate(quiz_response, quiz_name) + print("-----------------") + print(answers) + + result = {k: ('Correct' if v else 'Wrong') for k,v in answers.items()} + result_data = [] + for key in answers: + item = {} + item['question'] = key + item['quiz_result'] = result[key] + try: + item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option') + except: + item['selected_option'] = "Unattempted" + result_data.append(item) + # result_data = [{'question': key, 'selected_option': frappe.get_value('Options', quiz_response[key], 'option'), 'quiz_result': result[key]} for key in answers] + + add_quiz_activity(enrollment, quiz_name, result_data, score, status) return(score) - # quiz_name = kwargs.get('quiz') - # course_name = kwargs.get('course') - # enrollment = get_course_enrollment(course_name, frappe.session.user) - # try: - # quiz = frappe.get_doc("Quiz", quiz_name) - # answers, score = quiz.evaluate(quiz_response, enrollment, quiz_name) - # add_quiz_activity(enrollment, quiz_name, score, answers, quiz_response) - # return score - # except frappe.DoesNotExistError: - # frappe.throw("Quiz {0} does not exist".format(quiz_name)) - # return None @frappe.whitelist() def get_completed_courses(email=frappe.session.user): @@ -189,11 +196,17 @@ def add_activity(enrollment, content_type, content): def check_activity_exists(enrollment, content_type, content): activity = frappe.get_all("Course Activity", filters={'enrollment': enrollment, 'content_type': content_type, 'content': content}) - if activity: - return True - else: - return False + return bool(activity) -@frappe.whitelist() -def add_quiz_activity(enrollment, quiz, score, answers): - pass \ No newline at end of file +def add_quiz_activity(enrollment, quiz_name, result_data, score, status): + quiz_activity = frappe.get_doc({ + "doctype": "Quiz Activity", + "enrollment": enrollment, + "quiz": quiz_name, + "result": result_data, + "score": score, + "status": status + }) + quiz_activity.save() + print(quiz_activity) + frappe.db.commit() \ No newline at end of file From a920bca044db6dfb342861e29c5e845081e10da2 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 12:30:32 +0530 Subject: [PATCH 086/314] Minor UI fixes --- .../js/education/web-academy/components/ContentNavigation.vue | 4 ++-- .../js/education/web-academy/pages/AcademyCoursePage.vue | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue index 61e3988c58..738dcd9996 100644 --- a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue +++ b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue @@ -1,8 +1,8 @@ diff --git a/erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue b/erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue index ca5434b765..4149f4d10e 100644 --- a/erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue +++ b/erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue @@ -16,7 +16,7 @@ export default { name: "AcademyCoursePage", data() { return{ - nextContent: '', + nextContent: true, nextContentType: '', } }, From 25e42baeafe7e5d815b426b0383f3d704c36ee45 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 13:11:37 +0530 Subject: [PATCH 087/314] Course completion logic complete --- .../components/AcademyCourseCardButton.vue | 22 +++++++++++---- .../components/ContentNavigation.vue | 28 ++++++++++++------- .../web-academy/pages/AcademyCoursePage.vue | 2 +- erpnext/www/academy.py | 14 ++++++---- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue b/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue index 10e52e4ccf..7ff7a6e33c 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue index 738dcd9996..1ea5fca150 100644 --- a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue +++ b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue @@ -1,8 +1,8 @@ @@ -12,14 +12,16 @@ export default { name: 'ContentNavigation', methods: { goNext() { - frappe.call({ - method: "erpnext.www.academy.add_activity", - args: { - enrollment: this.$root.$data.enrolledCourses[this.$route.params.course], - content_type: this.$route.params.type, - content: this.$route.params.content - } - }) + if(this.$route.params.type != "Quiz"){ + frappe.call({ + method: "erpnext.www.academy.add_activity", + args: { + enrollment: this.$root.$data.enrolledCourses[this.$route.params.course], + content_type: this.$route.params.type, + content: this.$route.params.content + } + }) + } this.$router.push({ name: 'content', params: { course: this.$route.params.course, type:this.nextContentType, content:this.nextContent }}) }, finish() { @@ -33,6 +35,12 @@ export default { } }) } + frappe.call({ + method: "erpnext.www.academy.mark_course_complete", + args: { + enrollment: this.$root.$data.enrolledCourses[this.$route.params.course] + } + }) this.$router.push({ name: 'program', params: { code: this.$route.params.code}}) } } diff --git a/erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue b/erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue index 4149f4d10e..ca5434b765 100644 --- a/erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue +++ b/erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue @@ -16,7 +16,7 @@ export default { name: "AcademyCoursePage", data() { return{ - nextContent: true, + nextContent: '', nextContentType: '', } }, diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py index 69faeba85d..d68dee43c5 100644 --- a/erpnext/www/academy.py +++ b/erpnext/www/academy.py @@ -89,11 +89,8 @@ def evaluate_quiz(enrollment, quiz_response, quiz_name): """ import json quiz_response = json.loads(quiz_response) - print(quiz_response) quiz = frappe.get_doc("Quiz", quiz_name) answers, score, status = quiz.evaluate(quiz_response, quiz_name) - print("-----------------") - print(answers) result = {k: ('Correct' if v else 'Wrong') for k,v in answers.items()} result_data = [] @@ -113,7 +110,6 @@ def evaluate_quiz(enrollment, quiz_response, quiz_name): @frappe.whitelist() def get_completed_courses(email=frappe.session.user): - print("Get completed course ", email) try: student = frappe.get_doc("Student", get_student_id(email)) return student.get_completed_courses() @@ -208,5 +204,11 @@ def add_quiz_activity(enrollment, quiz_name, result_data, score, status): "status": status }) quiz_activity.save() - print(quiz_activity) - frappe.db.commit() \ No newline at end of file + frappe.db.commit() + +@frappe.whitelist() +def mark_course_complete(enrollment): + course_enrollment = frappe.get_doc("Course Enrollment", enrollment) + course_enrollment.completed = True + course_enrollment.save() + frappe.db.commit() From 5611bf4e299f1582c750f59c32c2bd14bba12704 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 13:20:16 +0530 Subject: [PATCH 088/314] Minor change --- erpnext/public/js/education/web-academy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/education/web-academy.js b/erpnext/public/js/education/web-academy.js index e6b48ecb28..3dfd0f2385 100644 --- a/erpnext/public/js/education/web-academy.js +++ b/erpnext/public/js/education/web-academy.js @@ -16,7 +16,7 @@ const routes = [ ]; var store = { - debug: true, + debug: false, isLogin: false, completedCourses: new Set(), enrolledPrograms: new Set(), From 86897b3cc8824f207f35337587f2207e138c0952 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 5 Nov 2018 14:54:40 +0530 Subject: [PATCH 089/314] UI: Kinda fixed "Completed" button render issue --- .../web-academy/components/AcademyCourseCardButton.vue | 3 --- .../education/web-academy/components/ContentNavigation.vue | 2 ++ .../js/education/web-academy/pages/AcademyProgramPage.vue | 5 ++++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue b/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue index 7ff7a6e33c..b0d8859b6e 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue @@ -11,9 +11,6 @@ export default { className: 'btn-primary' } }, - mounted() { - this.$root.$data.updateCompletedCourses() - } computed: { getButtonName: function() { if(this.$root.$data.checkCourseCompletion(this.course)){ diff --git a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue index 1ea5fca150..28f5a70b76 100644 --- a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue +++ b/erpnext/public/js/education/web-academy/components/ContentNavigation.vue @@ -41,6 +41,8 @@ export default { enrollment: this.$root.$data.enrolledCourses[this.$route.params.course] } }) + this.$root.$data.addCompletedCourses(this.$route.params.course) + this.$root.$data.updateCompletedCourses() this.$router.push({ name: 'program', params: { code: this.$route.params.code}}) } } diff --git a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue b/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue index b357302146..ef4545936e 100644 --- a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue +++ b/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue @@ -29,8 +29,11 @@ export default { course_list: [] } }, - mounted() { + beforeMount(){ + console.log("Before Mount") if(this.$root.$data.isLogin) this.$root.$data.updateCompletedCourses() + }, + mounted() { frappe.call({ method: "erpnext.www.academy.get_program_details", args: { From 9f316a3b3038a7188fb72ce1840671181cc12449 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 6 Nov 2018 11:25:52 +0530 Subject: [PATCH 090/314] Permission changes --- erpnext/education/doctype/course/course.json | 21 ++++++++++++++++++- .../education/doctype/program/program.json | 21 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/erpnext/education/doctype/course/course.json b/erpnext/education/doctype/course/course.json index 00a408ee22..148077877c 100644 --- a/erpnext/education/doctype/course/course.json +++ b/erpnext/education/doctype/course/course.json @@ -478,7 +478,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-10-16 13:03:09.310985", + "modified": "2018-10-19 13:03:09.310985", "modified_by": "Administrator", "module": "Education", "name": "Course", @@ -522,6 +522,25 @@ "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 } ], "quick_entry": 0, diff --git a/erpnext/education/doctype/program/program.json b/erpnext/education/doctype/program/program.json index b2777afc7c..4628da801e 100644 --- a/erpnext/education/doctype/program/program.json +++ b/erpnext/education/doctype/program/program.json @@ -476,7 +476,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-11-03 13:03:08.480261", + "modified": "2018-11-05 18:59:59.784033", "modified_by": "Administrator", "module": "Education", "name": "Program", @@ -520,6 +520,25 @@ "share": 1, "submit": 0, "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 } ], "quick_entry": 0, From 850dfd0358e5f92cec29963e6ac65b07d2ffc77c Mon Sep 17 00:00:00 2001 From: scmmishra Date: Wed, 7 Nov 2018 22:12:31 +0530 Subject: [PATCH 091/314] Set appropriate permissions --- .../education/doctype/article/article.json | 42 +++++++++++++++- .../education/doctype/content/content.json | 23 ++++++++- erpnext/education/doctype/course/course.json | 14 +++--- .../course_activity/course_activity.json | 23 ++++++++- .../course_enrollment/course_enrollment.json | 23 ++++++++- .../education/doctype/program/program.json | 48 +++++++++++++++++-- .../program_enrollment.json | 2 +- .../education/doctype/question/question.json | 42 +++++++++++++++- erpnext/education/doctype/quiz/quiz.json | 23 ++++++++- .../doctype/quiz_activity/quiz_activity.json | 23 ++++++++- .../education/doctype/student/student.json | 21 +++++++- erpnext/education/doctype/video/video.json | 42 +++++++++++++++- 12 files changed, 296 insertions(+), 30 deletions(-) diff --git a/erpnext/education/doctype/article/article.json b/erpnext/education/doctype/article/article.json index e879731160..0fdeeef918 100644 --- a/erpnext/education/doctype/article/article.json +++ b/erpnext/education/doctype/article/article.json @@ -153,7 +153,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-17 06:56:50.621421", + "modified": "2018-11-07 21:19:29.051716", "modified_by": "Administrator", "module": "Education", "name": "Article", @@ -173,11 +173,49 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "Academics User", "set_user_permissions": 0, "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 1, diff --git a/erpnext/education/doctype/content/content.json b/erpnext/education/doctype/content/content.json index 053372ff21..fa7fe577a2 100644 --- a/erpnext/education/doctype/content/content.json +++ b/erpnext/education/doctype/content/content.json @@ -515,7 +515,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-16 15:50:59.193504", + "modified": "2018-11-07 21:20:03.136554", "modified_by": "Administrator", "module": "Education", "name": "Content", @@ -535,7 +535,7 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "Instructor", "set_user_permissions": 0, "share": 1, "submit": 0, @@ -559,6 +559,25 @@ "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 0, diff --git a/erpnext/education/doctype/course/course.json b/erpnext/education/doctype/course/course.json index 148077877c..c145b2d7d7 100644 --- a/erpnext/education/doctype/course/course.json +++ b/erpnext/education/doctype/course/course.json @@ -478,7 +478,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-10-19 13:03:09.310985", + "modified": "2018-11-07 21:20:21.941865", "modified_by": "Administrator", "module": "Education", "name": "Course", @@ -517,17 +517,17 @@ "print": 1, "read": 1, "report": 1, - "role": "HR Manager", + "role": "Instructor", "set_user_permissions": 0, "share": 1, "submit": 0, "write": 1 - }, + }, { "amend": 0, "cancel": 0, - "create": 1, - "delete": 1, + "create": 0, + "delete": 0, "email": 1, "export": 1, "if_owner": 0, @@ -536,11 +536,11 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "LMS User", "set_user_permissions": 0, "share": 1, "submit": 0, - "write": 1 + "write": 0 } ], "quick_entry": 0, diff --git a/erpnext/education/doctype/course_activity/course_activity.json b/erpnext/education/doctype/course_activity/course_activity.json index 853bd46588..66bbdeb6b5 100644 --- a/erpnext/education/doctype/course_activity/course_activity.json +++ b/erpnext/education/doctype/course_activity/course_activity.json @@ -224,7 +224,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-25 20:30:34.573440", + "modified": "2018-11-07 21:15:03.187253", "modified_by": "Administrator", "module": "Education", "name": "Course Activity", @@ -244,7 +244,7 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "Academics User", "set_user_permissions": 0, "share": 1, "submit": 0, @@ -268,6 +268,25 @@ "share": 1, "submit": 0, "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 1, diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.json b/erpnext/education/doctype/course_enrollment/course_enrollment.json index 47bb973d5d..5de7f21493 100644 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.json +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.json @@ -190,7 +190,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-24 16:05:02.961543", + "modified": "2018-11-07 21:16:34.764628", "modified_by": "Administrator", "module": "Education", "name": "Course Enrollment", @@ -210,7 +210,7 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "Academics User", "set_user_permissions": 0, "share": 1, "submit": 0, @@ -234,6 +234,25 @@ "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 1, diff --git a/erpnext/education/doctype/program/program.json b/erpnext/education/doctype/program/program.json index 4628da801e..3b78df99af 100644 --- a/erpnext/education/doctype/program/program.json +++ b/erpnext/education/doctype/program/program.json @@ -476,7 +476,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-11-05 18:59:59.784033", + "modified": "2018-11-07 21:14:10.011904", "modified_by": "Administrator", "module": "Education", "name": "Program", @@ -502,6 +502,25 @@ "submit": 0, "write": 1 }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + }, { "amend": 0, "cancel": 0, @@ -524,8 +543,8 @@ { "amend": 0, "cancel": 0, - "create": 1, - "delete": 1, + "create": 0, + "delete": 0, "email": 1, "export": 1, "if_owner": 0, @@ -534,11 +553,30 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "LMS User", "set_user_permissions": 0, "share": 1, "submit": 0, - "write": 1 + "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Student", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 0, diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment.json b/erpnext/education/doctype/program_enrollment/program_enrollment.json index 6e1a0c34fd..1d8a4344a7 100644 --- a/erpnext/education/doctype/program_enrollment/program_enrollment.json +++ b/erpnext/education/doctype/program_enrollment/program_enrollment.json @@ -715,7 +715,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-11-03 17:52:44.017627", + "modified": "2018-11-07 21:13:06.502279", "modified_by": "Administrator", "module": "Education", "name": "Program Enrollment", diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json index cca89cff50..b7b3ca8eca 100644 --- a/erpnext/education/doctype/question/question.json +++ b/erpnext/education/doctype/question/question.json @@ -91,7 +91,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-18 15:31:28.471650", + "modified": "2018-11-07 21:18:19.991825", "modified_by": "Administrator", "module": "Education", "name": "Question", @@ -111,11 +111,49 @@ "print": 1, "read": 1, "report": 1, - "role": "Administrator", + "role": "Academics User", "set_user_permissions": 0, "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 1, diff --git a/erpnext/education/doctype/quiz/quiz.json b/erpnext/education/doctype/quiz/quiz.json index 25b9690451..cf69571da0 100644 --- a/erpnext/education/doctype/quiz/quiz.json +++ b/erpnext/education/doctype/quiz/quiz.json @@ -154,7 +154,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-11-02 10:58:56.590859", + "modified": "2018-11-07 21:14:30.782586", "modified_by": "Administrator", "module": "Education", "name": "Quiz", @@ -174,7 +174,7 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "Academics User", "set_user_permissions": 0, "share": 1, "submit": 0, @@ -198,6 +198,25 @@ "share": 1, "submit": 0, "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 } ], "quick_entry": 1, diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.json b/erpnext/education/doctype/quiz_activity/quiz_activity.json index f2aeea130f..4969bc657e 100644 --- a/erpnext/education/doctype/quiz_activity/quiz_activity.json +++ b/erpnext/education/doctype/quiz_activity/quiz_activity.json @@ -413,7 +413,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-25 20:29:08.305410", + "modified": "2018-11-07 21:16:14.515079", "modified_by": "Administrator", "module": "Education", "name": "Quiz Activity", @@ -433,7 +433,7 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "Academics User", "set_user_permissions": 0, "share": 1, "submit": 0, @@ -457,6 +457,25 @@ "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 1, diff --git a/erpnext/education/doctype/student/student.json b/erpnext/education/doctype/student/student.json index cdb66b033f..2e055bb1b1 100644 --- a/erpnext/education/doctype/student/student.json +++ b/erpnext/education/doctype/student/student.json @@ -1188,7 +1188,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-10-12 16:46:31.504987", + "modified": "2018-11-07 22:11:03.824250", "modified_by": "Administrator", "module": "Education", "name": "Student", @@ -1251,6 +1251,25 @@ "share": 1, "submit": 0, "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 0, diff --git a/erpnext/education/doctype/video/video.json b/erpnext/education/doctype/video/video.json index d8c3368d93..dd81e97e23 100644 --- a/erpnext/education/doctype/video/video.json +++ b/erpnext/education/doctype/video/video.json @@ -185,7 +185,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-10-18 12:26:47.709081", + "modified": "2018-11-07 21:19:09.321439", "modified_by": "Administrator", "module": "Education", "name": "Video", @@ -205,11 +205,49 @@ "print": 1, "read": 1, "report": 1, - "role": "System Manager", + "role": "Academics User", "set_user_permissions": 0, "share": 1, "submit": 0, "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + }, + { + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 0 } ], "quick_entry": 1, From b409f7a38855b1dd573dd4ef6633755f2e9e3411 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Wed, 7 Nov 2018 22:12:55 +0530 Subject: [PATCH 092/314] Minor UI Changes and Fixes --- erpnext/public/js/education/web-academy.js | 2 +- .../components/AcademyCourseCard.vue | 2 +- .../components/AcademyTopSectionButton.vue | 60 ++++++++++++------- .../web-academy/pages/AcademyProgramPage.vue | 1 - erpnext/www/academy.py | 6 ++ 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/erpnext/public/js/education/web-academy.js b/erpnext/public/js/education/web-academy.js index 3dfd0f2385..e6b48ecb28 100644 --- a/erpnext/public/js/education/web-academy.js +++ b/erpnext/public/js/education/web-academy.js @@ -16,7 +16,7 @@ const routes = [ ]; var store = { - debug: false, + debug: true, isLogin: false, completedCourses: new Set(), enrolledPrograms: new Set(), diff --git a/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue b/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue index 426b9877cb..9c47473969 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue @@ -12,7 +12,7 @@
- +
diff --git a/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue b/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue index e1df97e79e..8cc3a7b5fa 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue @@ -1,5 +1,5 @@ \ No newline at end of file diff --git a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue b/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue index ef4545936e..030c3ed34e 100644 --- a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue +++ b/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue @@ -30,7 +30,6 @@ export default { } }, beforeMount(){ - console.log("Before Mount") if(this.$root.$data.isLogin) this.$root.$data.updateCompletedCourses() }, mounted() { diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py index d68dee43c5..4aec61488a 100644 --- a/erpnext/www/academy.py +++ b/erpnext/www/academy.py @@ -110,6 +110,8 @@ def evaluate_quiz(enrollment, quiz_response, quiz_name): @frappe.whitelist() def get_completed_courses(email=frappe.session.user): + if get_student_id(email) == None: + return None try: student = frappe.get_doc("Student", get_student_id(email)) return student.get_completed_courses() @@ -161,6 +163,8 @@ def get_student_id(email=None): @frappe.whitelist() def get_program_enrollments(email=frappe.session.user): + if get_student_id(email) == None: + return None try: student = frappe.get_doc("Student", get_student_id(email)) return student.get_program_enrollments() @@ -169,6 +173,8 @@ def get_program_enrollments(email=frappe.session.user): @frappe.whitelist() def get_course_enrollments(email=frappe.session.user): + if get_student_id(email) == None: + return None try: student = frappe.get_doc("Student", get_student_id(email)) return student.get_course_enrollments() From 734a746687aa75b026a1e518725aba2056567b0f Mon Sep 17 00:00:00 2001 From: scmmishra Date: Wed, 7 Nov 2018 22:16:15 +0530 Subject: [PATCH 093/314] Minor DocType changes --- erpnext/education/doctype/article/article.json | 4 ++-- erpnext/education/doctype/question/question.json | 4 ++-- erpnext/education/doctype/video/video.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/erpnext/education/doctype/article/article.json b/erpnext/education/doctype/article/article.json index 0fdeeef918..6b79f6090e 100644 --- a/erpnext/education/doctype/article/article.json +++ b/erpnext/education/doctype/article/article.json @@ -2,7 +2,7 @@ "allow_copy": 0, "allow_events_in_timeline": 0, "allow_guest_to_view": 0, - "allow_import": 0, + "allow_import": 1, "allow_rename": 0, "autoname": "field:title", "beta": 0, @@ -153,7 +153,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-11-07 21:19:29.051716", + "modified": "2018-11-07 22:14:23.922612", "modified_by": "Administrator", "module": "Education", "name": "Article", diff --git a/erpnext/education/doctype/question/question.json b/erpnext/education/doctype/question/question.json index b7b3ca8eca..5ddad44405 100644 --- a/erpnext/education/doctype/question/question.json +++ b/erpnext/education/doctype/question/question.json @@ -2,7 +2,7 @@ "allow_copy": 0, "allow_events_in_timeline": 0, "allow_guest_to_view": 0, - "allow_import": 0, + "allow_import": 1, "allow_rename": 0, "autoname": "format:QUESTION-{#####}", "beta": 0, @@ -91,7 +91,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-11-07 21:18:19.991825", + "modified": "2018-11-07 22:15:02.726655", "modified_by": "Administrator", "module": "Education", "name": "Question", diff --git a/erpnext/education/doctype/video/video.json b/erpnext/education/doctype/video/video.json index dd81e97e23..30ad89a622 100644 --- a/erpnext/education/doctype/video/video.json +++ b/erpnext/education/doctype/video/video.json @@ -2,7 +2,7 @@ "allow_copy": 0, "allow_events_in_timeline": 0, "allow_guest_to_view": 0, - "allow_import": 0, + "allow_import": 1, "allow_rename": 0, "autoname": "field:title", "beta": 0, @@ -185,7 +185,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-11-07 21:19:09.321439", + "modified": "2018-11-07 22:14:29.957676", "modified_by": "Administrator", "module": "Education", "name": "Video", From 05e07b44b122f2078adf58923212771272b36a60 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Thu, 8 Nov 2018 13:01:39 +0530 Subject: [PATCH 094/314] Removed unused utils functions --- erpnext/education/utils.py | 128 ------------------------------------- 1 file changed, 128 deletions(-) diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index 9d57f66e5e..61758e2d84 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -53,132 +53,4 @@ def validate_duplicate_student(students): else: unique_students.append(stud.student) -@frappe.whitelist() -def evaluate_quiz(quiz_response, **kwargs): - """LMS Function: Evaluates a simple multiple choice quiz. It recieves arguments from `www/lms/course.js` as dictionary using FormData[1]. - - - :param quiz_response: contains user selected choices for a quiz in the form of a string formatted as a dictionary. The function uses `json.loads()` to convert it to a python dictionary. - [1]: https://developer.mozilla.org/en-US/docs/Web/API/FormData - """ - import json - quiz_response = json.loads(quiz_response) - quiz_name = kwargs.get('quiz') - course_name = kwargs.get('course') - enrollment = get_course_enrollment(course_name, frappe.session.user) - try: - quiz = frappe.get_doc("Quiz", quiz_name) - answers, score = quiz.evaluate(quiz_response, enrollment, quiz_name) - add_quiz_activity(enrollment, quiz_name, score, answers, quiz_response) - return score - except frappe.DoesNotExistError: - frappe.throw("Quiz {0} does not exist".format(quiz_name)) - return None - - -def add_quiz_activity(enrollment, quiz, score, answers, quiz_response): - print(quiz, answers, score) - if not enrollment: - frappe.throw("The user is not enrolled for the course {course}".format(course=course)) - activity = frappe.get_doc({ - "doctype": "Quiz Activity", - "enrollment": enrollment.name, - "quiz": quiz, - "score": score, - "date": frappe.utils.datetime.datetime.now() - }) - for question in quiz_response.keys(): - activity.append("result", - { - "question": question, - "selected_option": quiz_response[question], - "quiz_result": 'Correct' if answers[question] else 'Wrong' - }) - activity.save() - frappe.db.commit() - -@frappe.whitelist() -def add_activity(content_type, content, course, program): - if content_type == "Quiz": - pass - enrollment = get_course_enrollment(course, frappe.session.user) - if check_activity_exists(enrollment['name'], content_type, content): - pass - else: - course_actvity = frappe.get_doc({ - "doctype": "Course Activity", - "enrollment": enrollment['name'], - "content_type": content_type, - "content": content, - "date": frappe.utils.datetime.datetime.now() - }) - course_actvity.save() - frappe.db.commit() - -def check_activity_exists(enrollment, content_type, content): - activity = frappe.get_list("Course Activity", filters={"enrollment": enrollment, "content_type": content_type, "content": content}) - if activity: - return True - else: - return False - - -def get_program(): - program_list = frappe.get_list("Program", filters={"is_published": is_published}) - if program_list: - return program_list - else: - return None - -def get_featured_programs(): - featured_programs_name = frappe.get_list("Program", filters={"is_published": True, "is_featured": True}) - featured_list = [frappe.get_doc("Program", program["name"]) for program in featured_programs_name] - if featured_list: - return featured_list - else: - return None - -@frappe.whitelist() -def add_course_enrollment(course, email): - student_id = get_student_id(email) - if not get_course_enrollment(course, email): - enrollment = frappe.get_doc({ - "doctype": "Course Enrollment", - "student": student_id, - "course": course, - "enrollment_date": frappe.getdate() - }) - enrollment.save() - frappe.db.commit() - return enrollment - -def get_course_enrollment(course, email): - student_id = get_student_id(email) - try: - return frappe.get_list("Course Enrollment", filters={'course':course, 'student':student_id})[0] - except IndexError: - frappe.throw("The user is not enrolled for the course {course}".format(course=course)) - return None - -def get_student_id(email=None): - """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series). - - :param user: a user email address - """ - try: - return frappe.get_all('Student', filters={'student_email_id': email}, fields=['name'])[0].name - except IndexError: - frappe.throw("Student with email {0} does not exist".format(email)) - return None - -@frappe.whitelist() -def mark_course_complete(course): - try: - enrollment_name = get_course_enrollment(course, frappe.session.user) - enrollment = frappe.get_doc("Course Enrollment", enrollment_name) - enrollment.completed = 1 - enrollment.save() - pass - except: - frappe.throw("The user is not enrolled for the course {course}".format(course=course)) return None \ No newline at end of file From 8fa9adec37fb1676fcb0a968801d2446015feb85 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Thu, 8 Nov 2018 13:01:55 +0530 Subject: [PATCH 095/314] More Bug fixes UI and Permissions --- .../education/doctype/student/student.json | 2 +- erpnext/education/doctype/student/student.py | 6 ++--- erpnext/public/js/education/web-academy.js | 12 ++++++--- .../components/AcademyProgramCard.vue | 27 +++++++++++++++++-- erpnext/www/academy.py | 14 ++++++---- 5 files changed, 46 insertions(+), 15 deletions(-) diff --git a/erpnext/education/doctype/student/student.json b/erpnext/education/doctype/student/student.json index 2e055bb1b1..7205273a52 100644 --- a/erpnext/education/doctype/student/student.json +++ b/erpnext/education/doctype/student/student.json @@ -1188,7 +1188,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-11-07 22:11:03.824250", + "modified": "2018-11-08 12:26:01.047163", "modified_by": "Administrator", "module": "Education", "name": "Student", diff --git a/erpnext/education/doctype/student/student.py b/erpnext/education/doctype/student/student.py index 69959ea784..d23e0a04e0 100644 --- a/erpnext/education/doctype/student/student.py +++ b/erpnext/education/doctype/student/student.py @@ -55,7 +55,7 @@ class Student(Document): def get_program_enrollments(self): """Returns a list of course enrollments linked with the current student""" - program_enrollments = frappe.get_list("Program Enrollment", filters={"student": self.name}, fields=['program']) + program_enrollments = frappe.get_all("Program Enrollment", filters={"student": self.name}, fields=['program']) if not program_enrollments: return None else: @@ -79,7 +79,7 @@ class Student(Document): "program": program_name, "enrollment_date": frappe.utils.datetime.datetime.now() }) - enrollment.save() + enrollment.save(ignore_permissions=True) enrollment.submit() frappe.db.commit() return enrollment @@ -92,7 +92,7 @@ class Student(Document): "program_enrollment": program_enrollment, "enrollment_date": enrollment_date }) - enrollment.save() + enrollment.save(ignore_permissions=True) frappe.db.commit() def get_timeline_data(doctype, name): diff --git a/erpnext/public/js/education/web-academy.js b/erpnext/public/js/education/web-academy.js index e6b48ecb28..8088a5060d 100644 --- a/erpnext/public/js/education/web-academy.js +++ b/erpnext/public/js/education/web-academy.js @@ -48,8 +48,10 @@ var store = { email: frappe.session.user } }).then( r => { - for(var ii=0; ii < r.message.length; ii++){ - this.enrolledPrograms.add(r.message[ii]) + if(r.message){ + for(var ii=0; ii < r.message.length; ii++){ + this.enrolledPrograms.add(r.message[ii]) + } } }) if (this.debug) console.log('Updated State', this.enrolledPrograms) @@ -76,8 +78,10 @@ var store = { email: frappe.session.user } }).then( r => { - for(var ii=0; ii < r.message.length; ii++){ - this.completedCourses.add(r.message[ii]) + if(r.message){ + for(var ii=0; ii < r.message.length; ii++){ + this.completedCourses.add(r.message[ii]) + } } }) if (this.debug) console.log('Updated State', this.completedCourses) diff --git a/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue b/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue index 6ddf152a49..605dec211c 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue +++ b/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue @@ -10,8 +10,7 @@ @@ -37,6 +36,16 @@ export default { }) }, methods: { + primaryAction(){ + if(this.$root.$data.isLogin){ + if(this.$root.$data.checkProgramEnrollment(program_code)){ + this.$router.push('/Program/' + program.name) + } + else { + this.enroll() + } + } + } enroll() { frappe.call({ method: "erpnext.www.academy.enroll_in_program", @@ -45,6 +54,20 @@ export default { student_email_id: frappe.session.user } }) + this.$root.$data.enrolledPrograms.add(this.program_code) + this.$root.$data.updateEnrolledPrograms() + } + } + computed: { + buttonName() { + if(this.$root.$data.isLogin){ + if(this.$root.$data.checkProgramEnrollment(program_code)){ + return "Start Course" + } + else { + return "Enroll" + } + } } } }; diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py index 4aec61488a..94a0a71687 100644 --- a/erpnext/www/academy.py +++ b/erpnext/www/academy.py @@ -122,9 +122,12 @@ def get_completed_courses(email=frappe.session.user): def get_continue_data(program_name): program = frappe.get_doc("Program", program_name) courses = program.get_all_children() - continue_data = get_starting_content(courses[0].course) - continue_data['course'] = courses[0].course - return continue_data + try: + continue_data = get_starting_content(courses[0].course) + continue_data['course'] = courses[0].course + return continue_data + except: + return None def create_student(student_name=frappe.session.user): student = frappe.get_doc({ @@ -132,7 +135,7 @@ def create_student(student_name=frappe.session.user): "first_name": student_name, "student_email_id": student_name, }) - student.save() + student.save(ignore_permissions=True) frappe.db.commit() return student_name @@ -157,7 +160,8 @@ def get_student_id(email=None): :param user: a user email address """ try: - return frappe.get_all('Student', filters={'student_email_id': email}, fields=['name'])[0].name + student_id = frappe.db.get_all("Student", {"student_email_id": email}, ["name"])[0].name + return student_id except IndexError: return None From c1b1a5ec379e7fd6ae1781882f2c70f04e0c76e3 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Thu, 8 Nov 2018 13:31:15 +0530 Subject: [PATCH 096/314] Permission Changes --- erpnext/education/doctype/course/course.json | 21 ++++++++++++++++++- .../education/doctype/program/program.json | 21 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/erpnext/education/doctype/course/course.json b/erpnext/education/doctype/course/course.json index c145b2d7d7..01de14704c 100644 --- a/erpnext/education/doctype/course/course.json +++ b/erpnext/education/doctype/course/course.json @@ -478,7 +478,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-11-07 21:20:21.941865", + "modified": "2018-11-08 13:30:33.423194", "modified_by": "Administrator", "module": "Education", "name": "Course", @@ -541,6 +541,25 @@ "share": 1, "submit": 0, "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 } ], "quick_entry": 0, diff --git a/erpnext/education/doctype/program/program.json b/erpnext/education/doctype/program/program.json index 3b78df99af..32bde457bc 100644 --- a/erpnext/education/doctype/program/program.json +++ b/erpnext/education/doctype/program/program.json @@ -476,7 +476,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2018-11-07 21:14:10.011904", + "modified": "2018-11-08 13:30:59.498663", "modified_by": "Administrator", "module": "Education", "name": "Program", @@ -577,6 +577,25 @@ "share": 1, "submit": 0, "write": 0 + }, + { + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 } ], "quick_entry": 0, From cc166c01ebe39a1404b9ca042729edc886d347df Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 9 Nov 2018 11:47:09 +0530 Subject: [PATCH 097/314] Improved Client implementation --- .../course_enrollment/course_enrollment.py | 6 +- erpnext/public/build.json | 4 +- .../{web-academy => academy}/AcademyRoot.vue | 0 .../{web-academy.js => academy/academy.js} | 43 ++++++----- erpnext/public/js/education/academy/call.js | 13 ++++ .../components/AcademyCourseCard.vue | 41 ++++++++++- .../components/AcademyCourseCardButton.vue | 0 .../components/AcademyList.vue | 0 .../components/AcademyProgramCard.vue | 8 +- .../components/AcademyTopSection.vue | 0 .../components/AcademyTopSectionButton.vue | 0 .../education/academy/components/Button.vue | 25 +++++++ .../components/ContentArticle.vue | 0 .../components/ContentNavigation.vue | 5 +- .../components/ContentQuiz.vue | 0 .../components/ContentTitle.vue | 0 .../components/ContentVideo.vue | 0 .../components/Quiz/QuizSingleChoice.vue | 0 .../pages/AcademyCoursePage.vue | 0 .../pages/AcademyHome.vue | 0 .../academy/pages/AcademyProgramPage.vue | 73 +++++++++++++++++++ erpnext/public/js/education/academy/routes.js | 11 +++ .../web-academy/pages/AcademyProgramPage.vue | 54 -------------- erpnext/www/academy.html | 2 +- 24 files changed, 202 insertions(+), 83 deletions(-) rename erpnext/public/js/education/{web-academy => academy}/AcademyRoot.vue (100%) rename erpnext/public/js/education/{web-academy.js => academy/academy.js} (80%) create mode 100644 erpnext/public/js/education/academy/call.js rename erpnext/public/js/education/{web-academy => academy}/components/AcademyCourseCard.vue (55%) rename erpnext/public/js/education/{web-academy => academy}/components/AcademyCourseCardButton.vue (100%) rename erpnext/public/js/education/{web-academy => academy}/components/AcademyList.vue (100%) rename erpnext/public/js/education/{web-academy => academy}/components/AcademyProgramCard.vue (92%) rename erpnext/public/js/education/{web-academy => academy}/components/AcademyTopSection.vue (100%) rename erpnext/public/js/education/{web-academy => academy}/components/AcademyTopSectionButton.vue (100%) create mode 100644 erpnext/public/js/education/academy/components/Button.vue rename erpnext/public/js/education/{web-academy => academy}/components/ContentArticle.vue (100%) rename erpnext/public/js/education/{web-academy => academy}/components/ContentNavigation.vue (92%) rename erpnext/public/js/education/{web-academy => academy}/components/ContentQuiz.vue (100%) rename erpnext/public/js/education/{web-academy => academy}/components/ContentTitle.vue (100%) rename erpnext/public/js/education/{web-academy => academy}/components/ContentVideo.vue (100%) rename erpnext/public/js/education/{web-academy => academy}/components/Quiz/QuizSingleChoice.vue (100%) rename erpnext/public/js/education/{web-academy => academy}/pages/AcademyCoursePage.vue (100%) rename erpnext/public/js/education/{web-academy => academy}/pages/AcademyHome.vue (100%) create mode 100644 erpnext/public/js/education/academy/pages/AcademyProgramPage.vue create mode 100644 erpnext/public/js/education/academy/routes.js delete mode 100644 erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.py b/erpnext/education/doctype/course_enrollment/course_enrollment.py index 09ffade7d8..cfe502b8a3 100644 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.py +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.py @@ -7,4 +7,8 @@ import frappe from frappe.model.document import Document class CourseEnrollment(Document): - pass + + def get_all_activity(self): + course_activity_list = frappe.get_all("Course Activity", filters={'enrollment':self.name}, fields=['content', 'content_type', 'modified'], order_by='modified') + quiz_activity_list = frappe.get_all("Quiz Activity", filters={'enrollment':self.name}, fields=['quiz', 'status', 'modified'], order_by='modified') + return course_activity_list, quiz_activity_list \ No newline at end of file diff --git a/erpnext/public/build.json b/erpnext/public/build.json index 824b9b8283..66ac5fe4f1 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -55,7 +55,7 @@ "stock/dashboard/item_dashboard_list.html", "stock/dashboard/item_dashboard.js" ], - "js/web-academy.min.js": [ - "public/js/education/web-academy.js" + "js/academy.min.js": [ + "public/js/education/academy/academy.js" ] } diff --git a/erpnext/public/js/education/web-academy/AcademyRoot.vue b/erpnext/public/js/education/academy/AcademyRoot.vue similarity index 100% rename from erpnext/public/js/education/web-academy/AcademyRoot.vue rename to erpnext/public/js/education/academy/AcademyRoot.vue diff --git a/erpnext/public/js/education/web-academy.js b/erpnext/public/js/education/academy/academy.js similarity index 80% rename from erpnext/public/js/education/web-academy.js rename to erpnext/public/js/education/academy/academy.js index 8088a5060d..08cfc37af4 100644 --- a/erpnext/public/js/education/web-academy.js +++ b/erpnext/public/js/education/academy/academy.js @@ -1,21 +1,20 @@ import Vue from 'vue/dist/vue.js'; import VueRouter from 'vue-router/dist/vue-router.js' -import AcademyRoot from "./web-academy/AcademyRoot.vue"; -import AcademyHome from "./web-academy/pages/AcademyHome.vue"; -import AcademyProgramPage from "./web-academy/pages/AcademyProgramPage.vue"; -import AcademyCoursePage from "./web-academy/pages/AcademyCoursePage.vue"; +import AcademyRoot from "./AcademyRoot.vue"; +import routes from './routes'; +import './call'; Vue.use(VueRouter) -const routes = [ - {name: 'home', path: '', component: AcademyHome}, - {name: 'program', path: '/Program/:code', component: AcademyProgramPage, props: true}, - {name: 'content', path: '/Program/:code/:course/:type/:content', component: AcademyCoursePage, props: true}, -]; -var store = { + +frappe.provide('academy') + +frappe.utils.make_event_emitter(academy); + +academy.store = { debug: true, isLogin: false, completedCourses: new Set(), @@ -104,19 +103,13 @@ var store = { this.updateEnrolledPrograms() this.updateEnrolledCourses() this.checkLogin() - }, } -const router = new VueRouter({ - routes: routes, -}); - frappe.ready(() => { window.v = new Vue({ el: "#academy", - router: router, - data: store, + router: new VueRouter({ routes }), template: "", components: { AcademyRoot }, created: function() { @@ -125,4 +118,20 @@ frappe.ready(() => { } } }); + academy.store = new Vue({ + data: store, + methods: { + checkLogin (){ + if(frappe.session.user === "Guest"){ + if (this.debug) console.log('No Session') + this.isLogin = false + } + else { + if (this.debug) console.log('Current User: ', frappe.session.user) + this.isLogin = true + } + return this.isLogin + } + } + }); }) \ No newline at end of file diff --git a/erpnext/public/js/education/academy/call.js b/erpnext/public/js/education/academy/call.js new file mode 100644 index 0000000000..108a6e1d36 --- /dev/null +++ b/erpnext/public/js/education/academy/call.js @@ -0,0 +1,13 @@ +frappe.provide('academy'); + +academy.call = (method, args) => { + const method_path = 'erpnext.www.academy.' + method; + return new Promise((resolve, reject) => { + return frappe.call({ + method: method_path, + args, + }) + .then(r => resolve(r.message)) + .fail(reject) + }); +} \ No newline at end of file diff --git a/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue b/erpnext/public/js/education/academy/components/AcademyCourseCard.vue similarity index 55% rename from erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue rename to erpnext/public/js/education/academy/components/AcademyCourseCard.vue index 9c47473969..eda382f4fa 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyCourseCard.vue +++ b/erpnext/public/js/education/academy/components/AcademyCourseCard.vue @@ -12,7 +12,29 @@
- + + + + Completed + + + Start +
@@ -20,6 +42,7 @@ diff --git a/erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue b/erpnext/public/js/education/academy/components/AcademyCourseCardButton.vue similarity index 100% rename from erpnext/public/js/education/web-academy/components/AcademyCourseCardButton.vue rename to erpnext/public/js/education/academy/components/AcademyCourseCardButton.vue diff --git a/erpnext/public/js/education/web-academy/components/AcademyList.vue b/erpnext/public/js/education/academy/components/AcademyList.vue similarity index 100% rename from erpnext/public/js/education/web-academy/components/AcademyList.vue rename to erpnext/public/js/education/academy/components/AcademyList.vue diff --git a/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue b/erpnext/public/js/education/academy/components/AcademyProgramCard.vue similarity index 92% rename from erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue rename to erpnext/public/js/education/academy/components/AcademyProgramCard.vue index 605dec211c..ef3ac0896b 100644 --- a/erpnext/public/js/education/web-academy/components/AcademyProgramCard.vue +++ b/erpnext/public/js/education/academy/components/AcademyProgramCard.vue @@ -38,14 +38,14 @@ export default { methods: { primaryAction(){ if(this.$root.$data.isLogin){ - if(this.$root.$data.checkProgramEnrollment(program_code)){ + if(this.$root.$data.checkProgramEnrollment(this.program_code)){ this.$router.push('/Program/' + program.name) } else { this.enroll() } } - } + }, enroll() { frappe.call({ method: "erpnext.www.academy.enroll_in_program", @@ -57,11 +57,11 @@ export default { this.$root.$data.enrolledPrograms.add(this.program_code) this.$root.$data.updateEnrolledPrograms() } - } + }, computed: { buttonName() { if(this.$root.$data.isLogin){ - if(this.$root.$data.checkProgramEnrollment(program_code)){ + if(this.$root.$data.checkProgramEnrollment(this.program_code)){ return "Start Course" } else { diff --git a/erpnext/public/js/education/web-academy/components/AcademyTopSection.vue b/erpnext/public/js/education/academy/components/AcademyTopSection.vue similarity index 100% rename from erpnext/public/js/education/web-academy/components/AcademyTopSection.vue rename to erpnext/public/js/education/academy/components/AcademyTopSection.vue diff --git a/erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue b/erpnext/public/js/education/academy/components/AcademyTopSectionButton.vue similarity index 100% rename from erpnext/public/js/education/web-academy/components/AcademyTopSectionButton.vue rename to erpnext/public/js/education/academy/components/AcademyTopSectionButton.vue diff --git a/erpnext/public/js/education/academy/components/Button.vue b/erpnext/public/js/education/academy/components/Button.vue new file mode 100644 index 0000000000..4d8df4b314 --- /dev/null +++ b/erpnext/public/js/education/academy/components/Button.vue @@ -0,0 +1,25 @@ + + diff --git a/erpnext/public/js/education/web-academy/components/ContentArticle.vue b/erpnext/public/js/education/academy/components/ContentArticle.vue similarity index 100% rename from erpnext/public/js/education/web-academy/components/ContentArticle.vue rename to erpnext/public/js/education/academy/components/ContentArticle.vue diff --git a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue b/erpnext/public/js/education/academy/components/ContentNavigation.vue similarity index 92% rename from erpnext/public/js/education/web-academy/components/ContentNavigation.vue rename to erpnext/public/js/education/academy/components/ContentNavigation.vue index 28f5a70b76..7fa20a5c6e 100644 --- a/erpnext/public/js/education/web-academy/components/ContentNavigation.vue +++ b/erpnext/public/js/education/academy/components/ContentNavigation.vue @@ -41,9 +41,12 @@ export default { enrollment: this.$root.$data.enrolledCourses[this.$route.params.course] } }) - this.$root.$data.addCompletedCourses(this.$route.params.course) + // this.$root.$data.addCompletedCourses(this.$route.params.course) this.$root.$data.updateCompletedCourses() this.$router.push({ name: 'program', params: { code: this.$route.params.code}}) + + // + academy.trigger('course-completed', course_name); } } }; diff --git a/erpnext/public/js/education/web-academy/components/ContentQuiz.vue b/erpnext/public/js/education/academy/components/ContentQuiz.vue similarity index 100% rename from erpnext/public/js/education/web-academy/components/ContentQuiz.vue rename to erpnext/public/js/education/academy/components/ContentQuiz.vue diff --git a/erpnext/public/js/education/web-academy/components/ContentTitle.vue b/erpnext/public/js/education/academy/components/ContentTitle.vue similarity index 100% rename from erpnext/public/js/education/web-academy/components/ContentTitle.vue rename to erpnext/public/js/education/academy/components/ContentTitle.vue diff --git a/erpnext/public/js/education/web-academy/components/ContentVideo.vue b/erpnext/public/js/education/academy/components/ContentVideo.vue similarity index 100% rename from erpnext/public/js/education/web-academy/components/ContentVideo.vue rename to erpnext/public/js/education/academy/components/ContentVideo.vue diff --git a/erpnext/public/js/education/web-academy/components/Quiz/QuizSingleChoice.vue b/erpnext/public/js/education/academy/components/Quiz/QuizSingleChoice.vue similarity index 100% rename from erpnext/public/js/education/web-academy/components/Quiz/QuizSingleChoice.vue rename to erpnext/public/js/education/academy/components/Quiz/QuizSingleChoice.vue diff --git a/erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue b/erpnext/public/js/education/academy/pages/AcademyCoursePage.vue similarity index 100% rename from erpnext/public/js/education/web-academy/pages/AcademyCoursePage.vue rename to erpnext/public/js/education/academy/pages/AcademyCoursePage.vue diff --git a/erpnext/public/js/education/web-academy/pages/AcademyHome.vue b/erpnext/public/js/education/academy/pages/AcademyHome.vue similarity index 100% rename from erpnext/public/js/education/web-academy/pages/AcademyHome.vue rename to erpnext/public/js/education/academy/pages/AcademyHome.vue diff --git a/erpnext/public/js/education/academy/pages/AcademyProgramPage.vue b/erpnext/public/js/education/academy/pages/AcademyProgramPage.vue new file mode 100644 index 0000000000..7bea1ed5c1 --- /dev/null +++ b/erpnext/public/js/education/academy/pages/AcademyProgramPage.vue @@ -0,0 +1,73 @@ + + \ No newline at end of file diff --git a/erpnext/public/js/education/academy/routes.js b/erpnext/public/js/education/academy/routes.js new file mode 100644 index 0000000000..51c280d72a --- /dev/null +++ b/erpnext/public/js/education/academy/routes.js @@ -0,0 +1,11 @@ +import AcademyHome from "./academy/pages/AcademyHome.vue"; +import AcademyProgramPage from "./academy/pages/AcademyProgramPage.vue"; +import AcademyCoursePage from "./academy/pages/AcademyCoursePage.vue"; + +const routes = [ + {name: 'home', path: '', component: AcademyHome}, + {name: 'program', path: '/Program/:program_name', component: AcademyProgramPage, props: true}, + {name: 'content', path: '/Program/:code/:course/:type/:content', component: AcademyCoursePage, props: true}, +]; + +export default routes; \ No newline at end of file diff --git a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue b/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue deleted file mode 100644 index 030c3ed34e..0000000000 --- a/erpnext/public/js/education/web-academy/pages/AcademyProgramPage.vue +++ /dev/null @@ -1,54 +0,0 @@ - - \ No newline at end of file diff --git a/erpnext/www/academy.html b/erpnext/www/academy.html index 6e87f831e9..9d3cec8a51 100644 --- a/erpnext/www/academy.html +++ b/erpnext/www/academy.html @@ -4,5 +4,5 @@ {% block page_content %}
- + {% endblock %} \ No newline at end of file From 892b0c23fc64e454876dc4465ec1c2829b91389a Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 9 Nov 2018 18:24:26 +0530 Subject: [PATCH 098/314] Added class functions --- erpnext/education/doctype/course/course.py | 22 +++++------------- .../course_enrollment/course_enrollment.py | 23 ++++++++++++++++--- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/erpnext/education/doctype/course/course.py b/erpnext/education/doctype/course/course.py index 1e4270954d..9e701c6035 100644 --- a/erpnext/education/doctype/course/course.py +++ b/erpnext/education/doctype/course/course.py @@ -19,27 +19,17 @@ class Course(Document): if total_weightage != 100: frappe.throw(_("Total Weightage of all Assessment Criteria must be 100%")) - def get_content_value(self, data): + def get_contents(self): try: course_content_list = self.get_all_children() - content_data = [frappe.get_value(course_content.content_type, course_content.content, data) for course_content in course_content_list] + content_data = [frappe.get_doc(course_content.content_type, course_content.content) for course_content in course_content_list] except Exception as e: print(e) return None return content_data - def get_content_info(self): - try: - course_content_list = self.get_all_children() - content_data = [[course_content.content_type, course_content.content] for course_content in course_content_list] - except Exception as e: - print(e) - return None - return content_data + def get_first_content(self): + return self.get_contents()[0] - def get_content_title(self): - ''' - returns all the course content for the given course object. - ''' - content_title = self.get_content_value("title") - return content_title \ No newline at end of file + def get_last_content(self): + return self.get_contents()[-1] \ No newline at end of file diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.py b/erpnext/education/doctype/course_enrollment/course_enrollment.py index cfe502b8a3..dd90a5e96e 100644 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.py +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.py @@ -8,7 +8,24 @@ from frappe.model.document import Document class CourseEnrollment(Document): + def get_linked_activity(self): + course_activity_list = frappe.get_all("Course Activity", filters={'enrollment':self.name}) + course_activity = [frappe.get_doc("Course Activity", activity.name) for activity in course_activity_list] + quiz_activity_list = frappe.get_all("Quiz Activity", filters={'enrollment':self.name}) + quiz_activity = [frappe.get_doc("Quiz Activity", activity.name) for activity in quiz_activity_list] + return course_activity, quiz_activity + def get_all_activity(self): - course_activity_list = frappe.get_all("Course Activity", filters={'enrollment':self.name}, fields=['content', 'content_type', 'modified'], order_by='modified') - quiz_activity_list = frappe.get_all("Quiz Activity", filters={'enrollment':self.name}, fields=['quiz', 'status', 'modified'], order_by='modified') - return course_activity_list, quiz_activity_list \ No newline at end of file + courses, quizes = self.get_linked_activity() + joined = courses + quizes + activity = sorted(joined, key = lambda i: i.modified) # Sorting based on modified timestamp + return activity + + def check_course_completion(self): + pass + + def get_last_activity(self): + if len(self.get_all_activity()) == 0: + return None + else: + return self.get_all_activity()[-1] \ No newline at end of file From 708756ed40d16994745090d65e29cb9404448344 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 9 Nov 2018 18:25:19 +0530 Subject: [PATCH 099/314] Added academy namespace --- .../public/js/education/academy/academy.js | 207 ++++++++---------- erpnext/public/js/education/academy/call.js | 26 ++- .../academy/components/AcademyProgramCard.vue | 64 +++--- .../education/academy/pages/AcademyHome.vue | 41 ++-- erpnext/public/js/education/academy/routes.js | 6 +- erpnext/www/academy.html | 2 +- 6 files changed, 168 insertions(+), 178 deletions(-) diff --git a/erpnext/public/js/education/academy/academy.js b/erpnext/public/js/education/academy/academy.js index 08cfc37af4..961dc3926a 100644 --- a/erpnext/public/js/education/academy/academy.js +++ b/erpnext/public/js/education/academy/academy.js @@ -7,131 +7,110 @@ import './call'; Vue.use(VueRouter) - - - -frappe.provide('academy') - -frappe.utils.make_event_emitter(academy); - -academy.store = { - debug: true, +var store = { isLogin: false, completedCourses: new Set(), enrolledPrograms: new Set(), - enrolledCourses: {}, - - addCompletedCourses (courseName){ - if (this.debug) console.log('addCompletedCourses triggered with', courseName) - this.completedCourses.add(courseName) - }, - - checkCourseCompletion (courseName){ - return this.completedCourses.has(courseName) - }, - - checkProgramEnrollment (programName){ - return this.enrolledPrograms.has(programName) - }, - - checkCourseEnrollment (courseName){ - course = new Set(Object.keys(enrolledCourses)) - return course.has(courseName) - }, - - updateEnrolledPrograms (){ - if (this.debug) console.log('Updating enrolledPrograms') - frappe.call({ - method: "erpnext.www.academy.get_program_enrollments", - args:{ - email: frappe.session.user - } - }).then( r => { - if(r.message){ - for(var ii=0; ii < r.message.length; ii++){ - this.enrolledPrograms.add(r.message[ii]) - } - } - }) - if (this.debug) console.log('Updated State', this.enrolledPrograms) - }, - - updateEnrolledCourses (){ - if (this.debug) console.log('Updating enrolledCourses') - frappe.call({ - method: "erpnext.www.academy.get_course_enrollments", - args:{ - email: frappe.session.user - } - }).then( r => { - this.enrolledCourses = r.message - }) - if (this.debug) console.log('Updated State', this.enrolledCourses) - }, - - updateCompletedCourses (){ - if (this.debug) console.log('Updating States') - frappe.call({ - method: "erpnext.www.academy.get_completed_courses", - args:{ - email: frappe.session.user - } - }).then( r => { - if(r.message){ - for(var ii=0; ii < r.message.length; ii++){ - this.completedCourses.add(r.message[ii]) - } - } - }) - if (this.debug) console.log('Updated State', this.completedCourses) - }, - - checkLogin (){ - if(frappe.session.user === "Guest"){ - if (this.debug) console.log('No Session') - this.isLogin = false - } - else { - if (this.debug) console.log('Current User: ', frappe.session.user) - this.isLogin = true - } - return this.isLogin - }, - - updateState (){ - this.updateCompletedCourses() - this.updateEnrolledPrograms() - this.updateEnrolledCourses() - this.checkLogin() - }, + enrolledCourses: {} } frappe.ready(() => { - window.v = new Vue({ - el: "#academy", + frappe.provide('academy') + // frappe.utils.make_event_emitter(academy); + + academy.store = new Vue({ + data: store, + methods: { + addCompletedCourses (courseName){ + if (academy.debug) console.log('addCompletedCourses triggered with', courseName) + this.completedCourses.add(courseName) + }, + + checkCourseCompletion (courseName){ + return this.completedCourses.has(courseName) + }, + + checkProgramEnrollment (programName){ + return this.enrolledPrograms.has(programName) + }, + + checkCourseEnrollment (courseName){ + course = new Set(Object.keys(enrolledCourses)) + return course.has(courseName) + }, + + updateEnrolledPrograms (){ + if (academy.debug) console.log('Updating enrolledPrograms') + academy.call("get_program_enrollments").then(data => { + data.forEach(element => { + this.enrolledPrograms.add(element) + }) + }); + if (academy.debug) console.log('Updated State', this.enrolledPrograms) + }, + + updateEnrolledCourses (){ + if (academy.debug) console.log('Updating enrolledCourses') + frappe.call({ + method: "erpnext.www.academy.get_course_enrollments", + args:{ + email: frappe.session.user + } + }).then( r => { + this.enrolledCourses = r.message + }) + if (academy.debug) console.log('Updated State', this.enrolledCourses) + }, + + updateCompletedCourses (){ + if (academy.debug) console.log('Updating States') + frappe.call({ + method: "erpnext.www.academy.get_completed_courses", + args:{ + email: frappe.session.user + } + }).then( r => { + if(r.message){ + for(var ii=0; ii < r.message.length; ii++){ + this.completedCourses.add(r.message[ii]) + } + } + }) + if (academy.debug) console.log('Updated State', this.completedCourses) + }, + + checkLogin (){ + if(frappe.session.user === "Guest"){ + if (academy.debug) console.log('No Session') + this.isLogin = false + } + else { + if (academy.debug) console.log('Current User: ', frappe.session.user) + this.isLogin = true + } + return this.isLogin + }, + + updateState (){ + this.updateCompletedCourses() + this.updateEnrolledPrograms() + this.updateEnrolledCourses() + this.checkLogin() + }, + } + }); + + academy.view = new Vue({ + el: "#academy-app", router: new VueRouter({ routes }), template: "", components: { AcademyRoot }, created: function() { - if(store.checkLogin()){ - store.updateState() - } - } - }); - academy.store = new Vue({ - data: store, - methods: { - checkLogin (){ - if(frappe.session.user === "Guest"){ - if (this.debug) console.log('No Session') - this.isLogin = false - } - else { - if (this.debug) console.log('Current User: ', frappe.session.user) - this.isLogin = true - } - return this.isLogin + if(academy.store.checkLogin()){ + academy.store.updateState() } } }); + + academy.debug = true }) \ No newline at end of file diff --git a/erpnext/public/js/education/academy/call.js b/erpnext/public/js/education/academy/call.js index 108a6e1d36..64f914d69b 100644 --- a/erpnext/public/js/education/academy/call.js +++ b/erpnext/public/js/education/academy/call.js @@ -1,13 +1,15 @@ -frappe.provide('academy'); +frappe.ready(() => { + frappe.provide('academy'); -academy.call = (method, args) => { - const method_path = 'erpnext.www.academy.' + method; - return new Promise((resolve, reject) => { - return frappe.call({ - method: method_path, - args, - }) - .then(r => resolve(r.message)) - .fail(reject) - }); -} \ No newline at end of file + academy.call = (method, args) => { + const method_path = 'erpnext.www.academy.' + method; + return new Promise((resolve, reject) => { + return frappe.call({ + method: method_path, + args, + }) + .then(r => resolve(r.message)) + .fail(reject) + }); + } +}); \ No newline at end of file diff --git a/erpnext/public/js/education/academy/components/AcademyProgramCard.vue b/erpnext/public/js/education/academy/components/AcademyProgramCard.vue index ef3ac0896b..bea2acf825 100644 --- a/erpnext/public/js/education/academy/components/AcademyProgramCard.vue +++ b/erpnext/public/js/education/academy/components/AcademyProgramCard.vue @@ -10,65 +10,61 @@ diff --git a/erpnext/public/js/education/academy/pages/AcademyHome.vue b/erpnext/public/js/education/academy/pages/AcademyHome.vue index 630573a757..e59074567e 100644 --- a/erpnext/public/js/education/academy/pages/AcademyHome.vue +++ b/erpnext/public/js/education/academy/pages/AcademyHome.vue @@ -1,10 +1,10 @@ @@ -18,9 +18,9 @@ export default { name: "AcademyHome", data() { return{ - title: '', - description: '', - featured_programs: [] + portal: {}, + featuredPrograms: [], + // enrolledPrograms: new Set() } }, components: { @@ -28,15 +28,28 @@ export default { AcademyList, AcademyProgramCard, AcademyTopSectionButton - }, - mounted() { - frappe.call("erpnext.www.academy.get_portal_details").then(r => { - this.title = r.message.title, - this.description = r.message.description - }); - frappe.call("erpnext.www.academy.get_featured_programs").then(r => { - this.featured_programs = r.message - }); }, + beforeMount() { + // this.updateEnrolledPrograms().then(data => { + // data.forEach(element => { + // this.enrolledPrograms.add(element) + // }) + // }); + }, + mounted() { + this.getPortalDetails().then(data => this.portal = data); + this.getFeaturedPrograms().then(data => this.featuredPrograms = data); + }, + methods: { + // updateEnrolledPrograms(){ + // return academy.call("get_program_enrollments") + // }, + getPortalDetails() { + return academy.call("get_portal_details") + }, + getFeaturedPrograms() { + return academy.call("get_featured_programs") + } + } }; \ No newline at end of file diff --git a/erpnext/public/js/education/academy/routes.js b/erpnext/public/js/education/academy/routes.js index 51c280d72a..7896b1d94c 100644 --- a/erpnext/public/js/education/academy/routes.js +++ b/erpnext/public/js/education/academy/routes.js @@ -1,6 +1,6 @@ -import AcademyHome from "./academy/pages/AcademyHome.vue"; -import AcademyProgramPage from "./academy/pages/AcademyProgramPage.vue"; -import AcademyCoursePage from "./academy/pages/AcademyCoursePage.vue"; +import AcademyHome from "./pages/AcademyHome.vue"; +import AcademyProgramPage from "./pages/AcademyProgramPage.vue"; +import AcademyCoursePage from "./pages/AcademyCoursePage.vue"; const routes = [ {name: 'home', path: '', component: AcademyHome}, diff --git a/erpnext/www/academy.html b/erpnext/www/academy.html index 9d3cec8a51..f078b3695c 100644 --- a/erpnext/www/academy.html +++ b/erpnext/www/academy.html @@ -3,6 +3,6 @@ {% block title %}{{ heading or "Academy"}}{% endblock %} {% block page_content %} -
+
{% endblock %} \ No newline at end of file From db9c8b795a968462b9b0bc4b9b75aeedbab47d07 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 9 Nov 2018 18:25:44 +0530 Subject: [PATCH 100/314] Functions now have a login context --- erpnext/www/academy.py | 119 +++++++++++++++++++++++++++++------------ 1 file changed, 86 insertions(+), 33 deletions(-) diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py index 94a0a71687..87eabcbd8f 100644 --- a/erpnext/www/academy.py +++ b/erpnext/www/academy.py @@ -1,7 +1,7 @@ from __future__ import unicode_literals import frappe -# Functions to get homepage details +# Academy Utils @frappe.whitelist(allow_guest=True) def get_portal_details(): settings = frappe.get_doc("Education Settings") @@ -9,15 +9,63 @@ def get_portal_details(): description = settings.description return dict(title=title, description=description) +def check_program_enrollment(program_name): + if frappe.session.user in ("Guest", "Administrator"): + return False + student = get_student_id(frappe.session.user) + enrollment = frappe.get_list("Program Enrollment", filters={'student':student, 'program': program_name}) + if enrollment: + return True + else: + return False + @frappe.whitelist(allow_guest=True) def get_featured_programs(): featured_program_names = frappe.get_all("Program", filters={"is_published": True, "is_featured": True}) - featured_list = [program["name"] for program in featured_program_names] - if featured_list: + if featured_program_names: + featured_list = [get_program(program['name']) for program in featured_program_names] return featured_list else: return None +def get_program(program_name): + program = frappe.get_doc('Program', program_name) + is_enrolled = check_program_enrollment(program_name) + return {'program': program, 'is_enrolled': is_enrolled} + + +def get_enrollment(course_name): + student = get_student_id(frappe.session.user) + enrollment_name = frappe.get_all("Course Enrollment", filters={'student': student, 'course':course_name}) + try: + name = enrollment_name[0].name + enrollment = frappe.get_doc("Course Enrollment", name) + return enrollment + except: + return None + +@frappe.whitelist() +def get_student_id(email=None): + """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series). + + :param user: a user email address + """ + try: + student_id = frappe.db.get_all("Student", {"student_email_id": email}, ["name"])[0].name + return student_id + except IndexError: + return None + +def create_student(student_name=frappe.session.user): + student = frappe.get_doc({ + "doctype": "Student", + "first_name": student_name, + "student_email_id": student_name, + }) + student.save(ignore_permissions=True) + frappe.db.commit() + return student_name + # Functions to get program & course details @frappe.whitelist(allow_guest=True) def get_program_details(program_name): @@ -31,7 +79,31 @@ def get_program_details(program_name): def get_courses(program_name): program = frappe.get_doc('Program', program_name) courses = program.get_course_list() - return courses + course_data = [{'meta':get_continue_content(item.name), 'course':item} for item in courses] + return course_data + +@frappe.whitelist() +def get_continue_content(course_name): + enrollment = get_enrollment(course_name) + course = frappe.get_doc("Course", enrollment.course) + last_activity = enrollment.get_last_activity() + + if last_activity == None: + next_content = course.get_first_content() + return dict(content=next_content.name, content_type=next_content.doctype, flag="Start") + + if last_activity.doctype == "Quiz Activity": + next_content = get_next_content(last_activity.quiz, "Quiz", course.name) + else: + next_content = get_next_content(last_activity.content, last_activity.content_type, course.name) + + if next_content == None: + next_content = course.get_first_content() + return dict(content=next_content.name, content_type=next_content.doctype, flag="Complete") + else: + next_content['flag'] = "Continue" + return next_content + @frappe.whitelist() def get_starting_content(course_name): @@ -40,7 +112,6 @@ def get_starting_content(course_name): content_type = course.course_content[0].content_type return dict(content=content, content_type=content_type) - # Functions to get content details @frappe.whitelist() def get_content(content_name, content_type): @@ -109,11 +180,12 @@ def evaluate_quiz(enrollment, quiz_response, quiz_name): return(score) @frappe.whitelist() -def get_completed_courses(email=frappe.session.user): - if get_student_id(email) == None: +def get_completed_courses(): + student = get_student_id(frappe.session.user) + if student == None: return None try: - student = frappe.get_doc("Student", get_student_id(email)) + student = frappe.get_doc("Student", student) return student.get_completed_courses() except: return None @@ -129,16 +201,6 @@ def get_continue_data(program_name): except: return None -def create_student(student_name=frappe.session.user): - student = frappe.get_doc({ - "doctype": "Student", - "first_name": student_name, - "student_email_id": student_name, - }) - student.save(ignore_permissions=True) - frappe.db.commit() - return student_name - @frappe.whitelist() def enroll_all_courses_in_program(program_enrollment, student): course_list = [course.name for course in get_courses(program_enrollment.program)] @@ -153,18 +215,6 @@ def enroll_in_program(program_name, student_email_id): program_enrollment = student.enroll_in_program(program_name) enroll_all_courses_in_program(program_enrollment, student) -@frappe.whitelist() -def get_student_id(email=None): - """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series). - - :param user: a user email address - """ - try: - student_id = frappe.db.get_all("Student", {"student_email_id": email}, ["name"])[0].name - return student_id - except IndexError: - return None - @frappe.whitelist() def get_program_enrollments(email=frappe.session.user): if get_student_id(email) == None: @@ -176,15 +226,18 @@ def get_program_enrollments(email=frappe.session.user): return None @frappe.whitelist() -def get_course_enrollments(email=frappe.session.user): - if get_student_id(email) == None: +def get_course_enrollments(): + student = get_student_id(frappe.session.user) + if student == None: return None try: - student = frappe.get_doc("Student", get_student_id(email)) + student = frappe.get_doc("Student", student) return student.get_course_enrollments() except: return None + +# Academty Activity @frappe.whitelist() def add_activity(enrollment, content_type, content): if(check_activity_exists(enrollment, content_type, content)): From f9b2fb6717cd35bebb82d4c4732bb51a382b00fb Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 12 Nov 2018 12:50:54 +0530 Subject: [PATCH 101/314] Fixed course and content page --- .../course_enrollment/course_enrollment.json | 4 +- .../academy/components/AcademyCourseCard.vue | 64 ++++++------------- .../components/AcademyCourseCardButton.vue | 4 +- .../components/AcademyTopSectionButton.vue | 14 ++-- .../academy/components/ContentNavigation.vue | 12 ++-- .../academy/components/ContentQuiz.vue | 2 +- .../academy/pages/AcademyCoursePage.vue | 2 +- .../academy/pages/AcademyProgramPage.vue | 25 ++++---- erpnext/public/js/education/academy/routes.js | 2 +- erpnext/www/academy.py | 29 +++++---- 10 files changed, 67 insertions(+), 91 deletions(-) diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.json b/erpnext/education/doctype/course_enrollment/course_enrollment.json index 5de7f21493..a5b4289dca 100644 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.json +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.json @@ -62,7 +62,7 @@ "in_filter": 0, "in_global_search": 0, "in_list_view": 0, - "in_standard_filter": 0, + "in_standard_filter": 1, "label": "Student", "length": 0, "no_copy": 0, @@ -190,7 +190,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-11-07 21:16:34.764628", + "modified": "2018-11-09 19:23:07.967967", "modified_by": "Administrator", "module": "Education", "name": "Course Enrollment", diff --git a/erpnext/public/js/education/academy/components/AcademyCourseCard.vue b/erpnext/public/js/education/academy/components/AcademyCourseCard.vue index eda382f4fa..16ffc558d2 100644 --- a/erpnext/public/js/education/academy/components/AcademyCourseCard.vue +++ b/erpnext/public/js/education/academy/components/AcademyCourseCard.vue @@ -11,29 +11,13 @@ -
- - +
- Completed - - - Start + {{ courseMeta.flag }}
@@ -42,44 +26,36 @@ -{% endblock %} \ No newline at end of file diff --git a/erpnext/www/academy.py b/erpnext/www/academy.py deleted file mode 100644 index 294c41f1e7..0000000000 --- a/erpnext/www/academy.py +++ /dev/null @@ -1,282 +0,0 @@ -from __future__ import unicode_literals -import frappe - -# Academy Utils -@frappe.whitelist(allow_guest=True) -def get_portal_details(): - settings = frappe.get_doc("Education Settings") - title = settings.portal_title - description = settings.description - return dict(title=title, description=description) - -def check_program_enrollment(program_name): - if frappe.session.user in ("Guest", "Administrator"): - return False - student = get_student_id(frappe.session.user) - enrollment = frappe.get_list("Program Enrollment", filters={'student':student, 'program': program_name}) - if enrollment: - return True - else: - return False - -@frappe.whitelist(allow_guest=True) -def get_featured_programs(): - featured_program_names = frappe.get_all("Program", filters={"is_published": True, "is_featured": True}) - if featured_program_names: - featured_list = [get_program(program['name']) for program in featured_program_names] - return featured_list - else: - return None - -def get_program(program_name): - program = frappe.get_doc('Program', program_name) - is_enrolled = check_program_enrollment(program_name) - return {'program': program, 'is_enrolled': is_enrolled} - -@frappe.whitelist(allow_guest=True) -def get_program_details(program_name): - try: - program = frappe.get_doc('Program', program_name) - return program - except: - return None - - -def get_enrollment(course_name): - student = get_student_id(frappe.session.user) - enrollment_name = frappe.get_all("Course Enrollment", filters={'student': student, 'course':course_name}) - try: - name = enrollment_name[0].name - enrollment = frappe.get_doc("Course Enrollment", name) - return enrollment - except: - return None - -@frappe.whitelist() -def get_student_id(email=None): - """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series). - - :param user: a user email address - """ - try: - student_id = frappe.db.get_all("Student", {"student_email_id": email}, ["name"])[0].name - return student_id - except IndexError: - return None - -def create_student(student_name=frappe.session.user): - student = frappe.get_doc({ - "doctype": "Student", - "first_name": student_name, - "student_email_id": student_name, - }) - student.save(ignore_permissions=True) - frappe.db.commit() - return student_name - -# Functions to get program & course details -@frappe.whitelist(allow_guest=True) -def get_courses(program_name): - program = frappe.get_doc('Program', program_name) - courses = program.get_course_list() - course_data = [{'meta':get_continue_content(item.name), 'course':item} for item in courses] - return course_data - -@frappe.whitelist() -def get_continue_content(course_name): - if frappe.session.user == "Guest": - return dict(content=None, content_type=None, flag=None) - enrollment = get_enrollment(course_name) - course = frappe.get_doc("Course", enrollment.course) - last_activity = enrollment.get_last_activity() - - if last_activity == None: - next_content = course.get_first_content() - return dict(content=next_content.name, content_type=next_content.doctype, flag="Start") - - if last_activity.doctype == "Quiz Activity": - next_content = get_next_content(last_activity.quiz, "Quiz", course.name) - else: - next_content = get_next_content(last_activity.content, last_activity.content_type, course.name) - - if next_content == None: - next_content = course.get_first_content() - return dict(content=next_content.name, content_type=next_content.doctype, flag="Complete") - else: - next_content['flag'] = "Continue" - return next_content - - -@frappe.whitelist() -def get_starting_content(course_name): - course = frappe.get_doc('Course', course_name) - content = course.course_content[0].content - content_type = course.course_content[0].content_type - return dict(content=content, content_type=content_type) - -# Functions to get content details -@frappe.whitelist() -def get_content(content_name, content_type): - try: - content = frappe.get_doc(content_type, content_name) - return content - except: - frappe.throw("{0} with name {1} does not exist".format(content_type, content_name)) - return None - -@frappe.whitelist() -def get_next_content(content, content_type, course): - if frappe.session.user == "Guest": - return None - course_doc = frappe.get_doc("Course", course) - content_list = [{'content_type':item.content_type, 'content':item.content} for item in course_doc.get_all_children()] - current_index = content_list.index({'content': content, 'content_type': content_type}) - try: - return content_list[current_index + 1] - except IndexError: - return None - -def get_quiz_with_answers(quiz_name): - try: - quiz = frappe.get_doc("Quiz", quiz_name).get_questions() - quiz_output = [{'name':question.name, 'question':question.question, 'options':[{'name': option.name, 'option':option.option, 'is_correct':option.is_correct} for option in question.options]} for question in quiz] - return quiz_output - except: - frappe.throw("Quiz {0} does not exist".format(quiz_name)) - return None - -@frappe.whitelist() -def get_quiz_without_answers(quiz_name): - try: - quiz = frappe.get_doc("Quiz", quiz_name).get_questions() - quiz_output = [{'name':question.name, 'question':question.question, 'options':[{'name': option.name, 'option':option.option} for option in question.options]} for question in quiz] - return quiz_output - except: - frappe.throw("Quiz {0} does not exist".format(quiz_name)) - return None - -@frappe.whitelist() -def evaluate_quiz(enrollment, quiz_response, quiz_name): - """LMS Function: Evaluates a simple multiple choice quiz. - - - :param quiz_response: contains user selected choices for a quiz in the form of a string formatted as a dictionary. The function uses `json.loads()` to convert it to a python dictionary. - """ - import json - quiz_response = json.loads(quiz_response) - quiz = frappe.get_doc("Quiz", quiz_name) - answers, score, status = quiz.evaluate(quiz_response, quiz_name) - - result = {k: ('Correct' if v else 'Wrong') for k,v in answers.items()} - result_data = [] - for key in answers: - item = {} - item['question'] = key - item['quiz_result'] = result[key] - try: - item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option') - except: - item['selected_option'] = "Unattempted" - result_data.append(item) - # result_data = [{'question': key, 'selected_option': frappe.get_value('Options', quiz_response[key], 'option'), 'quiz_result': result[key]} for key in answers] - - add_quiz_activity(enrollment, quiz_name, result_data, score, status) - return(score) - -@frappe.whitelist() -def get_completed_courses(): - student = get_student_id(frappe.session.user) - if student == None: - return None - try: - student = frappe.get_doc("Student", student) - return student.get_completed_courses() - except: - return None - -@frappe.whitelist() -def get_continue_data(program_name): - program = frappe.get_doc("Program", program_name) - courses = program.get_all_children() - try: - continue_data = get_starting_content(courses[0].course) - continue_data['course'] = courses[0].course - return continue_data - except: - return None - -@frappe.whitelist() -def enroll_all_courses_in_program(program_enrollment, student): - program = frappe.get_doc("Program", program_enrollment.program) - course_list = [course.course for course in program.get_all_children()] - for course_name in course_list: - student.enroll_in_course(course_name=course_name, program_enrollment=program_enrollment.name) - -@frappe.whitelist() -def enroll_in_program(program_name): - if(not get_student_id(frappe.session.user)): - create_student(frappe.session.user) - student = frappe.get_doc("Student", get_student_id(frappe.session.user)) - program_enrollment = student.enroll_in_program(program_name) - enroll_all_courses_in_program(program_enrollment, student) - -@frappe.whitelist() -def get_program_enrollments(email=frappe.session.user): - if get_student_id(email) == None: - return None - try: - student = frappe.get_doc("Student", get_student_id(email)) - return student.get_program_enrollments() - except: - return None - -@frappe.whitelist() -def get_course_enrollments(): - student = get_student_id(frappe.session.user) - if student == None: - return None - try: - student = frappe.get_doc("Student", student) - return student.get_course_enrollments() - except: - return None - - -# Academty Activity -@frappe.whitelist() -def add_activity(enrollment, content_type, content): - if(check_activity_exists(enrollment, content_type, content)): - pass - else: - activity = frappe.get_doc({ - "doctype": "Course Activity", - "enrollment": enrollment, - "content_type": content_type, - "content": content, - "activity_date": frappe.utils.datetime.datetime.now() - }) - activity.save() - frappe.db.commit() - -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) - -def add_quiz_activity(enrollment, quiz_name, result_data, score, status): - quiz_activity = frappe.get_doc({ - "doctype": "Quiz Activity", - "enrollment": enrollment, - "quiz": quiz_name, - "result": result_data, - "score": score, - "status": status - }) - quiz_activity.save() - frappe.db.commit() - -@frappe.whitelist() -def mark_course_complete(enrollment): - course_enrollment = frappe.get_doc("Course Enrollment", enrollment) - course_enrollment.completed = True - course_enrollment.save() - frappe.db.commit() From 91bbe776c1a477db27b783335ebf1adf5125fe6d Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 13 Nov 2018 16:35:34 +0530 Subject: [PATCH 105/314] Modified `academy.call` to point to erpnext.www.lms --- erpnext/public/js/education/academy/call.js | 2 +- .../academy/components/AcademyTopSectionButton.vue | 4 ++-- .../js/education/academy/components/ContentArticle.vue | 2 +- .../js/education/academy/components/ContentNavigation.vue | 6 +++--- .../public/js/education/academy/components/ContentQuiz.vue | 4 ++-- .../public/js/education/academy/components/ContentVideo.vue | 2 +- .../public/js/education/academy/pages/AcademyCoursePage.vue | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/erpnext/public/js/education/academy/call.js b/erpnext/public/js/education/academy/call.js index 64f914d69b..bdcca3ad4d 100644 --- a/erpnext/public/js/education/academy/call.js +++ b/erpnext/public/js/education/academy/call.js @@ -2,7 +2,7 @@ frappe.ready(() => { frappe.provide('academy'); academy.call = (method, args) => { - const method_path = 'erpnext.www.academy.' + method; + const method_path = 'erpnext.www.lms.' + method; return new Promise((resolve, reject) => { return frappe.call({ method: method_path, diff --git a/erpnext/public/js/education/academy/components/AcademyTopSectionButton.vue b/erpnext/public/js/education/academy/components/AcademyTopSectionButton.vue index 2bab29d96d..8adb5ecc36 100644 --- a/erpnext/public/js/education/academy/components/AcademyTopSectionButton.vue +++ b/erpnext/public/js/education/academy/components/AcademyTopSectionButton.vue @@ -18,7 +18,7 @@ export default { mounted() { if(this.isLoggedIn && this.$route.name == 'program'){ frappe.call({ - method: "erpnext.www.academy.get_continue_data", + method: "erpnext.www.lms.get_continue_data", args: { program_name: this.$route.params.program_name } @@ -56,7 +56,7 @@ export default { } else { frappe.call({ - method: "erpnext.www.academy.enroll_in_program", + method: "erpnext.www.lms.enroll_in_program", args:{ program_name: this.$route.params.program_name, student_email_id: frappe.session.user diff --git a/erpnext/public/js/education/academy/components/ContentArticle.vue b/erpnext/public/js/education/academy/components/ContentArticle.vue index 64bfb86a3e..b0fc0e6c5f 100644 --- a/erpnext/public/js/education/academy/components/ContentArticle.vue +++ b/erpnext/public/js/education/academy/components/ContentArticle.vue @@ -28,7 +28,7 @@ export default { }, mounted() { frappe.call({ - method: "erpnext.www.academy.get_content", + method: "erpnext.www.lms.get_content", args: { content_name: this.content, content_type: this.type diff --git a/erpnext/public/js/education/academy/components/ContentNavigation.vue b/erpnext/public/js/education/academy/components/ContentNavigation.vue index 8c8280cb04..421606dfae 100644 --- a/erpnext/public/js/education/academy/components/ContentNavigation.vue +++ b/erpnext/public/js/education/academy/components/ContentNavigation.vue @@ -14,7 +14,7 @@ export default { goNext() { if(this.$route.params.type != "Quiz"){ frappe.call({ - method: "erpnext.www.academy.add_activity", + method: "erpnext.www.lms.add_activity", args: { enrollment: academy.store.enrolledCourses[this.$route.params.course], content_type: this.$route.params.type, @@ -27,7 +27,7 @@ export default { finish() { if(this.$route.params.type != "Quiz"){ frappe.call({ - method: "erpnext.www.academy.add_activity", + method: "erpnext.www.lms.add_activity", args: { enrollment: academy.store.enrolledCourses[this.$route.params.course], content_type: this.$route.params.type, @@ -36,7 +36,7 @@ export default { }) } frappe.call({ - method: "erpnext.www.academy.mark_course_complete", + method: "erpnext.www.lms.mark_course_complete", args: { enrollment: academy.store.enrolledCourses[this.$route.params.course] } diff --git a/erpnext/public/js/education/academy/components/ContentQuiz.vue b/erpnext/public/js/education/academy/components/ContentQuiz.vue index b13b5e6e07..149d314b9d 100644 --- a/erpnext/public/js/education/academy/components/ContentQuiz.vue +++ b/erpnext/public/js/education/academy/components/ContentQuiz.vue @@ -53,7 +53,7 @@ export default { }, mounted() { frappe.call({ - method: "erpnext.www.academy.get_quiz_without_answers", + method: "erpnext.www.lms.get_quiz_without_answers", args: { quiz_name: this.content, } @@ -70,7 +70,7 @@ export default { }, submitQuiz() { frappe.call({ - method: "erpnext.www.academy.evaluate_quiz", + method: "erpnext.www.lms.evaluate_quiz", args: { enrollment: academy.store.enrolledCourses[this.$route.params.course], quiz_response: this.quizResponse, diff --git a/erpnext/public/js/education/academy/components/ContentVideo.vue b/erpnext/public/js/education/academy/components/ContentVideo.vue index e3dbad7d14..95a6178f54 100644 --- a/erpnext/public/js/education/academy/components/ContentVideo.vue +++ b/erpnext/public/js/education/academy/components/ContentVideo.vue @@ -47,7 +47,7 @@ export default { }, mounted() { frappe.call({ - method: "erpnext.www.academy.get_content", + method: "erpnext.www.lms.get_content", args: { content_name: this.content, content_type: this.type diff --git a/erpnext/public/js/education/academy/pages/AcademyCoursePage.vue b/erpnext/public/js/education/academy/pages/AcademyCoursePage.vue index 81cf4ff847..9d50afe0a5 100644 --- a/erpnext/public/js/education/academy/pages/AcademyCoursePage.vue +++ b/erpnext/public/js/education/academy/pages/AcademyCoursePage.vue @@ -35,7 +35,7 @@ export default { }, mounted() { frappe.call({ - method: "erpnext.www.academy.get_next_content", + method: "erpnext.www.lms.get_next_content", args:{ content: this.content, content_type: this.type, From 44921a3ee929513ae9806a23ce63f17515d146d2 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 13 Nov 2018 16:35:52 +0530 Subject: [PATCH 106/314] Renamed default element for Vue to mount on --- erpnext/public/js/education/academy/academy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/erpnext/public/js/education/academy/academy.js b/erpnext/public/js/education/academy/academy.js index 961dc3926a..e8e96f1c12 100644 --- a/erpnext/public/js/education/academy/academy.js +++ b/erpnext/public/js/education/academy/academy.js @@ -101,7 +101,7 @@ frappe.ready(() => { }); academy.view = new Vue({ - el: "#academy-app", + el: "#lms-app", router: new VueRouter({ routes }), template: "", components: { AcademyRoot }, From 35bf561a6fc64fed0f2a7509de0fff98a6528c2e Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 13 Nov 2018 16:36:22 +0530 Subject: [PATCH 107/314] Renamed academy to lms on server side --- erpnext/www/lms.html | 8 ++ erpnext/www/lms.py | 283 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 291 insertions(+) create mode 100644 erpnext/www/lms.html create mode 100644 erpnext/www/lms.py diff --git a/erpnext/www/lms.html b/erpnext/www/lms.html new file mode 100644 index 0000000000..66fae7a3f3 --- /dev/null +++ b/erpnext/www/lms.html @@ -0,0 +1,8 @@ +{% extends "templates/web.html" %} + +{% block title %}{{ heading or "Academy"}}{% endblock %} + +{% block page_content %} +
+ +{% endblock %} \ No newline at end of file diff --git a/erpnext/www/lms.py b/erpnext/www/lms.py new file mode 100644 index 0000000000..ab01aed9d9 --- /dev/null +++ b/erpnext/www/lms.py @@ -0,0 +1,283 @@ +from __future__ import unicode_literals +import frappe + +# Academy Utils +@frappe.whitelist(allow_guest=True) +def get_portal_details(): + settings = frappe.get_doc("Education Settings") + title = settings.portal_title + description = settings.description + return dict(title=title, description=description) + +def check_program_enrollment(program_name): + if frappe.session.user in ("Guest", "Administrator"): + return False + student = get_student_id(frappe.session.user) + enrollment = frappe.get_list("Program Enrollment", filters={'student':student, 'program': program_name}) + if enrollment: + return True + else: + return False + +@frappe.whitelist(allow_guest=True) +def get_featured_programs(): + featured_program_names = frappe.get_all("Program", filters={"is_published": True, "is_featured": True}) + if featured_program_names: + featured_list = [get_program(program['name']) for program in featured_program_names] + return featured_list + else: + return None + +def get_program(program_name): + program = frappe.get_doc('Program', program_name) + is_enrolled = check_program_enrollment(program_name) + return {'program': program, 'is_enrolled': is_enrolled} + +@frappe.whitelist(allow_guest=True) +def get_program_details(program_name): + try: + program = frappe.get_doc('Program', program_name) + return program + except: + return None + + +def get_enrollment(course_name): + student = get_student_id(frappe.session.user) + enrollment_name = frappe.get_all("Course Enrollment", filters={'student': student, 'course':course_name}) + try: + name = enrollment_name[0].name + enrollment = frappe.get_doc("Course Enrollment", name) + return enrollment + except: + return None + +@frappe.whitelist() +def get_student_id(email=None): + """Returns student user name, example EDU-STU-2018-00001 (Based on the naming series). + + :param user: a user email address + """ + try: + student_id = frappe.db.get_all("Student", {"student_email_id": email}, ["name"])[0].name + return student_id + except IndexError: + return None + +def create_student(): + student_name=frappe.session.user + student = frappe.get_doc({ + "doctype": "Student", + "first_name": student_name, + "student_email_id": student_name, + }) + student.save(ignore_permissions=True) + frappe.db.commit() + return student_name + +# Functions to get program & course details +@frappe.whitelist(allow_guest=True) +def get_courses(program_name): + program = frappe.get_doc('Program', program_name) + courses = program.get_course_list() + course_data = [{'meta':get_continue_content(item.name), 'course':item} for item in courses] + return course_data + +@frappe.whitelist() +def get_continue_content(course_name): + if frappe.session.user == "Guest": + return dict(content=None, content_type=None, flag=None) + enrollment = get_enrollment(course_name) + course = frappe.get_doc("Course", enrollment.course) + last_activity = enrollment.get_last_activity() + + if last_activity == None: + next_content = course.get_first_content() + return dict(content=next_content.name, content_type=next_content.doctype, flag="Start") + + if last_activity.doctype == "Quiz Activity": + next_content = get_next_content(last_activity.quiz, "Quiz", course.name) + else: + next_content = get_next_content(last_activity.content, last_activity.content_type, course.name) + + if next_content == None: + next_content = course.get_first_content() + return dict(content=next_content.name, content_type=next_content.doctype, flag="Complete") + else: + next_content['flag'] = "Continue" + return next_content + + +@frappe.whitelist() +def get_starting_content(course_name): + course = frappe.get_doc('Course', course_name) + content = course.course_content[0].content + content_type = course.course_content[0].content_type + return dict(content=content, content_type=content_type) + +# Functions to get content details +@frappe.whitelist() +def get_content(content_name, content_type): + try: + content = frappe.get_doc(content_type, content_name) + return content + except: + frappe.throw("{0} with name {1} does not exist".format(content_type, content_name)) + return None + +@frappe.whitelist() +def get_next_content(content, content_type, course): + if frappe.session.user == "Guest": + return None + course_doc = frappe.get_doc("Course", course) + content_list = [{'content_type':item.content_type, 'content':item.content} for item in course_doc.get_all_children()] + current_index = content_list.index({'content': content, 'content_type': content_type}) + try: + return content_list[current_index + 1] + except IndexError: + return None + +def get_quiz_with_answers(quiz_name): + try: + quiz = frappe.get_doc("Quiz", quiz_name).get_questions() + quiz_output = [{'name':question.name, 'question':question.question, 'options':[{'name': option.name, 'option':option.option, 'is_correct':option.is_correct} for option in question.options]} for question in quiz] + return quiz_output + except: + frappe.throw("Quiz {0} does not exist".format(quiz_name)) + return None + +@frappe.whitelist() +def get_quiz_without_answers(quiz_name): + try: + quiz = frappe.get_doc("Quiz", quiz_name).get_questions() + quiz_output = [{'name':question.name, 'question':question.question, 'options':[{'name': option.name, 'option':option.option} for option in question.options]} for question in quiz] + return quiz_output + except: + frappe.throw("Quiz {0} does not exist".format(quiz_name)) + return None + +@frappe.whitelist() +def evaluate_quiz(enrollment, quiz_response, quiz_name): + """LMS Function: Evaluates a simple multiple choice quiz. + + + :param quiz_response: contains user selected choices for a quiz in the form of a string formatted as a dictionary. The function uses `json.loads()` to convert it to a python dictionary. + """ + import json + quiz_response = json.loads(quiz_response) + quiz = frappe.get_doc("Quiz", quiz_name) + answers, score, status = quiz.evaluate(quiz_response, quiz_name) + + result = {k: ('Correct' if v else 'Wrong') for k,v in answers.items()} + result_data = [] + for key in answers: + item = {} + item['question'] = key + item['quiz_result'] = result[key] + try: + item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option') + except: + item['selected_option'] = "Unattempted" + result_data.append(item) + # result_data = [{'question': key, 'selected_option': frappe.get_value('Options', quiz_response[key], 'option'), 'quiz_result': result[key]} for key in answers] + + add_quiz_activity(enrollment, quiz_name, result_data, score, status) + return(score) + +@frappe.whitelist() +def get_completed_courses(): + student = get_student_id(frappe.session.user) + if student == None: + return None + try: + student = frappe.get_doc("Student", student) + return student.get_completed_courses() + except: + return None + +@frappe.whitelist() +def get_continue_data(program_name): + program = frappe.get_doc("Program", program_name) + courses = program.get_all_children() + try: + continue_data = get_starting_content(courses[0].course) + continue_data['course'] = courses[0].course + return continue_data + except: + return None + +@frappe.whitelist() +def enroll_all_courses_in_program(program_enrollment, student): + program = frappe.get_doc("Program", program_enrollment.program) + course_list = [course.course for course in program.get_all_children()] + for course_name in course_list: + student.enroll_in_course(course_name=course_name, program_enrollment=program_enrollment.name) + +@frappe.whitelist() +def enroll_in_program(program_name): + if(not get_student_id(frappe.session.user)): + create_student(frappe.session.user) + student = frappe.get_doc("Student", get_student_id(frappe.session.user)) + program_enrollment = student.enroll_in_program(program_name) + enroll_all_courses_in_program(program_enrollment, student) + +@frappe.whitelist() +def get_program_enrollments(email=frappe.session.user): + if get_student_id(email) == None: + return None + try: + student = frappe.get_doc("Student", get_student_id(email)) + return student.get_program_enrollments() + except: + return None + +@frappe.whitelist() +def get_course_enrollments(): + student = get_student_id(frappe.session.user) + if student == None: + return None + try: + student = frappe.get_doc("Student", student) + return student.get_course_enrollments() + except: + return None + + +# Academty Activity +@frappe.whitelist() +def add_activity(enrollment, content_type, content): + if(check_activity_exists(enrollment, content_type, content)): + pass + else: + activity = frappe.get_doc({ + "doctype": "Course Activity", + "enrollment": enrollment, + "content_type": content_type, + "content": content, + "activity_date": frappe.utils.datetime.datetime.now() + }) + activity.save() + frappe.db.commit() + +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) + +def add_quiz_activity(enrollment, quiz_name, result_data, score, status): + quiz_activity = frappe.get_doc({ + "doctype": "Quiz Activity", + "enrollment": enrollment, + "quiz": quiz_name, + "result": result_data, + "score": score, + "status": status + }) + quiz_activity.save() + frappe.db.commit() + +@frappe.whitelist() +def mark_course_complete(enrollment): + course_enrollment = frappe.get_doc("Course Enrollment", enrollment) + course_enrollment.completed = True + course_enrollment.save() + frappe.db.commit() From 1fbe2d4b2b1d5cb4344249602d0112e56e68d052 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 13 Nov 2018 16:47:46 +0530 Subject: [PATCH 108/314] Renamed academy to lms (Client Side) --- erpnext/public/build.json | 2 +- .../{academy => lms}/AcademyRoot.vue | 0 .../js/education/{academy => lms}/call.js | 4 +- .../components/AcademyCourseCard.vue | 4 +- .../components/AcademyCourseCardButton.vue | 4 +- .../components/AcademyList.vue | 0 .../components/AcademyProgramCard.vue | 10 ++--- .../components/AcademyTopSection.vue | 0 .../components/AcademyTopSectionButton.vue | 8 ++-- .../{academy => lms}/components/Button.vue | 0 .../components/ContentArticle.vue | 0 .../components/ContentNavigation.vue | 12 +++--- .../components/ContentQuiz.vue | 2 +- .../components/ContentTitle.vue | 0 .../components/ContentVideo.vue | 0 .../components/Quiz/QuizSingleChoice.vue | 0 .../{academy/academy.js => lms/lms.js} | 38 +++++++++---------- .../pages/AcademyCoursePage.vue | 0 .../{academy => lms}/pages/AcademyHome.vue | 6 +-- .../pages/AcademyProgramPage.vue | 10 ++--- .../js/education/{academy => lms}/routes.js | 0 21 files changed, 50 insertions(+), 50 deletions(-) rename erpnext/public/js/education/{academy => lms}/AcademyRoot.vue (100%) rename erpnext/public/js/education/{academy => lms}/call.js (82%) rename erpnext/public/js/education/{academy => lms}/components/AcademyCourseCard.vue (93%) rename erpnext/public/js/education/{academy => lms}/components/AcademyCourseCardButton.vue (84%) rename erpnext/public/js/education/{academy => lms}/components/AcademyList.vue (100%) rename erpnext/public/js/education/{academy => lms}/components/AcademyProgramCard.vue (87%) rename erpnext/public/js/education/{academy => lms}/components/AcademyTopSection.vue (100%) rename erpnext/public/js/education/{academy => lms}/components/AcademyTopSectionButton.vue (86%) rename erpnext/public/js/education/{academy => lms}/components/Button.vue (100%) rename erpnext/public/js/education/{academy => lms}/components/ContentArticle.vue (100%) rename erpnext/public/js/education/{academy => lms}/components/ContentNavigation.vue (77%) rename erpnext/public/js/education/{academy => lms}/components/ContentQuiz.vue (96%) rename erpnext/public/js/education/{academy => lms}/components/ContentTitle.vue (100%) rename erpnext/public/js/education/{academy => lms}/components/ContentVideo.vue (100%) rename erpnext/public/js/education/{academy => lms}/components/Quiz/QuizSingleChoice.vue (100%) rename erpnext/public/js/education/{academy/academy.js => lms/lms.js} (64%) rename erpnext/public/js/education/{academy => lms}/pages/AcademyCoursePage.vue (100%) rename erpnext/public/js/education/{academy => lms}/pages/AcademyHome.vue (89%) rename erpnext/public/js/education/{academy => lms}/pages/AcademyProgramPage.vue (86%) rename erpnext/public/js/education/{academy => lms}/routes.js (100%) diff --git a/erpnext/public/build.json b/erpnext/public/build.json index 66ac5fe4f1..c9b107c5dd 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -56,6 +56,6 @@ "stock/dashboard/item_dashboard.js" ], "js/academy.min.js": [ - "public/js/education/academy/academy.js" + "public/js/education/lms/lms.js" ] } diff --git a/erpnext/public/js/education/academy/AcademyRoot.vue b/erpnext/public/js/education/lms/AcademyRoot.vue similarity index 100% rename from erpnext/public/js/education/academy/AcademyRoot.vue rename to erpnext/public/js/education/lms/AcademyRoot.vue diff --git a/erpnext/public/js/education/academy/call.js b/erpnext/public/js/education/lms/call.js similarity index 82% rename from erpnext/public/js/education/academy/call.js rename to erpnext/public/js/education/lms/call.js index bdcca3ad4d..0e6c186853 100644 --- a/erpnext/public/js/education/academy/call.js +++ b/erpnext/public/js/education/lms/call.js @@ -1,7 +1,7 @@ frappe.ready(() => { - frappe.provide('academy'); + frappe.provide('lms'); - academy.call = (method, args) => { + lms.call = (method, args) => { const method_path = 'erpnext.www.lms.' + method; return new Promise((resolve, reject) => { return frappe.call({ diff --git a/erpnext/public/js/education/academy/components/AcademyCourseCard.vue b/erpnext/public/js/education/lms/components/AcademyCourseCard.vue similarity index 93% rename from erpnext/public/js/education/academy/components/AcademyCourseCard.vue rename to erpnext/public/js/education/lms/components/AcademyCourseCard.vue index e33f0b063e..405e7ba8f0 100644 --- a/erpnext/public/js/education/academy/components/AcademyCourseCard.vue +++ b/erpnext/public/js/education/lms/components/AcademyCourseCard.vue @@ -38,10 +38,10 @@ export default { }, computed: { showStart() { - return academy.loggedIn && !this.courseMeta.flag == "Completed"; + return lms.loggedIn && !this.courseMeta.flag == "Completed"; }, showCompleted() { - return academy.loggedIn && this.courseMeta.flag == "Completed"; + return lms.loggedIn && this.courseMeta.flag == "Completed"; }, firstContentRoute() { return `${this.program_name}/${this.course.name}/${this.courseMeta.content_type}/${this.courseMeta.content}` diff --git a/erpnext/public/js/education/academy/components/AcademyCourseCardButton.vue b/erpnext/public/js/education/lms/components/AcademyCourseCardButton.vue similarity index 84% rename from erpnext/public/js/education/academy/components/AcademyCourseCardButton.vue rename to erpnext/public/js/education/lms/components/AcademyCourseCardButton.vue index 698eca0e86..180acb2b5f 100644 --- a/erpnext/public/js/education/academy/components/AcademyCourseCardButton.vue +++ b/erpnext/public/js/education/lms/components/AcademyCourseCardButton.vue @@ -13,7 +13,7 @@ export default { }, computed: { getButtonName: function() { - if(academy.store.checkCourseCompletion(this.course)){ + if(lms.store.checkCourseCompletion(this.course)){ return 'Completed' } else{ @@ -21,7 +21,7 @@ export default { } }, getClassName: function() { - if(academy.store.checkCourseCompletion(this.course)){ + if(lms.store.checkCourseCompletion(this.course)){ return 'btn-success' } } diff --git a/erpnext/public/js/education/academy/components/AcademyList.vue b/erpnext/public/js/education/lms/components/AcademyList.vue similarity index 100% rename from erpnext/public/js/education/academy/components/AcademyList.vue rename to erpnext/public/js/education/lms/components/AcademyList.vue diff --git a/erpnext/public/js/education/academy/components/AcademyProgramCard.vue b/erpnext/public/js/education/lms/components/AcademyProgramCard.vue similarity index 87% rename from erpnext/public/js/education/academy/components/AcademyProgramCard.vue rename to erpnext/public/js/education/lms/components/AcademyProgramCard.vue index bea2acf825..c8a7278219 100644 --- a/erpnext/public/js/education/academy/components/AcademyProgramCard.vue +++ b/erpnext/public/js/education/lms/components/AcademyProgramCard.vue @@ -31,18 +31,18 @@ export default { name: "AcademyProgramCard", data() { return { - isLogin: academy.store.isLogin + isLogin: lms.store.isLogin }; }, created() { }, methods: { enroll() { - academy.call('enroll_in_program', { + lms.call('enroll_in_program', { program_name: this.program.name, }).then( - academy.store.enrolledPrograms.add(this.program.name), - academy.store.updateEnrolledPrograms(), + lms.store.enrolledPrograms.add(this.program.name), + lms.store.updateEnrolledPrograms(), this.router.push('Program/' + this.program.name) ) } @@ -60,7 +60,7 @@ export default { return `Program/${this.program.name}` }, isEnrolled() { - return academy.store.enrolledPrograms.has(this.program.name) + return lms.store.enrolledPrograms.has(this.program.name) } }, components: { diff --git a/erpnext/public/js/education/academy/components/AcademyTopSection.vue b/erpnext/public/js/education/lms/components/AcademyTopSection.vue similarity index 100% rename from erpnext/public/js/education/academy/components/AcademyTopSection.vue rename to erpnext/public/js/education/lms/components/AcademyTopSection.vue diff --git a/erpnext/public/js/education/academy/components/AcademyTopSectionButton.vue b/erpnext/public/js/education/lms/components/AcademyTopSectionButton.vue similarity index 86% rename from erpnext/public/js/education/academy/components/AcademyTopSectionButton.vue rename to erpnext/public/js/education/lms/components/AcademyTopSectionButton.vue index 8adb5ecc36..822b834d47 100644 --- a/erpnext/public/js/education/academy/components/AcademyTopSectionButton.vue +++ b/erpnext/public/js/education/lms/components/AcademyTopSectionButton.vue @@ -8,7 +8,7 @@ export default { data() { return { buttonName: '', - isLoggedIn: academy.store.checkLogin(), + isLoggedIn: lms.store.checkLogin(), nextContent: '', nextContentType: '', nextCourse: '', @@ -30,7 +30,7 @@ export default { } if(this.isLoggedIn){ - if(academy.store.checkProgramEnrollment(this.$route.params.program_name)){ + if(lms.store.checkProgramEnrollment(this.$route.params.program_name)){ if(this.$route.name == 'home'){ this.buttonName = 'Explore Courses' } @@ -51,7 +51,7 @@ export default { if(this.$route.name == 'home'){ return } - else if(this.$route.name == 'program' && academy.store.checkProgramEnrollment(this.$route.params.program_name)){ + else if(this.$route.name == 'program' && lms.store.checkProgramEnrollment(this.$route.params.program_name)){ this.$router.push({ name: 'content', params: { program_name: this.$route.params.program_name, course: this.nextCourse, type: this.nextContentType, content: this.nextContent}}) } else { @@ -62,7 +62,7 @@ export default { student_email_id: frappe.session.user } }) - academy.store.updateEnrolledPrograms() + lms.store.updateEnrolledPrograms() } }, } diff --git a/erpnext/public/js/education/academy/components/Button.vue b/erpnext/public/js/education/lms/components/Button.vue similarity index 100% rename from erpnext/public/js/education/academy/components/Button.vue rename to erpnext/public/js/education/lms/components/Button.vue diff --git a/erpnext/public/js/education/academy/components/ContentArticle.vue b/erpnext/public/js/education/lms/components/ContentArticle.vue similarity index 100% rename from erpnext/public/js/education/academy/components/ContentArticle.vue rename to erpnext/public/js/education/lms/components/ContentArticle.vue diff --git a/erpnext/public/js/education/academy/components/ContentNavigation.vue b/erpnext/public/js/education/lms/components/ContentNavigation.vue similarity index 77% rename from erpnext/public/js/education/academy/components/ContentNavigation.vue rename to erpnext/public/js/education/lms/components/ContentNavigation.vue index 421606dfae..7495717ec1 100644 --- a/erpnext/public/js/education/academy/components/ContentNavigation.vue +++ b/erpnext/public/js/education/lms/components/ContentNavigation.vue @@ -16,7 +16,7 @@ export default { frappe.call({ method: "erpnext.www.lms.add_activity", args: { - enrollment: academy.store.enrolledCourses[this.$route.params.course], + enrollment: lms.store.enrolledCourses[this.$route.params.course], content_type: this.$route.params.type, content: this.$route.params.content } @@ -29,7 +29,7 @@ export default { frappe.call({ method: "erpnext.www.lms.add_activity", args: { - enrollment: academy.store.enrolledCourses[this.$route.params.course], + enrollment: lms.store.enrolledCourses[this.$route.params.course], content_type: this.$route.params.type, content: this.$route.params.content } @@ -38,15 +38,15 @@ export default { frappe.call({ method: "erpnext.www.lms.mark_course_complete", args: { - enrollment: academy.store.enrolledCourses[this.$route.params.course] + enrollment: lms.store.enrolledCourses[this.$route.params.course] } }) - // academy.store.addCompletedCourses(this.$route.params.course) - academy.store.updateCompletedCourses() + // lms.store.addCompletedCourses(this.$route.params.course) + lms.store.updateCompletedCourses() this.$router.push({ name: 'program', params: { program_name: this.$route.params.program_name}}) // - academy.trigger('course-completed', course_name); + lms.trigger('course-completed', course_name); } } }; diff --git a/erpnext/public/js/education/academy/components/ContentQuiz.vue b/erpnext/public/js/education/lms/components/ContentQuiz.vue similarity index 96% rename from erpnext/public/js/education/academy/components/ContentQuiz.vue rename to erpnext/public/js/education/lms/components/ContentQuiz.vue index 149d314b9d..dd32bf40d0 100644 --- a/erpnext/public/js/education/academy/components/ContentQuiz.vue +++ b/erpnext/public/js/education/lms/components/ContentQuiz.vue @@ -72,7 +72,7 @@ export default { frappe.call({ method: "erpnext.www.lms.evaluate_quiz", args: { - enrollment: academy.store.enrolledCourses[this.$route.params.course], + enrollment: lms.store.enrolledCourses[this.$route.params.course], quiz_response: this.quizResponse, quiz_name: this.content } diff --git a/erpnext/public/js/education/academy/components/ContentTitle.vue b/erpnext/public/js/education/lms/components/ContentTitle.vue similarity index 100% rename from erpnext/public/js/education/academy/components/ContentTitle.vue rename to erpnext/public/js/education/lms/components/ContentTitle.vue diff --git a/erpnext/public/js/education/academy/components/ContentVideo.vue b/erpnext/public/js/education/lms/components/ContentVideo.vue similarity index 100% rename from erpnext/public/js/education/academy/components/ContentVideo.vue rename to erpnext/public/js/education/lms/components/ContentVideo.vue diff --git a/erpnext/public/js/education/academy/components/Quiz/QuizSingleChoice.vue b/erpnext/public/js/education/lms/components/Quiz/QuizSingleChoice.vue similarity index 100% rename from erpnext/public/js/education/academy/components/Quiz/QuizSingleChoice.vue rename to erpnext/public/js/education/lms/components/Quiz/QuizSingleChoice.vue diff --git a/erpnext/public/js/education/academy/academy.js b/erpnext/public/js/education/lms/lms.js similarity index 64% rename from erpnext/public/js/education/academy/academy.js rename to erpnext/public/js/education/lms/lms.js index e8e96f1c12..13938e3a41 100644 --- a/erpnext/public/js/education/academy/academy.js +++ b/erpnext/public/js/education/lms/lms.js @@ -15,14 +15,14 @@ var store = { } frappe.ready(() => { - frappe.provide('academy') - // frappe.utils.make_event_emitter(academy); + frappe.provide('lms') + // frappe.utils.make_event_emitter(lms); - academy.store = new Vue({ + lms.store = new Vue({ data: store, methods: { addCompletedCourses (courseName){ - if (academy.debug) console.log('addCompletedCourses triggered with', courseName) + if (lms.debug) console.log('addCompletedCourses triggered with', courseName) this.completedCourses.add(courseName) }, @@ -40,32 +40,32 @@ frappe.ready(() => { }, updateEnrolledPrograms (){ - if (academy.debug) console.log('Updating enrolledPrograms') - academy.call("get_program_enrollments").then(data => { + if (lms.debug) console.log('Updating enrolledPrograms') + lms.call("get_program_enrollments").then(data => { data.forEach(element => { this.enrolledPrograms.add(element) }) }); - if (academy.debug) console.log('Updated State', this.enrolledPrograms) + if (lms.debug) console.log('Updated State', this.enrolledPrograms) }, updateEnrolledCourses (){ - if (academy.debug) console.log('Updating enrolledCourses') + if (lms.debug) console.log('Updating enrolledCourses') frappe.call({ - method: "erpnext.www.academy.get_course_enrollments", + method: "erpnext.www.lms.get_course_enrollments", args:{ email: frappe.session.user } }).then( r => { this.enrolledCourses = r.message }) - if (academy.debug) console.log('Updated State', this.enrolledCourses) + if (lms.debug) console.log('Updated State', this.enrolledCourses) }, updateCompletedCourses (){ - if (academy.debug) console.log('Updating States') + if (lms.debug) console.log('Updating States') frappe.call({ - method: "erpnext.www.academy.get_completed_courses", + method: "erpnext.www.lms.get_completed_courses", args:{ email: frappe.session.user } @@ -76,16 +76,16 @@ frappe.ready(() => { } } }) - if (academy.debug) console.log('Updated State', this.completedCourses) + if (lms.debug) console.log('Updated State', this.completedCourses) }, checkLogin (){ if(frappe.session.user === "Guest"){ - if (academy.debug) console.log('No Session') + if (lms.debug) console.log('No Session') this.isLogin = false } else { - if (academy.debug) console.log('Current User: ', frappe.session.user) + if (lms.debug) console.log('Current User: ', frappe.session.user) this.isLogin = true } return this.isLogin @@ -100,17 +100,17 @@ frappe.ready(() => { } }); - academy.view = new Vue({ + lms.view = new Vue({ el: "#lms-app", router: new VueRouter({ routes }), template: "", components: { AcademyRoot }, created: function() { - if(academy.store.checkLogin()){ - academy.store.updateState() + if(lms.store.checkLogin()){ + lms.store.updateState() } } }); - academy.debug = true + lms.debug = true }) \ No newline at end of file diff --git a/erpnext/public/js/education/academy/pages/AcademyCoursePage.vue b/erpnext/public/js/education/lms/pages/AcademyCoursePage.vue similarity index 100% rename from erpnext/public/js/education/academy/pages/AcademyCoursePage.vue rename to erpnext/public/js/education/lms/pages/AcademyCoursePage.vue diff --git a/erpnext/public/js/education/academy/pages/AcademyHome.vue b/erpnext/public/js/education/lms/pages/AcademyHome.vue similarity index 89% rename from erpnext/public/js/education/academy/pages/AcademyHome.vue rename to erpnext/public/js/education/lms/pages/AcademyHome.vue index e59074567e..64a66f159b 100644 --- a/erpnext/public/js/education/academy/pages/AcademyHome.vue +++ b/erpnext/public/js/education/lms/pages/AcademyHome.vue @@ -42,13 +42,13 @@ export default { }, methods: { // updateEnrolledPrograms(){ - // return academy.call("get_program_enrollments") + // return lms.call("get_program_enrollments") // }, getPortalDetails() { - return academy.call("get_portal_details") + return lms.call("get_portal_details") }, getFeaturedPrograms() { - return academy.call("get_featured_programs") + return lms.call("get_featured_programs") } } }; diff --git a/erpnext/public/js/education/academy/pages/AcademyProgramPage.vue b/erpnext/public/js/education/lms/pages/AcademyProgramPage.vue similarity index 86% rename from erpnext/public/js/education/academy/pages/AcademyProgramPage.vue rename to erpnext/public/js/education/lms/pages/AcademyProgramPage.vue index 607524ab73..e9b0085e25 100644 --- a/erpnext/public/js/education/academy/pages/AcademyProgramPage.vue +++ b/erpnext/public/js/education/lms/pages/AcademyProgramPage.vue @@ -32,13 +32,13 @@ export default { } }, beforeMount() { - if(academy.store.isLogin) academy.store.updateCompletedCourses() + if(lms.store.isLogin) lms.store.updateCompletedCourses() }, mounted() { this.getProgramDetails().then(data => this.program = data); this.getCourses().then(data => this.course_data = data); - // academy.on(`course-completed`, (course_name) => { + // lms.on(`course-completed`, (course_name) => { // const course = this.course_data.findIndex(c => c.name === course_name); // this.course_data[course].completed = true; // }); @@ -51,17 +51,17 @@ export default { ) }, getContentForNextCourse() { - return academy.call('get_continue_data', { + return lms.call('get_continue_data', { program_name: this.program_name }); }, getProgramDetails() { - return academy.call('get_program_details', { + return lms.call('get_program_details', { program_name: this.program_name }); }, getCourses() { - return academy.call('get_courses', { + return lms.call('get_courses', { program_name: this.program_name }) } diff --git a/erpnext/public/js/education/academy/routes.js b/erpnext/public/js/education/lms/routes.js similarity index 100% rename from erpnext/public/js/education/academy/routes.js rename to erpnext/public/js/education/lms/routes.js From 8ff10286653cfa45993f7192686ea71e49984b3d Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 13 Nov 2018 17:02:42 +0530 Subject: [PATCH 109/314] Renamed AcademyRoot to lmsRoot --- .../public/js/education/lms/{AcademyRoot.vue => lmsRoot.vue} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename erpnext/public/js/education/lms/{AcademyRoot.vue => lmsRoot.vue} (70%) diff --git a/erpnext/public/js/education/lms/AcademyRoot.vue b/erpnext/public/js/education/lms/lmsRoot.vue similarity index 70% rename from erpnext/public/js/education/lms/AcademyRoot.vue rename to erpnext/public/js/education/lms/lmsRoot.vue index a6bfb988fa..8208deda22 100644 --- a/erpnext/public/js/education/lms/AcademyRoot.vue +++ b/erpnext/public/js/education/lms/lmsRoot.vue @@ -1,10 +1,10 @@ \ No newline at end of file From 0225642459a2255b3a646033a0458e24c2420d79 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 13 Nov 2018 17:03:18 +0530 Subject: [PATCH 110/314] Renamed Pages --- erpnext/public/js/education/lms/lms.js | 6 +++--- .../pages/{AcademyCoursePage.vue => CoursePage.vue} | 2 +- .../lms/pages/{AcademyHome.vue => Home.vue} | 2 +- .../{AcademyProgramPage.vue => ProgramPage.vue} | 2 +- erpnext/public/js/education/lms/routes.js | 12 ++++++------ 5 files changed, 12 insertions(+), 12 deletions(-) rename erpnext/public/js/education/lms/pages/{AcademyCoursePage.vue => CoursePage.vue} (98%) rename erpnext/public/js/education/lms/pages/{AcademyHome.vue => Home.vue} (98%) rename erpnext/public/js/education/lms/pages/{AcademyProgramPage.vue => ProgramPage.vue} (98%) diff --git a/erpnext/public/js/education/lms/lms.js b/erpnext/public/js/education/lms/lms.js index 13938e3a41..103f45bec7 100644 --- a/erpnext/public/js/education/lms/lms.js +++ b/erpnext/public/js/education/lms/lms.js @@ -1,7 +1,7 @@ import Vue from 'vue/dist/vue.js'; import VueRouter from 'vue-router/dist/vue-router.js' -import AcademyRoot from "./AcademyRoot.vue"; +import lmsRoot from "./lmsRoot.vue"; import routes from './routes'; import './call'; @@ -103,8 +103,8 @@ frappe.ready(() => { lms.view = new Vue({ el: "#lms-app", router: new VueRouter({ routes }), - template: "", - components: { AcademyRoot }, + template: "", + components: { lmsRoot }, created: function() { if(lms.store.checkLogin()){ lms.store.updateState() diff --git a/erpnext/public/js/education/lms/pages/AcademyCoursePage.vue b/erpnext/public/js/education/lms/pages/CoursePage.vue similarity index 98% rename from erpnext/public/js/education/lms/pages/AcademyCoursePage.vue rename to erpnext/public/js/education/lms/pages/CoursePage.vue index 9d50afe0a5..260aefccda 100644 --- a/erpnext/public/js/education/lms/pages/AcademyCoursePage.vue +++ b/erpnext/public/js/education/lms/pages/CoursePage.vue @@ -13,7 +13,7 @@ import ContentNavigation from "../components/ContentNavigation.vue" export default { props:['program_name', 'course', 'type', 'content'], - name: "AcademyCoursePage", + name: "CoursePage", data() { return{ nextContent: '', diff --git a/erpnext/public/js/education/lms/pages/AcademyHome.vue b/erpnext/public/js/education/lms/pages/Home.vue similarity index 98% rename from erpnext/public/js/education/lms/pages/AcademyHome.vue rename to erpnext/public/js/education/lms/pages/Home.vue index 64a66f159b..0931a19fc2 100644 --- a/erpnext/public/js/education/lms/pages/AcademyHome.vue +++ b/erpnext/public/js/education/lms/pages/Home.vue @@ -15,7 +15,7 @@ import AcademyProgramCard from "../components/AcademyProgramCard.vue" import AcademyTopSectionButton from "../components/AcademyTopSectionButton.vue" export default { - name: "AcademyHome", + name: "Home", data() { return{ portal: {}, diff --git a/erpnext/public/js/education/lms/pages/AcademyProgramPage.vue b/erpnext/public/js/education/lms/pages/ProgramPage.vue similarity index 98% rename from erpnext/public/js/education/lms/pages/AcademyProgramPage.vue rename to erpnext/public/js/education/lms/pages/ProgramPage.vue index e9b0085e25..9a6c29a9c9 100644 --- a/erpnext/public/js/education/lms/pages/AcademyProgramPage.vue +++ b/erpnext/public/js/education/lms/pages/ProgramPage.vue @@ -18,7 +18,7 @@ import AcademyCourseCard from "../components/AcademyCourseCard.vue" export default { props: ['program_name'], - name: "AcademyProgramPage", + name: "ProgramPage", components: { AButton: Button, AcademyTopSection, diff --git a/erpnext/public/js/education/lms/routes.js b/erpnext/public/js/education/lms/routes.js index 8e4e865016..450e655a1a 100644 --- a/erpnext/public/js/education/lms/routes.js +++ b/erpnext/public/js/education/lms/routes.js @@ -1,11 +1,11 @@ -import AcademyHome from "./pages/AcademyHome.vue"; -import AcademyProgramPage from "./pages/AcademyProgramPage.vue"; -import AcademyCoursePage from "./pages/AcademyCoursePage.vue"; +import Home from "./pages/Home.vue"; +import ProgramPage from "./pages/ProgramPage.vue"; +import CoursePage from "./pages/CoursePage.vue"; const routes = [ - {name: 'home', path: '', component: AcademyHome}, - {name: 'program', path: '/Program/:program_name', component: AcademyProgramPage, props: true}, - {name: 'content', path: '/Program/:program_name/:course/:type/:content', component: AcademyCoursePage, props: true}, + {name: 'home', path: '', component: Home}, + {name: 'program', path: '/Program/:program_name', component: ProgramPage, props: true}, + {name: 'content', path: '/Program/:program_name/:course/:type/:content', component: CoursePage, props: true}, ]; export default routes; \ No newline at end of file From 2596ea08167fc9e68e81f40aba1b0164902739fc Mon Sep 17 00:00:00 2001 From: scmmishra Date: Tue, 13 Nov 2018 17:24:07 +0530 Subject: [PATCH 111/314] Renamed Vue Files --- .../{ContentArticle.vue => Article.vue} | 10 +++---- .../{AcademyList.vue => CardList.vue} | 2 +- .../{AcademyCourseCard.vue => CourseCard.vue} | 6 ++-- ...rseCardButton.vue => CourseCardButton.vue} | 2 +- .../{ContentNavigation.vue => Navigation.vue} | 2 +- ...AcademyProgramCard.vue => ProgramCard.vue} | 2 +- .../components/{ContentQuiz.vue => Quiz.vue} | 2 +- .../{ContentTitle.vue => Title.vue} | 2 +- .../{AcademyTopSection.vue => TopSection.vue} | 2 +- ...SectionButton.vue => TopSectionButton.vue} | 2 +- .../{ContentVideo.vue => Video.vue} | 2 +- .../js/education/lms/pages/CoursePage.vue | 24 ++++++++-------- .../public/js/education/lms/pages/Home.vue | 28 +++++++++---------- .../js/education/lms/pages/ProgramPage.vue | 22 +++++++-------- 14 files changed, 54 insertions(+), 54 deletions(-) rename erpnext/public/js/education/lms/components/{ContentArticle.vue => Article.vue} (79%) rename erpnext/public/js/education/lms/components/{AcademyList.vue => CardList.vue} (94%) rename erpnext/public/js/education/lms/components/{AcademyCourseCard.vue => CourseCard.vue} (94%) rename erpnext/public/js/education/lms/components/{AcademyCourseCardButton.vue => CourseCardButton.vue} (95%) rename erpnext/public/js/education/lms/components/{ContentNavigation.vue => Navigation.vue} (98%) rename erpnext/public/js/education/lms/components/{AcademyProgramCard.vue => ProgramCard.vue} (98%) rename erpnext/public/js/education/lms/components/{ContentQuiz.vue => Quiz.vue} (99%) rename erpnext/public/js/education/lms/components/{ContentTitle.vue => Title.vue} (96%) rename erpnext/public/js/education/lms/components/{AcademyTopSection.vue => TopSection.vue} (93%) rename erpnext/public/js/education/lms/components/{AcademyTopSectionButton.vue => TopSectionButton.vue} (98%) rename erpnext/public/js/education/lms/components/{ContentVideo.vue => Video.vue} (98%) diff --git a/erpnext/public/js/education/lms/components/ContentArticle.vue b/erpnext/public/js/education/lms/components/Article.vue similarity index 79% rename from erpnext/public/js/education/lms/components/ContentArticle.vue rename to erpnext/public/js/education/lms/components/Article.vue index b0fc0e6c5f..7fc1173bc9 100644 --- a/erpnext/public/js/education/lms/components/ContentArticle.vue +++ b/erpnext/public/js/education/lms/components/Article.vue @@ -1,8 +1,8 @@ diff --git a/erpnext/public/js/education/lms/components/AcademyList.vue b/erpnext/public/js/education/lms/components/CardList.vue similarity index 94% rename from erpnext/public/js/education/lms/components/AcademyList.vue rename to erpnext/public/js/education/lms/components/CardList.vue index 919a3a98ca..0c03cf6265 100644 --- a/erpnext/public/js/education/lms/components/AcademyList.vue +++ b/erpnext/public/js/education/lms/components/CardList.vue @@ -13,6 +13,6 @@ \ No newline at end of file diff --git a/erpnext/public/js/education/lms/components/AcademyCourseCard.vue b/erpnext/public/js/education/lms/components/CourseCard.vue similarity index 94% rename from erpnext/public/js/education/lms/components/AcademyCourseCard.vue rename to erpnext/public/js/education/lms/components/CourseCard.vue index 405e7ba8f0..200659bf2b 100644 --- a/erpnext/public/js/education/lms/components/AcademyCourseCard.vue +++ b/erpnext/public/js/education/lms/components/CourseCard.vue @@ -27,13 +27,13 @@ \ No newline at end of file diff --git a/erpnext/public/js/education/lms/components/AcademyTopSectionButton.vue b/erpnext/public/js/education/lms/components/TopSectionButton.vue similarity index 98% rename from erpnext/public/js/education/lms/components/AcademyTopSectionButton.vue rename to erpnext/public/js/education/lms/components/TopSectionButton.vue index 822b834d47..a9b227f5e0 100644 --- a/erpnext/public/js/education/lms/components/AcademyTopSectionButton.vue +++ b/erpnext/public/js/education/lms/components/TopSectionButton.vue @@ -4,7 +4,7 @@ diff --git a/erpnext/public/js/education/lms/pages/Home.vue b/erpnext/public/js/education/lms/pages/Home.vue index 0931a19fc2..f823d380e8 100644 --- a/erpnext/public/js/education/lms/pages/Home.vue +++ b/erpnext/public/js/education/lms/pages/Home.vue @@ -1,18 +1,18 @@ diff --git a/erpnext/public/js/education/lms/components/CardList.vue b/erpnext/public/js/education/lms/components/CardList.vue index 0c03cf6265..8f6f7c79ae 100644 --- a/erpnext/public/js/education/lms/components/CardList.vue +++ b/erpnext/public/js/education/lms/components/CardList.vue @@ -3,9 +3,9 @@

- +
- View All +
diff --git a/erpnext/public/js/education/lms/components/ProgramCard.vue b/erpnext/public/js/education/lms/components/ProgramCard.vue index 23e7a96381..6bd8532b52 100644 --- a/erpnext/public/js/education/lms/components/ProgramCard.vue +++ b/erpnext/public/js/education/lms/components/ProgramCard.vue @@ -57,7 +57,7 @@ export default { } }, programPageRoute() { - return `Program/${this.program.name}` + return { name: 'program', params: { program_name: this.program.name }} }, isEnrolled() { return lms.store.enrolledPrograms.has(this.program.name) diff --git a/erpnext/public/js/education/lms/components/Video.vue b/erpnext/public/js/education/lms/components/Video.vue index 26d3bf698c..c13d0dbfd2 100644 --- a/erpnext/public/js/education/lms/components/Video.vue +++ b/erpnext/public/js/education/lms/components/Video.vue @@ -46,15 +46,12 @@ export default { } }, mounted() { - frappe.call({ - method: "erpnext.www.lms.get_content", - args: { - content_name: this.content, - content_type: this.type - } - }).then(r => { - this.contentData = r.message - }); + this.getContent().then(data => this.contentData = data); }, + methods: { + getContent() { + return frappe.db.get_doc(this.type, this.content) + } + } }; diff --git a/erpnext/public/js/education/lms/pages/CoursePage.vue b/erpnext/public/js/education/lms/pages/CoursePage.vue index 477de4696b..f83857532a 100644 --- a/erpnext/public/js/education/lms/pages/CoursePage.vue +++ b/erpnext/public/js/education/lms/pages/CoursePage.vue @@ -1,7 +1,7 @@ @@ -9,7 +9,7 @@ import Article from "../components/Article.vue" import Quiz from "../components/Quiz.vue" import Video from "../components/Video.vue" -import Navigation from "../components/Navigation.vue" +import ContentNavigation from "../components/ContentNavigation.vue" export default { props:['program_name', 'course', 'type', 'content'], @@ -50,7 +50,7 @@ export default { Article, Video, Quiz, - Navigation + ContentNavigation } }; diff --git a/erpnext/public/js/education/lms/pages/Home.vue b/erpnext/public/js/education/lms/pages/Home.vue index f823d380e8..b3120845ce 100644 --- a/erpnext/public/js/education/lms/pages/Home.vue +++ b/erpnext/public/js/education/lms/pages/Home.vue @@ -4,11 +4,13 @@ - + + View All \ No newline at end of file diff --git a/erpnext/public/js/education/lms/pages/ProgramPage.vue b/erpnext/public/js/education/lms/pages/ProgramPage.vue index c0d4f15572..bc0f2670c1 100644 --- a/erpnext/public/js/education/lms/pages/ProgramPage.vue +++ b/erpnext/public/js/education/lms/pages/ProgramPage.vue @@ -1,16 +1,13 @@ + {% endblock %} \ No newline at end of file diff --git a/erpnext/www/lms.py b/erpnext/www/lms.py index ab01aed9d9..bb5daaf02a 100644 --- a/erpnext/www/lms.py +++ b/erpnext/www/lms.py @@ -28,6 +28,15 @@ def get_featured_programs(): else: return None +@frappe.whitelist(allow_guest=True) +def get_all_programs(): + program_names = frappe.get_all("Program", filters={"is_published": True}) + if program_names: + featured_list = [get_program(program['name']) for program in program_names] + return featured_list + else: + return None + def get_program(program_name): program = frappe.get_doc('Program', program_name) is_enrolled = check_program_enrollment(program_name) From c5a1226e93865759e07544f5a66943afad65ce34 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Thu, 15 Nov 2018 11:13:56 +0530 Subject: [PATCH 114/314] Refactored State management store --- .../education/lms/components/ProgramCard.vue | 28 ++++--- .../lms/components/TopSectionButton.vue | 4 +- erpnext/public/js/education/lms/lms.js | 84 +++++-------------- .../js/education/lms/pages/ProgramPage.vue | 2 +- 4 files changed, 41 insertions(+), 77 deletions(-) diff --git a/erpnext/public/js/education/lms/components/ProgramCard.vue b/erpnext/public/js/education/lms/components/ProgramCard.vue index 6bd8532b52..d0df94dad0 100644 --- a/erpnext/public/js/education/lms/components/ProgramCard.vue +++ b/erpnext/public/js/education/lms/components/ProgramCard.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/erpnext/www/lms.py b/erpnext/www/lms.py index 3ef721aa82..01fb323cb0 100644 --- a/erpnext/www/lms.py +++ b/erpnext/www/lms.py @@ -204,9 +204,7 @@ def check_quiz_completion(quiz, enrollment_name): def get_course_meta(course_enrollment): # course_enrollment = frappe.get_doc("Course Enrollment", course_enrollment_name) progress = get_course_progress(course_enrollment) - print(progress) count = sum([act['is_complete'] for act in progress]) - print('Count', count) if count == 0: return {'flag':'Start Course', 'content_type': progress[0]['content_type'], 'content': progress[0]['content']} elif count == len(progress): From be7fadc52180cafdaa3c8eabb82baf15fc255708 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Thu, 22 Nov 2018 12:22:20 +0530 Subject: [PATCH 125/314] Renamed CoursePage to ContentPage --- .../education/lms/pages/{CoursePage.vue => ContentPage.vue} | 2 +- erpnext/public/js/education/lms/routes.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename erpnext/public/js/education/lms/pages/{CoursePage.vue => ContentPage.vue} (98%) diff --git a/erpnext/public/js/education/lms/pages/CoursePage.vue b/erpnext/public/js/education/lms/pages/ContentPage.vue similarity index 98% rename from erpnext/public/js/education/lms/pages/CoursePage.vue rename to erpnext/public/js/education/lms/pages/ContentPage.vue index 1f39b445da..7a4ce31acf 100644 --- a/erpnext/public/js/education/lms/pages/CoursePage.vue +++ b/erpnext/public/js/education/lms/pages/ContentPage.vue @@ -13,7 +13,7 @@ import ContentNavigation from "../components/ContentNavigation.vue" export default { props:['program_name', 'course', 'type', 'content'], - name: "CoursePage", + name: "ContentPage", data() { return{ nextContent: '', diff --git a/erpnext/public/js/education/lms/routes.js b/erpnext/public/js/education/lms/routes.js index c28dd19bfe..9346af719e 100644 --- a/erpnext/public/js/education/lms/routes.js +++ b/erpnext/public/js/education/lms/routes.js @@ -1,12 +1,12 @@ import Home from "./pages/Home.vue"; import ProgramPage from "./pages/ProgramPage.vue"; -import CoursePage from "./pages/CoursePage.vue"; +import ContentPage from "./pages/ContentPage.vue"; import ListPage from "./pages/ListPage.vue"; const routes = [ {name: 'home', path: '', component: Home}, {name: 'program', path: '/Program/:program_name', component: ProgramPage, props: true}, - {name: 'content', path: '/Program/:program_name/:course/:type/:content', component: CoursePage, props: true}, + {name: 'content', path: '/Program/:program_name/:course/:type/:content', component: ContentPage, props: true}, {name: 'list', path: '/List/:master', component: ListPage, props: true}, { name: 'signup', From fdbabde80a0c3cbee2a4406f9781be890ed09abf Mon Sep 17 00:00:00 2001 From: scmmishra Date: Thu, 22 Nov 2018 15:33:30 +0530 Subject: [PATCH 126/314] UI fixes for course card --- .../education/lms/components/CourseCard.vue | 17 +++++++++++-- .../js/education/lms/pages/ProgramPage.vue | 11 ++++---- erpnext/www/lms.py | 25 ++++++++++--------- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/erpnext/public/js/education/lms/components/CourseCard.vue b/erpnext/public/js/education/lms/components/CourseCard.vue index 31ca773487..921ad9f7a0 100644 --- a/erpnext/public/js/education/lms/components/CourseCard.vue +++ b/erpnext/public/js/education/lms/components/CourseCard.vue @@ -33,8 +33,16 @@ import AButton from './Button.vue'; export default { - props: ['course', 'courseMeta', 'program_name'], + props: ['course', 'program_name'], name: "CourseCard", + data() { + return { + courseMeta: {} + } + }, + mounted() { + this.getCourseMeta().then(data => this.courseMeta = data) + }, components: { AButton }, @@ -68,7 +76,12 @@ export default { if(content_type == 'Video') return 'fa fa-play' if(content_type == 'Article') return 'fa fa-file-text-o' if(content_type == 'Quiz') return 'fa fa-question-circle-o' - } + }, + getCourseMeta() { + return lms.call('get_course_meta', { + course_name: this.course.name + }) + } } }; diff --git a/erpnext/public/js/education/lms/pages/ProgramPage.vue b/erpnext/public/js/education/lms/pages/ProgramPage.vue index 1c90f73ac0..65bb9a6ddf 100644 --- a/erpnext/public/js/education/lms/pages/ProgramPage.vue +++ b/erpnext/public/js/education/lms/pages/ProgramPage.vue @@ -3,7 +3,7 @@ - + @@ -24,7 +24,7 @@ export default { data() { return { program: {}, - course_data: [] + courseData: [], } }, beforeMount() { @@ -32,11 +32,10 @@ export default { }, mounted() { this.getProgramDetails().then(data => this.program = data); - this.getCourses().then(data => this.course_data = data); - + this.getCourses().then(data => this.courseData = data); // lms.on(`course-completed`, (course_name) => { - // const course = this.course_data.findIndex(c => c.name === course_name); - // this.course_data[course].completed = true; + // const course = this.courseData.findIndex(c => c.name === course_name); + // this.courseData[course].completed = true; // }); }, methods: { diff --git a/erpnext/www/lms.py b/erpnext/www/lms.py index 01fb323cb0..10d29480da 100644 --- a/erpnext/www/lms.py +++ b/erpnext/www/lms.py @@ -64,8 +64,7 @@ def get_program_details(program_name): def get_courses(program_name): program = frappe.get_doc('Program', program_name) courses = program.get_course_list() - course_data = [{'meta':get_course_meta(utils.get_course_enrollment(item.name)), 'course':item} for item in courses] - return course_data + return courses @frappe.whitelist() def get_next_content(content, content_type, course): @@ -171,7 +170,7 @@ def get_course_progress(course_enrollment): course = frappe.get_doc('Course', course_enrollment.course) contents = course.get_contents() progress = [] - for index, content in enumerate(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}) @@ -192,16 +191,18 @@ def check_quiz_completion(quiz, enrollment_name): status = bool(len(attempts) == quiz.max_attempts) score = None result = None - if attempts and quiz.grading_basis == 'Last Highest Score': - attempts = sorted(attempts, key = lambda i: int(i.score), reverse=True) - score = attempts[0]['score'] - result = attempts[0]['status'] - if result == 'Pass': - status = True + if attempts: + if quiz.grading_basis == 'Last Highest Score': + attempts = sorted(attempts, key = lambda i: int(i.score), reverse=True) + score = attempts[0]['score'] + result = attempts[0]['status'] + if result == 'Pass': + status = True return status, score, result - - -def get_course_meta(course_enrollment): + +@frappe.whitelist() +def get_course_meta(course_name): + course_enrollment = utils.get_course_enrollment(course_name) # course_enrollment = frappe.get_doc("Course Enrollment", course_enrollment_name) progress = get_course_progress(course_enrollment) count = sum([act['is_complete'] for act in progress]) From 082e3c94efe1c8e8dfd740dc06e383455f49696b Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 23 Nov 2018 17:16:22 +0530 Subject: [PATCH 127/314] Minor Fixes: Student Enrollment --- erpnext/education/utils.py | 7 ++++--- erpnext/www/lms.py | 4 +--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index acfa3884db..6fb72f1d5d 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -100,11 +100,12 @@ def get_course_enrollment(course_name): return None def create_student(): - student_name=frappe.session.user + user = frappe.get_doc("User", frappe.session.user) student = frappe.get_doc({ "doctype": "Student", - "first_name": student_name, - "student_email_id": student_name, + "first_name": user.first_name, + "last_name": user.last_name, + "student_email_id": user.email, }) student.save(ignore_permissions=True) frappe.db.commit() diff --git a/erpnext/www/lms.py b/erpnext/www/lms.py index 10d29480da..505834c65a 100644 --- a/erpnext/www/lms.py +++ b/erpnext/www/lms.py @@ -101,8 +101,6 @@ def get_quiz_without_answers(quiz_name): @frappe.whitelist() def evaluate_quiz(enrollment, quiz_response, quiz_name): """LMS Function: Evaluates a simple multiple choice quiz. - - :param quiz_response: contains user selected choices for a quiz in the form of a string formatted as a dictionary. The function uses `json.loads()` to convert it to a python dictionary. """ @@ -143,7 +141,7 @@ def add_quiz_activity(enrollment, quiz_name, result_data, score, status): @frappe.whitelist() def enroll_in_program(program_name): if(not utils.get_current_student()): - utils.create_student(frappe.session.user) + utils.create_student() student = frappe.get_doc("Student", utils.get_current_student()) program_enrollment = student.enroll_in_program(program_name) utils.enroll_all_courses_in_program(program_enrollment, student) From 9229f4fc92638d9abea0c2c91653b78a9b53277c Mon Sep 17 00:00:00 2001 From: scmmishra Date: Fri, 23 Nov 2018 17:16:33 +0530 Subject: [PATCH 128/314] UI fixes --- .../js/education/lms/components/ProgramCard.vue | 2 +- erpnext/public/js/education/lms/lms.js | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/erpnext/public/js/education/lms/components/ProgramCard.vue b/erpnext/public/js/education/lms/components/ProgramCard.vue index 53905aa353..bbe6ba594e 100644 --- a/erpnext/public/js/education/lms/components/ProgramCard.vue +++ b/erpnext/public/js/education/lms/components/ProgramCard.vue @@ -45,7 +45,7 @@ export default { program_name: this.program.name, }).then(data => { console.log(data) - lms.store.enrolledPrograms.add(data), + lms.store.updateEnrolledPrograms() this.$router.push(this.programRoute) }) } diff --git a/erpnext/public/js/education/lms/lms.js b/erpnext/public/js/education/lms/lms.js index 8914e7bf76..d45b4effb1 100644 --- a/erpnext/public/js/education/lms/lms.js +++ b/erpnext/public/js/education/lms/lms.js @@ -23,17 +23,19 @@ frappe.ready(() => { updateEnrolledPrograms() { if(this.isLogin) { lms.call("get_program_enrollments").then(data => { - if(data) this.enrolledPrograms = data + this.enrolledPrograms = data }); if (lms.debug) console.log('Updated Enrolled Programs', this.enrolledPrograms) } }, updateEnrolledCourses() { - lms.call("get_all_course_enrollments").then(data => { - if(data) this.enrolledCourses = data - }) - if (lms.debug) console.log('Updated Enrolled Courses', this.enrolledCourses) + if(this.isLogin) { + lms.call("get_all_course_enrollments").then(data => { + this.enrolledCourses = data + }) + if (lms.debug) console.log('Updated Enrolled Courses', this.enrolledCourses) + } }, checkLogin() { From 788ffbd5b6c23288283448ce69a4bc7cdc891a50 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sat, 24 Nov 2018 20:31:35 +0530 Subject: [PATCH 129/314] Minor improvements --- .../js/education/lms/components/CourseCard.vue | 12 ++++-------- erpnext/public/js/education/lms/routes.js | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/erpnext/public/js/education/lms/components/CourseCard.vue b/erpnext/public/js/education/lms/components/CourseCard.vue index 921ad9f7a0..e9b9e07f92 100644 --- a/erpnext/public/js/education/lms/components/CourseCard.vue +++ b/erpnext/public/js/education/lms/components/CourseCard.vue @@ -8,9 +8,10 @@ Course Content
  • - + {{ content.content }} +
    {{ content.content }}
@@ -37,22 +38,17 @@ export default { name: "CourseCard", data() { return { + isLogin: lms.store.isLogin, courseMeta: {} } }, mounted() { - this.getCourseMeta().then(data => this.courseMeta = data) + if(this.isLogin) this.getCourseMeta().then(data => this.courseMeta = data) }, components: { AButton }, computed: { - showStart() { - return lms.loggedIn && !this.courseMeta.flag == "Complete"; - }, - showCompleted() { - return lms.loggedIn && this.courseMeta.flag == "Complete"; - }, firstContentRoute() { return `${this.program_name}/${this.course.name}/${this.courseMeta.content_type}/${this.courseMeta.content}` }, diff --git a/erpnext/public/js/education/lms/routes.js b/erpnext/public/js/education/lms/routes.js index 9346af719e..921f8ec40e 100644 --- a/erpnext/public/js/education/lms/routes.js +++ b/erpnext/public/js/education/lms/routes.js @@ -6,8 +6,21 @@ import ListPage from "./pages/ListPage.vue"; const routes = [ {name: 'home', path: '', component: Home}, {name: 'program', path: '/Program/:program_name', component: ProgramPage, props: true}, - {name: 'content', path: '/Program/:program_name/:course/:type/:content', component: ContentPage, props: true}, - {name: 'list', path: '/List/:master', component: ListPage, props: true}, + { + name: 'content', + path: '/Program/:program_name/:course/:type/:content', + component: ContentPage, + props: true, + beforeEnter: (to, from, next) => { + if(!lms.store.isLogin) next({name: 'home'}) + } + }, + { + name: 'list', + path: '/List/:master', + component: ListPage, + props: true + }, { name: 'signup', path: '/Signup', From cc755f6204583acb7b8c75ce00b7db5c359e88dc Mon Sep 17 00:00:00 2001 From: scmmishra Date: Sun, 25 Nov 2018 19:20:39 +0530 Subject: [PATCH 130/314] Doctype Changes for Beta Release --- .../education/doctype/article/article.json | 418 ++++++------- .../course_activity/course_activity.json | 552 +++++++++--------- .../course_enrollment/course_enrollment.json | 458 +++++++-------- erpnext/education/doctype/quiz/quiz.json | 2 +- .../doctype/quiz_activity/quiz_activity.json | 4 +- erpnext/education/doctype/video/video.json | 478 +++++++-------- 6 files changed, 939 insertions(+), 973 deletions(-) diff --git a/erpnext/education/doctype/article/article.json b/erpnext/education/doctype/article/article.json index 6b79f6090e..c30cd189d6 100644 --- a/erpnext/education/doctype/article/article.json +++ b/erpnext/education/doctype/article/article.json @@ -1,230 +1,230 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "field:title", - "beta": 0, - "creation": "2018-10-17 05:45:38.471670", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 1, + "allow_rename": 0, + "autoname": "field:title", + "beta": 0, + "creation": "2018-10-17 05:45:38.471670", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "title", - "fieldtype": "Data", - "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, - "label": "Title", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "title", + "fieldtype": "Data", + "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, + "label": "Title", + "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": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "author", - "fieldtype": "Data", - "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, - "label": "Author", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "author", + "fieldtype": "Data", + "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, + "label": "Author", + "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 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "content", - "fieldtype": "Text Editor", - "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, - "label": "Content", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "content", + "fieldtype": "Text Editor", + "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, + "label": "Content", + "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 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "publish_date", - "fieldtype": "Date", - "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, - "label": "Publish Date", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "publish_date", + "fieldtype": "Date", + "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, + "label": "Publish Date", + "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 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-07 22:14:23.922612", - "modified_by": "Administrator", - "module": "Education", - "name": "Article", - "name_case": "", - "owner": "Administrator", + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-11-25 19:06:56.016865", + "modified_by": "Administrator", + "module": "Education", + "name": "Article", + "name_case": "", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Academics User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 0 } - ], - "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, + ], + "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 } \ No newline at end of file diff --git a/erpnext/education/doctype/course_activity/course_activity.json b/erpnext/education/doctype/course_activity/course_activity.json index 66bbdeb6b5..3f069dd123 100644 --- a/erpnext/education/doctype/course_activity/course_activity.json +++ b/erpnext/education/doctype/course_activity/course_activity.json @@ -1,301 +1,301 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "format:EDU-CA-{YYYY}-{#####}", - "beta": 0, - "creation": "2018-10-01 17:35:54.391413", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "format:EDU-CA-{YYYY}-{#####}", + "beta": 1, + "creation": "2018-10-01 17:35:54.391413", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "enrollment", - "fieldtype": "Link", - "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, - "label": "Enrollment", - "length": 0, - "no_copy": 0, - "options": "Course Enrollment", - "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": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "enrollment", + "fieldtype": "Link", + "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, + "label": "Enrollment", + "length": 0, + "no_copy": 0, + "options": "Course Enrollment", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "enrollment.course", - "fieldname": "course", - "fieldtype": "Data", - "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": "Course", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "enrollment.course", + "fieldname": "course", + "fieldtype": "Data", + "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": "Course", + "length": 0, + "no_copy": 0, + "options": "", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fetch_from": "enrollment.student", - "fieldname": "student", - "fieldtype": "Data", - "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": "Student", - "length": 0, - "no_copy": 0, - "options": "", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fetch_from": "enrollment.student", + "fieldname": "student", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Student", + "length": 0, + "no_copy": 0, + "options": "", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "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": 0, - "in_standard_filter": 0, - "label": "Content Type", - "length": 0, - "no_copy": 0, - "options": "\nArticle\nVideo", - "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": 1, - "translatable": 0, + "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": 0, + "in_standard_filter": 0, + "label": "Content Type", + "length": 0, + "no_copy": 0, + "options": "\nArticle\nVideo", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "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": 1, - "translatable": 0, + "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": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "activity_date", - "fieldtype": "Datetime", - "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, - "label": "Activity Date", - "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": 1, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "activity_date", + "fieldtype": "Datetime", + "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, + "label": "Activity Date", + "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": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-07 21:15:03.187253", - "modified_by": "Administrator", - "module": "Education", - "name": "Course Activity", - "name_case": "", - "owner": "Administrator", + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-11-25 19:06:07.261070", + "modified_by": "Administrator", + "module": "Education", + "name": "Course Activity", + "name_case": "", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Academics User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 1, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 1, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 0 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 0 } - ], - "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, + ], + "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 } \ No newline at end of file diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment.json b/erpnext/education/doctype/course_enrollment/course_enrollment.json index a5b4289dca..6286ec1e66 100644 --- a/erpnext/education/doctype/course_enrollment/course_enrollment.json +++ b/erpnext/education/doctype/course_enrollment/course_enrollment.json @@ -1,267 +1,233 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 0, - "allow_rename": 0, - "autoname": "format:EDU-CE-{YYYY}-{#####}", - "beta": 0, - "creation": "2018-10-15 15:35:39.375161", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 0, + "allow_rename": 0, + "autoname": "format:EDU-CE-{YYYY}-{#####}", + "beta": 1, + "creation": "2018-10-15 15:35:39.375161", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "program_enrollment", - "fieldtype": "Link", - "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, - "label": "Program Enrollment", - "length": 0, - "no_copy": 0, - "options": "Program Enrollment", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "program_enrollment", + "fieldtype": "Link", + "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, + "label": "Program Enrollment", + "length": 0, + "no_copy": 0, + "options": "Program Enrollment", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Student", - "length": 0, - "no_copy": 0, - "options": "Student", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "student", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 1, + "label": "Student", + "length": 0, + "no_copy": 0, + "options": "Student", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "course", - "fieldtype": "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": "Course", - "length": 0, - "no_copy": 0, - "options": "Course", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "course", + "fieldtype": "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": "Course", + "length": 0, + "no_copy": 0, + "options": "Course", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "enrollment_date", - "fieldtype": "Date", - "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, - "label": "Enrollment Date", - "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 - }, - { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "0", - "fieldname": "completed", - "fieldtype": "Check", - "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, - "label": "Completed", - "length": 0, - "no_copy": 0, - "options": "", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "enrollment_date", + "fieldtype": "Date", + "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, + "label": "Enrollment Date", + "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": 1, + "search_index": 0, + "set_only_once": 1, + "translatable": 0, "unique": 0 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-09 19:23:07.967967", - "modified_by": "Administrator", - "module": "Education", - "name": "Course Enrollment", - "name_case": "", - "owner": "Administrator", + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-11-25 18:59:01.742377", + "modified_by": "Administrator", + "module": "Education", + "name": "Course Enrollment", + "name_case": "", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Academics User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 0 } - ], - "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, + ], + "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 } \ No newline at end of file diff --git a/erpnext/education/doctype/quiz/quiz.json b/erpnext/education/doctype/quiz/quiz.json index 55f133ce6d..f91bc0f021 100644 --- a/erpnext/education/doctype/quiz/quiz.json +++ b/erpnext/education/doctype/quiz/quiz.json @@ -222,7 +222,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-11-15 15:03:05.551204", + "modified": "2018-11-25 19:07:36.190116", "modified_by": "Administrator", "module": "Education", "name": "Quiz", diff --git a/erpnext/education/doctype/quiz_activity/quiz_activity.json b/erpnext/education/doctype/quiz_activity/quiz_activity.json index 4c6a2d6e0d..e78db42f7d 100644 --- a/erpnext/education/doctype/quiz_activity/quiz_activity.json +++ b/erpnext/education/doctype/quiz_activity/quiz_activity.json @@ -5,7 +5,7 @@ "allow_import": 0, "allow_rename": 0, "autoname": "format:EDU-QA-{YYYY}-{#####}", - "beta": 0, + "beta": 1, "creation": "2018-10-15 15:48:40.482821", "custom": 0, "docstatus": 0, @@ -413,7 +413,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2018-11-15 12:51:05.530727", + "modified": "2018-11-25 19:05:52.434437", "modified_by": "Administrator", "module": "Education", "name": "Quiz Activity", diff --git a/erpnext/education/doctype/video/video.json b/erpnext/education/doctype/video/video.json index 30ad89a622..cc8f718ba4 100644 --- a/erpnext/education/doctype/video/video.json +++ b/erpnext/education/doctype/video/video.json @@ -1,262 +1,262 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "autoname": "field:title", - "beta": 0, - "creation": "2018-10-17 05:47:13.087395", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 1, + "allow_rename": 0, + "autoname": "field:title", + "beta": 0, + "creation": "2018-10-17 05:47:13.087395", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "title", - "fieldtype": "Data", - "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, - "label": "Title", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "title", + "fieldtype": "Data", + "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, + "label": "Title", + "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": 1 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "description", - "fieldtype": "Text Editor", - "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, - "label": "Description", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "description", + "fieldtype": "Text Editor", + "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, + "label": "Description", + "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 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "duration", - "fieldtype": "Data", - "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, - "label": "Duration", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "duration", + "fieldtype": "Data", + "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, + "label": "Duration", + "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 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "url", - "fieldtype": "Data", - "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, - "label": "URL", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "url", + "fieldtype": "Data", + "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, + "label": "URL", + "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 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "publish_date", - "fieldtype": "Date", - "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, - "label": "Publish Date", - "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, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "publish_date", + "fieldtype": "Date", + "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, + "label": "Publish Date", + "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 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-07 22:14:29.957676", - "modified_by": "Administrator", - "module": "Education", - "name": "Video", - "name_case": "", - "owner": "Administrator", + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2018-11-25 19:07:17.134288", + "modified_by": "Administrator", + "module": "Education", + "name": "Video", + "name_case": "", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Academics User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Academics User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "Instructor", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "Instructor", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 - }, + }, { - "amend": 0, - "cancel": 0, - "create": 0, - "delete": 0, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "LMS User", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 0, + "delete": 0, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "LMS User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 0 } - ], - "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, + ], + "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 } \ No newline at end of file From cbb7c7ff2396abea32b3b9106e571f4ad8b4a8f1 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 26 Nov 2018 11:59:12 +0530 Subject: [PATCH 131/314] ui fixes --- erpnext/public/js/education/lms/components/CourseCard.vue | 6 ++++-- erpnext/public/js/education/lms/routes.js | 7 ++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/erpnext/public/js/education/lms/components/CourseCard.vue b/erpnext/public/js/education/lms/components/CourseCard.vue index e9b9e07f92..494c5e59af 100644 --- a/erpnext/public/js/education/lms/components/CourseCard.vue +++ b/erpnext/public/js/education/lms/components/CourseCard.vue @@ -38,12 +38,11 @@ export default { name: "CourseCard", data() { return { - isLogin: lms.store.isLogin, courseMeta: {} } }, mounted() { - if(this.isLogin) this.getCourseMeta().then(data => this.courseMeta = data) + this.getCourseMeta().then(data => this.courseMeta = data) }, components: { AButton @@ -65,6 +64,9 @@ export default { else { return " hidden" } + }, + isLogin() { + return lms.store.checkLogin() } }, methods: { diff --git a/erpnext/public/js/education/lms/routes.js b/erpnext/public/js/education/lms/routes.js index 921f8ec40e..e6eb002e16 100644 --- a/erpnext/public/js/education/lms/routes.js +++ b/erpnext/public/js/education/lms/routes.js @@ -12,7 +12,12 @@ const routes = [ component: ContentPage, props: true, beforeEnter: (to, from, next) => { - if(!lms.store.isLogin) next({name: 'home'}) + if(!lms.store.isLogin){ + next({name: 'home'}) + } + else { + next() + } } }, { From affbfe7d0c9b5d7560351aaf720ee746895295f1 Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 26 Nov 2018 11:59:25 +0530 Subject: [PATCH 132/314] Added get_program_meta --- erpnext/www/lms.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/erpnext/www/lms.py b/erpnext/www/lms.py index 505834c65a..047b321c91 100644 --- a/erpnext/www/lms.py +++ b/erpnext/www/lms.py @@ -211,4 +211,11 @@ def get_course_meta(course_name): elif count < len(progress): next_item = next(item for item in progress if item['is_complete']==False) return {'flag':'Continue', 'content_type': next_item['content_type'], 'content': next_item['content']} - \ No newline at end of file + +@frappe.whitelist() +def get_program_meta(program_name): + program = frappe.get_doc("Program", program_name) + program_meta = {} + for course in program.get_all_children(): + program_meta[course.course] = get_course_meta(course.course) + return program_meta \ No newline at end of file From 97c994f3947267fbd405a4c6c33971e7fd63edaf Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 26 Nov 2018 14:41:15 +0530 Subject: [PATCH 133/314] create course enrollment if not already enrolled for a program --- erpnext/education/utils.py | 7 ++++++- .../js/education/lms/components/CourseCard.vue | 8 +++++--- erpnext/www/lms.py | 17 +++++++++++------ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/erpnext/education/utils.py b/erpnext/education/utils.py index 6fb72f1d5d..bf7327b17e 100644 --- a/erpnext/education/utils.py +++ b/erpnext/education/utils.py @@ -109,7 +109,12 @@ def create_student(): }) student.save(ignore_permissions=True) frappe.db.commit() - return student_name + return student + +def enroll_in_course(course_name, program_name): + student_id = get_current_student() + student = frappe.get_doc("Student", student_id) + student.enroll_in_course(course_name=course_name, program_enrollment=get_program_enrollment(program_name)) def enroll_all_courses_in_program(program_enrollment, student): program = frappe.get_doc("Program", program_enrollment.program) diff --git a/erpnext/public/js/education/lms/components/CourseCard.vue b/erpnext/public/js/education/lms/components/CourseCard.vue index 494c5e59af..2c589ac318 100644 --- a/erpnext/public/js/education/lms/components/CourseCard.vue +++ b/erpnext/public/js/education/lms/components/CourseCard.vue @@ -67,7 +67,7 @@ export default { }, isLogin() { return lms.store.checkLogin() - } + }, }, methods: { iconClass(content_type) { @@ -77,9 +77,10 @@ export default { }, getCourseMeta() { return lms.call('get_course_meta', { - course_name: this.course.name + course_name: this.course.name, + program_name: this.program_name }) - } + }, } }; @@ -92,6 +93,7 @@ export default { } li { list-style-type: none; + padding: 0; } .fa { font-size: 0.8em; diff --git a/erpnext/www/lms.py b/erpnext/www/lms.py index 047b321c91..0033557aec 100644 --- a/erpnext/www/lms.py +++ b/erpnext/www/lms.py @@ -199,9 +199,10 @@ def check_quiz_completion(quiz, enrollment_name): return status, score, result @frappe.whitelist() -def get_course_meta(course_name): +def get_course_meta(course_name, program_name): course_enrollment = utils.get_course_enrollment(course_name) - # course_enrollment = frappe.get_doc("Course Enrollment", course_enrollment_name) + if not course_enrollment: + utils.enroll_in_course(course_name, program_name) progress = get_course_progress(course_enrollment) count = sum([act['is_complete'] for act in progress]) if count == 0: @@ -215,7 +216,11 @@ def get_course_meta(course_name): @frappe.whitelist() def get_program_meta(program_name): program = frappe.get_doc("Program", program_name) - program_meta = {} - for course in program.get_all_children(): - program_meta[course.course] = get_course_meta(course.course) - return program_meta \ No newline at end of file + program_enrollment = frappe.get_list("Program Enrollment", filters={'student': utils.get_current_student(), 'program': program_name })[0].name + if not program_enrollment: + return None + else: + program_meta = {} + for course in program.get_all_children(): + program_meta[course.course] = get_course_meta(course.course, program_name) + return program_meta \ No newline at end of file From 201fec3101f2af52812d3dce854379ca8b4022ec Mon Sep 17 00:00:00 2001 From: scmmishra Date: Mon, 26 Nov 2018 16:52:45 +0530 Subject: [PATCH 134/314] Minor Improvements --- .../js/education/lms/components/CourseCard.vue | 2 +- .../js/education/lms/components/TopSection.vue | 4 ---- erpnext/public/js/education/lms/pages/Home.vue | 10 ---------- erpnext/public/js/education/lms/pages/ListPage.vue | 12 +++++++----- erpnext/www/lms.py | 14 +++++++++++--- 5 files changed, 19 insertions(+), 23 deletions(-) diff --git a/erpnext/public/js/education/lms/components/CourseCard.vue b/erpnext/public/js/education/lms/components/CourseCard.vue index 2c589ac318..7839aa6a0b 100644 --- a/erpnext/public/js/education/lms/components/CourseCard.vue +++ b/erpnext/public/js/education/lms/components/CourseCard.vue @@ -67,7 +67,7 @@ export default { }, isLogin() { return lms.store.checkLogin() - }, + } }, methods: { iconClass(content_type) { diff --git a/erpnext/public/js/education/lms/components/TopSection.vue b/erpnext/public/js/education/lms/components/TopSection.vue index 03b5f9945a..107bef08ad 100644 --- a/erpnext/public/js/education/lms/components/TopSection.vue +++ b/erpnext/public/js/education/lms/components/TopSection.vue @@ -1,10 +1,6 @@