Staffing plan for group company
diff --git a/erpnext/hr/doctype/job_opening/job_opening.js b/erpnext/hr/doctype/job_opening/job_opening.js
index b024310..960f5b3 100644
--- a/erpnext/hr/doctype/job_opening/job_opening.js
+++ b/erpnext/hr/doctype/job_opening/job_opening.js
@@ -2,38 +2,37 @@
 // For license information, please see license.txt
 
 frappe.ui.form.on('Job Opening', {
-  designation: function(frm) {
-    if(frm.doc.designation && frm.doc.company){
+	designation: function(frm) {
+		if(frm.doc.designation && frm.doc.company){
 			frappe.call({
 				"method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_active_staffing_plan_and_vacancies",
 				args: {
-          company: frm.doc.company,
-          designation: frm.doc.designation,
-          department: frm.doc.department,
-          date: frappe.datetime.now_date() // ToDo - Date in Job Opening?
+					company: frm.doc.company,
+					designation: frm.doc.designation,
+					department: frm.doc.department,
+					date: frappe.datetime.now_date() // ToDo - Date in Job Opening?
 				},
 				callback: function (data) {
 					if(data.message){
 						frm.set_value('staffing_plan', data.message[0]);
-            frm.set_value('planned_vacancies', data.message[1]);
+						frm.set_value('planned_vacancies', data.message[1]);
+					} else {
+						frm.set_value('staffing_plan', "");
+						frm.set_value('planned_vacancies', 0);
+						frappe.show_alert({
+							indicator: 'orange',
+							message: __('No Staffing Plans found for this Designation')
+						});
 					}
-          else{
-            frm.set_value('staffing_plan', "");
-            frm.set_value('planned_vacancies', 0);
-            frappe.show_alert({
-            	indicator: 'orange',
-            	message: __('No Staffing Plans found for this Designation')
-            });
-          }
 				}
 			});
 		}
-    else{
-      frm.set_value('staffing_plan', "");
-      frm.set_value('planned_vacancies', 0);
-    }
-  },
-  company: function(frm) {
-    frm.set_value('designation', "");
-  }
+		else{
+			frm.set_value('staffing_plan', "");
+			frm.set_value('planned_vacancies', 0);
+		}
+	},
+	company: function(frm) {
+		frm.set_value('designation', "");
+	}
 });
diff --git a/erpnext/hr/doctype/job_opening/job_opening.py b/erpnext/hr/doctype/job_opening/job_opening.py
index d3d662a..b579d6f 100644
--- a/erpnext/hr/doctype/job_opening/job_opening.py
+++ b/erpnext/hr/doctype/job_opening/job_opening.py
@@ -20,20 +20,33 @@
 	def validate(self):
 		if not self.route:
 			self.route = frappe.scrub(self.job_title).replace('_', '-')
-
-		if self.staffing_plan:
-			self.validate_current_vacancies()
+		self.validate_current_vacancies()
 
 	def validate_current_vacancies(self):
-		current_count = get_current_employee_count(self.designation)
-		current_count+= frappe.db.sql("""select count(*) from `tabJob Opening` \
-						where designation = '{0}' and status='Open'""".format(self.designation))[0][0]
+		if not self.staffing_plan:
+			vacancies = get_active_staffing_plan_and_vacancies(self.company,
+				self.designation, self.department)
+			if vacancies:
+				self.staffing_plan = vacancies[0]
+				self.planned_vacancies = vacancies[1]
+		elif not self.planned_vacancies:
+			planned_vacancies = frappe.db.sql("""
+				select vacancies from `tabStaffing Plan Detail`
+				where parent=%s and designation=%s""", (self.staffing_plan, self.designation))
+			self.planned_vacancies = planned_vacancies[0][0] if planned_vacancies else None
 
-		vacancies = get_active_staffing_plan_and_vacancies(self.company, self.designation, self.department)[1]
-		# set staffing_plan too?
-		if vacancies and vacancies <= current_count:
-			frappe.throw(_("Job Openings for designation {0} already opened or hiring \
-						completed as per Staffing Plan {1}".format(self.designation, self.staffing_plan)))
+		if self.staffing_plan and self.planned_vacancies:
+			staffing_plan_company = frappe.db.get_value("Staffing Plan", self.staffing_plan, "company")
+			lft, rgt = frappe.db.get_value("Company", staffing_plan_company, ["lft", "rgt"])
+
+			current_count = get_current_employee_count(self.designation, staffing_plan_company)
+			current_count+= frappe.db.sql("""select count(*) from `tabJob Opening` \
+				where designation=%s and status='Open'
+					and company in (select name from tabCompany where lft>=%s and rgt<=%s)
+				""", (self.designation, lft, rgt))[0][0]
+
+			if self.planned_vacancies <= current_count:
+				frappe.throw(_("Job Openings for designation {0} and company {1} already opened or hiring completed as per Staffing Plan {2}".format(self.designation, staffing_plan_company, self.staffing_plan)))
 
 	def get_context(self, context):
 		context.parents = [{'route': 'jobs', 'title': _('All Jobs') }]
diff --git a/erpnext/hr/doctype/staffing_plan/staffing_plan.js b/erpnext/hr/doctype/staffing_plan/staffing_plan.js
index 17f03e6..1c1a720 100644
--- a/erpnext/hr/doctype/staffing_plan/staffing_plan.js
+++ b/erpnext/hr/doctype/staffing_plan/staffing_plan.js
@@ -23,11 +23,12 @@
 frappe.ui.form.on('Staffing Plan Detail', {
 	designation: function(frm, cdt, cdn) {
 		let child = locals[cdt][cdn]
-		if(child.designation){
+		if(frm.doc.company && child.designation){
 			frappe.call({
 				"method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_current_employee_count",
 				args: {
-					designation: child.designation
+					designation: child.designation,
+					company: frm.doc.company
 				},
 				callback: function (data) {
 					if(data.message){
diff --git a/erpnext/hr/doctype/staffing_plan/staffing_plan.py b/erpnext/hr/doctype/staffing_plan/staffing_plan.py
index 588e536..37ff5cb 100644
--- a/erpnext/hr/doctype/staffing_plan/staffing_plan.py
+++ b/erpnext/hr/doctype/staffing_plan/staffing_plan.py
@@ -20,36 +20,47 @@
 			overlap = (frappe.db.sql("""select spd.parent \
 				from `tabStaffing Plan Detail` spd join `tabStaffing Plan` sp on spd.parent=sp.name \
 				where spd.designation='{0}' and sp.docstatus=1 \
-				and sp.to_date >= '{1}' and sp.from_date <='{2}'""".format(detail.designation, self.from_date, self.to_date)))
+				and sp.to_date >= '{1}' and sp.from_date <='{2}'"""
+			.format(detail.designation, self.from_date, self.to_date)))
 
 			if overlap and overlap [0][0]:
-				frappe.throw(_("Staffing Plan {0} already exist for designation {1}".format(overlap[0][0], detail.designation)))
+				frappe.throw(_("Staffing Plan {0} already exist for designation {1}"
+					.format(overlap[0][0], detail.designation)))
 
 @frappe.whitelist()
-def get_current_employee_count(designation):
+def get_current_employee_count(designation, company):
 	if not designation:
 		return False
-	employee_count = frappe.db.sql("""select count(*) from `tabEmployee` where \
-							designation = '{0}' and status='Active'""".format(designation))[0][0]
+
+	lft, rgt = frappe.db.get_value("Company", company, ["lft", "rgt"])
+	employee_count = frappe.db.sql("""select count(*) from `tabEmployee`
+		where designation = %s and status='Active'
+			and company in (select name from tabCompany where lft>=%s and rgt<=%s)
+		""", (designation, lft, rgt))[0][0]
 	return employee_count
 
-@frappe.whitelist()
 def get_active_staffing_plan_and_vacancies(company, designation, department=None, date=getdate(nowdate())):
 	if not company or not designation:
 		frappe.throw(_("Please select Company and Designation"))
 
-	conditions = "spd.designation='{0}' and sp.docstatus=1 and \
-	sp.company='{1}'".format(designation, company)
-
+	conditions = ""
 	if(department): #Department is an optional field
-		conditions += " and sp.department='{0}'".format(department)
+		conditions += " and sp.department='{0}'".format(frappe.db.escape(department))
 
 	if(date): #ToDo: Date should be mandatory?
 		conditions += " and '{0}' between sp.from_date and sp.to_date".format(date)
 
-	staffing_plan = frappe.db.sql("""select spd.parent, spd.vacancies \
+	staffing_plan = frappe.db.sql("""
+		select sp.name, spd.vacancies
 		from `tabStaffing Plan Detail` spd join `tabStaffing Plan` sp on spd.parent=sp.name
-		where {0}""".format(conditions))
+		where company=%s and spd.designation=%s and sp.docstatus=1 {0}
+	""".format(conditions), (company, designation))
+
+	if not staffing_plan:
+		parent_company = frappe.db.get_value("Company", company, "parent_company")
+		if parent_company:
+			staffing_plan = get_active_staffing_plan_and_vacancies(parent_company,
+				designation, department, date)
 
 	# Only a signle staffing plan can be active for a designation on given date
-	return staffing_plan[0] if staffing_plan else False
+	return staffing_plan[0] if staffing_plan else None