real time fee creation status via socketio
diff --git a/erpnext/schools/doctype/fee_schedule/fee_schedule.js b/erpnext/schools/doctype/fee_schedule/fee_schedule.js
index 5eba62d..952a4f6 100644
--- a/erpnext/schools/doctype/fee_schedule/fee_schedule.js
+++ b/erpnext/schools/doctype/fee_schedule/fee_schedule.js
@@ -6,15 +6,6 @@
 		frm.add_fetch("fee_structure", "receivable_account", "receivable_account");
 		frm.add_fetch("fee_structure", "income_account", "income_account");
 		frm.add_fetch("fee_structure", "cost_center", "cost_center");
-		frappe.realtime.on("fee_schedule_progress", function(data) {
-			if (data.progress && data.progress === 0) {
-				frappe.msgprint(__("Fee records will be created in the background. In case of any error the error message will be updated in the Schedule."));
-			}
-			if (data.progress) {
-				frm.reload_doc();
-				frm.dashboard.add_progress("Fee Creation Status", data.progress);
-			}
-		});
 	},
 
 	onload: function(frm) {
@@ -42,6 +33,21 @@
 				"academic_year": frm.doc.academic_year
 			};
 		});
+		frappe.realtime.on("fee_schedule_progress", function(data) {
+			if (data.reload && data.reload === 1) {
+				frm.reload_doc();
+			}
+			if (data.progress && data.progress === "0") {
+				frappe.msgprint(__("Fee records will be created in the background. In case of any error the error message will be updated in the Schedule."));
+			}
+			if (data.progress) {
+				let progress_bar = $(cur_frm.dashboard.progress_area).find(".progress-bar");
+				if (progress_bar) {
+					$(progress_bar).removeClass("progress-bar-danger").addClass("progress-bar-success progress-bar-striped");
+					$(progress_bar).css("width", data.progress+"%");
+				}
+			}
+		});
 	},
 
 	refresh: function(frm) {
@@ -53,9 +59,13 @@
 			frm.dashboard.add_indicator(__('Total Outstanding: {0}', [format_currency(info.total_unpaid,
 				info.currency)]), info.total_unpaid ? 'orange' : 'green');
 		}
-		
+		if (frm.doc.fee_creation_status=="In Process") {
+			frm.dashboard.add_progress("Fee Creation Status", "0");
+		}
 		if (!frm.doc.__islocal && !frm.doc.fee_creation_status || frm.doc.fee_creation_status == "Failed") {
 			frm.add_custom_button(__('Create Fees'), function() {
+				frm.doc.fee_creation_status = "In Process";
+				frm.save();
 				frappe.call({
 					method: "create_fees",
 					doc: frm.doc,
@@ -65,6 +75,9 @@
 				});
 			}, "fa fa-play", "btn-success");
 		}
+		if (frm.doc.fee_creation_status==="Successful") {
+			frm.set_read_only();
+		}
 	},
 
 	fee_structure: function(frm) {
@@ -98,6 +111,6 @@
 					frappe.model.set_value(cdt, cdn, "total_students", r.message);
 				}
 			}
-		})
+		});
 	}
 })
\ No newline at end of file
diff --git a/erpnext/schools/doctype/fee_schedule/fee_schedule.json b/erpnext/schools/doctype/fee_schedule/fee_schedule.json
index 8dd51f7..2b496af 100644
--- a/erpnext/schools/doctype/fee_schedule/fee_schedule.json
+++ b/erpnext/schools/doctype/fee_schedule/fee_schedule.json
@@ -39,7 +39,7 @@
    "read_only": 0, 
    "remember_last_selected_value": 0, 
    "report_hide": 0, 
-   "reqd": 0, 
+   "reqd": 1, 
    "search_index": 0, 
    "set_only_once": 0, 
    "unique": 0
@@ -1029,7 +1029,7 @@
  "issingle": 0, 
  "istable": 0, 
  "max_attachments": 0, 
- "modified": "2017-09-11 16:57:27.427777", 
+ "modified": "2017-09-12 02:03:37.062064", 
  "modified_by": "Administrator", 
  "module": "Schools", 
  "name": "Fee Schedule", 
