diff --git a/cypress/integration/control_link.js b/cypress/integration/control_link.js index a934132c89..63c99c4d1b 100644 --- a/cypress/integration/control_link.js +++ b/cypress/integration/control_link.js @@ -61,12 +61,18 @@ context('Control Link', () => { cy.server(); cy.route('GET', '/api/method/frappe.desk.form.utils.validate_link*').as('validate_link'); + cy.route('POST', '/api/method/frappe.desk.search.search_link').as('search_link'); cy.get('@todos').then(todos => { - cy.get('.frappe-control[data-fieldname=link] input').type(todos[0]).blur(); + cy.get('.frappe-control[data-fieldname=link] input').as('input'); + cy.get('@input').focus(); + cy.wait('@search_link'); + cy.get('@input').type(todos[0]).blur(); cy.wait('@validate_link'); - cy.get('.frappe-control[data-fieldname=link] input').focus(); - cy.get('.frappe-control[data-fieldname=link] .link-btn').click(); + cy.get('@input').focus(); + cy.get('.frappe-control[data-fieldname=link] .link-btn') + .should('be.visible') + .click(); cy.location('hash').should('eq', `#Form/ToDo/${todos[0]}`); }); }); diff --git a/frappe/email/receive.py b/frappe/email/receive.py index ee7075b570..b8fde57a43 100644 --- a/frappe/email/receive.py +++ b/frappe/email/receive.py @@ -298,7 +298,7 @@ class EmailServer: "Connection timed out", ) for message in messages: - if message in strip(cstr(e.message)) or message in strip(cstr(getattr(e, 'strerror', ''))): + if message in strip(cstr(e)) or message in strip(cstr(getattr(e, 'strerror', ''))): return True return False diff --git a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py index 26e0de35b5..c6ef12ff08 100644 --- a/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py +++ b/frappe/integrations/doctype/razorpay_settings/razorpay_settings.py @@ -242,7 +242,6 @@ class RazorpaySettings(Document): redirect_to = data.get('redirect_to') or None redirect_message = data.get('redirect_message') or None - if self.flags.status_changed_to in ("Authorized", "Verified", "Completed"): if self.data.reference_doctype and self.data.reference_docname: custom_redirect_to = None diff --git a/frappe/public/js/frappe/desk.js b/frappe/public/js/frappe/desk.js index 3deeb02ae4..4fbea6684f 100644 --- a/frappe/public/js/frappe/desk.js +++ b/frappe/public/js/frappe/desk.js @@ -136,11 +136,7 @@ frappe.Application = Class.extend({ method: 'frappe.core.page.background_jobs.background_jobs.get_scheduler_status', callback: function(r) { if (r.message[0] == __("Inactive")) { - frappe.msgprint({ - title: __("Scheduler Inactive"), - indicator: "red", - message: __("Background jobs are not running. Please contact Administrator") - }); + frappe.call('frappe.utils.scheduler.activate_scheduler'); } } }); diff --git a/frappe/public/js/frappe/file_uploader/FileUploader.vue b/frappe/public/js/frappe/file_uploader/FileUploader.vue index dbbde40f2a..845fbf92b4 100644 --- a/frappe/public/js/frappe/file_uploader/FileUploader.vue +++ b/frappe/public/js/frappe/file_uploader/FileUploader.vue @@ -367,6 +367,13 @@ export default { if (this.on_success) { this.on_success(file_doc, r); } + } else if (xhr.status === 403) { + let response = JSON.parse(xhr.responseText); + frappe.msgprint({ + title: __('Not permitted'), + indicator: 'red', + message: response._error_message + }); } else { file.failed = true; let error = null; diff --git a/frappe/public/js/frappe/list/list_view.js b/frappe/public/js/frappe/list/list_view.js index 41210e5df3..53686b779f 100644 --- a/frappe/public/js/frappe/list/list_view.js +++ b/frappe/public/js/frappe/list/list_view.js @@ -1099,10 +1099,21 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList { }); this.toggle_result_area(); this.render_list(); + if (this.$checks.length) { + this.set_rows_as_checked(); + } }); }); } + set_rows_as_checked() { + $.each(this.$checks, (i, el) => { + let docname = $(el).attr('data-name'); + this.$result.find(`.list-row-checkbox[data-name='${docname}']`).prop('checked', true); + }); + this.on_row_checked(); + } + on_row_checked() { this.$list_head_subject = this.$list_head_subject || this.$result.find('header .list-header-subject'); this.$checkbox_actions = this.$checkbox_actions || this.$result.find('header .checkbox-actions'); diff --git a/frappe/public/js/frappe/views/reports/query_report.js b/frappe/public/js/frappe/views/reports/query_report.js index 4b72a6b7b5..560cb3d17b 100644 --- a/frappe/public/js/frappe/views/reports/query_report.js +++ b/frappe/public/js/frappe/views/reports/query_report.js @@ -975,12 +975,15 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList { return this.data[index]; } }).filter(Boolean); - let totalRow = this.datatable.bodyRenderer.getTotalRow().reduce((row, cell) => { - row[cell.column.id] = cell.content; - return row; - }, {}); - rows.push(totalRow); + if (this.raw_data.add_total_row) { + let totalRow = this.datatable.bodyRenderer.getTotalRow().reduce((row, cell) => { + row[cell.column.id] = cell.content; + return row; + }, {}); + + rows.push(totalRow); + } return rows; } diff --git a/frappe/public/js/frappe/views/reports/report_view.js b/frappe/public/js/frappe/views/reports/report_view.js index 6503f1c7ac..7f6e24595a 100644 --- a/frappe/public/js/frappe/views/reports/report_view.js +++ b/frappe/public/js/frappe/views/reports/report_view.js @@ -500,10 +500,9 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView { axisOptions: { shortenYAxisNumbers: 1 }, - - format_tooltip_x: value => value.doc.name, - format_tooltip_y: - value => frappe.format(value, get_df(value.field), { always_show_decimals: true, inline: true }, get_doc(value.doc)) + tooltipOptions: { + formatTooltipY: value => frappe.format(value, get_df(this.chart_args.y_axes[0]), { always_show_decimals: true, inline: true }, get_doc(value.doc)) + } }); } diff --git a/frappe/utils/response.py b/frappe/utils/response.py index 886baf2c37..8169986e44 100644 --- a/frappe/utils/response.py +++ b/frappe/utils/response.py @@ -90,7 +90,7 @@ def as_json(): def as_pdf(): response = Response() response.mimetype = "application/pdf" - encoded_filename = quote(frappe.response['filename'].replace(' ', '_'), encoding='utf-8') + encoded_filename = quote(frappe.response['filename'].replace(' ', '_')) response.headers["Content-Disposition"] = ("filename=\"%s\"" % frappe.response['filename'].replace(' ', '_') + ";filename*=utf-8''%s" % encoded_filename).encode("utf-8") response.data = frappe.response['filecontent'] return response diff --git a/frappe/utils/scheduler.py b/frappe/utils/scheduler.py index 68c3bc58a8..b46036d996 100755 --- a/frappe/utils/scheduler.py +++ b/frappe/utils/scheduler.py @@ -337,3 +337,10 @@ def get_last_active(): WHERE `user_type` = 'System User' AND `name` NOT IN ({standard_users})""" .format(standard_users=", ".join(["%s"]*len(STANDARD_USERS))), STANDARD_USERS)[0][0] + +@frappe.whitelist() +def activate_scheduler(): + if is_scheduler_disabled(): + enable_scheduler() + if frappe.conf.pause_scheduler: + update_site_config('pause_scheduler', 0)