Student Report Card (#13346)

* finalise the assessment report

* minor fixes for button

* fix the travis and codacy
This commit is contained in:
Manas Solanki 2018-03-21 17:50:42 +05:30 committed by Nabin Hait
parent 969c8aaf52
commit e010ddf65f
6 changed files with 660 additions and 218 deletions

View File

@ -135,6 +135,10 @@ def get_data():
"name": "Assessment Plan Status",
"doctype": "Assessment Plan"
},
{
"type": "doctype",
"name": "Student Report Generation Tool"
}
]
},
{

View File

@ -22,14 +22,16 @@ class Student(Document):
def update_student_name_in_linked_doctype(self):
linked_doctypes = get_linked_doctypes("Student")
for d in linked_doctypes:
if "student_name" in [f.fieldname for f in frappe.get_meta(d).fields]:
frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
.format(d, linked_doctypes[d]["fieldname"]),(self.title, self.name))
meta = frappe.get_meta(d)
if not meta.issingle:
if "student_name" in [f.fieldname for f in meta.fields]:
frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
.format(d, linked_doctypes[d]["fieldname"]),(self.title, self.name))
if "child_doctype" in linked_doctypes[d].keys() and "student_name" in \
[f.fieldname for f in frappe.get_meta(linked_doctypes[d]["child_doctype"]).fields]:
frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
.format(linked_doctypes[d]["child_doctype"], linked_doctypes[d]["fieldname"]),(self.title, self.name))
if "child_doctype" in linked_doctypes[d].keys() and "student_name" in \
[f.fieldname for f in frappe.get_meta(linked_doctypes[d]["child_doctype"]).fields]:
frappe.db.sql("""UPDATE `tab{0}` set student_name = %s where {1} = %s"""
.format(linked_doctypes[d]["child_doctype"], linked_doctypes[d]["fieldname"]),(self.title, self.name))
def check_unique(self):
"""Validates if the Student Applicant is Unique"""

View File

