[fix] fixes birthday reminders #2021
This commit is contained in:
parent
88a1515b46
commit
5bceebc6a1
@ -170,7 +170,7 @@
|
|||||||
],
|
],
|
||||||
"icon": "icon-user",
|
"icon": "icon-user",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"modified": "2015-01-06 17:32:39.936580",
|
"modified": "2015-01-20 17:35:41.423211",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "Buying",
|
"module": "Buying",
|
||||||
"name": "Supplier",
|
"name": "Supplier",
|
||||||
|
@ -55,7 +55,8 @@ scheduler_events = {
|
|||||||
"erpnext.stock.reorder_item.reorder_item",
|
"erpnext.stock.reorder_item.reorder_item",
|
||||||
"erpnext.setup.doctype.email_digest.email_digest.send",
|
"erpnext.setup.doctype.email_digest.email_digest.send",
|
||||||
"erpnext.support.doctype.issue.issue.auto_close_tickets",
|
"erpnext.support.doctype.issue.issue.auto_close_tickets",
|
||||||
"erpnext.accounts.doctype.fiscal_year.fiscal_year.auto_create_fiscal_year"
|
"erpnext.accounts.doctype.fiscal_year.fiscal_year.auto_create_fiscal_year",
|
||||||
|
"erpnext.hr.doctype.employee.employee.send_birthday_reminders"
|
||||||
],
|
],
|
||||||
"daily_long": [
|
"daily_long": [
|
||||||
"erpnext.setup.doctype.backup_manager.backup_manager.take_backups_daily"
|
"erpnext.setup.doctype.backup_manager.backup_manager.take_backups_daily"
|
||||||
|
@ -51,8 +51,6 @@ class Employee(Document):
|
|||||||
self.update_user()
|
self.update_user()
|
||||||
self.update_user_permissions()
|
self.update_user_permissions()
|
||||||
|
|
||||||
self.update_dob_event()
|
|
||||||
|
|
||||||
def update_user_permissions(self):
|
def update_user_permissions(self):
|
||||||
frappe.permissions.add_user_permission("Employee", self.name, self.user_id)
|
frappe.permissions.add_user_permission("Employee", self.name, self.user_id)
|
||||||
frappe.permissions.set_user_permission_if_allowed("Company", self.company, self.user_id)
|
frappe.permissions.set_user_permission_if_allowed("Company", self.company, self.user_id)
|
||||||
@ -136,8 +134,6 @@ class Employee(Document):
|
|||||||
throw(_("User {0} is already assigned to Employee {1}").format(self.user_id, employee[0]))
|
throw(_("User {0} is already assigned to Employee {1}").format(self.user_id, employee[0]))
|
||||||
|
|
||||||
def validate_employee_leave_approver(self):
|
def validate_employee_leave_approver(self):
|
||||||
from erpnext.hr.doctype.leave_application.leave_application import InvalidLeaveApproverError
|
|
||||||
|
|
||||||
for l in self.get("leave_approvers")[:]:
|
for l in self.get("leave_approvers")[:]:
|
||||||
if "Leave Approver" not in frappe.get_roles(l.leave_approver):
|
if "Leave Approver" not in frappe.get_roles(l.leave_approver):
|
||||||
self.get("leave_approvers").remove(l)
|
self.get("leave_approvers").remove(l)
|
||||||
@ -147,39 +143,6 @@ class Employee(Document):
|
|||||||
if self.reports_to == self.name:
|
if self.reports_to == self.name:
|
||||||
throw(_("Employee cannot report to himself."))
|
throw(_("Employee cannot report to himself."))
|
||||||
|
|
||||||
def update_dob_event(self):
|
|
||||||
if self.status == "Active" and self.date_of_birth \
|
|
||||||
and not cint(frappe.db.get_value("HR Settings", None, "stop_birthday_reminders")):
|
|
||||||
birthday_event = frappe.db.sql("""select name from `tabEvent` where repeat_on='Every Year'
|
|
||||||
and ref_type='Employee' and ref_name=%s""", self.name)
|
|
||||||
|
|
||||||
starts_on = self.date_of_birth + " 00:00:00"
|
|
||||||
ends_on = self.date_of_birth + " 00:15:00"
|
|
||||||
|
|
||||||
if birthday_event:
|
|
||||||
event = frappe.get_doc("Event", birthday_event[0][0])
|
|
||||||
event.starts_on = starts_on
|
|
||||||
event.ends_on = ends_on
|
|
||||||
event.save()
|
|
||||||
else:
|
|
||||||
frappe.get_doc({
|
|
||||||
"doctype": "Event",
|
|
||||||
"subject": _("Birthday") + ": " + self.employee_name,
|
|
||||||
"description": _("Happy Birthday!") + " " + self.employee_name,
|
|
||||||
"starts_on": starts_on,
|
|
||||||
"ends_on": ends_on,
|
|
||||||
"event_type": "Public",
|
|
||||||
"all_day": 1,
|
|
||||||
"send_reminder": 1,
|
|
||||||
"repeat_this_event": 1,
|
|
||||||
"repeat_on": "Every Year",
|
|
||||||
"ref_type": "Employee",
|
|
||||||
"ref_name": self.name
|
|
||||||
}).insert()
|
|
||||||
else:
|
|
||||||
frappe.db.sql("""delete from `tabEvent` where repeat_on='Every Year' and
|
|
||||||
ref_type='Employee' and ref_name=%s""", self.name)
|
|
||||||
|
|
||||||
def on_trash(self):
|
def on_trash(self):
|
||||||
delete_events(self.doctype, self.name)
|
delete_events(self.doctype, self.name)
|
||||||
|
|
||||||
@ -217,3 +180,31 @@ def update_user_permissions(doc, method):
|
|||||||
if "Employee" in [d.role for d in doc.get("user_roles")]:
|
if "Employee" in [d.role for d in doc.get("user_roles")]:
|
||||||
employee = frappe.get_doc("Employee", {"user_id": doc.name})
|
employee = frappe.get_doc("Employee", {"user_id": doc.name})
|
||||||
employee.update_user_permissions()
|
employee.update_user_permissions()
|
||||||
|
|
||||||
|
def send_birthday_reminders():
|
||||||
|
"""Send Employee birthday reminders if no 'Stop Birthday Reminders' is not set."""
|
||||||
|
if int(frappe.db.get_single_value("HR Settings", "stop_birthday_reminders") or 0):
|
||||||
|
return
|
||||||
|
|
||||||
|
from frappe.utils.user import get_enabled_system_users
|
||||||
|
users = None
|
||||||
|
|
||||||
|
birthdays = get_employees_who_are_born_today()
|
||||||
|
|
||||||
|
if birthdays:
|
||||||
|
if not users:
|
||||||
|
users = [u.email_id or u.name for u in get_enabled_system_users()]
|
||||||
|
|
||||||
|
for e in birthdays:
|
||||||
|
frappe.sendmail(recipients=filter(lambda u: u not in (e.company_email, e.personal_email), users),
|
||||||
|
subject=_("Birthday Reminder for {0}").format(e.employee_name),
|
||||||
|
message=_("""Today is {0}'s birthday!""").format(e.employee_name),
|
||||||
|
reply_to=e.company_email or e.personal_email,
|
||||||
|
bulk=True)
|
||||||
|
|
||||||
|
def get_employees_who_are_born_today():
|
||||||
|
"""Get Employee properties whose birthday is today."""
|
||||||
|
return frappe.db.sql("""select name, personal_email, company_email, employee_name
|
||||||
|
from tabEmployee where day(date_of_birth) = day(curdate())
|
||||||
|
and month(date_of_birth) = month(curdate())
|
||||||
|
and status = 'Active'""", as_dict=True)
|
||||||
|
@ -3,4 +3,31 @@
|
|||||||
|
|
||||||
|
|
||||||
import frappe
|
import frappe
|
||||||
|
import unittest
|
||||||
|
import frappe.utils
|
||||||
|
|
||||||
test_records = frappe.get_test_records('Employee')
|
test_records = frappe.get_test_records('Employee')
|
||||||
|
|
||||||
|
class TestEmployee(unittest.TestCase):
|
||||||
|
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 = "1990" + frappe.utils.nowdate()[4:]
|
||||||
|
employee.company_email = "test@example.com"
|
||||||
|
employee.save()
|
||||||
|
|
||||||
|
from erpnext.hr.doctype.employee.employee import get_employees_who_are_born_today, send_birthday_reminders
|
||||||
|
|
||||||
|
self.assertTrue(employee.name in [e.name for e in get_employees_who_are_born_today()])
|
||||||
|
|
||||||
|
frappe.db.sql("delete from `tabBulk Email`")
|
||||||
|
|
||||||
|
hr_settings = frappe.get_doc("HR Settings", "HR Settings")
|
||||||
|
hr_settings.stop_birthday_reminders = 0
|
||||||
|
hr_settings.save()
|
||||||
|
|
||||||
|
send_birthday_reminders()
|
||||||
|
|
||||||
|
bulk_mails = frappe.db.sql("""select * from `tabBulk Email`""", as_dict=True)
|
||||||
|
self.assertTrue("Subject: Birthday Reminder for {0}".format(employee.employee_name) \
|
||||||
|
in bulk_mails[0].message)
|
||||||
|
|
||||||
|
@ -6,30 +6,10 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
|
||||||
from frappe.utils import cint
|
|
||||||
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
|
|
||||||
class HRSettings(Document):
|
class HRSettings(Document):
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.update_birthday_reminders()
|
|
||||||
|
|
||||||
from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series
|
from erpnext.setup.doctype.naming_series.naming_series import set_by_naming_series
|
||||||
set_by_naming_series("Employee", "employee_number",
|
set_by_naming_series("Employee", "employee_number",
|
||||||
self.get("emp_created_by")=="Naming Series", hide_name_field=True)
|
self.get("emp_created_by")=="Naming Series", hide_name_field=True)
|
||||||
|
|
||||||
def update_birthday_reminders(self):
|
|
||||||
original_stop_birthday_reminders = cint(frappe.db.get_value("HR Settings",
|
|
||||||
None, "stop_birthday_reminders"))
|
|
||||||
|
|
||||||
# reset birthday reminders
|
|
||||||
if cint(self.stop_birthday_reminders) != original_stop_birthday_reminders:
|
|
||||||
frappe.db.sql("""delete from `tabEvent` where repeat_on='Every Year' and ref_type='Employee'""")
|
|
||||||
|
|
||||||
if not self.stop_birthday_reminders:
|
|
||||||
for employee in frappe.db.sql_list("""select name from `tabEmployee` where status='Active' and
|
|
||||||
ifnull(date_of_birth, '')!=''"""):
|
|
||||||
frappe.get_doc("Employee", employee).update_dob_event()
|
|
||||||
|
|
||||||
frappe.msgprint(frappe._("Updated Birthday Reminders"))
|
|
@ -11,3 +11,7 @@ from frappe.utils import extract_email_id
|
|||||||
class JobApplicant(Document):
|
class JobApplicant(Document):
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.set_status()
|
self.set_status()
|
||||||
|
|
||||||
|
def set_sender(self, sender):
|
||||||
|
"""Will be called by **Communication** when a Job Application is created from an incoming email."""
|
||||||
|
self.email_id = sender
|
||||||
|
@ -104,3 +104,4 @@ erpnext.patches.v4_1.fix_jv_remarks
|
|||||||
erpnext.patches.v5_0.recalculate_total_amount_in_jv
|
erpnext.patches.v5_0.recalculate_total_amount_in_jv
|
||||||
erpnext.patches.v5_0.remove_shopping_cart_app
|
erpnext.patches.v5_0.remove_shopping_cart_app
|
||||||
erpnext.patches.v5_0.update_companywise_payment_account
|
erpnext.patches.v5_0.update_companywise_payment_account
|
||||||
|
erpnext.patches.v5_0.remove_birthday_events
|
||||||
|
6
erpnext/patches/v5_0/remove_birthday_events.py
Normal file
6
erpnext/patches/v5_0/remove_birthday_events.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
for e in frappe.db.sql_list("""select name from tabEvent where
|
||||||
|
repeat_on='Every Year' and ref_type='Employee'"""):
|
||||||
|
frappe.delete_doc("Event", e, force=True)
|
@ -15,6 +15,10 @@ class Lead(SellingController):
|
|||||||
def get_feed(self):
|
def get_feed(self):
|
||||||
return '{0}: {1}'.format(_(self.status), self.lead_name)
|
return '{0}: {1}'.format(_(self.status), self.lead_name)
|
||||||
|
|
||||||
|
def set_sender(self, sender):
|
||||||
|
"""Will be called by **Communication** when a Lead is created from an incoming email."""
|
||||||
|
self.email_id = sender
|
||||||
|
|
||||||
def onload(self):
|
def onload(self):
|
||||||
customer = frappe.db.get_value("Customer", {"lead_name": self.name})
|
customer = frappe.db.get_value("Customer", {"lead_name": self.name})
|
||||||
self.get("__onload").is_customer = customer
|
self.get("__onload").is_customer = customer
|
||||||
|
@ -11,7 +11,7 @@ class SalesPerson(NestedSet):
|
|||||||
nsm_parent_field = 'parent_sales_person';
|
nsm_parent_field = 'parent_sales_person';
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
for d in self.get('targets'):
|
for d in self.get('targets') or []:
|
||||||
if not flt(d.target_qty) and not flt(d.target_amount):
|
if not flt(d.target_qty) and not flt(d.target_amount):
|
||||||
frappe.throw(_("Either target qty or target amount is mandatory."))
|
frappe.throw(_("Either target qty or target amount is mandatory."))
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ class Territory(NestedSet):
|
|||||||
nsm_parent_field = 'parent_territory'
|
nsm_parent_field = 'parent_territory'
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
for d in self.get('targets'):
|
for d in self.get('targets') or []:
|
||||||
if not flt(d.target_qty) and not flt(d.target_amount):
|
if not flt(d.target_qty) and not flt(d.target_amount):
|
||||||
frappe.throw(_("Either target qty or target amount is mandatory"))
|
frappe.throw(_("Either target qty or target amount is mandatory"))
|
||||||
|
|
||||||
|
@ -187,7 +187,11 @@ def install(country=None):
|
|||||||
{'doctype': 'Industry Type', 'industry': _('Telecommunications')},
|
{'doctype': 'Industry Type', 'industry': _('Telecommunications')},
|
||||||
{'doctype': 'Industry Type', 'industry': _('Television')},
|
{'doctype': 'Industry Type', 'industry': _('Television')},
|
||||||
{'doctype': 'Industry Type', 'industry': _('Transportation')},
|
{'doctype': 'Industry Type', 'industry': _('Transportation')},
|
||||||
{'doctype': 'Industry Type', 'industry': _('Venture Capital')}
|
{'doctype': 'Industry Type', 'industry': _('Venture Capital')},
|
||||||
|
|
||||||
|
{'doctype': "Email Account", "email_id": "sales@example.com", "append_to": "Lead"},
|
||||||
|
{'doctype': "Email Account", "email_id": "support@example.com", "append_to": "Issue"},
|
||||||
|
{'doctype': "Email Account", "email_id": "jobs@example.com", "append_to": "Job Applicant"}
|
||||||
]
|
]
|
||||||
|
|
||||||
from frappe.modules import scrub
|
from frappe.modules import scrub
|
||||||
|
@ -15,6 +15,10 @@ class Issue(Document):
|
|||||||
def get_portal_page(self):
|
def get_portal_page(self):
|
||||||
return "ticket"
|
return "ticket"
|
||||||
|
|
||||||
|
def set_sender(self, sender):
|
||||||
|
"""Will be called by **Communication** when the Issue is created from an incoming email."""
|
||||||
|
self.raised_by = sender
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
self.update_status()
|
self.update_status()
|
||||||
self.set_lead_contact(self.raised_by)
|
self.set_lead_contact(self.raised_by)
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% if (items|length)==100 %}
|
{% if (items|length)==100 %}
|
||||||
<div class="alert alert-info info">Showing top 100 items.</div>
|
<div class="text-muted info">Showing top 100 items.</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="text-muted">No items listed.</div>
|
<div class="text-muted">No items listed.</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user