From f220e89d9f9848c318a58543b468a487a9f2d7bb Mon Sep 17 00:00:00 2001 From: Ranjith Date: Mon, 7 May 2018 13:58:54 +0530 Subject: [PATCH] Job Opening - get planned opening, validate vacancies by Staffing Plan --- erpnext/hr/doctype/job_opening/job_opening.js | 39 +++++++++++++++++++ .../hr/doctype/job_opening/job_opening.json | 35 ++++++++++++++++- erpnext/hr/doctype/job_opening/job_opening.py | 15 +++++++ 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/erpnext/hr/doctype/job_opening/job_opening.js b/erpnext/hr/doctype/job_opening/job_opening.js index e69de29bb2d..b0243103391 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 de15114a43c..a8771198090 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 60c911a0161..d3d662a743c 100644 --- a/erpnext/hr/doctype/job_opening/job_opening.py +++ b/erpnext/hr/doctype/job_opening/job_opening.py @@ -8,6 +8,7 @@ import frappe 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 @@ class JobOpening(WebsiteGenerator): 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') }]