[ux] email alert, fix moduleview, speed of loading

This commit is contained in:
Rushabh Mehta 2015-03-25 16:26:47 +05:30
parent 8fb3e0bfb2
commit b4cf9f7706
16 changed files with 133 additions and 62 deletions

View file

@ -10,6 +10,7 @@ import frappe
import frappe.defaults
import frappe.desk.desk_page
from frappe.utils import get_gravatar
from frappe.desk.form.load import get_meta_bundle
def get_bootinfo():
"""build and return boot info"""
@ -50,6 +51,7 @@ def get_bootinfo():
add_timezone_info(bootinfo)
load_conf_settings(bootinfo)
load_print(bootinfo, doclist)
doclist.append(get_meta_bundle("Page"))
# ipinfo
if frappe.session['data'].get('ipinfo'):

View file

@ -19,12 +19,7 @@
"depends_on": "doc_type",
"fieldname": "properties",
"fieldtype": "Section Break",
"label": "Properties",
"permlevel": 0
},
{
"fieldname": "column_break0",
"fieldtype": "Column Break",
"label": "",
"permlevel": 0
},
{
@ -48,22 +43,19 @@
"search_index": 0
},
{
"fieldname": "sort_field",
"fieldtype": "Select",
"label": "Sort Field",
"permlevel": 0
},
{
"fieldname": "sort_order",
"fieldtype": "Select",
"label": "Sort Order",
"options": "ASC\nDESC",
"permlevel": 0
},
{
"fieldname": "column_break1",
"fieldname": "column_break_5",
"fieldtype": "Column Break",
"permlevel": 0
"permlevel": 0,
"precision": ""
},
{
"depends_on": "",
"fieldname": "max_attachments",
"fieldtype": "Int",
"label": "Max Attachments",
"no_copy": 0,
"permlevel": 0,
"search_index": 0
},
{
"fieldname": "allow_copy",
@ -74,13 +66,30 @@
"search_index": 0
},
{
"depends_on": "",
"fieldname": "max_attachments",
"fieldtype": "Int",
"label": "Max Attachments",
"no_copy": 0,
"depends_on": "doc_type",
"fieldname": "section_break_8",
"fieldtype": "Section Break",
"permlevel": 0,
"search_index": 0
"precision": ""
},
{
"fieldname": "sort_field",
"fieldtype": "Select",
"label": "Sort Field",
"permlevel": 0
},
{
"fieldname": "column_break_10",
"fieldtype": "Column Break",
"permlevel": 0,
"precision": ""
},
{
"fieldname": "sort_order",
"fieldtype": "Select",
"label": "Sort Order",
"options": "ASC\nDESC",
"permlevel": 0
},
{
"depends_on": "doc_type",
@ -104,7 +113,7 @@
"icon": "icon-glass",
"idx": 1,
"issingle": 1,
"modified": "2015-03-20 07:13:20.652676",
"modified": "2015-03-25 06:18:19.010091",
"modified_by": "Administrator",
"module": "Custom",
"name": "Customize Form",

View file

@ -186,13 +186,26 @@ def set_last_modified(data):
item["last_modified"] = get_last_modified(item["name"])
def get_last_modified(doctype):
try:
last_modified = frappe.get_all(doctype, fields=["max(modified)"], as_list=True, limit_page_length=1)[0][0]
except Exception, e:
if e.args[0]==1146:
last_modified = None
else:
raise
def _get():
try:
last_modified = frappe.get_all(doctype, fields=["max(modified)"], as_list=True, limit_page_length=1)[0][0]
except Exception, e:
if e.args[0]==1146:
last_modified = None
else:
raise
# hack: save as -1 so that it is cached
if last_modified==None:
last_modified = -1
return last_modified
last_modified = frappe.cache().get_value("last_modified:" + doctype, _get)
if last_modified==-1:
last_modified = None
return last_modified
def get_report_list(module, is_standard="No"):

View file

@ -83,16 +83,6 @@
"search_index": 0,
"set_only_once": 0
},
{
"description": "Append as communication against this DocType (must have fields, \"Status\", \"Subject\")",
"fieldname": "append_to",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Append To",
"options": "DocType",
"permlevel": 0,
"precision": ""
},
{
"allow_on_submit": 0,
"fieldname": "mailbox_settings",
@ -184,6 +174,17 @@
"permlevel": 0,
"precision": ""
},
{
"depends_on": "enable_incoming",
"description": "Append as communication against this DocType (must have fields, \"Status\", \"Subject\")",
"fieldname": "append_to",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Append To",
"options": "DocType",
"permlevel": 0,
"precision": ""
},
{
"depends_on": "enable_incoming",
"description": "e.g. replies@yourcomany.com. All replies will come to this inbox.",
@ -403,7 +404,7 @@
"is_submittable": 0,
"issingle": 0,
"istable": 0,
"modified": "2015-03-23 02:09:54.864019",
"modified": "2015-03-25 05:32:14.036800",
"modified_by": "Administrator",
"module": "Email",
"name": "Email Account",

View file

@ -195,6 +195,10 @@ class EmailAccount(Document):
out = [e.strip() for e in self.send_notification_to.split("\n")]
return out
def on_trash(self):
"""Clear communications where email account is linked"""
frappe.db.sql("update `tabCommunication` set email_account='' where email_account=%s", self.name)
def pull(now=False):
"""Will be called via scheduler, pull emails from all enabled POP3 email accounts."""
import frappe.tasks

View file

@ -32,10 +32,15 @@ frappe.email_alert = {
}
}
frappe.ui.form.on("Email Alert", "refresh", function(frm) {
frappe.email_alert.setup_fieldname_select(frm);
});
frappe.ui.form.on("Email Alert", "document_type", function(frm) {
frappe.email_alert.setup_fieldname_select(frm);
frappe.ui.form.on("Email Alert", {
refresh: function(frm) {
frappe.email_alert.setup_fieldname_select(frm);
},
document_type: function(frm) {
frappe.email_alert.setup_fieldname_select(frm);
},
view_properties: function(frm) {
frappe.route_options = {doc_type:frm.doc.document_type};
frappe.set_route("Form", "Customize Form");
}
});

View file

@ -41,26 +41,26 @@
"fieldtype": "Select",
"in_list_view": 1,
"label": "Send Alert On",
"options": "\nNew\nSave\nSubmit\nCancel\nDate Change\nValue Change",
"options": "\nNew\nSave\nSubmit\nCancel\nDays After\nDays Before\nValue Change",
"permlevel": 0,
"reqd": 1,
"search_index": 1
},
{
"depends_on": "eval:doc.event==\"Date Change\"",
"depends_on": "eval:doc.event==\"Days After\" || doc.event==\"Days Before\"",
"description": "Send alert if date matches this field's value",
"fieldname": "date_changed",
"fieldtype": "Select",
"label": "Date Changed",
"label": "Reference Date",
"permlevel": 0
},
{
"default": "0",
"depends_on": "eval:doc.event==\"Date Change\"",
"description": "[Optional] Send the email X days in advance of the specified date. 0 equals same day.",
"depends_on": "eval:doc.event==\"Days After\" || doc.event==\"Days Before\"",
"description": "Send days before or after the reference date",
"fieldname": "days_in_advance",
"fieldtype": "Int",
"label": "Days in Advance",
"label": "Days Before or After",
"permlevel": 0
},
{
@ -131,10 +131,17 @@
"label": "Message Examples",
"options": "<h5>Message Example (Markdown)</h5>\n<pre>Transaction {{ doc.name }} has exceeded Due Date. Please take relevant action\n\n#### Details\n\nCustomer: {{ doc.customer }}\nAmount: {{ doc.total_amount }}</pre>",
"permlevel": 0
},
{
"fieldname": "view_properties",
"fieldtype": "Button",
"label": "View Properties (via Customize Form)",
"permlevel": 0,
"precision": ""
}
],
"icon": "icon-envelope",
"modified": "2015-03-11 16:43:51.288063",
"modified": "2015-03-25 06:20:07.472953",
"modified_by": "Administrator",
"module": "Email",
"name": "Email Alert",

