From 3e8ca0dd8d1b7279cba6eab85b40da601d442dcb Mon Sep 17 00:00:00 2001 From: marination Date: Fri, 27 Sep 2019 13:08:33 +0530 Subject: [PATCH 1/6] feat: Added 'Allow Import (via Data Import Tool)' checkbox in Customize Form Checkbox will let users enable DocTypes in Data Import Document Type Link Field in Data Import will fetch Importable DocTypes from meta --- frappe/custom/doctype/customize_form/customize_form.json | 9 ++++++++- frappe/custom/doctype/customize_form/customize_form.py | 3 ++- frappe/utils/user.py | 7 +++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/frappe/custom/doctype/customize_form/customize_form.json b/frappe/custom/doctype/customize_form/customize_form.json index d4b6bc6352..539051e4ef 100644 --- a/frappe/custom/doctype/customize_form/customize_form.json +++ b/frappe/custom/doctype/customize_form/customize_form.json @@ -18,6 +18,7 @@ "track_changes", "track_views", "allow_auto_repeat", + "allow_import", "image_view", "column_break_5", "title_field", @@ -167,13 +168,19 @@ "fieldname": "allow_auto_repeat", "fieldtype": "Check", "label": "Allow Auto Repeat" + }, + { + "default": "0", + "fieldname": "allow_import", + "fieldtype": "Check", + "label": "Allow Import (via Data Import Tool)" } ], "hide_toolbar": 1, "icon": "fa fa-glass", "idx": 1, "issingle": 1, - "modified": "2019-07-01 22:50:50.372465", + "modified": "2019-09-27 00:01:19.609039", "modified_by": "Administrator", "module": "Custom", "name": "Customize Form", diff --git a/frappe/custom/doctype/customize_form/customize_form.py b/frappe/custom/doctype/customize_form/customize_form.py index 425191c4eb..b851d40b83 100644 --- a/frappe/custom/doctype/customize_form/customize_form.py +++ b/frappe/custom/doctype/customize_form/customize_form.py @@ -30,7 +30,8 @@ doctype_properties = { 'max_attachments': 'Int', 'track_changes': 'Check', 'track_views': 'Check', - 'allow_auto_repeat': 'Check' + 'allow_auto_repeat': 'Check', + 'allow_import': 'Check' } docfield_properties = { diff --git a/frappe/utils/user.py b/frappe/utils/user.py index 1446b9749f..ec899d5c47 100755 --- a/frappe/utils/user.py +++ b/frappe/utils/user.py @@ -157,8 +157,11 @@ class UserPermissions: self.can_read.remove(dt) if "System Manager" in self.get_roles(): - self.can_import = list(filter(lambda d: d in self.can_create, - frappe.db.sql_list("""select name from `tabDocType` where allow_import = 1"""))) + docs = [x['name'] for x in frappe.get_all("DocType", "name")] + frappe.clear_cache() + for docname in docs: + if frappe.get_meta(docname).allow_import == 1: + self.can_import.append(docname) def get_defaults(self): import frappe.defaults From e08779c362536c4af1597de87a81b5522bcc5d01 Mon Sep 17 00:00:00 2001 From: marination Date: Wed, 9 Oct 2019 12:36:35 +0530 Subject: [PATCH 2/6] fix: Importable docs via Customize Form set in redis cache can_import list is set in redis cache Data Import's set query will fetch from cache ad update list --- .../core/doctype/data_import/data_import.js | 23 +++++++++++-------- .../core/doctype/data_import/data_import.py | 5 ++++ .../customize_form/customize_form.json | 2 +- frappe/utils/user.py | 6 ++--- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/frappe/core/doctype/data_import/data_import.js b/frappe/core/doctype/data_import/data_import.js index eeaa5ac34e..c5bd4e99c9 100644 --- a/frappe/core/doctype/data_import/data_import.js +++ b/frappe/core/doctype/data_import/data_import.js @@ -7,15 +7,20 @@ frappe.ui.form.on('Data Import', { frm.set_value("action", ""); } - frm.set_query("reference_doctype", function() { - return { - "filters": { - "issingle": 0, - "istable": 0, - "name": ['in', frappe.boot.user.can_import] - } - }; - }); + frappe.call({ + method: "frappe.core.doctype.data_import.data_import.get_importable_doc", + callback: function (r) { + frm.set_query("reference_doctype", function () { + return { + "filters": { + "issingle": 0, + "istable": 0, + "name": ['in', r.message] + } + }; + }); + } + }), // should never check public frm.fields_dict["import_file"].df.is_private = 1; diff --git a/frappe/core/doctype/data_import/data_import.py b/frappe/core/doctype/data_import/data_import.py index 5500f1c617..80f8553121 100644 --- a/frappe/core/doctype/data_import/data_import.py +++ b/frappe/core/doctype/data_import/data_import.py @@ -29,6 +29,11 @@ class DataImport(Document): upload(data_import_doc=self, from_data_import="Yes", validate_template=True) +@frappe.whitelist() +def get_importable_doc(): + import_lst = frappe.cache().hget("can_import", frappe.session.user) + return import_lst + @frappe.whitelist() def import_data(data_import): frappe.db.set_value("Data Import", data_import, "import_status", "In Progress", update_modified=False) diff --git a/frappe/custom/doctype/customize_form/customize_form.json b/frappe/custom/doctype/customize_form/customize_form.json index 539051e4ef..0b1df62f9d 100644 --- a/frappe/custom/doctype/customize_form/customize_form.json +++ b/frappe/custom/doctype/customize_form/customize_form.json @@ -180,7 +180,7 @@ "icon": "fa fa-glass", "idx": 1, "issingle": 1, - "modified": "2019-09-27 00:01:19.609039", + "modified": "2019-10-08 11:16:36.698006", "modified_by": "Administrator", "module": "Custom", "name": "Customize Form", diff --git a/frappe/utils/user.py b/frappe/utils/user.py index ec899d5c47..0959316ee8 100755 --- a/frappe/utils/user.py +++ b/frappe/utils/user.py @@ -157,11 +157,11 @@ class UserPermissions: self.can_read.remove(dt) if "System Manager" in self.get_roles(): - docs = [x['name'] for x in frappe.get_all("DocType", "name")] - frappe.clear_cache() + docs = [x["name"] for x in frappe.get_all("DocType", "name")] for docname in docs: - if frappe.get_meta(docname).allow_import == 1: + if frappe.get_meta(docname, cached=False).allow_import == 1: self.can_import.append(docname) + frappe.cache().hset("can_import", frappe.session.user, self.can_import) def get_defaults(self): import frappe.defaults From 5e6ce7d2eb0fc64326e169a62dea4dba85bff31e Mon Sep 17 00:00:00 2001 From: Himanshu Warekar Date: Fri, 11 Oct 2019 15:07:26 +0530 Subject: [PATCH 3/6] fix: TypeError: 'NoneType' object is not iterable --- frappe/integrations/doctype/google_calendar/google_calendar.py | 2 +- frappe/integrations/doctype/google_contacts/google_contacts.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frappe/integrations/doctype/google_calendar/google_calendar.py b/frappe/integrations/doctype/google_calendar/google_calendar.py index d6ba82ed5a..fa2eea6ce1 100644 --- a/frappe/integrations/doctype/google_calendar/google_calendar.py +++ b/frappe/integrations/doctype/google_calendar/google_calendar.py @@ -220,7 +220,7 @@ def sync_events_from_google_calendar(g_calendar, method=None, page_length=10): except HttpError as err: frappe.throw(_("Google Calendar - Could not fetch event from Google Calendar, error code {0}.").format(err.resp.status)) - for event in events.get("items"): + for event in events.get("items", []): results.append(event) if not events.get("nextPageToken"): diff --git a/frappe/integrations/doctype/google_contacts/google_contacts.py b/frappe/integrations/doctype/google_contacts/google_contacts.py index 522a0e31a6..0e28c1306c 100644 --- a/frappe/integrations/doctype/google_contacts/google_contacts.py +++ b/frappe/integrations/doctype/google_contacts/google_contacts.py @@ -155,7 +155,7 @@ def sync_contacts_from_google_contacts(g_contact): except HttpError as err: frappe.throw(_("Google Contacts - Could not sync contacts from Google Contacts {0}, error code {1}.").format(account.name, err.resp.status)) - for contact in contacts.get("connections"): + for contact in contacts.get("connections", []): results.append(contact) if not contacts.get("nextPageToken"): From 30c672039811e7790ef52f091d6fe1d38de56410 Mon Sep 17 00:00:00 2001 From: Sahil Khan Date: Fri, 11 Oct 2019 16:03:24 +0530 Subject: [PATCH 4/6] fix(patch): check if contact already exists for user --- frappe/patches/v11_0/create_contact_for_user.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frappe/patches/v11_0/create_contact_for_user.py b/frappe/patches/v11_0/create_contact_for_user.py index 8a9238572e..b4722ab3ae 100644 --- a/frappe/patches/v11_0/create_contact_for_user.py +++ b/frappe/patches/v11_0/create_contact_for_user.py @@ -17,6 +17,8 @@ def execute(): users = frappe.get_all('User', filters={"name": ('not in', 'Administrator, Guest')}, fields=["*"]) for user in users: + if frappe.db.exists("Contact", {"email_id": user.email}) or frappe.db.exists("Contact Email", {"email_id": user.email}): + continue if user.first_name: user.first_name = re.sub("[<>]+", '', frappe.safe_decode(user.first_name)) if user.last_name: From 106b7e995c6c2fd51fdec412964ab9dfa4e2e16c Mon Sep 17 00:00:00 2001 From: Sahil Khan Date: Fri, 11 Oct 2019 16:08:16 +0530 Subject: [PATCH 5/6] fix(patch): reload prepared report doctype --- frappe/patches/v11_0/delete_all_prepared_reports.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frappe/patches/v11_0/delete_all_prepared_reports.py b/frappe/patches/v11_0/delete_all_prepared_reports.py index 10bc049895..de36db66af 100644 --- a/frappe/patches/v11_0/delete_all_prepared_reports.py +++ b/frappe/patches/v11_0/delete_all_prepared_reports.py @@ -3,6 +3,7 @@ import frappe def execute(): if frappe.db.table_exists('Prepared Report'): + frappe.reload_doc("core", "doctype", "prepared_doctype") prepared_reports = frappe.get_all("Prepared Report") for report in prepared_reports: frappe.delete_doc("Prepared Report", report.name) From 30f30d57ffa7973827af3e38fcb1d9862d278eea Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Wed, 9 Oct 2019 14:47:00 +0530 Subject: [PATCH 6/6] fix: notification is not working if recipients is not set and cc is set --- frappe/email/doctype/notification/notification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/email/doctype/notification/notification.py b/frappe/email/doctype/notification/notification.py index 6ae4243775..d40f64b8bd 100644 --- a/frappe/email/doctype/notification/notification.py +++ b/frappe/email/doctype/notification/notification.py @@ -143,7 +143,7 @@ def get_context(context): attachments = self.get_attachment(doc) recipients, cc, bcc = self.get_list_of_recipients(doc, context) - if not recipients: + if not (recipients or cc or bcc): return sender = None if self.sender and self.sender_email: