Added ability to mark attendance against a Student Batch
diff --git a/erpnext/config/schools.py b/erpnext/config/schools.py
index 6acf081..41a8e71 100644
--- a/erpnext/config/schools.py
+++ b/erpnext/config/schools.py
@@ -73,6 +73,10 @@
 				},
 				{
 					"type": "doctype",
+					"name": "Student Batch Attendance Tool"
+				},
+				{
+					"type": "doctype",
 					"name": "Scheduling Tool"
 				}
 			]
diff --git a/erpnext/schools/api.py b/erpnext/schools/api.py
index 6011158..dea8515 100644
--- a/erpnext/schools/api.py
+++ b/erpnext/schools/api.py
@@ -30,33 +30,40 @@
 	return program_enrollment
 
 @frappe.whitelist()
-def check_attendance_records_exist(course_schedule):
-	"""Check if Attendance Records are made against the specified Course Schedule.
+def check_attendance_records_exist(course_schedule=None, student_batch=None, date=None):
+	"""Check if Attendance Records are made against the specified Course Schedule or Student Batch for given date.
 
 	:param course_schedule: Course Schedule.
+	:param student_batch: Student Batch.
+	:param date: Date.
 	"""
-	return frappe.get_list("Student Attendance", filters={"course_schedule": course_schedule})
+	if course_schedule:
+		return frappe.get_list("Student Attendance", filters={"course_schedule": course_schedule})
+	else:
+		return frappe.get_list("Student Attendance", filters={"student_batch": student_batch, "date": date})
 
 @frappe.whitelist()
-def mark_attendance(students_present, students_absent, course_schedule):
+def mark_attendance(students_present, students_absent, course_schedule=None, student_batch=None, date=None):
 	"""Creates Multiple Attendance Records.
 
 	:param students_present: Students Present JSON.
 	:param students_absent: Students Absent JSON.
 	:param course_schedule: Course Schedule.
+	:param student_batch: Student Batch.
+	:param date: Date.
 	"""
 	present = json.loads(students_present)
 	absent = json.loads(students_absent)
 
 	for d in present:
-		make_attendance_records(d["student"], d["student_name"], course_schedule, "Present")
+		make_attendance_records(d["student"], d["student_name"], "Present", course_schedule, student_batch, date)
 
 	for d in absent:
-		make_attendance_records(d["student"], d["student_name"], course_schedule, "Absent")
+		make_attendance_records(d["student"], d["student_name"], "Absent", course_schedule, student_batch, date)
 
 	frappe.msgprint(_("Attendance has been marked successfully."))
 
-def make_attendance_records(student, student_name, course_schedule, status):
+def make_attendance_records(student, student_name, status, course_schedule=None, student_batch=None, date=None):
 	"""Creates Attendance Record.
 
 	:param student: Student.
@@ -68,11 +75,22 @@
 	student_attendance.student = student
 	student_attendance.student_name = student_name
 	student_attendance.course_schedule = course_schedule
+	student_attendance.student_batch = student_batch
+	student_attendance.date = date
 	student_attendance.status = status
 	student_attendance.submit()
 	frappe.db.commit()
 
 @frappe.whitelist()
