Staffing plan for group company
This commit is contained in:
parent
247bd94824
commit
3881e98000
@ -2,38 +2,37 @@
|
|||||||
// For license information, please see license.txt
|
// For license information, please see license.txt
|
||||||
|
|
||||||
frappe.ui.form.on('Job Opening', {
|
frappe.ui.form.on('Job Opening', {
|
||||||
designation: function(frm) {
|
designation: function(frm) {
|
||||||
if(frm.doc.designation && frm.doc.company){
|
if(frm.doc.designation && frm.doc.company){
|
||||||
frappe.call({
|
frappe.call({
|
||||||
"method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_active_staffing_plan_and_vacancies",
|
"method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_active_staffing_plan_and_vacancies",
|
||||||
args: {
|
args: {
|
||||||
company: frm.doc.company,
|
company: frm.doc.company,
|
||||||
designation: frm.doc.designation,
|
designation: frm.doc.designation,
|
||||||
department: frm.doc.department,
|
department: frm.doc.department,
|
||||||
date: frappe.datetime.now_date() // ToDo - Date in Job Opening?
|
date: frappe.datetime.now_date() // ToDo - Date in Job Opening?
|
||||||
},
|
},
|
||||||
callback: function (data) {
|
callback: function (data) {
|
||||||
if(data.message){
|
if(data.message){
|
||||||
frm.set_value('staffing_plan', data.message[0]);
|
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{
|
else{
|
||||||
frm.set_value('staffing_plan', "");
|
frm.set_value('staffing_plan', "");
|
||||||
frm.set_value('planned_vacancies', 0);
|
frm.set_value('planned_vacancies', 0);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
company: function(frm) {
|
company: function(frm) {
|
||||||
frm.set_value('designation', "");
|
frm.set_value('designation', "");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -20,20 +20,33 @@ class JobOpening(WebsiteGenerator):
|
|||||||
def validate(self):
|
def validate(self):
|
||||||
if not self.route:
|
if not self.route:
|
||||||
self.route = frappe.scrub(self.job_title).replace('_', '-')
|
self.route = frappe.scrub(self.job_title).replace('_', '-')
|
||||||
|
self.validate_current_vacancies()
|
||||||
if self.staffing_plan:
|
|
||||||
self.validate_current_vacancies()
|
|
||||||
|
|
||||||
def validate_current_vacancies(self):
|
def validate_current_vacancies(self):
|
||||||
current_count = get_current_employee_count(self.designation)
|
if not self.staffing_plan:
|
||||||
current_count+= frappe.db.sql("""select count(*) from `tabJob Opening` \
|
vacancies = get_active_staffing_plan_and_vacancies(self.company,
|
||||||
where designation = '{0}' and status='Open'""".format(self.designation))[0][0]
|
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]
|
if self.staffing_plan and self.planned_vacancies:
|
||||||
# set staffing_plan too?
|
staffing_plan_company = frappe.db.get_value("Staffing Plan", self.staffing_plan, "company")
|
||||||
if vacancies and vacancies <= current_count:
|
lft, rgt = frappe.db.get_value("Company", staffing_plan_company, ["lft", "rgt"])
|
||||||
frappe.throw(_("Job Openings for designation {0} already opened or hiring \
|
|
||||||
completed as per Staffing Plan {1}".format(self.designation, self.staffing_plan)))
|
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):
|
def get_context(self, context):
|
||||||
context.parents = [{'route': 'jobs', 'title': _('All Jobs') }]
|
context.parents = [{'route': 'jobs', 'title': _('All Jobs') }]
|
||||||
|
@ -23,11 +23,12 @@ frappe.ui.form.on('Staffing Plan', {
|
|||||||
frappe.ui.form.on('Staffing Plan Detail', {
|
frappe.ui.form.on('Staffing Plan Detail', {
|
||||||
designation: function(frm, cdt, cdn) {
|
designation: function(frm, cdt, cdn) {
|
||||||
let child = locals[cdt][cdn]
|
let child = locals[cdt][cdn]
|
||||||
if(child.designation){
|
if(frm.doc.company && child.designation){
|
||||||
frappe.call({
|
frappe.call({
|
||||||
"method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_current_employee_count",
|
"method": "erpnext.hr.doctype.staffing_plan.staffing_plan.get_current_employee_count",
|
||||||
args: {
|
args: {
|
||||||
designation: child.designation
|
designation: child.designation,
|
||||||
|
company: frm.doc.company
|
||||||
},
|
},
|
||||||
callback: function (data) {
|
callback: function (data) {
|
||||||
if(data.message){
|
if(data.message){
|
||||||
|
@ -20,36 +20,47 @@ class StaffingPlan(Document):
|
|||||||
overlap = (frappe.db.sql("""select spd.parent \
|
overlap = (frappe.db.sql("""select spd.parent \
|
||||||
from `tabStaffing Plan Detail` spd join `tabStaffing Plan` sp on spd.parent=sp.name \
|
from `tabStaffing Plan Detail` spd join `tabStaffing Plan` sp on spd.parent=sp.name \
|
||||||
where spd.designation='{0}' and sp.docstatus=1 \
|
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]:
|
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()
|
@frappe.whitelist()
|
||||||
def get_current_employee_count(designation):
|
def get_current_employee_count(designation, company):
|
||||||
if not designation:
|
if not designation:
|
||||||
return False
|
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
|
return employee_count
|
||||||
|
|
||||||
@frappe.whitelist()
|
|
||||||
def get_active_staffing_plan_and_vacancies(company, designation, department=None, date=getdate(nowdate())):
|
def get_active_staffing_plan_and_vacancies(company, designation, department=None, date=getdate(nowdate())):
|
||||||
if not company or not designation:
|
if not company or not designation:
|
||||||
frappe.throw(_("Please select Company and Designation"))
|
frappe.throw(_("Please select Company and Designation"))
|
||||||
|
|
||||||
conditions = "spd.designation='{0}' and sp.docstatus=1 and \
|
conditions = ""
|
||||||
sp.company='{1}'".format(designation, company)
|
|
||||||
|
|
||||||
if(department): #Department is an optional field
|
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?
|
if(date): #ToDo: Date should be mandatory?
|
||||||
conditions += " and '{0}' between sp.from_date and sp.to_date".format(date)
|
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
|
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
|
# 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user