diff --git a/erpnext/schools/doctype/fee_schedule/fee_schedule.py b/erpnext/schools/doctype/fee_schedule/fee_schedule.py
index 1b2299c..b2ee260 100644
--- a/erpnext/schools/doctype/fee_schedule/fee_schedule.py
+++ b/erpnext/schools/doctype/fee_schedule/fee_schedule.py
@@ -4,7 +4,6 @@
 
 from __future__ import unicode_literals
 import frappe
-from frappe import _
 from frappe.model.document import Document
 from frappe.model.mapper import get_mapped_doc
 from frappe.utils import money_in_words
@@ -40,9 +39,8 @@
 		self.grand_total_in_words = money_in_words(self.grand_total)
 
 	def create_fees(self):
-		if not self.fee_creation_status or self.fee_creation_status == "Failed":
-			self.fee_creation_status = "In Process"
-			frappe.publish_realtime("fee_schedule_progress", {"progress": 0, "reload": True}, user=frappe.session.user)
+		if self.fee_creation_status == "In Process":
+			frappe.publish_realtime("fee_schedule_progress", {"progress": "0", "reload": 1}, user=frappe.session.user)
 			enqueue(generate_fee, queue='default', timeout=6000, event='generate_fee',
 				fee_schedule=self.name)
 
@@ -52,15 +50,13 @@
 	total_records = sum([int(d.total_students) for d in doc.student_groups])
 	created_records = 0
 	for d in doc.student_groups:
-		try:
-			students = frappe.db.sql(""" select sg.program, sg.batch, sgs.student, sgs.student_name
-				from `tabStudent Group` sg, `tabStudent Group Student` sgs
-				where sg.name=%s and sg.name=sgs.parent and sgs.active=1""", d.student_group, as_dict=1)
+		students = frappe.db.sql(""" select sg.program, sg.batch, sgs.student, sgs.student_name
+			from `tabStudent Group` sg, `tabStudent Group Student` sgs
+			where sg.name=%s and sg.name=sgs.parent and sgs.active=1""", d.student_group, as_dict=1)
 
-			# students = frappe.get_all("Student Group Student", fields=["student", "student_name"],
-			# 	filters={"parent": d.student_group, "parenttype": "Student Group", "active": 1})
-			for student in students:
-				doc = get_mapped_doc("Fee Schedule", fee_schedule,	{
+		for student in students:
+			try:
+				fees_doc = get_mapped_doc("Fee Schedule", fee_schedule,	{
 					"Fee Schedule": {
 						"doctype": "Fees",
 						"field_map": {
@@ -68,19 +64,19 @@
 						}
 					}
 				})
-				doc.student = student.student
-				doc.student_name = student.student_name
-				doc.program = student.program
-				doc.student_batch = student.batch
-				doc.send_payment_request = 1
-				doc.save()
-				doc.submit()
+				fees_doc.student = student.student
+				fees_doc.student_name = student.student_name
+				fees_doc.program = student.program
+				fees_doc.student_batch = student.batch
+				fees_doc.send_payment_request = doc.send_email
+				fees_doc.save()
+				fees_doc.submit()
 				created_records += 1
-				frappe.publish_realtime("fee_schedule_progress", {"progress": created_records}, user=frappe.session.user)
+				frappe.publish_realtime("fee_schedule_progress", {"progress": str(int(created_records * 100/total_records))}, user=frappe.session.user)
 
-		except Exception as e:
-			error = True
-			err_msg = frappe.local.message_log and "\n\n".join(frappe.local.message_log) or cstr(e)
+			except Exception as e:
+				error = True
+				err_msg = frappe.local.message_log and "\n\n".join(frappe.local.message_log) or cstr(e)
 
 	if error:
 		frappe.db.rollback()
@@ -91,6 +87,8 @@
 		frappe.db.set_value("Fee Schedule", fee_schedule, "fee_creation_status", "Successful")
 		frappe.db.set_value("Fee Schedule", fee_schedule, "error_log", None)
 
+	frappe.publish_realtime("fee_schedule_progress", {"progress": "100", "reload": 1}, user=frappe.session.user)
+
 
 @frappe.whitelist()
 def get_fee_structure(source_name,target_doc=None):