refactored assessment result tool (#10633)

* save the assessment instead of submit

* Added comments in the artool

* remove the cur_frm and message for submitted result

* link field for the assessment result
diff --git a/erpnext/public/js/schools/assessment_result_tool.html b/erpnext/public/js/schools/assessment_result_tool.html
index 3c09ccd..9fc17f7 100644
--- a/erpnext/public/js/schools/assessment_result_tool.html
+++ b/erpnext/public/js/schools/assessment_result_tool.html
@@ -1,44 +1,72 @@
 <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 criteria %}
-            <th class="score" style="width: 100px">{{ c.assessment_criteria }}</th>
-            {% endfor %}
-            <th class="score" style="width: 100px">Total Marks</th>
-            <!--criteria-->
-        </tr>
-        <tr>
-            {% for c in criteria %}
-            <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 criteria %}
-            <td>
-                <input type="text"
-                    data-max-score="{{c.maximum_score}}"
-                    data-criteria="{{c.assessment_criteria}}"
-                    data-student="{{s.student}}"
-                    {% if(s.assessment_details) { %}
-                        disabled
-                        value="{{s.assessment_details[c.assessment_criteria]}}"
-                    {% } %}/>
-            </td>
-            {% endfor %}
-            <td data-student="{{s.student}}" class="total-score">
-                {% if(s.assessment_details) { %} {{s.assessment_details.total_score}} {% } %}
-            </td>
-        </tr>
-        {% endfor %}
-    </tbody>
+	<thead>
+		<tr>
+			<th style="width: 90px" rowspan="2">Student</th>
+			<th style="width: 170px" rowspan="2">Student Name</th>
+			{% for c in criteria %}
+			<th class="score" style="width: 100px">{{ c.assessment_criteria }}</th>
+			{% endfor %}
+			<th class="score" style="width: 170px" rowspan="2">Comments</th>
+			<th class="score" style="width: 100px">Total Marks</th>
+			<!--criteria-->
+		</tr>
+		<tr>
+			{% for c in criteria %}
+			<th class="score" style="width: 100px">Score ({{ c.maximum_score }})</th>
+			{% endfor %}
+			<th class="score" style="width: 100px">Score ({{max_total_score}})</th>
+		</tr>
+	</thead>
+	<tbody>
+		{% for s in students %}
+		<tr 
+			{% if(s.assessment_details && s.docstatus && s.docstatus == 1) { %} class="text-muted" {% } %}
+			data-student="{{s.student}}">
+
+			<td>{{ s.student }}</td>
+			<td>{{ s.student_name }}</td>
+			{% for c in criteria %}
+			<td>
+				<span data-student="{{s.student}}" data-criteria="{{c.assessment_criteria}}" class="student-result-grade badge" >
+					{% if(s.assessment_details) { %}
+						{{s.assessment_details[c.assessment_criteria][1]}} 
+					{% } %}
+				</span>
+				<input type="number" class="student-result-data" style="width:70%; float:right;"
+					data-max-score="{{c.maximum_score}}"
+					data-criteria="{{c.assessment_criteria}}"
+					data-student="{{s.student}}"
+					{% if(s.assessment_details && s.docstatus && s.docstatus == 1) { %} disabled {% } %}
+					{% if(s.assessment_details) { %}
+						value="{{s.assessment_details[c.assessment_criteria][0]}}"
+					{% } %}/>
+			</td>
+			{% endfor %}
+			<td>
+				<input type="text" class="result-comment" data-student="{{s.student}}"
+				{% if(s.assessment_details && s.docstatus && s.docstatus == 1) { %} disabled {% } %}
+				{% if(s.assessment_details) { %}
+					value="{{s.assessment_details.comment}}"
+				{% } %}
+			</td>
+			<td>
+				<span data-student="{{s.student}}" class="total-score-grade badge" style="width:30%; float:left;">
+				{% if(s.assessment_details) { %}
+				{{s.assessment_details.total_score[1]}}
+				{% } %}
+				</span>
+				<span data-student="{{s.student}}" class="total-score" style="width:60%; float:center;">
+				{% if(s.assessment_details) { %}
+				{{s.assessment_details.total_score[0]}}
+				{% } %}
+				</span>
+				<span data-student="{{s.student}}" class="total-result-link" style="width: 10%; display:{% if(!s.assessment_details) { %}None{% } %}; float:right;">
+					<a class="btn-open no-decoration" title="Open Link" href="#Form/Assessment Result/{% if(s.assessment_details) { %}{{s.name}}{% } %}">
+						<i class="octicon octicon-arrow-right"></i>
+					</a>
+				</span>
+			</td>
+		</tr>
+		{% endfor %}
+	</tbody>
 </table>
