Merge branch 'develop' into fix-invalid-dashboard-filter
This commit is contained in:
commit
0cca0778cc
17 changed files with 111 additions and 50 deletions
16
.github/workflows/backport.yml
vendored
Normal file
16
.github/workflows/backport.yml
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
name: Backport
|
||||
on:
|
||||
pull_request:
|
||||
types:
|
||||
- closed
|
||||
- labeled
|
||||
|
||||
jobs:
|
||||
backport:
|
||||
runs-on: ubuntu-18.04
|
||||
name: Backport
|
||||
steps:
|
||||
- name: Backport
|
||||
uses: tibdex/backport@v1
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
|
@ -543,7 +543,7 @@ def only_for(roles, message=False):
|
|||
myroles = set(get_roles())
|
||||
if not roles.intersection(myroles):
|
||||
if message:
|
||||
msgprint(_('Only for {}').format(', '.join(roles)))
|
||||
msgprint(_('This action is only allowed for {}').format(bold(', '.join(roles))), _('Not Permitted'))
|
||||
raise PermissionError
|
||||
|
||||
def get_domain_data(module):
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,12 @@ frappe.ui.form.on('User', {
|
|||
|
||||
if(!frm.is_new()) {
|
||||
if(has_access_to_edit_user()) {
|
||||
|
||||
frm.add_custom_button(__("Resend Welcome Email"), function() {
|
||||
frm.call('send_welcome_mail_to_user').then(()=>{
|
||||
frappe.msgprint(__("Email has been sent to {0}", [frm.doc.email]));
|
||||
});
|
||||
});
|
||||
|
||||
frm.add_custom_button(__("Set User Permissions"), function() {
|
||||
frappe.route_options = {
|
||||
"user": doc.name
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -176,7 +174,6 @@ class User(Document):
|
|||
and name in ({0}) limit 1""".format(', '.join(['%s'] * len(self.roles))),
|
||||
[d.role for d in self.roles]))
|
||||
|
||||
|
||||
def share_with_self(self):
|
||||
if self.user_type=="System User":
|
||||
frappe.share.add(self.doctype, self.name, self.name, write=1, share=1,
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ def run(report_name, filters=None, user=None, ignore_prepared_report=False):
|
|||
else:
|
||||
result = generate_report_result(report, filters, user)
|
||||
|
||||
result["add_total_row"] = report.add_total_row and not result['skip_total_row']
|
||||
result["add_total_row"] = report.add_total_row and not result.get('skip_total_row', False)
|
||||
|
||||
return result
|
||||
|
||||
|
|
@ -303,6 +303,11 @@ def export_query():
|
|||
if file_format_type == "Excel":
|
||||
data = run(report_name, filters)
|
||||
data = frappe._dict(data)
|
||||
if not data.columns:
|
||||
frappe.respond_as_web_page(_("No data to export"),
|
||||
_("You can try changing the filters of your report."))
|
||||
return
|
||||
|
||||
columns = get_columns_dict(data.columns)
|
||||
|
||||
from frappe.utils.xlsxutils import make_xlsx
|
||||
|
|
|
|||
|
|
@ -57,9 +57,6 @@ def add_node():
|
|||
args = make_tree_args(**frappe.form_dict)
|
||||
doc = frappe.get_doc(args)
|
||||
|
||||
if args.doctype == "Sales Person":
|
||||
doc.employee = frappe.form_dict.get('employee')
|
||||
|
||||
doc.save()
|
||||
|
||||
def make_tree_args(**kwarg):
|
||||
|
|
|
|||
|
|
@ -256,7 +256,7 @@ def get_emails_sent_this_month():
|
|||
|
||||
def get_emails_sent_today():
|
||||
return frappe.db.sql("""SELECT COUNT(`name`) FROM `tabEmail Queue` WHERE
|
||||
`status`='Sent' AND `creation` > (NOW() - INTERVAL '24' HOUR)""")[0][0]
|
||||
`status` in ('Sent', 'Not Sent', 'Sending') AND `creation` > (NOW() - INTERVAL '24' HOUR)""")[0][0]
|
||||
|
||||
def get_unsubscribe_message(unsubscribe_message, expose_recipients):
|
||||
if unsubscribe_message:
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ frappe.views.BaseList = class BaseList {
|
|||
setup_filter_area() {
|
||||
this.filter_area = new FilterArea(this);
|
||||
|
||||
if (this.filters.length > 0) {
|
||||
if (this.filters && this.filters.length > 0) {
|
||||
return this.filter_area.set(this.filters);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1044,7 +1044,7 @@ frappe.views.ListView = class ListView extends frappe.views.BaseList {
|
|||
}
|
||||
|
||||
setup_realtime_updates() {
|
||||
if (this.list_view_settings.disable_auto_refresh) {
|
||||
if (this.list_view_settings && this.list_view_settings.disable_auto_refresh) {
|
||||
return;
|
||||
}
|
||||
frappe.realtime.on('list_update', data => {
|
||||
|
|
|
|||
|
|
@ -1022,7 +1022,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
}
|
||||
|
||||
get_menu_items() {
|
||||
return [
|
||||
let items = [
|
||||
{
|
||||
label: __('Refresh'),
|
||||
action: () => this.refresh(),
|
||||
|
|
@ -1153,6 +1153,18 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
standard: true
|
||||
},
|
||||
{
|
||||
label: __('User Permissions'),
|
||||
action: () => frappe.set_route('List', 'User Permission', {
|
||||
doctype: 'Report',
|
||||
name: this.report_name
|
||||
}),
|
||||
condition: () => frappe.model.can_set_user_permissions('Report'),
|
||||
standard: true
|
||||
}
|
||||
];
|
||||
|
||||
if (frappe.user.is_report_manager()) {
|
||||
items.push({
|
||||
label: __('Save'),
|
||||
action: () => {
|
||||
let d = new frappe.ui.Dialog({
|
||||
|
|
@ -1163,6 +1175,7 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
fieldname: 'report_name',
|
||||
label: __("Report Name"),
|
||||
default: this.report_doc.is_standard == 'No' ? this.report_name : "",
|
||||
reqd: true
|
||||
}
|
||||
],
|
||||
primary_action: (values) => {
|
||||
|
|
@ -1184,17 +1197,10 @@ frappe.views.QueryReport = class QueryReport extends frappe.views.BaseList {
|
|||
d.show();
|
||||
},
|
||||
standard: true
|
||||
},
|
||||
{
|
||||
label: __('User Permissions'),
|
||||
action: () => frappe.set_route('List', 'User Permission', {
|
||||
doctype: 'Report',
|
||||
name: this.report_name
|
||||
}),
|
||||
condition: () => frappe.model.can_set_user_permissions('Report'),
|
||||
standard: true
|
||||
}
|
||||
];
|
||||
})
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
add_portrait_warning(dialog) {
|
||||
|
|
|
|||
|
|
@ -1026,8 +1026,7 @@ def expand_relative_urls(html):
|
|||
html = re.sub('(href|src){1}([\s]*=[\s]*[\'"]?)((?!http)[^\'" >]+)([\'"]?)', _expand_relative_urls, html)
|
||||
|
||||
# background-image: url('/assets/...')
|
||||
html = re.sub('(:[\s]?url)(\([\'"]?)([^\)]*)([\'"]?\))', _expand_relative_urls, html)
|
||||
|
||||
html = re.sub('(:[\s]?url)(\([\'"]?)((?!http)[^\'" >]+)([\'"]?\))', _expand_relative_urls, html)
|
||||
return html
|
||||
|
||||
def quoted(url):
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue