@@ -48,6 +48,7 @@ frappe.ui.form.on("Email Alert", { | |||||
}, | }, | ||||
refresh: function(frm) { | refresh: function(frm) { | ||||
frappe.email_alert.setup_fieldname_select(frm); | frappe.email_alert.setup_fieldname_select(frm); | ||||
frm.trigger('event'); | |||||
}, | }, | ||||
document_type: function(frm) { | document_type: function(frm) { | ||||
frappe.email_alert.setup_fieldname_select(frm); | frappe.email_alert.setup_fieldname_select(frm); | ||||
@@ -55,5 +56,24 @@ frappe.ui.form.on("Email Alert", { | |||||
view_properties: function(frm) { | view_properties: function(frm) { | ||||
frappe.route_options = {doc_type:frm.doc.document_type}; | frappe.route_options = {doc_type:frm.doc.document_type}; | ||||
frappe.set_route("Form", "Customize Form"); | 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')); | |||||
} | |||||
} | |||||
}); | |||||
}); | |||||
} | |||||
} | } | ||||
}); | }); |
@@ -4,9 +4,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
import json | import json | ||||
import re | |||||
from frappe import _ | from frappe import _ | ||||
from jinja2 import Template | |||||
from frappe.model.document import Document | from frappe.model.document import Document | ||||
from frappe.utils import validate_email_add, nowdate | from frappe.utils import validate_email_add, nowdate | ||||
from frappe.utils.jinja import validate_template | from frappe.utils.jinja import validate_template | ||||
@@ -24,10 +22,9 @@ class EmailAlert(Document): | |||||
self.validate_forbidden_types() | self.validate_forbidden_types() | ||||
self.validate_condition() | self.validate_condition() | ||||
def validate_condition(self): | def validate_condition(self): | ||||
temp_doc = frappe.new_doc(self.document_type) | |||||
temp_doc = frappe.new_doc(self.document_type) | |||||
if self.condition: | if self.condition: | ||||
try: | try: | ||||
eval(self.condition, get_context(temp_doc)) | 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)) | 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(): | def trigger_daily_alerts(): | ||||
trigger_email_alerts(None, "daily") | 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` | for alert in frappe.db.sql_list("""select name from `tabEmail Alert` | ||||
where event in ('Days Before', 'Days After') and enabled=1"""): | where event in ('Days Before', 'Days After') and enabled=1"""): | ||||
alert = frappe.get_doc("Email Alert", alert) | 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: | else: | ||||
if method in ("on_update", "validate") and doc.flags.in_insert: | if method in ("on_update", "validate") and doc.flags.in_insert: | ||||
# don't call email alerts multiple times for inserts | # don't call email alerts multiple times for inserts | ||||
@@ -24,6 +24,9 @@ | |||||
.data-row.row { | .data-row.row { | ||||
margin: 0px; | margin: 0px; | ||||
} | } | ||||
.data-row textarea { | |||||
height: 40px !important; | |||||
} | |||||
.grid-body { | .grid-body { | ||||
background-color: #fff; | background-color: #fff; | ||||
} | } | ||||
@@ -279,7 +279,7 @@ frappe.ui.form.Grid = Class.extend({ | |||||
return this.fieldinfo[fieldname]; | return this.fieldinfo[fieldname]; | ||||
}, | }, | ||||
set_value: function(fieldname, value, doc) { | 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); | this.grid_rows_by_docname[doc.name].refresh_field(fieldname); | ||||
} | } | ||||
}, | }, | ||||
@@ -65,8 +65,9 @@ frappe.ui.Dialog = frappe.ui.FieldGroup.extend({ | |||||
}, | }, | ||||
focus_on_first_input: function() { | 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; | return false; | ||||
} | } | ||||
}); | }); | ||||
@@ -48,7 +48,6 @@ frappe.views.CommunicationComposer = Class.extend({ | |||||
get_fields: function() { | get_fields: function() { | ||||
return [ | return [ | ||||
{fieldtype: "Section Break"}, | |||||
{label:__("To"), fieldtype:"Data", reqd: 0, fieldname:"recipients"}, | {label:__("To"), fieldtype:"Data", reqd: 0, fieldname:"recipients"}, | ||||
{fieldtype: "Section Break", collapsible: 1, label: "CC & Standard Reply"}, | {fieldtype: "Section Break", collapsible: 1, label: "CC & Standard Reply"}, | ||||
{label:__("CC"), fieldtype:"Data", fieldname:"cc"}, | {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) | $(this.dialog.fields_dict.recipients.input).add(this.dialog.fields_dict.cc.input) | ||||
.bind( "keydown", function(event) { | .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(); | event.preventDefault(); | ||||
} | } | ||||
}) | }) | ||||
@@ -499,7 +497,7 @@ frappe.views.CommunicationComposer = Class.extend({ | |||||
}, | }, | ||||
appendTo: this.dialog.$wrapper, | appendTo: this.dialog.$wrapper, | ||||
focus: function() { | focus: function() { | ||||
event.preventDefault(); | |||||
return false; | |||||
}, | }, | ||||
select: function( event, ui ) { | select: function( event, ui ) { | ||||
var terms = split( this.value ); | var terms = split( this.value ); | ||||
@@ -29,6 +29,10 @@ | |||||
margin: 0px; | margin: 0px; | ||||
} | } | ||||
.data-row textarea { | |||||
height: 40px !important; | |||||
} | |||||
.grid-body { | .grid-body { | ||||
background-color: #fff; | background-color: #fff; | ||||
} | } | ||||