\ No newline at end of file
diff --git a/erpnext/schools/api.py b/erpnext/schools/api.py
index ff2da07..41d4a0d 100644
--- a/erpnext/schools/api.py
+++ b/erpnext/schools/api.py
@@ -18,6 +18,7 @@
 			(program), as_dict=1)
 	return courses
 
+
 @frappe.whitelist()
 def enroll_student(source_name):
 	"""Creates a Student Record and returns a Program Enrollment.
@@ -40,6 +41,7 @@
 	frappe.publish_realtime('enroll_student_progress', {"progress": [4, 4]}, user=frappe.session.user)	
 	return program_enrollment
 
+
 @frappe.whitelist()
 def check_attendance_records_exist(course_schedule=None, student_group=None, date=None):
 	"""Check if Attendance Records are made against the specified Course Schedule or Student Group for given date.
@@ -53,6 +55,7 @@
 	else:
 		return frappe.get_list("Student Attendance", filters={"student_group": student_group, "date": date})
 
+
 @frappe.whitelist()
 def mark_attendance(students_present, students_absent, course_schedule=None, student_group=None, date=None):
 	"""Creates Multiple Attendance Records.
@@ -76,6 +79,7 @@
 	frappe.db.commit()
 	frappe.msgprint(_("Attendance has been marked successfully."))
 
+
 def make_attendance_records(student, student_name, status, course_schedule=None, student_group=None, date=None):
 	"""Creates/Update Attendance Record.
 
@@ -103,6 +107,7 @@
 	student_attendance.status = status
 	student_attendance.save()
 
+
 @frappe.whitelist()
 def get_student_guardians(student):
 	"""Returns List of Guardians of a Student.
@@ -113,6 +118,7 @@
 		filters={"parent": student})
 	return guardians
 
+
 @frappe.whitelist()
 def get_student_group_students(student_group, include_inactive=0):
 	"""Returns List of student, student_name in Student Group.
@@ -127,6 +133,7 @@
 			filters={"parent": student_group, "active": 1}, order_by= "group_roll_number")
 	return students
 
+
 @frappe.whitelist()
 def get_fee_structure(program, academic_term=None):
 	"""Returns Fee Structure.
@@ -138,6 +145,7 @@
 		"academic_term": academic_term}, 'name', as_dict=True)
 	return fee_structure[0].name if fee_structure else None
 
+
 @frappe.whitelist()
 def get_fee_components(fee_structure):
 	"""Returns Fee Components.
@@ -148,6 +156,7 @@
 		fs = frappe.get_list("Fee Component", fields=["fees_category", "amount"] , filters={"parent": fee_structure}, order_by= "idx")
 		return fs
 
+
 @frappe.whitelist()
 def get_fee_schedule(program, student_category=None):
 	"""Returns Fee Schedule.
@@ -159,6 +168,7 @@
 		filters={"parent": program, "student_category": student_category }, order_by= "idx")
 	return fs
 
+
 @frappe.whitelist()
 def collect_fees(fees, amt):
 	paid_amount = flt(amt) + flt(frappe.db.get_value("Fees", fees, "paid_amount"))
@@ -167,6 +177,7 @@
 	frappe.db.set_value("Fees", fees, "outstanding_amount", (total_amount - paid_amount))
 	return paid_amount
 
+
 @frappe.whitelist()
 def get_course_schedule_events(start, end, filters=None):
 	"""Returns events for Course Schedule Calendar view rendering.
@@ -191,6 +202,7 @@
 
 	return data
 
