From 5d85379e8b867afbe033c4d7237a6a1c5c550315 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 29 Jan 2019 11:52:16 +0530 Subject: [PATCH 01/25] feat: override treeview buttons with sasme labelled button in tree file --- frappe/public/js/frappe/views/treeview.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/frappe/public/js/frappe/views/treeview.js b/frappe/public/js/frappe/views/treeview.js index dda728cff5..c42546f6e4 100644 --- a/frappe/public/js/frappe/views/treeview.js +++ b/frappe/public/js/frappe/views/treeview.js @@ -219,6 +219,9 @@ frappe.views.TreeView = Class.extend({ ] if(this.opts.toolbar && this.opts.extend_toolbar) { + toolbar = toolbar.filter(btn => { + return !me.opts.toolbar.find(d => d["label"]==btn["label"]); + }); return toolbar.concat(this.opts.toolbar) } else if (this.opts.toolbar && !this.opts.extend_toolbar) { return this.opts.toolbar From af35ae8fc81b37cef0690829b52e091f8c70e6a3 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 29 Jan 2019 11:53:18 +0530 Subject: [PATCH 02/25] feat: ability to pass selected node while overriding a button --- frappe/public/js/frappe/views/treeview.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/views/treeview.js b/frappe/public/js/frappe/views/treeview.js index c42546f6e4..94daa22f8e 100644 --- a/frappe/public/js/frappe/views/treeview.js +++ b/frappe/public/js/frappe/views/treeview.js @@ -229,9 +229,9 @@ frappe.views.TreeView = Class.extend({ return toolbar } }, - new_node: function() { + new_node: function(node) { var me = this; - var node = me.tree.get_selected_node(); + var node = node || me.tree.get_selected_node(); if(!(node && node.expandable)) { frappe.msgprint(__("Select a group node first.")); From c079646556fa0431d45ff8356218d20f0d26a0ff Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 29 Jan 2019 11:55:46 +0530 Subject: [PATCH 03/25] feat: ability to provide custom onchange for filter and to disable onchange completely --- frappe/public/js/frappe/views/treeview.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/frappe/public/js/frappe/views/treeview.js b/frappe/public/js/frappe/views/treeview.js index 94daa22f8e..472741fc56 100644 --- a/frappe/public/js/frappe/views/treeview.js +++ b/frappe/public/js/frappe/views/treeview.js @@ -100,17 +100,20 @@ frappe.views.TreeView = Class.extend({ filter.default = frappe.route_options[filter.fieldname] } - filter.change = function() { - var val = this.get_value(); - me.args[filter.fieldname] = val; - if (val) { - me.root_label = val; - me.page.set_title(val); - } else { - me.root_label = me.opts.root_label; - me.set_title(); + if(!filter.disable_onchange) { + filter.change = function() { + filter.on_change && filter.on_change(); + var val = this.get_value(); + me.args[filter.fieldname] = val; + if (val) { + me.root_label = val; + me.page.set_title(val); + } else { + me.root_label = me.opts.root_label; + me.set_title(); + } + me.make_tree(); } - me.make_tree(); } me.page.add_field(filter); From e6b94e764bc4f413ff10fbec6787ac60304ece15 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 29 Jan 2019 12:38:07 +0530 Subject: [PATCH 04/25] fix: codacy fix --- frappe/public/js/frappe/views/treeview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/views/treeview.js b/frappe/public/js/frappe/views/treeview.js index 472741fc56..d4d32eba40 100644 --- a/frappe/public/js/frappe/views/treeview.js +++ b/frappe/public/js/frappe/views/treeview.js @@ -234,7 +234,7 @@ frappe.views.TreeView = Class.extend({ }, new_node: function(node) { var me = this; - var node = node || me.tree.get_selected_node(); + node = node || me.tree.get_selected_node(); if(!(node && node.expandable)) { frappe.msgprint(__("Select a group node first.")); From eb2a0942e0294037b3f1cecb04430035ad664194 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Wed, 30 Jan 2019 10:32:16 +0530 Subject: [PATCH 05/25] feat: post_render function added to be triggered after treeview is successfully built --- frappe/public/js/frappe/views/treeview.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/frappe/public/js/frappe/views/treeview.js b/frappe/public/js/frappe/views/treeview.js index d4d32eba40..64c1696fe0 100644 --- a/frappe/public/js/frappe/views/treeview.js +++ b/frappe/public/js/frappe/views/treeview.js @@ -156,6 +156,12 @@ frappe.views.TreeView = Class.extend({ }); cur_tree = this.tree; + this.post_render(); + }, + + post_render: function() { + var me = this; + me.opts.post_render && me.opts.post_render(me); }, select_node: function(node) { From a7e127e4981edc5872e4f30f010a344ba42e3fac Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Wed, 30 Jan 2019 10:48:43 +0530 Subject: [PATCH 06/25] fix: get ancestors for a node with more filters --- frappe/utils/nestedset.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frappe/utils/nestedset.py b/frappe/utils/nestedset.py index 8bef19cedb..f5400318a7 100644 --- a/frappe/utils/nestedset.py +++ b/frappe/utils/nestedset.py @@ -15,7 +15,7 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.model.document import Document -from frappe.utils import now +from frappe.utils import now, cint class NestedSetRecursionError(frappe.ValidationError): pass class NestedSetMultipleRootsError(frappe.ValidationError): pass @@ -256,9 +256,10 @@ def get_root_of(doctype): and t1.rgt > t1.lft""".format(doctype, doctype)) return result[0][0] if result else None -def get_ancestors_of(doctype, name): +def get_ancestors_of(doctype, name, order_by="lft desc", limit=None): """Get ancestor elements of a DocType with a tree structure""" lft, rgt = frappe.db.get_value(doctype, name, ["lft", "rgt"]) + limit = "limit %s" % cint(limit) if limit else "" result = frappe.db.sql_list("""select name from `tab{0}` - where lft<%s and rgt>%s order by lft desc""".format(doctype), (lft, rgt)) + where lft<%s and rgt>%s order by {1} {2}""".format(doctype, order_by, limit), (lft, rgt)) return result or [] From c5ed692e1c3160bb8639b3875a5add1aa48c1dd7 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Wed, 30 Jan 2019 11:07:16 +0530 Subject: [PATCH 07/25] fix: minor revert change to new_node function --- frappe/public/js/frappe/views/treeview.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/views/treeview.js b/frappe/public/js/frappe/views/treeview.js index 64c1696fe0..2b76e135cf 100644 --- a/frappe/public/js/frappe/views/treeview.js +++ b/frappe/public/js/frappe/views/treeview.js @@ -238,9 +238,9 @@ frappe.views.TreeView = Class.extend({ return toolbar } }, - new_node: function(node) { + new_node: function() { var me = this; - node = node || me.tree.get_selected_node(); + var node = me.tree.get_selected_node(); if(!(node && node.expandable)) { frappe.msgprint(__("Select a group node first.")); From 04b3a5cabc60241c8f8bbd3f447ea22919389d57 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Wed, 30 Jan 2019 16:31:00 +0530 Subject: [PATCH 08/25] feat: added a utility method to get all the descendants of a node --- frappe/utils/nestedset.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frappe/utils/nestedset.py b/frappe/utils/nestedset.py index f5400318a7..021425bab2 100644 --- a/frappe/utils/nestedset.py +++ b/frappe/utils/nestedset.py @@ -263,3 +263,11 @@ def get_ancestors_of(doctype, name, order_by="lft desc", limit=None): result = frappe.db.sql_list("""select name from `tab{0}` where lft<%s and rgt>%s order by {1} {2}""".format(doctype, order_by, limit), (lft, rgt)) return result or [] + +def get_descendants_of(doctype, name, order_by="lft desc", limit=None): + '''Return descendants of the current record''' + lft, rgt = frappe.db.get_value(doctype, name, ['lft', 'rgt']) + limit = "limit %s" % cint(limit) if limit else "" + result = frappe.db.sql_list("""select name from `tab{0}` + where lft>%s and rgt<%s order by {1} {2}""".format(doctype, order_by, limit), (lft, rgt)) + return result or [] From 1d8f35ce979c6c02a091b42e08176401d9a8a317 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Fri, 1 Feb 2019 12:14:34 +0530 Subject: [PATCH 09/25] fix: use orm instead of query --- frappe/utils/nestedset.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/frappe/utils/nestedset.py b/frappe/utils/nestedset.py index 021425bab2..777dd7aba7 100644 --- a/frappe/utils/nestedset.py +++ b/frappe/utils/nestedset.py @@ -15,7 +15,7 @@ from __future__ import unicode_literals import frappe from frappe import _ from frappe.model.document import Document -from frappe.utils import now, cint +from frappe.utils import now class NestedSetRecursionError(frappe.ValidationError): pass class NestedSetMultipleRootsError(frappe.ValidationError): pass @@ -259,15 +259,17 @@ def get_root_of(doctype): def get_ancestors_of(doctype, name, order_by="lft desc", limit=None): """Get ancestor elements of a DocType with a tree structure""" lft, rgt = frappe.db.get_value(doctype, name, ["lft", "rgt"]) - limit = "limit %s" % cint(limit) if limit else "" - result = frappe.db.sql_list("""select name from `tab{0}` - where lft<%s and rgt>%s order by {1} {2}""".format(doctype, order_by, limit), (lft, rgt)) + + result = [d["name"] for d in frappe.db.get_list(doctype, {"lft": ["<", lft], "rgt": [">", rgt]}, + "name", order_by=order_by, limit_page_length=limit)] + return result or [] def get_descendants_of(doctype, name, order_by="lft desc", limit=None): '''Return descendants of the current record''' lft, rgt = frappe.db.get_value(doctype, name, ['lft', 'rgt']) - limit = "limit %s" % cint(limit) if limit else "" - result = frappe.db.sql_list("""select name from `tab{0}` - where lft>%s and rgt<%s order by {1} {2}""".format(doctype, order_by, limit), (lft, rgt)) + + result = [d["name"] for d in frappe.db.get_list(doctype, {"lft": [">", lft], "rgt": ["<", rgt]}, + "name", order_by=order_by, limit_page_length=limit)] + return result or [] From 570aee12e9531736f104b9ab477909c3873b859d Mon Sep 17 00:00:00 2001 From: Saurabh Date: Mon, 11 Feb 2019 17:20:35 +0530 Subject: [PATCH 10/25] fix: scrub new lines and white spaces from options and fetch_from field --- frappe/core/doctype/doctype/doctype.py | 29 +++++++++++++++----------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/frappe/core/doctype/doctype/doctype.py b/frappe/core/doctype/doctype/doctype.py index bd2caef2bc..388e4d4ef8 100644 --- a/frappe/core/doctype/doctype/doctype.py +++ b/frappe/core/doctype/doctype/doctype.py @@ -56,7 +56,6 @@ class DocType(Document): self.permissions = [] self.scrub_field_names() - self.scrub_options_in_select() self.set_default_in_list_view() self.set_default_translatable() self.validate_series() @@ -195,17 +194,6 @@ class DocType(Document): # unique is automatically an index if d.unique: d.search_index = 0 - def scrub_options_in_select(self): - """Strip options for whitespaces""" - for field in self.fields: - if field.fieldtype == "Select" and field.options is not None: - options_list = [] - for i, option in enumerate(field.options.split("\n")): - _option = option.strip() - if i==0 or _option: - options_list.append(_option) - field.options = '\n'.join(options_list) - def validate_series(self, autoname=None, name=None): """Validate if `autoname` property is correctly set.""" if not autoname: autoname = self.autoname @@ -693,6 +681,21 @@ def validate_fields(meta): re.match("""[\w\.:_]+\s*={1}\s*[\w\.@'"]+""", depends_on): frappe.throw(_("Invalid {0} condition").format(frappe.unscrub(field)), frappe.ValidationError) + def scrub_options_in_select(field): + """Strip options for whitespaces""" + + if field.fieldtype == "Select" and field.options is not None: + options_list = [] + for i, option in enumerate(field.options.split("\n")): + _option = option.strip() + if i==0 or _option: + options_list.append(_option) + field.options = '\n'.join(options_list) + + def scrub_fetch_from(field): + if hasattr(field, 'fetch_from') and getattr(field, 'fetch_from'): + field.fetch_from = field.fetch_from.strip('\n').strip() + fields = meta.get("fields") fieldname_list = [d.fieldname for d in fields] @@ -720,6 +723,8 @@ def validate_fields(meta): check_illegal_default(d) check_unique_and_text(d) check_illegal_depends_on_conditions(d) + scrub_options_in_select(d) + scrub_fetch_from(d) check_fold(fields) check_search_fields(meta, fields) From 6a2458d3455808a1a82e69b016f6b19a91d60117 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 12 Feb 2019 17:36:29 +0530 Subject: [PATCH 11/25] feat: use email account name as sender name --- .../doctype/email_account/email_account.json | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/frappe/email/doctype/email_account/email_account.json b/frappe/email/doctype/email_account/email_account.json index 5ab3cd1630..ce9b0f30b0 100644 --- a/frappe/email/doctype/email_account/email_account.json +++ b/frappe/email/doctype/email_account/email_account.json @@ -1,5 +1,6 @@ { "allow_copy": 0, + "allow_events_in_timeline": 0, "allow_guest_to_view": 0, "allow_import": 0, "allow_rename": 1, @@ -1063,6 +1064,40 @@ "translatable": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "enable_outgoing", + "description": "Uses the Email Address Name mentioned in this Account as the Sender's Name for all emails sent using this Account.", + "fieldname": "always_use_account_name_as_sender_name", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Always use Account's Name as Sender's Name", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_in_quick_entry": 0, @@ -1563,7 +1598,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2019-01-30 11:02:41.011412", + "modified": "2019-02-12 17:09:50.653403", "modified_by": "Administrator", "module": "Email", "name": "Email Account", From 9d6160182952a28e39466764e2fe2484f223f011 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 12 Feb 2019 17:37:45 +0530 Subject: [PATCH 12/25] feat: replace sender name by email account name --- frappe/core/doctype/communication/email.py | 9 ++++++--- frappe/email/email_body.py | 7 +++++++ frappe/email/smtp.py | 7 +++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/frappe/core/doctype/communication/email.py b/frappe/core/doctype/communication/email.py index 00dc294432..4e0337ae47 100755 --- a/frappe/core/doctype/communication/email.py +++ b/frappe/core/doctype/communication/email.py @@ -307,7 +307,8 @@ def set_incoming_outgoing_accounts(doc): doc.outgoing_email_account = frappe.db.get_value("Email Account", {"append_to": doc.reference_doctype, "enable_outgoing": 1}, - ["email_id", "always_use_account_email_id_as_sender", "name"], as_dict=True) + ["email_id", "always_use_account_email_id_as_sender", "name", + "always_use_account_name_as_sender_name"], as_dict=True) if not doc.incoming_email_account: doc.incoming_email_account = frappe.db.get_value("Email Account", @@ -317,12 +318,14 @@ def set_incoming_outgoing_accounts(doc): # if from address is not the default email account doc.outgoing_email_account = frappe.db.get_value("Email Account", {"email_id": doc.sender, "enable_outgoing": 1}, - ["email_id", "always_use_account_email_id_as_sender", "name", "send_unsubscribe_message"], as_dict=True) or frappe._dict() + ["email_id", "always_use_account_email_id_as_sender", "name", + "send_unsubscribe_message", "always_use_account_name_as_sender_name"], as_dict=True) or frappe._dict() if not doc.outgoing_email_account: doc.outgoing_email_account = frappe.db.get_value("Email Account", {"default_outgoing": 1, "enable_outgoing": 1}, - ["email_id", "always_use_account_email_id_as_sender", "name", "send_unsubscribe_message"],as_dict=True) or frappe._dict() + ["email_id", "always_use_account_email_id_as_sender", "name", + "send_unsubscribe_message", "always_use_account_name_as_sender_name"],as_dict=True) or frappe._dict() if doc.sent_or_received == "Sent": doc.db_set("email_account", doc.outgoing_email_account.name) diff --git a/frappe/email/email_body.py b/frappe/email/email_body.py index 0cdaa66a58..ba3d59819a 100755 --- a/frappe/email/email_body.py +++ b/frappe/email/email_body.py @@ -174,6 +174,7 @@ class EMail: self.reply_to = validate_email_add(strip(self.reply_to) or self.sender, True) self.replace_sender() + self.replace_sender_name() self.recipients = [strip(r) for r in self.recipients] self.cc = [strip(r) for r in self.cc] @@ -188,6 +189,12 @@ class EMail: sender_name, sender_email = parse_addr(self.sender) self.sender = email.utils.formataddr((str(Header(sender_name or self.email_account.name, 'utf-8')), self.email_account.email_id)) + def replace_sender_name(self): + if cint(self.email_account.always_use_account_name_as_sender_name): + self.set_header('X-Original-From', self.sender) + sender_name, sender_email = parse_addr(self.sender) + self.sender = email.utils.formataddr((str(Header(self.email_account.name, 'utf-8')), sender_email)) + def set_message_id(self, message_id, is_notification=False): if message_id: self.msg_root["Message-Id"] = '<' + message_id + '>' diff --git a/frappe/email/smtp.py b/frappe/email/smtp.py index 549b3f1d1e..99b5f94bf0 100644 --- a/frappe/email/smtp.py +++ b/frappe/email/smtp.py @@ -109,7 +109,8 @@ def get_default_outgoing_email_account(raise_exception_not_set=True): "mail_password": "Super.Secret.Password", "auto_email_id": "emails@example.com", "email_sender_name": "Example Notifications", - "always_use_account_email_id_as_sender": 0 + "always_use_account_email_id_as_sender": 0, + "always_use_account_name_as_sender_name": 0 } ''' email_account = _get_email_account({"enable_outgoing": 1, "default_outgoing": 1}) @@ -128,7 +129,8 @@ def get_default_outgoing_email_account(raise_exception_not_set=True): "login_id": frappe.conf.get("mail_login"), "email_id": frappe.conf.get("auto_email_id") or frappe.conf.get("mail_login") or 'notifications@example.com', "password": frappe.conf.get("mail_password"), - "always_use_account_email_id_as_sender": frappe.conf.get("always_use_account_email_id_as_sender", 0) + "always_use_account_email_id_as_sender": frappe.conf.get("always_use_account_email_id_as_sender", 0), + "always_use_account_name_as_sender_name": frappe.conf.get("always_use_account_name_as_sender_name", 0) }) email_account.from_site_config = True email_account.name = frappe.conf.get("email_sender_name") or "Frappe" @@ -182,6 +184,7 @@ class SMTPServer: self.use_tls = self.email_account.use_tls self.sender = self.email_account.email_id self.always_use_account_email_id_as_sender = cint(self.email_account.get("always_use_account_email_id_as_sender")) + self.always_use_account_name_as_sender_name = cint(self.email_account.get("always_use_account_name_as_sender_name")) @property def sess(self): From d5dd0e06f87643eedaa3d047ead512acde07958c Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 13 Feb 2019 17:47:44 +0530 Subject: [PATCH 13/25] fix: Fallback for get_build_version --- frappe/www/desk.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frappe/www/desk.py b/frappe/www/desk.py index 8de09b3720..9924108b11 100644 --- a/frappe/www/desk.py +++ b/frappe/www/desk.py @@ -85,4 +85,9 @@ def get_desk_assets(build_version): } def get_build_version(): - return str(os.path.getmtime(os.path.join(frappe.local.sites_path, '.build'))) + try: + return str(os.path.getmtime(os.path.join(frappe.local.sites_path, '.build'))) + except OSError: + # .build can sometimes not exist + # this is not a major problem so send fallback + return frappe.utils.random_string(8) From 37cb76346c35374b9dbb385d0c0e96339dcda528 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Wed, 13 Feb 2019 17:51:30 +0530 Subject: [PATCH 14/25] fix: Set minimum body height so that scrollbar does not overlap --- frappe/public/less/frappe-datatable.less | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/public/less/frappe-datatable.less b/frappe/public/less/frappe-datatable.less index ba25c7a10d..d89a692ea0 100644 --- a/frappe/public/less/frappe-datatable.less +++ b/frappe/public/less/frappe-datatable.less @@ -35,6 +35,7 @@ .dt-scrollable { max-height: calc(100vh - 250px); + min-height: 100px; } table td.dt-cell { From a9e9c2e9a0c5010693b2931c2084304ae34433a4 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 13 Feb 2019 22:59:20 +0530 Subject: [PATCH 15/25] Return empty list from get_decendants if doc not found --- frappe/database.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/frappe/database.py b/frappe/database.py index d9ad3e7cbe..10a51af24e 100644 --- a/frappe/database.py +++ b/frappe/database.py @@ -967,9 +967,14 @@ class Database: def get_descendants(self, doctype, name): '''Return descendants of the current record''' - lft, rgt = self.get_value(doctype, name, ('lft', 'rgt')) - return self.sql_list('''select name from `tab{doctype}` - where lft > {lft} and rgt < {rgt}'''.format(doctype=doctype, lft=lft, rgt=rgt)) + node_location_indexes = self.get_value(doctype, name, ('lft', 'rgt')) + if node_location_indexes: + lft, rgt = node_location_indexes + return self.sql_list('''select name from `tab{doctype}` + where lft > {lft} and rgt < {rgt}'''.format(doctype=doctype, lft=lft, rgt=rgt)) + else: + # when document does not exist + return [] def enqueue_jobs_after_commit(): if frappe.flags.enqueue_after_commit and len(frappe.flags.enqueue_after_commit) > 0: From d014e0276899006a60c4723d96c89e87ad0b53bd Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 13 Feb 2019 23:00:40 +0530 Subject: [PATCH 16/25] Index user field in User Permission doctype for faster select query --- .../user_permission/user_permission.json | 482 +++++++++--------- 1 file changed, 241 insertions(+), 241 deletions(-) diff --git a/frappe/core/doctype/user_permission/user_permission.json b/frappe/core/doctype/user_permission/user_permission.json index 9a38f8d953..3502e9800f 100644 --- a/frappe/core/doctype/user_permission/user_permission.json +++ b/frappe/core/doctype/user_permission/user_permission.json @@ -1,262 +1,262 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "beta": 0, - "creation": "2017-07-17 14:25:27.881871", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 1, + "allow_rename": 0, + "beta": 0, + "creation": "2017-07-17 14:25:27.881871", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "user", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "User", - "length": 0, - "no_copy": 0, - "options": "User", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "user", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "User", + "length": 0, + "no_copy": 0, + "options": "User", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 1, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "allow", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Allow", - "length": 0, - "no_copy": 0, - "options": "DocType", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "allow", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Allow", + "length": 0, + "no_copy": 0, + "options": "DocType", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "for_value", - "fieldtype": "Dynamic Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "For Value", - "length": 0, - "no_copy": 0, - "options": "allow", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "for_value", + "fieldtype": "Dynamic Link", + "hidden": 0, + "ignore_user_permissions": 1, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "For Value", + "length": 0, + "no_copy": 0, + "options": "allow", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "advanced_control_section", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Advanced Control", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "advanced_control_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Advanced Control", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fieldname": "apply_to_all_doctypes", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Apply To All Document Types", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "1", + "fieldname": "apply_to_all_doctypes", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Apply To All Document Types", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:!doc.apply_to_all_doctypes", - "fieldname": "applicable_for", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Applicable For", - "length": 0, - "no_copy": 0, - "options": "DocType", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:!doc.apply_to_all_doctypes", + "fieldname": "applicable_for", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Applicable For", + "length": 0, + "no_copy": 0, + "options": "DocType", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2018-11-12 16:26:12.362352", - "modified_by": "Administrator", - "module": "Core", - "name": "User Permission", - "name_case": "", - "owner": "Administrator", + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2019-02-13 22:58:27.428741", + "modified_by": "Administrator", + "module": "Core", + "name": "User Permission", + "name_case": "", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "user", - "track_changes": 1, - "track_seen": 0, + ], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "user", + "track_changes": 1, + "track_seen": 0, "track_views": 0 } \ No newline at end of file From fadb3f79eceb25dc07e8ed71bb90bbde617642fb Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 13 Feb 2019 23:07:09 +0530 Subject: [PATCH 17/25] Remove unwanted trailing spaces --- .../user_permission/user_permission.json | 482 +++++++++--------- 1 file changed, 241 insertions(+), 241 deletions(-) diff --git a/frappe/core/doctype/user_permission/user_permission.json b/frappe/core/doctype/user_permission/user_permission.json index 3502e9800f..c2ea05e731 100644 --- a/frappe/core/doctype/user_permission/user_permission.json +++ b/frappe/core/doctype/user_permission/user_permission.json @@ -1,262 +1,262 @@ { - "allow_copy": 0, - "allow_events_in_timeline": 0, - "allow_guest_to_view": 0, - "allow_import": 1, - "allow_rename": 0, - "beta": 0, - "creation": "2017-07-17 14:25:27.881871", - "custom": 0, - "docstatus": 0, - "doctype": "DocType", - "document_type": "", - "editable_grid": 1, - "engine": "InnoDB", + "allow_copy": 0, + "allow_events_in_timeline": 0, + "allow_guest_to_view": 0, + "allow_import": 1, + "allow_rename": 0, + "beta": 0, + "creation": "2017-07-17 14:25:27.881871", + "custom": 0, + "docstatus": 0, + "doctype": "DocType", + "document_type": "", + "editable_grid": 1, + "engine": "InnoDB", "fields": [ { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "user", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "User", - "length": 0, - "no_copy": 0, - "options": "User", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 1, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "user", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "User", + "length": 0, + "no_copy": 0, + "options": "User", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 1, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "allow", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "Allow", - "length": 0, - "no_copy": 0, - "options": "DocType", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "allow", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "Allow", + "length": 0, + "no_copy": 0, + "options": "DocType", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "for_value", - "fieldtype": "Dynamic Link", - "hidden": 0, - "ignore_user_permissions": 1, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 1, - "label": "For Value", - "length": 0, - "no_copy": 0, - "options": "allow", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 1, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "for_value", + "fieldtype": "Dynamic Link", + "hidden": 0, + "ignore_user_permissions": 1, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 1, + "label": "For Value", + "length": 0, + "no_copy": 0, + "options": "allow", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 1, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "fieldname": "advanced_control_section", - "fieldtype": "Section Break", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Advanced Control", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "advanced_control_section", + "fieldtype": "Section Break", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Advanced Control", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "default": "1", - "fieldname": "apply_to_all_doctypes", - "fieldtype": "Check", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 0, - "in_standard_filter": 0, - "label": "Apply To All Document Types", - "length": 0, - "no_copy": 0, - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "1", + "fieldname": "apply_to_all_doctypes", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Apply To All Document Types", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 - }, + }, { - "allow_bulk_edit": 0, - "allow_in_quick_entry": 0, - "allow_on_submit": 0, - "bold": 0, - "collapsible": 0, - "columns": 0, - "depends_on": "eval:!doc.apply_to_all_doctypes", - "fieldname": "applicable_for", - "fieldtype": "Link", - "hidden": 0, - "ignore_user_permissions": 0, - "ignore_xss_filter": 0, - "in_filter": 0, - "in_global_search": 0, - "in_list_view": 1, - "in_standard_filter": 0, - "label": "Applicable For", - "length": 0, - "no_copy": 0, - "options": "DocType", - "permlevel": 0, - "precision": "", - "print_hide": 0, - "print_hide_if_no_value": 0, - "read_only": 0, - "remember_last_selected_value": 0, - "report_hide": 0, - "reqd": 0, - "search_index": 0, - "set_only_once": 0, - "translatable": 0, + "allow_bulk_edit": 0, + "allow_in_quick_entry": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "depends_on": "eval:!doc.apply_to_all_doctypes", + "fieldname": "applicable_for", + "fieldtype": "Link", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 1, + "in_standard_filter": 0, + "label": "Applicable For", + "length": 0, + "no_copy": 0, + "options": "DocType", + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "translatable": 0, "unique": 0 } - ], - "has_web_view": 0, - "hide_heading": 0, - "hide_toolbar": 0, - "idx": 0, - "image_view": 0, - "in_create": 0, - "is_submittable": 0, - "issingle": 0, - "istable": 0, - "max_attachments": 0, - "modified": "2019-02-13 22:58:27.428741", - "modified_by": "Administrator", - "module": "Core", - "name": "User Permission", - "name_case": "", - "owner": "Administrator", + ], + "has_web_view": 0, + "hide_heading": 0, + "hide_toolbar": 0, + "idx": 0, + "image_view": 0, + "in_create": 0, + "is_submittable": 0, + "issingle": 0, + "istable": 0, + "max_attachments": 0, + "modified": "2019-02-13 22:58:27.428741", + "modified_by": "Administrator", + "module": "Core", + "name": "User Permission", + "name_case": "", + "owner": "Administrator", "permissions": [ { - "amend": 0, - "cancel": 0, - "create": 1, - "delete": 1, - "email": 1, - "export": 1, - "if_owner": 0, - "import": 0, - "permlevel": 0, - "print": 1, - "read": 1, - "report": 1, - "role": "System Manager", - "set_user_permissions": 0, - "share": 1, - "submit": 0, + "amend": 0, + "cancel": 0, + "create": 1, + "delete": 1, + "email": 1, + "export": 1, + "if_owner": 0, + "import": 0, + "permlevel": 0, + "print": 1, + "read": 1, + "report": 1, + "role": "System Manager", + "set_user_permissions": 0, + "share": 1, + "submit": 0, "write": 1 } - ], - "quick_entry": 0, - "read_only": 0, - "read_only_onload": 0, - "show_name_in_global_search": 0, - "sort_field": "modified", - "sort_order": "DESC", - "title_field": "user", - "track_changes": 1, - "track_seen": 0, + ], + "quick_entry": 0, + "read_only": 0, + "read_only_onload": 0, + "show_name_in_global_search": 0, + "sort_field": "modified", + "sort_order": "DESC", + "title_field": "user", + "track_changes": 1, + "track_seen": 0, "track_views": 0 } \ No newline at end of file From 917f7c8419edb2cdeded461b60c54ea68e0c8843 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Thu, 14 Feb 2019 15:31:01 +0530 Subject: [PATCH 18/25] fix: Clear server messages after Password Update --- frappe/www/update-password.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frappe/www/update-password.html b/frappe/www/update-password.html index 9e5ab57bd4..9689a1d3b9 100644 --- a/frappe/www/update-password.html +++ b/frappe/www/update-password.html @@ -78,7 +78,12 @@ frappe.ready(function() { .removeClass().addClass('indicator green') .html("{{ _('Password Updated') }}"); if(r.message) { - frappe.msgprint("{{ _("Password Updated") }}"); + frappe.msgprint({ + message: "{{ _("Password Updated") }}", + // password is updated successfully + // clear any server message + clear: true + }); setTimeout(function() { window.location.href = r.message; }, 2000); From ca7fb4df3a6e13496878c13a7113aab3cff01254 Mon Sep 17 00:00:00 2001 From: Jay Parikh Date: Thu, 14 Feb 2019 11:59:43 +0000 Subject: [PATCH 19/25] Fix - svg logo not working for Desk Icon --- frappe/public/js/frappe/ui/app_icon.js | 1 - 1 file changed, 1 deletion(-) diff --git a/frappe/public/js/frappe/ui/app_icon.js b/frappe/public/js/frappe/ui/app_icon.js index 5ca6adb556..a2efb08aa4 100644 --- a/frappe/public/js/frappe/ui/app_icon.js +++ b/frappe/public/js/frappe/ui/app_icon.js @@ -35,7 +35,6 @@ frappe.ui.app_icon = { } }); icon = ''+ icon+''; - return icon; } else { icon = ''; } From 2fd6cd65f5341f283a800c77858285335dae1000 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Fri, 15 Feb 2019 12:48:33 +0530 Subject: [PATCH 20/25] fix: Permlevel check in Print Stupid check hides fields with permlevel > 0 no matter who has access --- frappe/www/printview.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/www/printview.py b/frappe/www/printview.py index ea7cae836a..d8c9ec66bd 100644 --- a/frappe/www/printview.py +++ b/frappe/www/printview.py @@ -326,7 +326,7 @@ def is_visible(df, doc): if df.fieldname in doc.hide_in_print_layout: return False - if df.permlevel or 0 > 0 and not doc.has_permlevel_access_to(df.fieldname, df): + if (df.permlevel or 0) > 0 and not doc.has_permlevel_access_to(df.fieldname, df): return False return not doc.is_print_hide(df.fieldname, df) From 683be9e0966a288ce641b4b45031f5d994b13e5f Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Fri, 15 Feb 2019 14:24:08 +0530 Subject: [PATCH 21/25] feat(error-report): Collect frame locals in error report (#6938) * feat(error-report): Collect frame locals in error report * style: Linting fixes --- frappe/__init__.py | 3 ++- frappe/public/js/frappe/request.js | 8 +++++++- frappe/utils/error.py | 11 +++++++++++ frappe/utils/response.py | 4 ++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 1be882ab35..1516c6bdba 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -16,6 +16,7 @@ from faker import Faker # public from .exceptions import * from .utils.jinja import (get_jenv, get_template, render_template, get_email_from_template, get_jloader) +from .utils.error import get_frame_locals # Hamless for Python 3 # For Python 2 set default encoding to utf-8 @@ -273,7 +274,7 @@ def errprint(msg): if not request or (not "cmd" in local.form_dict) or conf.developer_mode: print(msg.encode('utf-8')) - error_log.append(msg) + error_log.append({"exc": msg, "locals": get_frame_locals()}) def log(msg): """Add to `debug_log`. diff --git a/frappe/public/js/frappe/request.js b/frappe/public/js/frappe/request.js index 28240858f4..99b130ceb9 100644 --- a/frappe/public/js/frappe/request.js +++ b/frappe/public/js/frappe/request.js @@ -187,7 +187,7 @@ frappe.request.call = function(opts) { type: opts.type, dataType: opts.dataType || 'json', async: opts.async, - headers: { + headers: { "X-Frappe-CSRF-Token": frappe.csrf_token, "Accept": "application/json" }, @@ -374,9 +374,12 @@ frappe.request.report_error = function(xhr, request_opts) { var data = JSON.parse(xhr.responseText); if (data.exc) { var exc = (JSON.parse(data.exc) || []).join("\n"); + var locals = (JSON.parse(data.locals) || []).join("\n"); delete data.exc; + delete data.locals; } else { var exc = ""; + locals = ""; } if (exc) { @@ -408,6 +411,9 @@ frappe.request.report_error = function(xhr, request_opts) { '
Error Report
', '
' + exc + '
', '
', + '
Locals
', + '
' + locals + '
', + '
', '
Request Data
', '
' + JSON.stringify(request_opts, null, "\t") + '
', '
', diff --git a/frappe/utils/error.py b/frappe/utils/error.py index f249355ee5..a4b2710d0a 100644 --- a/frappe/utils/error.py +++ b/frappe/utils/error.py @@ -199,3 +199,14 @@ def clear_old_snapshots(): def get_error_snapshot_path(): return frappe.get_site_path('error-snapshots') + +def get_frame_locals(): + traceback = sys.exc_info()[2] + if traceback: + frames = inspect.getinnerframes(traceback, context=0) + _locals = ['Locals (most recent call last):'] + for frame, filename, lineno, function, __, __ in frames: + if '/apps/' in filename: + _locals.append('File "{}", line {}, in {}\n{}'.format(filename, lineno, function, json.dumps(frame.f_locals, default=str, indent=4))) + + return '\n'.join(_locals) diff --git a/frappe/utils/response.py b/frappe/utils/response.py index b1f0ddb42d..07bd85c980 100644 --- a/frappe/utils/response.py +++ b/frappe/utils/response.py @@ -105,8 +105,8 @@ def make_logs(response = None): response = frappe.local.response if frappe.error_log: - # frappe.response['exc'] = json.dumps("\n".join([cstr(d) for d in frappe.error_log])) - response['exc'] = json.dumps([frappe.utils.cstr(d) for d in frappe.local.error_log]) + response['exc'] = json.dumps([frappe.utils.cstr(d["exc"]) for d in frappe.local.error_log]) + response['locals'] = json.dumps([frappe.utils.cstr(d["locals"]) for d in frappe.local.error_log]) if frappe.local.message_log: response['_server_messages'] = json.dumps([frappe.utils.cstr(d) for From d9a317e2024dd427993e106f7febfaf70b6a73a5 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Fri, 15 Feb 2019 15:00:05 +0530 Subject: [PATCH 22/25] fix(desk): Prepared Report fixes (#6939) * fix(desk): Fetch prepared report matching filter values * fix(desk): Ignore filters when prepared report doc name is given * fix(desk): Delete prepared report if data is corrupted * style: Linting fixes --- frappe/desk/query_report.py | 42 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/frappe/desk/query_report.py b/frappe/desk/query_report.py index 105be44dce..f548b99024 100644 --- a/frappe/desk/query_report.py +++ b/frappe/desk/query_report.py @@ -191,29 +191,33 @@ def run(report_name, filters=None, user=None): def get_prepared_report_result(report, filters, dn="", user=None): latest_report_data = {} - # Only look for completed prepared reports with given filters. - doc_list = frappe.get_all("Prepared Report", - filters={"status": "Completed", "report_name": report.name, "filters": filters, "owner": user}) - doc = None - if len(doc_list): - if dn: - # Get specified dn - doc = frappe.get_doc("Prepared Report", dn) - else: + if dn: + # Get specified dn + doc = frappe.get_doc("Prepared Report", dn) + else: + # Only look for completed prepared reports with given filters. + doc_list = frappe.get_all("Prepared Report", filters={"status": "Completed", "filters": json.dumps(filters), "owner": user}) + if doc_list: # Get latest doc = frappe.get_doc("Prepared Report", doc_list[0]) - # Prepared Report data is stored in a GZip compressed JSON file - attached_file_name = frappe.db.get_value("File", {"attached_to_doctype": doc.doctype, "attached_to_name":doc.name}, "name") - compressed_content = get_file(attached_file_name)[1] - uncompressed_content = gzip_decompress(compressed_content) - data = json.loads(uncompressed_content) - if data: - latest_report_data = { - "columns": json.loads(doc.columns) if doc.columns else data[0], - "result": data - } + if doc: + try: + # Prepared Report data is stored in a GZip compressed JSON file + attached_file_name = frappe.db.get_value("File", {"attached_to_doctype": doc.doctype, "attached_to_name":doc.name}, "name") + compressed_content = get_file(attached_file_name)[1] + uncompressed_content = gzip_decompress(compressed_content) + data = json.loads(uncompressed_content) + if data: + latest_report_data = { + "columns": json.loads(doc.columns) if doc.columns else data[0], + "result": data + } + except Exception: + frappe.delete_doc("Prepared Report", doc.name) + frappe.db.commit() + doc = None latest_report_data.update({ "prepared_report": True, From cc0ce14f678155e8f472c525184d4af4bdf4bf60 Mon Sep 17 00:00:00 2001 From: Saif Date: Fri, 15 Feb 2019 14:31:22 +0500 Subject: [PATCH 23/25] fix: Update DataTable hook for columnTotal (#6904) Update for changes in https://github.com/frappe/datatable/pull/55 --- frappe/public/js/frappe/misc/utils.js | 14 ++++++++------ .../public/js/frappe/views/reports/grid_report.js | 2 +- .../public/js/frappe/views/reports/query_report.js | 2 +- .../public/js/frappe/views/reports/report_view.js | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/frappe/public/js/frappe/misc/utils.js b/frappe/public/js/frappe/misc/utils.js index 865a7d69c6..e038552fe4 100644 --- a/frappe/public/js/frappe/misc/utils.js +++ b/frappe/public/js/frappe/misc/utils.js @@ -658,13 +658,15 @@ Object.assign(frappe.utils, { return route; }, - report_total_accumulator: function(column, values, type) { - if (column.fieldtype == "Percent" || type === "mean") { - return values.reduce((a, b) => ({content: a.content + flt(b.content)})).content / values.length; - } else if (frappe.model.is_numeric_field(column.fieldtype)) { - return values.reduce((a, b) => ({content: a.content + flt(b.content)})).content; + report_column_total: function(values, column, type) { + if (column.column.fieldtype == "Percent" || type === "mean") { + return values.reduce((a, b) => a + flt(b)) / values.length; + } else if (column.column.fieldtype == "Int") { + return values.reduce((a, b) => a + cint(b)); + } else if (frappe.model.is_numeric_field(column.column.fieldtype)) { + return values.reduce((a, b) => a + flt(b)); } else { - return false; + return null; } } }); diff --git a/frappe/public/js/frappe/views/reports/grid_report.js b/frappe/public/js/frappe/views/reports/grid_report.js index a392e34b06..a8dda60606 100644 --- a/frappe/public/js/frappe/views/reports/grid_report.js +++ b/frappe/public/js/frappe/views/reports/grid_report.js @@ -424,7 +424,7 @@ frappe.views.GridReport = Class.extend({ } }, hooks: { - totalAccumulator: frappe.utils.report_total_accumulator + columnTotal: frappe.utils.report_column_total } }); diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index b6dc343adc..3ac5f9ed23 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -436,7 +436,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { cellHeight: 33, showTotalRow: this.raw_data.add_total_row, hooks: { - totalAccumulator: frappe.utils.report_total_accumulator + columnTotal: frappe.utils.report_column_total } }; diff --git a/frappe/public/js/frappe/views/reports/report_view.js b/frappe/public/js/frappe/views/reports/report_view.js index 921bfe07a1..f9d5aeb19a 100644 --- a/frappe/public/js/frappe/views/reports/report_view.js +++ b/frappe/public/js/frappe/views/reports/report_view.js @@ -230,7 +230,7 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView { } }, hooks: { - totalAccumulator: frappe.utils.report_total_accumulator + columnTotal: frappe.utils.report_column_total }, headerDropdown: [{ label: __('Add Column'), From 5ddf3c10bba6605ca310b4616764d0db05dd7499 Mon Sep 17 00:00:00 2001 From: Zarrar Date: Fri, 15 Feb 2019 15:10:14 +0530 Subject: [PATCH 24/25] fix: Language Code naming validation (#6933) * fix: language code naming fix * fix: validate name and language code --- frappe/core/doctype/language/language.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/frappe/core/doctype/language/language.py b/frappe/core/doctype/language/language.py index 8c7e01cb62..fb18abdf5e 100644 --- a/frappe/core/doctype/language/language.py +++ b/frappe/core/doctype/language/language.py @@ -3,11 +3,22 @@ # For license information, please see license.txt from __future__ import unicode_literals -import frappe, json +import frappe, json, re +from frappe import _ from frappe.model.document import Document class Language(Document): - pass + def validate(self): + validate_with_regex(self.language_code, "Language Code") + + def before_rename(self, old, new, merge=False): + validate_with_regex(new, "Name") + +def validate_with_regex(name, label): + pattern = re.compile("^[a-zA-Z]+[-_]*[a-zA-Z]+$") + if not pattern.match(name): + frappe.throw(_("""{0} must begin and end with a letter and can only contain letters, + hyphen or underscore.""").format(label)) def export_languages_json(): '''Export list of all languages''' From 73001d8202a3d125b0f09397bb907eabbd00af29 Mon Sep 17 00:00:00 2001 From: Frappe Bot Date: Fri, 15 Feb 2019 10:17:14 +0000 Subject: [PATCH 25/25] bumped to version 11.1.6 --- frappe/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index 1516c6bdba..bdd534bc62 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -24,7 +24,7 @@ if sys.version[0] == '2': reload(sys) sys.setdefaultencoding("utf-8") -__version__ = '11.1.5' +__version__ = '11.1.6' __title__ = "Frappe Framework" local = Local()