diff --git a/css/all-app.css b/css/all-app.css index b2fd2e5732..b49caedee9 100644 --- a/css/all-app.css +++ b/css/all-app.css @@ -1043,7 +1043,7 @@ div.dialog_head { } div.dialog_body { - padding: 8px 4px 16px 4px; + padding: 8px 8px 16px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; diff --git a/css/all-web.css b/css/all-web.css index 9359de898e..bebfe9a334 100644 --- a/css/all-web.css +++ b/css/all-web.css @@ -362,7 +362,7 @@ div.dialog_head { } div.dialog_body { - padding: 8px 4px 16px 4px; + padding: 8px 8px 16px; border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; diff --git a/erpnext/home/page/my_company/my_company.js b/erpnext/home/page/my_company/my_company.js index 775c89e7a8..8217cc71c1 100644 --- a/erpnext/home/page/my_company/my_company.js +++ b/erpnext/home/page/my_company/my_company.js @@ -758,253 +758,3 @@ MemberCoversationComment = function(cell, det, conv) { -// ========================== Role object ===================================== - -pscript.all_roles = null; - -RoleObj = function(profile_id){ - this.roles_dict = {}; - this.profile_id = profile_id; - this.setup_done = 0; - - var d = new Dialog(500,500,'Assign Roles'); - d.make_body([ - ['HTML','roles'] - ]); - - this.dialog = d; - this.make_role_body(profile_id); - this.make_help_body(); - - this.body.innerHTML = 'Loading... ' - var me=this; - - d.onshow = function() { - if(!me.setup_done) - me.get_all_roles(me.profile_id); - } -} - -// make role body -RoleObj.prototype.make_role_body = function(id){ - var me = this; - var d = this.dialog; - this.role_div = $a(d.widgets['roles'],'div'); - - this.head = $a(this.role_div,'div','',{marginLeft:'4px', marginBottom:'4px',fontWeight:'bold'}); - this.body = $a(this.role_div,'div'); - this.footer = $a(this.role_div,'div'); - - this.update_btn = $btn(this.footer,'Update',function() { me.update_roles(me.profile_id); },{marginRight:'4px'},'',1); -} - -// make help body -RoleObj.prototype.make_help_body = function(){ - var me = this; - - var d = this.dialog; - this.help_div = $a(d.widgets['roles'],'div'); - - var head = $a(this.help_div,'div'); this.help_div.head = head; - var body = $a(this.help_div,'div'); this.help_div.body = body; - var tail = $a(this.help_div,'div'); this.help_div.tail = tail; - - var back_btn = $btn(tail,'Back', function() { - // back to assign roles - $(me.role_div).slideToggle('medium'); - $(me.help_div).slideToggle('medium'); - }); - this.help_div.back_btn = back_btn; - $dh(this.help_div); -} - -// get all roles -RoleObj.prototype.get_all_roles = function(id){ - if(pscript.all_roles) { - this.make_roles(id); - return; - } - - var me = this; - var callback = function(r,rt){ - pscript.all_roles = r.message; - me.make_roles(id); - } - $c_obj('Company Control','get_all_roles','',callback); -} - -// make roles -RoleObj.prototype.make_roles = function(id){ - var me = this; - var list = pscript.all_roles; - me.setup_done = 1; - me.body.innerHTML = ''; - - var tbl = make_table( me.body, cint(list.length / 2) + 1,4,'100%',['5%','45%','5%','45%'],{padding:'4px'}); - var in_right = 0; var ridx = 0; - - for(i=0;i 1){ - var c = confirm("You have unchecked the System Manager role.\nYou will lose administrative rights and will not be able to set roles.\n\nDo you want to continue anyway?"); - if(!c) return; - } - else{ - var c = "There should be atleast one user with System Manager role."; - me.roles_dict['System Manager'].checked = 1; - } - } - me.set_roles(id); - } - $c_obj('Company Control','get_sm_count','',callback); - } - else{ - me.set_roles(id); - } -} - -// set roles -RoleObj.prototype.set_roles = function(id){ - - var me = this; - var role_list = []; - - for(d in me.roles_dict){ - if(me.roles_dict[d].checked){ - role_list.push(d); - } - } - - var callback = function(r,rt){ - me.update_btn.done_working(); - me.dialog.hide(); - } - var arg = {'usr':id, 'role_list':role_list}; - me.update_btn.set_working(); - $c_obj('Company Control','update_roles',docstring(arg), callback); - -} - -// get permission -RoleObj.prototype.get_permissions = function(role){ - var me = this; - - var callback = function(r,rt){ - $(me.help_div).slideToggle('medium'); - $(me.role_div).slideToggle('medium'); - me.set_permissions(r.message, role); - } - $c_obj('Company Control','get_permission',role,callback); -} - - -// set permission -RoleObj.prototype.set_permissions = function(perm, role){ - var me = this; - me.help_div.body.innerHTML =''; - - if(perm){ - me.help_div.head.innerHTML = 'Permissions for ' + role + ':

'; - - perm_tbl = make_table(me.help_div.body,cint(perm.length)+2,7,'100%',['30%','10%','10%','10%','10%','10%','10%'],{padding:'4px'}); - - var head_lst = ['Document','Read','Write','Create','Submit','Cancel','Amend']; - - for(var i=0; i<(head_lst.length-1);i++){ - $td(perm_tbl,0,i).innerHTML= ""+head_lst[i]+""; - } - var accept_img1 = 'lib/images/icons/accept.gif'; - var cancel_img1 = 'lib/images/icons/cancel.gif'; - - for(i=1; i
'; -} diff --git a/erpnext/support/doctype/customer_issue/customer_issue.py b/erpnext/support/doctype/customer_issue/customer_issue.py index b00a6a03c8..af839cf09f 100644 --- a/erpnext/support/doctype/customer_issue/customer_issue.py +++ b/erpnext/support/doctype/customer_issue/customer_issue.py @@ -15,6 +15,7 @@ # along with this program. If not, see . # Please edit this list and import only required elements + import webnotes from webnotes.utils import add_days, add_months, add_years, cint, cstr, date_diff, default_fields, flt, fmt_money, formatdate, generate_hash, getTraceback, get_defaults, get_first_day, get_last_day, getdate, has_common, month_name, now, nowdate, replace_newlines, sendmail, set_default, str_esc_quote, user_format, validate_email_add diff --git a/erpnext/utilities/page/messages/messages.js b/erpnext/utilities/page/messages/messages.js index 39f7974870..43adce404d 100644 --- a/erpnext/utilities/page/messages/messages.js +++ b/erpnext/utilities/page/messages/messages.js @@ -1,3 +1,19 @@ +// ERPNext - web based ERP (http://erpnext.com) +// Copyright (C) 2012 Web Notes Technologies Pvt Ltd +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + wn.provide('erpnext.messages'); wn.pages.messages.onload = function(wrapper) { diff --git a/erpnext/utilities/page/messages/messages.py b/erpnext/utilities/page/messages/messages.py index d7c60267ed..8e92ff9ec9 100644 --- a/erpnext/utilities/page/messages/messages.py +++ b/erpnext/utilities/page/messages/messages.py @@ -1,3 +1,19 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + import webnotes @webnotes.whitelist() diff --git a/erpnext/utilities/page/todo/todo.js b/erpnext/utilities/page/todo/todo.js index 77e4625fae..435002301b 100644 --- a/erpnext/utilities/page/todo/todo.js +++ b/erpnext/utilities/page/todo/todo.js @@ -1,3 +1,19 @@ +// ERPNext - web based ERP (http://erpnext.com) +// Copyright (C) 2012 Web Notes Technologies Pvt Ltd +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + wn.provide('erpnext.todo'); erpnext.todo.refresh = function() { diff --git a/erpnext/utilities/page/todo/todo.py b/erpnext/utilities/page/todo/todo.py index c10809e8bf..05d55fe4a8 100644 --- a/erpnext/utilities/page/todo/todo.py +++ b/erpnext/utilities/page/todo/todo.py @@ -1,3 +1,19 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + import webnotes from webnotes.model.doc import Document diff --git a/erpnext/utilities/page/users/__init__.py b/erpnext/utilities/page/users/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/erpnext/utilities/page/users/users.css b/erpnext/utilities/page/users/users.css new file mode 100644 index 0000000000..1a85d153c0 --- /dev/null +++ b/erpnext/utilities/page/users/users.css @@ -0,0 +1,35 @@ +.user-card { + border-radius: 5px; + width: 200px; + margin: 11px; + padding: 11px; + background-color: #FFEDBD; + box-shadow: 3px 3px 5px #888; + float: left; + overflow: hidden; +} + +.user-card.disabled { + background-color: #eee; +} + +.user-card img { + height: 60px; +} + +.user-role { + padding: 5px; + width: 45%; + float: left; +} + +table.user-perm { + border-collapse: collapse; +} + +table.user-perm td, table.user-perm th { + padding: 5px; + text-align: center; + border-bottom: 1px solid #aaa; + min-width: 30px; +} \ No newline at end of file diff --git a/erpnext/utilities/page/users/users.html b/erpnext/utilities/page/users/users.html new file mode 100644 index 0000000000..fe2f000413 --- /dev/null +++ b/erpnext/utilities/page/users/users.html @@ -0,0 +1,13 @@ +
+ × +

Users

+
+
Add, disable, delete users and change their roles, passwords and security settings
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/erpnext/utilities/page/users/users.js b/erpnext/utilities/page/users/users.js new file mode 100644 index 0000000000..21519b85a1 --- /dev/null +++ b/erpnext/utilities/page/users/users.js @@ -0,0 +1,377 @@ +// ERPNext - web based ERP (http://erpnext.com) +// Copyright (C) 2012 Web Notes Technologies Pvt Ltd +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +$.extend(wn.pages.users, { + onload: function(wrapper) { + wn.pages.users.profiles = {}; + wn.pages.users.refresh(); + wn.pages.users.setup(); + wn.pages.users.role_editor = new erpnext.RoleEditor(); + }, + setup: function() { + // set roles + $('.users-area').on('click', '.btn.user-roles', function() { + var uid = $(this).parent().parent().attr('data-name'); + wn.pages.users.role_editor.show(uid); + }); + + // settings + $('.users-area').on('click', '.btn.user-settings', function() { + var uid = $(this).parent().parent().attr('data-name'); + wn.pages.users.show_settings(uid); + }); + + // delete + $('.users-area').on('click', 'a.close', function() { + $card = $(this).parent(); + var uid = $card.attr('data-name'); + $card.css('opacity', 0.6); + wn.call({ + method: 'utilities.page.users.users.delete', + args: {'uid': uid}, + callback: function(r,rt) { + if(!r.exc) + $card.fadeOut() + } + }); + }) + + }, + refresh: function() { + // make the list + wn.call({ + method:'utilities.page.users.users.get', + callback: function(r, rt) { + $('.users-area').empty(); + for(var i in r.message) { + var p = r.message[i]; + wn.pages.users.profiles[p.name] = p; + wn.pages.users.render(p); + } + } + }); + }, + render: function(data) { + if(data.file_list) { + data.imgsrc = 'files/' + data.files_list.split('\n')[0].split(',')[1]; + } else { + data.imgsrc = 'lib/images/ui/no_img_' + (data.gender=='Female' ? 'f' : 'm'); + } + data.fullname = wn.boot.user_fullnames[data.name]; + data.delete_html = ''; + if(!data.enabled) + data.delete_html = '×'; + + $('.users-area').append(repl('
\ + %(delete_html)s\ + \ + \ +
', data)); + + if(!data.enabled) { + $('.users-area .user-card:last') + .addClass('disabled') + .find('.user-fullname').html('Disabled'); + } + }, + show_settings: function(uid) { + var me = wn.pages.users; + if(!me.settings_dialog) + me.make_settings_dialog(); + + var p = me.profiles[uid]; + me.uid = uid; + + me.settings_dialog.set_values({ + restrict_ip: p.restrict_ip || '', + login_before: p.login_before || '', + login_after: p.login_after || '', + enabled: p.enabled || 0, + new_password: '' + }); + + me.settings_dialog.show(); + + }, + make_settings_dialog: function() { + var me = wn.pages.users; + me.settings_dialog = new wn.widgets.Dialog({ + title: 'Set User Security', + width: 500, + fields: [ + { + label:'Enabled', + description: 'Uncheck to disable', + fieldtype: 'Check', fieldname: 'enabled' + }, + { + label:'IP Address', + description: 'Restrict user login by IP address, partial ips (111.111.111), \ + multiple addresses (separated by commas) allowed', + fieldname:'restrict_ip', fieldtype:'Data' + }, + { + label:'Login After', + description: 'User can only login after this hour (0-24)', + fieldtype: 'Int', fieldname: 'login_after' + }, + { + label:'Login Before', + description: 'User can only login before this hour (0-24)', + fieldtype: 'Int', fieldname: 'login_before' + }, + { + label:'New Password', + description: 'Update the current user password', + fieldtype: 'Data', fieldname: 'new_password' + }, + { + label:'Update', fieldtype:'Button', fieldname:'update' + } + ] + }); + + this.settings_dialog.fields_dict.update.input.onclick = function() { + var btn = this; + this.set_working(); + var args = me.settings_dialog.get_values(); + args.user = me.uid; + + if (args.new_password) { + me.get_password(btn, args); + } else { + btn.set_working(); + me.update_security(args); + } + }; + + }, + update_security: function(args) { + var me = wn.pages.users; + $c_page('utilities', 'users', 'update_security', JSON.stringify(args), function(r,rt) { + if(r.exc) { + msgprint(r.exc); + return; + } + me.settings_dialog.hide(); + $.extend(me.profiles[me.uid], me.settings_dialog.get_values()); + me.refresh(); + }); + }, + get_password: function(btn, args) { + var me = wn.pages.users; + var pass_d = new wn.widgets.Dialog({ + title: 'Your Password', + width: 300, + fields: [ + { + label: 'Please Enter Your Password', + description: "Your password is required to update the user's password", + fieldtype: 'Password', fieldname: 'sys_admin_pwd', reqd: 1 + }, + { + label: 'Continue', fieldtype: 'Button', fieldname: 'continue' + } + ] + }); + + pass_d.fields_dict.continue.input.onclick = function() { + btn.pwd_dialog.hide(); + args.sys_admin_pwd = btn.pwd_dialog.get_values().sys_admin_pwd; + btn.set_working(); + me.update_security(args); + btn.done_working(); + } + + pass_d.show(); + btn.pwd_dialog = pass_d; + btn.done_working(); + }, + add_user: function() { + var me = wn.pages.users; + var d = new wn.widgets.Dialog({ + title: 'Add User', + width: 400, + fields: [{ + fieldtype: 'Data', fieldname: 'user', reqd: 1, + label: 'Email Id of the user to add' + }, { + fieldtype: 'Data', fieldname: 'first_name', reqd: 1, label: 'First Name' + }, { + fieldtype: 'Data', fieldname: 'last_name', label: 'Last Name' + }, { + fieldtype: 'Data', fieldname: 'password', reqd: 1, label: 'Password' + }, { + fieldtype: 'Button', label: 'Add', fieldname: 'add' + }] + }); + + d.make(); + d.fields_dict.add.input.onclick = function() { + v = d.get_values(); + if(v) { + d.fields_dict.add.input.set_working(); + $c_page('utilities', 'users', 'add_user', v, function(r,rt) { + if(r.exc) { msgprint(r.exc); return; } + else { + d.hide(); + me.refresh(); + } + }) + } + } + d.show(); + } +}); + +erpnext.RoleEditor = Class.extend({ + init: function() { + this.dialog = new wn.widgets.Dialog({ + title: 'Set Roles' + }); + var me = this; + $(this.dialog.body).html('
Loading...
') + wn.call({ + method:'utilities.page.users.users.get_roles', + callback: function(r) { + me.roles = r.message; + me.show_roles(); + } + }); + }, + show_roles: function() { + var me = this; + $(this.dialog.body).empty(); + for(var i in this.roles) { + $(this.dialog.body).append(repl('
\ + \ + %(role)s\ +
', {role: this.roles[i]})); + } + $(this.dialog.body).append('
\ +
'); + $(this.dialog.body).find('button.btn-primary').click(function() { + me.save(); + }); + $(this.dialog.body).find('.user-role a').click(function() { + me.show_permissions($(this).parent().attr('data-user-role')) + return false; + }) + }, + show: function(uid) { + var me = this; + this.uid = uid; + this.dialog.show(); + // set user roles + wn.call({ + method:'utilities.page.users.users.get_user_roles', + args: {uid:uid}, + callback: function(r, rt) { + $(me.dialog.body).find('input[type="checkbox"]').attr('checked', false); + for(var i in r.message) { + $(me.dialog.body) + .find('[data-user-role="'+r.message[i] + +'"] input[type="checkbox"]').attr('checked',true); + } + } + }) + }, + save: function() { + var set_roles = []; + var unset_roles = []; + $(this.dialog.body).find('[data-user-role]').each(function() { + var $check = $(this).find('input[type="checkbox"]'); + if($check.attr('checked')) { + set_roles.push($(this).attr('data-user-role')); + } else { + unset_roles.push($(this).attr('data-user-role')); + } + }) + wn.call({ + method:'utilities.page.users.users.update_roles', + args: { + set_roles: JSON.stringify(set_roles), + unset_roles: JSON.stringify(unset_roles), + uid: this.uid + }, + btn: $(this.dialog.body).find('.btn-primary').get(0), + callback: function() { + + } + }) + }, + show_permissions: function(role) { + // show permissions for a role + var me = this; + if(!this.perm_dialog) + this.make_perm_dialog() + $(this.perm_dialog.body).empty(); + wn.call({ + method:'utilities.page.users.users.get_perm_info', + args: {role: role}, + callback: function(r) { + var $body = $(me.perm_dialog.body); + $body.append('\ + \ + \ + \ + \ + \ + \ +
Document TypeLevelReadWriteSubmitCancelAmend
'); + for(var i in r.message) { + var perm = r.message[i]; + + // if permission -> icon + for(key in perm) { + if(key!='parent' && key!='permlevel') { + if(perm[key]) { + perm[key] = ''; + } else { + perm[key] = ''; + } + } + } + + $body.find('tbody').append(repl('\ + %(parent)s\ + %(permlevel)s\ + %(read)s\ + %(write)s\ + %(submit)s\ + %(cancel)s\ + %(amend)s\ + ', perm)) + } + + me.perm_dialog.show(); + } + }); + + }, + make_perm_dialog: function() { + this.perm_dialog = new wn.widgets.Dialog({ + title:'Role Permissions', + width: 500 + }); + } +}) diff --git a/erpnext/utilities/page/users/users.py b/erpnext/utilities/page/users/users.py new file mode 100644 index 0000000000..44e2fb2aac --- /dev/null +++ b/erpnext/utilities/page/users/users.py @@ -0,0 +1,192 @@ +# ERPNext - web based ERP (http://erpnext.com) +# Copyright (C) 2012 Web Notes Technologies Pvt Ltd +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import webnotes +import json + +from webnotes.model.doc import Document +from webnotes.utils import cint + +@webnotes.whitelist() +def get(arg=None): + """return all users""" + return webnotes.conn.sql("""select name, file_list, enabled, gender, + restrict_ip, login_before, login_after from tabProfile + where docstatus<2 and name not in ('Administrator', 'Guest') order by + ifnull(enabled,0) desc, name""", as_dict=1) + +@webnotes.whitelist() +def get_roles(arg=None): + """return all roles""" + return [r[0] for r in webnotes.conn.sql("""select name from tabRole + where name not in ('Administrator', 'Guest', 'All') order by name""")] + +@webnotes.whitelist() +def get_user_roles(arg=None): + """get roles for a user""" + return [r[0] for r in webnotes.conn.sql("""select role from tabUserRole + where parent=%s""", webnotes.form_dict['uid'])] + +@webnotes.whitelist() +def get_perm_info(arg=None): + """get permission info""" + return webnotes.conn.sql("""select parent, permlevel, `read`, `write`, submit, + cancel, amend from tabDocPerm where role=%s + and docstatus<2 order by parent, permlevel""", + webnotes.form_dict['role'], as_dict=1) + +@webnotes.whitelist() +def update_roles(arg=None): + """update set and unset roles""" + # remove roles + unset = json.loads(webnotes.form_dict['unset_roles']) + webnotes.conn.sql("""delete from tabUserRole where parent='%s' + and role in ('%s')""" % (webnotes.form_dict['uid'], "','".join(unset))) + + # check for 1 system manager + if not webnotes.conn.sql("""select parent from tabUserRole where role='System Manager' + and docstatus<2"""): + webnotes.msgprint("Sorry there must be atleast one 'System Manager'") + raise webnotes.ValidationError + + # add roles + roles = get_user_roles() + toset = json.loads(webnotes.form_dict['set_roles']) + for role in toset: + if not role in roles: + d = Document('UserRole') + d.role = role + d.parent = webnotes.form_dict['uid'] + d.save() + + webnotes.msgprint('Roles Updated') + +@webnotes.whitelist() +def update_security(args=''): + args = json.loads(args) + webnotes.conn.set_value('Profile', args['user'], 'restrict_ip', args.get('restrict_ip')) + webnotes.conn.set_value('Profile', args['user'], 'login_after', args.get('login_after')) + webnotes.conn.set_value('Profile', args['user'], 'login_before', args.get('login_before')) + webnotes.conn.set_value('Profile', args['user'], 'enabled', int(args.get('enabled',0)) or 0) + + if 'new_password' in args: + if cint(webnotes.conn.get_value('Control Panel',None,'sync_with_gateway')): + import server_tools.gateway_utils + res = server_tools.gateway_utils.change_password('', args['new_password'], + args['user'], args['sys_admin_pwd']) + if 'Traceback' not in res['message']: + webnotes.msgprint(res['message']) + webnotes.conn.sql("update tabProfile set password=password(%s) where name=%s", + (args['new_password'], args['user'])) + else: + webnotes.msgprint('Settings Updated') + + + +# +# user addition +# + +@webnotes.whitelist() +def add_user(args): + args = json.loads(args) + # erpnext-saas + if cint(webnotes.conn.get_value('Control Panel', None, 'sync_with_gateway')): + from server_tools.gateway_utils import add_user_gateway + add_user_gateway(args['user']) + + add_profile(args) + +@webnotes.whitelist() +def add_profile(args): + from webnotes.utils import validate_email_add, now + email = args['user'] + + sql = webnotes.conn.sql + + if not email: + email = webnotes.form_dict.get('user') + if not validate_email_add(email): + raise Exception + return 'Invalid Email Id' + + if sql("select name from tabProfile where name = %s", email): + # exists, enable it + sql("update tabProfile set enabled = 1, docstatus=0 where name = %s", email) + webnotes.msgprint('Profile exists, enabled it with new password') + else: + # does not exist, create it! + pr = Document('Profile') + pr.name = email + pr.email = email + pr.first_name = args.get('first_name') + pr.last_name = args.get('last_name') + pr.enabled = 1 + pr.user_type = 'System User' + pr.save(1) + + if args.get('password'): + sql(""" + UPDATE tabProfile + SET password = PASSWORD(%s), modified = %s + WHERE name = %s""", (args.get('password'), now, email)) + + send_welcome_mail(email, args) + +@webnotes.whitelist() +def send_welcome_mail(email, args): + """send welcome mail to user with password and login url""" + pr = Document('Profile', email) + from webnotes.utils.email_lib import sendmail_md + args.update({ + 'company': webnotes.conn.get_default('company'), + 'password': args.get('password'), + 'account_url': webnotes.conn.get_default('account_url') + }) + if not args.get('last_name'): args['last_name'] = '' + sendmail_md(pr.email, subject="Welcome to ERPNext", msg=welcome_txt % args, from_defs=1) + +# +# delete user +# +@webnotes.whitelist() +def delete(arg=None): + """delete user""" + webnotes.conn.sql("update tabProfile set enabled=0, docstatus=2 where name=%s", + webnotes.form_dict['uid']) + # erpnext-saas + if int(webnotes.conn.get_value('Control Panel', None, 'sync_with_gateway')): + from server_tools.gateway_utils import remove_user_gateway + remove_user_gateway(webnotes.form_dict['uid']) + + webnotes.login_manager.logout(user=webnotes.form_dict['uid']) + +welcome_txt = """ +## %(company)s + +Dear %(first_name)s %(last_name)s + +Welcome! + +A new account has been created for you, here are your details: + +login-id: %(user)s +password: %(password)s + +To login to your new ERPNext account, please go to: + +%(account_url)s +""" \ No newline at end of file diff --git a/erpnext/utilities/page/users/users.txt b/erpnext/utilities/page/users/users.txt new file mode 100644 index 0000000000..165cc1695b --- /dev/null +++ b/erpnext/utilities/page/users/users.txt @@ -0,0 +1,28 @@ +# Page, users +[ + + # These values are common in all dictionaries + { + 'creation': '2012-02-28 10:29:39', + 'docstatus': 0, + 'modified': '2012-02-28 10:29:39', + 'modified_by': u'Administrator', + 'owner': u'Administrator' + }, + + # These values are common for all Page + { + 'doctype': 'Page', + 'module': u'Utilities', + 'name': '__common__', + 'page_name': u'users', + 'standard': u'Yes', + 'title': u'Users' + }, + + # Page, users + { + 'doctype': 'Page', + 'name': u'users' + } +] \ No newline at end of file diff --git a/version.num b/version.num index 8c28da60d7..5cd7ca2206 100644 --- a/version.num +++ b/version.num @@ -1 +1 @@ -747 \ No newline at end of file +748 \ No newline at end of file