+
 @frappe.whitelist()
 def get_assessment_criteria(course):
 	"""Returns Assessmemt Criteria and their Weightage from Course Master.
@@ -200,22 +212,30 @@
 	return frappe.get_list("Course Assessment Criteria", \
 		fields=["assessment_criteria", "weightage"], filters={"parent": course}, order_by= "idx")
 
+
 @frappe.whitelist()
 def get_assessment_students(assessment_plan, student_group):
-	
 	student_list = get_student_group_students(student_group)
 	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.assessment_criteria: cstr(d.score) + " ("+ d.grade + ")"})
-			student_result.update({"total_score": cstr(result.total_score) + " (" + result.grade + ")"})
-			student.update({'assessment_details': student_result})
+				student_result.update({d.assessment_criteria: [cstr(d.score), d.grade]})
+			student_result.update({
+				"total_score": [cstr(result.total_score), result.grade],
+				"comment": result.comment
+			})
+			student.update({
+				"assessment_details": student_result,
+				"docstatus": result.docstatus,
+				"name": result.name
+			})
 		else:
 			student.update({'assessment_details': None})
 	return student_list
 
+
 @frappe.whitelist()
 def get_assessment_details(assessment_plan):
 	"""Returns Assessment Criteria  and Maximum Score from Assessment Plan Master.
@@ -223,7 +243,8 @@
 	:param Assessment Plan: Assessment Plan
 	"""
 	return frappe.get_list("Assessment Plan Criteria", \
-		fields=["assessment_criteria", "maximum_score"], filters={"parent": assessment_plan}, order_by= "idx")
+		fields=["assessment_criteria", "maximum_score", "docstatus"], filters={"parent": assessment_plan}, order_by= "idx")
+
 
 @frappe.whitelist()
 def get_result(student, assessment_plan):
@@ -232,12 +253,14 @@
 	:param Student: Student
 	:param Assessment Plan: Assessment Plan
 	"""
-	results = frappe.get_all("Assessment Result", filters={"student": student, "assessment_plan": assessment_plan, "docstatus": 1})
+	results = frappe.get_all("Assessment Result", filters={"student": student,
+		"assessment_plan": assessment_plan, "docstatus": ("!=", 2)})
 	if results:
 		return frappe.get_doc("Assessment Result", results[0])
 	else:
 		return None
 
