brotherton-erpnext/erpnext/hr/report/employee_exits/employee_exits.py
2022-03-28 18:52:46 +05:30

236 lines
6.2 KiB
Python

# Copyright (c) 2013, Frappe Technologies Pvt. Ltd. and contributors
# License: MIT. See LICENSE
import frappe
from frappe import _
from frappe.query_builder import Order
from frappe.utils import getdate
def execute(filters=None):
columns = get_columns()
data = get_data(filters)
chart = get_chart_data(data)
report_summary = get_report_summary(data)
return columns, data, None, chart, report_summary
def get_columns():
return [
{
"label": _("Employee"),
"fieldname": "employee",
"fieldtype": "Link",
"options": "Employee",
"width": 150,
},
{"label": _("Employee Name"), "fieldname": "employee_name", "fieldtype": "Data", "width": 150},
{
"label": _("Date of Joining"),
"fieldname": "date_of_joining",
"fieldtype": "Date",
"width": 120,
},
{"label": _("Relieving Date"), "fieldname": "relieving_date", "fieldtype": "Date", "width": 120},
{
"label": _("Exit Interview"),
"fieldname": "exit_interview",
"fieldtype": "Link",
"options": "Exit Interview",
"width": 150,
},
{
"label": _("Interview Status"),
"fieldname": "interview_status",
"fieldtype": "Data",
"width": 130,
},
{
"label": _("Final Decision"),
"fieldname": "employee_status",
"fieldtype": "Data",
"width": 150,
},
{
"label": _("Full and Final Statement"),
"fieldname": "full_and_final_statement",
"fieldtype": "Link",
"options": "Full and Final Statement",
"width": 180,
},
{
"label": _("Department"),
"fieldname": "department",
"fieldtype": "Link",
"options": "Department",
"width": 120,
},
{
"label": _("Designation"),
"fieldname": "designation",
"fieldtype": "Link",
"options": "Designation",
"width": 120,
},
{
"label": _("Reports To"),
"fieldname": "reports_to",
"fieldtype": "Link",
"options": "Employee",
"width": 120,
},
]
def get_data(filters):
employee = frappe.qb.DocType("Employee")
interview = frappe.qb.DocType("Exit Interview")
fnf = frappe.qb.DocType("Full and Final Statement")
query = (
frappe.qb.from_(employee)
.left_join(interview)
.on(interview.employee == employee.name)
.left_join(fnf)
.on(fnf.employee == employee.name)
.select(
employee.name.as_("employee"),
employee.employee_name.as_("employee_name"),
employee.date_of_joining.as_("date_of_joining"),
employee.relieving_date.as_("relieving_date"),
employee.department.as_("department"),
employee.designation.as_("designation"),
employee.reports_to.as_("reports_to"),
interview.name.as_("exit_interview"),
interview.status.as_("interview_status"),
interview.employee_status.as_("employee_status"),
interview.reference_document_name.as_("questionnaire"),
fnf.name.as_("full_and_final_statement"),
)
.distinct()
.where(
((employee.relieving_date.isnotnull()) | (employee.relieving_date != ""))
& ((interview.name.isnull()) | ((interview.name.isnotnull()) & (interview.docstatus != 2)))
& ((fnf.name.isnull()) | ((fnf.name.isnotnull()) & (fnf.docstatus != 2)))
)
.orderby(employee.relieving_date, order=Order.asc)
)
query = get_conditions(filters, query, employee, interview, fnf)
result = query.run(as_dict=True)
return result
def get_conditions(filters, query, employee, interview, fnf):
if filters.get("from_date") and filters.get("to_date"):
query = query.where(
employee.relieving_date[getdate(filters.get("from_date")) : getdate(filters.get("to_date"))]
)
elif filters.get("from_date"):
query = query.where(employee.relieving_date >= filters.get("from_date"))
elif filters.get("to_date"):
query = query.where(employee.relieving_date <= filters.get("to_date"))
if filters.get("company"):
query = query.where(employee.company == filters.get("company"))
if filters.get("department"):
query = query.where(employee.department == filters.get("department"))
if filters.get("designation"):
query = query.where(employee.designation == filters.get("designation"))
if filters.get("employee"):
query = query.where(employee.name == filters.get("employee"))
if filters.get("reports_to"):
query = query.where(employee.reports_to == filters.get("reports_to"))
if filters.get("interview_status"):
query = query.where(interview.status == filters.get("interview_status"))
if filters.get("final_decision"):
query = query.where(interview.employee_status == filters.get("final_decision"))
if filters.get("exit_interview_pending"):
query = query.where((interview.name == "") | (interview.name.isnull()))
if filters.get("questionnaire_pending"):
query = query.where(
(interview.reference_document_name == "") | (interview.reference_document_name.isnull())
)
if filters.get("fnf_pending"):
query = query.where((fnf.name == "") | (fnf.name.isnull()))
return query
def get_chart_data(data):
if not data:
return None
retained = 0
exit_confirmed = 0
pending = 0
for entry in data:
if entry.employee_status == "Employee Retained":
retained += 1
elif entry.employee_status == "Exit Confirmed":
exit_confirmed += 1
else:
pending += 1
chart = {
"data": {
"labels": [_("Retained"), _("Exit Confirmed"), _("Decision Pending")],
"datasets": [{"name": _("Employee Status"), "values": [retained, exit_confirmed, pending]}],
},
"type": "donut",
"colors": ["green", "red", "blue"],
}
return chart
def get_report_summary(data):
if not data:
return None
total_resignations = len(data)
interviews_pending = len([entry.name for entry in data if not entry.exit_interview])
fnf_pending = len([entry.name for entry in data if not entry.full_and_final_statement])
questionnaires_pending = len([entry.name for entry in data if not entry.questionnaire])
return [
{
"value": total_resignations,
"label": _("Total Resignations"),
"indicator": "Red" if total_resignations > 0 else "Green",
"datatype": "Int",
},
{
"value": interviews_pending,
"label": _("Pending Interviews"),
"indicator": "Blue" if interviews_pending > 0 else "Green",
"datatype": "Int",
},
{
"value": fnf_pending,
"label": _("Pending FnF"),
"indicator": "Blue" if fnf_pending > 0 else "Green",
"datatype": "Int",
},
{
"value": questionnaires_pending,
"label": _("Pending Questionnaires"),
"indicator": "Blue" if questionnaires_pending > 0 else "Green",
"datatype": "Int",
},
]