From b6214715e5f16db0ccb9ffec7ad4ab59d943d1ed Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Fri, 3 Jun 2016 15:57:18 +0530 Subject: [PATCH] [ux] email alert - show tasks for today, fix for multiple address selection in email, fixes frappe/erpnext#5436 --- .../email/doctype/email_alert/email_alert.js | 20 ++++++++ .../email/doctype/email_alert/email_alert.py | 46 ++++++++++++------- frappe/public/css/form_grid.css | 3 ++ frappe/public/js/frappe/form/grid.js | 2 +- frappe/public/js/frappe/ui/dialog.js | 5 +- .../public/js/frappe/views/communication.js | 8 ++-- frappe/public/less/form_grid.less | 4 ++ 7 files changed, 64 insertions(+), 24 deletions(-) diff --git a/frappe/email/doctype/email_alert/email_alert.js b/frappe/email/doctype/email_alert/email_alert.js index 87228eeabc..67b7737ed1 100755 --- a/frappe/email/doctype/email_alert/email_alert.js +++ b/frappe/email/doctype/email_alert/email_alert.js @@ -48,6 +48,7 @@ frappe.ui.form.on("Email Alert", { }, refresh: function(frm) { frappe.email_alert.setup_fieldname_select(frm); + frm.trigger('event'); }, document_type: function(frm) { frappe.email_alert.setup_fieldname_select(frm); @@ -55,5 +56,24 @@ frappe.ui.form.on("Email Alert", { view_properties: function(frm) { frappe.route_options = {doc_type:frm.doc.document_type}; frappe.set_route("Form", "Customize Form"); + }, + event: function(frm) { + if(in_list(['Days Before', 'Days After'], frm.doc.event)) { + frm.add_custom_button(__('Get Alerts for Today'), function() { + frappe.call({ + method: 'frappe.email.doctype.email_alert.email_alert.get_documents_for_today', + args: { + email_alert: frm.doc.name + }, + callback: function(r) { + if(r.message) { + msgprint(r.message); + } else { + msgprint(__('No alerts for today')); + } + } + }); + }); + } } }); diff --git a/frappe/email/doctype/email_alert/email_alert.py b/frappe/email/doctype/email_alert/email_alert.py index 9f9c0f2f52..066f143357 100755 --- a/frappe/email/doctype/email_alert/email_alert.py +++ b/frappe/email/doctype/email_alert/email_alert.py @@ -4,9 +4,7 @@ from __future__ import unicode_literals import frappe import json -import re from frappe import _ -from jinja2 import Template from frappe.model.document import Document from frappe.utils import validate_email_add, nowdate from frappe.utils.jinja import validate_template @@ -24,10 +22,9 @@ class EmailAlert(Document): self.validate_forbidden_types() self.validate_condition() - def validate_condition(self): - temp_doc = frappe.new_doc(self.document_type) + temp_doc = frappe.new_doc(self.document_type) if self.condition: try: eval(self.condition, get_context(temp_doc)) @@ -42,6 +39,33 @@ class EmailAlert(Document): frappe.throw(_("Cannot set Email Alert on Document Type {0}").format(self.document_type)) + def get_documents_for_today(self): + '''get list of documents that will be triggered today''' + docs = [] + + diff_days = self.days_in_advance + if self.event=="Days After": + diff_days = -diff_days + + for name in frappe.db.sql_list("""select name from `tab{0}` where + DATE(`{1}`) = ADDDATE(DATE(%s), INTERVAL %s DAY)""".format(self.document_type, + self.date_changed), (nowdate(), diff_days or 0)): + + doc = frappe.get_doc(self.document_type, name) + + if self.condition and not eval(self.condition, get_context(doc)): + continue + + docs.append(doc) + + return docs + +@frappe.whitelist() +def get_documents_for_today(email_alert): + email_alert = frappe.get_doc('Email Alert', email_alert) + email_alert.check_permission('read') + return [d.name for d in email_alert.get_documents_for_today()] + def trigger_daily_alerts(): trigger_email_alerts(None, "daily") @@ -55,19 +79,9 @@ def trigger_email_alerts(doc, method=None): for alert in frappe.db.sql_list("""select name from `tabEmail Alert` where event in ('Days Before', 'Days After') and enabled=1"""): - alert = frappe.get_doc("Email Alert", alert) - - diff_days = alert.days_in_advance - if alert.event=="Days After": - diff_days = -diff_days - - for name in frappe.db.sql_list("""select name from `tab{0}` where - DATE(`{1}`) = ADDDATE(DATE(%s), INTERVAL %s DAY)""".format(alert.document_type, alert.date_changed), - (nowdate(), diff_days or 0)): - - evaluate_alert(frappe.get_doc(alert.document_type, name), - alert, alert.event) + for doc in alert.get_documents_for_today(): + evaluate_alert(doc, alert, alert.event) else: if method in ("on_update", "validate") and doc.flags.in_insert: # don't call email alerts multiple times for inserts diff --git a/frappe/public/css/form_grid.css b/frappe/public/css/form_grid.css index 2fe53877cd..c9fa89aab5 100644 --- a/frappe/public/css/form_grid.css +++ b/frappe/public/css/form_grid.css @@ -24,6 +24,9 @@ .data-row.row { margin: 0px; } +.data-row textarea { + height: 40px !important; +} .grid-body { background-color: #fff; } diff --git a/frappe/public/js/frappe/form/grid.js b/frappe/public/js/frappe/form/grid.js index 958efd691c..8e860a3acf 100644 --- a/frappe/public/js/frappe/form/grid.js +++ b/frappe/public/js/frappe/form/grid.js @@ -279,7 +279,7 @@ frappe.ui.form.Grid = Class.extend({ return this.fieldinfo[fieldname]; }, set_value: function(fieldname, value, doc) { - if(this.display_status!=="None") { + if(this.display_status!=="None" && this.grid_rows_by_docname[doc.name]) { this.grid_rows_by_docname[doc.name].refresh_field(fieldname); } }, diff --git a/frappe/public/js/frappe/ui/dialog.js b/frappe/public/js/frappe/ui/dialog.js index 1e59706cf3..a1921835dc 100644 --- a/frappe/public/js/frappe/ui/dialog.js +++ b/frappe/public/js/frappe/ui/dialog.js @@ -65,8 +65,9 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({ }, focus_on_first_input: function() { - this.fields_list.every(function(f) { - if(!in_list(['Date', 'Datetime', 'Time'], f.df.fieldtype) && f.set_focus()) { + $.each(this.fields_list, function(i, f) { + if(!in_list(['Date', 'Datetime', 'Time'], f.df.fieldtype) && f.set_focus) { + f.set_focus(); return false; } }); diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 63d6c04cc2..654de7ef20 100644 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -48,7 +48,6 @@ frappe.views.CommunicationComposer = Class.extend({ get_fields: function() { return [ - {fieldtype: "Section Break"}, {label:__("To"), fieldtype:"Data", reqd: 0, fieldname:"recipients"}, {fieldtype: "Section Break", collapsible: 1, label: "CC & Standard Reply"}, {label:__("CC"), fieldtype:"Data", fieldname:"cc"}, @@ -475,9 +474,8 @@ frappe.views.CommunicationComposer = Class.extend({ $(this.dialog.fields_dict.recipients.input).add(this.dialog.fields_dict.cc.input) .bind( "keydown", function(event) { - if (event.keyCode === $.ui.keyCode.TAB && - $(this).data( "autocomplete" ) && - $(this).data( "autocomplete" ).menu.active ) { + if (event.keyCode === $.ui.keyCode.TAB && + $(this).autocomplete("instance").menu.active) { event.preventDefault(); } }) @@ -499,7 +497,7 @@ frappe.views.CommunicationComposer = Class.extend({ }, appendTo: this.dialog.$wrapper, focus: function() { - event.preventDefault(); + return false; }, select: function( event, ui ) { var terms = split( this.value ); diff --git a/frappe/public/less/form_grid.less b/frappe/public/less/form_grid.less index 4822cda6b6..f5578a367b 100644 --- a/frappe/public/less/form_grid.less +++ b/frappe/public/less/form_grid.less @@ -29,6 +29,10 @@ margin: 0px; } +.data-row textarea { + height: 40px !important; +} + .grid-body { background-color: #fff; }