+
 @frappe.whitelist()
 def get_grade(grading_scale, percentage):
 	"""Returns Grade based on the Grading Scale and Score.
@@ -257,25 +280,63 @@
 			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({
-			"assessment_criteria": s,
-			"score": flt(student_score[s])
+def mark_assessment_result(assessment_plan, scores):
+	student_score = json.loads(scores);
+	assessment_details = []
+	for criteria in student_score.get("assessment_details"):
+		assessment_details.append({
+			"assessment_criteria": criteria,
+			"score": flt(student_score["assessment_details"][criteria])
 		})
-	assessment_result = frappe.new_doc("Assessment Result")
+	assessment_result = get_assessment_result_doc(student_score["student"], assessment_plan)
 	assessment_result.update({
-		"student": student,
-		"student_name": frappe.db.get_value("Student", student, "title"),
+		"student": student_score.get("student"),
 		"assessment_plan": assessment_plan,
-		"details": details
+		"comment": student_score.get("comment"),
+		"total_score":student_score.get("total_score"),
+		"details": assessment_details
 	})
 	assessment_result.save()
-	assessment_result.submit()	
-	return assessment_result
+	details = {}
+	for d in assessment_result.details:
+		details.update({d.assessment_criteria: d.grade})
+	assessment_result_dict = {
+		"name": assessment_result.name,
+		"student": assessment_result.student,
+		"total_score": assessment_result.total_score,
+		"grade": assessment_result.grade,
+		"details": details
+	}
+	return assessment_result_dict
+
+
+@frappe.whitelist()
+def submit_assessment_results(assessment_plan, student_group):
+	total_result = 0
+	student_list = get_student_group_students(student_group)
+	for i, student in enumerate(student_list):
+		doc = get_result(student.student, assessment_plan)
+		if doc and doc.docstatus==0:
+			total_result += 1
+			doc.submit()
+	return total_result
+
+
+def get_assessment_result_doc(student, assessment_plan):
+	assessment_result = frappe.get_all("Assessment Result", filters={"student": student,
+			"assessment_plan": assessment_plan, "docstatus": ("!=", 2)})
+	if assessment_result:
+		doc = frappe.get_doc("Assessment Result", assessment_result[0])
+		if doc.docstatus == 0:
+			return doc
+		elif doc.docstatus == 1:
+			frappe.msgprint("Result already Submitted")
+			return None
+	else:
+		return frappe.new_doc("Assessment Result")
+
 
 @frappe.whitelist()
 def update_email_group(doctype, name):
diff --git a/erpnext/schools/doctype/assessment_result/assessment_result.json b/erpnext/schools/doctype/assessment_result/assessment_result.json
index c6b3c44..13b927c 100644
--- a/erpnext/schools/doctype/assessment_result/assessment_result.json
+++ b/erpnext/schools/doctype/assessment_result/assessment_result.json
@@ -410,7 +410,7 @@
    "collapsible": 0, 
    "columns": 0, 
    "fieldname": "comment", 
-   "fieldtype": "Long Text", 
+   "fieldtype": "Small Text", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
@@ -474,7 +474,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-06-30 08:21:46.875594", 
+ "modified": "2017-08-31 15:39:24.813328", 
  "modified_by": "Administrator", 
  "module": "Schools", 
  "name": "Assessment Result", 
diff --git a/erpnext/schools/doctype/assessment_result/assessment_result.py b/erpnext/schools/doctype/assessment_result/assessment_result.py
index c878ec3..3c036dd 100644
--- a/erpnext/schools/doctype/assessment_result/assessment_result.py
+++ b/erpnext/schools/doctype/assessment_result/assessment_result.py
@@ -9,13 +9,18 @@
 from frappe.model.document import Document
 from erpnext.schools.api import get_grade
 from erpnext.schools.api import get_assessment_details
+from frappe.utils.csvutils import getlink
+
 
 class AssessmentResult(Document):
 	def validate(self):
+		if self.student and not self.student_name:
+			self.student_name = frappe.db.get_value("Student", self.student, "title")
 		self.grading_scale = frappe.db.get_value("Assessment Plan", self.assessment_plan, "grading_scale")
 		self.validate_maximum_score()
 		self.validate_grade()
-	
+		self.validate_duplicate()
+
 	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)
@@ -34,3 +39,13 @@
 			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)
+
+	def validate_duplicate(self):
+		assessment_result = frappe.get_list("Assessment Result", filters={"name": ("not in", [self.name]),
+			"student":self.student, "assessment_plan":self.assessment_plan, "docstatus":("!=", 2)})
+		if assessment_result:
+			frappe.throw(_("Assessment Result record {0} already exists.".format(getlink("Assessment Result",assessment_result[0].name))))
+
+
+
+
diff --git a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js
index a2eecef..dfa7b14 100644
--- a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js
+++ b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.js
@@ -1,12 +1,13 @@
-
 // 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");
 
 frappe.ui.form.on('Assessment Result Tool', {
+	setup: function(frm) {
+		frm.add_fetch("assessment_plan", "student_group", "student_group");
+	},
+
 	refresh: function(frm) {
-		frm.trigger("assessment_plan");
 		if (frappe.route_options) {
 			frm.set_value("student_group", frappe.route_options.student_group);
 			frm.set_value("assessment_plan", frappe.route_options.assessment_plan);
@@ -14,98 +15,145 @@
 		}
 		frm.disable_save();
 		frm.page.clear_indicator();
+		frm.trigger("assessment_plan");
 	},
 
 	assessment_plan: function(frm) {
-		if(!frm.doc.student_group) return;
-		frappe.call({
-			method: "erpnext.schools.api.get_assessment_students",
-			args: {
-				"assessment_plan": frm.doc.assessment_plan,
-				"student_group": frm.doc.student_group
-			},
-			callback: function(r) {
-				frm.events.render_table(frm, r.message);
-			}
-		});
+		frm.doc.show_submit = false;
+		if(frm.doc.assessment_plan) {
+			if (!frm.doc.student_group)
+				return
+			frappe.call({
+				method: "erpnext.schools.api.get_assessment_students",
+				args: {
+					"assessment_plan": frm.doc.assessment_plan,
+					"student_group": frm.doc.student_group
+				},
+				callback: function(r) {
+					frm.doc.students = r.message;
+					frm.events.render_table(frm);
+					for (let value of r.message) {
+						if (!value.docstatus) {
+							frm.doc.show_submit = true;
+							break;
+						}
+					}
+					frm.events.submit_result(frm);
+				}
+			});
+		}
 	},
 
-	render_table: function(frm, students) {
+	render_table: function(frm) {
 		$(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] = {}
-		});
-		
+		let assessment_plan = frm.doc.assessment_plan;
 		frappe.call({
 			method: "erpnext.schools.api.get_assessment_details",
 			args: {
 				assessment_plan: assessment_plan
 			},
 			callback: function(r) {
-				var criteria_list = r.message;
-				var max_total_score = 0;
-				criteria_list.forEach(function(c) {
-					max_total_score += c.maximum_score
-				});
-				var result_table = $(frappe.render_template('assessment_result_tool', {
-					frm: frm,
-					students: students,
-					criteria: criteria_list,
-					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 == criteria_list.length) {
-						console.log("ok");
-						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.assessment_criteria === criteria;
-									}).grade;
-									$input.val(`${value} (${grade})`);
-									$input.attr('disabled', true);
-								});
-
-							}
-						}))
-					}
-				});
-
+				frm.events.get_marks(frm, r.message);
 			}
 		});
 	},
 
+	get_marks: function(frm, criteria_list) {
+		let max_total_score = 0;
+		criteria_list.forEach(function(c) {
+			max_total_score += c.maximum_score
+		});
+		var result_table = $(frappe.render_template('assessment_result_tool', {
+			frm: frm,
+			students: frm.doc.students,
+			criteria: criteria_list,
+			max_total_score: max_total_score
+		}));
+		result_table.appendTo(frm.fields_dict.result_html.wrapper);
+
+		result_table.on('change', 'input', function(e) {
+			let $input = $(e.target);
+			let student = $input.data().student;
+			let max_score = $input.data().maxScore;
+			let value = $input.val();
+			if(value < 0) {
+				$input.val(0);
+			} else if(value > max_score) {
+				$input.val(max_score);
+			}
+			let total_score = 0;
+			let student_scores = {};
+			student_scores["assessment_details"] = {}
+			result_table.find(`input[data-student=${student}].student-result-data`)
+				.each(function(el, input) {
+					let $input = $(input);
+					let criteria = $input.data().criteria;
+					let value = parseFloat($input.val());
+					if (value) {
+						student_scores["assessment_details"][criteria] = value;
+					}
+					total_score += value;
+			});
+			if(!Number.isNaN(total_score)) {
+				result_table.find(`span[data-student=${student}].total-score`).html(total_score);
+			}
+			if (Object.keys(student_scores["assessment_details"]).length === criteria_list.length) {
+				student_scores["student"] = student;
+				student_scores["total_score"] = total_score;
+				result_table.find(`[data-student=${student}].result-comment`)
+					.each(function(el, input){
+					student_scores["comment"] = $(input).val();
+				});
+				frappe.call({
+					method: "erpnext.schools.api.mark_assessment_result",
+					args: {
+						"assessment_plan": frm.doc.assessment_plan,
+						"scores": student_scores
+					},
+					callback: function(r) {
+						let assessment_result = r.message;
+						if (!frm.doc.show_submit) {
+							frm.doc.show_submit = true;
+							frm.events.submit_result;
+						}
+						for (var criteria of Object.keys(assessment_result.details)) {
+							result_table.find(`[data-criteria=${criteria}][data-student=${assessment_result
+								.student}].student-result-grade`).each(function(e1, input) {
+									$(input).html(assessment_result.details[criteria]);
+							});
+						}
+						result_table.find(`span[data-student=${assessment_result.student}].total-score-grade`).html(assessment_result.grade);
+						let link_span = result_table.find(`span[data-student=${assessment_result.student}].total-result-link`);
+						$(link_span).css("display", "block");
+						$(link_span).find("a").attr("href", "#Form/Assessment Result/"+assessment_result.name);
+					}
+				});
+			}
+		});
+	},
+
+	submit_result: function(frm) {
+		if (frm.doc.show_submit) {
+			frm.page.set_primary_action(__("Submit"), function() {
+				frappe.call({
+					method: "erpnext.schools.api.submit_assessment_results",
+					args: {
+						"assessment_plan": frm.doc.assessment_plan,
+						"student_group": frm.doc.student_group
+					},
+					callback: function(r) {
+						if (r.message) {
+							frappe.msgprint(__("{0} Result submittted", [r.message]));
+						} else {
+							frappe.msgprint(__("No Result to submit"));
+						}
+						frm.events.assessment_plan(frm);
+					}
+				});
+			});
+		}
+		else {
+			frm.page.clear_primary_action();
+		}
+	}
 });
diff --git a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py
index a0d286c..649f420 100644
--- a/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py
+++ b/erpnext/schools/doctype/assessment_result_tool/assessment_result_tool.py
@@ -7,4 +7,4 @@
 from frappe.model.document import Document
 
 class AssessmentResultTool(Document):
-	pass
+	pass
\ No newline at end of file