You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

270 lines
9.0 KiB

  1. # Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
  2. # License: GNU General Public License v3. See license.txt
  3. import unittest
  4. from datetime import timedelta
  5. import frappe
  6. from frappe.utils import add_months, getdate
  7. from erpnext.setup.doctype.employee.test_employee import make_employee
  8. from hrms.controllers.employee_reminders import send_holidays_reminder_in_advance
  9. from hrms.hr.doctype.hr_settings.hr_settings import set_proceed_with_frequency_change
  10. from hrms.hr.utils import get_holidays_for_employee
  11. class TestEmployeeReminders(unittest.TestCase):
  12. @classmethod
  13. def setUpClass(cls):
  14. from erpnext.setup.doctype.holiday_list.test_holiday_list import make_holiday_list
  15. # Create a test holiday list
  16. test_holiday_dates = cls.get_test_holiday_dates()
  17. test_holiday_list = make_holiday_list(
  18. "TestHolidayRemindersList",
  19. holiday_dates=[
  20. {"holiday_date": test_holiday_dates[0], "description": "test holiday1"},
  21. {"holiday_date": test_holiday_dates[1], "description": "test holiday2"},
  22. {"holiday_date": test_holiday_dates[2], "description": "test holiday3", "weekly_off": 1},
  23. {"holiday_date": test_holiday_dates[3], "description": "test holiday4"},
  24. {"holiday_date": test_holiday_dates[4], "description": "test holiday5"},
  25. {"holiday_date": test_holiday_dates[5], "description": "test holiday6"},
  26. ],
  27. from_date=getdate() - timedelta(days=10),
  28. to_date=getdate() + timedelta(weeks=5),
  29. )
  30. # Create a test employee
  31. test_employee = frappe.get_doc(
  32. "Employee", make_employee("test@gopher.io", company="_Test Company")
  33. )
  34. # Attach the holiday list to employee
  35. test_employee.holiday_list = test_holiday_list.name
  36. test_employee.save()
  37. # Attach to class
  38. cls.test_employee = test_employee
  39. cls.test_holiday_dates = test_holiday_dates
  40. # Employee without holidays in this month/week
  41. test_employee_2 = make_employee("test@empwithoutholiday.io", company="_Test Company")
  42. test_employee_2 = frappe.get_doc("Employee", test_employee_2)
  43. test_holiday_list = make_holiday_list(
  44. "TestHolidayRemindersList2",
  45. holiday_dates=[
  46. {"holiday_date": add_months(getdate(), 1), "description": "test holiday1"},
  47. ],
  48. from_date=add_months(getdate(), -2),
  49. to_date=add_months(getdate(), 2),
  50. )
  51. test_employee_2.holiday_list = test_holiday_list.name
  52. test_employee_2.save()
  53. cls.test_employee_2 = test_employee_2
  54. cls.holiday_list_2 = test_holiday_list
  55. @classmethod
  56. def get_test_holiday_dates(cls):
  57. today_date = getdate()
  58. return [
  59. today_date,
  60. today_date - timedelta(days=4),
  61. today_date - timedelta(days=3),
  62. today_date + timedelta(days=1),
  63. today_date + timedelta(days=3),
  64. today_date + timedelta(weeks=3),
  65. ]
  66. def setUp(self):
  67. # Clear Email Queue
  68. frappe.db.sql("delete from `tabEmail Queue`")
  69. frappe.db.sql("delete from `tabEmail Queue Recipient`")
  70. def test_is_holiday(self):
  71. from erpnext.setup.doctype.employee.employee import is_holiday
  72. self.assertTrue(is_holiday(self.test_employee.name))
  73. self.assertTrue(is_holiday(self.test_employee.name, date=self.test_holiday_dates[1]))
  74. self.assertFalse(is_holiday(self.test_employee.name, date=getdate() - timedelta(days=1)))
  75. # Test weekly_off holidays
  76. self.assertTrue(is_holiday(self.test_employee.name, date=self.test_holiday_dates[2]))
  77. self.assertFalse(
  78. is_holiday(self.test_employee.name, date=self.test_holiday_dates[2], only_non_weekly=True)
  79. )
  80. # Test with descriptions
  81. has_holiday, descriptions = is_holiday(self.test_employee.name, with_description=True)
  82. self.assertTrue(has_holiday)
  83. self.assertTrue("test holiday1" in descriptions)
  84. def test_birthday_reminders(self):
  85. employee = frappe.get_doc(
  86. "Employee", frappe.db.sql_list("select name from tabEmployee limit 1")[0]
  87. )
  88. employee.date_of_birth = "1992" + frappe.utils.nowdate()[4:]
  89. employee.company_email = "test@example.com"
  90. employee.company = "_Test Company"
  91. employee.save()
  92. from hrms.controllers.employee_reminders import (
  93. get_employees_who_are_born_today,
  94. send_birthday_reminders,
  95. )
  96. employees_born_today = get_employees_who_are_born_today()
  97. self.assertTrue(employees_born_today.get("_Test Company"))
  98. hr_settings = frappe.get_doc("HR Settings", "HR Settings")
  99. hr_settings.send_birthday_reminders = 1
  100. hr_settings.save()
  101. send_birthday_reminders()
  102. email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
  103. self.assertTrue("Subject: Birthday Reminder" in email_queue[0].message)
  104. def test_work_anniversary_reminders(self):
  105. from hrms.controllers.employee_reminders import (
  106. get_employees_having_an_event_today,
  107. send_work_anniversary_reminders,
  108. )
  109. emp = make_employee(
  110. "test_emp_work_anniversary@gmail.com",
  111. company="_Test Company",
  112. date_of_joining=frappe.utils.add_years(getdate(), -2),
  113. )
  114. employees_having_work_anniversary = get_employees_having_an_event_today("work_anniversary")
  115. employees = employees_having_work_anniversary.get("_Test Company") or []
  116. user_ids = []
  117. for entry in employees:
  118. user_ids.append(entry.user_id)
  119. self.assertTrue("test_emp_work_anniversary@gmail.com" in user_ids)
  120. hr_settings = frappe.get_doc("HR Settings", "HR Settings")
  121. hr_settings.send_work_anniversary_reminders = 1
  122. hr_settings.save()
  123. send_work_anniversary_reminders()
  124. email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
  125. self.assertTrue("Subject: Work Anniversary Reminder" in email_queue[0].message)
  126. def test_work_anniversary_reminder_not_sent_for_0_years(self):
  127. make_employee(
  128. "test_work_anniversary_2@gmail.com",
  129. date_of_joining=getdate(),
  130. company="_Test Company",
  131. )
  132. from hrms.controllers.employee_reminders import get_employees_having_an_event_today
  133. employees_having_work_anniversary = get_employees_having_an_event_today("work_anniversary")
  134. employees = employees_having_work_anniversary.get("_Test Company") or []
  135. user_ids = []
  136. for entry in employees:
  137. user_ids.append(entry.user_id)
  138. self.assertTrue("test_work_anniversary_2@gmail.com" not in user_ids)
  139. def test_send_holidays_reminder_in_advance(self):
  140. setup_hr_settings("Weekly")
  141. holidays = get_holidays_for_employee(
  142. self.test_employee.get("name"),
  143. getdate(),
  144. getdate() + timedelta(days=3),
  145. only_non_weekly=True,
  146. raise_exception=False,
  147. )
  148. send_holidays_reminder_in_advance(self.test_employee.get("name"), holidays)
  149. email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
  150. self.assertEqual(len(email_queue), 1)
  151. self.assertTrue("Holidays this Week." in email_queue[0].message)
  152. def test_advance_holiday_reminders_monthly(self):
  153. from hrms.controllers.employee_reminders import send_reminders_in_advance_monthly
  154. setup_hr_settings("Monthly")
  155. # disable emp 2, set same holiday list
  156. frappe.db.set_value(
  157. "Employee",
  158. self.test_employee_2.name,
  159. {"status": "Left", "holiday_list": self.test_employee.holiday_list},
  160. )
  161. send_reminders_in_advance_monthly()
  162. email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
  163. self.assertTrue(len(email_queue) > 0)
  164. # even though emp 2 has holiday, non-active employees should not be recipients
  165. recipients = frappe.db.get_all("Email Queue Recipient", pluck="recipient")
  166. self.assertTrue(self.test_employee_2.user_id not in recipients)
  167. # teardown: enable emp 2
  168. frappe.db.set_value(
  169. "Employee",
  170. self.test_employee_2.name,
  171. {"status": "Active", "holiday_list": self.holiday_list_2.name},
  172. )
  173. def test_advance_holiday_reminders_weekly(self):
  174. from hrms.controllers.employee_reminders import send_reminders_in_advance_weekly
  175. setup_hr_settings("Weekly")
  176. # disable emp 2, set same holiday list
  177. frappe.db.set_value(
  178. "Employee",
  179. self.test_employee_2.name,
  180. {"status": "Left", "holiday_list": self.test_employee.holiday_list},
  181. )
  182. send_reminders_in_advance_weekly()
  183. email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
  184. self.assertTrue(len(email_queue) > 0)
  185. # even though emp 2 has holiday, non-active employees should not be recipients
  186. recipients = frappe.db.get_all("Email Queue Recipient", pluck="recipient")
  187. self.assertTrue(self.test_employee_2.user_id not in recipients)
  188. # teardown: enable emp 2
  189. frappe.db.set_value(
  190. "Employee",
  191. self.test_employee_2.name,
  192. {"status": "Active", "holiday_list": self.holiday_list_2.name},
  193. )
  194. def test_reminder_not_sent_if_no_holdays(self):
  195. setup_hr_settings("Monthly")
  196. # reminder not sent if there are no holidays
  197. holidays = get_holidays_for_employee(
  198. self.test_employee_2.get("name"),
  199. getdate(),
  200. getdate() + timedelta(days=3),
  201. only_non_weekly=True,
  202. raise_exception=False,
  203. )
  204. send_holidays_reminder_in_advance(self.test_employee_2.get("name"), holidays)
  205. email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True)
  206. self.assertEqual(len(email_queue), 0)
  207. def setup_hr_settings(frequency=None):
  208. # Get HR settings and enable advance holiday reminders
  209. hr_settings = frappe.get_doc("HR Settings", "HR Settings")
  210. hr_settings.send_holiday_reminders = 1
  211. set_proceed_with_frequency_change()
  212. hr_settings.frequency = frequency or "Weekly"
  213. hr_settings.save()