Merge pull request #1190 from anandpdoshi/hotfix-scheduler-errors

[minor] [scheduler] send scheduler errors as email digest
This commit is contained in:
Pratik Vyas 2013-12-16 22:18:43 -08:00
commit 60ec93811e
9 changed files with 119 additions and 34 deletions

View File

@ -0,0 +1,23 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
def execute():
from webnotes.profile import get_system_managers
system_managers = get_system_managers(only_name=True)
if not system_managers:
return
# scheduler errors digest
edigest = webnotes.new_bean("Email Digest")
edigest.doc.fields.update({
"name": "Scheduler Errors",
"company": webnotes.conn.get_default("company"),
"frequency": "Daily",
"enabled": 1,
"recipient_list": "\n".join(system_managers),
"scheduler_errors": 1
})
edigest.insert()

View File

@ -0,0 +1,11 @@
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import webnotes
def execute():
from webnotes.utils import extract_email_id
for name, recipients in webnotes.conn.sql("""select name, recipient_list from `tabEmail Digest`"""):
recipients = "\n".join([extract_email_id(r) for r in recipients.split("\n")])
webnotes.conn.set_value("Email Digest", name, "recipient_list", recipients)

View File

@ -258,4 +258,6 @@ patch_list = [
"execute:webnotes.delete_doc('Report', 'Stock Ledger') #2013-11-29", "execute:webnotes.delete_doc('Report', 'Stock Ledger') #2013-11-29",
"execute:webnotes.delete_doc('Report', 'Payment Collection With Ageing')", "execute:webnotes.delete_doc('Report', 'Payment Collection With Ageing')",
"execute:webnotes.delete_doc('Report', 'Payment Made With Ageing')", "execute:webnotes.delete_doc('Report', 'Payment Made With Ageing')",
"patches.1311.p07_scheduler_errors_digest",
"patches.1311.p08_email_digest_recipients",
] ]

View File

@ -70,8 +70,10 @@ cur_frm.cscript.addremove_recipients = function(doc, dt, dn) {
check.checked = 1; check.checked = 1;
add_or_update = 'Update'; add_or_update = 'Update';
} }
var fullname = wn.user.full_name(v.name);
if(fullname !== v.name) v.name = fullname + " <" + v.name + ">";
if(v.enabled==0) { if(v.enabled==0) {
v.name = "<span style='color: red'>" + v.name + " (disabled user)</span>" v.name = repl("<span style='color: red'> %(name)s (disabled user)</span>", {name: v.name});
} }
var profile = $a($td(tab, i+1, 1), 'span', '', '', v.name); var profile = $a($td(tab, i+1, 1), 'span', '', '', v.name);
//profile.onclick = function() { check.checked = !check.checked; } //profile.onclick = function() { check.checked = !check.checked; }

View File

