diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py index 38a584626c4..029ef747407 100644 --- a/erpnext/config/desktop.py +++ b/erpnext/config/desktop.py @@ -228,15 +228,6 @@ def get_data(): "_doctype": "Student Applicant", "type": "list" }, - { - "module_name": "Assessment Plan", - "color": "#8a70be", - "icon": "fa fa-file-text-alt", - "label": _("Assessment Plan"), - "link": "List/Assessment Plan", - "_doctype": "Assessment Plan", - "type": "list" - }, { "module_name": "Fees", "color": "#83C21E", diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py index cac6cfa27ea..903f54b4117 100644 --- a/erpnext/config/schools.py +++ b/erpnext/config/schools.py @@ -129,6 +129,10 @@ def get_data(): { "type": "doctype", "name": "Evaluation Criteria" + }, + { + "type": "doctype", + "name": "Assessment Result Tool" } ] }, diff --git a/erpnext/public/build.json b/erpnext/public/build.json index 30b09000fd3..c4056813b68 100644 --- a/erpnext/public/build.json +++ b/erpnext/public/build.json @@ -28,7 +28,8 @@ "public/js/templates/item_selector.html", "public/js/utils/item_selector.js", "public/js/help_links.js", - "public/js/schools/student_button.html" + "public/js/schools/student_button.html", + "public/js/schools/assessment_result_tool.html" ], "js/item-dashboard.min.js": [ "stock/dashboard/item_dashboard.html", diff --git a/erpnext/public/css/erpnext.css b/erpnext/public/css/erpnext.css index ca3b4b5965b..7f85de9315b 100644 --- a/erpnext/public/css/erpnext.css +++ b/erpnext/public/css/erpnext.css @@ -212,3 +212,25 @@ body[data-route="pos"] .modal-dialog { margin: 15px; width: 130px; } +.frappe-control[data-fieldname='result_html'] { + overflow: scroll; +} +.assessment-result-tool { + table-layout: fixed; +} +.assessment-result-tool input { + width: 100%; + border: 0; + outline: none; + text-align: right; +} +.assessment-result-tool th { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.assessment-result-tool .total-score, +.assessment-result-tool .grade, +.assessment-result-tool .score { + text-align: right; +} diff --git a/erpnext/public/js/schools/assessment_result_tool.html b/erpnext/public/js/schools/assessment_result_tool.html new file mode 100644 index 00000000000..6f9e2566c25 --- /dev/null +++ b/erpnext/public/js/schools/assessment_result_tool.html @@ -0,0 +1,44 @@ + + + + + + {% for c in criterias %} + + {% endfor %} + + + + + {% for c in criterias %} + + {% endfor %} + + + + + {% for s in students %} + + + + {% for c in criterias %} + + {% endfor %} + + + {% endfor %} + +
StudentStudent Name{{ c.evaluation_criteria }}Total Marks
{{ c.maximum_score }}{{max_total_score}}
{{ s.student }}{{ s.student_name }} + + + {% if(s.assessment_details) { %} {{s.assessment_details.total_score}} {% } %} +
\ No newline at end of file diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less index e2ccdddf0e7..790a031736d 100644 --- a/erpnext/public/less/erpnext.less +++ b/erpnext/public/less/erpnext.less @@ -257,3 +257,28 @@ body[data-route="pos"] .modal-dialog { margin: 15px; width: 130px; } + +// assessment tool +.frappe-control[data-fieldname='result_html'] { + overflow: scroll; +} +.assessment-result-tool { + table-layout: fixed; + + input { + width: 100%; + border: 0; + outline: none; + text-align: right; + } + + th { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .total-score, .grade, .score { + text-align: right; + } +} \ No newline at end of file diff --git a/erpnext/schools/api.py b/erpnext/schools/api.py index e48748e621b..e31a9444ca2 100644 --- a/erpnext/schools/api.py +++ b/erpnext/schools/api.py @@ -7,7 +7,7 @@ import frappe import json from frappe import _ from frappe.model.mapper import get_mapped_doc -from frappe.utils import flt +from frappe.utils import flt, cstr @frappe.whitelist() def enroll_student(source_name): @@ -84,7 +84,7 @@ def make_attendance_records(student, student_name, status, course_schedule=None, @frappe.whitelist() def get_student_batch_students(student_batch): - """Returns List of student, student_name in Student Batch. + """Returns List of student, student_name, idx in Student Batch. :param student_batch: Student Batch. """ @@ -172,7 +172,26 @@ def get_evaluation_criterias(course): """ return frappe.get_list("Course Evaluation Criteria", \ fields=["evaluation_criteria", "weightage"], filters={"parent": course}, order_by= "idx") - + +@frappe.whitelist() +def get_assessment_students(assessment_plan, student_group=None, student_batch=None): + student_list = [] + if student_group: + student_list = get_student_group_students(student_group) + elif student_batch: + student_list = get_student_batch_students(student_batch) + for i, student in enumerate(student_list): + result = get_result(student.student, assessment_plan) + if result: + student_result = {} + for d in result.details: + student_result.update({d.evaluation_criteria: cstr(d.score) + " ("+ d.grade + ")"}) + student_result.update({"total_score": cstr(result.total_score) + " (" + result.grade + ")"}) + student.update({'assessment_details': student_result}) + else: + student.update({'assessment_details': None}) + return student_list + @frappe.whitelist() def get_assessment_details(assessment_plan): """Returns Evaluation Criteria and Maximum Score from Assessment Plan Master. @@ -182,6 +201,18 @@ def get_assessment_details(assessment_plan): return frappe.get_list("Assessment Evaluation Criteria", \ fields=["evaluation_criteria", "maximum_score"], filters={"parent": assessment_plan}, order_by= "idx") +@frappe.whitelist() +def get_result(student, assessment_plan): + """Returns Submitted Result of given student for specified Assessment Plan + + :param Student: Student + :param Assessment Plan: Assessment Plan + """ + results = frappe.get_all("Assessment Result", filters={"student": student, "assessment_plan": assessment_plan, "docstatus": 1}) + if results: + return frappe.get_doc("Assessment Result", results[0]) + else: + return None @frappe.whitelist() def get_grade(grading_scale, percentage): @@ -199,5 +230,25 @@ def get_grade(grading_scale, percentage): grade = grading_scale_intervals.get(interval) break else: - grade = "Unsuccessful" - return grade \ No newline at end of file + grade = "" + return grade + +@frappe.whitelist() +def mark_assessment_result(student, assessment_plan, scores): + student_score = json.loads(scores) + details = [] + for s in student_score.keys(): + details.append({ + "evaluation_criteria": s, + "score": flt(student_score[s]) + }) + assessment_result = frappe.new_doc("Assessment Result") + assessment_result.update({ + "student": student, + "student_name": frappe.db.get_value("Student", student, "title"), + "assessment_plan": assessment_plan, + "details": details + }) + assessment_result.save() + assessment_result.submit() + return assessment_result \ No newline at end of file diff --git a/erpnext/schools/doctype/assessment_plan/assessment_plan.js b/erpnext/schools/doctype/assessment_plan/assessment_plan.js index 7b746ffb77f..374b444a969 100644 --- a/erpnext/schools/doctype/assessment_plan/assessment_plan.js +++ b/erpnext/schools/doctype/assessment_plan/assessment_plan.js @@ -2,6 +2,7 @@ // For license information, please see license.txt cur_frm.add_fetch("student_group", "course", "course"); +cur_frm.add_fetch("student_group", "student_batch", "student_batch"); cur_frm.add_fetch("examiner", "instructor_name", "examiner_name"); cur_frm.add_fetch("supervisor", "instructor_name", "supervisor_name"); diff --git a/erpnext/schools/doctype/assessment_plan/assessment_plan.json b/erpnext/schools/doctype/assessment_plan/assessment_plan.json index 10ae53c7bb7..967c689f0de 100644 --- a/erpnext/schools/doctype/assessment_plan/assessment_plan.json +++ b/erpnext/schools/doctype/assessment_plan/assessment_plan.json @@ -73,18 +73,18 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "student_group", + "fieldname": "assessment_group", "fieldtype": "Link", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, - "in_list_view": 1, + "in_list_view": 0, "in_standard_filter": 1, - "label": "Student Group", + "label": "Assessment Group", "length": 0, "no_copy": 0, - "options": "Student Group", + "options": "Assessment Group", "permlevel": 0, "precision": "", "print_hide": 0, @@ -97,92 +97,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "student_batch", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Student Batch", - "length": 0, - "no_copy": 0, - "options": "Student Batch", - "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, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "examiner", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Examiner", - "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": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "examiner_name", - "fieldtype": "Data", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Examiner Name", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 1, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, { "allow_on_submit": 0, "bold": 0, @@ -239,35 +153,6 @@ "set_only_once": 0, "unique": 0 }, - { - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "assessment_group", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_list_view": 0, - "in_standard_filter": 1, - "label": "Assessment Group", - "length": 0, - "no_copy": 0, - "options": "Assessment 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": 0, - "search_index": 0, - "set_only_once": 0, - "unique": 0 - }, { "allow_on_submit": 0, "bold": 0, @@ -320,7 +205,7 @@ "read_only": 0, "remember_last_selected_value": 0, "report_hide": 0, - "reqd": 0, + "reqd": 1, "search_index": 0, "set_only_once": 0, "unique": 0 @@ -330,18 +215,16 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "supervisor", - "fieldtype": "Link", + "fieldname": "section_break_10", + "fieldtype": "Section Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Supervisor", "length": 0, "no_copy": 0, - "options": "Instructor", "permlevel": 0, "precision": "", "print_hide": 0, @@ -359,22 +242,79 @@ "bold": 0, "collapsible": 0, "columns": 0, - "fieldname": "supervisor_name", - "fieldtype": "Data", + "fieldname": "student_group", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 1, + "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": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "column_break_10", + "fieldtype": "Column Break", "hidden": 0, "ignore_user_permissions": 0, "ignore_xss_filter": 0, "in_filter": 0, "in_list_view": 0, "in_standard_filter": 0, - "label": "Supervisor Name", "length": 0, "no_copy": 0, "permlevel": 0, "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 1, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "student_batch", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Student Batch", + "length": 0, + "no_copy": 0, + "options": "Student Batch", + "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, @@ -470,6 +410,63 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "examiner", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Examiner", + "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": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "examiner_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Examiner Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -553,6 +550,63 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "supervisor", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Supervisor", + "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": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "supervisor_name", + "fieldtype": "Data", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Supervisor Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_on_submit": 0, "bold": 0, @@ -649,7 +703,7 @@ "istable": 0, "max_attachments": 0, "menu_index": 0, - "modified": "2017-01-04 16:21:40.752137", + "modified": "2017-01-05 12:15:33.183100", "modified_by": "Administrator", "module": "Schools", "name": "Assessment Plan", diff --git a/erpnext/schools/doctype/assessment_plan/assessment_plan.py b/erpnext/schools/doctype/assessment_plan/assessment_plan.py index 4c472fc87a1..aa84ae342db 100644 --- a/erpnext/schools/doctype/assessment_plan/assessment_plan.py +++ b/erpnext/schools/doctype/assessment_plan/assessment_plan.py @@ -9,8 +9,12 @@ from frappe import _ class AssessmentPlan(Document): def validate(self): + if not (self.student_batch or self.student_group): + frappe.throw(_("Please select Student Group or Student Batch")) + self.validate_student_batch() self.validate_overlap() + def validate_overlap(self): """Validates overlap for Student Group/Student Batch, Instructor, Room""" @@ -35,3 +39,7 @@ class AssessmentPlan(Document): validate_overlap_for(self, "Assessment Plan", "room") validate_overlap_for(self, "Assessment Plan", "supervisor", self.supervisor) + + def validate_student_batch(self): + if self.student_group: + self.student_batch = frappe.db.get_value("Student Group", self.student_group, "student_batch") \ No newline at end of file diff --git a/erpnext/schools/doctype/assessment_result/assessment_result.py b/erpnext/schools/doctype/assessment_result/assessment_result.py index d39f3ca67ed..860dcbd8ae7 100644 --- a/erpnext/schools/doctype/assessment_result/assessment_result.py +++ b/erpnext/schools/doctype/assessment_result/assessment_result.py @@ -4,21 +4,33 @@ from __future__ import unicode_literals import frappe +from frappe import _ from frappe.utils import flt from frappe.model.document import Document from erpnext.schools.api import get_grade +from erpnext.schools.api import get_assessment_details class AssessmentResult(Document): def validate(self): - self.maximum_score = frappe.db.get_value("Assessment Plan", self.assessment_plan, "maximum_assessment_score") + self.grading_scale = frappe.db.get_value("Assessment Plan", self.assessment_plan, "grading_scale") + self.validate_maximum_score() self.validate_grade() + def validate_maximum_score(self): + self.maximum_score = frappe.db.get_value("Assessment Plan", self.assessment_plan, "maximum_assessment_score") + assessment_details = get_assessment_details(self.assessment_plan) + max_scores = {} + for d in assessment_details: + max_scores.update({d.evaluation_criteria: d.maximum_score}) + + for d in self.details: + d.maximum_score = max_scores.get(d.evaluation_criteria) + if d.score > d.maximum_score: + frappe.throw(_("Score cannot be greater than Maximum Score")) + def validate_grade(self): self.total_score = 0.0 for d in self.details: - if d.score > d.maximum_score: - frappe.throw(_("Score cannot be greater than Maximum Score")) - else: - d.grade = get_grade(self.grading_scale, (flt(d.score)/d.maximum_score)*100) - self.total_score += d.score + d.grade = get_grade(self.grading_scale, (flt(d.score)/d.maximum_score)*100) + self.total_score += d.score self.grade = get_grade(self.grading_scale, (self.total_score/self.maximum_score)*100) diff --git a/erpnext/schools/doctype/assessment_result_tool/__init__.py b/erpnext/schools/doctype/assessment_result_tool/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js new file mode 100644 index 00000000000..c58304beca4 --- /dev/null +++ b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js @@ -0,0 +1,105 @@ +// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors +// For license information, please see license.txt + +cur_frm.add_fetch("assessment_plan", "student_group", "student_group"); +cur_frm.add_fetch("assessment_plan", "student_batch", "student_batch"); + +frappe.ui.form.on('Assessment Result Tool', { + refresh: function(frm) { + frm.disable_save(); + frm.page.clear_indicator(); + }, + + assessment_plan: function(frm) { + if(!(frm.doc.student_batch || frm.doc.student_group)) return; + frappe.call({ + method: "erpnext.schools.api.get_assessment_students", + args: { + "assessment_plan": frm.doc.assessment_plan, + "student_batch": frm.doc.student_batch, + "student_group": frm.doc.student_group + }, + callback: function(r) { + frm.events.render_table(frm, r.message); + } + }); + }, + + render_table: function(frm, students) { + $(frm.fields_dict.result_html.wrapper).empty(); + var assessment_plan = frm.doc.assessment_plan; + var student_scores = {}; + students.forEach(function(stu) { + student_scores[stu.student] = {} + }); + + frappe.call({ + method: "erpnext.schools.api.get_assessment_details", + args: { + assessment_plan: assessment_plan + }, + callback: function(r) { + var criterias = r.message; + var max_total_score = 0; + criterias.forEach(function(c) { + max_total_score += c.maximum_score + }); + var result_table = $(frappe.render_template('assessment_result_tool', { + frm: frm, + students: students, + criterias: criterias, + max_total_score: max_total_score + })); + result_table.appendTo(frm.fields_dict.result_html.wrapper) + + result_table.on('change', 'input', function(e) { + var $input = $(e.target); + var max_score = $input.data().maxScore; + var student = $input.data().student; + var criteria = $input.data().criteria; + var value = $input.val(); + if(value < 0) { + $input.val(0); + value = 0; + } + if(value > max_score) { + $input.val(max_score); + value = max_score; + } + student_scores[student][criteria] = value; + if(Object.keys(student_scores[student]).length == criterias.length) { + frappe.call(({ + method: "erpnext.schools.api.mark_assessment_result", + args: { + "student": student, + "assessment_plan": assessment_plan, + "scores": student_scores[student] + }, + callback: function(r) { + var doc = r.message; + var student = doc.student; + result_table.find(`[data-student=${student}].total-score`) + .html(doc.total_score + ' ('+ doc.grade + ')'); + var details = doc.details; + result_table.find(`tr[data-student=${student}]`).addClass('text-muted'); + result_table.find(`input[data-student=${student}]`).each(function(el, input) { + var $input = $(input); + var criteria = $input.data().criteria; + var value = $input.val(); + var grade = details.find(function(d) { + return d.evaluation_criteria === criteria; + }).grade; + $input.val(`${value} (${grade})`); + $input.attr('disabled', true); + }); + + } + })) + } + }); + + } + }); + }, + +}); diff --git a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.json b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.json new file mode 100644 index 00000000000..87dff4d1545 --- /dev/null +++ b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.json @@ -0,0 +1,232 @@ +{ + "allow_copy": 1, + "allow_import": 0, + "allow_rename": 0, + "beta": 0, + "creation": "2017-01-05 12:27:48.951036", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", + "fields": [ + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "", + "fieldname": "assessment_plan", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Assessment Plan", + "length": 0, + "no_copy": 0, + "options": "Assessment Plan", + "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, + "unique": 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_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, + "unique": 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_list_view": 0, + "in_standard_filter": 0, + "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": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "student_batch", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Student Batch", + "length": 0, + "no_copy": 0, + "options": "Student Batch", + "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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "assessment_plan", + "fieldname": "section_break_5", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 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, + "unique": 0 + }, + { + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "result_html", + "fieldtype": "HTML", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Result HTML", + "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, + "unique": 0 + } + ], + "hide_heading": 1, + "hide_toolbar": 1, + "idx": 0, + "image_view": 0, + "in_create": 0, + "in_dialog": 0, + "is_submittable": 0, + "issingle": 1, + "istable": 0, + "max_attachments": 0, + "modified": "2017-01-05 15:45:59.338722", + "modified_by": "Administrator", + "module": "Schools", + "name": "Assessment Result Tool", + "name_case": "", + "owner": "Administrator", + "permissions": [ + { + "amend": 0, + "apply_user_permissions": 0, + "cancel": 0, + "create": 1, + "delete": 0, + "email": 1, + "export": 0, + "if_owner": 0, + "import": 0, + "is_custom": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 0, + "role": "Academics User", + "set_user_permissions": 0, + "share": 1, + "submit": 0, + "write": 1 + } + ], + "quick_entry": 1, + "read_only": 0, + "read_only_onload": 0, + "sort_field": "modified", + "sort_order": "DESC", + "track_changes": 0, + "track_seen": 0 +} \ No newline at end of file diff --git a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py new file mode 100644 index 00000000000..a0d286ccbe9 --- /dev/null +++ b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors +# For license information, please see license.txt + +from __future__ import unicode_literals +import frappe +from frappe.model.document import Document + +class AssessmentResultTool(Document): + pass diff --git a/erpnext/schools/doctype/grading_scale/grading_scale.py b/erpnext/schools/doctype/grading_scale/grading_scale.py index 8e66f1a2d44..f7f6ba9d921 100644 --- a/erpnext/schools/doctype/grading_scale/grading_scale.py +++ b/erpnext/schools/doctype/grading_scale/grading_scale.py @@ -4,7 +4,16 @@ from __future__ import unicode_literals import frappe +from frappe import _ from frappe.model.document import Document class GradingScale(Document): - pass + def validate(self): + thresholds = [] + for d in self.intervals: + if d.threshold in thresholds: + frappe.throw(_("Treshold {0}% appears more than once.".format(d.threshold))) + else: + thresholds.append(d.threshold) + if 0 not in thresholds: + frappe.throw(_("Please define grade for treshold 0%")) \ No newline at end of file diff --git a/erpnext/schools/doctype/grading_scale/test_records.json b/erpnext/schools/doctype/grading_scale/test_records.json index fbe7d990aab..72b69547ac6 100644 --- a/erpnext/schools/doctype/grading_scale/test_records.json +++ b/erpnext/schools/doctype/grading_scale/test_records.json @@ -9,6 +9,10 @@ { "grade_code": "B", "threshold": 50 + }, + { + "grade_code": "C", + "threshold": 0 } ] }