@@ -327,7 +327,8 @@ def reset_perms(doctype): | |||||
def generate_hash(txt=None): | def generate_hash(txt=None): | ||||
"""Generates random hash for session id""" | """Generates random hash for session id""" | ||||
import hashlib, time | import hashlib, time | ||||
return hashlib.sha224((txt or "") + repr(time.time())).hexdigest() | |||||
from .utils import random_string | |||||
return hashlib.sha224((txt or "") + repr(time.time()) + repr(random_string(8))).hexdigest() | |||||
def reset_metadata_version(): | def reset_metadata_version(): | ||||
v = generate_hash() | v = generate_hash() | ||||
@@ -6,26 +6,27 @@ frappe.email_alert = { | |||||
} | } | ||||
frappe.model.with_doctype(frm.doc.document_type, function() { | frappe.model.with_doctype(frm.doc.document_type, function() { | ||||
var get_select_options = function(df) { | |||||
return {value: df.fieldname, label: df.fieldname + " (" + __(df.label) + ")"}; | |||||
} | |||||
var fields = frappe.get_doc("DocType", frm.doc.document_type).fields; | var fields = frappe.get_doc("DocType", frm.doc.document_type).fields; | ||||
var options = $.map(fields, | var options = $.map(fields, | ||||
function(d) { return in_list(frappe.model.no_value_type, d.fieldtype) ? | function(d) { return in_list(frappe.model.no_value_type, d.fieldtype) ? | ||||
null : d.fieldname; }); | |||||
options = options.join("\n"); | |||||
null : get_select_options(d); }); | |||||
// set value changed options | // set value changed options | ||||
frm.set_df_property("value_changed", "options", "\n" + options); | |||||
frm.set_df_property("value_changed", "options", [""].concat(options)); | |||||
// set date changed options | // set date changed options | ||||
frm.set_df_property("date_changed", "options", $.map(fields, | frm.set_df_property("date_changed", "options", $.map(fields, | ||||
function(d) { return (d.fieldtype=="Date" || d.fieldtype=="Datetime") ? | function(d) { return (d.fieldtype=="Date" || d.fieldtype=="Datetime") ? | ||||
d.fieldname : null; })); | |||||
get_select_options(d) : null; })); | |||||
// set email recipient options | // set email recipient options | ||||
frappe.meta.get_docfield("Email Alert Recipient", "email_by_document_field", | frappe.meta.get_docfield("Email Alert Recipient", "email_by_document_field", | ||||
frm.doc.name).options = "\nowner\n" + options; | |||||
frm.doc.name).options = ["owner"].concat(options); | |||||
}); | }); | ||||
} | } | ||||
@@ -1,10 +1,17 @@ | |||||
{ | { | ||||
"autoname": "field:subject", | |||||
"autoname": "hash", | |||||
"creation": "2014-07-11 17:18:09.923399", | "creation": "2014-07-11 17:18:09.923399", | ||||
"docstatus": 0, | "docstatus": 0, | ||||
"doctype": "DocType", | "doctype": "DocType", | ||||
"document_type": "System", | "document_type": "System", | ||||
"fields": [ | "fields": [ | ||||
{ | |||||
"default": "1", | |||||
"fieldname": "enabled", | |||||
"fieldtype": "Check", | |||||
"label": "Enabled", | |||||
"permlevel": 0 | |||||
}, | |||||
{ | { | ||||
"fieldname": "filters", | "fieldname": "filters", | ||||
"fieldtype": "Section Break", | "fieldtype": "Section Break", | ||||
@@ -120,7 +127,7 @@ | |||||
} | } | ||||
], | ], | ||||
"icon": "icon-envelope", | "icon": "icon-envelope", | ||||
"modified": "2014-07-14 15:33:46.806944", | |||||
"modified": "2014-07-15 05:07:14.002351", | |||||
"modified_by": "Administrator", | "modified_by": "Administrator", | ||||
"module": "Core", | "module": "Core", | ||||
"name": "Email Alert", | "name": "Email Alert", | ||||
@@ -140,5 +147,6 @@ | |||||
} | } | ||||
], | ], | ||||
"sort_field": "modified", | "sort_field": "modified", | ||||
"sort_order": "DESC" | |||||
"sort_order": "DESC", | |||||
"title_field": "subject" | |||||
} | } |
@@ -15,13 +15,21 @@ class EmailAlert(Document): | |||||
if self.event=="Value Change" and not self.value_changed: | if self.event=="Value Change" and not self.value_changed: | ||||
frappe.throw(_("Please specify which value field must be checked")) | frappe.throw(_("Please specify which value field must be checked")) | ||||
forbidden_document_types = ("Bulk Email",) | |||||
if self.document_type in forbidden_document_types: | |||||
frappe.throw(_("Cannot set Email Alert on Document Type {0}").format(self.document_type)) | |||||
def trigger_daily_alerts(): | def trigger_daily_alerts(): | ||||
trigger_email_alerts(None, "Date Change") | trigger_email_alerts(None, "Date Change") | ||||
def trigger_email_alerts(doc, method=None): | def trigger_email_alerts(doc, method=None): | ||||
if frappe.flags.in_import or frappe.flags.in_patch: | |||||
# don't send email alerts while syncing or patching | |||||
return | |||||
if method=="Date Change": | if method=="Date Change": | ||||
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='Date Change'"""): | |||||
where event='Date Change' and enabled=1"""): | |||||
alert = frappe.get_doc("Email Alert", alert) | alert = frappe.get_doc("Email Alert", alert) | ||||
@@ -46,7 +54,7 @@ def trigger_email_alerts(doc, method=None): | |||||
}[method] | }[method] | ||||
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 document_type=%s and event=%s""", (doc.doctype, eevent)): | |||||
where document_type=%s and event=%s and enabled=1""", (doc.doctype, eevent)): | |||||
evaluate_alert(doc, alert, eevent) | evaluate_alert(doc, alert, eevent) | ||||
def evaluate_alert(doc, alert, event): | def evaluate_alert(doc, alert, event): | ||||
@@ -86,7 +94,7 @@ def evaluate_alert(doc, alert, event): | |||||
footer = """<div style='margin-top: 20px; font-size: 80%; color: #888'> | footer = """<div style='margin-top: 20px; font-size: 80%; color: #888'> | ||||
This Email Alert {{alert.name}} was autogenerated for | |||||
This Email Alert <em>{{alert.subject}}</em> was autogenerated for | |||||
{{ doc.doctype }} <a href="/desk#Form/{{doc.doctype}}/{{doc.name}}">{{doc.name}}</a>. | {{ doc.doctype }} <a href="/desk#Form/{{doc.doctype}}/{{doc.name}}">{{doc.name}}</a>. | ||||
To update, modify it, go to Setup > Email > <a href="/desk#List/Email Alert">Email Alert</a> | To update, modify it, go to Setup > Email > <a href="/desk#List/Email Alert">Email Alert</a> | ||||
""" | """ |
@@ -339,6 +339,10 @@ class BaseDocument(object): | |||||
frappe.throw(_("Not allowed to change {0} after submission").format(df.label), | frappe.throw(_("Not allowed to change {0} after submission").format(df.label), | ||||
frappe.UpdateAfterSubmitError) | frappe.UpdateAfterSubmitError) | ||||
def get_formatted(self, fieldname, doc=None): | |||||
from frappe.utils.formatters import format_value | |||||
return format_value(self.get(fieldname), self.meta.get_field(fieldname), doc=doc or self) | |||||
def _filter(data, filters, limit=None): | def _filter(data, filters, limit=None): | ||||
"""pass filters as: | """pass filters as: | ||||
{"key": "val", "key": ["!=", "val"], | {"key": "val", "key": ["!=", "val"], | ||||
@@ -4,7 +4,7 @@ | |||||
from __future__ import unicode_literals | from __future__ import unicode_literals | ||||
import frappe | import frappe | ||||
from frappe import _, msgprint | from frappe import _, msgprint | ||||
from frappe.utils import flt, cint, cstr, now | |||||
from frappe.utils import flt, cint, cstr, now, get_url_to_form | |||||
from frappe.modules import load_doctype_module | from frappe.modules import load_doctype_module | ||||
from frappe.model.base_document import BaseDocument | from frappe.model.base_document import BaseDocument | ||||
from frappe.model.naming import set_new_name | from frappe.model.naming import set_new_name | ||||
@@ -553,3 +553,6 @@ class Document(BaseDocument): | |||||
self._precision[parentfield or "main"][fieldname] = self._precision.default | self._precision[parentfield or "main"][fieldname] = self._precision.default | ||||
return self._precision[parentfield or "main"][fieldname] | return self._precision[parentfield or "main"][fieldname] | ||||
def get_url(self): | |||||
return "/desk#Form/{doctype}/{name}".format(doctype=self.doctype, name=self.name) |
@@ -5,6 +5,7 @@ execute:frappe.reload_doc('core', 'doctype', 'docperm') #2014-06-04 | |||||
execute:frappe.reload_doc('core', 'doctype', 'page') #2013-13-26 | execute:frappe.reload_doc('core', 'doctype', 'page') #2013-13-26 | ||||
execute:frappe.reload_doc('core', 'doctype', 'report') #2014-06-03 | execute:frappe.reload_doc('core', 'doctype', 'report') #2014-06-03 | ||||
execute:frappe.reload_doc('core', 'doctype', 'version') #2014-02-21 | execute:frappe.reload_doc('core', 'doctype', 'version') #2014-02-21 | ||||
execute:frappe.reload_doc('core', 'doctype', 'email_alert') #2014-07-15 | |||||
execute:frappe.db.sql("alter table `tabSessions` modify `user` varchar(255), engine=InnoDB") | execute:frappe.db.sql("alter table `tabSessions` modify `user` varchar(255), engine=InnoDB") | ||||
execute:frappe.db.sql("delete from `tabDocField` where parent='0'") | execute:frappe.db.sql("delete from `tabDocField` where parent='0'") | ||||
frappe.patches.v4_0.change_varchar_length | frappe.patches.v4_0.change_varchar_length | ||||
@@ -11,6 +11,7 @@ def execute(): | |||||
ss = frappe.get_doc("System Settings", "System Settings") | ss = frappe.get_doc("System Settings", "System Settings") | ||||
if ss.time_zone in momentjs_data.get("links"): | if ss.time_zone in momentjs_data.get("links"): | ||||
ss.time_zone = momentjs_data["links"][ss.time_zone] | ss.time_zone = momentjs_data["links"][ss.time_zone] | ||||
ss.ignore_mandatory = True | |||||
ss.save() | ss.save() | ||||
for user, time_zone in frappe.db.sql("select name, time_zone from `tabUser` where ifnull(time_zone, '')!=''"): | for user, time_zone in frappe.db.sql("select name, time_zone from `tabUser` where ifnull(time_zone, '')!=''"): | ||||
@@ -5,7 +5,7 @@ | |||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | ||||
<title>{{ subject or "" }}</title> | <title>{{ subject or "" }}</title> | ||||
</head> | </head> | ||||
<body> | |||||
<body style="line-height: 1.6;"> | |||||
<!-- body --> | <!-- body --> | ||||
<div style="font-family: Helvetica, Arial, sans-serif; font-size: 14px;">{{ content }}</div> | <div style="font-family: Helvetica, Arial, sans-serif; font-size: 14px;">{{ content }}</div> | ||||
@@ -0,0 +1,22 @@ | |||||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||||
# MIT License. See license.txt | |||||
from __future__ import unicode_literals | |||||
from frappe.utils import formatdate, fmt_money | |||||
from frappe.model.meta import get_field_currency, get_field_precision | |||||
def format_value(value, df, doc=None): | |||||
if df.fieldtype=="Date": | |||||
return formatdate(value) | |||||
elif df.fieldtype == "Currency": | |||||
return fmt_money(value, precision=get_field_precision(df, doc), currency=get_field_currency(df, doc)) | |||||
elif df.fieldtype == "Float": | |||||
return fmt_money(value) | |||||
elif df.fieldtype == "Percent": | |||||
return "{}%".format(flt(value, 2)) | |||||
return value | |||||