From 582e1a8c2cbfb188fbbecef93061f521b278cbe9 Mon Sep 17 00:00:00 2001 From: Zarrar Date: Mon, 26 Feb 2018 12:27:26 +0530 Subject: [PATCH 01/13] [Hotfix] Skip notification count on Desk for Reports and Toggle charts based on Filter (#5080) * fix desktop crash after adding item balance report (simple) icon * toggle true when changing report filter range --- frappe/core/page/desktop/desktop.js | 2 +- frappe/public/js/frappe/views/reports/grid_report.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/frappe/core/page/desktop/desktop.js b/frappe/core/page/desktop/desktop.js index 7b95ba07a1..bc051f5038 100644 --- a/frappe/core/page/desktop/desktop.js +++ b/frappe/core/page/desktop/desktop.js @@ -313,7 +313,7 @@ $.extend(frappe.desktop, { } // if module found - if(module._id.indexOf('/')===-1) { + if(module._id.indexOf('/')===-1 && !module._report) { var notifier = $(".module-count-" + module._id); if(notifier.length) { notifier.toggle(sum ? true : false); diff --git a/frappe/public/js/frappe/views/reports/grid_report.js b/frappe/public/js/frappe/views/reports/grid_report.js index 054a3b2b09..9a54ea2546 100644 --- a/frappe/public/js/frappe/views/reports/grid_report.js +++ b/frappe/public/js/frappe/views/reports/grid_report.js @@ -669,6 +669,8 @@ frappe.views.GridReportWithPlot = frappe.views.GridReport.extend({ if (in_list(["Daily", "Weekly"], this.filter_inputs.range.val())) { this.chart_area.toggle(false); return; + } else { + this.chart_area.toggle(true); } var chart_data = this.get_chart_data ? this.get_chart_data() : null; From f97719c5781604125ea4d433c3647041a832e506 Mon Sep 17 00:00:00 2001 From: Zlash65 Date: Tue, 27 Feb 2018 15:20:03 +0530 Subject: [PATCH 02/13] dynamic link not working for base filters --- frappe/public/js/frappe/form/controls/dynamic_link.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/form/controls/dynamic_link.js b/frappe/public/js/frappe/form/controls/dynamic_link.js index 02e970091e..f62f1432fe 100644 --- a/frappe/public/js/frappe/form/controls/dynamic_link.js +++ b/frappe/public/js/frappe/form/controls/dynamic_link.js @@ -13,7 +13,7 @@ frappe.ui.form.ControlDynamicLink = frappe.ui.form.ControlLink.extend({ let input = null; if (cur_list) { // for list page - input = cur_list.filter_area.standard_filters_wrapper.find(selector); + input = cur_list.wrapper.find(selector); } if (cur_page) { input = $(cur_page.page).find(selector); From a56fe9a8fbfbad32e710464be894ca79d50b656e Mon Sep 17 00:00:00 2001 From: Zarrar Date: Thu, 22 Feb 2018 10:56:44 +0530 Subject: [PATCH 03/13] added function to update link-link based dependent values (#5048) --- frappe/model/rename_doc.py | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index ad747e8c63..039ad9502b 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -386,3 +386,48 @@ def bulk_rename(doctype, rows=None, via_console = False): if not via_console: return rename_log + +def update_linked_doctypes(parent, child, name, value): + """ + parent = Master DocType in which the changes are being made + child = DocType name of the field thats being updated + name = docname + value = updated value of the field + """ + parent_list = get_link_fields(parent) + child_list = get_link_fields(child) + + product_list = list_combinatrix(parent_list, child_list) + + for d in product_list: + frappe.db.sql(""" + update + `tab{doctype}` + set + {fieldname} = "{value}" + where + {parent_fieldname} = "{docname}" + and {fieldname} != "{value}" + """.format( + doctype = d['parent']['parent'], + fieldname = d['child']['fieldname'], + parent_fieldname = d['parent']['fieldname'], + value = value, + docname = name + )) + +def list_combinatrix(dict1, dict2): + """ form all possible products with the given lists elements """ + out, dict3 = [], {} + + from itertools import product + prod = product(dict1, dict2) + + for d in prod: + if d[0]['parent'] == d[1]['parent']: + dict3['parent'] = d[0] + dict3['child'] = d[1] + out.append(dict3) + dict3 = {} + + return out From c2fb0c3bdedec6a6db24e9d5b14135a901df7399 Mon Sep 17 00:00:00 2001 From: Achilles Rasquinha Date: Thu, 22 Feb 2018 18:05:38 +0530 Subject: [PATCH 04/13] conditional check for single docs (#5060) --- frappe/model/rename_doc.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index 039ad9502b..a84556ca63 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -400,21 +400,22 @@ def update_linked_doctypes(parent, child, name, value): product_list = list_combinatrix(parent_list, child_list) for d in product_list: - frappe.db.sql(""" - update - `tab{doctype}` - set - {fieldname} = "{value}" - where - {parent_fieldname} = "{docname}" - and {fieldname} != "{value}" - """.format( - doctype = d['parent']['parent'], - fieldname = d['child']['fieldname'], - parent_fieldname = d['parent']['fieldname'], - value = value, - docname = name - )) + if not d['parent']['issingle']: + frappe.db.sql(""" + update + `tab{doctype}` + set + {fieldname} = "{value}" + where + {parent_fieldname} = "{docname}" + and {fieldname} != "{value}" + """.format( + doctype = d['parent']['parent'], + fieldname = d['child']['fieldname'], + parent_fieldname = d['parent']['fieldname'], + value = frappe.db.escape(value), + docname = frappe.db.escape(name) + )) def list_combinatrix(dict1, dict2): """ form all possible products with the given lists elements """ From 1aad5d072a857cd7261cdd30e96343501e1cd356 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Fri, 23 Feb 2018 11:55:52 +0530 Subject: [PATCH 05/13] [optimize] get_link_fields --- frappe/model/rename_doc.py | 64 +++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index a84556ca63..fabd89690c 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -182,40 +182,46 @@ def update_link_field_values(link_fields, old, new, doctype): def get_link_fields(doctype): # get link fields from tabDocField - link_fields = frappe.db.sql("""\ - select parent, fieldname, - (select issingle from tabDocType dt - where dt.name = df.parent) as issingle - from tabDocField df - where - df.options=%s and df.fieldtype='Link'""", (doctype,), as_dict=1) + if not frappe.flags.link_fields: + frappe.flags.link_fields = {} - # get link fields from tabCustom Field - custom_link_fields = frappe.db.sql("""\ - select dt as parent, fieldname, - (select issingle from tabDocType dt - where dt.name = df.dt) as issingle - from `tabCustom Field` df - where - df.options=%s and df.fieldtype='Link'""", (doctype,), as_dict=1) + if not doctype in frappe.flags.link_fields: + link_fields = frappe.db.sql("""\ + select parent, fieldname, + (select issingle from tabDocType dt + where dt.name = df.parent) as issingle + from tabDocField df + where + df.options=%s and df.fieldtype='Link'""", (doctype,), as_dict=1) - # add custom link fields list to link fields list - link_fields += custom_link_fields + # get link fields from tabCustom Field + custom_link_fields = frappe.db.sql("""\ + select dt as parent, fieldname, + (select issingle from tabDocType dt + where dt.name = df.dt) as issingle + from `tabCustom Field` df + where + df.options=%s and df.fieldtype='Link'""", (doctype,), as_dict=1) - # remove fields whose options have been changed using property setter - property_setter_link_fields = frappe.db.sql("""\ - select ps.doc_type as parent, ps.field_name as fieldname, - (select issingle from tabDocType dt - where dt.name = ps.doc_type) as issingle - from `tabProperty Setter` ps - where - ps.property_type='options' and - ps.field_name is not null and - ps.value=%s""", (doctype,), as_dict=1) + # add custom link fields list to link fields list + link_fields += custom_link_fields - link_fields += property_setter_link_fields + # remove fields whose options have been changed using property setter + property_setter_link_fields = frappe.db.sql("""\ + select ps.doc_type as parent, ps.field_name as fieldname, + (select issingle from tabDocType dt + where dt.name = ps.doc_type) as issingle + from `tabProperty Setter` ps + where + ps.property_type='options' and + ps.field_name is not null and + ps.value=%s""", (doctype,), as_dict=1) - return link_fields + link_fields += property_setter_link_fields + + frappe.flags.link_fields[doctype] = link_fields + + return frappe.flags.link_fields[doctype] def update_options_for_fieldtype(fieldtype, old, new): if frappe.conf.developer_mode: From 22534536ce72070c21edd5c7a4eca320b985a2fc Mon Sep 17 00:00:00 2001 From: Zarrar Date: Fri, 23 Feb 2018 17:40:00 +0530 Subject: [PATCH 06/13] optimize update_linked_doctype util and get_fetch (#5071) --- frappe/model/rename_doc.py | 78 +++++++++++++++++++++----------------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index fabd89690c..1264432a60 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -393,48 +393,58 @@ def bulk_rename(doctype, rows=None, via_console = False): if not via_console: return rename_log -def update_linked_doctypes(parent, child, name, value): +def update_linked_doctypes(linked_doctype_info_list, docname, value): """ - parent = Master DocType in which the changes are being made - child = DocType name of the field thats being updated - name = docname - value = updated value of the field + linked_doctype_info_list = list formed by get_fetch_fields() function + docname = Master DocType's name in which modification are made + value = Value for the field thats set in other DocType's by fetching from Master DocType """ - parent_list = get_link_fields(parent) - child_list = get_link_fields(child) - product_list = list_combinatrix(parent_list, child_list) + for d in linked_doctype_info_list: + frappe.db.sql(""" + update + `tab{doctype}` + set + {linked_to_fieldname} = "{value}" + where + {master_fieldname} = "{docname}" + and {linked_to_fieldname} != "{value}" + """.format( + doctype = d['doctype'], + linked_to_fieldname = d['linked_to_fieldname'], + value = value, + master_fieldname = d['master_fieldname'], + docname = docname + )) - for d in product_list: - if not d['parent']['issingle']: - frappe.db.sql(""" - update - `tab{doctype}` - set - {fieldname} = "{value}" - where - {parent_fieldname} = "{docname}" - and {fieldname} != "{value}" - """.format( - doctype = d['parent']['parent'], - fieldname = d['child']['fieldname'], - parent_fieldname = d['parent']['fieldname'], - value = frappe.db.escape(value), - docname = frappe.db.escape(name) - )) +def get_fetch_fields(master, linked_to): + """ + master = Master DocType in which the changes are being made + linked_to = DocType name of the field thats being updated in Master -def list_combinatrix(dict1, dict2): - """ form all possible products with the given lists elements """ - out, dict3 = [], {} + This function fetches list of all DocType where both master and linked_to is found + as link fields. + Forms a list of dict in the form - + [{doctype: , parent_fieldname: , child_fieldname: ] + where + doctype = DocType where changes need to be made + parent_fieldname = Fieldname where options = parent + child_fieldname = Fieldname where options = child + """ + + master_list = get_link_fields(master) + linked_to_list = get_link_fields(linked_to) + out, linked_doctype_info = [], {} from itertools import product - prod = product(dict1, dict2) + product_list = product(master_list, linked_to_list) - for d in prod: + for d in product_list: if d[0]['parent'] == d[1]['parent']: - dict3['parent'] = d[0] - dict3['child'] = d[1] - out.append(dict3) - dict3 = {} + linked_doctype_info['doctype'] = d[0]['parent'] + linked_doctype_info['master_fieldname'] = d[0]['fieldname'] + linked_doctype_info['linked_to_fieldname'] = d[1]['fieldname'] + out.append(linked_doctype_info) + linked_doctype_info = {} return out From b5ecdf22fd77f91b95816a712481fee0ebd5e445 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Sun, 25 Feb 2018 10:41:11 +0530 Subject: [PATCH 07/13] Update territory and customer_group patch optimization (#5073) --- frappe/model/rename_doc.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index 1264432a60..7a33ccc1fa 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -393,12 +393,13 @@ def bulk_rename(doctype, rows=None, via_console = False): if not via_console: return rename_log -def update_linked_doctypes(linked_doctype_info_list, docname, value): +def update_linked_doctypes(doctype, docname, linked_to, value, ignore_doctypes=None): """ linked_doctype_info_list = list formed by get_fetch_fields() function docname = Master DocType's name in which modification are made value = Value for the field thats set in other DocType's by fetching from Master DocType """ + linked_doctype_info_list = get_fetch_fields(doctype, linked_to, ignore_doctypes) for d in linked_doctype_info_list: frappe.db.sql(""" @@ -417,34 +418,35 @@ def update_linked_doctypes(linked_doctype_info_list, docname, value): docname = docname )) -def get_fetch_fields(master, linked_to): +def get_fetch_fields(doctype, linked_to, ignore_doctypes=None): """ - master = Master DocType in which the changes are being made + doctype = Master DocType in which the changes are being made linked_to = DocType name of the field thats being updated in Master - This function fetches list of all DocType where both master and linked_to is found + This function fetches list of all DocType where both doctype and linked_to is found as link fields. Forms a list of dict in the form - - [{doctype: , parent_fieldname: , child_fieldname: ] + [{doctype: , master_fieldname: , linked_to_fieldname: ] where doctype = DocType where changes need to be made - parent_fieldname = Fieldname where options = parent - child_fieldname = Fieldname where options = child + master_fieldname = Fieldname where options = doctype + linked_to_fieldname = Fieldname where options = linked_to """ - master_list = get_link_fields(master) + master_list = get_link_fields(doctype) linked_to_list = get_link_fields(linked_to) - out, linked_doctype_info = [], {} + out = [] from itertools import product product_list = product(master_list, linked_to_list) for d in product_list: - if d[0]['parent'] == d[1]['parent']: + linked_doctype_info = frappe._dict() + if d[0]['parent'] == d[1]['parent'] \ + and (not ignore_doctypes or d[0]['parent'] not in ignore_doctypes): linked_doctype_info['doctype'] = d[0]['parent'] linked_doctype_info['master_fieldname'] = d[0]['fieldname'] linked_doctype_info['linked_to_fieldname'] = d[1]['fieldname'] out.append(linked_doctype_info) - linked_doctype_info = {} return out From aa442e33b08c0128a6a71ae00c183f93e2b7b60f Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 27 Feb 2018 15:54:07 +0530 Subject: [PATCH 08/13] update linked docs if not single --- frappe/model/rename_doc.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frappe/model/rename_doc.py b/frappe/model/rename_doc.py index 7a33ccc1fa..cc502016ea 100644 --- a/frappe/model/rename_doc.py +++ b/frappe/model/rename_doc.py @@ -443,7 +443,8 @@ def get_fetch_fields(doctype, linked_to, ignore_doctypes=None): for d in product_list: linked_doctype_info = frappe._dict() if d[0]['parent'] == d[1]['parent'] \ - and (not ignore_doctypes or d[0]['parent'] not in ignore_doctypes): + and (not ignore_doctypes or d[0]['parent'] not in ignore_doctypes) \ + and not d[1]['issingle']: linked_doctype_info['doctype'] = d[0]['parent'] linked_doctype_info['master_fieldname'] = d[0]['fieldname'] linked_doctype_info['linked_to_fieldname'] = d[1]['fieldname'] From afeae4e6c7eb41f940ca33adfcbd803e6a8ba892 Mon Sep 17 00:00:00 2001 From: Suraj Shetty Date: Wed, 28 Feb 2018 11:59:02 +0530 Subject: [PATCH 09/13] global clear cache fix --- frappe/sessions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/sessions.py b/frappe/sessions.py index f35a667dc6..a0432ea3c4 100644 --- a/frappe/sessions.py +++ b/frappe/sessions.py @@ -52,7 +52,7 @@ def clear_cache(user=None): def clear_global_cache(): frappe.model.meta.clear_cache() frappe.cache().delete_value(["app_hooks", "installed_apps", - "app_modules", "module_app", "notification_config", 'system_settings' + "app_modules", "module_app", "notification_config", 'system_settings', 'scheduler_events', 'time_zone', 'webhooks', 'active_domains', 'active_modules']) frappe.setup_module_map() From dbd93a3779424eaa9f75d3efe99b9c12b892e7ee Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Wed, 28 Feb 2018 17:08:19 +0530 Subject: [PATCH 10/13] [Fix] Email not sent when click on send in email prompt (#5092) --- frappe/public/js/frappe/views/communication.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 08797827fa..3ca9715556 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -554,7 +554,7 @@ frappe.views.CommunicationComposer = Class.extend({ }, is_print_letterhead_checked: function() { - if($(this.frm.wrapper).find('.form-print-wrapper').is(':visible')){ + if (this.frm && $(this.frm.wrapper).find('.form-print-wrapper').is(':visible')){ return $(this.frm.wrapper).find('.print-letterhead').prop('checked'); } else { return (frappe.model.get_doc(":Print Settings", "Print Settings") || From a62628637f72ab969f1d573dd569cb406eb4c498 Mon Sep 17 00:00:00 2001 From: Zarrar Date: Thu, 1 Mar 2018 11:40:07 +0530 Subject: [PATCH 11/13] Dropdown to select view mode fix (#5100) --- frappe/public/js/frappe/views/gantt/gantt_view.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frappe/public/js/frappe/views/gantt/gantt_view.js b/frappe/public/js/frappe/views/gantt/gantt_view.js index 885c7ddcc3..e58d5e7403 100644 --- a/frappe/public/js/frappe/views/gantt/gantt_view.js +++ b/frappe/public/js/frappe/views/gantt/gantt_view.js @@ -114,6 +114,10 @@ frappe.views.GanttView = frappe.views.ListRenderer.extend({ var mode = $(this).data('value'); me.gantt.change_view_mode(mode); $dropdown.find(".dropdown-text").text(mode); + $dropdown.removeClass('open'); + }); + $dropdown.on('click', '.dropdown-toggle', function() { + $dropdown.addClass('open'); }); }, From 22d0636f29f95878fc1f6dfe9e80140094758ac6 Mon Sep 17 00:00:00 2001 From: Zarrar Date: Mon, 5 Mar 2018 11:04:16 +0530 Subject: [PATCH 12/13] [Hotfix] Editing Filters does not remove the previous pill (#5110) * editing filter does not remove previous pill * fix undefined in kanban pill --- frappe/public/js/frappe/ui/filters/filters.js | 5 ++--- frappe/public/js/frappe/views/kanban/kanban_board.js | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/frappe/public/js/frappe/ui/filters/filters.js b/frappe/public/js/frappe/ui/filters/filters.js index 2ff8b51d5a..df161892f7 100644 --- a/frappe/public/js/frappe/ui/filters/filters.js +++ b/frappe/public/js/frappe/ui/filters/filters.js @@ -280,8 +280,7 @@ frappe.ui.Filter = Class.extend({ this.flist.remove(this); this.flist.push_new_filter(f[0], f[1], f[2], f[3]); - this.wrapper.remove(); - this.flist.update_filters(); + this.remove(); }, remove: function(dont_run) { @@ -499,7 +498,7 @@ frappe.ui.Filter = Class.extend({ }); this.$btn_group.find(".toggle-filter").on("click", function() { - $(this).closest('.show_filters').find('.filter_area').show() + $(this).closest('.show_filters').find('.filter_area').show(); me.wrapper.toggle(); }) this.wrapper.toggle(false); diff --git a/frappe/public/js/frappe/views/kanban/kanban_board.js b/frappe/public/js/frappe/views/kanban/kanban_board.js index a236d6a4fe..8ab6ae7a23 100644 --- a/frappe/public/js/frappe/views/kanban/kanban_board.js +++ b/frappe/public/js/frappe/views/kanban/kanban_board.js @@ -897,7 +897,8 @@ frappe.provide("frappe.views"); } meta.fields.forEach(function (df) { - if (in_list(['Data', 'Text', 'Small Text', 'Text Editor'], df.fieldtype) && !title_field) { + if (in_list(['Data', 'Text', 'Small Text', 'Text Editor'], df.fieldtype) + && !df.hidden && !title_field) { // can be mapped to textarea title_field = df; } From f290b38290b18c764c31a7511df5023128139157 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 5 Mar 2018 15:12:48 +0600 Subject: [PATCH 13/13] bumped to version 10.1.2 --- frappe/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frappe/__init__.py b/frappe/__init__.py index f18a794e7c..c4ae62f0af 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.1' +__version__ = '10.1.2' __title__ = "Frappe Framework" local = Local()