mirror of
https://github.com/frappe/erpnext.git
synced 2026-06-02 19:59:12 +00:00
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
This commit is contained in:
committed by
Rushabh Mehta
parent
aebcb17daf
commit
a22c94c246
@@ -1,44 +1,72 @@
|
|||||||
<table class="table table-bordered assessment-result-tool">
|
<table class="table table-bordered assessment-result-tool">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 100px" rowspan="2">Student</th>
|
<th style="width: 90px" rowspan="2">Student</th>
|
||||||
<th style="width: 200px" rowspan="2">Student Name</th>
|
<th style="width: 170px" rowspan="2">Student Name</th>
|
||||||
{% for c in criteria %}
|
{% for c in criteria %}
|
||||||
<th class="score" style="width: 100px">{{ c.assessment_criteria }}</th>
|
<th class="score" style="width: 100px">{{ c.assessment_criteria }}</th>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<th class="score" style="width: 100px">Total Marks</th>
|
<th class="score" style="width: 170px" rowspan="2">Comments</th>
|
||||||
<!--criteria-->
|
<th class="score" style="width: 100px">Total Marks</th>
|
||||||
</tr>
|
<!--criteria-->
|
||||||
<tr>
|
</tr>
|
||||||
{% for c in criteria %}
|
<tr>
|
||||||
<th class="score" style="width: 100px">{{ c.maximum_score }}</th>
|
{% for c in criteria %}
|
||||||
{% endfor %}
|
<th class="score" style="width: 100px">Score ({{ c.maximum_score }})</th>
|
||||||
<th class="score" style="width: 100px">{{max_total_score}}</th>
|
{% endfor %}
|
||||||
</tr>
|
<th class="score" style="width: 100px">Score ({{max_total_score}})</th>
|
||||||
</thead>
|
</tr>
|
||||||
<tbody>
|
</thead>
|
||||||
{% for s in students %}
|
<tbody>
|
||||||
<tr
|
{% for s in students %}
|
||||||
{% if(s.assessment_details) { %} class="text-muted" {% } %}
|
<tr
|
||||||
data-student="{{s.student}}">
|
{% if(s.assessment_details && s.docstatus && s.docstatus == 1) { %} class="text-muted" {% } %}
|
||||||
<td>{{ s.student }}</td>
|
data-student="{{s.student}}">
|
||||||
<td>{{ s.student_name }}</td>
|
|
||||||
{% for c in criteria %}
|
<td>{{ s.student }}</td>
|
||||||
<td>
|
<td>{{ s.student_name }}</td>
|
||||||
<input type="text"
|
{% for c in criteria %}
|
||||||
data-max-score="{{c.maximum_score}}"
|
<td>
|
||||||
data-criteria="{{c.assessment_criteria}}"
|
<span data-student="{{s.student}}" data-criteria="{{c.assessment_criteria}}" class="student-result-grade badge" >
|
||||||
data-student="{{s.student}}"
|
{% if(s.assessment_details) { %}
|
||||||
{% if(s.assessment_details) { %}
|
{{s.assessment_details[c.assessment_criteria][1]}}
|
||||||
disabled
|
{% } %}
|
||||||
value="{{s.assessment_details[c.assessment_criteria]}}"
|
</span>
|
||||||
{% } %}/>
|
<input type="number" class="student-result-data" style="width:70%; float:right;"
|
||||||
</td>
|
data-max-score="{{c.maximum_score}}"
|
||||||
{% endfor %}
|
data-criteria="{{c.assessment_criteria}}"
|
||||||
<td data-student="{{s.student}}" class="total-score">
|
data-student="{{s.student}}"
|
||||||
{% if(s.assessment_details) { %} {{s.assessment_details.total_score}} {% } %}
|
{% if(s.assessment_details && s.docstatus && s.docstatus == 1) { %} disabled {% } %}
|
||||||
</td>
|
{% if(s.assessment_details) { %}
|
||||||
</tr>
|
value="{{s.assessment_details[c.assessment_criteria][0]}}"
|
||||||
{% endfor %}
|
{% } %}/>
|
||||||
</tbody>
|
</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>
|
</table>
|
||||||
@@ -18,6 +18,7 @@ def get_course(program):
|
|||||||
(program), as_dict=1)
|
(program), as_dict=1)
|
||||||
return courses
|
return courses
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def enroll_student(source_name):
|
def enroll_student(source_name):
|
||||||
"""Creates a Student Record and returns a Program Enrollment.
|
"""Creates a Student Record and returns a Program Enrollment.
|
||||||
@@ -40,6 +41,7 @@ def enroll_student(source_name):
|
|||||||
frappe.publish_realtime('enroll_student_progress', {"progress": [4, 4]}, user=frappe.session.user)
|
frappe.publish_realtime('enroll_student_progress', {"progress": [4, 4]}, user=frappe.session.user)
|
||||||
return program_enrollment
|
return program_enrollment
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def check_attendance_records_exist(course_schedule=None, student_group=None, date=None):
|
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.
|
"""Check if Attendance Records are made against the specified Course Schedule or Student Group for given date.
|
||||||
@@ -53,6 +55,7 @@ def check_attendance_records_exist(course_schedule=None, student_group=None, dat
|
|||||||
else:
|
else:
|
||||||
return frappe.get_list("Student Attendance", filters={"student_group": student_group, "date": date})
|
return frappe.get_list("Student Attendance", filters={"student_group": student_group, "date": date})
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def mark_attendance(students_present, students_absent, course_schedule=None, student_group=None, date=None):
|
def mark_attendance(students_present, students_absent, course_schedule=None, student_group=None, date=None):
|
||||||
"""Creates Multiple Attendance Records.
|
"""Creates Multiple Attendance Records.
|
||||||
@@ -76,6 +79,7 @@ def mark_attendance(students_present, students_absent, course_schedule=None, stu
|
|||||||
frappe.db.commit()
|
frappe.db.commit()
|
||||||
frappe.msgprint(_("Attendance has been marked successfully."))
|
frappe.msgprint(_("Attendance has been marked successfully."))
|
||||||
|
|
||||||
|
|
||||||
def make_attendance_records(student, student_name, status, course_schedule=None, student_group=None, date=None):
|
def make_attendance_records(student, student_name, status, course_schedule=None, student_group=None, date=None):
|
||||||
"""Creates/Update Attendance Record.
|
"""Creates/Update Attendance Record.
|
||||||
|
|
||||||
@@ -103,6 +107,7 @@ def make_attendance_records(student, student_name, status, course_schedule=None,
|
|||||||
student_attendance.status = status
|
student_attendance.status = status
|
||||||
student_attendance.save()
|
student_attendance.save()
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_student_guardians(student):
|
def get_student_guardians(student):
|
||||||
"""Returns List of Guardians of a Student.
|
"""Returns List of Guardians of a Student.
|
||||||
@@ -113,6 +118,7 @@ def get_student_guardians(student):
|
|||||||
filters={"parent": student})
|
filters={"parent": student})
|
||||||
return guardians
|
return guardians
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_student_group_students(student_group, include_inactive=0):
|
def get_student_group_students(student_group, include_inactive=0):
|
||||||
"""Returns List of student, student_name in Student Group.
|
"""Returns List of student, student_name in Student Group.
|
||||||
@@ -127,6 +133,7 @@ def get_student_group_students(student_group, include_inactive=0):
|
|||||||
filters={"parent": student_group, "active": 1}, order_by= "group_roll_number")
|
filters={"parent": student_group, "active": 1}, order_by= "group_roll_number")
|
||||||
return students
|
return students
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_fee_structure(program, academic_term=None):
|
def get_fee_structure(program, academic_term=None):
|
||||||
"""Returns Fee Structure.
|
"""Returns Fee Structure.
|
||||||
@@ -138,6 +145,7 @@ def get_fee_structure(program, academic_term=None):
|
|||||||
"academic_term": academic_term}, 'name', as_dict=True)
|
"academic_term": academic_term}, 'name', as_dict=True)
|
||||||
return fee_structure[0].name if fee_structure else None
|
return fee_structure[0].name if fee_structure else None
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_fee_components(fee_structure):
|
def get_fee_components(fee_structure):
|
||||||
"""Returns Fee Components.
|
"""Returns Fee Components.
|
||||||
@@ -148,6 +156,7 @@ def get_fee_components(fee_structure):
|
|||||||
fs = frappe.get_list("Fee Component", fields=["fees_category", "amount"] , filters={"parent": fee_structure}, order_by= "idx")
|
fs = frappe.get_list("Fee Component", fields=["fees_category", "amount"] , filters={"parent": fee_structure}, order_by= "idx")
|
||||||
return fs
|
return fs
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_fee_schedule(program, student_category=None):
|
def get_fee_schedule(program, student_category=None):
|
||||||
"""Returns Fee Schedule.
|
"""Returns Fee Schedule.
|
||||||
@@ -159,6 +168,7 @@ def get_fee_schedule(program, student_category=None):
|
|||||||
filters={"parent": program, "student_category": student_category }, order_by= "idx")
|
filters={"parent": program, "student_category": student_category }, order_by= "idx")
|
||||||
return fs
|
return fs
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def collect_fees(fees, amt):
|
def collect_fees(fees, amt):
|
||||||
paid_amount = flt(amt) + flt(frappe.db.get_value("Fees", fees, "paid_amount"))
|
paid_amount = flt(amt) + flt(frappe.db.get_value("Fees", fees, "paid_amount"))
|
||||||
@@ -167,6 +177,7 @@ def collect_fees(fees, amt):
|
|||||||
frappe.db.set_value("Fees", fees, "outstanding_amount", (total_amount - paid_amount))
|
frappe.db.set_value("Fees", fees, "outstanding_amount", (total_amount - paid_amount))
|
||||||
return paid_amount
|
return paid_amount
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_course_schedule_events(start, end, filters=None):
|
def get_course_schedule_events(start, end, filters=None):
|
||||||
"""Returns events for Course Schedule Calendar view rendering.
|
"""Returns events for Course Schedule Calendar view rendering.
|
||||||
@@ -191,6 +202,7 @@ def get_course_schedule_events(start, end, filters=None):
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_assessment_criteria(course):
|
def get_assessment_criteria(course):
|
||||||
"""Returns Assessmemt Criteria and their Weightage from Course Master.
|
"""Returns Assessmemt Criteria and their Weightage from Course Master.
|
||||||
@@ -200,22 +212,30 @@ def get_assessment_criteria(course):
|
|||||||
return frappe.get_list("Course Assessment Criteria", \
|
return frappe.get_list("Course Assessment Criteria", \
|
||||||
fields=["assessment_criteria", "weightage"], filters={"parent": course}, order_by= "idx")
|
fields=["assessment_criteria", "weightage"], filters={"parent": course}, order_by= "idx")
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_assessment_students(assessment_plan, student_group):
|
def get_assessment_students(assessment_plan, student_group):
|
||||||
|
|
||||||
student_list = get_student_group_students(student_group)
|
student_list = get_student_group_students(student_group)
|
||||||
for i, student in enumerate(student_list):
|
for i, student in enumerate(student_list):
|
||||||
result = get_result(student.student, assessment_plan)
|
result = get_result(student.student, assessment_plan)
|
||||||
if result:
|
if result:
|
||||||
student_result = {}
|
student_result = {}
|
||||||
for d in result.details:
|
for d in result.details:
|
||||||
student_result.update({d.assessment_criteria: cstr(d.score) + " ("+ d.grade + ")"})
|
student_result.update({d.assessment_criteria: [cstr(d.score), d.grade]})
|
||||||
student_result.update({"total_score": cstr(result.total_score) + " (" + result.grade + ")"})
|
student_result.update({
|
||||||
student.update({'assessment_details': student_result})
|
"total_score": [cstr(result.total_score), result.grade],
|
||||||
|
"comment": result.comment
|
||||||
|
})
|
||||||
|
student.update({
|
||||||
|
"assessment_details": student_result,
|
||||||
|
"docstatus": result.docstatus,
|
||||||
|
"name": result.name
|
||||||
|
})
|
||||||
else:
|
else:
|
||||||
student.update({'assessment_details': None})
|
student.update({'assessment_details': None})
|
||||||
return student_list
|
return student_list
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_assessment_details(assessment_plan):
|
def get_assessment_details(assessment_plan):
|
||||||
"""Returns Assessment Criteria and Maximum Score from Assessment Plan Master.
|
"""Returns Assessment Criteria and Maximum Score from Assessment Plan Master.
|
||||||
@@ -223,7 +243,8 @@ def get_assessment_details(assessment_plan):
|
|||||||
:param Assessment Plan: Assessment Plan
|
:param Assessment Plan: Assessment Plan
|
||||||
"""
|
"""
|
||||||
return frappe.get_list("Assessment Plan Criteria", \
|
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()
|
@frappe.whitelist()
|
||||||
def get_result(student, assessment_plan):
|
def get_result(student, assessment_plan):
|
||||||
@@ -232,12 +253,14 @@ def get_result(student, assessment_plan):
|
|||||||
:param Student: Student
|
:param Student: Student
|
||||||
:param Assessment Plan: Assessment Plan
|
: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:
|
if results:
|
||||||
return frappe.get_doc("Assessment Result", results[0])
|
return frappe.get_doc("Assessment Result", results[0])
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_grade(grading_scale, percentage):
|
def get_grade(grading_scale, percentage):
|
||||||
"""Returns Grade based on the Grading Scale and Score.
|
"""Returns Grade based on the Grading Scale and Score.
|
||||||
@@ -257,25 +280,63 @@ def get_grade(grading_scale, percentage):
|
|||||||
grade = ""
|
grade = ""
|
||||||
return grade
|
return grade
|
||||||
|
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def mark_assessment_result(student, assessment_plan, scores):
|
def mark_assessment_result(assessment_plan, scores):
|
||||||
student_score = json.loads(scores)
|
student_score = json.loads(scores);
|
||||||
details = []
|
assessment_details = []
|
||||||
for s in student_score.keys():
|
for criteria in student_score.get("assessment_details"):
|
||||||
details.append({
|
assessment_details.append({
|
||||||
"assessment_criteria": s,
|
"assessment_criteria": criteria,
|
||||||
"score": flt(student_score[s])
|
"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({
|
assessment_result.update({
|
||||||
"student": student,
|
"student": student_score.get("student"),
|
||||||
"student_name": frappe.db.get_value("Student", student, "title"),
|
|
||||||
"assessment_plan": assessment_plan,
|
"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.save()
|
||||||
assessment_result.submit()
|
details = {}
|
||||||
return assessment_result
|
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()
|
@frappe.whitelist()
|
||||||
def update_email_group(doctype, name):
|
def update_email_group(doctype, name):
|
||||||
|
|||||||
@@ -410,7 +410,7 @@
|
|||||||
"collapsible": 0,
|
"collapsible": 0,
|
||||||
"columns": 0,
|
"columns": 0,
|
||||||
"fieldname": "comment",
|
"fieldname": "comment",
|
||||||
"fieldtype": "Long Text",
|
"fieldtype": "Small Text",
|
||||||
"hidden": 0,
|
"hidden": 0,
|
||||||
"ignore_user_permissions": 0,
|
"ignore_user_permissions": 0,
|
||||||
"ignore_xss_filter": 0,
|
"ignore_xss_filter": 0,
|
||||||
@@ -474,7 +474,7 @@
|
|||||||
"issingle": 0,
|
"issingle": 0,
|
||||||
"istable": 0,
|
"istable": 0,
|
||||||
"max_attachments": 0,
|
"max_attachments": 0,
|
||||||
"modified": "2017-06-30 08:21:46.875594",
|
"modified": "2017-08-31 15:39:24.813328",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Schools",
|
"module": "Schools",
|
||||||
"name": "Assessment Result",
|
"name": "Assessment Result",
|
||||||
|
|||||||
@@ -9,13 +9,18 @@ from frappe.utils import flt
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
from erpnext.schools.api import get_grade
|
from erpnext.schools.api import get_grade
|
||||||
from erpnext.schools.api import get_assessment_details
|
from erpnext.schools.api import get_assessment_details
|
||||||
|
from frappe.utils.csvutils import getlink
|
||||||
|
|
||||||
|
|
||||||
class AssessmentResult(Document):
|
class AssessmentResult(Document):
|
||||||
def validate(self):
|
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.grading_scale = frappe.db.get_value("Assessment Plan", self.assessment_plan, "grading_scale")
|
||||||
self.validate_maximum_score()
|
self.validate_maximum_score()
|
||||||
self.validate_grade()
|
self.validate_grade()
|
||||||
|
self.validate_duplicate()
|
||||||
|
|
||||||
def validate_maximum_score(self):
|
def validate_maximum_score(self):
|
||||||
self.maximum_score = frappe.db.get_value("Assessment Plan", self.assessment_plan, "maximum_assessment_score")
|
self.maximum_score = frappe.db.get_value("Assessment Plan", self.assessment_plan, "maximum_assessment_score")
|
||||||
assessment_details = get_assessment_details(self.assessment_plan)
|
assessment_details = get_assessment_details(self.assessment_plan)
|
||||||
@@ -34,3 +39,13 @@ class AssessmentResult(Document):
|
|||||||
d.grade = get_grade(self.grading_scale, (flt(d.score)/d.maximum_score)*100)
|
d.grade = get_grade(self.grading_scale, (flt(d.score)/d.maximum_score)*100)
|
||||||
self.total_score += d.score
|
self.total_score += d.score
|
||||||
self.grade = get_grade(self.grading_scale, (self.total_score/self.maximum_score)*100)
|
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))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
|
|
||||||
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
|
||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
cur_frm.add_fetch("assessment_plan", "student_group", "student_group");
|
|
||||||
|
|
||||||
frappe.ui.form.on('Assessment Result Tool', {
|
frappe.ui.form.on('Assessment Result Tool', {
|
||||||
|
setup: function(frm) {
|
||||||
|
frm.add_fetch("assessment_plan", "student_group", "student_group");
|
||||||
|
},
|
||||||
|
|
||||||
refresh: function(frm) {
|
refresh: function(frm) {
|
||||||
frm.trigger("assessment_plan");
|
|
||||||
if (frappe.route_options) {
|
if (frappe.route_options) {
|
||||||
frm.set_value("student_group", frappe.route_options.student_group);
|
frm.set_value("student_group", frappe.route_options.student_group);
|
||||||
frm.set_value("assessment_plan", frappe.route_options.assessment_plan);
|
frm.set_value("assessment_plan", frappe.route_options.assessment_plan);
|
||||||
@@ -14,98 +15,145 @@ frappe.ui.form.on('Assessment Result Tool', {
|
|||||||
}
|
}
|
||||||
frm.disable_save();
|
frm.disable_save();
|
||||||
frm.page.clear_indicator();
|
frm.page.clear_indicator();
|
||||||
|
frm.trigger("assessment_plan");
|
||||||
},
|
},
|
||||||
|
|
||||||
assessment_plan: function(frm) {
|
assessment_plan: function(frm) {
|
||||||
if(!frm.doc.student_group) return;
|
frm.doc.show_submit = false;
|
||||||
frappe.call({
|
if(frm.doc.assessment_plan) {
|
||||||
method: "erpnext.schools.api.get_assessment_students",
|
if (!frm.doc.student_group)
|
||||||
args: {
|
return
|
||||||
"assessment_plan": frm.doc.assessment_plan,
|
frappe.call({
|
||||||
"student_group": frm.doc.student_group
|
method: "erpnext.schools.api.get_assessment_students",
|
||||||
},
|
args: {
|
||||||
callback: function(r) {
|
"assessment_plan": frm.doc.assessment_plan,
|
||||||
frm.events.render_table(frm, r.message);
|
"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();
|
$(frm.fields_dict.result_html.wrapper).empty();
|
||||||
var assessment_plan = frm.doc.assessment_plan;
|
let assessment_plan = frm.doc.assessment_plan;
|
||||||
var student_scores = {};
|
|
||||||
students.forEach(function(stu) {
|
|
||||||
student_scores[stu.student] = {}
|
|
||||||
});
|
|
||||||
|
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.schools.api.get_assessment_details",
|
method: "erpnext.schools.api.get_assessment_details",
|
||||||
args: {
|
args: {
|
||||||
assessment_plan: assessment_plan
|
assessment_plan: assessment_plan
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
var criteria_list = r.message;
|
frm.events.get_marks(frm, 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);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ import frappe
|
|||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class AssessmentResultTool(Document):
|
class AssessmentResultTool(Document):
|
||||||
pass
|
pass
|
||||||
Reference in New Issue
Block a user