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
This commit is contained in:
parent
2826fd3c20
commit
5142fc9365
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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", {
|
||||
});
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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}
|
||||
});
|
||||
};
|
@ -7,9 +7,15 @@ import frappe
|
||||
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
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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 @@ frappe.ui.form.on("Assessment Plan", {
|
||||
|
||||
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 @@ frappe.ui.form.on("Assessment Plan", {
|
||||
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 @@ frappe.ui.form.on("Assessment Plan", {
|
||||
},
|
||||
|
||||
maximum_assessment_score: function(frm) {
|
||||
frm.trigger("course");
|
||||
frm.trigger('course');
|
||||
}
|
||||
});
|
@ -6,12 +6,16 @@ from frappe import _
|
||||
def get_data():
|
||||
return {
|
||||
'fieldname': 'assessment_plan',
|
||||
'non_standard_fieldnames': {
|
||||
},
|
||||
'transactions': [
|
||||
{
|
||||
'label': _('Assessment'),
|
||||
'items': ['Assessment Result']
|
||||
}
|
||||
],
|
||||
'reports': [
|
||||
{
|
||||
'label': _('Report'),
|
||||
'items': ['Assessment Plan Status']
|
||||
}
|
||||
]
|
||||
}
|
@ -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 @@ frappe.ui.form.on("Assessment Result", {
|
||||
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 @@ frappe.ui.form.on("Assessment Result", {
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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 @@ frappe.ui.form.on('Course Topic', {
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
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}
|
||||
});
|
||||
}
|
@ -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 @@ class Course(Document):
|
||||
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
|
||||
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
|
@ -6,12 +6,10 @@ from frappe import _
|
||||
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 @@ def get_data():
|
||||
},
|
||||
{
|
||||
'label': _('Assessment'),
|
||||
'items': ['Assessment Plan']
|
||||
'items': ['Assessment Plan', 'Assessment Result']
|
||||
},
|
||||
]
|
||||
}
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -4,13 +4,13 @@ cur_frm.add_fetch("student_group", "course", "course")
|
||||
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");
|
||||
}
|
||||
}
|
||||
});
|
File diff suppressed because it is too large
Load Diff
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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 @@ frappe.ui.form.on('Fee Schedule', {
|
||||
}
|
||||
};
|
||||
});
|
||||
frm.set_query("income_account", function(doc) {
|
||||
|
||||
frm.set_query('income_account', function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
'account_type': 'Income Account',
|
||||
@ -27,57 +28,59 @@ frappe.ui.form.on('Fee Schedule', {
|
||||
}
|
||||
};
|
||||
});
|
||||
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 @@ frappe.ui.form.on('Fee Schedule', {
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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 @@ frappe.ui.form.on('Fee Structure', {
|
||||
}
|
||||
};
|
||||
});
|
||||
frm.set_query("income_account", function(doc) {
|
||||
frm.set_query('income_account', function(doc) {
|
||||
return {
|
||||
filters: {
|
||||
'account_type': 'Income Account',
|
||||
@ -38,27 +38,27 @@ frappe.ui.form.on('Fee Structure', {
|
||||
},
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -3,8 +3,8 @@ cur_frm.add_fetch("employee", "image", "image");
|
||||
|
||||
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 @@ frappe.ui.form.on("Instructor", {
|
||||
});
|
||||
},
|
||||
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) {
|
||||
|
@ -30,4 +30,14 @@ class Instructor(Document):
|
||||
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))
|
||||
|
24
erpnext/education/doctype/instructor/instructor_dashboard.py
Normal file
24
erpnext/education/doctype/instructor/instructor_dashboard.py
Normal file
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -10,11 +10,15 @@ def get_data():
|
||||
},
|
||||
{
|
||||
'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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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 @@ frappe.ui.form.on('Quiz', {
|
||||
});
|
||||
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'));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
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}
|
||||
});
|
||||
};
|
@ -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 @@ def compare_list_elementwise(*args):
|
||||
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
|
@ -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", {
|
||||
});
|
19
erpnext/education/doctype/room/room_dashboard.py
Normal file
19
erpnext/education/doctype/room/room_dashboard.py
Normal file
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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 @@ frappe.ui.form.on("Student Group", {
|
||||
|
||||
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 @@ frappe.ui.form.on("Student Group", {
|
||||
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'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -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']
|
||||
}
|
||||
]
|
||||
}
|
@ -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}
|
||||
});
|
||||
};
|
@ -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 @@ class Topic(Document):
|
||||
except Exception as e:
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
return None
|
||||
return content_data
|
||||
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')
|
Loading…
x
Reference in New Issue
Block a user