diff --git a/public/js/toolbar.js b/public/js/toolbar.js index ed7aff18394..bcd2ddd388f 100644 --- a/public/js/toolbar.js +++ b/public/js/toolbar.js @@ -58,27 +58,32 @@ erpnext.toolbar.add_modules = function() { ').prependTo('.navbar .nav:first'); var modules_list = wn.user.get_desktop_items().sort(); + + var _get_list_item = function(m) { + args = { + module: m, + module_page: wn.modules[m].link, + module_label: wn._(wn.modules[m].label || m), + icon: wn.modules[m].icon + } + + return repl('
  • \ + %(module_label)s
  • ', args); + } // add to dropdown for(var i in modules_list) { var m = modules_list[i] - if(m!='Setup' && wn.boot.profile.allow_modules.indexOf(m)!=-1 && wn.modules[m]) { - args = { - module: m, - module_page: wn.modules[m].link, - module_label: wn._(wn.modules[m].label || m) - } - - $('.navbar .modules').append(repl('
  • %(module_label)s
  • ', args)); + $('.navbar .modules').append(_get_list_item(m)); } } // setup for system manager if(user_roles.indexOf("System Manager")!=-1) { - $('.navbar .modules').append('
  • \ -
  • '+wn._('Setup')+'
  • '); + $('.navbar .modules').append('
  • ' + _get_list_item("Setup")); } } diff --git a/setup/doctype/email_digest/email_digest.py b/setup/doctype/email_digest/email_digest.py index 612677d81ae..a14066963fc 100644 --- a/setup/doctype/email_digest/email_digest.py +++ b/setup/doctype/email_digest/email_digest.py @@ -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", - "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"] +content_sequence = [ + ["Accounts", ["income_year_to_date", "bank_balance", + "income", "expenses_booked", "collections", "payments", + "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 = """

    %(digest)s

    +user_specific_content = ["calendar_events", "todo_list"] + +digest_template = """\ + +

    %(digest)s

    %(date)s

    %(company)s


    @@ -47,6 +56,10 @@ row_template = """

    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,26 +85,49 @@ class DocType: recipients = filter(lambda r: r in valid_users, self.doc.recipient_list.split("\n")) + common_msg = self.get_common_content() if recipients: - from webnotes.utils.email_lib import sendmail - sendmail(recipients=recipients, subject=(self.doc.frequency + " Digest"), - sender="ERPNext Notifications ", - msg=self.get_digest_msg()) - + 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=user_id, subject=(self.doc.frequency + " Digest"), + sender="ERPNext Notifications ", + 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, "

    " + _(module) + "

    "]] + module_out + [[1, "
    "]] + 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)()) - - return self.get_msg_html(out) + out.append(getattr(self, "get_"+ctype)(user_id)) + + 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 = """

    No Updates For:


    """ + "\n".join(no_value) + no_value = """

    No Updates For:

    """ + "\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)) @@ -249,6 +285,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 += """

    %s [%s (%s)]

    """ % \ + (e.subject, datetime_in_user_format(e.starts_on), _("All Day")) + else: + html += "

    %s [%s - %s]

    " % \ + (e.subject, datetime_in_user_format(e.starts_on), datetime_in_user_format(e.ends_on)) + + return html and 1 or 0, "

    Upcoming Calendar Events (max 10):

    " + html + "
    " + + 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 += "

    %s: %s

    " % (todo.priority, todo.description or \ + get_url_to_form(todo.reference_type, todo.reference_name)) + + + return html and 1 or 0, "

    To Do (max 10):

    " + html + "
    " def get_new_count(self, doctype, label, filter_by_company=True): if filter_by_company: @@ -330,6 +399,26 @@ class DocType: to_date = today - relativedelta(days=today.day) 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() diff --git a/setup/doctype/email_digest/email_digest.txt b/setup/doctype/email_digest/email_digest.txt index b03c542db2d..316a840a5dd 100644 --- a/setup/doctype/email_digest/email_digest.txt +++ b/setup/doctype/email_digest/email_digest.txt @@ -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 } ] \ No newline at end of file