diff --git a/frappe/core/doctype/docfield/docfield.json b/frappe/core/doctype/docfield/docfield.json index c78495898e..622663bca4 100644 --- a/frappe/core/doctype/docfield/docfield.json +++ b/frappe/core/doctype/docfield/docfield.json @@ -108,7 +108,7 @@ "no_copy": 0, "oldfieldname": "fieldtype", "oldfieldtype": "Select", - "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nSection Break\nSelect\nSmall Text\nTable\nTable MultiSelect\nText\nText Editor\nTime\nSignature", + "options": "Attach\nAttach Image\nBarcode\nButton\nCheck\nCode\nColor\nColumn Break\nCurrency\nData\nDate\nDatetime\nDynamic Link\nFloat\nFold\nGeolocation\nHeading\nHTML\nHTML Editor\nImage\nInt\nLink\nLong Text\nMarkdown Editor\nPassword\nPercent\nRead Only\nRating\nSection Break\nSelect\nSmall Text\nTable\nTable MultiSelect\nText\nText Editor\nTime\nSignature", "permlevel": 0, "print_hide": 0, "print_hide_if_no_value": 0, @@ -1710,7 +1710,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2019-04-08 12:19:53.415372", + "modified": "2019-05-28 12:19:53.415372", "modified_by": "Administrator", "module": "Core", "name": "DocField", diff --git a/frappe/database/database.py b/frappe/database/database.py index 72e6715e69..3aab284de0 100644 --- a/frappe/database/database.py +++ b/frappe/database/database.py @@ -178,10 +178,11 @@ class Database(object): frappe.errprint(("Execution time: {0} sec").format(round(time_end - time_start, 2))) except Exception as e: - if(frappe.db.db_type == 'postgres'): + if frappe.conf.db_type == 'postgres': self.rollback() - if frappe.db.db_type == 'mariadb' and self.is_syntax_error(e): + elif self.is_syntax_error(e): + # only for mariadb frappe.errprint('Syntax error in query:') frappe.errprint(query) @@ -929,12 +930,26 @@ class Database(object): if values: query = frappe.safe_decode(self._cursor.mogrify(query, values)) if query.strip().lower().split()[0] in ('insert', 'delete', 'update', 'alter'): - # ([`\"']?) Captures ', " or ` at the begining of the table name (if provided) + # single_word_regex is designed to match following patterns + # `tabXxx`, tabXxx and "tabXxx" + + # multi_word_regex is designed to match following patterns + # `tabXxx Xxx` and "tabXxx Xxx" + + # ([`"]?) Captures " or ` at the begining of the table name (if provided) + # \1 matches the first captured group (quote character) at the end of the table name + # multi word table name must have surrounding quotes. + # (tab([A-Z]\w+)( [A-Z]\w+)*) Captures table names that start with "tab" # and are continued with multiple words that start with a captital letter # e.g. 'tabXxx' or 'tabXxx Xxx' or 'tabXxx Xxx Xxx' and so on - # \1 matches the first captured group (quote character) at the end of the table name - tables = [groups[1] for groups in re.findall(r'([`"\']?)(tab([A-Z]\w+)( [A-Z]\w+)*)\1', query)] + + single_word_regex = r'([`"]?)(tab([A-Z]\w+))\1' + multi_word_regex = r'([`"])(tab([A-Z]\w+)( [A-Z]\w+)+)\1' + tables = [] + for regex in (single_word_regex, multi_word_regex): + tables += [groups[1] for groups in re.findall(regex, query)] + if frappe.flags.touched_tables is None: frappe.flags.touched_tables = set() frappe.flags.touched_tables.update(tables) diff --git a/frappe/email/__init__.py b/frappe/email/__init__.py index 2875ba6c74..494a6e2bb3 100644 --- a/frappe/email/__init__.py +++ b/frappe/email/__init__.py @@ -23,7 +23,7 @@ def get_contact_list(txt, page_length=20): out = frappe.db.sql("""select email_id as value, concat(first_name, ifnull(concat(' ',last_name), '' )) as description from tabContact - where name like %(txt)s + where name like %(txt)s or email_id like %(txt)s %(condition)s limit %(page_length)s""", { 'txt': '%' + txt + '%', diff --git a/frappe/patches.txt b/frappe/patches.txt index b2276d5d81..ac3b3501f5 100644 --- a/frappe/patches.txt +++ b/frappe/patches.txt @@ -242,6 +242,7 @@ frappe.patches.v12_0.replace_null_values_in_tables frappe.patches.v12_0.reset_home_settings frappe.patches.v12_0.update_print_format_type frappe.patches.v11_0.remove_doctype_user_permissions_for_page_and_report #2019-05-01 +frappe.patches.v11_0.apply_customization_to_custom_doctype frappe.patches.v12_0.remove_feedback_rating frappe.patches.v12_0.move_form_attachments_to_attachments_folder frappe.patches.v12_0.move_timeline_links_to_dynamic_links diff --git a/frappe/patches/v11_0/apply_customization_to_custom_doctype.py b/frappe/patches/v11_0/apply_customization_to_custom_doctype.py new file mode 100644 index 0000000000..69db27368b --- /dev/null +++ b/frappe/patches/v11_0/apply_customization_to_custom_doctype.py @@ -0,0 +1,55 @@ +import frappe +from frappe.utils import cint + +# This patch aims to apply & delete all the customization +# on custom doctypes done through customize form + +# This is required because customize form in now blocked +# for custom doctypes and user may not be able to +# see previous customization + +def execute(): + custom_doctypes = frappe.get_all('DocType', filters={ + 'custom': 1 + }) + + for doctype in custom_doctypes: + property_setters = frappe.get_all('Property Setter', filters={ + 'doc_type': doctype.name, + 'doctype_or_field': 'DocField' + }, fields=['name', 'property', 'value', 'property_type', 'field_name']) + + custom_fields = frappe.get_all('Custom Field', + filters={'dt': doctype.name}, + fields=['*'] + ) + + property_setter_map = {} + + for prop in property_setters: + property_setter_map[prop.field_name] = prop + frappe.db.sql('DELETE FROM `tabProperty Setter` WHERE `name`=%s', prop.name) + + meta = frappe.get_doc('DocType', doctype.name) + + for df in meta.fields: + ps = property_setter_map.get(df.fieldname, None) + if ps: + value = cint(ps.value) if ps.property_type == 'Int' else ps.value + df.set(ps.property, value) + + for cf in custom_fields: + cf.pop('parenttype') + cf.pop('parentfield') + cf.pop('parent') + cf.pop('name') + field = meta.get_field(cf.fieldname) + if field: + field.update(cf) + else: + df = frappe.new_doc('DocField', meta, 'fields') + df.update(cf) + meta.fields.append(df) + frappe.db.sql('DELETE FROM `tabCustom Field` WHERE name=%s', cf.name) + + meta.save() \ No newline at end of file diff --git a/frappe/public/js/frappe/dom.js b/frappe/public/js/frappe/dom.js index da03bd29f8..6411c2fb2b 100644 --- a/frappe/public/js/frappe/dom.js +++ b/frappe/public/js/frappe/dom.js @@ -290,28 +290,31 @@ frappe.get_modal = function(title, content) { - `) + `); }; frappe.is_online = function() { diff --git a/frappe/public/js/frappe/form/multi_select_dialog.js b/frappe/public/js/frappe/form/multi_select_dialog.js index 61ebee4ba1..4e569033ba 100644 --- a/frappe/public/js/frappe/form/multi_select_dialog.js +++ b/frappe/public/js/frappe/form/multi_select_dialog.js @@ -19,6 +19,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ let me = this; this.page_length = 20; + this.start = 0; let fields = [ { @@ -55,7 +56,13 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ }, { fieldtype: "Section Break" }, { fieldtype: "HTML", fieldname: "results_area" }, - { fieldtype: "Button", fieldname: "make_new", label: __('Create a new ' + me.doctype) } + { fieldtype: "Button", fieldname: "more_btn", label: __("More"), + click: function(){ + me.start += 20; + frappe.flags.auto_scroll = true; + me.get_results(); + } + } ]); let doctype_plural = !this.doctype.endsWith('y') ? this.doctype + 's' @@ -65,25 +72,30 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ title: __("Select {0}", [(this.doctype=='[Select]') ? __("value") : __(doctype_plural)]), fields: fields, primary_action_label: __("Get Items"), + secondary_action_label: __("Make {0}", [me.doctype]), primary_action: function() { me.action(me.get_checked_values(), me.args); + }, + secondary_action: function(e) { + // If user wants to close the modal + if (e) { + frappe.route_options = {}; + + Object.keys(me.setters).forEach(function(setter) { + frappe.route_options[setter] = me.dialog.fields_dict[setter].get_value() || undefined; + }); + + frappe.new_doc(me.doctype, true); + } } }); this.$parent = $(this.dialog.body); this.$wrapper = this.dialog.fields_dict.results_area.$wrapper.append(`
`); - this.$results = this.$wrapper.find('.results'); - this.$make_new_btn = this.dialog.fields_dict.make_new.$wrapper; - this.$placeholder = $(`
- - -

No ${this.doctype} found

- -
-
`); + this.$results = this.$wrapper.find('.results'); + this.$results.append(this.make_list_row()); this.args = {}; @@ -94,6 +106,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ bind_events: function() { let me = this; + this.$results.on('click', '.list-item-container', function (e) { if (!$(e.target).is(':checkbox') && !$(e.target).is('a')) { $(this).find(':checkbox').trigger('click'); @@ -105,10 +118,12 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ }); this.$parent.find('.input-with-feedback').on('change', (e) => { + frappe.flags.auto_scroll = false; this.get_results(); }); this.$parent.find('[data-fieldname="date_range"]').on('blur', (e) => { + frappe.flags.auto_scroll = false; this.get_results(); }); @@ -116,17 +131,10 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ var $this = $(this); clearTimeout($this.data('timeout')); $this.data('timeout', setTimeout(function() { + frappe.flags.auto_scroll = false; me.get_results(); }, 300)); }); - - this.$parent.on('click', '.btn[data-fieldname="make_new"]', (e) => { - frappe.route_options = {}; - Object.keys(this.setters).forEach(function(setter) { - frappe.route_options[setter] = me.dialog.fields_dict[setter].get_value() || undefined; - }); - frappe.new_doc(this.doctype, true); - }); }, get_checked_values: function() { @@ -170,22 +178,28 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ render_result_list: function(results, more = 0) { var me = this; - this.$results.empty(); - if(results.length === 0) { - this.$make_new_btn.addClass('hide'); - this.$results.append(me.$placeholder); - return; - } - this.$make_new_btn.removeClass('hide'); - this.$results.append(this.make_list_row()); + var more_btn = me.dialog.fields_dict.more_btn.$wrapper; + + // Make empty result set if filter is set + if (!frappe.flags.auto_scroll) { + this.$results.empty(); + } + + if(results.length === 0) { + this.$results.empty(); + more_btn.hide(); + return; + } else if(more) { + more_btn.show(); + } + results.forEach((result) => { me.$results.append(me.make_list_row(result)); - }) - if (more) { - let message = __("Only {0} entries shown. Please filter for more specific results.", [this.page_length]); - me.$results.append($(`
${message}
`)); + }); + + if (frappe.flags.auto_scroll) { + this.$results.animate({scrollTop: me.$results.prop('scrollHeight')}, 500); } }, @@ -208,6 +222,7 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ txt: me.dialog.fields_dict["search_term"].get_value(), filters: filters, filter_fields: Object.keys(me.setters).concat([me.date_field]), + start: this.start, page_length: this.page_length + 1, query: this.get_query ? this.get_query().query : '', as_dict: 1 @@ -219,8 +234,8 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ args: args, callback: function(r) { let results = [], more = 0; - if(r.values.length) { - if(r.values.length > me.page_length){ + if (r.values.length) { + if (r.values.length > me.page_length) { r.values.pop(); more = 1; } @@ -241,7 +256,9 @@ frappe.ui.form.MultiSelectDialog = Class.extend({ }); // Preselect oldest entry - results[0].checked = 1 + if (me.start < 1) { + results[0].checked = 1; + } } me.render_result_list(results, more); } diff --git a/frappe/public/js/frappe/form/save.js b/frappe/public/js/frappe/form/save.js index ca5bc93133..d154061b83 100644 --- a/frappe/public/js/frappe/form/save.js +++ b/frappe/public/js/frappe/form/save.js @@ -185,7 +185,10 @@ frappe.ui.form.save = function (frm, action, callback, btn) { throw "saving"; } - frappe.ui.form.remove_old_form_route(); + // ensure we remove new docs routes ONLY + if ( frm.is_new() ) { + frappe.ui.form.remove_old_form_route(); + } frappe.ui.form.is_saving = true; return frappe.call({ @@ -224,14 +227,9 @@ frappe.ui.form.save = function (frm, action, callback, btn) { } frappe.ui.form.remove_old_form_route = () => { - let index = -1; - let current_route = frappe.get_route(); - frappe.route_history.map((arr, i) => { - if (arr.join("/") === current_route.join("/")) { - index = i; - } - }); - frappe.route_history.splice(index, 1); + let current_route = frappe.get_route().join("/"); + frappe.route_history = frappe.route_history + .filter((route) => route.join("/") !== current_route); } frappe.ui.form.update_calling_link = (newdoc) => { diff --git a/frappe/public/js/frappe/router.js b/frappe/public/js/frappe/router.js index 4a4c42852a..648efd2776 100644 --- a/frappe/public/js/frappe/router.js +++ b/frappe/public/js/frappe/router.js @@ -195,7 +195,11 @@ $(window).on('hashchange', function() { // hide open dialog if(window.cur_dialog && cur_dialog.hide_on_page_refresh) { - cur_dialog.hide(); + if (!cur_dialog.minimizable) { + cur_dialog.hide(); + } else if (!cur_dialog.is_minimized) { + cur_dialog.toggle_minimize(); + } } frappe.route(); diff --git a/frappe/public/js/frappe/ui/dialog.js b/frappe/public/js/frappe/ui/dialog.js index eb9215e208..0b3e0828f9 100644 --- a/frappe/public/js/frappe/ui/dialog.js +++ b/frappe/public/js/frappe/ui/dialog.js @@ -61,6 +61,10 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { this.get_close_btn().html(this.secondary_action_label || this.action.secondary.label); } + if (this.minimizable) { + this.get_minimize_btn().removeClass('hide').on('click', () => this.toggle_minimize()); + } + var me = this; this.$wrapper .on("hide.bs.modal", function() { @@ -101,6 +105,10 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { return this.$wrapper.find(".modal-header .btn-primary"); } + get_minimize_btn() { + return this.$wrapper.find(".modal-header .btn-modal-minimize"); + } + set_message(text) { this.$message.removeClass('hide'); this.$body.addClass('hide'); @@ -179,6 +187,13 @@ frappe.ui.Dialog = class Dialog extends frappe.ui.FieldGroup { cancel() { this.get_close_btn().trigger("click"); } + toggle_minimize() { + let modal = this.$wrapper.closest('.modal').toggleClass('modal-minimize'); + modal.attr('tabindex') ? modal.removeAttr('tabindex') : modal.attr('tabindex', -1); + this.get_minimize_btn().find('i').toggleClass('octicon-chevron-down').toggleClass('octicon-chevron-up'); + this.is_minimized = !this.is_minimized; + this.on_minimize_toggle && this.on_minimize_toggle(this.is_minimized); + } }; diff --git a/frappe/public/js/frappe/ui/link_preview.js b/frappe/public/js/frappe/ui/link_preview.js index 962adcf344..4db3050b83 100644 --- a/frappe/public/js/frappe/ui/link_preview.js +++ b/frappe/public/js/frappe/ui/link_preview.js @@ -175,9 +175,10 @@ frappe.ui.LinkPreview = class { animation: false, }); - if(!this.is_link) { - this.element.data('bs.popover').tip().addClass('control-field-popover'); - } + const $popover = this.element.data('bs.popover').tip(); + + $popover.addClass('link-preview-popover'); + $popover.toggleClass('control-field-popover', this.is_link); this.$links.push(this.element); diff --git a/frappe/public/js/frappe/utils/energy_point_utils.js b/frappe/public/js/frappe/utils/energy_point_utils.js index 05b3347fdc..1a22fd5077 100644 --- a/frappe/public/js/frappe/utils/energy_point_utils.js +++ b/frappe/public/js/frappe/utils/energy_point_utils.js @@ -32,7 +32,6 @@ Object.assign(frappe.energy_points, { }, get_history_log_message(log) { const owner_name = frappe.user.full_name(log.owner).bold(); - const user = frappe.user.full_name(log.user).bold(); const ref_doc = log.reference_name; if (log.type === 'Appreciation') { @@ -42,7 +41,7 @@ Object.assign(frappe.energy_points, { return __('{0} criticized on {1}', [owner_name, ref_doc]); } if (log.type === 'Revert') { - return __('{0} reverted {1}', [user, log.revert_of]); + return __('{0} reverted {1}', [owner_name, log.revert_of]); } return __('via automatic rule {0} on {1}', [log.rule.bold(), ref_doc]); }, @@ -57,8 +56,7 @@ Object.assign(frappe.energy_points, { return __('{0} criticized {1}', [owner_name, user]); } if (log.type === 'Revert') { - return __('{0} reverted {1}', [user, - frappe.utils.get_form_link('Energy Point Log', log.revert_of, true)]); + return __('{0} reverted {1}', [owner_name, log.revert_of]); } return __('gained by {0} via automatic rule {1}', [user, log.rule.bold()]); }, diff --git a/frappe/public/js/frappe/views/container.js b/frappe/public/js/frappe/views/container.js index 30f9a147db..8e67792079 100644 --- a/frappe/public/js/frappe/views/container.js +++ b/frappe/public/js/frappe/views/container.js @@ -60,7 +60,11 @@ frappe.views.Container = Class.extend({ // hide dialog if(window.cur_dialog && cur_dialog.display && !cur_dialog.keep_open) { - cur_dialog.hide(); + if (!cur_dialog.minimizable) { + cur_dialog.hide(); + } else if (!cur_dialog.is_minimized) { + cur_dialog.toggle_minimize(); + } } // hide current diff --git a/frappe/public/less/desk.less b/frappe/public/less/desk.less index 6835d52bad..945c23e423 100644 --- a/frappe/public/less/desk.less +++ b/frappe/public/less/desk.less @@ -464,27 +464,6 @@ li.user-progress { border-radius: 0px; } -// like pop-over -.liked-by-popover { - .popover-content { - padding: 0px; - overflow: scroll; - max-height: 150px; - } - min-width: 100px; - ul { - margin: 0px; - li { - padding: 10px; - cursor: pointer; - &:hover { - background: @btn-bg; - } - } - } - -} - .screenshot { border: 1px solid @border-color; box-shadow: 1px 1px 7px rgba(0,0,0,0.15); @@ -1074,6 +1053,27 @@ img.img-loading:after { } } +// like pop-over +.liked-by-popover { + .popover-content { + padding: 0px; + overflow: scroll; + max-height: 150px; + } + min-width: 100px; + ul { + margin: 0px; + li { + padding: 10px; + cursor: pointer; + &:hover { + background: @btn-bg; + } + } + } + +} + body.full-width { @media (min-width: @screen-md) { .container { @@ -1087,3 +1087,21 @@ body.full-width { .whitespace-nowrap { white-space: nowrap; } + +.modal-minimize { + position: initial; + .modal-backdrop { + display: none; + } + .modal-dialog { + z-index: 101; + position: fixed; + right: 0; + bottom: 0; + margin: 0; + max-width: 500px; + } + .modal-body { + display: none; + } +} \ No newline at end of file diff --git a/frappe/public/less/indicator.less b/frappe/public/less/indicator.less index a859361db0..5c46f4a896 100644 --- a/frappe/public/less/indicator.less +++ b/frappe/public/less/indicator.less @@ -80,3 +80,11 @@ margin-top: 7.5px; margin-right: 3px; } + +.indicator.blink { + animation: blink 1s linear infinite; +} + +@keyframes blink { + 50% { opacity: 0.5; } +} \ No newline at end of file diff --git a/frappe/public/less/link_preview.less b/frappe/public/less/link_preview.less index 9e8ed30e57..5bc9767815 100644 --- a/frappe/public/less/link_preview.less +++ b/frappe/public/less/link_preview.less @@ -1,4 +1,4 @@ -.popover { +.link-preview-popover { border-radius: 0; max-width: 100%; .popover-content { diff --git a/frappe/social/doctype/energy_point_log/energy_point_log.py b/frappe/social/doctype/energy_point_log/energy_point_log.py index c94c1bd371..fdea818991 100644 --- a/frappe/social/doctype/energy_point_log/energy_point_log.py +++ b/frappe/social/doctype/energy_point_log/energy_point_log.py @@ -131,26 +131,35 @@ def get_energy_points(user): @frappe.whitelist() def get_user_energy_and_review_points(user=None, from_date=None, as_dict=True): conditions = '' - values = [] + given_points_condition = '' + values = frappe._dict() if user: - conditions = 'WHERE `user` = %s' - values.append(user) + conditions = 'WHERE `user` = %(user)s' + values.user = user if from_date: conditions += 'WHERE' if not conditions else 'AND' - conditions += ' `creation` >= %s' - values.append(from_date) + given_points_condition += "AND `creation` >= %(from_date)s" + conditions += " `creation` >= %(from_date)s OR `type`='Review'" + values.from_date = from_date points_list = frappe.db.sql(""" SELECT - SUM(CASE WHEN `type`!= 'Review' THEN `points` ELSE 0 END) as energy_points, - SUM(CASE WHEN `type`='Review' THEN `points` ELSE 0 END) as review_points, - SUM(CASE WHEN `type`='Review' and `points` < 0 THEN ABS(`points`) ELSE 0 END) as given_points, + SUM(CASE WHEN `type` != 'Review' THEN `points` ELSE 0 END) AS energy_points, + SUM(CASE WHEN `type` = 'Review' THEN `points` ELSE 0 END) AS review_points, + SUM(CASE + WHEN `type`='Review' AND `points` < 0 {given_points_condition} + THEN ABS(`points`) + ELSE 0 + END) as given_points, `user` FROM `tabEnergy Point Log` {conditions} GROUP BY `user` ORDER BY `energy_points` DESC - """.format(conditions=conditions), values=tuple(values), as_dict=1) + """.format( + conditions=conditions, + given_points_condition=given_points_condition + ), values=values, as_dict=1) if not as_dict: return points_list diff --git a/frappe/tests/test_db.py b/frappe/tests/test_db.py index 974d3e770e..bb479d67c7 100644 --- a/frappe/tests/test_db.py +++ b/frappe/tests/test_db.py @@ -48,6 +48,12 @@ class TestDB(unittest.TestCase): todo.save() self.assertIn('tabToDo', frappe.flags.touched_tables) + if frappe.db.db_type != "postgres": + frappe.flags.touched_tables = set() + frappe.db.sql("UPDATE tabToDo SET description = 'Updated Description'") + self.assertNotIn('tabToDo SET', frappe.flags.touched_tables) + self.assertIn('tabToDo', frappe.flags.touched_tables) + frappe.flags.touched_tables = set() todo.delete() self.assertIn('tabToDo', frappe.flags.touched_tables) diff --git a/frappe/translate.py b/frappe/translate.py index 44edcf999f..829ae6a609 100644 --- a/frappe/translate.py +++ b/frappe/translate.py @@ -507,7 +507,7 @@ def extract_messages_from_code(code, is_py=False): :param is_py: include messages in triple quotes e.g. `_('''message''')`""" try: code = frappe.as_unicode(render_include(code)) - except (TemplateError, ImportError, InvalidIncludePath): + except (TemplateError, ImportError, InvalidIncludePath, IOError): # Exception will occur when it encounters John Resig's microtemplating code pass diff --git a/frappe/website/router.py b/frappe/website/router.py index 4e172b5290..d22bacf282 100644 --- a/frappe/website/router.py +++ b/frappe/website/router.py @@ -99,7 +99,10 @@ def get_page_info_from_doctypes(path=None): values = [] controller = get_controller(doctype) meta = frappe.get_meta(doctype) - condition_field = meta.is_published_field or controller.website.condition_field + + condition_field = (meta.is_published_field or + # custom doctypes dont have controllers and no website attribute + (controller.website.condition_field if not meta.custom else None)) if condition_field: condition ="where {0}=1".format(condition_field) diff --git a/package.json b/package.json index dd5a96d741..352ba6d492 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "cookie": "^0.3.1", "express": "^4.16.2", "fast-deep-equal": "^2.0.1", - "frappe-datatable": "^1.13.1", + "frappe-datatable": "^1.13.2", "frappe-gantt": "^0.1.0", "fuse.js": "^3.2.0", "highlight.js": "^9.12.0", diff --git a/requirements.txt b/requirements.txt index d61cadd4c4..bed4601951 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ rauth>=0.6.2 requests redis==2.10.6 selenium -babel +babel==2.6.0 ipython html2text==2016.9.19 email_reply_parser diff --git a/yarn.lock b/yarn.lock index 64bc06edff..bfe0d375f0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1753,10 +1753,10 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -frappe-datatable@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.13.1.tgz#dbfa27fe735832cea54a0b35e3d3bfb839778c8d" - integrity sha512-FOC8dpsOSI+KnF5sBrYja9b2Y+3qUvYy/H6108QchKSvXYvuWVr/uuLk2N5xlz38PWU3d7n5lK0dkx+zXTKJ0w== +frappe-datatable@^1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/frappe-datatable/-/frappe-datatable-1.13.2.tgz#8b36c7cfc0ea660fc72eea8b1ae3c5dcc2a7d67d" + integrity sha512-4PyPDX22K4e4S3WGlLQx3oyxIW+ENsbGiN9L6aUpmjU+fOCC7J/FfSwGKdua2f+4yD+2ObpkyJYazBl3inAeCA== dependencies: hyperlist "^1.0.0-beta" lodash "^4.17.5"