From 4816c72bbe1d4c5fa48f64312a3fbd7836997bab Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Sat, 5 Jan 2019 13:46:59 +0530 Subject: [PATCH 01/17] [Fix] 'dict' object has no attribute 'applicable_for' --- frappe/core/doctype/user_permission/user_permission.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index 0be62ffd01..0fd2efa757 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -56,10 +56,10 @@ def get_user_permissions(user=None): if not out.get(perm.allow): out[perm.allow] = [] - out[perm.allow].append({ + out[perm.allow].append(frappe._dict({ 'doc': doc_name, 'applicable_for': perm.get('applicable_for') - }) + })) try: for perm in frappe.get_all('User Permission', @@ -74,6 +74,7 @@ def get_user_permissions(user=None): for doc in decendants: add_doc_to_perm(perm, doc) + out = frappe._dict(out) frappe.cache().hset("user_permissions", user, out) except frappe.SQLError as e: From 19a8a6cdc0430e2913f1ed34b3299ba2c77a1d0d Mon Sep 17 00:00:00 2001 From: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com> Date: Wed, 16 Jan 2019 18:54:37 +0530 Subject: [PATCH 02/17] fix: Address and contact report (#6763) --- .../addresses_and_contacts.py | 54 ++++++++----------- 1 file changed, 22 insertions(+), 32 deletions(-) diff --git a/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py b/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py index edb69b831d..16451d0d46 100644 --- a/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py +++ b/frappe/contacts/report/addresses_and_contacts/addresses_and_contacts.py @@ -2,7 +2,6 @@ # For license information, please see license.txt from __future__ import unicode_literals -from six.moves import range from six import iteritems import frappe @@ -35,66 +34,57 @@ def get_columns(filters): ] def get_data(filters): - data = [] party_type = filters.get("party_type") party = filters.get("party_name") return get_party_addresses_and_contact(party_type, party) -def get_party_addresses_and_contact(party_type, party): +def get_party_addresses_and_contact(reference_doctype, reference_name): data = [] filters = None - party_details = frappe._dict() + reference_details = frappe._dict() - if not party_type: + if not reference_doctype: return [] - if party: - filters = { "name": party } + if reference_name: + filters = { "name": reference_name } - party_list = [d[0] for d in frappe.get_list(party_type, filters=filters, fields=["name"], as_list=True)] - for d in party_list: - party_details.setdefault(d, frappe._dict()) + reference_list = [d[0] for d in frappe.get_list(reference_doctype, filters=filters, fields=["name"], as_list=True)] + for d in reference_list: + reference_details.setdefault(d, frappe._dict()) - party_details = get_party_details(party_type, party_list, "Address", party_details) - party_details = get_party_details(party_type, party_list, "Contact", party_details) + reference_details = get_party_details(reference_doctype, "Address", reference_list, reference_details) + reference_details = get_party_details(reference_doctype, "Contact", reference_list, reference_details) - for party, details in iteritems(party_details): + for reference_name, details in iteritems(reference_details): addresses = details.get("address", []) contacts = details.get("contact", []) if not any([addresses, contacts]): - result = [party] + result = [reference_name] result.extend(add_blank_columns_for("Contact")) result.extend(add_blank_columns_for("Address")) data.append(result) else: - addresses = map(list, addresses) - contacts = map(list, contacts) + result = [reference_name] + result.extend(list(addresses) or add_blank_columns_for("Address")) + result.extend(list(contacts) or add_blank_columns_for("Contact")) + data.append(result) - max_length = max(len(addresses), len(contacts)) - for idx in range(0, max_length): - result = [party] - address = addresses[idx] if idx < len(addresses) else add_blank_columns_for("Address") - contact = contacts[idx] if idx < len(contacts) else add_blank_columns_for("Contact") - result.extend(address) - result.extend(contact) - - data.append(result) return data -def get_party_details(party_type, party_list, doctype, party_details): +def get_party_details(reference_doctype, doctype, reference_list, reference_details): filters = [ - ["Dynamic Link", "link_doctype", "=", party_type], - ["Dynamic Link", "link_name", "in", party_list] + ["Dynamic Link", "link_doctype", "=", reference_doctype], + ["Dynamic Link", "link_name", "in", reference_list] ] fields = ["`tabDynamic Link`.link_name"] + field_map.get(doctype, []) records = frappe.get_list(doctype, filters=filters, fields=fields, as_list=True) for d in records: - details = party_details.get(d[0]) or {} - details.setdefault(frappe.scrub(doctype), []).append(d[1:]) + reference_details[d[0]][frappe.scrub(doctype)] = d[1:] - return party_details + return reference_details def add_blank_columns_for(doctype): - return ["" for field in field_map.get(doctype, [])] \ No newline at end of file + return ["" for _ in field_map.get(doctype, [])] \ No newline at end of file From 12348525688cbeaf5620e85f25e3510f47aba767 Mon Sep 17 00:00:00 2001 From: Charles-Henri Decultot Date: Fri, 18 Jan 2019 07:39:45 +0100 Subject: [PATCH 03/17] fix: Removal of a logging line (#6778) --- frappe/desk/doctype/event/event.py | 1 - 1 file changed, 1 deletion(-) diff --git a/frappe/desk/doctype/event/event.py b/frappe/desk/doctype/event/event.py index 0c64c487fb..e705470744 100644 --- a/frappe/desk/doctype/event/event.py +++ b/frappe/desk/doctype/event/event.py @@ -93,7 +93,6 @@ def get_permission_query_conditions(user): } def has_permission(doc, user): - frappe.log_error(doc.owner) if doc.event_type=="Public" or doc.owner==user: return True From 3d95621cd5e2cf3515207351f3201499efb228b3 Mon Sep 17 00:00:00 2001 From: Zarrar Date: Fri, 18 Jan 2019 13:33:59 +0530 Subject: [PATCH 04/17] feat(email): Retry sending Email 3 times before deeming it as error (#6754) * added field to note number of retries * incase of unprecedented errors increase retry counter and try sending again --- .../doctype/email_queue/email_queue.json | 33 ++++++++++++++++++- frappe/email/queue.py | 16 +++++---- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/frappe/email/doctype/email_queue/email_queue.json b/frappe/email/doctype/email_queue/email_queue.json index e4ebc153b5..ec640b19e9 100644 --- a/frappe/email/doctype/email_queue/email_queue.json +++ b/frappe/email/doctype/email_queue/email_queue.json @@ -524,6 +524,37 @@ "search_index": 0, "set_only_once": 0, "unique": 0 + }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "default": "0", + "fieldname": "retry", + "fieldtype": "Int", + "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": "Retry", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 1, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 } ], "has_web_view": 0, @@ -537,7 +568,7 @@ "issingle": 0, "istable": 0, "max_attachments": 0, - "modified": "2017-09-25 15:39:21.781324", + "modified": "2019-01-11 09:05:04.175368", "modified_by": "Administrator", "module": "Email", "name": "Email Queue", diff --git a/frappe/email/queue.py b/frappe/email/queue.py index 8f5a28efac..5fb1228034 100755 --- a/frappe/email/queue.py +++ b/frappe/email/queue.py @@ -382,7 +382,7 @@ def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=Fals email = frappe.db.sql('''select name, status, communication, message, sender, reference_doctype, reference_name, unsubscribe_param, unsubscribe_method, expose_recipients, - show_as_cc, add_unsubscribe_link, attachments + show_as_cc, add_unsubscribe_link, attachments, retry from `tabEmail Queue` where @@ -464,12 +464,16 @@ def send_one(email, smtpserver=None, auto_commit=True, now=False, from_test=Fals except Exception as e: frappe.db.rollback() - if any("Sent" == s.status for s in recipients_list): - frappe.db.sql("""update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""", - (text_type(e), email.name), auto_commit=auto_commit) + if email.retry < 3: + frappe.db.sql("""update `tabEmail Queue` set status='Not Sent', modified=%s, retry=retry+1 where name=%s""", + (now_datetime(), email.name), auto_commit=auto_commit) else: - frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s -where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) + if any("Sent" == s.status for s in recipients_list): + frappe.db.sql("""update `tabEmail Queue` set status='Partially Errored', error=%s where name=%s""", + (text_type(e), email.name), auto_commit=auto_commit) + else: + frappe.db.sql("""update `tabEmail Queue` set status='Error', error=%s + where name=%s""", (text_type(e), email.name), auto_commit=auto_commit) if email.communication: frappe.get_doc('Communication', email.communication).set_delivery_status(commit=auto_commit) From d9ee1674c59a1b80782bba7ce536c23fbe9acc12 Mon Sep 17 00:00:00 2001 From: Andrew McLeod Date: Fri, 18 Jan 2019 08:29:12 +0000 Subject: [PATCH 05/17] fix: Add 'parent' argument to frappe.db.get_value. (#6570) Add 'parent' to call to get_value in data.js. Fixes issues with lookups in data.js which check for already existing names. Without this, the get_value calls fail for child fields such as 'barcode' in Item Barcode with PermissionError warning. --- frappe/public/js/frappe/db.js | 5 +++-- frappe/public/js/frappe/form/controls/data.js | 4 +++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frappe/public/js/frappe/db.js b/frappe/public/js/frappe/db.js index 5571dc2d49..d487c3fe56 100644 --- a/frappe/public/js/frappe/db.js +++ b/frappe/public/js/frappe/db.js @@ -30,13 +30,14 @@ frappe.db = { }); }); }, - get_value: function(doctype, filters, fieldname, callback) { + get_value: function(doctype, filters, fieldname, callback, parent) { return frappe.call({ method: "frappe.client.get_value", args: { doctype: doctype, fieldname: fieldname, - filters: filters + filters: filters, + parent: parent }, callback: function(r) { callback && callback(r.message); diff --git a/frappe/public/js/frappe/form/controls/data.js b/frappe/public/js/frappe/form/controls/data.js index 2e83e3b612..6dc8c3d387 100644 --- a/frappe/public/js/frappe/form/controls/data.js +++ b/frappe/public/js/frappe/form/controls/data.js @@ -45,7 +45,9 @@ frappe.ui.form.ControlData = frappe.ui.form.ControlInput.extend({ if (val) { this.set_description(__('{0} already exists. Select another name', [val.name])); } - }); + }, + this.doc.parenttype + ); this.last_check = null; }, 1000); this.last_check = timeout; From 98bd66ba0033ef767b5303b9952e7fa1a059496f Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Sun, 20 Jan 2019 10:35:57 +0530 Subject: [PATCH 06/17] fix(requirements): freeze requests-oauthlib to 1.1.0 --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index c3671e8e62..4c6510df51 100644 --- a/requirements.txt +++ b/requirements.txt @@ -35,6 +35,7 @@ pyasn1 zxcvbn-python unittest-xml-reporting oauthlib==2.1.0 +requests-oauthlib==1.1.0 pdfkit PyJWT PyPDF2 From 76380687adf0169f1af03625192ae05612ee6b89 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 21 Jan 2019 15:17:06 +0530 Subject: [PATCH 07/17] fix: Make event emitter from blank object MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - If a function is passed to jQuery, it calls it 🤷🏻‍♂️ - In hindsight, it is not needed to pass the object to jQuery - This fixes a weird bug explained here https://github.com/frappe/frappe/pull/6791 --- frappe/public/js/frappe/event_emitter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/event_emitter.js b/frappe/public/js/frappe/event_emitter.js index aeed656e4e..d0938b9b4a 100644 --- a/frappe/public/js/frappe/event_emitter.js +++ b/frappe/public/js/frappe/event_emitter.js @@ -4,7 +4,7 @@ frappe.provide('frappe.utils'); */ const EventEmitterMixin = { init() { - this.jq = jQuery(this); + this.jq = jQuery({}); }, trigger(evt, data) { From 95e9afa1f36849fbb544dad0ab71abd2d53bf8b3 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Mon, 21 Jan 2019 16:52:12 +0530 Subject: [PATCH 08/17] feat: Clear user permissions button (#6767) * Add button to delete user permissions in bulk * Show no records deleted the delete count is 0 * Return this from show of dialog to make it chainable * Add test for clear user permissions function * Fix test * Format code * Reset the user * Remove rollback from test * Move clear user permission button to menu * fix: Translations --- .../user_permission/user_permission.py | 12 ++++- .../user_permission/user_permission_list.js | 52 +++++++++++++++++++ frappe/public/js/frappe/ui/dialog.js | 1 + frappe/tests/test_permissions.py | 34 +++++++++++- 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 frappe/core/doctype/user_permission/user_permission_list.js diff --git a/frappe/core/doctype/user_permission/user_permission.py b/frappe/core/doctype/user_permission/user_permission.py index 0fd2efa757..43dff47745 100644 --- a/frappe/core/doctype/user_permission/user_permission.py +++ b/frappe/core/doctype/user_permission/user_permission.py @@ -96,7 +96,7 @@ def get_applicable_for_doctype_list(doctype, txt, searchfield, start, page_len, linked_doctypes = get_linked_doctypes(doctype, True).keys() linked_doctypes = list(linked_doctypes) linked_doctypes += [doctype] - + if txt: linked_doctypes = [d for d in linked_doctypes if txt in d.lower()] @@ -111,3 +111,13 @@ def get_applicable_for_doctype_list(doctype, txt, searchfield, start, page_len, def get_permitted_documents(doctype): return [d.get('doc') for d in get_user_permissions().get(doctype, []) \ if d.get('doc')] + +@frappe.whitelist() +def clear_user_permissions(user, for_doctype): + frappe.only_for('System Manager') + + total = frappe.db.count('User Permission', filters = dict(user=user, allow=for_doctype)) + if total: + frappe.db.sql('DELETE FROM `tabUser Permission` WHERE user=%s AND allow=%s', (user, for_doctype)) + frappe.clear_cache() + return total diff --git a/frappe/core/doctype/user_permission/user_permission_list.js b/frappe/core/doctype/user_permission/user_permission_list.js new file mode 100644 index 0000000000..39a4648334 --- /dev/null +++ b/frappe/core/doctype/user_permission/user_permission_list.js @@ -0,0 +1,52 @@ +frappe.listview_settings['User Permission'] = { + onload: function(list_view) { + list_view.page.add_menu_item(__("Clear User Permissions"), () => { + const dialog = new frappe.ui.Dialog({ + title: __('Clear User Permissions'), + fields: [ + { + 'fieldname': 'user', + 'label': __('For User'), + 'fieldtype': 'Link', + 'options': 'User', + 'reqd': 1 + }, + { + 'fieldname': 'for_doctype', + 'label': __('For Document Type'), + 'fieldtype': 'Link', + 'options': 'DocType', + 'reqd': 1 + }, + ], + primary_action: (data) => { + // mandatory not filled + if (!data) return; + + frappe.confirm(__('Are you sure?'), () => { + frappe + .xcall('frappe.core.doctype.user_permission.user_permission.clear_user_permissions', data) + .then(data => { + dialog.hide(); + let message = ''; + if (data === 0) { + message = __('No records deleted'); + } else { + message = __('{0} records deleted', [data]); + } + frappe.show_alert({ + message, + indicator: 'green' + }); + list_view.refresh(); + }); + }); + + }, + primary_action_label: __('Clear') + }); + + dialog.show(); + }); + } +}; diff --git a/frappe/public/js/frappe/ui/dialog.js b/frappe/public/js/frappe/ui/dialog.js index cd76db91d4..cfbd765497 100644 --- a/frappe/public/js/frappe/ui/dialog.js +++ b/frappe/public/js/frappe/ui/dialog.js @@ -153,6 +153,7 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { this.$wrapper.modal("show"); this.primary_action_fulfilled = false; this.is_visible = true; + return this; } hide() { this.$wrapper.modal("hide"); diff --git a/frappe/tests/test_permissions.py b/frappe/tests/test_permissions.py index 9924e92eda..13106697c5 100644 --- a/frappe/tests/test_permissions.py +++ b/frappe/tests/test_permissions.py @@ -14,6 +14,7 @@ from frappe.permissions import (add_user_permission, remove_user_permission, get_valid_perms) from frappe.core.page.permission_manager.permission_manager import update, reset from frappe.test_runner import make_test_records_for_doctype +from frappe.core.doctype.user_permission.user_permission import clear_user_permissions test_dependencies = ['Blogger', 'Blog Post', "User", "Contact", "Salutation"] @@ -427,4 +428,35 @@ class TestPermissions(unittest.TestCase): self.assertTrue(doc.has_permission("delete")) # delete the created doc - frappe.delete_doc('Blog Post', '-test-blog-post-title') \ No newline at end of file + frappe.delete_doc('Blog Post', '-test-blog-post-title') + + def test_clear_user_permissions(self): + current_user = frappe.session.user + frappe.set_user('Administrator') + clear_user_permissions_for_doctype('Blog Category', 'test2@example.com') + clear_user_permissions_for_doctype('Blog Post', 'test2@example.com') + + add_user_permission('Blog Post', '-test-blog-post-1', 'test2@example.com') + add_user_permission('Blog Post', '-test-blog-post-2', 'test2@example.com') + add_user_permission("Blog Category", '_Test Blog Category 1', 'test2@example.com') + + deleted_user_permission_count = clear_user_permissions('test2@example.com', 'Blog Post') + + self.assertEqual(deleted_user_permission_count, 2) + + blog_post_user_permission_count = frappe.db.count('User Permission', filters={ + 'user': 'test2@example.com', + 'allow': 'Blog Post' + }) + + self.assertEqual(blog_post_user_permission_count, 0) + + blog_category_user_permission_count = frappe.db.count('User Permission', filters={ + 'user': 'test2@example.com', + 'allow': 'Blog Category' + }) + + self.assertEqual(blog_category_user_permission_count, 1) + + # reset the user + frappe.set_user(current_user) From 6724b0fd26583bc4067b2db97811d2bf7e20dd64 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 21 Jan 2019 17:42:21 +0530 Subject: [PATCH 09/17] fix(quill): Convert ol to ul before sending the value to server (#6795) --- .../public/js/frappe/form/controls/text_editor.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/text_editor.js b/frappe/public/js/frappe/form/controls/text_editor.js index 5203c57e7f..f5dfeb3893 100644 --- a/frappe/public/js/frappe/form/controls/text_editor.js +++ b/frappe/public/js/frappe/form/controls/text_editor.js @@ -181,6 +181,19 @@ frappe.ui.form.ControlTextEditor = frappe.ui.form.ControlCode.extend({ }, get_input_value() { - return this.quill ? this.quill.root.innerHTML : ''; + let value = this.quill ? this.quill.root.innerHTML : ''; + // quill keeps ol as a common container for both type of lists + // and uses css for appearances, this is not semantic + // so we convert ol to ul if it is unordered + const $value = $(`
${value}
`); + $value.find('ol li[data-list=bullet]:first-child').each((i, li) => { + let $li = $(li); + let $parent = $li.parent(); + let $children = $parent.children(); + let $ul = $('
    ').append($children); + $parent.replaceWith($ul); + }); + value = $value.html(); + return value; } }); From 987a604749b5fce6bbd6dcdbc77cf9f943b26ca5 Mon Sep 17 00:00:00 2001 From: Faris Ansari Date: Mon, 21 Jan 2019 17:57:38 +0530 Subject: [PATCH 10/17] fix: Use ImportError instead of ModuleNotFoundError (#6797) - ModuleNotFoundError is available in python 3.6 --- frappe/utils/print_format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/utils/print_format.py b/frappe/utils/print_format.py index ca6ff8c2d3..26f90e16f2 100644 --- a/frappe/utils/print_format.py +++ b/frappe/utils/print_format.py @@ -106,7 +106,7 @@ def print_by_server(doctype, name, print_format=None, doc=None, no_letterhead=0) print_settings = frappe.get_doc("Print Settings") try: import cups - except ModuleNotFoundError: + except ImportError: frappe.throw("You need to install pycups to use this feature!") return try: From 555049b75f8b781e56b8475e434cd27eedcc7e64 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 22 Jan 2019 11:25:47 +0530 Subject: [PATCH 11/17] fix(grid): Download hidden fields data from grid (#6796) --- frappe/public/js/frappe/form/grid.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/public/js/frappe/form/grid.js b/frappe/public/js/frappe/form/grid.js index d751ca3d5a..a535d0b35a 100644 --- a/frappe/public/js/frappe/form/grid.js +++ b/frappe/public/js/frappe/form/grid.js @@ -683,8 +683,8 @@ export default class Grid { data.push([__("Do not edit headers which are preset in the template")]); data.push(["------"]); $.each(frappe.get_meta(me.df.options).fields, function(i, df) { - // don't include the hidden field in the template - if(frappe.model.is_value_type(df.fieldtype) && !df.hidden) { + // don't include the read-only field in the template + if(frappe.model.is_value_type(df.fieldtype) && !df.read_only) { data[1].push(df.label); data[2].push(df.fieldname); let description = (df.description || "") + ' '; From 132a92e6ccc23a596ee5f5aa5e052210b7dd7e76 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Tue, 22 Jan 2019 11:26:10 +0530 Subject: [PATCH 12/17] fix: "list object has no get attribute" error while saving new doc (#6799) * Fix .get() function not found error while saving new doc * Remove print statement --- frappe/model/create_new.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frappe/model/create_new.py b/frappe/model/create_new.py index 0d77044eeb..c6bcc42f06 100644 --- a/frappe/model/create_new.py +++ b/frappe/model/create_new.py @@ -133,13 +133,14 @@ def user_permissions_exist(df, user_permissions): def get_default_based_on_another_field(df, user_permissions, parent_doc): # default value based on another document + from frappe.permissions import get_allowed_docs_for_doctype + ref_doctype = df.default[1:] ref_fieldname = ref_doctype.lower().replace(" ", "_") reference_name = parent_doc.get(ref_fieldname) if parent_doc else frappe.db.get_default(ref_fieldname) - default_value = frappe.db.get_value(ref_doctype, reference_name, df.fieldname) is_allowed_default_value = (not user_permissions_exist(df, user_permissions) or - (default_value in user_permissions.get(df.options).get('docs', []))) + (default_value in get_allowed_docs_for_doctype(user_permissions[df.options], df.parent))) # is this allowed as per user permissions if is_allowed_default_value: From b2f559ce7956fde1646a7d8447e0ffb3185d02f6 Mon Sep 17 00:00:00 2001 From: Aditya Hase Date: Tue, 22 Jan 2019 11:27:18 +0530 Subject: [PATCH 13/17] fix(list-view): Show count that matches number of rows (#6798) --- frappe/public/js/frappe/list/list_view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index f8cdd116d4..1d36bebdfa 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -597,7 +597,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { args: { doctype: this.doctype, filters: this.get_filters_for_args(), - fields: [`count(${frappe.model.get_full_column_name('name', this.doctype)}) as total_count`] + fields: [`count(distinct ${frappe.model.get_full_column_name('name', this.doctype)}) as total_count`], } }).then(r => { this.total_count = r.message.values[0][0] || current_count; From c7c82ff972020c4782fb5743262de4f9ef776340 Mon Sep 17 00:00:00 2001 From: Saif Date: Tue, 22 Jan 2019 10:58:26 +0500 Subject: [PATCH 14/17] WebsiteGenerator call super class clear_cache (#6786) --- frappe/website/website_generator.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/website/website_generator.py b/frappe/website/website_generator.py index d25c56b6b1..67b29c0c06 100644 --- a/frappe/website/website_generator.py +++ b/frappe/website/website_generator.py @@ -68,6 +68,7 @@ class WebsiteGenerator(Document): return title_field def clear_cache(self): + super(WebsiteGenerator, self).clear_cache() clear_cache(self.route) def scrub(self, text): From c58d2c34d48575867d229085231d6fb80b73be6a Mon Sep 17 00:00:00 2001 From: Zarrar Date: Tue, 22 Jan 2019 14:40:26 +0530 Subject: [PATCH 15/17] fix: don't append signature if it is already present (#6800) --- frappe/public/js/frappe/views/communication.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 95fef7cf5a..027f1fd1b7 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -639,6 +639,10 @@ frappe.views.CommunicationComposer = Class.extend({ + this.real_name + ",


    " + (this.message || ""); } + if(this.message && signature && this.message.includes(signature)) { + signature = ""; + } + let reply = (this.message || "") + (signature ? ("
    " + signature) : ""); let content = ''; From a00b063d36995c522a8a6648ea1ddb47a4e577dd Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Tue, 22 Jan 2019 15:39:38 +0550 Subject: [PATCH 16/17] bumped to version 10.1.70 --- frappe/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index c5784af033..fb344b50ee 100644 --- a/frappe/__init__.py +++ b/frappe/__init__.py @@ -14,7 +14,7 @@ import os, sys, importlib, inspect, json from .exceptions import * from .utils.jinja import get_jenv, get_template, render_template, get_email_from_template -__version__ = '10.1.69' +__version__ = '10.1.70' __title__ = "Frappe Framework" local = Local() From 8f7ad2e2f7ed99dfc3e0c2f4f7ab3d93f807d66f Mon Sep 17 00:00:00 2001 From: Sagar Vora Date: Tue, 22 Jan 2019 16:02:02 +0550 Subject: [PATCH 17/17] bumped to version 11.0.3-beta.50 --- frappe/hooks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/hooks.py b/frappe/hooks.py index 2cb67836d3..5d722b299a 100644 --- a/frappe/hooks.py +++ b/frappe/hooks.py @@ -12,7 +12,7 @@ source_link = "https://github.com/frappe/frappe" app_license = "MIT" develop_version = '12.x.x-develop' -staging_version = '11.0.3-beta.49' +staging_version = '11.0.3-beta.50' app_email = "info@frappe.io"