feat(Education): added form dashboards and refactored custom buttons for better linking (#22727)
* feat: add form dashboards to all forms in Education Module
* feat: Add Course to Programs button in Course DocType
* refactor: custom buttons in Education module forms
* feat: buttons to add topic, article, quiz to their respective parent doctypes
* feat: add charts to form dashboards
* fix: code cleanup
diff --git a/erpnext/education/doctype/academic_term/academic_term_dashboard.py b/erpnext/education/doctype/academic_term/academic_term_dashboard.py
new file mode 100644
index 0000000..871e0f3
--- /dev/null
+++ b/erpnext/education/doctype/academic_term/academic_term_dashboard.py
@@ -0,0 +1,25 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'academic_term',
+ 'transactions': [
+ {
+ 'label': _('Student'),
+ 'items': ['Student Applicant', 'Student Group', 'Student Log']
+ },
+ {
+ 'label': _('Fee'),
+ 'items': ['Fees', 'Fee Schedule', 'Fee Structure']
+ },
+ {
+ 'label': _('Program'),
+ 'items': ['Program Enrollment']
+ },
+ {
+ 'label': _('Assessment'),
+ 'items': ['Assessment Plan', 'Assessment Result']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/academic_year/academic_year.js b/erpnext/education/doctype/academic_year/academic_year.js
index 21caa63..0e86198 100644
--- a/erpnext/education/doctype/academic_year/academic_year.js
+++ b/erpnext/education/doctype/academic_year/academic_year.js
@@ -1,10 +1,2 @@
-frappe.ui.form.on("Academic Year", "refresh", function(frm) {
- if(!frm.doc.__islocal) {
- frm.add_custom_button(__("Student Group"), function() {
- frappe.route_options = {
- academic_year: frm.doc.name
- }
- frappe.set_route("List", "Student Group");
- });
- }
+frappe.ui.form.on("Academic Year", {
});
\ No newline at end of file
diff --git a/erpnext/education/doctype/academic_year/academic_year_dashboard.py b/erpnext/education/doctype/academic_year/academic_year_dashboard.py
new file mode 100644
index 0000000..f27f7d1
--- /dev/null
+++ b/erpnext/education/doctype/academic_year/academic_year_dashboard.py
@@ -0,0 +1,25 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'academic_year',
+ 'transactions': [
+ {
+ 'label': _('Student'),
+ 'items': ['Student Admission', 'Student Applicant', 'Student Group', 'Student Log']
+ },
+ {
+ 'label': _('Fee'),
+ 'items': ['Fees', 'Fee Schedule', 'Fee Structure']
+ },
+ {
+ 'label': _('Academic Term and Program'),
+ 'items': ['Academic Term', 'Program Enrollment']
+ },
+ {
+ 'label': _('Assessment'),
+ 'items': ['Assessment Plan', 'Assessment Result']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/article/article.js b/erpnext/education/doctype/article/article.js
index 4c9c6f0..edfec26 100644
--- a/erpnext/education/doctype/article/article.js
+++ b/erpnext/education/doctype/article/article.js
@@ -3,6 +3,54 @@
frappe.ui.form.on('Article', {
refresh: function(frm) {
+ if (!frm.doc.__islocal) {
+ frm.add_custom_button(__('Add to Topics'), function() {
+ frm.trigger('add_article_to_topics');
+ }, __('Action'));
+ }
+ },
+ add_article_to_topics: function(frm) {
+ get_topics_without_article(frm.doc.name).then(r => {
+ if (r.message.length) {
+ frappe.prompt([
+ {
+ fieldname: 'topics',
+ label: __('Topics'),
+ fieldtype: 'MultiSelectPills',
+ get_data: function() {
+ return r.message;
+ }
+ }
+ ],
+ function(data) {
+ frappe.call({
+ method: 'erpnext.education.doctype.topic.topic.add_content_to_topics',
+ args: {
+ 'content_type': 'Article',
+ 'content': frm.doc.name,
+ 'topics': data.topics,
+ },
+ callback: function(r) {
+ if (!r.exc) {
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: __('...Adding Article to Topics')
+ });
+ }, __('Add Article to Topics'), __('Add'));
+ } else {
+ frappe.msgprint(__('This article is already added to the existing topics'));
+ }
+ });
}
});
+
+let get_topics_without_article = function(article) {
+ return frappe.call({
+ type: 'GET',
+ method: 'erpnext.education.doctype.article.article.get_topics_without_article',
+ args: {'article': article}
+ });
+};
\ No newline at end of file
diff --git a/erpnext/education/doctype/article/article.py b/erpnext/education/doctype/article/article.py
index 7dc850b..8ba367d 100644
--- a/erpnext/education/doctype/article/article.py
+++ b/erpnext/education/doctype/article/article.py
@@ -7,9 +7,15 @@
from frappe.model.document import Document
class Article(Document):
-
-
def get_article(self):
pass
-
+@frappe.whitelist()
+def get_topics_without_article(article):
+ data = []
+ for entry in frappe.db.get_all('Topic'):
+ topic = frappe.get_doc('Topic', entry.name)
+ topic_contents = [tc.content for tc in topic.topic_content]
+ if not topic_contents or article not in topic_contents:
+ data.append(topic.name)
+ return data
\ No newline at end of file
diff --git a/erpnext/education/doctype/assessment_group/assessment_group_dashboard.py b/erpnext/education/doctype/assessment_group/assessment_group_dashboard.py
new file mode 100644
index 0000000..2649d4b
--- /dev/null
+++ b/erpnext/education/doctype/assessment_group/assessment_group_dashboard.py
@@ -0,0 +1,15 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'assessment_group',
+ 'transactions': [
+ {
+ 'label': _('Assessment'),
+ 'items': ['Assessment Plan', 'Assessment Result']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/assessment_plan/assessment_plan.js b/erpnext/education/doctype/assessment_plan/assessment_plan.js
index 0cb642b..c4c5614 100644
--- a/erpnext/education/doctype/assessment_plan/assessment_plan.js
+++ b/erpnext/education/doctype/assessment_plan/assessment_plan.js
@@ -2,9 +2,9 @@
// For license information, please see license.txt
-frappe.ui.form.on("Assessment Plan", {
+frappe.ui.form.on('Assessment Plan', {
onload: function(frm) {
- frm.set_query("assessment_group", function(doc, cdt, cdn) {
+ frm.set_query('assessment_group', function(doc, cdt, cdn) {
return{
filters: {
'is_group': 0
@@ -22,20 +22,20 @@
refresh: function(frm) {
if (frm.doc.docstatus == 1) {
- frm.add_custom_button(__("Assessment Result"), function() {
+ frm.add_custom_button(__('Assessment Result Tool'), function() {
frappe.route_options = {
assessment_plan: frm.doc.name,
student_group: frm.doc.student_group
}
- frappe.set_route("Form", "Assessment Result Tool");
- });
+ frappe.set_route('Form', 'Assessment Result Tool');
+ }, __('Tools'));
}
},
course: function(frm) {
if (frm.doc.course && frm.doc.maximum_assessment_score) {
frappe.call({
- method: "erpnext.education.api.get_assessment_criteria",
+ method: 'erpnext.education.api.get_assessment_criteria',
args: {
course: frm.doc.course
},
@@ -43,12 +43,12 @@
if (r.message) {
frm.doc.assessment_criteria = [];
$.each(r.message, function(i, d) {
- var row = frappe.model.add_child(frm.doc, "Assessment Plan Criteria", "assessment_criteria");
+ var row = frappe.model.add_child(frm.doc, 'Assessment Plan Criteria', 'assessment_criteria');
row.assessment_criteria = d.assessment_criteria;
row.maximum_score = d.weightage / 100 * frm.doc.maximum_assessment_score;
});
}
- refresh_field("assessment_criteria");
+ refresh_field('assessment_criteria');
}
});
@@ -56,6 +56,6 @@
},
maximum_assessment_score: function(frm) {
- frm.trigger("course");
+ frm.trigger('course');
}
});
\ No newline at end of file
diff --git a/erpnext/education/doctype/assessment_plan/assessment_plan_dashboard.py b/erpnext/education/doctype/assessment_plan/assessment_plan_dashboard.py
index c36dfb1..5e6c29d 100644
--- a/erpnext/education/doctype/assessment_plan/assessment_plan_dashboard.py
+++ b/erpnext/education/doctype/assessment_plan/assessment_plan_dashboard.py
@@ -6,12 +6,16 @@
def get_data():
return {
'fieldname': 'assessment_plan',
- 'non_standard_fieldnames': {
- },
'transactions': [
{
'label': _('Assessment'),
'items': ['Assessment Result']
}
+ ],
+ 'reports': [
+ {
+ 'label': _('Report'),
+ 'items': ['Assessment Plan Status']
+ }
]
}
\ No newline at end of file
diff --git a/erpnext/education/doctype/assessment_result/assessment_result.js b/erpnext/education/doctype/assessment_result/assessment_result.js
index 84865ca..12fdd91 100644
--- a/erpnext/education/doctype/assessment_result/assessment_result.js
+++ b/erpnext/education/doctype/assessment_result/assessment_result.js
@@ -1,7 +1,13 @@
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
-frappe.ui.form.on("Assessment Result", {
+frappe.ui.form.on('Assessment Result', {
+ refresh: function(frm) {
+ if (!frm.doc.__islocal) {
+ frm.trigger('setup_chart');
+ }
+ },
+
onload: function(frm) {
frm.set_query('assessment_plan', function(){
return {
@@ -15,7 +21,7 @@
assessment_plan: function(frm) {
if (frm.doc.assessment_plan) {
frappe.call({
- method: "erpnext.education.api.get_assessment_details",
+ method: 'erpnext.education.api.get_assessment_details',
args: {
assessment_plan: frm.doc.assessment_plan
},
@@ -23,40 +29,75 @@
if (r.message) {
frm.doc.details = [];
$.each(r.message, function(i, d) {
- var row = frappe.model.add_child(frm.doc, "Assessment Result Detail", "details");
+ var row = frappe.model.add_child(frm.doc, 'Assessment Result Detail', 'details');
row.assessment_criteria = d.assessment_criteria;
row.maximum_score = d.maximum_score;
});
}
- refresh_field("details");
+ refresh_field('details');
}
});
}
+ },
+
+ setup_chart: function(frm) {
+ let labels = [];
+ let maximum_scores = [];
+ let scores = [];
+ $.each(frm.doc.details, function(_i, e) {
+ labels.push(e.assessment_criteria);
+ maximum_scores.push(e.maximum_score);
+ scores.push(e.score);
+ });
+
+ if (labels.length && maximum_scores.length && scores.length) {
+ frm.dashboard.chart_area.empty().removeClass('hidden');
+ new frappe.Chart('.form-graph', {
+ title: 'Assessment Results',
+ data: {
+ labels: labels,
+ datasets: [
+ {
+ name: 'Maximum Score',
+ chartType: 'bar',
+ values: maximum_scores,
+ },
+ {
+ name: 'Score Obtained',
+ chartType: 'bar',
+ values: scores,
+ }
+ ]
+ },
+ colors: ['#4CA746', '#98D85B'],
+ type: 'bar'
+ });
+ }
}
});
-frappe.ui.form.on("Assessment Result Detail", {
+frappe.ui.form.on('Assessment Result Detail', {
score: function(frm, cdt, cdn) {
var d = locals[cdt][cdn];
if(!d.maximum_score || !frm.doc.grading_scale) {
- d.score = "";
- frappe.throw(__("Please fill in all the details to generate Assessment Result."));
+ d.score = '';
+ frappe.throw(__('Please fill in all the details to generate Assessment Result.'));
}
if (d.score > d.maximum_score) {
- frappe.throw(__("Score cannot be greater than Maximum Score"));
+ frappe.throw(__('Score cannot be greater than Maximum Score'));
}
else {
frappe.call({
- method: "erpnext.education.api.get_grade",
+ method: 'erpnext.education.api.get_grade',
args: {
grading_scale: frm.doc.grading_scale,
percentage: ((d.score/d.maximum_score) * 100)
},
callback: function(r) {
if (r.message) {
- frappe.model.set_value(cdt, cdn, "grade", r.message);
+ frappe.model.set_value(cdt, cdn, 'grade', r.message);
}
}
});
diff --git a/erpnext/education/doctype/assessment_result/assessment_result_dashboard.py b/erpnext/education/doctype/assessment_result/assessment_result_dashboard.py
new file mode 100644
index 0000000..438379d
--- /dev/null
+++ b/erpnext/education/doctype/assessment_result/assessment_result_dashboard.py
@@ -0,0 +1,14 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'reports': [
+ {
+ 'label': _('Reports'),
+ 'items': ['Final Assessment Grades', 'Course wise Assessment Report']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/course/course.js b/erpnext/education/doctype/course/course.js
index 6932989..81e4a8c 100644
--- a/erpnext/education/doctype/course/course.js
+++ b/erpnext/education/doctype/course/course.js
@@ -1,41 +1,60 @@
-frappe.ui.form.on("Course", "refresh", function(frm) {
- if(!cur_frm.doc.__islocal) {
- frm.add_custom_button(__("Program"), function() {
- frappe.route_options = {
- "Program Course.course": frm.doc.name
- }
- frappe.set_route("List", "Program");
- });
+frappe.ui.form.on('Course', {
+ refresh: function(frm) {
+ if (!cur_frm.doc.__islocal) {
+ frm.add_custom_button(__('Add to Programs'), function() {
+ frm.trigger('add_course_to_programs')
+ }, __('Action'));
+ }
- frm.add_custom_button(__("Student Group"), function() {
- frappe.route_options = {
- course: frm.doc.name
+ frm.set_query('default_grading_scale', function(){
+ return {
+ filters: {
+ docstatus: 1
+ }
}
- frappe.set_route("List", "Student Group");
});
+ },
- frm.add_custom_button(__("Course Schedule"), function() {
- frappe.route_options = {
- course: frm.doc.name
+ add_course_to_programs: function(frm) {
+ get_programs_without_course(frm.doc.name).then(r => {
+ if (r.message.length) {
+ frappe.prompt([
+ {
+ fieldname: 'programs',
+ label: __('Programs'),
+ fieldtype: 'MultiSelectPills',
+ get_data: function() {
+ return r.message;
+ }
+ },
+ {
+ fieldtype: 'Check',
+ label: __('Is Mandatory'),
+ fieldname: 'mandatory',
+ }
+ ],
+ function(data) {
+ frappe.call({
+ method: 'erpnext.education.doctype.course.course.add_course_to_programs',
+ args: {
+ 'course': frm.doc.name,
+ 'programs': data.programs,
+ 'mandatory': data.mandatory
+ },
+ callback: function(r) {
+ if (!r.exc) {
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: __('...Adding Course to Programs')
+ })
+ }, __('Add Course to Programs'), __('Add'));
+ } else {
+ frappe.msgprint(__('This course is already added to the existing programs'));
}
- frappe.set_route("List", "Course Schedule");
- });
-
- frm.add_custom_button(__("Assessment Plan"), function() {
- frappe.route_options = {
- course: frm.doc.name
- }
- frappe.set_route("List", "Assessment Plan");
});
}
-
- frm.set_query('default_grading_scale', function(){
- return {
- filters: {
- docstatus: 1
- }
- }
- });
});
frappe.ui.form.on('Course Topic', {
@@ -50,3 +69,11 @@
};
}
});
+
+let get_programs_without_course = function(course) {
+ return frappe.call({
+ type: 'GET',
+ method: 'erpnext.education.doctype.course.course.get_programs_without_course',
+ args: {'course': course}
+ });
+}
\ No newline at end of file
diff --git a/erpnext/education/doctype/course/course.py b/erpnext/education/doctype/course/course.py
index 0747a22..06efa54 100644
--- a/erpnext/education/doctype/course/course.py
+++ b/erpnext/education/doctype/course/course.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
+import json
from frappe.model.document import Document
from frappe import _
@@ -17,12 +18,39 @@
for criteria in self.assessment_criteria:
total_weightage += criteria.weightage or 0
if total_weightage != 100:
- frappe.throw(_("Total Weightage of all Assessment Criteria must be 100%"))
+ frappe.throw(_('Total Weightage of all Assessment Criteria must be 100%'))
def get_topics(self):
topic_data= []
for topic in self.topics:
- topic_doc = frappe.get_doc("Topic", topic.topic)
+ topic_doc = frappe.get_doc('Topic', topic.topic)
if topic_doc.topic_content:
topic_data.append(topic_doc)
- return topic_data
\ No newline at end of file
+ return topic_data
+
+
+@frappe.whitelist()
+def add_course_to_programs(course, programs, mandatory=False):
+ programs = json.loads(programs)
+ for entry in programs:
+ program = frappe.get_doc('Program', entry)
+ program.append('courses', {
+ 'course': course,
+ 'course_name': course,
+ 'mandatory': mandatory
+ })
+ program.flags.ignore_mandatory = True
+ program.save()
+ frappe.db.commit()
+ frappe.msgprint(_('Course {0} has been added to all the selected programs successfully.').format(frappe.bold(course)),
+ title=_('Programs updated'), indicator='green')
+
+@frappe.whitelist()
+def get_programs_without_course(course):
+ data = []
+ for entry in frappe.db.get_all('Program'):
+ program = frappe.get_doc('Program', entry.name)
+ courses = [c.course for c in program.courses]
+ if not courses or course not in courses:
+ data.append(program.name)
+ return data
\ No newline at end of file
diff --git a/erpnext/education/doctype/course/course_dashboard.py b/erpnext/education/doctype/course/course_dashboard.py
index 752af29..8a570bd 100644
--- a/erpnext/education/doctype/course/course_dashboard.py
+++ b/erpnext/education/doctype/course/course_dashboard.py
@@ -6,12 +6,10 @@
def get_data():
return {
'fieldname': 'course',
- 'non_standard_fieldnames': {
- },
'transactions': [
{
- 'label': _('Course'),
- 'items': ['Course Enrollment', 'Course Schedule']
+ 'label': _('Program and Course'),
+ 'items': ['Program', 'Course Enrollment', 'Course Schedule']
},
{
'label': _('Student'),
@@ -19,7 +17,7 @@
},
{
'label': _('Assessment'),
- 'items': ['Assessment Plan']
+ 'items': ['Assessment Plan', 'Assessment Result']
},
]
}
\ No newline at end of file
diff --git a/erpnext/education/doctype/course_enrollment/course_enrollment_dashboard.py b/erpnext/education/doctype/course_enrollment/course_enrollment_dashboard.py
new file mode 100644
index 0000000..b9dd457
--- /dev/null
+++ b/erpnext/education/doctype/course_enrollment/course_enrollment_dashboard.py
@@ -0,0 +1,15 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'enrollment',
+ 'transactions': [
+ {
+ 'label': _('Activity'),
+ 'items': ['Course Activity', 'Quiz Activity']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/course_schedule/course_schedule.js b/erpnext/education/doctype/course_schedule/course_schedule.js
index 692c2a8..4275f6e 100644
--- a/erpnext/education/doctype/course_schedule/course_schedule.js
+++ b/erpnext/education/doctype/course_schedule/course_schedule.js
@@ -4,13 +4,13 @@
frappe.ui.form.on("Course Schedule", {
refresh: function(frm) {
if (!frm.doc.__islocal) {
- frm.add_custom_button(__("Attendance"), function() {
+ frm.add_custom_button(__("Mark Attendance"), function() {
frappe.route_options = {
based_on: "Course Schedule",
course_schedule: frm.doc.name
}
frappe.set_route("Form", "Student Attendance Tool");
- });
+ }).addClass("btn-primary");
}
}
});
\ No newline at end of file
diff --git a/erpnext/education/doctype/course_schedule/course_schedule.json b/erpnext/education/doctype/course_schedule/course_schedule.json
index 7346cab..8c6746b 100644
--- a/erpnext/education/doctype/course_schedule/course_schedule.json
+++ b/erpnext/education/doctype/course_schedule/course_schedule.json
@@ -1,520 +1,520 @@
{
- "allow_copy": 0,
- "allow_guest_to_view": 0,
- "allow_import": 1,
- "allow_rename": 0,
- "autoname": "naming_series:",
- "beta": 0,
- "creation": "2015-09-09 16:34:04.960369",
- "custom": 0,
- "docstatus": 0,
- "doctype": "DocType",
- "document_type": "Document",
- "editable_grid": 0,
- "engine": "InnoDB",
+ "allow_copy": 0,
+ "allow_guest_to_view": 0,
+ "allow_import": 1,
+ "allow_rename": 0,
+ "autoname": "naming_series:",
+ "beta": 0,
+ "creation": "2015-09-09 16:34:04.960369",
+ "custom": 0,
+ "docstatus": 0,
+ "doctype": "DocType",
+ "document_type": "Document",
+ "editable_grid": 0,
+ "engine": "InnoDB",
"fields": [
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "fieldname": "student_group",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 1,
- "label": "Student Group",
- "length": 0,
- "no_copy": 0,
- "options": "Student Group",
- "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_group",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 0,
+ "in_standard_filter": 1,
+ "label": "Student Group",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Student Group",
+ "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": "instructor",
- "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": "Instructor",
- "length": 0,
- "no_copy": 0,
- "options": "Instructor",
- "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": "instructor",
+ "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": "Instructor",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Instructor",
+ "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,
- "fetch_from": "instructor.Instructor_name",
- "fieldname": "instructor_name",
- "fieldtype": "Read Only",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "label": "Instructor Name",
- "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": "instructor.Instructor_name",
+ "fieldname": "instructor_name",
+ "fieldtype": "Read Only",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 1,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Instructor Name",
+ "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,
- "fieldname": "column_break_2",
- "fieldtype": "Column Break",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 0,
- "in_list_view": 0,
- "in_standard_filter": 0,
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 0,
- "print_hide_if_no_value": 0,
- "read_only": 0,
- "remember_last_selected_value": 0,
- "report_hide": 0,
- "reqd": 0,
- "search_index": 0,
- "set_only_once": 0,
- "translatable": 0,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_2",
+ "fieldtype": "Column Break",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
"unique": 0
- },
+ },
{
- "allow_bulk_edit": 0,
- "allow_in_quick_entry": 0,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "",
- "fieldname": "naming_series",
- "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": "Naming Series",
- "length": 0,
- "no_copy": 0,
- "options": "EDU-CSH-.YYYY.-",
- "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,
+ "default": "",
+ "fieldname": "naming_series",
+ "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": "Naming Series",
+ "length": 0,
+ "no_copy": 0,
+ "options": "EDU-CSH-.YYYY.-",
+ "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": "course",
- "fieldtype": "Link",
- "hidden": 0,
- "ignore_user_permissions": 0,
- "ignore_xss_filter": 0,
- "in_filter": 0,
- "in_global_search": 1,
- "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": 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": 1,
+ "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": 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": "color",
- "fieldtype": "Color",
- "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": "Color",
- "length": 0,
- "no_copy": 0,
- "permlevel": 0,
- "precision": "",
- "print_hide": 1,
- "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": "color",
+ "fieldtype": "Color",
+ "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": "Color",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 1,
+ "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_6",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "section_break_6",
+ "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,
- "allow_on_submit": 0,
- "bold": 0,
- "collapsible": 0,
- "columns": 0,
- "default": "Today",
- "fieldname": "schedule_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": "Schedule 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,
+ "default": "Today",
+ "fieldname": "schedule_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": "Schedule 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,
- "fieldname": "room",
- "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": "Room",
- "length": 0,
- "no_copy": 0,
- "options": "Room",
- "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": "room",
+ "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": "Room",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Room",
+ "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_9",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "column_break_9",
+ "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,
- "fieldname": "from_time",
- "fieldtype": "Time",
- "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": "From Time",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "from_time",
+ "fieldtype": "Time",
+ "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": "From Time",
+ "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": "to_time",
- "fieldtype": "Time",
- "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": "To Time",
- "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,
+ "allow_bulk_edit": 0,
+ "allow_in_quick_entry": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "to_time",
+ "fieldtype": "Time",
+ "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": "To Time",
+ "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": "title",
- "fieldtype": "Data",
- "hidden": 1,
- "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": 1,
+ "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": 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,
- "menu_index": 0,
- "modified": "2018-08-21 14:44:51.827225",
- "modified_by": "Administrator",
- "module": "Education",
- "name": "Course Schedule",
- "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,
+ "menu_index": 0,
+ "modified": "2018-08-21 14:44:51.827225",
+ "modified_by": "Administrator",
+ "module": "Education",
+ "name": "Course Schedule",
+ "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
}
- ],
- "quick_entry": 0,
- "read_only": 0,
- "read_only_onload": 0,
- "restrict_to_domain": "Education",
- "show_name_in_global_search": 0,
- "sort_field": "schedule_date",
- "sort_order": "DESC",
- "title_field": "title",
- "track_changes": 0,
- "track_seen": 0,
+ ],
+ "quick_entry": 0,
+ "read_only": 0,
+ "read_only_onload": 0,
+ "restrict_to_domain": "Education",
+ "show_name_in_global_search": 0,
+ "sort_field": "schedule_date",
+ "sort_order": "DESC",
+ "title_field": "title",
+ "track_changes": 0,
+ "track_seen": 0,
"track_views": 0
}
\ No newline at end of file
diff --git a/erpnext/education/doctype/course_schedule/course_schedule_dashboard.py b/erpnext/education/doctype/course_schedule/course_schedule_dashboard.py
new file mode 100644
index 0000000..0866cd6
--- /dev/null
+++ b/erpnext/education/doctype/course_schedule/course_schedule_dashboard.py
@@ -0,0 +1,15 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'course_schedule',
+ 'transactions': [
+ {
+ 'label': _('Attendance'),
+ 'items': ['Student Attendance']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule.js b/erpnext/education/doctype/fee_schedule/fee_schedule.js
index 1338331..75dd446 100644
--- a/erpnext/education/doctype/fee_schedule/fee_schedule.js
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule.js
@@ -3,13 +3,13 @@
frappe.ui.form.on('Fee Schedule', {
setup: function(frm) {
- frm.add_fetch("fee_structure", "receivable_account", "receivable_account");
- frm.add_fetch("fee_structure", "income_account", "income_account");
- frm.add_fetch("fee_structure", "cost_center", "cost_center");
+ frm.add_fetch('fee_structure', 'receivable_account', 'receivable_account');
+ frm.add_fetch('fee_structure', 'income_account', 'income_account');
+ frm.add_fetch('fee_structure', 'cost_center', 'cost_center');
},
onload: function(frm) {
- frm.set_query("receivable_account", function(doc) {
+ frm.set_query('receivable_account', function(doc) {
return {
filters: {
'account_type': 'Receivable',
@@ -18,7 +18,8 @@
}
};
});
- frm.set_query("income_account", function(doc) {
+
+ frm.set_query('income_account', function(doc) {
return {
filters: {
'account_type': 'Income Account',
@@ -27,57 +28,59 @@
}
};
});
- frm.set_query("student_group", "student_groups", function() {
+
+ frm.set_query('student_group', 'student_groups', function() {
return {
- "program": frm.doc.program,
- "academic_term": frm.doc.academic_term,
- "academic_year": frm.doc.academic_year,
- "disabled": 0
+ 'program': frm.doc.program,
+ 'academic_term': frm.doc.academic_term,
+ 'academic_year': frm.doc.academic_year,
+ 'disabled': 0
};
});
- frappe.realtime.on("fee_schedule_progress", function(data) {
+
+ frappe.realtime.on('fee_schedule_progress', function(data) {
if (data.reload && data.reload === 1) {
frm.reload_doc();
}
if (data.progress) {
- let progress_bar = $(cur_frm.dashboard.progress_area).find(".progress-bar");
+ let progress_bar = $(cur_frm.dashboard.progress_area).find('.progress-bar');
if (progress_bar) {
- $(progress_bar).removeClass("progress-bar-danger").addClass("progress-bar-success progress-bar-striped");
- $(progress_bar).css("width", data.progress+"%");
+ $(progress_bar).removeClass('progress-bar-danger').addClass('progress-bar-success progress-bar-striped');
+ $(progress_bar).css('width', data.progress+'%');
}
}
});
},
refresh: function(frm) {
- if(!frm.doc.__islocal && frm.doc.__onload && frm.doc.__onload.dashboard_info &&
- frm.doc.fee_creation_status=="Successful") {
+ if (!frm.doc.__islocal && frm.doc.__onload && frm.doc.__onload.dashboard_info &&
+ frm.doc.fee_creation_status === 'Successful') {
var info = frm.doc.__onload.dashboard_info;
frm.dashboard.add_indicator(__('Total Collected: {0}', [format_currency(info.total_paid,
info.currency)]), 'blue');
frm.dashboard.add_indicator(__('Total Outstanding: {0}', [format_currency(info.total_unpaid,
info.currency)]), info.total_unpaid ? 'orange' : 'green');
}
- if (frm.doc.fee_creation_status=="In Process") {
- frm.dashboard.add_progress("Fee Creation Status", "0");
+ if (frm.doc.fee_creation_status === 'In Process') {
+ frm.dashboard.add_progress('Fee Creation Status', '0');
}
- if (frm.doc.docstatus==1 && !frm.doc.fee_creation_status || frm.doc.fee_creation_status == "Failed") {
+ if (frm.doc.docstatus === 1 && !frm.doc.fee_creation_status || frm.doc.fee_creation_status === 'Failed') {
frm.add_custom_button(__('Create Fees'), function() {
frappe.call({
- method: "create_fees",
+ method: 'create_fees',
doc: frm.doc,
callback: function() {
frm.refresh();
}
});
- }, "fa fa-play", "btn-success");
+ }).addClass('btn-primary');;
}
- if (frm.doc.fee_creation_status == "Successful") {
- frm.add_custom_button(__("View Fees Records"), function() {
+ if (frm.doc.fee_creation_status === 'Successful') {
+ frm.add_custom_button(__('View Fees Records'), function() {
frappe.route_options = {
fee_schedule: frm.doc.name
};
- frappe.set_route("List", "Fees");
+ frappe.set_route('List', 'Fees');
});
}
@@ -86,35 +89,35 @@
fee_structure: function(frm) {
if (frm.doc.fee_structure) {
frappe.call({
- method: "erpnext.education.doctype.fee_schedule.fee_schedule.get_fee_structure",
+ method: 'erpnext.education.doctype.fee_schedule.fee_schedule.get_fee_structure',
args: {
- "target_doc": frm.doc.name,
- "source_name": frm.doc.fee_structure
+ 'target_doc': frm.doc.name,
+ 'source_name': frm.doc.fee_structure
},
callback: function(r) {
var doc = frappe.model.sync(r.message);
- frappe.set_route("Form", doc[0].doctype, doc[0].name);
+ frappe.set_route('Form', doc[0].doctype, doc[0].name);
}
});
}
}
});
-frappe.ui.form.on("Fee Schedule Student Group", {
+frappe.ui.form.on('Fee Schedule Student Group', {
student_group: function(frm, cdt, cdn) {
var row = locals[cdt][cdn];
if (row.student_group && frm.doc.academic_year) {
frappe.call({
- method: "erpnext.education.doctype.fee_schedule.fee_schedule.get_total_students",
+ method: 'erpnext.education.doctype.fee_schedule.fee_schedule.get_total_students',
args: {
- "student_group": row.student_group,
- "academic_year": frm.doc.academic_year,
- "academic_term": frm.doc.academic_term,
- "student_category": frm.doc.student_category
+ 'student_group': row.student_group,
+ 'academic_year': frm.doc.academic_year,
+ 'academic_term': frm.doc.academic_term,
+ 'student_category': frm.doc.student_category
},
callback: function(r) {
- if(!r.exc) {
- frappe.model.set_value(cdt, cdn, "total_students", r.message);
+ if (!r.exc) {
+ frappe.model.set_value(cdt, cdn, 'total_students', r.message);
}
}
});
diff --git a/erpnext/education/doctype/fee_schedule/fee_schedule_dashboard.py b/erpnext/education/doctype/fee_schedule/fee_schedule_dashboard.py
new file mode 100644
index 0000000..acfe400
--- /dev/null
+++ b/erpnext/education/doctype/fee_schedule/fee_schedule_dashboard.py
@@ -0,0 +1,13 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+
+def get_data():
+ return {
+ 'fieldname': 'fee_schedule',
+ 'transactions': [
+ {
+ 'items': ['Fees']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/fee_structure/fee_structure.js b/erpnext/education/doctype/fee_structure/fee_structure.js
index f09d2ef..b331c6d 100644
--- a/erpnext/education/doctype/fee_structure/fee_structure.js
+++ b/erpnext/education/doctype/fee_structure/fee_structure.js
@@ -3,21 +3,21 @@
frappe.ui.form.on('Fee Structure', {
setup: function(frm) {
- frm.add_fetch("company", "default_receivable_account", "receivable_account");
- frm.add_fetch("company", "default_income_account", "income_account");
- frm.add_fetch("company", "cost_center", "cost_center");
+ frm.add_fetch('company', 'default_receivable_account', 'receivable_account');
+ frm.add_fetch('company', 'default_income_account', 'income_account');
+ frm.add_fetch('company', 'cost_center', 'cost_center');
},
onload: function(frm) {
- frm.set_query("academic_term", function() {
+ frm.set_query('academic_term', function() {
return {
- "filters": {
- "academic_year": frm.doc.academic_year
+ 'filters': {
+ 'academic_year': frm.doc.academic_year
}
};
});
- frm.set_query("receivable_account", function(doc) {
+ frm.set_query('receivable_account', function(doc) {
return {
filters: {
'account_type': 'Receivable',
@@ -26,7 +26,7 @@
}
};
});
- frm.set_query("income_account", function(doc) {
+ frm.set_query('income_account', function(doc) {
return {
filters: {
'account_type': 'Income Account',
@@ -38,27 +38,27 @@
},
refresh: function(frm) {
- if(frm.doc.docstatus === 1) {
+ if (frm.doc.docstatus === 1) {
frm.add_custom_button(__('Create Fee Schedule'), function() {
frm.events.make_fee_schedule(frm);
- });
+ }).addClass('btn-primary');
}
},
make_fee_schedule: function(frm) {
frappe.model.open_mapped_doc({
- method: "erpnext.education.doctype.fee_structure.fee_structure.make_fee_schedule",
+ method: 'erpnext.education.doctype.fee_structure.fee_structure.make_fee_schedule',
frm: frm
});
}
});
-frappe.ui.form.on("Fee Component", {
+frappe.ui.form.on('Fee Component', {
amount: function(frm) {
var total_amount = 0;
- for(var i=0;i<frm.doc.components.length;i++) {
+ for (var i=0;i<frm.doc.components.length;i++) {
total_amount += frm.doc.components[i].amount;
}
- frm.set_value("total_amount", total_amount);
+ frm.set_value('total_amount', total_amount);
}
});
\ No newline at end of file
diff --git a/erpnext/education/doctype/fee_structure/fee_structure_dashboard.py b/erpnext/education/doctype/fee_structure/fee_structure_dashboard.py
new file mode 100644
index 0000000..73e314f
--- /dev/null
+++ b/erpnext/education/doctype/fee_structure/fee_structure_dashboard.py
@@ -0,0 +1,15 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'fee_structure',
+ 'transactions': [
+ {
+ 'label': _('Fee'),
+ 'items': ['Fees', 'Fee Schedule']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/grading_scale/grading_scale_dashboard.py b/erpnext/education/doctype/grading_scale/grading_scale_dashboard.py
new file mode 100644
index 0000000..2a3f13b
--- /dev/null
+++ b/erpnext/education/doctype/grading_scale/grading_scale_dashboard.py
@@ -0,0 +1,20 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'grading_scale',
+ 'non_standard_fieldnames': {
+ 'Course': 'default_grading_scale'
+ },
+ 'transactions': [
+ {
+ 'label': _('Course'),
+ 'items': ['Course']
+ },
+ {
+ 'label': _('Assessment'),
+ 'items': ['Assessment Plan', 'Assessment Result']
+ }
+ ]
+ }
diff --git a/erpnext/education/doctype/instructor/instructor.js b/erpnext/education/doctype/instructor/instructor.js
index 69bd2cf..abb47ed 100644
--- a/erpnext/education/doctype/instructor/instructor.js
+++ b/erpnext/education/doctype/instructor/instructor.js
@@ -3,8 +3,8 @@
frappe.ui.form.on("Instructor", {
employee: function(frm) {
- if(!frm.doc.employee) return;
- frappe.db.get_value('Employee', {name: frm.doc.employee}, 'company', (d) => {
+ if (!frm.doc.employee) return;
+ frappe.db.get_value("Employee", {name: frm.doc.employee}, "company", (d) => {
frm.set_query("department", function() {
return {
"filters": {
@@ -22,30 +22,16 @@
});
},
refresh: function(frm) {
- if(!frm.doc.__islocal) {
- frm.add_custom_button(__("Student Group"), function() {
- frappe.route_options = {
- instructor: frm.doc.name
- }
- frappe.set_route("List", "Student Group");
- });
- frm.add_custom_button(__("Course Schedule"), function() {
- frappe.route_options = {
- instructor: frm.doc.name
- }
- frappe.set_route("List", "Course Schedule");
- });
+ if (!frm.doc.__islocal) {
frm.add_custom_button(__("As Examiner"), function() {
- frappe.route_options = {
+ frappe.new_doc("Assessment Plan", {
examiner: frm.doc.name
- }
- frappe.set_route("List", "Assessment Plan");
+ });
}, __("Assessment Plan"));
frm.add_custom_button(__("As Supervisor"), function() {
- frappe.route_options = {
+ frappe.new_doc("Assessment Plan", {
supervisor: frm.doc.name
- }
- frappe.set_route("List", "Assessment Plan");
+ });
}, __("Assessment Plan"));
}
frm.set_query("employee", function(doc) {
diff --git a/erpnext/education/doctype/instructor/instructor.py b/erpnext/education/doctype/instructor/instructor.py
index 28df2fc..b1bfcbb 100644
--- a/erpnext/education/doctype/instructor/instructor.py
+++ b/erpnext/education/doctype/instructor/instructor.py
@@ -30,4 +30,14 @@
if self.employee and frappe.db.get_value("Instructor", {'employee': self.employee, 'name': ['!=', self.name]}, 'name'):
frappe.throw(_("Employee ID is linked with another instructor"))
-
+def get_timeline_data(doctype, name):
+ """Return timeline for course schedule"""
+ return dict(frappe.db.sql(
+ """
+ SELECT unix_timestamp(`schedule_date`), count(*)
+ FROM `tabCourse Schedule`
+ WHERE
+ instructor=%s and
+ `schedule_date` > date_sub(curdate(), interval 1 year)
+ GROUP BY schedule_date
+ """, name))
diff --git a/erpnext/education/doctype/instructor/instructor_dashboard.py b/erpnext/education/doctype/instructor/instructor_dashboard.py
new file mode 100644
index 0000000..a404fc5
--- /dev/null
+++ b/erpnext/education/doctype/instructor/instructor_dashboard.py
@@ -0,0 +1,24 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'heatmap': True,
+ 'heatmap_message': _('This is based on the course schedules of this Instructor'),
+ 'fieldname': 'instructor',
+ 'non_standard_fieldnames': {
+ 'Assessment Plan': 'supervisor'
+ },
+ 'transactions': [
+ {
+ 'label': _('Course and Assessment'),
+ 'items': ['Course Schedule', 'Assessment Plan']
+ },
+ {
+ 'label': _('Students'),
+ 'items': ['Student Group']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/program/program_dashboard.py b/erpnext/education/doctype/program/program_dashboard.py
index cb8f742..c5d2494 100644
--- a/erpnext/education/doctype/program/program_dashboard.py
+++ b/erpnext/education/doctype/program/program_dashboard.py
@@ -10,11 +10,15 @@
},
{
'label': _('Student Activity'),
- 'items': ['Student Group' ]
+ 'items': ['Student Group', 'Student Log']
},
{
'label': _('Fee'),
- 'items': ['Fees','Fee Structure']
+ 'items': ['Fees','Fee Structure', 'Fee Schedule']
+ },
+ {
+ 'label': _('Assessment'),
+ 'items': ['Assessment Plan', 'Assessment Result']
}
]
}
\ No newline at end of file
diff --git a/erpnext/education/doctype/program_enrollment/program_enrollment_dashboard.py b/erpnext/education/doctype/program_enrollment/program_enrollment_dashboard.py
new file mode 100644
index 0000000..18d307c
--- /dev/null
+++ b/erpnext/education/doctype/program_enrollment/program_enrollment_dashboard.py
@@ -0,0 +1,19 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'program_enrollment',
+ 'transactions': [
+ {
+ 'label': _('Course and Fee'),
+ 'items': ['Course Enrollment', 'Fees']
+ }
+ ],
+ 'reports': [
+ {
+ 'label': _('Report'),
+ 'items': ['Student and Guardian Contact Details']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/quiz/quiz.js b/erpnext/education/doctype/quiz/quiz.js
index 7b87088..01bcf73 100644
--- a/erpnext/education/doctype/quiz/quiz.js
+++ b/erpnext/education/doctype/quiz/quiz.js
@@ -3,11 +3,17 @@
frappe.ui.form.on('Quiz', {
refresh: function(frm) {
-
+ if (!frm.doc.__islocal) {
+ frm.add_custom_button(__('Add to Topics'), function() {
+ frm.trigger('add_quiz_to_topics');
+ }, __('Action'));
+ }
},
+
validate: function(frm){
frm.events.check_duplicate_question(frm.doc.question);
},
+
check_duplicate_question: function(questions_data){
var questions = [];
questions_data.forEach(function(q){
@@ -15,7 +21,51 @@
});
var questions_set = new Set(questions);
if (questions.length != questions_set.size) {
- frappe.throw(__("The question cannot be duplicate"));
+ frappe.throw(__('The question cannot be duplicate'));
}
+ },
+
+ add_quiz_to_topics: function(frm) {
+ get_topics_without_quiz(frm.doc.name).then(r => {
+ if (r.message.length) {
+ frappe.prompt([
+ {
+ fieldname: 'topics',
+ label: __('Topics'),
+ fieldtype: 'MultiSelectPills',
+ get_data: function() {
+ return r.message;
+ }
+ }
+ ],
+ function(data) {
+ frappe.call({
+ method: 'erpnext.education.doctype.topic.topic.add_content_to_topics',
+ args: {
+ 'content_type': 'Quiz',
+ 'content': frm.doc.name,
+ 'topics': data.topics,
+ },
+ callback: function(r) {
+ if (!r.exc) {
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: __('...Adding Quiz to Topics')
+ });
+ }, __('Add Quiz to Topics'), __('Add'));
+ } else {
+ frappe.msgprint(__('This quiz is already added to the existing topics'));
+ }
+ });
}
-});
\ No newline at end of file
+});
+
+let get_topics_without_quiz = function(quiz) {
+ return frappe.call({
+ type: 'GET',
+ method: 'erpnext.education.doctype.quiz.quiz.get_topics_without_quiz',
+ args: {'quiz': quiz}
+ });
+};
\ No newline at end of file
diff --git a/erpnext/education/doctype/quiz/quiz.py b/erpnext/education/doctype/quiz/quiz.py
index ae1cb6c..a774b88 100644
--- a/erpnext/education/doctype/quiz/quiz.py
+++ b/erpnext/education/doctype/quiz/quiz.py
@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
+import json
from frappe import _
from frappe.model.document import Document
@@ -59,3 +60,12 @@
except TypeError:
frappe.throw(_("Compare List function takes on list arguments"))
+@frappe.whitelist()
+def get_topics_without_quiz(quiz):
+ data = []
+ for entry in frappe.db.get_all('Topic'):
+ topic = frappe.get_doc('Topic', entry.name)
+ topic_contents = [tc.content for tc in topic.topic_content]
+ if not topic_contents or quiz not in topic_contents:
+ data.append(topic.name)
+ return data
\ No newline at end of file
diff --git a/erpnext/education/doctype/room/room.js b/erpnext/education/doctype/room/room.js
index 032db98..20cee6b 100644
--- a/erpnext/education/doctype/room/room.js
+++ b/erpnext/education/doctype/room/room.js
@@ -1,10 +1,2 @@
-frappe.ui.form.on("Room", "refresh", function(frm) {
- if(!cur_frm.doc.__islocal) {
- frm.add_custom_button(__("Course Schedule"), function() {
- frappe.route_options = {
- room: frm.doc.name
- }
- frappe.set_route("List", "Course Schedule");
- });
- }
+frappe.ui.form.on("Room", {
});
\ No newline at end of file
diff --git a/erpnext/education/doctype/room/room_dashboard.py b/erpnext/education/doctype/room/room_dashboard.py
new file mode 100644
index 0000000..99aac33
--- /dev/null
+++ b/erpnext/education/doctype/room/room_dashboard.py
@@ -0,0 +1,19 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'room',
+ 'transactions': [
+ {
+ 'label': _('Course'),
+ 'items': ['Course Schedule']
+ },
+ {
+ 'label': _('Assessment'),
+ 'items': ['Assessment Plan']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/student_attendance/student_attendance_dashboard.py b/erpnext/education/doctype/student_attendance/student_attendance_dashboard.py
new file mode 100644
index 0000000..9c41b8f
--- /dev/null
+++ b/erpnext/education/doctype/student_attendance/student_attendance_dashboard.py
@@ -0,0 +1,12 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'reports': [
+ {
+ 'label': _('Reports'),
+ 'items': ['Student Monthly Attendance Sheet', 'Student Batch-Wise Attendance']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/student_category/student_category_dashboard.py b/erpnext/education/doctype/student_category/student_category_dashboard.py
new file mode 100644
index 0000000..f31c34b
--- /dev/null
+++ b/erpnext/education/doctype/student_category/student_category_dashboard.py
@@ -0,0 +1,13 @@
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'student_category',
+ 'transactions': [
+ {
+ 'label': _('Fee'),
+ 'items': ['Fee Structure', 'Fee Schedule', 'Fees']
+ }
+ ]
+ }
diff --git a/erpnext/education/doctype/student_group/student_group.js b/erpnext/education/doctype/student_group/student_group.js
index 1372440..51e3b74 100644
--- a/erpnext/education/doctype/student_group/student_group.js
+++ b/erpnext/education/doctype/student_group/student_group.js
@@ -1,18 +1,18 @@
-cur_frm.add_fetch("student", "title", "student_name");
+cur_frm.add_fetch('student', 'title', 'student_name');
-frappe.ui.form.on("Student Group", {
+frappe.ui.form.on('Student Group', {
onload: function(frm) {
- frm.set_query("academic_term", function() {
+ frm.set_query('academic_term', function() {
return {
- "filters": {
- "academic_year": (frm.doc.academic_year)
+ filters: {
+ 'academic_year': (frm.doc.academic_year)
}
};
});
if (!frm.__islocal) {
- frm.set_query("student", "students", function() {
+ frm.set_query('student', 'students', function() {
return{
- query: "erpnext.education.doctype.student_group.student_group.fetch_students",
+ query: 'erpnext.education.doctype.student_group.student_group.fetch_students',
filters: {
'academic_year': frm.doc.academic_year,
'group_based_on': frm.doc.group_based_on,
@@ -30,87 +30,86 @@
refresh: function(frm) {
if (!frm.doc.__islocal) {
- frm.add_custom_button(__("Attendance"), function() {
- frappe.route_options = {
- based_on: "Student Group",
- student_group: frm.doc.name
- }
- frappe.set_route("List", "Student Attendance Tool");
- });
- frm.add_custom_button(__("Course Schedule"), function() {
- frappe.route_options = {
- student_group: frm.doc.name
- }
- frappe.set_route("List", "Course Schedule");
- });
- frm.add_custom_button(__("Assessment Plan"), function() {
- frappe.route_options = {
- student_group: frm.doc.name
- }
- frappe.set_route("List", "Assessment Plan");
- });
- frm.add_custom_button(__("Update Email Group"), function() {
+
+ frm.add_custom_button(__('Add Guardians to Email Group'), function() {
frappe.call({
- method: "erpnext.education.api.update_email_group",
+ method: 'erpnext.education.api.update_email_group',
args: {
- "doctype": "Student Group",
- "name": frm.doc.name
+ 'doctype': 'Student Group',
+ 'name': frm.doc.name
}
});
- });
- frm.add_custom_button(__("Newsletter"), function() {
+ }, __('Actions'));
+
+ frm.add_custom_button(__('Student Attendance Tool'), function() {
frappe.route_options = {
- "Newsletter Email Group.email_group": frm.doc.name
+ based_on: 'Student Group',
+ student_group: frm.doc.name
}
- frappe.set_route("List", "Newsletter");
- });
+ frappe.set_route('Form', 'Student Attendance Tool', 'Student Attendance Tool');
+ }, __('Tools'));
+
+ frm.add_custom_button(__('Course Scheduling Tool'), function() {
+ frappe.route_options = {
+ student_group: frm.doc.name
+ }
+ frappe.set_route('Form', 'Course Scheduling Tool', 'Course Scheduling Tool');
+ }, __('Tools'));
+
+ frm.add_custom_button(__('Newsletter'), function() {
+ frappe.route_options = {
+ 'Newsletter Email Group.email_group': frm.doc.name
+ }
+ frappe.set_route('List', 'Newsletter');
+ }, __('View'));
+
}
},
-
+
group_based_on: function(frm) {
- if (frm.doc.group_based_on == "Batch") {
+ if (frm.doc.group_based_on == 'Batch') {
frm.doc.course = null;
frm.set_df_property('program', 'reqd', 1);
frm.set_df_property('course', 'reqd', 0);
}
- else if (frm.doc.group_based_on == "Course") {
+ else if (frm.doc.group_based_on == 'Course') {
frm.set_df_property('program', 'reqd', 0);
frm.set_df_property('course', 'reqd', 1);
}
- else if (frm.doc.group_based_on == "Activity") {
+ else if (frm.doc.group_based_on == 'Activity') {
frm.set_df_property('program', 'reqd', 0);
frm.set_df_property('course', 'reqd', 0);
}
},
get_students: function(frm) {
- if (frm.doc.group_based_on == "Batch" || frm.doc.group_based_on == "Course") {
+ if (frm.doc.group_based_on == 'Batch' || frm.doc.group_based_on == 'Course') {
var student_list = [];
var max_roll_no = 0;
- $.each(frm.doc.students, function(i,d) {
+ $.each(frm.doc.students, function(_i,d) {
student_list.push(d.student);
if (d.group_roll_number>max_roll_no) {
max_roll_no = d.group_roll_number;
}
});
- if(frm.doc.academic_year) {
+ if (frm.doc.academic_year) {
frappe.call({
- method: "erpnext.education.doctype.student_group.student_group.get_students",
+ method: 'erpnext.education.doctype.student_group.student_group.get_students',
args: {
- "academic_year": frm.doc.academic_year,
- "academic_term": frm.doc.academic_term,
- "group_based_on": frm.doc.group_based_on,
- "program": frm.doc.program,
- "batch" : frm.doc.batch,
- "student_category" : frm.doc.student_category,
- "course": frm.doc.course
+ 'academic_year': frm.doc.academic_year,
+ 'academic_term': frm.doc.academic_term,
+ 'group_based_on': frm.doc.group_based_on,
+ 'program': frm.doc.program,
+ 'batch' : frm.doc.batch,
+ 'student_category' : frm.doc.student_category,
+ 'course': frm.doc.course
},
callback: function(r) {
- if(r.message) {
+ if (r.message) {
$.each(r.message, function(i, d) {
if(!in_list(student_list, d.student)) {
- var s = frm.add_child("students");
+ var s = frm.add_child('students');
s.student = d.student;
s.student_name = d.student_name;
if (d.active === 0) {
@@ -119,16 +118,16 @@
s.group_roll_number = ++max_roll_no;
}
});
- refresh_field("students");
+ refresh_field('students');
frm.save();
} else {
- frappe.msgprint(__("Student Group is already updated."))
+ frappe.msgprint(__('Student Group is already updated.'))
}
}
})
}
} else {
- frappe.msgprint(__("Select students manually for the Activity based Group"));
+ frappe.msgprint(__('Select students manually for the Activity based Group'));
}
}
});
diff --git a/erpnext/education/doctype/student_group/student_group_dashboard.py b/erpnext/education/doctype/student_group/student_group_dashboard.py
new file mode 100644
index 0000000..ad7a6de
--- /dev/null
+++ b/erpnext/education/doctype/student_group/student_group_dashboard.py
@@ -0,0 +1,19 @@
+# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
+# License: GNU General Public License v3. See license.txt
+from __future__ import unicode_literals
+from frappe import _
+
+def get_data():
+ return {
+ 'fieldname': 'student_group',
+ 'transactions': [
+ {
+ 'label': _('Assessment'),
+ 'items': ['Assessment Plan', 'Assessment Result']
+ },
+ {
+ 'label': _('Course'),
+ 'items': ['Course Schedule']
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/erpnext/education/doctype/topic/topic.js b/erpnext/education/doctype/topic/topic.js
index 695c174..2002b0c 100644
--- a/erpnext/education/doctype/topic/topic.js
+++ b/erpnext/education/doctype/topic/topic.js
@@ -3,6 +3,53 @@
frappe.ui.form.on('Topic', {
refresh: function(frm) {
+ if (!cur_frm.doc.__islocal) {
+ frm.add_custom_button(__('Add to Courses'), function() {
+ frm.trigger('add_topic_to_courses');
+ }, __('Action'));
+ }
+ },
+ add_topic_to_courses: function(frm) {
+ get_courses_without_topic(frm.doc.name).then(r => {
+ if (r.message.length) {
+ frappe.prompt([
+ {
+ fieldname: 'courses',
+ label: __('Courses'),
+ fieldtype: 'MultiSelectPills',
+ get_data: function() {
+ return r.message;
+ }
+ }
+ ],
+ function(data) {
+ frappe.call({
+ method: 'erpnext.education.doctype.topic.topic.add_topic_to_courses',
+ args: {
+ 'topic': frm.doc.name,
+ 'courses': data.courses
+ },
+ callback: function(r) {
+ if (!r.exc) {
+ frm.reload_doc();
+ }
+ },
+ freeze: true,
+ freeze_message: __('...Adding Topic to Courses')
+ });
+ }, __('Add Topic to Courses'), __('Add'));
+ } else {
+ frappe.msgprint(__('This topic is already added to the existing courses'));
+ }
+ });
}
});
+
+let get_courses_without_topic = function(topic) {
+ return frappe.call({
+ type: 'GET',
+ method: 'erpnext.education.doctype.topic.topic.get_courses_without_topic',
+ args: {'topic': topic}
+ });
+};
\ No newline at end of file
diff --git a/erpnext/education/doctype/topic/topic.py b/erpnext/education/doctype/topic/topic.py
index 7e5da32..a5253e9 100644
--- a/erpnext/education/doctype/topic/topic.py
+++ b/erpnext/education/doctype/topic/topic.py
@@ -4,6 +4,8 @@
from __future__ import unicode_literals
import frappe
+import json
+from frappe import _
from frappe.model.document import Document
class Topic(Document):
@@ -14,4 +16,44 @@
except Exception as e:
frappe.log_error(frappe.get_traceback())
return None
- return content_data
\ No newline at end of file
+ return content_data
+
+@frappe.whitelist()
+def get_courses_without_topic(topic):
+ data = []
+ for entry in frappe.db.get_all('Course'):
+ course = frappe.get_doc('Course', entry.name)
+ topics = [t.topic for t in course.topics]
+ if not topics or topic not in topics:
+ data.append(course.name)
+ return data
+
+@frappe.whitelist()
+def add_topic_to_courses(topic, courses, mandatory=False):
+ courses = json.loads(courses)
+ for entry in courses:
+ course = frappe.get_doc('Course', entry)
+ course.append('topics', {
+ 'topic': topic,
+ 'topic_name': topic
+ })
+ course.flags.ignore_mandatory = True
+ course.save()
+ frappe.db.commit()
+ frappe.msgprint(_('Topic {0} has been added to all the selected courses successfully.').format(frappe.bold(topic)),
+ title=_('Courses updated'), indicator='green')
+
+@frappe.whitelist()
+def add_content_to_topics(content_type, content, topics):
+ topics = json.loads(topics)
+ for entry in topics:
+ topic = frappe.get_doc('Topic', entry)
+ topic.append('topic_content', {
+ 'content_type': content_type,
+ 'content': content,
+ })
+ topic.flags.ignore_mandatory = True
+ topic.save()
+ frappe.db.commit()
+ frappe.msgprint(_('{0} {1} has been added to all the selected topics successfully.').format(content_type, frappe.bold(content)),
+ title=_('Topics updated'), indicator='green')
\ No newline at end of file