View file

@ -27,15 +27,20 @@ def trigger_email_alerts(doc, method=None):
# don't send email alerts while syncing or patching
return
if method=="Date Change":
if method in ("Days Before", "Days After"):
for alert in frappe.db.sql_list("""select name from `tabEmail Alert`
where event='Date Change' and enabled=1"""):
alert = frappe.get_doc("Email Alert", alert)
diff_days = alert.days_in_advance
if method=="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(), alert.days_in_advance or 0)):
(nowdate(), diff_days or 0)):
evaluate_alert(frappe.get_doc(alert.document_type, name),
alert, "Date Change")

View file

@ -577,6 +577,8 @@ class Document(BaseDocument):
elif self._action=="update_after_submit":
self.run_method("on_update_after_submit")
frappe.cache().set_value("last_modified:" + self.doctype, self.modified)
def check_no_back_links_exist(self):
"""Check if document links to any active document before Cancel."""

View file

@ -67,3 +67,4 @@ frappe.patches.v5_0.update_shared
frappe.patches.v5_0.bookmarks_to_stars
frappe.patches.v5_0.style_settings_to_website_theme
frappe.patches.v5_0.rename_ref_type_fieldnames
frappe.patches.v5_0.fix_email_alert

View file

@ -0,0 +1,16 @@
from __future__ import unicode_literals
import frappe
def execute():
frappe.reload_doctype("Email Alert")
for e in frappe.get_all("Email Alert"):
email_alert = frappe.get_doc("Email Alert", e.name)
if email_alert.event == "Date Change":
if email_alert.days_in_advance < 0:
email_alert.event = "Days After"
email_alert.days_in_advance = -email_alert.days_in_advance
else:
email_alert.event = "Days Before"
email_alert.save()