@ -19,16 +19,16 @@ content_sequence = [
["Selling", ["new_leads", "new_enquiries", "new_quotations", "new_sales_orders"]], ["Selling", ["new_leads", "new_enquiries", "new_quotations", "new_sales_orders"]],
["Stock", ["new_delivery_notes", "new_purchase_receipts", "new_stock_entries"]], ["Stock", ["new_delivery_notes", "new_purchase_receipts", "new_stock_entries"]],
["Support", ["new_communications", "new_support_tickets", "open_tickets"]], ["Support", ["new_communications", "new_support_tickets", "open_tickets"]],
["Projects", ["new_projects"]] ["Projects", ["new_projects"]],
["System", ["scheduler_errors"]],
] ]
user_specific_content = ["calendar_events", "todo_list"] user_specific_content = ["calendar_events", "todo_list"]
digest_template = """\ digest_template = """<style>p.ed-indent { margin-right: 17px; }</style>
<style>p.ed-indent { margin-right: 17px; }</style> <h2>%(name)s</h2>
<h2>%(digest)s</h2>
<p style='color: grey'>%(date)s</p>
<h4>%(company)s</h4> <h4>%(company)s</h4>
<p style='color: grey'>%(date)s</p>
<hr> <hr>
%(with_value)s %(with_value)s
%(no_value)s %(no_value)s
@ -53,10 +53,10 @@ class DocType(DocListController):
def get_profiles(self): def get_profiles(self):
"""get list of profiles""" """get list of profiles"""
import webnotes
profile_list = webnotes.conn.sql(""" profile_list = webnotes.conn.sql("""
select name, enabled from tabProfile select name, enabled from tabProfile
where docstatus=0 and name not in ('Administrator', 'Guest') where docstatus=0 and name not in ('Administrator', 'Guest')
and user_type = "System User"
order by enabled desc, name asc""", as_dict=1) order by enabled desc, name asc""", as_dict=1)
if self.doc.recipient_list: if self.doc.recipient_list:
@ -81,7 +81,9 @@ class DocType(DocListController):
msg_for_this_receipient = self.get_msg_html(self.get_user_specific_content(user_id) + \ msg_for_this_receipient = self.get_msg_html(self.get_user_specific_content(user_id) + \
common_msg) common_msg)
from webnotes.utils.email_lib import sendmail from webnotes.utils.email_lib import sendmail
sendmail(recipients=user_id, subject="[ERPNext] " + (self.doc.frequency + " Digest"), sendmail(recipients=user_id,
subject="[ERPNext] [{frequency} Digest] {name}".format(
frequency=self.doc.frequency, name=self.doc.name),
msg=msg_for_this_receipient) msg=msg_for_this_receipient)
def get_digest_msg(self): def get_digest_msg(self):
@ -123,7 +125,7 @@ class DocType(DocListController):
if with_value: if with_value:
with_value = "\n".join(with_value) with_value = "\n".join(with_value)
else: else:
with_value = "<p>There were no updates in the items selected for this digest.</p>" with_value = "<p>There were no updates in the items selected for this digest.</p><hr>"
# seperate out no value items # seperate out no value items
no_value = [o[1] for o in out if not o[0]] no_value = [o[1] for o in out if not o[0]]
@ -138,7 +140,8 @@ class DocType(DocListController):
"date": date, "date": date,
"company": self.doc.company, "company": self.doc.company,
"with_value": with_value, "with_value": with_value,
"no_value": no_value or "" "no_value": no_value or "",
"name": self.doc.name
} }
return msg return msg
@ -453,6 +456,10 @@ class DocType(DocListController):
else: else:
return 0, "No Open Tickets!" return 0, "No Open Tickets!"
def get_scheduler_errors(self):
import webnotes.utils.scheduler
return webnotes.utils.scheduler.get_error_report(self.from_date, self.to_date)
def onload(self): def onload(self):
self.get_next_sending() self.get_next_sending()

View File