@ -1,82 +1,371 @@
<style>
.whole-report {
font-size: 9pt;
font-family: 'Helvetica Neue', Helvetica, Arial, 'Open Sans', 'sans-serif';
-webkit-print-color-adjust: exact;
@media screen {
.print-format-gutter {
background-color: #ddd;
padding: 15px 0px;
}
.print-format {
background-color: white;
box-shadow: 0px 0px 9px rgba(0,0,0,0.5);
max-width: 8.3in;
min-height: 11.69in;
padding: 0.75in;
margin: auto;
}
.print-format.landscape {
max-width: 11.69in;
padding: 0.2in;
}
.page-break {
padding: 30px 0px;
border-bottom: 1px dashed #888;
}
.page-break:first-child {
padding-top: 0px;
}
.page-break:last-child {
border-bottom: 0px;
}
/* mozilla hack for images in table */
body:last-child .print-format td img {
width: 100% !important;
}
@media(max-width: 767px) {
.print-format {
padding: 0.2in;
}
}
}
h2 {
text-align: center;
@media print {
.print-format p {
margin-left: 1px;
margin-right: 1px;
}
}
span {
padding-bottom: 5px;
.data-field {
margin-top: 5px;
margin-bottom: 5px;
}
thead {
background-color: #eee !important;
.data-field .value {
word-wrap: break-word;
}
.important .value {
font-size: 120%;
font-weight: bold;
}
td {
.important label {
line-height: 1.8;
margin: 0px;
}
.table {
margin: 20px 0px;
}
.square-image {
width: 100%;
height: 0;
padding: 50% 0;
background-size: contain;
/*background-size: cover;*/
background-repeat: no-repeat !important;
background-position: center center;
border-radius: 4px;
}
.print-item-image {
object-fit: contain;
}
.pdf-variables,
.pdf-variable,
.visible-pdf {
display: none !important;
}
.print-format {
font-size: 9pt;
font-family: "Helvetica Neue", Helvetica, Arial, "Open Sans", sans-serif;
-webkit-print-color-adjust:exact;
}
.page-break {
page-break-after: always;
}
.print-heading {
border-bottom: 1px solid #aaa;
margin-bottom: 10px;
}
.print-heading h2 {
margin: 0px;
}
.print-heading h4 {
margin-top: 5px;
}
table.no-border, table.no-border td {
border: 0px;
}
.print-format label {
/* wkhtmltopdf breaks label into multiple lines when it is inline-block */
display: block;
}
.print-format img {
max-width: 100%;
}
.print-format table td > .primary:first-child {
font-weight: bold;
}
.print-format td, .print-format th {
vertical-align: top !important;
padding: 6px !important;
text-align: left;
}
.print-format p {
margin: 3px 0px 3px;
}
table td div {
/* needed to avoid partial cutting of text between page break in wkhtmltopdf */
page-break-inside: avoid !important;
}
/* hack for webkit specific browser */
@media (-webkit-min-device-pixel-ratio:0) {
thead, tfoot { display: table-row-group; }
}
[document-status] {
margin-bottom: 5mm;
}
.signature-img {
background: #fff;
border-radius: 3px;
margin-top: 5px;
max-height: 150px;
}
.print-heading {
text-align: right;
text-transform: uppercase;
color: #666;
padding-bottom: 20px;
margin-bottom: 20px;
border-bottom: 1px solid #d1d8dd;
}
.print-heading h2 {
font-size: 24px;
}
.print-format th {
background-color: #eee !important;
border-bottom: 0px !important;
}
/* modern format: for-test */
.doc-field {
margin-bottom: 5px;
.pbi_avoid {
page-break-inside: avoid !important;
}
.pb_before {
page-break-before: always !important;
}
</style>
<div class="whole-report">
<h2>{{ _("Student Report Card") }}</h2>
<hr>
<span class="doc-field"> {{ _("Student: ") }} <b> {{ frappe.db.get_value("Student", doc.students[0], "title") }} </b> </span> <br>
<span class="doc-field"> {{ _("Program: ") }} <b> {{ doc.program }} </b> </span> <br>
<span class="doc-field"> {{ _("Assessment Group: ") }} <b> {{ doc.assessment_group }} </b> </span>
<hr>
<div class="page-break">
<div id="header-html" class="hidden-pdf">
{% if letterhead and add_letterhead %}
<div class="">{{ letterhead }}</div>
{% endif %}
<div class="print-heading">
<h2>{{ _("Student Report Card") }}<br>
<small>{{ doc.student_name }}</small>
</h2>
</div>
</div>
<div class="row section-break">
<div class="col-xs-6 column-break">
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Student ID: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.students[0] }}
</div>
</div>
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Student Name: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.student_name }}
</div>
</div>
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Program: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.program }}
</div>
</div>
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Batch: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.student_batch }}
</div>
</div>
</div>
<div class="col-xs-6 column-break">
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Academic Year: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.academic_year }}
</div>
</div>
{% if doc.academic_term %}
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Academic Term: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.academic_term }}
</div>
</div>
{% endif %}
<div class="row data-field">
<div class="col-xs-5">
<label>{{ _("Assessment Group: ") }}</label>
</div>
<div class="col-xs-7">
{{ doc.assessment_group }}
</div>
</div>
</div>
</div>
{% if doc.show_marks | int %}
{% set result_data = 'score' %}
{% else %}
{% set result_data = 'grade' %}
{% endif %}
{% for course in courses %}
<br>
<div class="doc-field">
Course: <b>{{ course }} ({{ frappe.db.get_value("Course", course, "course_name") }}) </b>
<div class="row section-break pbi_avoid">
<div class="col-xs-12 column-break">
<div>
<table class="table table-bordered table-condensed">
<caption>
<div class="row">
<div class="col-xs-1">
<label>{{ _("Course: ") }}</label>
</div>
<div class="col-xs-11">
{{ course }} ({{ frappe.db.get_value("Course", course, "course_name") }})
</div>
</div>
</caption>
<thead>
<tr>
<th style="width: {{ 650//(assessment_groups|length + 1) }}px">{{ _("Assessment Criteria") }}</th>
{% for assessment_group in assessment_groups %}
<th> {{ assessment_group }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for criteria in course_criteria[course] %}
<tr>
<td>{{ criteria }}</td>
{% for assessment_group in assessment_groups %}
{% if (assessment_result.get(course) and assessment_result.get(course).get(assessment_group) and assessment_result.get(course).get(assessment_group).get(criteria)) %}
<td>
{{ assessment_result.get(course).get(assessment_group).get(criteria).get(result_data) }}
{% if result_data == 'score' %}
({{ assessment_result.get(course).get(assessment_group).get(criteria).get('maximum_score') }})
{% endif %}
</td>
{% else %}
<td></td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<table class="table table-bordered table-condensed">
<thead>
<tr>
<td>Assessment Criteria</td>
{% for assessment_group in assessment_groups %}
<td> {{ assessment_group }}</td>
{% endfor %}
</tr>
</thead>
<tbody>
{% for criteria in course_criteria[course] %}
<tr>
<td>{{ criteria }}</td>
{% for assessment_group in assessment_groups %}
{% if (assessment_result.get(course) and assessment_result.get(course).get(assessment_group) and assessment_result.get(course).get(assessment_group).get(criteria)) %}
<td> {{ assessment_result.get(course).get(assessment_group).get(criteria).get("grade") }} </td>
{% else %}
<td></td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endfor %}
<hr>
<h4>{{ _("Attendance")}}</h4> <br>
<div>
Present {{ doc.present_days }} out of {{ doc.max_days }}
<br>
<div class="row section-break pbi_avoid">
<div class="col-xs-6 column-break">
<h4>{{ _("Student Attendance")}}</h4> <br>
<div>
Present {{ doc.attendance.get("Present") if doc.attendance.get("Present") != None else '0' }} days
out of {{ doc.attendance.get("Present") + doc.attendance.get("Absent") }}
</div>
</div>
<div class="col-xs-6 column-break">
<h4>{{ _("Parents Teacher Meeting Attendance")}}</h4> <br>
<div>
Present {{ doc.parents_attendance if doc.parents_attendance != None else '0' }}
out of {{ doc.parents_meeting if doc.parents_meeting != None else '0' }}
</div>
</div>
</div>
<hr>
<h4>{{ _("Parents Meeting Attendance")}}</h4> <br>
<div>
Present {{ doc.parents_attendance }} out of {{ doc.parents_meeting }}
{% if doc.assessment_terms %}
<div class="row section-break pb_before">
<div class="col-xs-12">
<p> {{ doc.assessment_terms }} </p>
</div>
</div>
{% endif %}
</div>
</div>

