Job Opening - get planned opening, validate vacancies by Staffing Plan
diff --git a/erpnext/hr/doctype/job_opening/job_opening.js b/erpnext/hr/doctype/job_opening/job_opening.js
index e69de29..b024310 100644
--- a/erpnext/hr/doctype/job_opening/job_opening.js
+++ b/erpnext/hr/doctype/job_opening/job_opening.js
@@ -0,0 +1,39 @@
+// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and contributors
+// For license information, please see license.txt
+
+frappe.ui.form.on('Job Opening', {
+ 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?
+ },
+ callback: function (data) {
+ if(data.message){
+ frm.set_value('staffing_plan', data.message[0]);
+ 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);
+ }
+ },
+ company: function(frm) {
+ frm.set_value('designation', "");
+ }
+});
diff --git a/erpnext/hr/doctype/job_opening/job_opening.json b/erpnext/hr/doctype/job_opening/job_opening.json
index de15114..a877119 100644
--- a/erpnext/hr/doctype/job_opening/job_opening.json
+++ b/erpnext/hr/doctype/job_opening/job_opening.json
@@ -224,7 +224,38 @@
"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,
+ "search_index": 0,
+ "set_only_once": 0,
+ "translatable": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "fieldname": "planned_vacancies",
+ "fieldtype": "Int",
+ "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": "Planned number of Positions",
+ "length": 0,
+ "no_copy": 0,
+ "permlevel": 0,
+ "precision": "",
+ "print_hide": 0,
+ "print_hide_if_no_value": 0,
+ "read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
@@ -369,7 +400,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
- "modified": "2018-04-13 18:52:56.109392",
+ "modified": "2018-04-18 19:27:15.004385",
"modified_by": "Administrator",
"module": "HR",
"name": "Job Opening",
diff --git a/erpnext/hr/doctype/job_opening/job_opening.py b/erpnext/hr/doctype/job_opening/job_opening.py
index 60c911a..d3d662a 100644
--- a/erpnext/hr/doctype/job_opening/job_opening.py
+++ b/erpnext/hr/doctype/job_opening/job_opening.py
@@ -8,6 +8,7 @@
from frappe.website.website_generator import WebsiteGenerator
from frappe import _
+from erpnext.hr.doctype.staffing_plan.staffing_plan import get_current_employee_count, get_active_staffing_plan_and_vacancies
class JobOpening(WebsiteGenerator):
website = frappe._dict(
@@ -20,6 +21,20 @@
if not self.route:
self.route = frappe.scrub(self.job_title).replace('_', '-')
+ if self.staffing_plan:
+ 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]
+
+ 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)))
+
def get_context(self, context):
context.parents = [{'route': 'jobs', 'title': _('All Jobs') }]