Merge branch 'develop' of github.com:frappe/frappe into report-key-error-dev
This commit is contained in:
commit
8e5fbb033c
17 changed files with 98 additions and 60 deletions
|
|
@ -25,9 +25,8 @@ context('Awesome Bar', () => {
|
|||
|
||||
cy.get('h1').should('contain', 'To Do');
|
||||
|
||||
cy.get('.toggle-filter')
|
||||
.should('have.length', 1)
|
||||
.should('contain', 'ID like %test%');
|
||||
cy.get('[data-original-title="Name"] > .input-with-feedback')
|
||||
.should('have.value', '%test%');
|
||||
});
|
||||
|
||||
it('navigates to new form', () => {
|
||||
|
|
|
|||
|
|
@ -437,7 +437,7 @@ def sendmail(recipients=[], sender="", subject="No Subject", message="No Message
|
|||
|
||||
|
||||
:param recipients: List of recipients.
|
||||
:param sender: Email sender. Default is current user.
|
||||
:param sender: Email sender. Default is current user or default outgoing account.
|
||||
:param subject: Email Subject.
|
||||
:param message: (or `content`) Email Content.
|
||||
:param as_markdown: Convert content markdown to HTML.
|
||||
|
|
@ -459,7 +459,6 @@ def sendmail(recipients=[], sender="", subject="No Subject", message="No Message
|
|||
:param args: Arguments for rendering the template
|
||||
:param header: Append header in email
|
||||
"""
|
||||
|
||||
text_content = None
|
||||
if template:
|
||||
message, text_content = get_email_from_template(template, args)
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ import logging
|
|||
from werkzeug.wrappers import Request
|
||||
from werkzeug.local import LocalManager
|
||||
from werkzeug.exceptions import HTTPException, NotFound
|
||||
from werkzeug.contrib.profiler import ProfilerMiddleware
|
||||
from werkzeug.wsgi import SharedDataMiddleware
|
||||
from werkzeug.middleware.profiler import ProfilerMiddleware
|
||||
from werkzeug.middleware.shared_data import SharedDataMiddleware
|
||||
|
||||
import frappe
|
||||
import frappe.handler
|
||||
|
|
|
|||
|
|
@ -523,7 +523,7 @@ def run_ui_tests(context, app, headless=False):
|
|||
|
||||
# run for headless mode
|
||||
run_or_open = 'run' if headless else 'open'
|
||||
command = '{site_env} {password_env} yarn run cypress:{run_or_open}'
|
||||
command = '{site_env} {password_env} yarn run cypress {run_or_open}'
|
||||
formatted_command = command.format(site_env=site_env, password_env=password_env, run_or_open=run_or_open)
|
||||
frappe.commands.popen(formatted_command, cwd=app_base_path, raise_err=True)
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,15 @@ frappe.ui.form.on("Address", {
|
|||
}
|
||||
});
|
||||
frm.refresh_field("links");
|
||||
|
||||
if (frm.doc.links) {
|
||||
for (let i in frm.doc.links) {
|
||||
let link = frm.doc.links[i];
|
||||
frm.add_custom_button(__("{0}: {1}", [__(link.link_doctype), __(link.link_name)]), function() {
|
||||
frappe.set_route("Form", link.link_doctype, link.link_name);
|
||||
}, __("Links"));
|
||||
}
|
||||
}
|
||||
},
|
||||
validate: function(frm) {
|
||||
// clear linked customer / supplier / sales partner on saving...
|
||||
|
|
@ -38,9 +47,13 @@ frappe.ui.form.on("Address", {
|
|||
() => frappe.timeout(1),
|
||||
() => {
|
||||
const last_doc = frappe.contacts.get_last_doc(frm);
|
||||
if(frappe.dynamic_link && frappe.dynamic_link.doc
|
||||
&& frappe.dynamic_link.doc.name == last_doc.docname){
|
||||
frappe.set_route('Form', last_doc.doctype, last_doc.docname);
|
||||
if (frappe.dynamic_link && frappe.dynamic_link.doc && frappe.dynamic_link.doc.name == last_doc.docname) {
|
||||
for (let i in frm.doc.links) {
|
||||
let link = frm.doc.links[i];
|
||||
if (last_doc.doctype == link.link_doctype && last_doc.docname == link.link_name) {
|
||||
frappe.set_route('Form', last_doc.doctype, last_doc.docname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ frappe.ui.form.on("Contact", {
|
|||
});
|
||||
frm.refresh_field("links");
|
||||
|
||||
if (frm.doc.links.length > 0) {
|
||||
if (frm.doc.links) {
|
||||
frappe.call({
|
||||
method: "frappe.contacts.doctype.contact.contact.address_query",
|
||||
args: {links: frm.doc.links},
|
||||
|
|
@ -58,6 +58,13 @@ frappe.ui.form.on("Contact", {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (let i in frm.doc.links) {
|
||||
let link = frm.doc.links[i];
|
||||
frm.add_custom_button(__("{0}: {1}", [__(link.link_doctype), __(link.link_name)]), function() {
|
||||
frappe.set_route("Form", link.link_doctype, link.link_name);
|
||||
}, __("Links"));
|
||||
}
|
||||
}
|
||||
},
|
||||
validate: function(frm) {
|
||||
|
|
@ -73,9 +80,13 @@ frappe.ui.form.on("Contact", {
|
|||
() => frappe.timeout(1),
|
||||
() => {
|
||||
const last_doc = frappe.contacts.get_last_doc(frm);
|
||||
if(frappe.dynamic_link && frappe.dynamic_link.doc
|
||||
&& frappe.dynamic_link.doc.name == last_doc.docname){
|
||||
frappe.set_route('Form', last_doc.doctype, last_doc.docname);
|
||||
if (frappe.dynamic_link && frappe.dynamic_link.doc && frappe.dynamic_link.doc.name == last_doc.docname) {
|
||||
for (let i in frm.doc.links) {
|
||||
let link = frm.doc.links[i];
|
||||
if (last_doc.doctype == link.link_doctype && last_doc.docname == link.link_name) {
|
||||
frappe.set_route('Form', last_doc.doctype, last_doc.docname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -98,8 +98,6 @@ class User(Document):
|
|||
clear_notifications(user=self.name)
|
||||
frappe.clear_cache(user=self.name)
|
||||
self.send_password_notification(self.__new_password)
|
||||
if self.__new_password:
|
||||
self.reset_password_key = ''
|
||||
create_contact(self, ignore_mandatory=True)
|
||||
if self.name not in ('Administrator', 'Guest') and not self.user_image:
|
||||
frappe.enqueue('frappe.core.doctype.user.user.update_gravatar', name=self.name)
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ def get_diff(old, new, for_child=False):
|
|||
if not new:
|
||||
return None
|
||||
|
||||
blacklisted_fields = ["Markdown Editor", "Text Editor", "Code", "HTML Editor"]
|
||||
|
||||
# capture data import if set
|
||||
data_import = new.flags.via_data_import
|
||||
out = frappe._dict(changed = [], added = [], removed = [], row_changed = [], data_import=data_import)
|
||||
|
|
@ -75,12 +77,12 @@ def get_diff(old, new, for_child=False):
|
|||
out.removed.append([df.fieldname, d.as_dict()])
|
||||
|
||||
elif (old_value != new_value):
|
||||
# Check for None values
|
||||
old_data = old.get_formatted(df.fieldname) if old_value else old_value
|
||||
new_data = new.get_formatted(df.fieldname) if new_value else new_value
|
||||
if df.fieldtype not in blacklisted_fields:
|
||||
old_value = old.get_formatted(df.fieldname) if old_value else old_value
|
||||
new_value = new.get_formatted(df.fieldname) if new_value else new_value
|
||||
|
||||
if old_data != new_data:
|
||||
out.changed.append((df.fieldname, old_data, new_data))
|
||||
if old_value != new_value:
|
||||
out.changed.append((df.fieldname, old_value, new_value))
|
||||
|
||||
# docstatus
|
||||
if not for_child and old.docstatus != new.docstatus:
|
||||
|
|
|
|||
|
|
@ -20,7 +20,8 @@ frappe.ui.form.on("Customize Form", {
|
|||
frm.set_query("default_print_format", function() {
|
||||
return {
|
||||
filters: {
|
||||
'print_format_type': ['!=', 'JS']
|
||||
'print_format_type': ['!=', 'JS'],
|
||||
'doc_type': ['=', frm.doc.doc_type]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -106,9 +106,8 @@ def send_email(success, service_name, error_status=None):
|
|||
if not frappe.db:
|
||||
frappe.connect()
|
||||
|
||||
if frappe.db.get_value("S3 Backup Settings", None, "notification_email"):
|
||||
recipients = split_emails(frappe.db.get_value("S3 Backup Settings", None, "notification_email"))
|
||||
frappe.sendmail(recipients=recipients, subject=subject, message=message)
|
||||
recipients = split_emails(frappe.db.get_value("S3 Backup Settings", None, "notify_email"))
|
||||
frappe.sendmail(recipients=recipients, subject=subject, message=message)
|
||||
|
||||
|
||||
def backup_to_s3():
|
||||
|
|
|
|||
|
|
@ -10,9 +10,20 @@ from frappe import _
|
|||
import requests
|
||||
import json
|
||||
|
||||
|
||||
error_messages = {
|
||||
400: "400: Invalid Payload or User not found",
|
||||
403: "403: Action Prohibited",
|
||||
404: "404: Channel not found",
|
||||
410: "410: The Channel is Archived",
|
||||
500: "500: Rollup Error, Slack seems to be down"
|
||||
}
|
||||
|
||||
|
||||
class SlackWebhookURL(Document):
|
||||
pass
|
||||
|
||||
|
||||
def send_slack_message(webhook_url, message, reference_doctype, reference_name):
|
||||
slack_url = frappe.db.get_value("Slack Webhook URL", webhook_url, "webhook_url")
|
||||
doc_url = get_url_to_form(reference_doctype, reference_name)
|
||||
|
|
@ -21,10 +32,10 @@ def send_slack_message(webhook_url, message, reference_doctype, reference_name):
|
|||
"fallback": _("See the document at {0}").format(doc_url),
|
||||
"actions": [
|
||||
{
|
||||
"type": "button",
|
||||
"text": _("Go to the document"),
|
||||
"url": doc_url,
|
||||
"style": "primary"
|
||||
"type": "button",
|
||||
"text": _("Go to the document"),
|
||||
"url": doc_url,
|
||||
"style": "primary"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -32,10 +43,9 @@ def send_slack_message(webhook_url, message, reference_doctype, reference_name):
|
|||
data = {"text": message, "attachments": attachments}
|
||||
r = requests.post(slack_url, data=json.dumps(data))
|
||||
|
||||
|
||||
if r.ok == True:
|
||||
return 'success'
|
||||
|
||||
elif r.ok == False:
|
||||
frappe.log_error(r.error, _('Slack Webhook Error'))
|
||||
if not r.ok:
|
||||
message = error_messages.get(r.status_code, r.status_code)
|
||||
frappe.log_error(message, _('Slack Webhook Error'))
|
||||
return 'error'
|
||||
|
||||
return 'success'
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ from __future__ import unicode_literals
|
|||
import frappe
|
||||
import os
|
||||
from werkzeug.exceptions import NotFound
|
||||
from werkzeug.wsgi import SharedDataMiddleware
|
||||
from frappe.utils import get_site_name, get_site_path, get_site_base_path, get_path, cstr
|
||||
from werkzeug.middleware.shared_data import SharedDataMiddleware
|
||||
from frappe.utils import get_site_name, cstr
|
||||
|
||||
|
||||
class StaticDataMiddleware(SharedDataMiddleware):
|
||||
def __call__(self, environ, start_response):
|
||||
|
|
|
|||
|
|
@ -205,13 +205,7 @@ frappe.form.formatters = {
|
|||
return html;
|
||||
},
|
||||
Comment: function(value) {
|
||||
var html = "";
|
||||
$.each(JSON.parse(value || "[]"), function(i, v) {
|
||||
if(v) html+= '<span class="label label-warning" \
|
||||
style="margin-right: 7px;"\
|
||||
data-field="_comments" data-label="'+v.name+'">'+v.comment+'</span>';
|
||||
});
|
||||
return html;
|
||||
return value;
|
||||
},
|
||||
Assign: function(value) {
|
||||
var html = "";
|
||||
|
|
|
|||
|
|
@ -540,7 +540,7 @@ class FilterArea {
|
|||
out.promise = out.promise || Promise.resolve();
|
||||
out.non_standard_filters = out.non_standard_filters || [];
|
||||
|
||||
if (fields_dict[fieldname] && condition === '=') {
|
||||
if (fields_dict[fieldname] && (condition === '=' || condition === "like")) {
|
||||
// standard filter
|
||||
out.promise = out.promise.then(
|
||||
() => fields_dict[fieldname].set_value(value)
|
||||
|
|
|
|||
|
|
@ -791,7 +791,13 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
|
|||
let std_fields = frappe.model.std_fields.filter( df => df.fieldname !== 'docstatus');
|
||||
|
||||
// add status field derived from docstatus, if status is not a standard field
|
||||
if (!frappe.meta.has_field(this.doctype, 'status')) {
|
||||
let has_status_values = false;
|
||||
|
||||
if (this.data) {
|
||||
has_status_values = frappe.get_indicator(this.data[0], this.doctype);
|
||||
}
|
||||
|
||||
if (!frappe.meta.has_field(this.doctype, 'status') && has_status_values) {
|
||||
doctype_fields = [{
|
||||
label: __('Status'),
|
||||
fieldname: 'docstatus',
|
||||
|
|
@ -1038,18 +1044,23 @@ frappe.views.ReportView = class ReportView extends frappe.views.ListView {
|
|||
if (col.field === 'docstatus' && !frappe.meta.has_field(this.doctype, 'status')) {
|
||||
// get status from docstatus
|
||||
let status = frappe.get_indicator(d, this.doctype);
|
||||
if (!status[0]) {
|
||||
// get_indicator returns the dependent field's condition as the 3rd parameter
|
||||
let dependent_col = status[2].split(',')[0];
|
||||
// add status dependency column
|
||||
this.add_status_dependency_column(dependent_col, this.doctype);
|
||||
if (status) {
|
||||
if (!status[0]) {
|
||||
// get_indicator returns the dependent field's condition as the 3rd parameter
|
||||
let dependent_col = status[2].split(',')[0];
|
||||
// add status dependency column
|
||||
this.add_status_dependency_column(dependent_col, this.doctype);
|
||||
}
|
||||
return {
|
||||
name: d.name,
|
||||
doctype: col.docfield.parent,
|
||||
content: status[0],
|
||||
editable: false
|
||||
};
|
||||
} else {
|
||||
// no status values found
|
||||
this.remove_column_from_datatable(col);
|
||||
}
|
||||
return {
|
||||
name: d.name,
|
||||
doctype: col.docfield.parent,
|
||||
content: status[0],
|
||||
editable: false
|
||||
};
|
||||
} else if (col.field in d) {
|
||||
const value = d[col.field];
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -112,4 +112,4 @@ def generate_theme_files_if_not_exist():
|
|||
doc.generate_theme_if_not_exist()
|
||||
doc.save()
|
||||
except Exception:
|
||||
pass
|
||||
frappe.log_error(frappe.get_traceback(), "Theme File Generation Failed")
|
||||
|
|
|
|||
|
|
@ -61,6 +61,6 @@ stripe==2.40.0
|
|||
unittest-xml-reporting==2.5.2
|
||||
urllib3==1.25.7
|
||||
watchdog==0.8.0
|
||||
Werkzeug==0.16.0
|
||||
Werkzeug==0.16.1
|
||||
xlrd==1.2.0
|
||||
zxcvbn-python==4.4.24
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue