From d3a410b0f380ed9cc71484ca2b6ca86e123dfd10 Mon Sep 17 00:00:00 2001 From: Neil Trini Lasrado Date: Mon, 28 Nov 2016 15:25:17 +0530 Subject: [PATCH] Added Student Monthly Attendence Sheet Report --- erpnext/config/schools.py | 6 ++ .../__init__.py | 0 .../student_monthly_attendance_sheet.js | 42 ++++++++++ .../student_monthly_attendance_sheet.json | 17 ++++ .../student_monthly_attendance_sheet.py | 82 +++++++++++++++++++ 5 files changed, 147 insertions(+) create mode 100644 erpnext/schools/report/student_monthly_attendance_sheet/__init__.py create mode 100644 erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js create mode 100644 erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.json create mode 100644 erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.py diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py index 7a415f013d..c338496518 100644 --- a/erpnext/config/schools.py +++ b/erpnext/config/schools.py @@ -74,6 +74,12 @@ def get_data(): { "type": "doctype", "name": "Student Batch Attendance Tool" + }, + { + "type": "report", + "is_query_report": True, + "name": "Student Monthly Attendance Sheet", + "doctype": "Attendance" } ] }, diff --git a/erpnext/schools/report/student_monthly_attendance_sheet/__init__.py b/erpnext/schools/report/student_monthly_attendance_sheet/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js b/erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js new file mode 100644 index 0000000000..32c0551653 --- /dev/null +++ b/erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.js @@ -0,0 +1,42 @@ +// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +// License: GNU General Public License v3. See license.txt + + +frappe.query_reports["Student Monthly Attendance Sheet"] = { + "filters": [ + { + "fieldname":"month", + "label": __("Month"), + "fieldtype": "Select", + "options": "Jan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec", + "default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", + "Dec"][frappe.datetime.str_to_obj(frappe.datetime.get_today()).getMonth()], + }, + { + "fieldname":"year", + "label": __("Year"), + "fieldtype": "Select", + "reqd": 1 + }, + { + "fieldname":"student_batch", + "label": __("Student Batch"), + "fieldtype": "Link", + "options": "Student Batch", + "reqd": 1 + } + ], + + "onload": function() { + return frappe.call({ + method: "erpnext.schools.report.student_monthly_attendance_sheet.student_monthly_attendance_sheet.get_attendance_years", + callback: function(r) { + var year_filter = frappe.query_report_filters_by_name.year; + year_filter.df.options = r.message; + year_filter.df.default = r.message.split("\n")[0]; + year_filter.refresh(); + year_filter.set_input(year_filter.df.default); + } + }); + } +} diff --git a/erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.json b/erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.json new file mode 100644 index 0000000000..8fa8b796a4 --- /dev/null +++ b/erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.json @@ -0,0 +1,17 @@ +{ + "add_total_row": 0, + "apply_user_permissions": 1, + "creation": "2013-05-13 14:04:03", + "docstatus": 0, + "doctype": "Report", + "idx": 1, + "is_standard": "Yes", + "modified": "2014-06-03 07:18:17.181332", + "modified_by": "Administrator", + "module": "Schools", + "name": "Student Monthly Attendance Sheet", + "owner": "Administrator", + "ref_doctype": "Attendance", + "report_name": "Student Monthly Attendance Sheet", + "report_type": "Script Report" +} \ No newline at end of file diff --git a/erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.py b/erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.py new file mode 100644 index 0000000000..8c6006eae6 --- /dev/null +++ b/erpnext/schools/report/student_monthly_attendance_sheet/student_monthly_attendance_sheet.py @@ -0,0 +1,82 @@ +# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors +# License: GNU General Public License v3. See license.txt + +from __future__ import unicode_literals +import frappe +from frappe.utils import cstr, cint, getdate +from frappe import msgprint, _ +from calendar import monthrange +from erpnext.schools.api import get_student_batch_students + +def execute(filters=None): + if not filters: filters = {} + + conditions, filters = get_conditions(filters) + columns = get_columns(filters) + att_map = get_attendance_list(conditions, filters) + students = get_student_batch_students(filters.get("student_batch")) + data = [] + for stud in students: + row = [stud.student, stud.student_name] + + total_p = total_a = 0.0 + for day in range(filters["total_days_in_month"]): + status="None" + if att_map.get(stud.student): + status = att_map.get(stud.student).get(day + 1, "None") + status_map = {"Present": "P", "Absent": "A", "None": ""} + row.append(status_map[status]) + + if status == "Present": + total_p += 1 + elif status == "Absent": + total_a += 1 + + row += [total_p, total_a] + data.append(row) + + return columns, data + +def get_columns(filters): + columns = [ _("Student") + ":Link/Student:90", _("Student Name") + "::150"] + + for day in range(filters["total_days_in_month"]): + columns.append(cstr(day+1) +"::20") + + columns += [_("Total Present") + ":Int:95", _("Total Absent") + ":Int:90"] + return columns + +def get_attendance_list(conditions, filters): + attendance_list = frappe.db.sql("""select student, day(date) as day_of_month, + status from `tabStudent Attendance` where docstatus = 1 %s order by student, date""" % + conditions, filters, as_dict=1) + + att_map = {} + for d in attendance_list: + att_map.setdefault(d.student, frappe._dict()).setdefault(d.day_of_month, "") + att_map[d.student][d.day_of_month] = d.status + + return att_map + +def get_conditions(filters): + if not (filters.get("month") and filters.get("year")): + msgprint(_("Please select month and year"), raise_exception=1) + + filters["month"] = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", + "Dec"].index(filters.month) + 1 + + filters["total_days_in_month"] = monthrange(cint(filters.year), filters.month)[1] + + conditions = " and month(date) = %(month)s and year(date) = %(year)s" + + if filters.get("student_batch"): conditions += " and student_batch = %(student_batch)s" + + return conditions, filters + +@frappe.whitelist() +def get_attendance_years(): + year_list = frappe.db.sql_list("""select distinct YEAR(date) from `tabStudent Attendance` ORDER BY YEAR(date) DESC""") + if not year_list: + year_list = [getdate().year] + + return "\n".join(str(year) for year in year_list)