Browse Source
* feat: Add reminders section to HR Settings * refactor: Extract generic function for getting Employees * feat: Employee Work Anniversary Reminder * feat: Daily Holiday Reminder * fix: Unnecessary params and replace [] with .get() * test: Daily Holiday Reminders * test: is_holiday basic tests * refactor: Move employee reminders code to separate module * feat: Add advance reminder to HR settings * feat: Advance Holiday Reminders * refactor: get_holidays_for_employee * feat: Email holiday reminders in advance + tests * fix: Remove unused import * refactor: HR Setting Reminder Section * refactor: Remove Daily Holiday Reminders feat * feat: Reminder miss warning * fix: Failing test and function name change * chore: Add patch for field rename * chore: Rename frequency label * fix: Failing patch test * fix: sider and removed description of fields * fix: email alignment Co-authored-by: pateljannat <pateljannat2308@gmail.com> Co-authored-by: Jannat Patel <31363128+pateljannat@users.noreply.github.com> (cherry picked from commit 24b2a315818d08ad4cb03347ccf5297df916a5ac) Co-authored-by: Mohammad Hussain Nagaria <34810212+NagariaHussain@users.noreply.github.com> Co-authored-by: Jannat Patel <31363128+pateljannat@users.noreply.github.com>develop
Frappe PR Bot
3 years ago
committed by
GitHub
18 changed files with 691 additions and 168 deletions
@ -0,0 +1,247 @@ |
|||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# License: GNU General Public License v3. See license.txt |
|||
|
|||
import frappe |
|||
from frappe import _ |
|||
from frappe.utils import comma_sep, getdate, today, add_months, add_days |
|||
from erpnext.hr.doctype.employee.employee import get_all_employee_emails, get_employee_email |
|||
from erpnext.hr.utils import get_holidays_for_employee |
|||
|
|||
# ----------------- |
|||
# HOLIDAY REMINDERS |
|||
# ----------------- |
|||
def send_reminders_in_advance_weekly(): |
|||
to_send_in_advance = int(frappe.db.get_single_value("HR Settings", "send_holiday_reminders") or 1) |
|||
frequency = frappe.db.get_single_value("HR Settings", "frequency") |
|||
if not (to_send_in_advance and frequency == "Weekly"): |
|||
return |
|||
|
|||
send_advance_holiday_reminders("Weekly") |
|||
|
|||
def send_reminders_in_advance_monthly(): |
|||
to_send_in_advance = int(frappe.db.get_single_value("HR Settings", "send_holiday_reminders") or 1) |
|||
frequency = frappe.db.get_single_value("HR Settings", "frequency") |
|||
if not (to_send_in_advance and frequency == "Monthly"): |
|||
return |
|||
|
|||
send_advance_holiday_reminders("Monthly") |
|||
|
|||
def send_advance_holiday_reminders(frequency): |
|||
"""Send Holiday Reminders in Advance to Employees |
|||
`frequency` (str): 'Weekly' or 'Monthly' |
|||
""" |
|||
if frequency == "Weekly": |
|||
start_date = getdate() |
|||
end_date = add_days(getdate(), 7) |
|||
elif frequency == "Monthly": |
|||
# Sent on 1st of every month |
|||
start_date = getdate() |
|||
end_date = add_months(getdate(), 1) |
|||
else: |
|||
return |
|||
|
|||
employees = frappe.db.get_all('Employee', pluck='name') |
|||
for employee in employees: |
|||
holidays = get_holidays_for_employee( |
|||
employee, |
|||
start_date, end_date, |
|||
only_non_weekly=True, |
|||
raise_exception=False |
|||
) |
|||
|
|||
if not (holidays is None): |
|||
send_holidays_reminder_in_advance(employee, holidays) |
|||
|
|||
def send_holidays_reminder_in_advance(employee, holidays): |
|||
employee_doc = frappe.get_doc('Employee', employee) |
|||
employee_email = get_employee_email(employee_doc) |
|||
frequency = frappe.db.get_single_value("HR Settings", "frequency") |
|||
|
|||
email_header = _("Holidays this Month.") if frequency == "Monthly" else _("Holidays this Week.") |
|||
frappe.sendmail( |
|||
recipients=[employee_email], |
|||
subject=_("Upcoming Holidays Reminder"), |
|||
template="holiday_reminder", |
|||
args=dict( |
|||
reminder_text=_("Hey {}! This email is to remind you about the upcoming holidays.").format(employee_doc.get('first_name')), |
|||
message=_("Below is the list of upcoming holidays for you:"), |
|||
advance_holiday_reminder=True, |
|||
holidays=holidays, |
|||
frequency=frequency[:-2] |
|||
), |
|||
header=email_header |
|||
) |
|||
|
|||
# ------------------ |
|||
# BIRTHDAY REMINDERS |
|||
# ------------------ |
|||
def send_birthday_reminders(): |
|||
"""Send Employee birthday reminders if no 'Stop Birthday Reminders' is not set.""" |
|||
to_send = int(frappe.db.get_single_value("HR Settings", "send_birthday_reminders") or 1) |
|||
if not to_send: |
|||
return |
|||
|
|||
employees_born_today = get_employees_who_are_born_today() |
|||
|
|||
for company, birthday_persons in employees_born_today.items(): |
|||
employee_emails = get_all_employee_emails(company) |
|||
birthday_person_emails = [get_employee_email(doc) for doc in birthday_persons] |
|||
recipients = list(set(employee_emails) - set(birthday_person_emails)) |
|||
|
|||
reminder_text, message = get_birthday_reminder_text_and_message(birthday_persons) |
|||
send_birthday_reminder(recipients, reminder_text, birthday_persons, message) |
|||
|
|||
if len(birthday_persons) > 1: |
|||
# special email for people sharing birthdays |
|||
for person in birthday_persons: |
|||
person_email = person["user_id"] or person["personal_email"] or person["company_email"] |
|||
others = [d for d in birthday_persons if d != person] |
|||
reminder_text, message = get_birthday_reminder_text_and_message(others) |
|||
send_birthday_reminder(person_email, reminder_text, others, message) |
|||
|
|||
def get_birthday_reminder_text_and_message(birthday_persons): |
|||
if len(birthday_persons) == 1: |
|||
birthday_person_text = birthday_persons[0]['name'] |
|||
else: |
|||
# converts ["Jim", "Rim", "Dim"] to Jim, Rim & Dim |
|||
person_names = [d['name'] for d in birthday_persons] |
|||
birthday_person_text = comma_sep(person_names, frappe._("{0} & {1}"), False) |
|||
|
|||
reminder_text = _("Today is {0}'s birthday 🎉").format(birthday_person_text) |
|||
message = _("A friendly reminder of an important date for our team.") |
|||
message += "<br>" |
|||
message += _("Everyone, let’s congratulate {0} on their birthday.").format(birthday_person_text) |
|||
|
|||
return reminder_text, message |
|||
|
|||
def send_birthday_reminder(recipients, reminder_text, birthday_persons, message): |
|||
frappe.sendmail( |
|||
recipients=recipients, |
|||
subject=_("Birthday Reminder"), |
|||
template="birthday_reminder", |
|||
args=dict( |
|||
reminder_text=reminder_text, |
|||
birthday_persons=birthday_persons, |
|||
message=message, |
|||
), |
|||
header=_("Birthday Reminder 🎂") |
|||
) |
|||
|
|||
def get_employees_who_are_born_today(): |
|||
"""Get all employee born today & group them based on their company""" |
|||
return get_employees_having_an_event_today("birthday") |
|||
|
|||
def get_employees_having_an_event_today(event_type): |
|||
"""Get all employee who have `event_type` today |
|||
& group them based on their company. `event_type` |
|||
can be `birthday` or `work_anniversary`""" |
|||
|
|||
from collections import defaultdict |
|||
|
|||
# Set column based on event type |
|||
if event_type == 'birthday': |
|||
condition_column = 'date_of_birth' |
|||
elif event_type == 'work_anniversary': |
|||
condition_column = 'date_of_joining' |
|||
else: |
|||
return |
|||
|
|||
employees_born_today = frappe.db.multisql({ |
|||
"mariadb": f""" |
|||
SELECT `personal_email`, `company`, `company_email`, `user_id`, `employee_name` AS 'name', `image`, `date_of_joining` |
|||
FROM `tabEmployee` |
|||
WHERE |
|||
DAY({condition_column}) = DAY(%(today)s) |
|||
AND |
|||
MONTH({condition_column}) = MONTH(%(today)s) |
|||
AND |
|||
`status` = 'Active' |
|||
""", |
|||
"postgres": f""" |
|||
SELECT "personal_email", "company", "company_email", "user_id", "employee_name" AS 'name', "image" |
|||
FROM "tabEmployee" |
|||
WHERE |
|||
DATE_PART('day', {condition_column}) = date_part('day', %(today)s) |
|||
AND |
|||
DATE_PART('month', {condition_column}) = date_part('month', %(today)s) |
|||
AND |
|||
"status" = 'Active' |
|||
""", |
|||
}, dict(today=today(), condition_column=condition_column), as_dict=1) |
|||
|
|||
grouped_employees = defaultdict(lambda: []) |
|||
|
|||
for employee_doc in employees_born_today: |
|||
grouped_employees[employee_doc.get('company')].append(employee_doc) |
|||
|
|||
return grouped_employees |
|||
|
|||
|
|||
# -------------------------- |
|||
# WORK ANNIVERSARY REMINDERS |
|||
# -------------------------- |
|||
def send_work_anniversary_reminders(): |
|||
"""Send Employee Work Anniversary Reminders if 'Send Work Anniversary Reminders' is checked""" |
|||
to_send = int(frappe.db.get_single_value("HR Settings", "send_work_anniversary_reminders") or 1) |
|||
if not to_send: |
|||
return |
|||
|
|||
employees_joined_today = get_employees_having_an_event_today("work_anniversary") |
|||
|
|||
for company, anniversary_persons in employees_joined_today.items(): |
|||
employee_emails = get_all_employee_emails(company) |
|||
anniversary_person_emails = [get_employee_email(doc) for doc in anniversary_persons] |
|||
recipients = list(set(employee_emails) - set(anniversary_person_emails)) |
|||
|
|||
reminder_text, message = get_work_anniversary_reminder_text_and_message(anniversary_persons) |
|||
send_work_anniversary_reminder(recipients, reminder_text, anniversary_persons, message) |
|||
|
|||
if len(anniversary_persons) > 1: |
|||
# email for people sharing work anniversaries |
|||
for person in anniversary_persons: |
|||
person_email = person["user_id"] or person["personal_email"] or person["company_email"] |
|||
others = [d for d in anniversary_persons if d != person] |
|||
reminder_text, message = get_work_anniversary_reminder_text_and_message(others) |
|||
send_work_anniversary_reminder(person_email, reminder_text, others, message) |
|||
|
|||
def get_work_anniversary_reminder_text_and_message(anniversary_persons): |
|||
if len(anniversary_persons) == 1: |
|||
anniversary_person = anniversary_persons[0]['name'] |
|||
persons_name = anniversary_person |
|||
# Number of years completed at the company |
|||
completed_years = getdate().year - anniversary_persons[0]['date_of_joining'].year |
|||
anniversary_person += f" completed {completed_years} years" |
|||
else: |
|||
person_names_with_years = [] |
|||
names = [] |
|||
for person in anniversary_persons: |
|||
person_text = person['name'] |
|||
names.append(person_text) |
|||
# Number of years completed at the company |
|||
completed_years = getdate().year - person['date_of_joining'].year |
|||
person_text += f" completed {completed_years} years" |
|||
person_names_with_years.append(person_text) |
|||
|
|||
# converts ["Jim", "Rim", "Dim"] to Jim, Rim & Dim |
|||
anniversary_person = comma_sep(person_names_with_years, frappe._("{0} & {1}"), False) |
|||
persons_name = comma_sep(names, frappe._("{0} & {1}"), False) |
|||
|
|||
reminder_text = _("Today {0} at our Company! 🎉").format(anniversary_person) |
|||
message = _("A friendly reminder of an important date for our team.") |
|||
message += "<br>" |
|||
message += _("Everyone, let’s congratulate {0} on their work anniversary!").format(persons_name) |
|||
|
|||
return reminder_text, message |
|||
|
|||
def send_work_anniversary_reminder(recipients, reminder_text, anniversary_persons, message): |
|||
frappe.sendmail( |
|||
recipients=recipients, |
|||
subject=_("Work Anniversary Reminder"), |
|||
template="anniversary_reminder", |
|||
args=dict( |
|||
reminder_text=reminder_text, |
|||
anniversary_persons=anniversary_persons, |
|||
message=message, |
|||
), |
|||
header=_("🎊️🎊️ Work Anniversary Reminder 🎊️🎊️") |
|||
) |
@ -0,0 +1,173 @@ |
|||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# License: GNU General Public License v3. See license.txt |
|||
|
|||
import frappe |
|||
import unittest |
|||
|
|||
from frappe.utils import getdate |
|||
from datetime import timedelta |
|||
from erpnext.hr.doctype.employee.test_employee import make_employee |
|||
from erpnext.hr.doctype.hr_settings.hr_settings import set_proceed_with_frequency_change |
|||
|
|||
|
|||
class TestEmployeeReminders(unittest.TestCase): |
|||
@classmethod |
|||
def setUpClass(cls): |
|||
from erpnext.hr.doctype.holiday_list.test_holiday_list import make_holiday_list |
|||
|
|||
# Create a test holiday list |
|||
test_holiday_dates = cls.get_test_holiday_dates() |
|||
test_holiday_list = make_holiday_list( |
|||
'TestHolidayRemindersList', |
|||
holiday_dates=[ |
|||
{'holiday_date': test_holiday_dates[0], 'description': 'test holiday1'}, |
|||
{'holiday_date': test_holiday_dates[1], 'description': 'test holiday2'}, |
|||
{'holiday_date': test_holiday_dates[2], 'description': 'test holiday3', 'weekly_off': 1}, |
|||
{'holiday_date': test_holiday_dates[3], 'description': 'test holiday4'}, |
|||
{'holiday_date': test_holiday_dates[4], 'description': 'test holiday5'}, |
|||
{'holiday_date': test_holiday_dates[5], 'description': 'test holiday6'}, |
|||
], |
|||
from_date=getdate()-timedelta(days=10), |
|||
to_date=getdate()+timedelta(weeks=5) |
|||
) |
|||
|
|||
# Create a test employee |
|||
test_employee = frappe.get_doc( |
|||
'Employee', |
|||
make_employee('test@gopher.io', company="_Test Company") |
|||
) |
|||
|
|||
# Attach the holiday list to employee |
|||
test_employee.holiday_list = test_holiday_list.name |
|||
test_employee.save() |
|||
|
|||
# Attach to class |
|||
cls.test_employee = test_employee |
|||
cls.test_holiday_dates = test_holiday_dates |
|||
|
|||
@classmethod |
|||
def get_test_holiday_dates(cls): |
|||
today_date = getdate() |
|||
return [ |
|||
today_date, |
|||
today_date-timedelta(days=4), |
|||
today_date-timedelta(days=3), |
|||
today_date+timedelta(days=1), |
|||
today_date+timedelta(days=3), |
|||
today_date+timedelta(weeks=3) |
|||
] |
|||
|
|||
def setUp(self): |
|||
# Clear Email Queue |
|||
frappe.db.sql("delete from `tabEmail Queue`") |
|||
|
|||
def test_is_holiday(self): |
|||
from erpnext.hr.doctype.employee.employee import is_holiday |
|||
|
|||
self.assertTrue(is_holiday(self.test_employee.name)) |
|||
self.assertTrue(is_holiday(self.test_employee.name, date=self.test_holiday_dates[1])) |
|||
self.assertFalse(is_holiday(self.test_employee.name, date=getdate()-timedelta(days=1))) |
|||
|
|||
# Test weekly_off holidays |
|||
self.assertTrue(is_holiday(self.test_employee.name, date=self.test_holiday_dates[2])) |
|||
self.assertFalse(is_holiday(self.test_employee.name, date=self.test_holiday_dates[2], only_non_weekly=True)) |
|||
|
|||
# Test with descriptions |
|||
has_holiday, descriptions = is_holiday(self.test_employee.name, with_description=True) |
|||
self.assertTrue(has_holiday) |
|||
self.assertTrue('test holiday1' in descriptions) |
|||
|
|||
def test_birthday_reminders(self): |
|||
employee = frappe.get_doc("Employee", frappe.db.sql_list("select name from tabEmployee limit 1")[0]) |
|||
employee.date_of_birth = "1992" + frappe.utils.nowdate()[4:] |
|||
employee.company_email = "test@example.com" |
|||
employee.company = "_Test Company" |
|||
employee.save() |
|||
|
|||
from erpnext.hr.doctype.employee.employee_reminders import get_employees_who_are_born_today, send_birthday_reminders |
|||
|
|||
employees_born_today = get_employees_who_are_born_today() |
|||
self.assertTrue(employees_born_today.get("_Test Company")) |
|||
|
|||
hr_settings = frappe.get_doc("HR Settings", "HR Settings") |
|||
hr_settings.send_birthday_reminders = 1 |
|||
hr_settings.save() |
|||
|
|||
send_birthday_reminders() |
|||
|
|||
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True) |
|||
self.assertTrue("Subject: Birthday Reminder" in email_queue[0].message) |
|||
|
|||
def test_work_anniversary_reminders(self): |
|||
employee = frappe.get_doc("Employee", frappe.db.sql_list("select name from tabEmployee limit 1")[0]) |
|||
employee.date_of_joining = "1998" + frappe.utils.nowdate()[4:] |
|||
employee.company_email = "test@example.com" |
|||
employee.company = "_Test Company" |
|||
employee.save() |
|||
|
|||
from erpnext.hr.doctype.employee.employee_reminders import get_employees_having_an_event_today, send_work_anniversary_reminders |
|||
|
|||
employees_having_work_anniversary = get_employees_having_an_event_today('work_anniversary') |
|||
self.assertTrue(employees_having_work_anniversary.get("_Test Company")) |
|||
|
|||
hr_settings = frappe.get_doc("HR Settings", "HR Settings") |
|||
hr_settings.send_work_anniversary_reminders = 1 |
|||
hr_settings.save() |
|||
|
|||
send_work_anniversary_reminders() |
|||
|
|||
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True) |
|||
self.assertTrue("Subject: Work Anniversary Reminder" in email_queue[0].message) |
|||
|
|||
def test_send_holidays_reminder_in_advance(self): |
|||
from erpnext.hr.utils import get_holidays_for_employee |
|||
from erpnext.hr.doctype.employee.employee_reminders import send_holidays_reminder_in_advance |
|||
|
|||
# Get HR settings and enable advance holiday reminders |
|||
hr_settings = frappe.get_doc("HR Settings", "HR Settings") |
|||
hr_settings.send_holiday_reminders = 1 |
|||
set_proceed_with_frequency_change() |
|||
hr_settings.frequency = 'Weekly' |
|||
hr_settings.save() |
|||
|
|||
holidays = get_holidays_for_employee( |
|||
self.test_employee.get('name'), |
|||
getdate(), getdate() + timedelta(days=3), |
|||
only_non_weekly=True, |
|||
raise_exception=False |
|||
) |
|||
|
|||
send_holidays_reminder_in_advance( |
|||
self.test_employee.get('name'), |
|||
holidays |
|||
) |
|||
|
|||
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True) |
|||
self.assertEqual(len(email_queue), 1) |
|||
|
|||
def test_advance_holiday_reminders_monthly(self): |
|||
from erpnext.hr.doctype.employee.employee_reminders import send_reminders_in_advance_monthly |
|||
# Get HR settings and enable advance holiday reminders |
|||
hr_settings = frappe.get_doc("HR Settings", "HR Settings") |
|||
hr_settings.send_holiday_reminders = 1 |
|||
set_proceed_with_frequency_change() |
|||
hr_settings.frequency = 'Monthly' |
|||
hr_settings.save() |
|||
|
|||
send_reminders_in_advance_monthly() |
|||
|
|||
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True) |
|||
self.assertTrue(len(email_queue) > 0) |
|||
|
|||
def test_advance_holiday_reminders_weekly(self): |
|||
from erpnext.hr.doctype.employee.employee_reminders import send_reminders_in_advance_weekly |
|||
# Get HR settings and enable advance holiday reminders |
|||
hr_settings = frappe.get_doc("HR Settings", "HR Settings") |
|||
hr_settings.send_holiday_reminders = 1 |
|||
hr_settings.frequency = 'Weekly' |
|||
hr_settings.save() |
|||
|
|||
send_reminders_in_advance_weekly() |
|||
|
|||
email_queue = frappe.db.sql("""select * from `tabEmail Queue`""", as_dict=True) |
|||
self.assertTrue(len(email_queue) > 0) |
@ -1,17 +1,79 @@ |
|||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors |
|||
# License: GNU General Public License v3. See license.txt |
|||
|
|||
# For license information, please see license.txt |
|||
|
|||
from __future__ import unicode_literals |
|||
import frappe |
|||
|
|||
from frappe.model.document import Document |
|||
from frappe.utils import format_date |
|||
|
|||
# Wether to proceed with frequency change |
|||
PROCEED_WITH_FREQUENCY_CHANGE = False |
|||
|
|||
class HRSettings(Document): |
|||
def validate(self): |
|||
self.set_naming_series() |
|||
|
|||
# Based on proceed flag |
|||
global PROCEED_WITH_FREQUENCY_CHANGE |
|||
if not PROCEED_WITH_FREQUENCY_CHANGE: |
|||
self.validate_frequency_change() |
|||
PROCEED_WITH_FREQUENCY_CHANGE = False |
|||
|
|||
def set_naming_series(self): |
|||
from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series |
|||
set_by_naming_series("Employee", "employee_number", |
|||
self.get("emp_created_by")=="Naming Series", hide_name_field=True) |
|||
|
|||
def validate_frequency_change(self): |
|||
weekly_job, monthly_job = None, None |
|||
|
|||
try: |
|||
weekly_job = frappe.get_doc( |
|||
'Scheduled Job Type', |
|||
'employee_reminders.send_reminders_in_advance_weekly' |
|||
) |
|||
|
|||
monthly_job = frappe.get_doc( |
|||
'Scheduled Job Type', |
|||
'employee_reminders.send_reminders_in_advance_monthly' |
|||
) |
|||
except frappe.DoesNotExistError: |
|||
return |
|||
|
|||
next_weekly_trigger = weekly_job.get_next_execution() |
|||
next_monthly_trigger = monthly_job.get_next_execution() |
|||
|
|||
if self.freq_changed_from_monthly_to_weekly(): |
|||
if next_monthly_trigger < next_weekly_trigger: |
|||
self.show_freq_change_warning(next_monthly_trigger, next_weekly_trigger) |
|||
|
|||
elif self.freq_changed_from_weekly_to_monthly(): |
|||
if next_monthly_trigger > next_weekly_trigger: |
|||
self.show_freq_change_warning(next_weekly_trigger, next_monthly_trigger) |
|||
|
|||
def freq_changed_from_weekly_to_monthly(self): |
|||
return self.has_value_changed("frequency") and self.frequency == "Monthly" |
|||
|
|||
def freq_changed_from_monthly_to_weekly(self): |
|||
return self.has_value_changed("frequency") and self.frequency == "Weekly" |
|||
|
|||
def show_freq_change_warning(self, from_date, to_date): |
|||
from_date = frappe.bold(format_date(from_date)) |
|||
to_date = frappe.bold(format_date(to_date)) |
|||
frappe.msgprint( |
|||
msg=frappe._('Employees will miss holiday reminders from {} until {}. <br> Do you want to proceed with this change?').format(from_date, to_date), |
|||
title='Confirm change in Frequency', |
|||
primary_action={ |
|||
'label': frappe._('Yes, Proceed'), |
|||
'client_action': 'erpnext.proceed_save_with_reminders_frequency_change' |
|||
}, |
|||
raise_exception=frappe.ValidationError |
|||
) |
|||
|
|||
@frappe.whitelist() |
|||
def set_proceed_with_frequency_change(): |
|||
'''Enables proceed with frequency change''' |
|||
global PROCEED_WITH_FREQUENCY_CHANGE |
|||
PROCEED_WITH_FREQUENCY_CHANGE = True |
|||
|
@ -0,0 +1,23 @@ |
|||
import frappe |
|||
from frappe.model.utils.rename_field import rename_field |
|||
|
|||
def execute(): |
|||
frappe.reload_doc('hr', 'doctype', 'hr_settings') |
|||
|
|||
try: |
|||
# Rename the field |
|||
rename_field('HR Settings', 'stop_birthday_reminders', 'send_birthday_reminders') |
|||
|
|||
# Reverse the value |
|||
old_value = frappe.db.get_single_value('HR Settings', 'send_birthday_reminders') |
|||
|
|||
frappe.db.set_value( |
|||
'HR Settings', |
|||
'HR Settings', |
|||
'send_birthday_reminders', |
|||
1 if old_value == 0 else 0 |
|||
) |
|||
|
|||
except Exception as e: |
|||
if e.args[0] != 1054: |
|||
raise |
@ -0,0 +1,25 @@ |
|||
<div class="gray-container text-center"> |
|||
<div> |
|||
{% for person in anniversary_persons %} |
|||
{% if person.image %} |
|||
<img |
|||
class="avatar-frame standard-image" |
|||
src="{{ person.image }}" |
|||
style="{{ css_style or '' }}" |
|||
title="{{ person.name }}"> |
|||
</span> |
|||
{% else %} |
|||
<span |
|||
class="avatar-frame standard-image" |
|||
style="{{ css_style or '' }}" |
|||
title="{{ person.name }}"> |
|||
{{ frappe.utils.get_abbr(person.name) }} |
|||
</span> |
|||
{% endif %} |
|||
{% endfor %} |
|||
</div> |
|||
<div style="margin-top: 15px"> |
|||
<span>{{ reminder_text }}</span> |
|||
<p class="text-muted">{{ message }}</p> |
|||
</div> |
|||
</div> |
@ -0,0 +1,16 @@ |
|||
<div> |
|||
<span>{{ reminder_text }}</span> |
|||
<p class="text-muted">{{ message }}</p> |
|||
</div> |
|||
|
|||
{% if advance_holiday_reminder %} |
|||
{% if holidays | len > 0 %} |
|||
<ol> |
|||
{% for holiday in holidays %} |
|||
<li>{{ frappe.format(holiday.holiday_date, 'Date') }} - {{ holiday.description }}</li> |
|||
{% endfor %} |
|||
</ol> |
|||
{% else %} |
|||
<p>You don't have no upcoming holidays this {{ frequency }}.</p> |
|||
{% endif %} |
|||
{% endif %} |
Loading…
Reference in new issue