refactor: Employee birthday reminder
diff --git a/erpnext/hr/doctype/employee/employee.py b/erpnext/hr/doctype/employee/employee.py
index dfc600c..df11314 100755
--- a/erpnext/hr/doctype/employee/employee.py
+++ b/erpnext/hr/doctype/employee/employee.py
@@ -278,63 +278,71 @@
if int(frappe.db.get_single_value("HR Settings", "stop_birthday_reminders") or 0):
return
- birthdays = get_employees_who_are_born_today()
+ employees_born_today = get_employees_who_are_born_today()
- if birthdays:
- employee_list = frappe.get_all('Employee',
- fields=['name','employee_name'],
- filters={'status': 'Active',
- 'company': birthdays[0]['company']
- }
- )
- employee_emails = get_employee_emails(employee_list)
- birthday_names = [name["employee_name"] for name in birthdays]
- birthday_emails = [email["user_id"] or email["personal_email"] or email["company_email"] for email in birthdays]
+ 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))
- birthdays.append({'company_email': '','employee_name': '','personal_email': '','user_id': ''})
+ reminder_text, message = get_birthday_reminder_text_and_message(birthday_persons)
+ send_birthday_reminder(recipients, reminder_text, birthday_persons, message)
- for e in birthdays:
- if e['company_email'] or e['personal_email'] or e['user_id']:
- if len(birthday_names) == 1:
- continue
- recipients = e['company_email'] or e['personal_email'] or e['user_id']
+ 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_employee_email(employee_doc):
+ return employee_doc["user_id"] or employee_doc["personal_email"] or employee_doc["company_email"]
- else:
- recipients = list(set(employee_emails) - set(birthday_emails))
-
- frappe.sendmail(recipients=recipients,
- subject=_("Birthday Reminder"),
- message=get_birthday_reminder_message(e, birthday_names),
- header=['Birthday Reminder', 'green'],
- )
-
-def get_birthday_reminder_message(employee, employee_names):
- """Get employee birthday reminder message"""
- pattern = "</Li><Br><Li>"
- message = pattern.join(filter(lambda u: u not in (employee['employee_name']), employee_names))
- message = message.title()
-
- if pattern not in message:
- message = "Today is {0}'s birthday \U0001F603".format(message)
-
+def get_birthday_reminder_text_and_message(birthday_persons):
+ if len(birthday_persons) == 1:
+ birthday_person_text = birthday_persons[0]['name']
else:
- message = "Today your colleagues are celebrating their birthdays \U0001F382<br><ul><strong><li> " + message +"</li></strong></ul>"
+ # converts ["Jim", "Rim", "Dim"] to Jim, Rim & Dim
+ person_names = [d['name'] for d in birthday_persons]
+ last_person = person_names[-1]
+ birthday_person_text = ", ".join(person_names[:-1])
+ birthday_person_text += " & {}".format(last_person)
- return message
+ reminder_text = "Today is {0}'s birthday 🎉".format(birthday_person_text)
+ message = "A friendly reminder of an important date for our team. Everyone, let’s congratulate {0} their birthday".format(birthday_person_text)
+ return reminder_text, message
-def get_employees_who_are_born_today():
- """Get Employee properties whose birthday is today."""
- return frappe.db.get_values("Employee",
- fieldname=["name", "personal_email", "company", "company_email", "user_id", "employee_name"],
- filters={
- "date_of_birth": ("like", "%{}".format(format_datetime(getdate(), "-MM-dd"))),
- "status": "Active",
- },
- as_dict=True
+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,
+ 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"""
+ from collections import defaultdict
+ employees_born_today = frappe.db.get_all("Employee",
+ fields=["personal_email", "company", "company_email", "user_id", "employee_name as name", "image"],
+ filters={
+ "date_of_birth": ("like", "{}".format(format_datetime(getdate(), "-MM-dd"))),
+ "status": "Active",
+ })
+
+ grouped_employees = defaultdict(lambda: [])
+
+ for employee_doc in employees_born_today:
+ grouped_employees[employee_doc.get('company')].append(employee_doc)
+
+ return grouped_employees
def get_holiday_list_for_employee(employee, raise_exception=True):
if employee:
@@ -404,14 +412,21 @@
user.insert()
return user.name
-def get_employee_emails(employee_list):
+def get_all_employee_emails(company):
'''Returns list of employee emails either based on user_id or company_email'''
+ employee_list = frappe.get_all('Employee',
+ fields=['name','employee_name'],
+ filters={
+ 'status': 'Active',
+ 'company': company
+ }
+ )
employee_emails = []
for employee in employee_list:
if not employee:
continue
- user, company_email, personal_email = frappe.db.get_value('Employee', employee,
- ['user_id', 'company_email', 'personal_email'])
+ user, company_email, personal_email = frappe.db.get_value('Employee',
+ employee, ['user_id', 'company_email', 'personal_email'])
email = user or company_email or personal_email
if email:
employee_emails.append(email)
diff --git a/erpnext/templates/emails/birthday_reminder.html b/erpnext/templates/emails/birthday_reminder.html
new file mode 100644
index 0000000..e4c91c7
--- /dev/null
+++ b/erpnext/templates/emails/birthday_reminder.html
@@ -0,0 +1,16 @@
+<div class="gray-container text-center">
+ <div>
+ {% for person in birthday_persons %}
+ <span class="avatar avatar-small " title="Mitali">
+ <span class="avatar-frame standard-image" style="{% if person.image %}background-image: url({{person.image}}); {% endif %} margin-right: 5px;"
+ title={{person.name}}>
+ {% if not person.image %} {{ person.name[:1] }} {% endif %}
+ </span>
+ </span>
+ {% endfor %}
+ </div>
+ <div style="margin-top: 15px">
+ <span>{{ reminder_text }}</span>
+ <p class="text-muted">{{ message }}</p>
+ </div>
+</div>
\ No newline at end of file