@ -2,7 +2,7 @@
{ {
"creation": "2013-02-21 14:15:31", "creation": "2013-02-21 14:15:31",
"docstatus": 0, "docstatus": 0,
"modified": "2013-07-05 14:36:13", "modified": "2013-12-16 12:37:43",
"modified_by": "Administrator", "modified_by": "Administrator",
"owner": "Administrator" "owner": "Administrator"
}, },
@ -100,11 +100,10 @@
"label": "Add/Remove Recipients" "label": "Add/Remove Recipients"
}, },
{ {
"description": "Check all the items below that you want to send in this digest.",
"doctype": "DocField", "doctype": "DocField",
"fieldname": "select_digest_content", "fieldname": "accounts",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"label": "Select Digest Content" "label": "Accounts"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
@ -178,7 +177,7 @@
"doctype": "DocField", "doctype": "DocField",
"fieldname": "section_break_20", "fieldname": "section_break_20",
"fieldtype": "Section Break", "fieldtype": "Section Break",
"options": "Simple" "label": "Buying & Selling"
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
@ -234,6 +233,12 @@
"fieldtype": "Check", "fieldtype": "Check",
"label": "New Sales Orders" "label": "New Sales Orders"
}, },
{
"doctype": "DocField",
"fieldname": "section_break_34",
"fieldtype": "Section Break",
"label": "Inventory & Support"
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "stock_module", "fieldname": "stock_module",
@ -258,12 +263,6 @@
"fieldtype": "Check", "fieldtype": "Check",
"label": "New Stock Entries" "label": "New Stock Entries"
}, },
{
"doctype": "DocField",
"fieldname": "section_break_34",
"fieldtype": "Section Break",
"options": "Simple"
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "support_module", "fieldname": "support_module",
@ -288,6 +287,12 @@
"fieldtype": "Check", "fieldtype": "Check",
"label": "New Communications" "label": "New Communications"
}, },
{
"doctype": "DocField",
"fieldname": "section_break_40",
"fieldtype": "Section Break",
"label": "Projects & System"
},
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "projects_module", "fieldname": "projects_module",
@ -302,7 +307,25 @@
}, },
{ {
"doctype": "DocField", "doctype": "DocField",
"fieldname": "utilities_module", "fieldname": "core_module",
"fieldtype": "Column Break",
"label": "System"
},
{
"doctype": "DocField",
"fieldname": "scheduler_errors",
"fieldtype": "Check",
"label": "Scheduler Failed Events"
},
{
"doctype": "DocField",
"fieldname": "user_specific",
"fieldtype": "Section Break",
"label": "User Specific"
},
{
"doctype": "DocField",
"fieldname": "general",
"fieldtype": "Column Break", "fieldtype": "Column Break",
"label": "General" "label": "General"
}, },
@ -318,6 +341,12 @@
"fieldtype": "Check", "fieldtype": "Check",
"label": "To Do List" "label": "To Do List"
}, },
{
"doctype": "DocField",
"fieldname": "stub",
"fieldtype": "Column Break",
"label": "Stub"
},
{ {
"cancel": 1, "cancel": 1,
"create": 1, "create": 1,

View File

@ -171,7 +171,7 @@ def create_feed_and_todo():
def create_email_digest(): def create_email_digest():
from webnotes.profile import get_system_managers from webnotes.profile import get_system_managers
system_managers = get_system_managers() system_managers = get_system_managers(only_name=True)
if not system_managers: if not system_managers:
return return
@ -186,10 +186,23 @@ def create_email_digest():
}) })
for fieldname in edigest.meta.get_fieldnames({"fieldtype": "Check"}): for fieldname in edigest.meta.get_fieldnames({"fieldtype": "Check"}):
if fieldname != "scheduler_errors":
edigest.doc.fields[fieldname] = 1 edigest.doc.fields[fieldname] = 1
edigest.insert() edigest.insert()
# scheduler errors digest
edigest = webnotes.new_bean("Email Digest")
edigest.doc.fields.update({
"name": "Scheduler Errors",
"company": webnotes.conn.get_default("company"),
"frequency": "Daily",
"recipient_list": "\n".join(system_managers),
"scheduler_errors": 1,
"enabled": 1
})
edigest.insert()
def get_fy_details(fy_start_date, fy_end_date): def get_fy_details(fy_start_date, fy_end_date):
start_year = getdate(fy_start_date).year start_year = getdate(fy_start_date).year
if start_year == getdate(fy_end_date).year: if start_year == getdate(fy_end_date).year:

View File

@ -14,3 +14,4 @@ def on_method(bean, method):
if bean.doc.doctype=="Stock Entry" and method in ("on_submit", "on_cancel"): if bean.doc.doctype=="Stock Entry" and method in ("on_submit", "on_cancel"):
update_completed_qty(bean.controller, method) update_completed_qty(bean.controller, method)

View File

@ -34,10 +34,6 @@ def execute_daily():
from core.doctype.notification_count.notification_count import delete_notification_count_for from core.doctype.notification_count.notification_count import delete_notification_count_for
delete_notification_count_for("Event") delete_notification_count_for("Event")
# email digest
from setup.doctype.email_digest.email_digest import send
run_fn(send)
# run recurring invoices # run recurring invoices
from accounts.doctype.sales_invoice.sales_invoice import manage_recurring_invoices from accounts.doctype.sales_invoice.sales_invoice import manage_recurring_invoices
run_fn(manage_recurring_invoices) run_fn(manage_recurring_invoices)
@ -54,8 +50,9 @@ def execute_daily():
from stock.utils import reorder_item from stock.utils import reorder_item
run_fn(reorder_item) run_fn(reorder_item)
# scheduler error # email digest
scheduler.report_errors() from setup.doctype.email_digest.email_digest import send
run_fn(send)
def execute_weekly(): def execute_weekly():
from setup.doctype.backup_manager.backup_manager import take_backups_weekly from setup.doctype.backup_manager.backup_manager import take_backups_weekly