View file

@ -114,6 +114,7 @@ body[data-route^="Module"] .main-menu .form-sidebar {
}
.sidebar-menu li {
position: relative;
margin-bottom: 7px;
}
.form-sidebar .form-tags .tag-area {
margin-top: -3px;

View file

@ -455,6 +455,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({
me.set_working(true);
return frappe.call({
method: 'frappe.desk.reportview.delete_items',
freeze: true,
args: {
items: $.map(dl, function(d, i) { return d.name }),
doctype: me.doctype

View file

@ -120,6 +120,8 @@ frappe.ui.Listing = Class.extend({
if(this.new_doctype) {
var make_new_doc = function() { (me.custom_new_doc || me.make_new_doc).apply(me, [me.new_doctype]); };
this.page.set_primary_action(__("New"), function() { make_new_doc(); }, "octicon octicon-plus");
} else {
this.page.clear_primary_action();
}
},
@ -171,6 +173,7 @@ frappe.ui.Listing = Class.extend({
return frappe.call({
method: this.opts.method || 'frappe.desk.query_builder.runquery',
type: "GET",
freeze: true,
args: this.get_call_args(),
callback: function(r) {
if(!me.opts.no_loading)

View file

@ -81,6 +81,7 @@ body[data-route^="Module"] .main-menu {
li {
position: relative;
margin-bottom: 7px;
}
}

View file

@ -119,7 +119,7 @@ def add_index(out, context):
next_item = context.doc.get_next()
if next_item:
if next_item.name[0]!="/": next_item.name = "/" + next_item.name
html = ('<p><br><a href="{name}">'+_("Next")+': {title}</a></p>').format(**next_item)
html = ('<p><br><a class="btn-next" href="{name}">'+_("Next")+': {title}</a></p>').format(**next_item)
out["content"] = out["content"].replace("{next}", html)
def add_hero(out, context):