email digest for todo and calendar

This commit is contained in:
Anand Doshi 2013-02-16 14:51:25 +05:30
parent 32faa57692
commit d628916a2c
2 changed files with 276 additions and 119 deletions

View File

@ -16,19 +16,28 @@
from __future__ import unicode_literals
import webnotes
from webnotes.utils import fmt_money, formatdate, now_datetime, cstr, esc
from webnotes import _
from webnotes.utils import fmt_money, formatdate, now_datetime, cstr, esc, get_url_to_form
from webnotes.utils.dateutils import datetime_in_user_format
from datetime import timedelta
from dateutil.relativedelta import relativedelta
content_sequence = ["income_year_to_date", "bank_balance",
content_sequence = [
["Accounts", ["income_year_to_date", "bank_balance",
"income", "expenses_booked", "collections", "payments",
"invoiced_amount", "payables",
"new_leads", "new_enquiries", "new_quotations", "new_sales_orders",
"new_delivery_notes", "new_purchase_requests", "new_supplier_quotations",
"new_purchase_orders", "new_purchase_receipts", "new_stock_entries",
"new_support_tickets", "new_communications", "new_projects", "open_tickets"]
"invoiced_amount", "payables"]],
["Buying", ["new_purchase_requests", "new_supplier_quotations", "new_purchase_orders"]],
["Selling", ["new_leads", "new_enquiries", "new_quotations", "new_sales_orders"]],
["Stock", ["new_delivery_notes", "new_purchase_receipts", "new_stock_entries"]],
["Support", ["new_communications", "new_support_tickets", "open_tickets"]],
["Projects", ["new_projects"]]
]
digest_template = """<h2>%(digest)s</h2>
user_specific_content = ["calendar_events", "todo_list"]
digest_template = """\
<style>p.ed-indent { margin-right: 17px; }</style>
<h2>%(digest)s</h2>
<p style='color: grey'>%(date)s</p>
<h4>%(company)s</h4>
<hr>
@ -47,6 +56,10 @@ row_template = """<p style="%(style)s">
class DocType:
def __init__(self, doc, doclist=[]):
self.doc, self.doclist = doc, doclist
self.from_date, self.to_date = self.get_from_to_date()
self.future_from_date, self.future_to_date = self.get_future_from_to_date()
self.currency = webnotes.conn.get_value("Company", self.doc.company,
"default_currency")
def get_profiles(self):
"""get list of profiles"""
@ -72,25 +85,48 @@ class DocType:
recipients = filter(lambda r: r in valid_users,
self.doc.recipient_list.split("\n"))
common_msg = self.get_common_content()
if recipients:
for user_id in recipients:
msg_for_this_receipient = self.get_msg_html(self.get_user_specific_content(user_id) + \
common_msg)
from webnotes.utils.email_lib import sendmail
sendmail(recipients=recipients, subject=(self.doc.frequency + " Digest"),
sendmail(recipients=user_id, subject=(self.doc.frequency + " Digest"),
sender="ERPNext Notifications <notifications+email_digest@erpnext.com>",
msg=self.get_digest_msg())
msg=msg_for_this_receipient)
def get_digest_msg(self):
""""""
self.from_date, self.to_date = self.get_from_to_date()
self.currency = webnotes.conn.get_value("Company", self.doc.company,
"default_currency")
return self.get_msg_html(self.get_user_specific_content(webnotes.session.user) + \
self.get_common_content())
def get_common_content(self):
out = []
for module, content in content_sequence:
module_out = []
for ctype in content:
if self.doc.fields.get(ctype) and hasattr(self, "get_"+ctype):
module_out.append(getattr(self, "get_"+ctype)())
if any([m[0] for m in module_out]):
out += [[1, "<h4>" + _(module) + "</h4>"]] + module_out + [[1, "<hr>"]]
else:
out += module_out
return out
def get_user_specific_content(self, user_id):
original_session_user = webnotes.session.user
# setting session user for role base event fetching
webnotes.session.user = user_id
out = []
for ctype in content_sequence:
for ctype in user_specific_content:
if self.doc.fields.get(ctype) and hasattr(self, "get_"+ctype):
# appends [not "no updates", html]
out.append(getattr(self, "get_"+ctype)())
out.append(getattr(self, "get_"+ctype)(user_id))
return self.get_msg_html(out)
webnotes.session.user = original_session_user
return out
def get_msg_html(self, out):
with_value = [o[1] for o in out if o[0]]
@ -103,7 +139,7 @@ class DocType:
# seperate out no value items
no_value = [o[1] for o in out if not o[0]]
if no_value:
no_value = """<hr><h4>No Updates For:</h4><br>""" + "\n".join(no_value)
no_value = """<h4>No Updates For:</h4>""" + "\n".join(no_value)
date = self.doc.frequency == "Daily" and formatdate(self.from_date) or \
"%s to %s" % (formatdate(self.from_date), formatdate(self.to_date))
@ -250,6 +286,39 @@ class DocType:
def get_new_projects(self):
return self.get_new_count("Project", "New Projects", False)
def get_calendar_events(self, user_id):
from core.doctype.event.event import get_events
events = get_events(self.future_from_date, self.future_to_date)
html = ""
if events:
for i, e in enumerate(events):
if i>=10:
break
if e.all_day:
html += """<p>%s [%s (%s)]</p>""" % \
(e.subject, datetime_in_user_format(e.starts_on), _("All Day"))
else:
html += "<p>%s [%s - %s]</p>" % \
(e.subject, datetime_in_user_format(e.starts_on), datetime_in_user_format(e.ends_on))
return html and 1 or 0, "<h4>Upcoming Calendar Events (max 10):</h4>" + html + "<hr>"
def get_todo_list(self, user_id):
from utilities.page.todo.todo import get
todo_list = get()
html = ""
if todo_list:
for i, todo in enumerate([todo for todo in todo_list if not todo.checked]):
if i>= 10:
break
html += "<p>%s: %s</p>" % (todo.priority, todo.description or \
get_url_to_form(todo.reference_type, todo.reference_name))
return html and 1 or 0, "<h4>To Do (max 10):</h4>" + html + "<hr>"
def get_new_count(self, doctype, label, filter_by_company=True):
if filter_by_company:
company = """and company="%s" """ % self.doc.company
@ -331,6 +400,26 @@ class DocType:
return from_date, to_date
def get_future_from_to_date(self):
today = now_datetime().date()
# decide from date based on email digest frequency
if self.doc.frequency == "Daily":
# from date, to_date is today
from_date = to_date = today
elif self.doc.frequency == "Weekly":
# from date is the current week's monday
from_date = today - timedelta(days=today.weekday())
# to date is the current week's sunday
to_date = from_date + timedelta(days=6)
else:
# from date is the 1st day of the current month
from_date = today - relativedelta(days=today.day-1)
# to date is the last day of the current month
to_date = from_date + relativedelta(days=-1, months=1)
return from_date, to_date
def get_next_sending(self):
from_date, to_date = self.get_from_to_date()

View File

@ -1,8 +1,8 @@
[
{
"creation": "2013-01-10 16:34:23",
"creation": "2013-01-25 11:35:08",
"docstatus": 0,
"modified": "2013-01-22 14:56:01",
"modified": "2013-02-16 14:43:52",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -23,19 +23,14 @@
"permlevel": 0
},
{
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"name": "__common__",
"parent": "Email Digest",
"parentfield": "permissions",
"parenttype": "DocType",
"permlevel": 0,
"read": 1,
"report": 1,
"role": "System Manager",
"submit": 0,
"write": 1
"submit": 0
},
{
"doctype": "DocType",
@ -112,92 +107,9 @@
},
{
"doctype": "DocField",
"fieldname": "new_leads",
"fieldtype": "Check",
"label": "New Leads"
},
{
"doctype": "DocField",
"fieldname": "new_enquiries",
"fieldtype": "Check",
"label": "New Enquiries"
},
{
"doctype": "DocField",
"fieldname": "new_quotations",
"fieldtype": "Check",
"label": "New Quotations"
},
{
"doctype": "DocField",
"fieldname": "new_sales_orders",
"fieldtype": "Check",
"label": "New Sales Orders"
},
{
"doctype": "DocField",
"fieldname": "new_delivery_notes",
"fieldtype": "Check",
"label": "New Delivery Notes"
},
{
"doctype": "DocField",
"fieldname": "new_purchase_requests",
"fieldtype": "Check",
"label": "New Purchase Requests"
},
{
"doctype": "DocField",
"fieldname": "new_supplier_quotations",
"fieldtype": "Check",
"label": "New Supplier Quotations"
},
{
"doctype": "DocField",
"fieldname": "new_purchase_orders",
"fieldtype": "Check",
"label": "New Purchase Orders"
},
{
"doctype": "DocField",
"fieldname": "new_purchase_receipts",
"fieldtype": "Check",
"label": "New Purchase Receipts"
},
{
"doctype": "DocField",
"fieldname": "new_stock_entries",
"fieldtype": "Check",
"label": "New Stock Entries"
},
{
"doctype": "DocField",
"fieldname": "new_support_tickets",
"fieldtype": "Check",
"label": "New Support Tickets"
},
{
"doctype": "DocField",
"fieldname": "new_communications",
"fieldtype": "Check",
"label": "New Communications"
},
{
"doctype": "DocField",
"fieldname": "new_projects",
"fieldtype": "Check",
"label": "New Projects"
},
{
"doctype": "DocField",
"fieldname": "open_tickets",
"fieldtype": "Check",
"label": "Open Tickets"
},
{
"doctype": "DocField",
"fieldname": "cb1",
"fieldtype": "Column Break"
"fieldname": "accounts_module",
"fieldtype": "Column Break",
"label": "Accounts"
},
{
"doctype": "DocField",
@ -248,6 +160,162 @@
"label": "Payables"
},
{
"doctype": "DocPerm"
"doctype": "DocField",
"fieldname": "buying_module",
"fieldtype": "Column Break",
"label": "Buying"
},
{
"doctype": "DocField",
"fieldname": "new_purchase_requests",
"fieldtype": "Check",
"label": "New Purchase Requests"
},
{
"doctype": "DocField",
"fieldname": "new_supplier_quotations",
"fieldtype": "Check",
"label": "New Supplier Quotations"
},
{
"doctype": "DocField",
"fieldname": "new_purchase_orders",
"fieldtype": "Check",
"label": "New Purchase Orders"
},
{
"doctype": "DocField",
"fieldname": "selling_module",
"fieldtype": "Column Break",
"label": "Selling"
},
{
"doctype": "DocField",
"fieldname": "new_leads",
"fieldtype": "Check",
"label": "New Leads"
},
{
"doctype": "DocField",
"fieldname": "new_enquiries",
"fieldtype": "Check",
"label": "New Enquiries"
},
{
"doctype": "DocField",
"fieldname": "new_quotations",
"fieldtype": "Check",
"label": "New Quotations"
},
{
"doctype": "DocField",
"fieldname": "new_sales_orders",
"fieldtype": "Check",
"label": "New Sales Orders"
},
{
"doctype": "DocField",
"fieldname": "section_break_34",
"fieldtype": "Section Break",
"options": "Simple"
},
{
"doctype": "DocField",
"fieldname": "stock_module",
"fieldtype": "Column Break",
"label": "Stock"
},
{
"doctype": "DocField",
"fieldname": "new_delivery_notes",
"fieldtype": "Check",
"label": "New Delivery Notes"
},
{
"doctype": "DocField",
"fieldname": "new_purchase_receipts",
"fieldtype": "Check",
"label": "New Purchase Receipts"
},
{
"doctype": "DocField",
"fieldname": "new_stock_entries",
"fieldtype": "Check",
"label": "New Stock Entries"
},
{
"doctype": "DocField",
"fieldname": "support_module",
"fieldtype": "Column Break",
"label": "Support"
},
{
"doctype": "DocField",
"fieldname": "new_support_tickets",
"fieldtype": "Check",
"label": "New Support Tickets"
},
{
"doctype": "DocField",
"fieldname": "open_tickets",
"fieldtype": "Check",
"label": "Open Tickets"
},
{
"doctype": "DocField",
"fieldname": "new_communications",
"fieldtype": "Check",
"label": "New Communications"
},
{
"doctype": "DocField",
"fieldname": "projects_module",
"fieldtype": "Column Break",
"label": "Projects"
},
{
"doctype": "DocField",
"fieldname": "new_projects",
"fieldtype": "Check",
"label": "New Projects"
},
{
"doctype": "DocField",
"fieldname": "section_break_41",
"fieldtype": "Section Break",
"options": "Simple"
},
{
"doctype": "DocField",
"fieldname": "utilities_module",
"fieldtype": "Column Break",
"label": "General"
},
{
"doctype": "DocField",
"fieldname": "calendar_events",
"fieldtype": "Check",
"label": "Calendar Events"
},
{
"doctype": "DocField",
"fieldname": "todo_list",
"fieldtype": "Check",
"label": "To Do List"
},
{
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"permlevel": 0,
"report": 1,
"write": 1
},
{
"amend": 0,
"cancel": 0,
"create": 0,
"doctype": "DocPerm",
"permlevel": 1
}
]