@@ -81,6 +81,12 @@ def application(request): | |||
frappe.db.commit() | |||
rollback = False | |||
# update session | |||
if getattr(frappe.local, "session_obj", None): | |||
updated_in_db = frappe.local.session_obj.update() | |||
if updated_in_db: | |||
frappe.db.commit() | |||
finally: | |||
if frappe.local.request.method in ("POST", "PUT") and frappe.db and rollback: | |||
frappe.db.rollback() | |||
@@ -121,6 +121,11 @@ def get_data(): | |||
"name": "Outgoing Email Settings", | |||
"description": _("Set outgoing mail server.") | |||
}, | |||
{ | |||
"type": "doctype", | |||
"name": "Standard Reply", | |||
"description": _("Standard replies to common queries.") | |||
}, | |||
] | |||
}, | |||
{ | |||
@@ -1,6 +1,6 @@ | |||
{ | |||
"autoname": "CustomScript.####", | |||
"creation": "2013-01-10 16:34:01.000000", | |||
"creation": "2013-01-10 16:34:01", | |||
"description": "Adds a custom script (client or server) to a DocType", | |||
"docstatus": 0, | |||
"doctype": "DocType", | |||
@@ -8,6 +8,7 @@ | |||
{ | |||
"fieldname": "dt", | |||
"fieldtype": "Link", | |||
"in_list_view": 1, | |||
"label": "DocType", | |||
"oldfieldname": "dt", | |||
"oldfieldtype": "Link", | |||
@@ -19,6 +20,7 @@ | |||
"fieldname": "script_type", | |||
"fieldtype": "Select", | |||
"hidden": 1, | |||
"in_list_view": 1, | |||
"label": "Script Type", | |||
"oldfieldname": "script_type", | |||
"oldfieldtype": "Select", | |||
@@ -29,16 +31,24 @@ | |||
{ | |||
"fieldname": "script", | |||
"fieldtype": "Code", | |||
"in_list_view": 1, | |||
"label": "Script", | |||
"oldfieldname": "script", | |||
"oldfieldtype": "Code", | |||
"options": "Script", | |||
"permlevel": 0 | |||
}, | |||
{ | |||
"fieldname": "sample", | |||
"fieldtype": "HTML", | |||
"label": "Sample", | |||
"options": "<h3>Custom Script Help</h3>\n<p>Custom Scripts are executed only on the client-side (i.e. in Forms). Here are some examples to get you started</p>\n<pre><code>\n// additional validation on dates\ncur_frm.cscript.custom_validate = function(doc) {\n if (doc.from_date < get_today()) {\n msgprint(\"You can not select past date in From Date\");\n validated = false;\n }\n}\n\n// make a field read-only after saving\ncur_frm.cscript.custom_refresh = function(doc) {\n // use the __islocal value of doc, to check if the doc is saved or not\n cur_frm.set_df_property(\"myfield\", \"read_only\", doc.__islocal ? 0 : 1);\n}\n\n// addtional permission checking\ncur_frm.cscript.custom_validate = function(doc) {\n if(user==\"user1@example.com\" && doc.purpose!=\"Material Receipt\") {\n msgprint(\"You are only allowed Material Receipt\");\n validated = false;\n }\n}\n\n// calculate sales incentive\ncur_frm.cscript.custom_validate = function(doc) {\n // calculate incentives for each person on the deal\n total_incentive = 0\n $.each(wn.model.get(\"Sales Team\", {parent:doc.name}), function(i, d) {\n\n // calculate incentive\n var incentive_percent = 2;\n if(doc.grand_total > 400) incentive_percent = 4;\n\n // actual incentive\n d.incentives = flt(doc.grand_total) * incentive_percent / 100;\n total_incentive += flt(d.incentives)\n });\n\n doc.total_incentive = total_incentive;\n}\n</code>\n</pre>", | |||
"permlevel": 0 | |||
} | |||
], | |||
"icon": "icon-glass", | |||
"idx": 1, | |||
"modified": "2014-01-20 17:48:31.000000", | |||
"modified": "2014-06-19 06:55:02.522204", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "Custom Script", | |||
@@ -41,7 +41,7 @@ class DocType(Document): | |||
frappe.db.sql('UPDATE tabDocType SET modified=%s WHERE `name`=%s', (now(), p[0])) | |||
def scrub_field_names(self): | |||
restricted = ('name','parent','idx','owner','creation','modified','modified_by', | |||
restricted = ('name','parent','creation','modified','modified_by', | |||
'parentfield','parenttype',"file_list") | |||
for d in self.get("fields"): | |||
if d.fieldtype: | |||
@@ -0,0 +1,71 @@ | |||
{ | |||
"allow_import": 1, | |||
"autoname": "field:subject", | |||
"creation": "2014-06-19 05:20:26.331041", | |||
"docstatus": 0, | |||
"doctype": "DocType", | |||
"document_type": "Transaction", | |||
"fields": [ | |||
{ | |||
"fieldname": "subject", | |||
"fieldtype": "Data", | |||
"in_list_view": 1, | |||
"label": "Subject", | |||
"permlevel": 0, | |||
"reqd": 1 | |||
}, | |||
{ | |||
"fieldname": "response", | |||
"fieldtype": "Text Editor", | |||
"in_list_view": 1, | |||
"label": "Response", | |||
"permlevel": 0, | |||
"reqd": 1 | |||
}, | |||
{ | |||
"default": "user", | |||
"fieldname": "owner", | |||
"fieldtype": "Link", | |||
"hidden": 1, | |||
"label": "Owner", | |||
"options": "User", | |||
"permlevel": 0 | |||
} | |||
], | |||
"icon": "icon-comment", | |||
"modified": "2014-06-19 05:45:09.855045", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "Standard Reply", | |||
"name_case": "", | |||
"owner": "Administrator", | |||
"permissions": [ | |||
{ | |||
"permlevel": 0, | |||
"read": 1, | |||
"role": "All" | |||
}, | |||
{ | |||
"apply_user_permissions": 1, | |||
"create": 1, | |||
"permlevel": 0, | |||
"read": 1, | |||
"role": "All", | |||
"write": 1 | |||
}, | |||
{ | |||
"create": 1, | |||
"delete": 1, | |||
"email": 1, | |||
"export": 1, | |||
"import": 1, | |||
"permlevel": 0, | |||
"read": 1, | |||
"report": 1, | |||
"role": "System Manager", | |||
"write": 1 | |||
} | |||
], | |||
"sort_field": "modified", | |||
"sort_order": "DESC" | |||
} |
@@ -0,0 +1,9 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
# For license information, please see license.txt | |||
from __future__ import unicode_literals | |||
import frappe | |||
from frappe.model.document import Document | |||
class StandardReply(Document): | |||
pass |
@@ -1,100 +1,100 @@ | |||
{ | |||
"creation": "2014-04-17 16:53:52.640856", | |||
"docstatus": 0, | |||
"doctype": "DocType", | |||
"document_type": "System", | |||
"creation": "2014-04-17 16:53:52.640856", | |||
"docstatus": 0, | |||
"doctype": "DocType", | |||
"document_type": "System", | |||
"fields": [ | |||
{ | |||
"fieldname": "localization", | |||
"fieldtype": "Section Break", | |||
"label": "Localization", | |||
"fieldname": "localization", | |||
"fieldtype": "Section Break", | |||
"label": "Localization", | |||
"permlevel": 0 | |||
}, | |||
}, | |||
{ | |||
"fieldname": "language", | |||
"fieldtype": "Select", | |||
"in_list_view": 1, | |||
"label": "Language", | |||
"options": "Loading...", | |||
"permlevel": 0, | |||
"reqd": 1, | |||
"fieldname": "language", | |||
"fieldtype": "Select", | |||
"in_list_view": 1, | |||
"label": "Language", | |||
"options": "Loading...", | |||
"permlevel": 0, | |||
"reqd": 1, | |||
"search_index": 0 | |||
}, | |||
}, | |||
{ | |||
"fieldname": "time_zone", | |||
"fieldtype": "Select", | |||
"label": "Time Zone", | |||
"permlevel": 0, | |||
"fieldname": "time_zone", | |||
"fieldtype": "Select", | |||
"label": "Time Zone", | |||
"permlevel": 0, | |||
"reqd": 1 | |||
}, | |||
}, | |||
{ | |||
"fieldname": "date_and_number_format", | |||
"fieldtype": "Section Break", | |||
"label": "Date and Number Format", | |||
"fieldname": "date_and_number_format", | |||
"fieldtype": "Section Break", | |||
"label": "Date and Number Format", | |||
"permlevel": 0 | |||
}, | |||
}, | |||
{ | |||
"fieldname": "date_format", | |||
"fieldtype": "Select", | |||
"label": "Date Format", | |||
"options": "yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\ndd.mm.yyyy\nmm/dd/yyyy\nmm-dd-yyyy", | |||
"permlevel": 0, | |||
"fieldname": "date_format", | |||
"fieldtype": "Select", | |||
"label": "Date Format", | |||
"options": "yyyy-mm-dd\ndd-mm-yyyy\ndd/mm/yyyy\ndd.mm.yyyy\nmm/dd/yyyy\nmm-dd-yyyy", | |||
"permlevel": 0, | |||
"reqd": 1 | |||
}, | |||
}, | |||
{ | |||
"fieldname": "number_format", | |||
"fieldtype": "Select", | |||
"label": "Number Format", | |||
"options": "#,###.##\n#.###,##\n# ###.##\n# ###,##\n#,###.###\n#,##,###.##\n#.###\n#,###", | |||
"permlevel": 0, | |||
"fieldname": "number_format", | |||
"fieldtype": "Select", | |||
"label": "Number Format", | |||
"options": "#,###.##\n#.###,##\n# ###.##\n# ###,##\n#'###.##\n#, ###.##\n#,##,###.##\n#,###.###\n#.###\n#,###", | |||
"permlevel": 0, | |||
"reqd": 1 | |||
}, | |||
}, | |||
{ | |||
"fieldname": "float_precision", | |||
"fieldtype": "Select", | |||
"label": "Float Precision", | |||
"options": "\n2\n3\n4\n5\n6", | |||
"fieldname": "float_precision", | |||
"fieldtype": "Select", | |||
"label": "Float Precision", | |||
"options": "\n2\n3\n4\n5\n6", | |||
"permlevel": 0 | |||
}, | |||
}, | |||
{ | |||
"fieldname": "security", | |||
"fieldtype": "Section Break", | |||
"label": "Security", | |||
"fieldname": "security", | |||
"fieldtype": "Section Break", | |||
"label": "Security", | |||
"permlevel": 0 | |||
}, | |||
}, | |||
{ | |||
"default": "06:00", | |||
"description": "Session Expiry in Hours e.g. 06:00", | |||
"fieldname": "session_expiry", | |||
"fieldtype": "Data", | |||
"label": "Session Expiry", | |||
"options": "", | |||
"default": "06:00", | |||
"description": "Session Expiry in Hours e.g. 06:00", | |||
"fieldname": "session_expiry", | |||
"fieldtype": "Data", | |||
"label": "Session Expiry", | |||
"options": "", | |||
"permlevel": 0 | |||
}, | |||
}, | |||
{ | |||
"description": "Run scheduled jobs only if checked", | |||
"fieldname": "enable_scheduler", | |||
"fieldtype": "Check", | |||
"in_list_view": 0, | |||
"label": "Enable Scheduled Jobs", | |||
"description": "Run scheduled jobs only if checked", | |||
"fieldname": "enable_scheduler", | |||
"fieldtype": "Check", | |||
"in_list_view": 0, | |||
"label": "Enable Scheduled Jobs", | |||
"permlevel": 0 | |||
} | |||
], | |||
"icon": "icon-cog", | |||
"issingle": 1, | |||
"modified": "2014-06-02 02:09:03.623094", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "System Settings", | |||
"name_case": "", | |||
"owner": "Administrator", | |||
], | |||
"icon": "icon-cog", | |||
"issingle": 1, | |||
"modified": "2014-06-18 02:09:03.623094", | |||
"modified_by": "Administrator", | |||
"module": "Core", | |||
"name": "System Settings", | |||
"name_case": "", | |||
"owner": "Administrator", | |||
"permissions": [ | |||
{ | |||
"create": 1, | |||
"permlevel": 0, | |||
"read": 1, | |||
"role": "System Manager", | |||
"create": 1, | |||
"permlevel": 0, | |||
"read": 1, | |||
"role": "System Manager", | |||
"write": 1 | |||
} | |||
] | |||
} | |||
} |
@@ -161,7 +161,8 @@ frappe.pages['data-import-tool'].onload = function(wrapper) { | |||
$("#dit-output").empty(); | |||
$.each(r.messages, function(i, v) { | |||
var $p = $('<p>').html(v).appendTo('#dit-output'); | |||
var $p = $('<p></p>').html(frappe.markdown(v)).appendTo('#dit-output'); | |||
$("<hr>").appendTo('#dit-output'); | |||
if(v.substr(0,5)=='Error') { | |||
$p.css('color', 'red'); | |||
} else if(v.substr(0,8)=='Inserted') { | |||
@@ -217,7 +217,7 @@ def upload(rows = None, submit_after_import=None, ignore_encoding_errors=False, | |||
error = True | |||
if doc: | |||
frappe.errprint(doc if isinstance(doc, dict) else doc.as_dict()) | |||
err_msg = frappe.local.message_log and "<br>".join(frappe.local.message_log) or cstr(e) | |||
err_msg = frappe.local.message_log and "\n\n".join(frappe.local.message_log) or cstr(e) | |||
ret.append('Error for row (#%d) %s : %s' % (row_idx + 1, | |||
len(row)>1 and row[1] or "", err_msg)) | |||
frappe.errprint(frappe.get_traceback()) | |||
@@ -2556,7 +2556,7 @@ | |||
"code": "ve", | |||
"number_format": "#,###.##" | |||
}, | |||
"Viet Nam": { | |||
"Vietnam": { | |||
"code": "vn", | |||
"currency": "VND", | |||
"currency_name": "Dong", | |||
@@ -87,11 +87,6 @@ def execute_cmd(cmd): | |||
if ret: | |||
frappe.response['message'] = ret | |||
# update session | |||
if "session_obj" in frappe.local: | |||
frappe.local.session_obj.update() | |||
def get_attr(cmd): | |||
"""get method object from cmd""" | |||
if '.' in cmd: | |||
@@ -13,6 +13,7 @@ class BaseDocument(object): | |||
def __init__(self, d): | |||
self.update(d) | |||
self.dont_update_if_missing = [] | |||
@property | |||
def meta(self): | |||
@@ -42,7 +43,8 @@ class BaseDocument(object): | |||
if "doctype" in d: | |||
self.set("doctype", d.get("doctype")) | |||
for key, value in d.iteritems(): | |||
if self.get(key) is None: | |||
# dont_update_if_missing is a list of fieldnames, for which, you don't want to set default value | |||
if (self.get(key) is None) and (value is not None) and (key not in self.dont_update_if_missing): | |||
self.set(key, value) | |||
def get_db_value(self, key): | |||
@@ -162,6 +164,9 @@ class BaseDocument(object): | |||
if doc[k] is None: | |||
del doc[k] | |||
if self.get("_user_tags"): | |||
doc["_user_tags"] = self.get("_user_tags") | |||
if self.get("__islocal"): | |||
doc["__islocal"] = 1 | |||
@@ -275,6 +280,33 @@ class BaseDocument(object): | |||
return invalid_links | |||
def _validate_selects(self): | |||
if frappe.flags.in_import: | |||
return | |||
for df in self.meta.get_select_fields(): | |||
if not (self.get(df.fieldname) and df.options): | |||
continue | |||
options = (df.options or "").split("\n") | |||
# if only empty options | |||
if not filter(None, options): | |||
continue | |||
# strip and set | |||
self.set(df.fieldname, cstr(self.get(df.fieldname)).strip()) | |||
value = self.get(df.fieldname) | |||
if value not in options and not (frappe.flags.in_test and value.startswith("_T-")): | |||
# show an elaborate message | |||
prefix = _("Row #{0}:").format(self.idx) if self.get("parentfield") else "" | |||
label = _(self.meta.get_label(df.fieldname)) | |||
comma_options = '", "'.join(_(each) for each in options) | |||
frappe.throw(_('{0} {1} cannot be "{2}". It should be one of "{3}"').format(prefix, label, | |||
value, comma_options)) | |||
def _validate_constants(self): | |||
if frappe.flags.in_import: | |||
return | |||
@@ -48,6 +48,7 @@ def get_controller(doctype): | |||
class Document(BaseDocument): | |||
def __init__(self, arg1, arg2=None): | |||
self.doctype = self.name = None | |||
if arg1 and isinstance(arg1, basestring): | |||
if not arg2: | |||
# single | |||
@@ -72,6 +73,8 @@ class Document(BaseDocument): | |||
# incorrect arguments. let's not proceed. | |||
raise frappe.DataError("Document({0}, {1})".format(arg1, arg2)) | |||
self.dont_update_if_missing = [] | |||
def load_from_db(self): | |||
if not getattr(self, "_metaclass", False) and self.meta.issingle: | |||
self.update(frappe.db.get_singles_dict(self.doctype)) | |||
@@ -225,8 +228,10 @@ class Document(BaseDocument): | |||
def _validate(self): | |||
self._validate_mandatory() | |||
self._validate_links() | |||
self._validate_selects() | |||
self._validate_constants() | |||
for d in self.get_all_children(): | |||
d._validate_selects() | |||
d._validate_constants() | |||
self._extract_images_from_text_editor() | |||
@@ -61,6 +61,10 @@ class Meta(Document): | |||
def get_link_fields(self): | |||
return self.get("fields", {"fieldtype": "Link", "options":["!=", "[Select]"]}) | |||
def get_select_fields(self): | |||
return self.get("fields", {"fieldtype": "Select", "options":["not in", | |||
["[Select]", "Loading...", "attach_files:"]]}) | |||
def get_table_fields(self): | |||
if not hasattr(self, "_table_fields"): | |||
if self.name!="DocType": | |||
@@ -40,3 +40,4 @@ execute:import frappe.website.render; frappe.website.render.clear_cache("login") | |||
frappe.patches.v4_0.fix_attach_field_file_url | |||
execute:frappe.reset_perms("User") #2014-06-13 | |||
execute:frappe.db.sql("""delete from `tabUserRole` where ifnull(parentfield, '')=''""") #2014-06-17 | |||
frappe.patches.v4_0.remove_user_owner_custom_field |
@@ -0,0 +1,10 @@ | |||
# Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import frappe | |||
def execute(): | |||
user_owner = frappe.db.get_value("Custom Field", {"fieldname": "user_owner"}) | |||
if user_owner: | |||
frappe.delete_doc("Custom Field", user_owner) |
@@ -1,14 +1,6 @@ | |||
// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors | |||
// MIT License. See license.txt | |||
if(!console) { | |||
var console = { | |||
log: function(txt) { | |||
// suppress | |||
} | |||
} | |||
} | |||
$(document).ready(function() { | |||
frappe.assets.check(); | |||
frappe.provide('frappe.app'); | |||
@@ -60,8 +60,10 @@ frappe.number_format_info = { | |||
"#.###,##": {decimal_str:",", group_sep:".", precision:2}, | |||
"# ###.##": {decimal_str:".", group_sep:" ", precision:2}, | |||
"# ###,##": {decimal_str:",", group_sep:" ", precision:2}, | |||
"#,###.###": {decimal_str:".", group_sep:",", precision:3}, | |||
"#'###.##": {decimal_str:".", group_sep:"'", precision:2}, | |||
"#, ###.##": {decimal_str:".", group_sep:", ", precision:2}, | |||
"#,##,###.##": {decimal_str:".", group_sep:",", precision:2}, | |||
"#,###.###": {decimal_str:".", group_sep:",", precision:3}, | |||
"#.###": {decimal_str:"", group_sep:".", precision:0}, | |||
"#,###": {decimal_str:"", group_sep:",", precision:0}, | |||
} | |||
@@ -255,7 +255,7 @@ frappe.ui.Filter = Class.extend({ | |||
if(df.fieldtype=='Check') { | |||
df.fieldtype='Select'; | |||
df.options='No\nYes'; | |||
} else if(['Text','Small Text','Text Editor','Code','Tags','Comments'].indexOf(df.fieldtype)!=-1) { | |||
} else if(['Text','Small Text','Text Editor','Code','Tag','Comments'].indexOf(df.fieldtype)!=-1) { | |||
df.fieldtype = 'Data'; | |||
} else if(df.fieldtype=='Link' && this.$w.find('.condition').val()!="=") { | |||
df.fieldtype = 'Data'; | |||
@@ -45,7 +45,7 @@ frappe.ui.toolbar.Toolbar = Class.extend({ | |||
placeholder="' + __("Search or type a command") + '" \ | |||
style="padding: 2px 6px; height: 24px; margin-top: 5px; \ | |||
margin-left: 10px; background-color: #ddd; \ | |||
min-width: 230px; \ | |||
min-width: 230px; font-size: 85%;\ | |||
border-radius: 10px;">\ | |||
</div>\ | |||
</form>\ | |||
@@ -113,6 +113,7 @@ frappe.views.CommunicationList = Class.extend({ | |||
}); | |||
frappe.last_edited_communication = {}; | |||
frappe.standard_replies = {}; | |||
frappe.views.CommunicationComposer = Class.extend({ | |||
init: function(opts) { | |||
@@ -129,6 +130,8 @@ frappe.views.CommunicationComposer = Class.extend({ | |||
description:__("Email addresses, separted by commas")}, | |||
{label:__("Subject"), fieldtype:"Data", reqd: 1, | |||
fieldname:"subject"}, | |||
{label:__("Standard Reply"), fieldtype:"Link", options:"Standard Reply", | |||
fieldname:"standard_reply"}, | |||
{label:__("Message"), fieldtype:"Text Editor", reqd: 1, | |||
fieldname:"content"}, | |||
{label:__("Send As Email"), fieldtype:"Check", | |||
@@ -155,6 +158,7 @@ frappe.views.CommunicationComposer = Class.extend({ | |||
this.dialog.$wrapper.find("[data-edit='outdent']").remove(); | |||
this.dialog.get_input("send").addClass("btn-primary"); | |||
$(document).on("upload_complete", function(event, attachment) { | |||
if(me.dialog.display) { | |||
var wrapper = $(me.dialog.fields_dict.select_attachments.wrapper); | |||
@@ -185,10 +189,39 @@ frappe.views.CommunicationComposer = Class.extend({ | |||
this.setup_email(); | |||
this.setup_autosuggest(); | |||
this.setup_last_edited_communication(); | |||
this.setup_standard_reply(); | |||
$(this.dialog.fields_dict.recipients.input).val(this.recipients || "").change(); | |||
$(this.dialog.fields_dict.subject.input).val(this.subject || "").change(); | |||
this.setup_earlier_reply(); | |||
}, | |||
setup_standard_reply: function() { | |||
var me = this; | |||
this.dialog.get_input("standard_reply").on("change", function() { | |||
var standard_reply = $(this).val(); | |||
var prepend_reply = function() { | |||
var content_field = me.dialog.fields_dict.content; | |||
var content = content_field.get_value() || ""; | |||
content_field.set_input( | |||
frappe.standard_replies[standard_reply] | |||
+ "<br><br>" + content); | |||
} | |||
if(frappe.standard_replies[standard_reply]) { | |||
prepend_reply(); | |||
} else { | |||
$.ajax({ | |||
url:"/api/resource/Standard Reply/" + standard_reply, | |||
statusCode: { | |||
200: function(data) { | |||
frappe.standard_replies[standard_reply] = data.data.response; | |||
prepend_reply(); | |||
} | |||
} | |||
}); | |||
} | |||
}); | |||
}, | |||
setup_last_edited_communication: function() { | |||
var me = this; | |||
this.dialog.onhide = function() { | |||
@@ -238,7 +238,7 @@ frappe.views.DocListView = frappe.ui.Listing.extend({ | |||
init_minbar: function() { | |||
var me = this; | |||
this.appframe.add_icon_btn("2", 'icon-tag', __('Show Tags'), function() { me.toggle_tags(); }); | |||
this.wrapper.on("click", ".list-tag-preview", function() { me.toggle_tags(); }); | |||
this.$page.on("click", ".list-tag-preview", function() { me.toggle_tags(); }); | |||
if(this.can_delete || this.listview.settings.selectable) { | |||
this.appframe.add_icon_btn("2", 'icon-remove', __('Delete'), function() { me.delete_items(); }); | |||
this.appframe.add_icon_btn("2", 'icon-ok', __('Select All'), function() { | |||
@@ -397,12 +397,14 @@ frappe.views.ReportView = frappe.ui.Listing.extend({ | |||
this.$w.find('.result-list').on("click", ".label-info", function() { | |||
if($(this).attr("data-label")) { | |||
me.set_filter("_user_tags", $(this).attr("data-label")); | |||
me.refresh(); | |||
} | |||
}); | |||
this.$w.find('.result-list').on("click", "[data-workflow-state]", function() { | |||
if($(this).attr("data-workflow-state")) { | |||
me.set_filter(me.state_fieldname, | |||
$(this).attr("data-workflow-state")); | |||
me.refresh(); | |||
} | |||
}); | |||
}, | |||
@@ -3,7 +3,7 @@ | |||
frappe.provide('frappe.views'); | |||
// opts: | |||
// opts: | |||
// stats = list of fields | |||
// doctype | |||
// parent | |||
@@ -29,7 +29,7 @@ frappe.views.SidebarStats = Class.extend({ | |||
$.each(me.stats, function(i, v) { | |||
me.render_stat(v, (r.message || {})[v]); | |||
}); | |||
// reload button at the end | |||
if(me.stats.length) { | |||
$('<a class="small"><i class="refresh"></i> '+__('Refresh')+'</a>') | |||
@@ -46,11 +46,14 @@ frappe.views.SidebarStats = Class.extend({ | |||
}, | |||
render_stat: function(field, stat) { | |||
var me = this; | |||
var show_tags = '<a class="list-tag-preview small" style="margin-left: 7px;">' | |||
+__("Show tags") +'</a>'; | |||
if(!stat || !stat.length) { | |||
if(field==='_user_tags') { | |||
$('<div class="side-panel">\ | |||
<h5 class="text-muted"><i class="icon-tag"></i> '+__('Tags')+'</h5>\ | |||
<h5 class="text-muted"><i class="icon-tag">\ | |||
</i> '+__('Tags')+show_tags+'</h5>\ | |||
<div class="side-panel-body">\ | |||
<div class="text-muted small"><i>'+__('No records tagged.')+'</i><br>' | |||
+'</div>\ | |||
@@ -59,9 +62,9 @@ frappe.views.SidebarStats = Class.extend({ | |||
return; | |||
} | |||
var label = frappe.meta.docfield_map[this.doctype][field] ? | |||
var label = frappe.meta.docfield_map[this.doctype][field] ? | |||
frappe.meta.docfield_map[this.doctype][field].label : field; | |||
if(label==='_user_tags') label = 'Tags'; | |||
if(label==='_user_tags') label = 'Tags' + show_tags; | |||
// grid | |||
var $w = $('<div class="side-panel">\ | |||
@@ -76,12 +79,12 @@ frappe.views.SidebarStats = Class.extend({ | |||
$.each(stat, function(i,v) { sum = sum + v[1]; }) | |||
// render items | |||
$.each(stat, function(i, v) { | |||
$.each(stat, function(i, v) { | |||
me.render_stat_item(i, v, sum, field).appendTo($w.find('.side-panel-body')); | |||
}); | |||
$w.appendTo(this.wrapper); | |||
}, | |||
}, | |||
render_stat_item: function(i, v, max, field) { | |||
var me = this; | |||
var args = {} | |||
@@ -91,8 +94,8 @@ frappe.views.SidebarStats = Class.extend({ | |||
args.count = v[1]; | |||
args.field = field; | |||
args.bar_style = ""; | |||
$item = $(repl('<div class="progress">\ | |||
$item = $(repl('<div class="progress" style="height: 7px;">\ | |||
<div class="progress-bar %(bar_style)s" style="width: %(width)s%"></div>\ | |||
</div>\ | |||
<div class="stat-label" style="margin-top: -19px; text-align: center; \ | |||
@@ -100,7 +103,7 @@ frappe.views.SidebarStats = Class.extend({ | |||
<a href="#" data-label="%(label)s" data-field="%(field)s">\ | |||
%(_label)s</a> (%(count)s)\ | |||
</div>', args)); | |||
this.setup_stat_item_click($item); | |||
return $item; | |||
}, | |||
@@ -116,5 +119,5 @@ frappe.views.SidebarStats = Class.extend({ | |||
me.set_filter(fieldname, label); | |||
return false; | |||
}); | |||
}, | |||
}); | |||
}, | |||
}); |
@@ -285,8 +285,9 @@ $.extend(_p, { | |||
// This is used to calculate and substitude values in the HTML | |||
run_embedded_js: function(container, doc) { | |||
script_list = $(container).find("script"); | |||
for(var i=0; i<script_list.length; i++) { | |||
var script_list = $(container).find("script"); | |||
for(var i=0, j=script_list.length; i<j; i++) { | |||
var element = script_list[i]; | |||
var code = element.innerHTML; | |||
var new_html = code ? (eval(code) || "") : ""; | |||
@@ -294,6 +295,9 @@ $.extend(_p, { | |||
$(element).replaceWith(this.add_span(new_html + "")); | |||
} | |||
} | |||
// remove scripts once executed | |||
$(container).find("script").remove(); | |||
}, | |||
add_span: function(html) { | |||
@@ -250,29 +250,32 @@ class Session: | |||
def update(self, force=False): | |||
"""extend session expiry""" | |||
self.data['data']['last_updated'] = frappe.utils.now() | |||
self.data['data']['lang'] = unicode(frappe.lang) | |||
if (frappe.session['user'] == "Guest" or frappe.form_dict.cmd=="logout"): | |||
return | |||
now = frappe.utils.now() | |||
self.data['data']['last_updated'] = now | |||
self.data['data']['lang'] = unicode(frappe.lang) | |||
# update session in db | |||
time_diff = None | |||
last_updated = frappe.cache().get_value("last_db_session_update:" + self.sid) | |||
time_diff = frappe.utils.time_diff_in_seconds(now, last_updated) if last_updated else None | |||
if last_updated: | |||
time_diff = frappe.utils.time_diff_in_seconds(frappe.utils.now(), | |||
last_updated) | |||
if force or (frappe.session['user'] != 'Guest' and \ | |||
((time_diff==None) or (time_diff > 1800))): | |||
# database persistence is secondary, don't update it too often | |||
# database persistence is secondary, don't update it too often | |||
updated_in_db = False | |||
if force or (time_diff==None) or (time_diff > 600): | |||
frappe.db.sql("""update tabSessions set sessiondata=%s, | |||
lastupdate=NOW() where sid=%s""" , (str(self.data['data']), | |||
self.data['sid'])) | |||
if frappe.form_dict.cmd not in ("frappe.sessions.clear", "logout"): | |||
frappe.cache().set_value("last_db_session_update:" + self.sid, | |||
frappe.utils.now()) | |||
frappe.cache().set_value("session:" + self.sid, self.data) | |||
updated_in_db = True | |||
# set in memcache | |||
frappe.cache().set_value("last_db_session_update:" + self.sid, now) | |||
frappe.cache().set_value("session:" + self.sid, self.data) | |||
return updated_in_db | |||
def get_expiry_period(): | |||
exp_sec = frappe.defaults.get_global_default("session_expiry") or "06:00:00" | |||
@@ -55,9 +55,8 @@ | |||
{%- endfor -%} | |||
</ul> | |||
</li> | |||
{% if not disable_signup %} | |||
<li class="btn-login-area"><a href="/login">Sign Up / Login</a></li> | |||
{% endif %} | |||
<li class="btn-login-area"><a href="/login"> | |||
{%- if not disable_signup %}Sign Up / {% endif -%} Login</a></li> | |||
</ul> | |||
</div> | |||
</div> | |||
@@ -393,13 +393,16 @@ def fmt_money(amount, precision=None, currency=None): | |||
return amount | |||
number_format_info = { | |||
"#.###": ("", ".", 0), | |||
"#,###": ("", ",", 0), | |||
"#,###.##": (".", ",", 2), | |||
"#,##,###.##": (".", ",", 2), | |||
"#.###,##": (",", ".", 2), | |||
"# ###.##": (".", " ", 2), | |||
"# ###,##": (",", " ", 2), | |||
"#'###.##": (".", "'", 2), | |||
"#, ###.##": (".", ", ", 2), | |||
"#,##,###.##": (".", ",", 2), | |||
"#,###.###": (".", ",", 3), | |||
"#.###": ("", ".", 0), | |||
"#,###": ("", ",", 0) | |||
} | |||
def get_number_format_info(format): | |||