fix: load user_info on-demandversion-14
@@ -12,6 +12,8 @@ Read the documentation: https://frappeframework.com/docs | |||||
""" | """ | ||||
import os, warnings | import os, warnings | ||||
STANDARD_USERS = ('Guest', 'Administrator') | |||||
_dev_server = os.environ.get('DEV_SERVER', False) | _dev_server = os.environ.get('DEV_SERVER', False) | ||||
if _dev_server: | if _dev_server: | ||||
@@ -121,6 +123,7 @@ def set_user_lang(user, user_language=None): | |||||
local.lang = get_user_lang(user) | local.lang = get_user_lang(user) | ||||
# local-globals | # local-globals | ||||
db = local("db") | db = local("db") | ||||
qb = local("qb") | qb = local("qb") | ||||
conf = local("conf") | conf = local("conf") | ||||
@@ -250,8 +250,7 @@ class LoginManager: | |||||
if not self.user: | if not self.user: | ||||
return | return | ||||
from frappe.core.doctype.user.user import STANDARD_USERS | |||||
if self.user in STANDARD_USERS: | |||||
if self.user in frappe.STANDARD_USERS: | |||||
return False | return False | ||||
reset_pwd_after_days = cint(frappe.db.get_single_value("System Settings", | reset_pwd_after_days = cint(frappe.db.get_single_value("System Settings", | ||||
@@ -17,7 +17,7 @@ from frappe.social.doctype.energy_point_log.energy_point_log import get_energy_p | |||||
from frappe.model.base_document import get_controller | from frappe.model.base_document import get_controller | ||||
from frappe.social.doctype.post.post import frequently_visited_links | from frappe.social.doctype.post.post import frequently_visited_links | ||||
from frappe.core.doctype.navbar_settings.navbar_settings import get_navbar_settings, get_app_logo | from frappe.core.doctype.navbar_settings.navbar_settings import get_navbar_settings, get_app_logo | ||||
from frappe.utils import get_time_zone | |||||
from frappe.utils import get_time_zone, add_user_info | |||||
def get_bootinfo(): | def get_bootinfo(): | ||||
"""build and return boot info""" | """build and return boot info""" | ||||
@@ -222,17 +222,14 @@ def load_translations(bootinfo): | |||||
bootinfo["__messages"] = messages | bootinfo["__messages"] = messages | ||||
def get_user_info(): | def get_user_info(): | ||||
user_info = frappe.db.get_all('User', fields=['`name`', 'full_name as fullname', 'user_image as image', 'gender', | |||||
'email', 'username', 'bio', 'location', 'interest', 'banner_image', 'allowed_in_mentions', 'user_type', 'time_zone'], | |||||
filters=dict(enabled=1)) | |||||
# get info for current user | |||||
user_info = frappe._dict() | |||||
add_user_info(frappe.session.user, user_info) | |||||
user_info_map = {d.name: d for d in user_info} | |||||
if frappe.session.user == 'Administrator' and user_info.Administrator.email: | |||||
user_info[user_info.Administrator.email] = user_info.Administrator | |||||
admin_data = user_info_map.get('Administrator') | |||||
if admin_data: | |||||
user_info_map[admin_data.email] = admin_data | |||||
return user_info_map | |||||
return user_info | |||||
def get_user(bootinfo): | def get_user(bootinfo): | ||||
"""get user info""" | """get user info""" | ||||
@@ -19,7 +19,7 @@ from frappe.core.doctype.user_type.user_type import user_linked_with_permission_ | |||||
from frappe.query_builder import DocType | from frappe.query_builder import DocType | ||||
STANDARD_USERS = ("Guest", "Administrator") | |||||
STANDARD_USERS = frappe.STANDARD_USERS | |||||
class User(Document): | class User(Document): | ||||
__new_password = None | __new_password = None | ||||
@@ -94,30 +94,78 @@ def get_docinfo(doc=None, doctype=None, name=None): | |||||
automated_messages = filter(lambda x: x['communication_type'] == 'Automated Message', all_communications) | automated_messages = filter(lambda x: x['communication_type'] == 'Automated Message', all_communications) | ||||
communications_except_auto_messages = filter(lambda x: x['communication_type'] != 'Automated Message', all_communications) | communications_except_auto_messages = filter(lambda x: x['communication_type'] != 'Automated Message', all_communications) | ||||
frappe.response["docinfo"] = { | |||||
docinfo = frappe._dict(user_info = {}) | |||||
add_comments(doc, docinfo) | |||||
docinfo.update({ | |||||
"attachments": get_attachments(doc.doctype, doc.name), | "attachments": get_attachments(doc.doctype, doc.name), | ||||
"attachment_logs": get_comments(doc.doctype, doc.name, 'attachment'), | |||||
"communications": communications_except_auto_messages, | "communications": communications_except_auto_messages, | ||||
"automated_messages": automated_messages, | "automated_messages": automated_messages, | ||||
'comments': get_comments(doc.doctype, doc.name), | |||||
'total_comments': len(json.loads(doc.get('_comments') or '[]')), | 'total_comments': len(json.loads(doc.get('_comments') or '[]')), | ||||
'versions': get_versions(doc), | 'versions': get_versions(doc), | ||||
"assignments": get_assignments(doc.doctype, doc.name), | "assignments": get_assignments(doc.doctype, doc.name), | ||||
"assignment_logs": get_comments(doc.doctype, doc.name, 'assignment'), | |||||
"permissions": get_doc_permissions(doc), | "permissions": get_doc_permissions(doc), | ||||
"shared": frappe.share.get_users(doc.doctype, doc.name), | "shared": frappe.share.get_users(doc.doctype, doc.name), | ||||
"info_logs": get_comments(doc.doctype, doc.name, comment_type=['Info', 'Edit', 'Label']), | |||||
"share_logs": get_comments(doc.doctype, doc.name, 'share'), | |||||
"like_logs": get_comments(doc.doctype, doc.name, 'Like'), | |||||
"workflow_logs": get_comments(doc.doctype, doc.name, comment_type="Workflow"), | |||||
"views": get_view_logs(doc.doctype, doc.name), | "views": get_view_logs(doc.doctype, doc.name), | ||||
"energy_point_logs": get_point_logs(doc.doctype, doc.name), | "energy_point_logs": get_point_logs(doc.doctype, doc.name), | ||||
"additional_timeline_content": get_additional_timeline_content(doc.doctype, doc.name), | "additional_timeline_content": get_additional_timeline_content(doc.doctype, doc.name), | ||||
"milestones": get_milestones(doc.doctype, doc.name), | "milestones": get_milestones(doc.doctype, doc.name), | ||||
"is_document_followed": is_document_followed(doc.doctype, doc.name, frappe.session.user), | "is_document_followed": is_document_followed(doc.doctype, doc.name, frappe.session.user), | ||||
"tags": get_tags(doc.doctype, doc.name), | "tags": get_tags(doc.doctype, doc.name), | ||||
"document_email": get_document_email(doc.doctype, doc.name) | |||||
} | |||||
"document_email": get_document_email(doc.doctype, doc.name), | |||||
}) | |||||
update_user_info(docinfo) | |||||
frappe.response["docinfo"] = docinfo | |||||
def add_comments(doc, docinfo): | |||||
# divide comments into separate lists | |||||
docinfo.comments = [] | |||||
docinfo.shared = [] | |||||
docinfo.assignment_logs = [] | |||||
docinfo.attachment_logs = [] | |||||
docinfo.info_logs = [] | |||||
docinfo.like_logs = [] | |||||
docinfo.workflow_logs = [] | |||||
comments = frappe.get_all("Comment", | |||||
fields=["name", "creation", "content", "owner", "comment_type"], | |||||
filters={ | |||||
"reference_doctype": doc.doctype, | |||||
"reference_name": doc.name | |||||
} | |||||
) | |||||
for c in comments: | |||||
if c.comment_type == "Comment": | |||||
c.content = frappe.utils.markdown(c.content) | |||||
docinfo.comments.append(c) | |||||
elif c.comment_type in ('Shared', 'Unshared'): | |||||
docinfo.shared.append(c) | |||||
elif c.comment_type in ('Assignment Completed', 'Assigned'): | |||||
docinfo.assignment_logs.append(c) | |||||
elif c.comment_type in ('Attachment', 'Attachment Removed'): | |||||
docinfo.attachment_logs.append(c) | |||||
elif c.comment_type in ('Info', 'Edit', 'Label'): | |||||
docinfo.info_logs.append(c) | |||||
elif c.comment_type == "Like": | |||||
docinfo.like_logs.append(c) | |||||
elif c.comment_type == "Workflow": | |||||
docinfo.workflow_logs.append(c) | |||||
frappe.utils.add_user_info(c.owner, docinfo.user_info) | |||||
return comments | |||||
def get_milestones(doctype, name): | def get_milestones(doctype, name): | ||||
return frappe.db.get_all('Milestone', fields = ['creation', 'owner', 'track_field', 'value'], | return frappe.db.get_all('Milestone', fields = ['creation', 'owner', 'track_field', 'value'], | ||||
@@ -252,7 +300,7 @@ def get_communication_data(doctype, name, start=0, limit=20, after=None, fields= | |||||
return communications | return communications | ||||
def get_assignments(dt, dn): | def get_assignments(dt, dn): | ||||
cl = frappe.get_all("ToDo", | |||||
return frappe.get_all("ToDo", | |||||
fields=['name', 'allocated_to as owner', 'description', 'status'], | fields=['name', 'allocated_to as owner', 'description', 'status'], | ||||
filters={ | filters={ | ||||
'reference_type': dt, | 'reference_type': dt, | ||||
@@ -260,8 +308,6 @@ def get_assignments(dt, dn): | |||||
'status': ('!=', 'Cancelled'), | 'status': ('!=', 'Cancelled'), | ||||
}) | }) | ||||
return cl | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
def get_badge_info(doctypes, filters): | def get_badge_info(doctypes, filters): | ||||
filters = json.loads(filters) | filters = json.loads(filters) | ||||
@@ -319,3 +365,24 @@ def get_additional_timeline_content(doctype, docname): | |||||
contents.extend(frappe.get_attr(method)(doctype, docname) or []) | contents.extend(frappe.get_attr(method)(doctype, docname) or []) | ||||
return contents | return contents | ||||
def update_user_info(docinfo): | |||||
for d in docinfo.communications: | |||||
frappe.utils.add_user_info(d.sender, docinfo.user_info) | |||||
for d in docinfo.shared: | |||||
frappe.utils.add_user_info(d.user, docinfo.user_info) | |||||
for d in docinfo.assignments: | |||||
frappe.utils.add_user_info(d.owner, docinfo.user_info) | |||||
for d in docinfo.views: | |||||
frappe.utils.add_user_info(d.owner, docinfo.user_info) | |||||
@frappe.whitelist() | |||||
def get_user_info_for_viewers(users): | |||||
user_info = {} | |||||
for user in json.loads(users): | |||||
frappe.utils.add_user_info(user, user_info) | |||||
return user_info |
@@ -12,7 +12,7 @@ from io import StringIO | |||||
from frappe.core.doctype.access_log.access_log import make_access_log | from frappe.core.doctype.access_log.access_log import make_access_log | ||||
from frappe.utils import cstr, format_duration | from frappe.utils import cstr, format_duration | ||||
from frappe.model.base_document import get_controller | from frappe.model.base_document import get_controller | ||||
from frappe.utils import add_user_info | |||||
@frappe.whitelist() | @frappe.whitelist() | ||||
@frappe.read_only() | @frappe.read_only() | ||||
@@ -219,6 +219,8 @@ def compress(data, args=None): | |||||
"""separate keys and values""" | """separate keys and values""" | ||||
from frappe.desk.query_report import add_total_row | from frappe.desk.query_report import add_total_row | ||||
user_info = {} | |||||
if not data: return data | if not data: return data | ||||
if args is None: | if args is None: | ||||
args = {} | args = {} | ||||
@@ -230,13 +232,19 @@ def compress(data, args=None): | |||||
new_row.append(row.get(key)) | new_row.append(row.get(key)) | ||||
values.append(new_row) | values.append(new_row) | ||||
# add user info for assignments (avatar) | |||||
if row._assign: | |||||
for user in json.loads(row._assign): | |||||
add_user_info(user, user_info) | |||||
if args.get("add_total_row"): | if args.get("add_total_row"): | ||||
meta = frappe.get_meta(args.doctype) | meta = frappe.get_meta(args.doctype) | ||||
values = add_total_row(values, keys, meta) | values = add_total_row(values, keys, meta) | ||||
return { | return { | ||||
"keys": keys, | "keys": keys, | ||||
"values": values | |||||
"values": values, | |||||
"user_info": user_info | |||||
} | } | ||||
@frappe.whitelist() | @frappe.whitelist() | ||||
@@ -646,8 +646,6 @@ class BaseDocument(object): | |||||
value, comma_options)) | value, comma_options)) | ||||
def _validate_data_fields(self): | def _validate_data_fields(self): | ||||
from frappe.core.doctype.user.user import STANDARD_USERS | |||||
# data_field options defined in frappe.model.data_field_options | # data_field options defined in frappe.model.data_field_options | ||||
for data_field in self.meta.get_data_fields(): | for data_field in self.meta.get_data_fields(): | ||||
data = self.get(data_field.fieldname) | data = self.get(data_field.fieldname) | ||||
@@ -658,7 +656,7 @@ class BaseDocument(object): | |||||
continue | continue | ||||
if data_field_options == "Email": | if data_field_options == "Email": | ||||
if (self.owner in STANDARD_USERS) and (data in STANDARD_USERS): | |||||
if (self.owner in frappe.STANDARD_USERS) and (data in frappe.STANDARD_USERS): | |||||
continue | continue | ||||
for email_address in frappe.utils.split_emails(data): | for email_address in frappe.utils.split_emails(data): | ||||
frappe.utils.validate_email_address(email_address, throw=True) | frappe.utils.validate_email_address(email_address, throw=True) | ||||
@@ -27,19 +27,40 @@ frappe.ui.form.FormViewers.set_users = function(data, type) { | |||||
const users = data.users || []; | const users = data.users || []; | ||||
const new_users = users.filter(user => !past_users.includes(user)); | const new_users = users.filter(user => !past_users.includes(user)); | ||||
frappe.model.set_docinfo(doctype, docname, type, { | |||||
past: past_users.concat(new_users), | |||||
new: new_users, | |||||
current: users | |||||
}); | |||||
if ( | |||||
cur_frm && | |||||
cur_frm.doc && | |||||
cur_frm.doc.doctype === doctype && | |||||
cur_frm.doc.name == docname && | |||||
cur_frm.viewers | |||||
) { | |||||
cur_frm.viewers.refresh(true, type); | |||||
if (new_users.length===0) return; | |||||
const set_and_refresh = () => { | |||||
const info = { | |||||
past: past_users.concat(new_users), | |||||
new: new_users, | |||||
current: users | |||||
}; | |||||
frappe.model.set_docinfo(doctype, docname, type, info); | |||||
if ( | |||||
cur_frm && | |||||
cur_frm.doc && | |||||
cur_frm.doc.doctype === doctype && | |||||
cur_frm.doc.name == docname && | |||||
cur_frm.viewers | |||||
) { | |||||
cur_frm.viewers.refresh(true, type); | |||||
} | |||||
}; | |||||
let unknown_users = []; | |||||
for (let user of users) { | |||||
if (!frappe.boot.user_info[user]) unknown_users.push(user); | |||||
} | |||||
if (unknown_users.length===0) { | |||||
set_and_refresh(); | |||||
} else { | |||||
// load additional user info | |||||
frappe.xcall('frappe.desk.form.load.get_user_info_for_viewers', {users: unknown_users}).then((data) => { | |||||
Object.assign(frappe.boot.user_info, data); | |||||
set_and_refresh(); | |||||
}); | |||||
} | } | ||||
}; | }; |
@@ -484,6 +484,11 @@ frappe.views.BaseList = class BaseList { | |||||
prepare_data(r) { | prepare_data(r) { | ||||
let data = r.message || {}; | let data = r.message || {}; | ||||
// extract user_info for assignments | |||||
Object.assign(frappe.boot.user_info, data.user_info); | |||||
delete data.user_info; | |||||
data = !Array.isArray(data) | data = !Array.isArray(data) | ||||
? frappe.utils.dict(data.keys, data.values) | ? frappe.utils.dict(data.keys, data.values) | ||||
: data; | : data; | ||||
@@ -1,7 +1,7 @@ | |||||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | // Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | ||||
// MIT License. See license.txt | // MIT License. See license.txt | ||||
$.extend(frappe.model, { | |||||
Object.assign(frappe.model, { | |||||
docinfo: {}, | docinfo: {}, | ||||
sync: function(r) { | sync: function(r) { | ||||
/* docs: | /* docs: | ||||
@@ -33,22 +33,28 @@ $.extend(frappe.model, { | |||||
} | } | ||||
if(d.localname) { | if(d.localname) { | ||||
frappe.model.new_names[d.localname] = d.name; | |||||
$(document).trigger('rename', [d.doctype, d.localname, d.name]); | |||||
delete locals[d.doctype][d.localname]; | |||||
// update docinfo to new dict keys | |||||
if(i===0) { | |||||
frappe.model.docinfo[d.doctype][d.name] = frappe.model.docinfo[d.doctype][d.localname]; | |||||
frappe.model.docinfo[d.doctype][d.localname] = undefined; | |||||
} | |||||
frappe.model.rename_after_save(d, i); | |||||
} | } | ||||
} | } | ||||
} | |||||
frappe.model.sync_docinfo(r); | |||||
}, | |||||
rename_after_save: (d, i) => { | |||||
frappe.model.new_names[d.localname] = d.name; | |||||
$(document).trigger('rename', [d.doctype, d.localname, d.name]); | |||||
delete locals[d.doctype][d.localname]; | |||||
// update docinfo to new dict keys | |||||
if(i===0) { | |||||
frappe.model.docinfo[d.doctype][d.name] = frappe.model.docinfo[d.doctype][d.localname]; | |||||
frappe.model.docinfo[d.doctype][d.localname] = undefined; | |||||
} | } | ||||
}, | |||||
sync_docinfo: (r) => { | |||||
// set docinfo (comments, assign, attachments) | // set docinfo (comments, assign, attachments) | ||||
if(r.docinfo) { | if(r.docinfo) { | ||||
var doc; | var doc; | ||||
@@ -62,10 +68,14 @@ $.extend(frappe.model, { | |||||
frappe.model.docinfo[doc.doctype] = {}; | frappe.model.docinfo[doc.doctype] = {}; | ||||
frappe.model.docinfo[doc.doctype][doc.name] = r.docinfo; | frappe.model.docinfo[doc.doctype][doc.name] = r.docinfo; | ||||
} | } | ||||
// copy values to frappe.boot.user_info | |||||
Object.assign(frappe.boot.user_info, r.docinfo.user_info); | |||||
} | } | ||||
return r.docs; | return r.docs; | ||||
}, | }, | ||||
add_to_locals: function(doc) { | add_to_locals: function(doc) { | ||||
if(!locals[doc.doctype]) | if(!locals[doc.doctype]) | ||||
locals[doc.doctype] = {}; | locals[doc.doctype] = {}; | ||||
@@ -100,6 +110,7 @@ $.extend(frappe.model, { | |||||
} | } | ||||
} | } | ||||
}, | }, | ||||
update_in_locals: function(doc) { | update_in_locals: function(doc) { | ||||
// update values in the existing local doc instead of replacing | // update values in the existing local doc instead of replacing | ||||
let local_doc = locals[doc.doctype][doc.name]; | let local_doc = locals[doc.doctype][doc.name]; | ||||
@@ -2,14 +2,6 @@ frappe.user_info = function(uid) { | |||||
if(!uid) | if(!uid) | ||||
uid = frappe.session.user; | uid = frappe.session.user; | ||||
if(uid.toLowerCase()==="bot") { | |||||
return { | |||||
fullname: __("Bot"), | |||||
image: "/assets/frappe/images/ui/bot.png", | |||||
abbr: "B" | |||||
}; | |||||
} | |||||
if(!(frappe.boot.user_info && frappe.boot.user_info[uid])) { | if(!(frappe.boot.user_info && frappe.boot.user_info[uid])) { | ||||
var user_info = {fullname: uid || "Unknown"}; | var user_info = {fullname: uid || "Unknown"}; | ||||
} else { | } else { | ||||
@@ -22,29 +14,6 @@ frappe.user_info = function(uid) { | |||||
return user_info; | return user_info; | ||||
}; | }; | ||||
frappe.ui.set_user_background = function(src, selector, style) { | |||||
if(!selector) selector = "#page-desktop"; | |||||
if(!style) style = "Fill Screen"; | |||||
if(src) { | |||||
if (window.cordova && src.indexOf("http") === -1) { | |||||
src = frappe.base_url + src; | |||||
} | |||||
var background = repl('background: url("%(src)s") center center;', {src: src}); | |||||
} else { | |||||
var background = "background-color: #4B4C9D;"; | |||||
} | |||||
frappe.dom.set_style(repl('%(selector)s { \ | |||||
%(background)s \ | |||||
background-attachment: fixed; \ | |||||
%(style)s \ | |||||
}', { | |||||
selector:selector, | |||||
background:background, | |||||
style: style==="Fill Screen" ? "background-size: cover;" : "" | |||||
})); | |||||
}; | |||||
frappe.provide('frappe.user'); | frappe.provide('frappe.user'); | ||||
$.extend(frappe.user, { | $.extend(frappe.user, { | ||||
@@ -56,7 +56,7 @@ def get_email_address(user=None): | |||||
def get_formatted_email(user, mail=None): | def get_formatted_email(user, mail=None): | ||||
"""get Email Address of user formatted as: `John Doe <johndoe@example.com>`""" | """get Email Address of user formatted as: `John Doe <johndoe@example.com>`""" | ||||
fullname = get_fullname(user) | fullname = get_fullname(user) | ||||
method = get_hook_method('get_sender_details') | method = get_hook_method('get_sender_details') | ||||
if method: | if method: | ||||
sender_name, mail = method() | sender_name, mail = method() | ||||
@@ -623,12 +623,11 @@ def get_installed_apps_info(): | |||||
return out | return out | ||||
def get_site_info(): | def get_site_info(): | ||||
from frappe.core.doctype.user.user import STANDARD_USERS | |||||
from frappe.email.queue import get_emails_sent_this_month | from frappe.email.queue import get_emails_sent_this_month | ||||
from frappe.utils.user import get_system_managers | from frappe.utils.user import get_system_managers | ||||
# only get system users | # only get system users | ||||
users = frappe.get_all('User', filters={'user_type': 'System User', 'name': ('not in', STANDARD_USERS)}, | |||||
users = frappe.get_all('User', filters={'user_type': 'System User', 'name': ('not in', frappe.STANDARD_USERS)}, | |||||
fields=['name', 'enabled', 'last_login', 'last_active', 'language', 'time_zone']) | fields=['name', 'enabled', 'last_login', 'last_active', 'language', 'time_zone']) | ||||
system_managers = get_system_managers(only_name=True) | system_managers = get_system_managers(only_name=True) | ||||
for u in users: | for u in users: | ||||
@@ -898,3 +897,14 @@ def dictify(arg): | |||||
arg = frappe._dict(arg) | arg = frappe._dict(arg) | ||||
return arg | return arg | ||||
def add_user_info(user, user_info): | |||||
if user not in user_info: | |||||
info = frappe.db.get_value("User", | |||||
user, ["full_name", "user_image", "name", 'email'], as_dict=True) or frappe._dict() | |||||
user_info[user] = frappe._dict( | |||||
fullname = info.full_name or user, | |||||
image = info.user_image, | |||||
name = user, | |||||
email = info.email | |||||
) |
@@ -17,7 +17,6 @@ import schedule | |||||
# imports - module imports | # imports - module imports | ||||
import frappe | import frappe | ||||
from frappe.core.doctype.user.user import STANDARD_USERS | |||||
from frappe.installer import update_site_config | from frappe.installer import update_site_config | ||||
from frappe.utils import get_sites, now_datetime | from frappe.utils import get_sites, now_datetime | ||||
from frappe.utils.background_jobs import get_jobs | from frappe.utils.background_jobs import get_jobs | ||||
@@ -230,7 +230,6 @@ def get_fullname_and_avatar(user): | |||||
def get_system_managers(only_name=False): | def get_system_managers(only_name=False): | ||||
"""returns all system manager's user details""" | """returns all system manager's user details""" | ||||
import email.utils | import email.utils | ||||
from frappe.core.doctype.user.user import STANDARD_USERS | |||||
system_managers = frappe.db.sql("""SELECT DISTINCT `name`, `creation`, | system_managers = frappe.db.sql("""SELECT DISTINCT `name`, `creation`, | ||||
CONCAT_WS(' ', | CONCAT_WS(' ', | ||||
CASE WHEN `first_name`= '' THEN NULL ELSE `first_name` END, | CASE WHEN `first_name`= '' THEN NULL ELSE `first_name` END, | ||||
@@ -245,8 +244,8 @@ def get_system_managers(only_name=False): | |||||
FROM `tabHas Role` AS ur | FROM `tabHas Role` AS ur | ||||
WHERE ur.parent = p.name | WHERE ur.parent = p.name | ||||
AND ur.role='System Manager') | AND ur.role='System Manager') | ||||
ORDER BY `creation` DESC""".format(", ".join(["%s"]*len(STANDARD_USERS))), | |||||
STANDARD_USERS, as_dict=True) | |||||
ORDER BY `creation` DESC""".format(", ".join(["%s"]*len(frappe.STANDARD_USERS))), | |||||
frappe.STANDARD_USERS, as_dict=True) | |||||
if only_name: | if only_name: | ||||
return [p.name for p in system_managers] | return [p.name for p in system_managers] | ||||