View File

@ -22,11 +22,45 @@ frappe.ui.form.on('Student Report Generation Tool', {
refresh: function(frm) {
frm.disable_save();
frm.page.clear_indicator();
frm.fields_dict.preview_report_card.$input.addClass("btn-primary");
frm.page.set_primary_action(__('Print Report Card'), () => {
let url = "/api/method/erpnext.education.doctype.student_report_generation_tool.student_report_generation_tool.preview_report_card";
open_url_post(url, frm.doc, true);
});
},
preview_report_card: function(frm) {
let url = "/api/method/erpnext.education.doctype.student_report_generation_tool.student_report_generation_tool.preview_report_card";
open_url_post(url, frm.doc);
student: function(frm) {
if (frm.doc.student) {
frappe.call({
method:"erpnext.education.api.get_current_enrollment",
args: {
"student": frm.doc.student,
"academic_year": frm.doc.academic_year
},
callback: function(r) {
if(r){
$.each(r.message, function(i, d) {
if (frm.fields_dict.hasOwnProperty(i)) {
frm.set_value(i, d);
}
});
}
}
});
}
},
terms: function(frm) {
if(frm.doc.terms) {
return frappe.call({
method: 'erpnext.setup.doctype.terms_and_conditions.terms_and_conditions.get_terms_and_conditions',
args: {
template_name: frm.doc.terms,
doc: frm.doc
},
callback: function(r) {
frm.set_value("assessment_terms", r.message);
}
});
}
}
});

View File

@ -18,19 +18,19 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_year",
"fieldname": "student",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Academic Year",
"label": "Student",
"length": 0,
"no_copy": 0,
"options": "Academic Year",
"options": "Student",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -49,8 +49,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_term",
"fieldtype": "Link",
"fieldname": "student_name",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -58,10 +58,9 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Academic Term",
"label": "Student Name",
"length": 0,
"no_copy": 0,
"options": "Academic Term",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -80,7 +79,38 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student",
"fieldname": "program",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Program",
"length": 0,
"no_copy": 0,
"options": "Program",
"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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student_batch",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@ -89,10 +119,101 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Student",
"label": "Batch",
"length": 0,
"no_copy": 0,
"options": "Student Batch Name",
"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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "include_all_assessment",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Include All Assessment Group",
"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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "show_marks",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Show Marks",
"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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "1",
"fieldname": "add_letterhead",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Add letterhead",
"length": 0,
"no_copy": 0,
"options": "Student",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -171,7 +292,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "program",
"fieldname": "academic_year",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
@ -180,10 +301,73 @@
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Program",
"label": "Academic Year",
"length": 0,
"no_copy": 0,
"options": "Program",
"options": "Academic Year",
"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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_term",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Academic Term",
"length": 0,
"no_copy": 0,
"options": "Academic Term",
"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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"depends_on": "add_letterhead",
"fieldname": "letter_head",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Letter Head",
"length": 0,
"no_copy": 0,
"options": "Letter Head",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -211,96 +395,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Attendance Print Section",
"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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "max_days",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Institution Open (Days)",
"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_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "present_days",
"fieldtype": "Data",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Student Present (Days)",
"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_bulk_edit": 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_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Print Section",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -330,7 +425,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Total Parent's Meeting",
"label": "Total Parents Teacher Meeting",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -360,7 +455,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Parent Present",
"label": "Attended by Parents",
"length": 0,
"no_copy": 0,
"options": "",
@ -382,8 +477,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_9",
"fieldtype": "Section Break",
"fieldname": "terms",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -391,8 +486,10 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Terms",
"length": 0,
"no_copy": 0,
"options": "Terms and Conditions",
"permlevel": 0,
"precision": "",
"print_hide": 0,
@ -411,8 +508,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "preview_report_card",
"fieldtype": "Button",
"fieldname": "assessment_terms",
"fieldtype": "Text Editor",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@ -420,7 +517,7 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Print Report Card",
"label": "Assessment Terms",
"length": 0,
"no_copy": 0,
"permlevel": 0,
@ -446,7 +543,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2018-03-16 01:56:31.095554",
"modified": "2018-03-20 17:57:53.936119",
"modified_by": "Administrator",
"module": "Education",
"name": "Student Report Generation Tool",

View File

@ -16,60 +16,76 @@ class StudentReportGenerationTool(Document):
@frappe.whitelist()
def preview_report_card(program, assessment_group, academic_year, academic_term=None, student=None, student_group=None,
max_days=None, present_days=None, parents_meeting=None, parents_attendance=None):
doc = frappe._dict()
def preview_report_card(**kwargs):
doc = frappe._dict(**kwargs)
doc.students = [doc.student]
if not (doc.student_name and doc.student_batch):
program_enrollment = frappe.get_all("Program Enrollment", fields=["student_batch_name", "student_name"],
filters={"student": doc.student, "docstatus": ('!=', 2), "academic_year": doc.academic_year})
if program_enrollment:
doc.batch = program_enrollment[0].student_batch_name
doc.student_name = program_enrollment[0].student_name
# doc.program = program
doc.assessment_group = assessment_group
doc.academic_year = academic_year
doc.max_days = max_days
doc.present_days = present_days
doc.parents_meeting = parents_meeting
doc.parents_attendance = parents_attendance
if academic_term:
doc.academic_term = academic_term
if student_group:
doc.student_group = student_group
if student:
doc.students = [student]
if not doc.students and not doc.student_group:
frappe.throw("Please select the Student or Student Group")
values = get_formatted_result(doc, get_course=True, get_all_assessment_groups=True)
student_details = values.get("student_details")
assessment_result = values.get("assessment_result").get(doc.students[0])
# get the assessment result of the selected student
values = get_formatted_result(doc, get_course=True, get_all_assessment_groups=doc.include_all_assessment)
assessment_result = values.get("assessment_result").get(doc.student)
courses = values.get("course_dict")
course_criteria = get_courses_criteria(courses)
assessment_groups = get_child_assessment_groups(doc.assessment_group)
if program:
doc.program = program
# get the assessment group as per the user selection
if int(doc.include_all_assessment):
assessment_groups = get_child_assessment_groups(doc.assessment_group)
else:
assessment_groups = [doc.assessment_group]
# get the attendance of the student for that peroid of time.
doc.attendance = get_attendance_count(doc.students[0], doc.academic_year, doc.academic_term)
template = "erpnext/education/doctype/student_report_generation_tool/student_report_generation_tool.html"
base_template_path = "frappe/www/printview.html"
from frappe.www.printview import get_letter_head
letterhead = get_letter_head(frappe._dict({"letter_head": doc.letterhead}), not doc.add_letterhead)
html = frappe.render_template(template,
{
"doc": doc,
"assessment_result": assessment_result,
"courses": courses,
"assessment_groups": assessment_groups,
"course_criteria": course_criteria
"course_criteria": course_criteria,
"letterhead": letterhead.content,
"add_letterhead": int(doc.add_letterhead) if int(doc.add_letterhead) else 0
})
final_template = frappe.render_template(base_template_path, {"body": html, "title": "Report Card"})
final_template = frappe.render_template(base_template_path, {
"body": html,
"title": "Report Card"
})
frappe.response.filename = "Report Card.pdf"
frappe.response.filename = "Report Card " + doc.students[0] + ".pdf"
frappe.response.filecontent = get_pdf(final_template)
frappe.response.type = "download"
def get_courses_criteria(courses):
course_criteria = frappe._dict()
for course in courses:
course_criteria[course] = [d.assessment_criteria for d in frappe.get_all("Course Assessment Criteria",
fields=["assessment_criteria"], filters={"parent": course})]
return course_criteria
def get_attendance_count(student, academic_year, academic_term=None):
if academic_year:
from_date, to_date = frappe.db.get_value("Academic Year", academic_year, ["year_start_date", "year_end_date"])
elif academic_term:
from_date, to_date = frappe.db.get_value("Academic Term", academic_term, ["term_start_date", "term_end_date"])
if from_date and to_date:
attendance = dict(frappe.db.sql('''select status, count(student) as no_of_days
from `tabStudent Attendance` where student = %s
and date between %s and %s group by status''',
(student, from_date, to_date)))
if "Absent" not in attendance.keys():
attendance["Absent"] = 0
if "Present" not in attendance.keys():
attendance["Present"] = 0
return attendance
else:
frappe.throw("Provide the academic year and set the starting and ending date.")