+def get_student_batch_students(student_batch):
+	"""Returns List of student, student_name in Student Batch.
+
+	:param student_batch: Student Batch.
+	"""
+	students = frappe.get_list("Student Batch Student", fields=["student", "student_name"] , filters={"parent": student_batch}, order_by= "idx")
+	return students
+
+@frappe.whitelist()
 def get_student_group_students(student_group):
 	"""Returns List of student, student_name in Student Group.
 
diff --git a/erpnext/schools/doctype/assessment/assessment.json b/erpnext/schools/doctype/assessment/assessment.json
index 9f1349c..845f2f6 100644
--- a/erpnext/schools/doctype/assessment/assessment.json
+++ b/erpnext/schools/doctype/assessment/assessment.json
@@ -92,7 +92,36 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "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, 
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
@@ -593,7 +622,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2016-11-07 05:47:47.529783", 
+ "modified": "2016-11-16 13:05:54.953750", 
  "modified_by": "Administrator", 
  "module": "Schools", 
  "name": "Assessment", 
diff --git a/erpnext/schools/doctype/assessment/assessment.py b/erpnext/schools/doctype/assessment/assessment.py
index de6a653..cb307cb 100644
--- a/erpnext/schools/doctype/assessment/assessment.py
+++ b/erpnext/schools/doctype/assessment/assessment.py
@@ -8,56 +8,66 @@
 from frappe import _
 
 class Assessment(Document):
-    def validate(self):
-        self.validate_overlap()
-    
-    def validate_overlap(self):
-        """Validates overlap for Student Group, Supervisor, Room"""
+	def validate(self):
+		self.validate_overlap()
+	
+	def validate_overlap(self):
+		"""Validates overlap for Student Group/Student Batch, Instructor, Room"""
+		
+		from erpnext.schools.utils import validate_overlap_for
 
-        from erpnext.schools.utils import validate_overlap_for
+		#Validate overlapping course schedules.
+		if self.student_batch:
+			validate_overlap_for(self, "Course Schedule", "student_batch")
 
-        validate_overlap_for(self, "Assessment", "student_group")
-        validate_overlap_for(self, "Course Schedule", "student_group" )
-        
-        if self.room:
-            validate_overlap_for(self, "Assessment", "room")
-            validate_overlap_for(self, "Course Schedule", "room")
+		if self.student_group:
+			validate_overlap_for(self, "Course Schedule", "student_group")
+		
+		validate_overlap_for(self, "Course Schedule", "instructor")
+		validate_overlap_for(self, "Course Schedule", "room")
 
-        if self.supervisor:
-            validate_overlap_for(self, "Assessment", "supervisor")
-            validate_overlap_for(self, "Course Schedule", "instructor", self.supervisor)
+		#validate overlapping assessment schedules.
+		if self.student_batch:
+			validate_overlap_for(self, "Assessment", "student_batch")
+		
+		if self.student_group:
+			validate_overlap_for(self, "Assessment", "student_group")
+		
+		validate_overlap_for(self, "Assessment", "room")
+		validate_overlap_for(self, "Assessment", "supervisor", self.instructor)
+
 
 def get_assessment_list(doctype, txt, filters, limit_start, limit_page_length=20):
-    user = frappe.session.user
-    student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user)
-    if student:
-        return frappe. db.sql('''select course, schedule_date, from_time, to_time, sgs.name from `tabAssessment` as assessment, 
-            `tabStudent Group Student` as sgs where assessment.student_group = sgs.parent and sgs.student = %s and assessment.docstatus=1
-            order by assessment.name asc limit {0} , {1}'''
-            .format(limit_start, limit_page_length), student, as_dict = True)
+	user = frappe.session.user
+	student = frappe.db.sql("select name from `tabStudent` where student_email_id= %s", user)
+	if student:
+		return frappe. db.sql('''select course, schedule_date, from_time, to_time, sgs.name from `tabAssessment` as assessment, 
+			`tabStudent Group Student` as sgs where assessment.student_group = sgs.parent and sgs.student = %s and assessment.docstatus=1
+			order by assessment.name asc limit {0} , {1}'''
+			.format(limit_start, limit_page_length), student, as_dict = True)
 
 def get_list_context(context=None):
-    return {
-        "show_sidebar": True,
-        'no_breadcrumbs': True,
-        "title": _("Assessment Schedule"),
-        "get_list": get_assessment_list,
-        "row_template": "templates/includes/assessment/assessment_row.html"
-    }
+	return {
+		"show_sidebar": True,
+		'no_breadcrumbs': True,
+		"title": _("Assessment Schedule"),
+		"get_list": get_assessment_list,
+		"row_template": "templates/includes/assessment/assessment_row.html"
+	}
 
 @frappe.whitelist()
 def get_grade(grading_structure, result):
-    grade = frappe.db.sql("""select gi.from_score, gi.to_score, gi.grade_code, gi.grade_description 
-        from `tabGrading Structure` as gs, `tabGrade Interval` as gi 
-        where gs.name = gi.parent and gs.name = %(grading_structure)s and gi.from_score <= %(result)s 
-        and gi.to_score >= %(result)s""".format(), 
-        {
-            "grading_structure":grading_structure,
-            "result": result
-        },
-        as_dict=True)
-    
-    return grade[0].grade_code if grade else ""
+	grade = frappe.db.sql("""select gi.from_score, gi.to_score, gi.grade_code, gi.grade_description 
+		from `tabGrading Structure` as gs, `tabGrade Interval` as gi 
+		where gs.name = gi.parent and gs.name = %(grading_structure)s and gi.from_score <= %(result)s 
+		and gi.to_score >= %(result)s""".format(), 
+		{
+			"grading_structure":grading_structure,
+			"result": result
+		},
+		as_dict=True)
+   	 
+	return grade[0].grade_code if grade else ""
 
 def validate_grade(score, grade):
-    pass
\ No newline at end of file
+	pass
\ No newline at end of file
diff --git a/erpnext/schools/doctype/course_schedule/course_schedule.js b/erpnext/schools/doctype/course_schedule/course_schedule.js
index 2defbd5..ab34ae9 100644
--- a/erpnext/schools/doctype/course_schedule/course_schedule.js
+++ b/erpnext/schools/doctype/course_schedule/course_schedule.js
@@ -12,7 +12,7 @@
 	},
 	
 	refresh :function(frm) {
-		if(!frm.doc.__islocal) {
+		if(!frm.doc.__islocal && frm.doc.student_group) {
 			frappe.call({
 				method: "erpnext.schools.api.check_attendance_records_exist",
 				args: {
diff --git a/erpnext/schools/doctype/course_schedule/course_schedule.json b/erpnext/schools/doctype/course_schedule/course_schedule.json
index eda1ec7..4a4b2d3 100644
--- a/erpnext/schools/doctype/course_schedule/course_schedule.json
+++ b/erpnext/schools/doctype/course_schedule/course_schedule.json
@@ -2,7 +2,7 @@
  "allow_copy": 0, 
  "allow_import": 1, 
  "allow_rename": 0, 
- "autoname": "naming_series", 
+ "autoname": "naming_series:", 
  "beta": 0, 
  "creation": "2015-09-09 16:34:04.960369", 
  "custom": 0, 
@@ -17,6 +17,35 @@
    "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": "student_group", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -36,7 +65,7 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
@@ -75,24 +104,23 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "default": "SH", 
-   "fieldname": "naming_series", 
-   "fieldtype": "Select", 
+   "fieldname": "instructor_name", 
+   "fieldtype": "Read Only", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Naming Series", 
+   "label": "Instructor Name", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "SH", 
+   "options": "instructor.Instructor_name", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
    "print_hide_if_no_value": 0, 
-   "read_only": 0, 
+   "read_only": 1, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
    "reqd": 0, 
@@ -132,26 +160,27 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "course", 
-   "fieldtype": "Read Only", 
+   "default": "SH", 
+   "fieldname": "naming_series", 
+   "fieldtype": "Select", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Course", 
+   "label": "Naming Series", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "student_group.course", 
+   "options": "SH", 
    "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": 1, 
+   "reqd": 0, 
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
@@ -161,26 +190,26 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "instructor_name", 
-   "fieldtype": "Read Only", 
+   "fieldname": "course", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Instructor Name", 
+   "label": "Course", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "instructor.Instructor_name", 
+   "options": "Course", 
    "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, 
+   "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
@@ -449,7 +478,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2016-11-07 05:51:34.493014", 
+ "modified": "2016-11-16 16:38:00.454295", 
  "modified_by": "Administrator", 
  "module": "Schools", 
  "name": "Course Schedule", 
diff --git a/erpnext/schools/doctype/course_schedule/course_schedule.py b/erpnext/schools/doctype/course_schedule/course_schedule.py
index 11f3894..ec30c62 100644
--- a/erpnext/schools/doctype/course_schedule/course_schedule.py
+++ b/erpnext/schools/doctype/course_schedule/course_schedule.py
@@ -4,34 +4,62 @@
 
 from __future__ import unicode_literals
 import frappe
+from frappe import _
 from frappe.model.document import Document
 
 class CourseSchedule(Document):
 	def validate(self):
 		self.instructor_name = frappe.db.get_value("Instructor", self.instructor, "instructor_name")
 		self.set_title()
+		self.validate_mandatory()
+		self.validate_course()
+		self.set_student_batch()
 		self.validate_date()
 		self.validate_overlap()
-		
+	
 	def set_title(self):
 		"""Set document Title"""
 		self.title = self.course + " by " + (self.instructor_name if self.instructor_name else self.instructor)
 
+	def validate_mandatory(self):
+		if not (self.student_batch or self.student_group):
+			frappe.throw(_("""Student Batch or Student Group is mandatory"""))
+	
+	def validate_course(self):
+		if self.student_group:
+			self.course= frappe.db.get_value("Student Group", self.student_group, "course")
+	
+	def set_student_batch(self):
+		if self.student_group:
+			self.student_batch = frappe.db.get_value("Student Group", self.student_group, "student_batch")
+	
 	def validate_date(self):
 		"""Validates if from_time is greater than to_time"""
 		if self.from_time > self.to_time:
-			frappe.throw("From Time cannot be greater than To Time.")
+			frappe.throw(_("From Time cannot be greater than To Time."))
 	
 	def validate_overlap(self):
-		"""Validates overlap for Student Group, Instructor, Room"""
+		"""Validates overlap for Student Group/Student Batch, Instructor, Room"""
 		
 		from erpnext.schools.utils import validate_overlap_for
 
-		validate_overlap_for(self, "Course Schedule", "student_group" )
+		#Validate overlapping course schedules.
+		if self.student_batch:
+			validate_overlap_for(self, "Course Schedule", "student_batch")
+
+		if self.student_group:
+			validate_overlap_for(self, "Course Schedule", "student_group")
+		
 		validate_overlap_for(self, "Course Schedule", "instructor")
 		validate_overlap_for(self, "Course Schedule", "room")
 
-		validate_overlap_for(self, "Assessment", "student_group")
+		#validate overlapping assessment schedules.
+		if self.student_batch:
+			validate_overlap_for(self, "Assessment", "student_batch")
+		
+		if self.student_group:
+			validate_overlap_for(self, "Assessment", "student_group")
+		
 		validate_overlap_for(self, "Assessment", "room")
 		validate_overlap_for(self, "Assessment", "supervisor", self.instructor)
 
diff --git a/erpnext/schools/doctype/scheduling_tool/scheduling_tool.js b/erpnext/schools/doctype/scheduling_tool/scheduling_tool.js
index 7109771..5011375 100644
--- a/erpnext/schools/doctype/scheduling_tool/scheduling_tool.js
+++ b/erpnext/schools/doctype/scheduling_tool/scheduling_tool.js
@@ -1,4 +1,5 @@
 cur_frm.add_fetch("student_group", "program", "program");
+cur_frm.add_fetch("student_group", "student_batch", "student_batch");
 cur_frm.add_fetch("student_group", "course", "course");
 cur_frm.add_fetch("student_group", "academic_year", "academic_year");
 cur_frm.add_fetch("student_group", "academic_term", "academic_term");
diff --git a/erpnext/schools/doctype/scheduling_tool/scheduling_tool.json b/erpnext/schools/doctype/scheduling_tool/scheduling_tool.json
index 41a7b94..cf2c1a3 100644
--- a/erpnext/schools/doctype/scheduling_tool/scheduling_tool.json
+++ b/erpnext/schools/doctype/scheduling_tool/scheduling_tool.json
@@ -9,11 +9,42 @@
  "doctype": "DocType", 
  "document_type": "Setup", 
  "editable_grid": 0, 
+ "engine": "InnoDB", 
  "fields": [
   {
    "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, 
+   "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, 
@@ -21,6 +52,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Student Group", 
    "length": 0, 
    "no_copy": 0, 
@@ -30,6 +62,36 @@
    "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": "course", 
+   "fieldtype": "Link", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Course", 
+   "length": 0, 
+   "no_copy": 0, 
+   "options": "Course", 
+   "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, 
@@ -40,6 +102,34 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
+   "fieldname": "column_break_3", 
+   "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": "academic_year", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -47,6 +137,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Academic Year", 
    "length": 0, 
    "no_copy": 0, 
@@ -56,6 +147,7 @@
    "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, 
@@ -66,6 +158,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "academic_term", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -73,6 +166,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Academic Term", 
    "length": 0, 
    "no_copy": 0, 
@@ -82,6 +176,7 @@
    "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, 
@@ -92,30 +187,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "column_break_3", 
-   "fieldtype": "Column Break", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "length": 0, 
-   "no_copy": 0, 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 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": "program", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -123,6 +195,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Program", 
    "length": 0, 
    "no_copy": 0, 
@@ -132,6 +205,7 @@
    "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, 
@@ -142,32 +216,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
-   "fieldname": "course", 
-   "fieldtype": "Link", 
-   "hidden": 0, 
-   "ignore_user_permissions": 0, 
-   "ignore_xss_filter": 0, 
-   "in_filter": 0, 
-   "in_list_view": 0, 
-   "label": "Course", 
-   "length": 0, 
-   "no_copy": 0, 
-   "options": "Course", 
-   "permlevel": 0, 
-   "precision": "", 
-   "print_hide": 0, 
-   "print_hide_if_no_value": 0, 
-   "read_only": 1, 
-   "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": "section_break_6", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -175,6 +224,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -182,6 +232,7 @@
    "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, 
@@ -192,6 +243,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "room", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -199,6 +251,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Room", 
    "length": 0, 
    "no_copy": 0, 
@@ -208,6 +261,7 @@
    "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, 
@@ -218,6 +272,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "column_break_9", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -225,6 +280,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -232,6 +288,7 @@
    "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, 
@@ -242,6 +299,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "instructor", 
    "fieldtype": "Link", 
    "hidden": 0, 
@@ -249,6 +307,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Instructor", 
    "length": 0, 
    "no_copy": 0, 
@@ -258,6 +317,7 @@
    "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, 
@@ -268,6 +328,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "instructor_name", 
    "fieldtype": "Read Only", 
    "hidden": 0, 
@@ -275,6 +336,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Instructor Name", 
    "length": 0, 
    "no_copy": 0, 
@@ -284,6 +346,7 @@
    "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, 
@@ -294,6 +357,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "section_break_7", 
    "fieldtype": "Section Break", 
    "hidden": 0, 
@@ -301,6 +365,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -308,6 +373,7 @@
    "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, 
@@ -318,6 +384,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "default": "", 
    "fieldname": "from_time", 
    "fieldtype": "Time", 
@@ -326,6 +393,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "From Time", 
    "length": 0, 
    "no_copy": 0, 
@@ -334,6 +402,7 @@
    "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, 
@@ -344,6 +413,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "default": "", 
    "fieldname": "course_start_date", 
    "fieldtype": "Date", 
@@ -352,6 +422,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Course Start Date", 
    "length": 0, 
    "no_copy": 0, 
@@ -361,6 +432,7 @@
    "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, 
@@ -371,6 +443,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "day", 
    "fieldtype": "Select", 
    "hidden": 0, 
@@ -378,6 +451,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Day", 
    "length": 0, 
    "no_copy": 0, 
@@ -387,6 +461,7 @@
    "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, 
@@ -397,6 +472,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "rechedule", 
    "fieldtype": "Check", 
    "hidden": 0, 
@@ -404,6 +480,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Rechedule", 
    "length": 0, 
    "no_copy": 0, 
@@ -412,6 +489,7 @@
    "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, 
@@ -422,6 +500,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "column_break_15", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -429,6 +508,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "length": 0, 
    "no_copy": 0, 
    "permlevel": 0, 
@@ -436,6 +516,7 @@
    "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, 
@@ -446,6 +527,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "to_time", 
    "fieldtype": "Time", 
    "hidden": 0, 
@@ -453,6 +535,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "To TIme", 
    "length": 0, 
    "no_copy": 0, 
@@ -461,6 +544,7 @@
    "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, 
@@ -471,6 +555,7 @@
    "allow_on_submit": 0, 
    "bold": 0, 
    "collapsible": 0, 
+   "columns": 0, 
    "default": "", 
    "fieldname": "course_end_date", 
    "fieldtype": "Date", 
@@ -479,6 +564,7 @@
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
    "in_list_view": 0, 
+   "in_standard_filter": 0, 
    "label": "Course End Date", 
    "length": 0, 
    "no_copy": 0, 
@@ -487,6 +573,7 @@
    "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, 
@@ -505,7 +592,7 @@
  "istable": 0, 
  "max_attachments": 0, 
  "menu_index": 0, 
- "modified": "2016-07-25 01:24:48.220756", 
+ "modified": "2016-11-16 16:03:41.854229", 
  "modified_by": "Administrator", 
  "module": "Schools", 
  "name": "Scheduling Tool", 
@@ -522,6 +609,7 @@
    "export": 0, 
    "if_owner": 0, 
    "import": 0, 
+   "is_custom": 0, 
    "permlevel": 0, 
    "print": 0, 
    "read": 1, 
diff --git a/erpnext/schools/doctype/scheduling_tool/scheduling_tool.py b/erpnext/schools/doctype/scheduling_tool/scheduling_tool.py
index 4a62a74..b8ba578 100644
--- a/erpnext/schools/doctype/scheduling_tool/scheduling_tool.py
+++ b/erpnext/schools/doctype/scheduling_tool/scheduling_tool.py
@@ -22,7 +22,9 @@
 		self.validate_mandatory()
 		self.validate_date()
 		self.instructor_name= frappe.db.get_value("Instructor", self.instructor, "instructor_name")
-		self.course= frappe.db.get_value("Student Group", self.student_group, "course")
+		
+		if self.student_group:
+			self.course= frappe.db.get_value("Student Group", self.student_group, "course")
 		
 		if self.rechedule:
 			rescheduled, reschedule_errors = self.delete_course_schedule(rescheduled, reschedule_errors)
@@ -54,7 +56,11 @@
 			
 	def validate_mandatory(self):
 		"""Validates all mandatory fields"""
-		fields = ['student_group', 'room', 'instructor', 'from_time', 'to_time', 'course_start_date', 'course_end_date', 'day']
+		
+		if not (self.student_batch or self.student_group):
+			frappe.throw(_("""Student Batch or Student Group is mandatory"""))
+		
+		fields = ['course', 'room', 'instructor', 'from_time', 'to_time', 'course_start_date', 'course_end_date', 'day']
 		for d in  fields:
 			if not self.get(d):
 				frappe.throw(_("{0} is mandatory").format(self.meta.get_label(d)))	
@@ -68,6 +74,8 @@
 		"""Delete all course schedule within the Date range and specified filters"""
 		schedules = frappe.get_list("Course Schedule", fields=["name", "schedule_date"], filters = 
 			[["student_group", "=", self.student_group],
+			["student_batch", "=", self.student_batch],
+			["course", "=", self.course],
 			["schedule_date", ">=", self.course_start_date], 
 			["schedule_date", "<=", self.course_end_date]])
 		for d in schedules:
@@ -85,6 +93,7 @@
 		
 		course_schedule = frappe.new_doc("Course Schedule")
 		course_schedule.student_group = self.student_group
+		course_schedule.student_batch = self.student_batch
 		course_schedule.course = self.course
 		course_schedule.instructor = self.instructor
 		course_schedule.instructor_name = self.instructor_name
diff --git a/erpnext/schools/doctype/student_attendance/student_attendance.js b/erpnext/schools/doctype/student_attendance/student_attendance.js
index 5068208..6e79d52 100644
--- a/erpnext/schools/doctype/student_attendance/student_attendance.js
+++ b/erpnext/schools/doctype/student_attendance/student_attendance.js
@@ -1,6 +1,9 @@
 // Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
 // For license information, please see license.txt
 
+cur_frm.add_fetch("course_schedule", "schedule_date", "date");
+cur_frm.add_fetch("course_schedule", "student_batch", "student_batch");
+
 frappe.ui.form.on('Student Attendance', {
 	refresh: function(frm) {
 
diff --git a/erpnext/schools/doctype/student_attendance/student_attendance.json b/erpnext/schools/doctype/student_attendance/student_attendance.json
index 9caa9ae..70fcdf3 100644
--- a/erpnext/schools/doctype/student_attendance/student_attendance.json
+++ b/erpnext/schools/doctype/student_attendance/student_attendance.json
@@ -46,18 +46,18 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "student_name", 
-   "fieldtype": "Read Only", 
+   "fieldname": "course_schedule", 
+   "fieldtype": "Link", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 0, 
+   "in_list_view": 1, 
    "in_standard_filter": 0, 
-   "label": "Student Name", 
+   "label": "Course Schedule", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "student.title", 
+   "options": "Course Schedule", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -75,6 +75,34 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
+   "fieldname": "date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Date", 
+   "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": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
    "fieldname": "column_break_3", 
    "fieldtype": "Column Break", 
    "hidden": 0, 
@@ -102,18 +130,18 @@
    "bold": 0, 
    "collapsible": 0, 
    "columns": 0, 
-   "fieldname": "course_schedule", 
-   "fieldtype": "Link", 
+   "fieldname": "student_name", 
+   "fieldtype": "Read Only", 
    "hidden": 0, 
    "ignore_user_permissions": 0, 
    "ignore_xss_filter": 0, 
    "in_filter": 0, 
-   "in_list_view": 1, 
+   "in_list_view": 0, 
    "in_standard_filter": 0, 
-   "label": "Course Schedule", 
+   "label": "Student Name", 
    "length": 0, 
    "no_copy": 0, 
-   "options": "Course Schedule", 
+   "options": "student.title", 
    "permlevel": 0, 
    "precision": "", 
    "print_hide": 0, 
@@ -121,7 +149,36 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 1, 
+   "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, 
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
@@ -195,7 +252,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2016-11-07 05:29:02.601819", 
+ "modified": "2016-11-16 16:58:35.779867", 
  "modified_by": "Administrator", 
  "module": "Schools", 
  "name": "Student Attendance", 
diff --git a/erpnext/schools/doctype/student_attendance/student_attendance.py b/erpnext/schools/doctype/student_attendance/student_attendance.py
index 65dbd68..d9949b0 100644
--- a/erpnext/schools/doctype/student_attendance/student_attendance.py
+++ b/erpnext/schools/doctype/student_attendance/student_attendance.py
@@ -9,13 +9,31 @@
 
 class StudentAttendance(Document):
 	def validate(self):
+		self.validate_date()
+		self.validate_mandatory()
 		self.validate_duplication()
 		
+	def validate_date(self):
+		if self.course_schedule:
+			self.date = frappe.db.get_value("Course Schedule", self.course_schedule, "schedule_date")
+	
+	def validate_mandatory(self):
+		if not (self.student_batch or self.course_schedule):
+			frappe.throw(_("""Student Batch or Course Schedule is mandatory"""))
+	
 	def validate_duplication(self):
 		"""Check if the Attendance Record is Unique"""
-		attendance_records= frappe.db.sql("""select name from `tabStudent Attendance` where \
-			student= %s and course_schedule= %s and name != %s""",
-			(self.student, self.course_schedule, self.name))
+		
+		attendance_records=None
+		if self.course_schedule:
+			attendance_records= frappe.db.sql("""select name from `tabStudent Attendance` where \
+				student= %s and course_schedule= %s and name != %s and docstatus=1""",
+				(self.student, self.course_schedule, self.name))
+		else:
+			attendance_records= frappe.db.sql("""select name from `tabStudent Attendance` where \
+				student= %s and date= %s and name != %s and course_schedule='' and docstatus=1""",
+				(self.student, self.date, self.name))
+			
 		if attendance_records:
-			frappe.throw(_("Attendance Record {0} exists against Student {1} for Course Schedule {2}")
-				.format(attendance_records[0][0], self.student, self.course_schedule))
+			frappe.throw(_("Attendance Record {0} exists against Student {1}")
+				.format(attendance_records[0][0], self.student))
diff --git a/erpnext/schools/doctype/student_batch_attendance_tool/__init__.py b/erpnext/schools/doctype/student_batch_attendance_tool/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/schools/doctype/student_batch_attendance_tool/__init__.py
diff --git a/erpnext/schools/doctype/student_batch_attendance_tool/student_batch_attendance_tool.js b/erpnext/schools/doctype/student_batch_attendance_tool/student_batch_attendance_tool.js
new file mode 100644
index 0000000..a6d035a
--- /dev/null
+++ b/erpnext/schools/doctype/student_batch_attendance_tool/student_batch_attendance_tool.js
@@ -0,0 +1,128 @@
+// Copyright (c) 2016, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+frappe.provide("schools")
+
+frappe.ui.form.on('Student Batch Attendance Tool', {
+	refresh: function(frm) {
+		frm.disable_save();
+		hide_field('attendance');
+	},
+	
+	student_batch :function(frm) {
+		if(frm.doc.student_batch && frm.doc.date) {
+			frappe.call({
+				method: "erpnext.schools.api.check_attendance_records_exist",
+				args: {
+					"student_batch": frm.doc.student_batch,
+					"date": frm.doc.date
+				},
+				callback: function(r) {
+					if(r.message) {
+						frappe.msgprint("Attendance already marked.");
+						hide_field('attendance');
+					}
+					else {
+						frappe.call({
+							method: "erpnext.schools.api.get_student_batch_students",
+							args: {
+								"student_batch": frm.doc.student_batch
+							},
+							callback: function(r) {
+								if (r.message) {
+									unhide_field('attendance');
+									frm.events.get_students(frm, r.message)
+								}
+							}
+						});
+					}
+				}
+			});
+		}
+	},
+	
+	date: function(frm) {
+		frm.trigger("student_batch");
+	},
+	
+	get_students: function(frm, students) {
+		if(!frm.students_area) {
+		frm.students_area = $('<div>')
+			.appendTo(frm.fields_dict.students_html.wrapper);
+		}
+		frm.students_editor = new schools.StudentsEditor(frm, frm.students_area, students)
+	}
+});
+
+
+schools.StudentsEditor = Class.extend({
+	init: function(frm, wrapper, students) {
+		this.wrapper = wrapper;
+		this.frm = frm;
+		this.make(frm, students);
+	},
+	make: function(frm, students) {
+		var me = this;
+		
+		$(this.wrapper).empty();
+		var student_toolbar = $('<p>\
+			<button class="btn btn-default btn-add btn-xs" style="margin-right: 5px;"></button>\
+			<button class="btn btn-xs btn-default btn-remove" style="margin-right: 5px;"></button>\
+			<button class="btn btn-default btn-primary btn-mark-att btn-xs"></button></p>').appendTo($(this.wrapper));
+
+		student_toolbar.find(".btn-add")
+			.html(__('Check all'))
+			.on("click", function() {
+			$(me.wrapper).find('input[type="checkbox"]').each(function(i, check) {
+				if(!$(check).is(":checked")) {
+					check.checked = true;
+				}
+			});
+		});
+
+		student_toolbar.find(".btn-remove")
+			.html(__('Uncheck all'))
+			.on("click", function() {
+			$(me.wrapper).find('input[type="checkbox"]').each(function(i, check) {
+				if($(check).is(":checked")) {
+					check.checked = false;
+				}
+			});
+		});
+		
+		student_toolbar.find(".btn-mark-att")
+			.html(__('Mark Attendence'))
+			.on("click", function() {
+				var students_present = [];
+				var students_absent = [];
+				$(me.wrapper).find('input[type="checkbox"]').each(function(i, check) {
+					if($(check).is(":checked")) {
+						students_present.push(students[i]);
+					}
+					else {
+						students_absent.push(students[i]);
+					}
+				});
+				frappe.call({
+					method: "erpnext.schools.api.mark_attendance",
+					args: {
+						"students_present": students_present,
+						"students_absent": students_absent,
+						"student_batch": frm.doc.student_batch,
+						"date": frm.doc.date
+					},
+					callback: function(r) {
+						hide_field('attendance');
+					}
+				});
+		});
+
+		
+		$.each(students, function(i, m) {
+			$(repl('<div class="col-sm-6">\
+				<div class="checkbox">\
+				<label><input type="checkbox" class="students-check" student="%(student)s">\
+				%(student)s</label>\
+			</div></div>', {student: m.student_name})).appendTo(me.wrapper);
+		});
+	}
+});
diff --git a/erpnext/schools/doctype/student_batch_attendance_tool/student_batch_attendance_tool.json b/erpnext/schools/doctype/student_batch_attendance_tool/student_batch_attendance_tool.json
new file mode 100644
index 0000000..3361dcb
--- /dev/null
+++ b/erpnext/schools/doctype/student_batch_attendance_tool/student_batch_attendance_tool.json
@@ -0,0 +1,201 @@
+{
+ "allow_copy": 1, 
+ "allow_import": 0, 
+ "allow_rename": 0, 
+ "beta": 0, 
+ "creation": "2016-11-16 17:12:46.437539", 
+ "custom": 0, 
+ "docstatus": 0, 
+ "doctype": "DocType", 
+ "document_type": "", 
+ "editable_grid": 1, 
+ "engine": "InnoDB", 
+ "fields": [
+  {
+   "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": 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": "date", 
+   "fieldtype": "Date", 
+   "hidden": 0, 
+   "ignore_user_permissions": 0, 
+   "ignore_xss_filter": 0, 
+   "in_filter": 0, 
+   "in_list_view": 0, 
+   "in_standard_filter": 0, 
+   "label": "Date", 
+   "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": 1, 
+   "search_index": 0, 
+   "set_only_once": 0, 
+   "unique": 0
+  }, 
+  {
+   "allow_on_submit": 0, 
+   "bold": 0, 
+   "collapsible": 0, 
+   "columns": 0, 
+   "depends_on": "", 
+   "fieldname": "attendance", 
+   "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": "Attendance", 
+   "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": "students_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": "Students 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": "2016-11-16 17:16:43.835693", 
+ "modified_by": "Administrator", 
+ "module": "Schools", 
+ "name": "Student Batch Attendance 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": 0, 
+ "read_only": 0, 
+ "read_only_onload": 0, 
+ "sort_field": "modified", 
+ "sort_order": "DESC", 
+ "track_seen": 0
+}
\ No newline at end of file
diff --git a/erpnext/schools/doctype/student_batch_attendance_tool/student_batch_attendance_tool.py b/erpnext/schools/doctype/student_batch_attendance_tool/student_batch_attendance_tool.py
new file mode 100644
index 0000000..49a5ae8
--- /dev/null
+++ b/erpnext/schools/doctype/student_batch_attendance_tool/student_batch_attendance_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 StudentBatchAttendanceTool(Document):
+	pass