diff --git a/frappe/core/doctype/user/test_user.js b/frappe/core/doctype/user/test_user.js new file mode 100644 index 0000000000..52f9b7e42c --- /dev/null +++ b/frappe/core/doctype/user/test_user.js @@ -0,0 +1,23 @@ +/* eslint-disable */ +// rename this file from _test_[name] to test_[name] to activate +// and remove above this line + +QUnit.test("test: User", function (assert) { + let done = assert.async(); + + // number of asserts + assert.expect(1); + + frappe.run_serially([ + // insert a new User + () => frappe.tests.make('User', [ + // values to be set + {key: 'value'} + ]), + () => { + assert.equal(cur_frm.doc.key, 'value'); + }, + () => done() + ]); + +}); diff --git a/frappe/core/doctype/user/user.js b/frappe/core/doctype/user/user.js index 5409b569c7..ac443c8d69 100644 --- a/frappe/core/doctype/user/user.js +++ b/frappe/core/doctype/user/user.js @@ -60,11 +60,11 @@ frappe.ui.form.on('User', { "user": doc.name }; frappe.set_route('List', 'User Permission'); - }, null, "btn-default") + }, __("Permissions")) frm.add_custom_button(__('View Permitted Documents'), () => frappe.set_route('query-report', 'Permitted Documents For User', - {user: frm.doc.name})); + {user: frm.doc.name}), __("Permissions")); frm.toggle_display(['sb1', 'sb3', 'modules_access'], true); } @@ -76,7 +76,7 @@ frappe.ui.form.on('User', { "user": frm.doc.name } }) - }) + }, __("Password")); frm.add_custom_button(__("Reset OTP Secret"), function() { frappe.call({ @@ -85,7 +85,7 @@ frappe.ui.form.on('User', { "user": frm.doc.name } }) - }) + }, __("Password")); frm.trigger('enabled'); diff --git a/frappe/core/doctype/user/user.json b/frappe/core/doctype/user/user.json index 31714b7116..53e16ba388 100644 --- a/frappe/core/doctype/user/user.json +++ b/frappe/core/doctype/user/user.json @@ -1043,6 +1043,36 @@ "set_only_once": 0, "unique": 0 }, + { + "allow_bulk_edit": 0, + "allow_on_submit": 0, + "bold": 0, + "collapsible": 0, + "columns": 0, + "fieldname": "send_me_a_copy", + "fieldtype": "Check", + "hidden": 0, + "ignore_user_permissions": 0, + "ignore_xss_filter": 0, + "in_filter": 0, + "in_global_search": 0, + "in_list_view": 0, + "in_standard_filter": 0, + "label": "Send Me A Copy of Outgoing Emails", + "length": 0, + "no_copy": 0, + "permlevel": 0, + "precision": "", + "print_hide": 0, + "print_hide_if_no_value": 0, + "read_only": 0, + "remember_last_selected_value": 0, + "report_hide": 0, + "reqd": 0, + "search_index": 0, + "set_only_once": 0, + "unique": 0 + }, { "allow_bulk_edit": 0, "allow_on_submit": 0, @@ -1971,7 +2001,7 @@ "istable": 0, "max_attachments": 5, "menu_index": 0, - "modified": "2017-07-07 17:18:14.047969", + "modified": "2017-08-23 10:34:11.944298", "modified_by": "Administrator", "module": "Core", "name": "User", diff --git a/frappe/core/doctype/user/user.py b/frappe/core/doctype/user/user.py index e7d24baf2e..923ae43582 100644 --- a/frappe/core/doctype/user/user.py +++ b/frappe/core/doctype/user/user.py @@ -952,7 +952,7 @@ def send_token_via_email(tmp_id,token=None): delayed=False, retry=3) return True - + @frappe.whitelist(allow_guest=True) def reset_otp_secret(user): otp_issuer = frappe.db.get_value('System Settings', 'System Settings', 'otp_issuer_name') @@ -964,7 +964,7 @@ def reset_otp_secret(user): 'recipients':user_email, 'sender':None, 'subject':'OTP Secret Reset - {}'.format(otp_issuer or "Frappe Framework"), 'message':'
Your OTP secret on {} has been reset. If you did not perform this reset and did not request it, please contact your System Administrator immediately.
'.format(otp_issuer or "Frappe Framework"), 'delayed':False, - 'retry':3 + 'retry':3 } enqueue(method=frappe.sendmail, queue='short', timeout=300, event=None, async=True, job_name=None, now=False, **email_args) return frappe.msgprint(_("OTP Secret has been reset. Re-registration will be required on next login.")) diff --git a/frappe/public/js/frappe/views/communication.js b/frappe/public/js/frappe/views/communication.js index 741f910114..81c5f8d417 100755 --- a/frappe/public/js/frappe/views/communication.js +++ b/frappe/public/js/frappe/views/communication.js @@ -63,7 +63,7 @@ frappe.views.CommunicationComposer = Class.extend({ {label:__("Send As Email"), fieldtype:"Check", fieldname:"send_email"}, {label:__("Send me a copy"), fieldtype:"Check", - fieldname:"send_me_a_copy"}, + fieldname:"send_me_a_copy", 'default': frappe.boot.user.send_me_a_copy}, {label:__("Send Read Receipt"), fieldtype:"Check", fieldname:"send_read_receipt"}, {label:__("Communication Medium"), fieldtype:"Select", @@ -375,7 +375,14 @@ frappe.views.CommunicationComposer = Class.extend({ $(fields.select_print_format.wrapper).toggle(true); } - $(fields.send_email.input).prop("checked", true) + $(fields.send_email.input).prop("checked", true); + + $(fields.send_me_a_copy.input).on('click', () => { + // update send me a copy (make it sticky) + let val = fields.send_me_a_copy.get_value(); + frappe.db.set_value('User', frappe.session.user, 'send_me_a_copy', val); + frappe.boot.user.send_me_a_copy = val; + }); // toggle print format $(fields.send_email.input).click(function() { diff --git a/frappe/sessions.py b/frappe/sessions.py index 37f26921f0..0a0f7e04bd 100644 --- a/frappe/sessions.py +++ b/frappe/sessions.py @@ -33,7 +33,7 @@ def clear_cache(user=None): cache = frappe.cache() groups = ("bootinfo", "user_recent", "roles", "user_doc", "lang", - "defaults", "user_permissions", "roles", "home_page", "linked_with", + "defaults", "user_permissions", "home_page", "linked_with", "desktop_icons", 'portal_menu_items') if user: diff --git a/frappe/utils/user.py b/frappe/utils/user.py index 67a9f6ee58..0fd7fa58d0 100755 --- a/frappe/utils/user.py +++ b/frappe/utils/user.py @@ -193,8 +193,8 @@ class UserPermissions: def load_user(self): d = frappe.db.sql("""select email, first_name, last_name, creation, - email_signature, user_type, language, background_image, background_style, mute_sounds - from tabUser where name = %s""", (self.name,), as_dict=1)[0] + email_signature, user_type, language, background_image, background_style, + mute_sounds, send_me_a_copy from tabUser where name = %s""", (self.name,), as_dict=1)[0] if not self.can_read: self.build_permissions()