blob: c06fb5930dcbb0441851f1354303b39a31678cc4 [file] [log] [blame]
Rucha Mahabal357657f2021-06-24 13:00:50 +05301# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
2# License: GNU General Public License v3. See license.txt
3
Rucha Mahabal357657f2021-06-24 13:00:50 +05304import frappe
5from frappe import _
6from frappe.desk.form import assign_to
7from frappe.model.document import Document
Chillar Anand915b3432021-09-02 16:44:59 +05308from frappe.utils import add_days, flt, unique
9
Rucha Mahabal3fe2ef62022-06-15 12:43:45 +053010from erpnext.setup.doctype.employee.employee import get_holiday_list_for_employee
11from erpnext.setup.doctype.holiday_list.holiday_list import is_holiday
Chillar Anand915b3432021-09-02 16:44:59 +053012
Rucha Mahabal357657f2021-06-24 13:00:50 +053013
14class EmployeeBoardingController(Document):
Ankush Menat494bd9e2022-03-28 18:52:46 +053015 """
16 Create the project and the task for the boarding process
17 Assign to the concerned person and roles as per the onboarding/separation template
18 """
19
Rucha Mahabal357657f2021-06-24 13:00:50 +053020 def validate(self):
21 # remove the task if linked before submitting the form
22 if self.amended_from:
23 for activity in self.activities:
Ankush Menat494bd9e2022-03-28 18:52:46 +053024 activity.task = ""
Rucha Mahabal357657f2021-06-24 13:00:50 +053025
26 def on_submit(self):
27 # create the project for the given employee onboarding
Ankush Menat494bd9e2022-03-28 18:52:46 +053028 project_name = _(self.doctype) + " : "
29 if self.doctype == "Employee Onboarding":
Rucha Mahabal357657f2021-06-24 13:00:50 +053030 project_name += self.job_applicant
31 else:
32 project_name += self.employee
33
Ankush Menat494bd9e2022-03-28 18:52:46 +053034 project = frappe.get_doc(
35 {
36 "doctype": "Project",
37 "project_name": project_name,
38 "expected_start_date": self.date_of_joining
39 if self.doctype == "Employee Onboarding"
40 else self.resignation_letter_date,
41 "department": self.department,
42 "company": self.company,
43 }
44 ).insert(ignore_permissions=True, ignore_mandatory=True)
Rucha Mahabal357657f2021-06-24 13:00:50 +053045
Ankush Menat494bd9e2022-03-28 18:52:46 +053046 self.db_set("project", project.name)
47 self.db_set("boarding_status", "Pending")
Rucha Mahabal357657f2021-06-24 13:00:50 +053048 self.reload()
49 self.create_task_and_notify_user()
50
51 def create_task_and_notify_user(self):
52 # create the task for the given project and assign to the concerned person
Rucha Mahabal71b7c632021-08-27 11:12:24 +053053 holiday_list = self.get_holiday_list()
54
Rucha Mahabal357657f2021-06-24 13:00:50 +053055 for activity in self.activities:
56 if activity.task:
57 continue
58
Rucha Mahabal71b7c632021-08-27 11:12:24 +053059 dates = self.get_task_dates(activity, holiday_list)
60
Ankush Menat494bd9e2022-03-28 18:52:46 +053061 task = frappe.get_doc(
62 {
63 "doctype": "Task",
64 "project": self.project,
65 "subject": activity.activity_name + " : " + self.employee_name,
66 "description": activity.description,
67 "department": self.department,
68 "company": self.company,
69 "task_weight": activity.task_weight,
70 "exp_start_date": dates[0],
71 "exp_end_date": dates[1],
72 }
73 ).insert(ignore_permissions=True)
74 activity.db_set("task", task.name)
Rucha Mahabal357657f2021-06-24 13:00:50 +053075
76 users = [activity.user] if activity.user else []
77 if activity.role:
Ankush Menat494bd9e2022-03-28 18:52:46 +053078 user_list = frappe.db.sql_list(
79 """
Rucha Mahabal357657f2021-06-24 13:00:50 +053080 SELECT
81 DISTINCT(has_role.parent)
82 FROM
83 `tabHas Role` has_role
84 LEFT JOIN `tabUser` user
85 ON has_role.parent = user.name
86 WHERE
87 has_role.parenttype = 'User'
88 AND user.enabled = 1
89 AND has_role.role = %s
Ankush Menat494bd9e2022-03-28 18:52:46 +053090 """,
91 activity.role,
92 )
Rucha Mahabal357657f2021-06-24 13:00:50 +053093 users = unique(users + user_list)
94
Ankush Menat494bd9e2022-03-28 18:52:46 +053095 if "Administrator" in users:
96 users.remove("Administrator")
Rucha Mahabal357657f2021-06-24 13:00:50 +053097
98 # assign the task the users
99 if users:
100 self.assign_task_to_users(task, users)
101
Rucha Mahabal71b7c632021-08-27 11:12:24 +0530102 def get_holiday_list(self):
Ankush Menat494bd9e2022-03-28 18:52:46 +0530103 if self.doctype == "Employee Separation":
Rucha Mahabal71b7c632021-08-27 11:12:24 +0530104 return get_holiday_list_for_employee(self.employee)
105 else:
106 if self.employee:
107 return get_holiday_list_for_employee(self.employee)
108 else:
109 if not self.holiday_list:
Ankush Menat494bd9e2022-03-28 18:52:46 +0530110 frappe.throw(_("Please set the Holiday List."), frappe.MandatoryError)
Rucha Mahabal71b7c632021-08-27 11:12:24 +0530111 else:
112 return self.holiday_list
113
114 def get_task_dates(self, activity, holiday_list):
115 start_date = end_date = None
116
Rucha Mahabal47383672022-02-21 22:54:46 +0530117 if activity.begin_on is not None:
Rucha Mahabal71b7c632021-08-27 11:12:24 +0530118 start_date = add_days(self.boarding_begins_on, activity.begin_on)
119 start_date = self.update_if_holiday(start_date, holiday_list)
120
Rucha Mahabal47383672022-02-21 22:54:46 +0530121 if activity.duration is not None:
Rucha Mahabal71b7c632021-08-27 11:12:24 +0530122 end_date = add_days(self.boarding_begins_on, activity.begin_on + activity.duration)
123 end_date = self.update_if_holiday(end_date, holiday_list)
124
125 return [start_date, end_date]
126
127 def update_if_holiday(self, date, holiday_list):
128 while is_holiday(holiday_list, date):
129 date = add_days(date, 1)
130 return date
131
Rucha Mahabal357657f2021-06-24 13:00:50 +0530132 def assign_task_to_users(self, task, users):
133 for user in users:
134 args = {
Ankush Menat494bd9e2022-03-28 18:52:46 +0530135 "assign_to": [user],
136 "doctype": task.doctype,
137 "name": task.name,
138 "description": task.description or task.subject,
139 "notify": self.notify_users_by_email,
Rucha Mahabal357657f2021-06-24 13:00:50 +0530140 }
141 assign_to.add(args)
142
143 def on_cancel(self):
144 # delete task project
Rucha Mahabal36882f32022-01-29 15:27:36 +0530145 project = self.project
Ankush Menat494bd9e2022-03-28 18:52:46 +0530146 for task in frappe.get_all("Task", filters={"project": project}):
147 frappe.delete_doc("Task", task.name, force=1)
148 frappe.delete_doc("Project", project, force=1)
149 self.db_set("project", "")
Rucha Mahabal357657f2021-06-24 13:00:50 +0530150 for activity in self.activities:
Ankush Menat494bd9e2022-03-28 18:52:46 +0530151 activity.db_set("task", "")
Rucha Mahabal357657f2021-06-24 13:00:50 +0530152
Ankush Menat494bd9e2022-03-28 18:52:46 +0530153 frappe.msgprint(
154 _("Linked Project {} and Tasks deleted.").format(project), alert=True, indicator="blue"
155 )
Rucha Mahabal36882f32022-01-29 15:27:36 +0530156
Rucha Mahabal357657f2021-06-24 13:00:50 +0530157
158@frappe.whitelist()
159def get_onboarding_details(parent, parenttype):
Ankush Menat494bd9e2022-03-28 18:52:46 +0530160 return frappe.get_all(
161 "Employee Boarding Activity",
162 fields=[
163 "activity_name",
164 "role",
165 "user",
166 "required_for_employee_creation",
167 "description",
168 "task_weight",
169 "begin_on",
170 "duration",
171 ],
172 filters={"parent": parent, "parenttype": parenttype},
173 order_by="idx",
174 )
Rucha Mahabal357657f2021-06-24 13:00:50 +0530175
176
177def update_employee_boarding_status(project):
Ankush Menat494bd9e2022-03-28 18:52:46 +0530178 employee_onboarding = frappe.db.exists("Employee Onboarding", {"project": project.name})
179 employee_separation = frappe.db.exists("Employee Separation", {"project": project.name})
Rucha Mahabal357657f2021-06-24 13:00:50 +0530180
181 if not (employee_onboarding or employee_separation):
182 return
183
Ankush Menat494bd9e2022-03-28 18:52:46 +0530184 status = "Pending"
Rucha Mahabal357657f2021-06-24 13:00:50 +0530185 if flt(project.percent_complete) > 0.0 and flt(project.percent_complete) < 100.0:
Ankush Menat494bd9e2022-03-28 18:52:46 +0530186 status = "In Process"
Rucha Mahabal357657f2021-06-24 13:00:50 +0530187 elif flt(project.percent_complete) == 100.0:
Ankush Menat494bd9e2022-03-28 18:52:46 +0530188 status = "Completed"
Rucha Mahabal357657f2021-06-24 13:00:50 +0530189
190 if employee_onboarding:
Ankush Menat494bd9e2022-03-28 18:52:46 +0530191 frappe.db.set_value("Employee Onboarding", employee_onboarding, "boarding_status", status)
Rucha Mahabal357657f2021-06-24 13:00:50 +0530192 elif employee_separation:
Ankush Menat494bd9e2022-03-28 18:52:46 +0530193 frappe.db.set_value("Employee Separation", employee_separation, "boarding_status", status)