Added assessment result tool
diff --git a/erpnext/config/desktop.py b/erpnext/config/desktop.py
index 38a5846..029ef74 100644
--- a/erpnext/config/desktop.py
+++ b/erpnext/config/desktop.py
@@ -229,15 +229,6 @@
"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",
"icon": "fa fa-money",
diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py
index cac6cfa..903f54b 100644
--- a/erpnext/config/schools.py
+++ b/erpnext/config/schools.py
@@ -129,6 +129,10 @@
{
"type": "doctype",
"name": "Evaluation Criteria"
+ },
+ {
+ "type": "doctype",
+ "name": "Assessment Result Tool"
}
]
},
diff --git a/erpnext/public/build.json b/erpnext/public/build.json
index 30b0900..c405681 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 ca3b4b5..7f85de9 100644
--- a/erpnext/public/css/erpnext.css
+++ b/erpnext/public/css/erpnext.css
@@ -212,3 +212,25 @@
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 0000000..6f9e256
--- /dev/null
+++ b/erpnext/public/js/schools/assessment_result_tool.html
@@ -0,0 +1,44 @@
+<table class="table table-bordered assessment-result-tool">
+ <thead>
+ <tr>
+ <th style="width: 100px" rowspan="2">Student</th>
+ <th style="width: 200px" rowspan="2">Student Name</th>
+ {% for c in criterias %}
+ <th class="score" style="width: 100px">{{ c.evaluation_criteria }}</th>
+ {% endfor %}
+ <th class="score" style="width: 100px">Total Marks</th>
+ <!--criteria-->
+ </tr>
+ <tr>
+ {% for c in criterias %}
+ <th class="score" style="width: 100px">{{ c.maximum_score }}</th>
+ {% endfor %}
+ <th class="score" style="width: 100px">{{max_total_score}}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for s in students %}
+ <tr
+ {% if(s.assessment_details) { %} class="text-muted" {% } %}
+ data-student="{{s.student}}">
+ <td>{{ s.student }}</td>
+ <td>{{ s.student_name }}</td>
+ {% for c in criterias %}
+ <td>
+ <input type="text"
+ data-max-score="{{c.maximum_score}}"
+ data-criteria="{{c.evaluation_criteria}}"
+ data-student="{{s.student}}"
+ {% if(s.assessment_details) { %}
+ disabled
+ value="{{s.assessment_details[c.evaluation_criteria]}}"
+ {% } %}/>
+ </td>
+ {% endfor %}
+ <td data-student="{{s.student}}" class="total-score">
+ {% if(s.assessment_details) { %} {{s.assessment_details.total_score}} {% } %}
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
\ No newline at end of file
diff --git a/erpnext/public/less/erpnext.less b/erpnext/public/less/erpnext.less
index e2ccddd..790a031 100644
--- a/erpnext/public/less/erpnext.less
+++ b/erpnext/public/less/erpnext.less
@@ -257,3 +257,28 @@
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 e48748e..e31a944 100644
--- a/erpnext/schools/api.py
+++ b/erpnext/schools/api.py
@@ -7,7 +7,7 @@
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 @@
@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 @@
"""
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 @@
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 @@
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 7b746ff..374b444 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 10ae53c..967c689 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,
@@ -102,92 +102,6 @@
"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,
- "collapsible": 0,
- "columns": 0,
"fieldname": "column_break_2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -244,35 +158,6 @@
"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,
- "collapsible": 0,
- "columns": 0,
"fieldname": "maximum_assessment_score",
"fieldtype": "Float",
"hidden": 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,
@@ -475,6 +415,63 @@
"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,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "column_break_4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -558,6 +555,63 @@
"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,
+ "collapsible": 0,
+ "columns": 0,
"fieldname": "section_break_20",
"fieldtype": "Section Break",
"hidden": 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 4c472fc..aa84ae3 100644
--- a/erpnext/schools/doctype/assessment_plan/assessment_plan.py
+++ b/erpnext/schools/doctype/assessment_plan/assessment_plan.py
@@ -9,8 +9,12 @@
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 @@
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 d39f3ca..860dcbd 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 0000000..e69de29
--- /dev/null
+++ b/erpnext/schools/doctype/assessment_result_tool/__init__.py
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 0000000..c58304b
--- /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 0000000..87dff4d
--- /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 0000000..a0d286c
--- /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 8e66f1a..f7f6ba9 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 fbe7d99..72b6954 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
}
]
}