Restrict Employee and Leave Approver to relevant Employee and Leave Application records

This commit is contained in:
Anand Doshi 2013-12-23 19:59:29 +05:30
parent 9b67f4344b
commit 2926651e1c
4 changed files with 78 additions and 49 deletions

View File

@ -7,13 +7,11 @@ import webnotes
from webnotes.utils import getdate, validate_email_add, cstr, cint
from webnotes.model.doc import make_autoname
from webnotes import msgprint, _
import webnotes.permissions
from webnotes.defaults import get_restrictions
from webnotes.model.controller import DocListController
class DocType:
def __init__(self,doc,doclist=[]):
self.doc = doc
self.doclist = doclist
class DocType(DocListController):
def autoname(self):
naming_method = webnotes.conn.get_value("HR Settings", None, "emp_created_by")
if not naming_method:
@ -39,33 +37,36 @@ class DocType:
def on_update(self):
if self.doc.user_id:
self.restrict_user()
self.update_user_default()
self.update_profile()
self.restrict_leave_approver()
def update_user_default(self):
from webnotes.defaults import get_restrictions
if not "HR User" in webnotes.local.user.get_roles():
if not self.doc.user_id in get_restrictions().get("Employee", []):
webnotes.conn.set_default("Employee", self.doc.name, self.doc.user_id, "Restriction")
def restrict_user(self):
"""restrict to this employee for user"""
self.add_restriction_if_required("Employee", self.doc.user_id)
webnotes.conn.set_default("employee", self.doc.name, self.doc.user_id)
def update_user_default(self):
webnotes.conn.set_default("employee_name", self.doc.employee_name, self.doc.user_id)
webnotes.conn.set_default("company", self.doc.company, self.doc.user_id)
self.set_default_leave_approver()
def set_default_leave_approver(self):
employee_leave_approvers = self.doclist.get({"parentfield": "employee_leave_approvers"})
if len(employee_leave_approvers):
webnotes.conn.set_default("leave_approver", employee_leave_approvers[0].leave_approver,
self.doc.user_id)
elif self.doc.reports_to:
from webnotes.profile import Profile
reports_to_user = webnotes.conn.get_value("Employee", self.doc.reports_to, "user_id")
if "Leave Approver" in Profile(reports_to_user).get_roles():
webnotes.conn.set_default("leave_approver", reports_to_user, self.doc.user_id)
def restrict_leave_approver(self):
"""restrict to this employee for leave approver"""
employee_leave_approvers = [d.leave_approver for d in self.doclist.get({"parentfield": "employee_leave_approvers"})]
if self.doc.reports_to and self.doc.reports_to not in employee_leave_approvers:
employee_leave_approvers.append(webnotes.conn.get_value("Employee", self.doc.reports_to, "user_id"))
for user in employee_leave_approvers:
self.add_restriction_if_required("Employee", user)
self.add_restriction_if_required("Leave Application", user)
def add_restriction_if_required(self, doctype, user):
if webnotes.permissions.has_only_non_restrict_role(webnotes.get_doctype(doctype), user) \
and self.doc.name not in get_restrictions(user).get("Employee", []):
webnotes.defaults.add_default("Employee", self.doc.name, user, "Restriction")
def update_profile(self):
# add employee role if missing
if not "Employee" in webnotes.conn.sql_list("""select role from tabUserRole

View File

@ -2,7 +2,7 @@
{
"creation": "2013-03-07 09:04:18",
"docstatus": 0,
"modified": "2013-12-20 19:24:06",
"modified": "2013-12-23 19:35:27",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -760,6 +760,7 @@
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"restrict": 0,
"role": "HR User",
"write": 1
},
@ -767,6 +768,7 @@
"cancel": 1,
"create": 1,
"doctype": "DocPerm",
"restrict": 1,
"role": "HR Manager",
"write": 1
}

View File

@ -2,7 +2,7 @@
{
"creation": "2013-02-20 11:18:11",
"docstatus": 0,
"modified": "2013-12-20 19:24:12",
"modified": "2013-12-23 19:53:41",
"modified_by": "Administrator",
"owner": "Administrator"
},
@ -256,6 +256,7 @@
"permlevel": 0,
"print": 1,
"report": 1,
"restrict": 1,
"role": "HR User",
"submit": 1,
"write": 1

View File

@ -3,51 +3,59 @@
from __future__ import unicode_literals
import webnotes
import webnotes.permissions
import webnotes.model.doctype
import webnotes.defaults
def execute():
webnotes.reload_doc("core", "doctype", "docperm")
update_user_properties()
update_user_match()
add_employee_restrictions_to_leave_approver()
update_permissions()
remove_duplicate_restrictions()
webnotes.defaults.clear_cache()
webnotes.clear_cache()
def update_user_properties():
webnotes.reload_doc("core", "doctype", "docfield")
for d in webnotes.conn.sql("""select parent, defkey, defvalue from tabDefaultValue
for d in webnotes.conn.sql("""select parent, defkey, defvalue from tabDefaultValue
where parent not in ('__global', 'Control Panel')""", as_dict=True):
df = webnotes.conn.sql("""select options from tabDocField
df = webnotes.conn.sql("""select options from tabDocField
where fieldname=%s and fieldtype='Link'""", d.defkey, as_dict=True)
if df:
webnotes.conn.sql("""update tabDefaultValue
set defkey=%s, parenttype='Restriction'
where defkey=%s and
webnotes.conn.sql("""update tabDefaultValue
set defkey=%s, parenttype='Restriction'
where defkey=%s and
parent not in ('__global', 'Control Panel')""", (df[0].options, d.defkey))
def update_user_match():
import webnotes.defaults
doctype_matches = {}
for doctype, match in webnotes.conn.sql("""select parent, `match` from `tabDocPerm`
where `match` like %s""", "%:user"):
where `match` like %s and ifnull(`match`, '')!="leave_approver:user" """, "%:user"):
doctype_matches.setdefault(doctype, []).append(match)
for doctype, user_matches in doctype_matches.items():
# get permissions of this doctype
perms = webnotes.conn.sql("""select role, `match` from `tabDocPerm`
where parent=%s and permlevel=0 and `read`=1""", doctype, as_dict=True)
meta = webnotes.get_doctype(doctype)
# for each user with roles of this doctype, check if match condition applies
for profile in webnotes.conn.sql_list("""select name from `tabProfile`
where enabled=1 and user_type='System User'"""):
roles = webnotes.get_roles(profile)
perms = webnotes.permissions.get_user_perms(meta, "read", profile)
# user does not have required roles
if not perms:
continue
user_match = False
# assume match
user_match = True
for perm in perms:
if perm.role in roles and (perm.match and \
(perm.match.endswith(":user") or perm.match.endswith(":profile"))):
user_match = True
if not perm.match:
# aha! non match found
user_match = False
break
if not user_match:
@ -60,18 +68,35 @@ def update_user_match():
where `{field}`=%s""".format(doctype=doctype, field=match.split(":")[0]), profile):
webnotes.defaults.add_default(doctype, name, profile, "Restriction")
def add_employee_restrictions_to_leave_approver():
from core.page.user_properties import user_properties
# add restrict rights to HR User and HR Manager
webnotes.conn.sql("""update `tabDocPerm` set `restrict`=1 where parent in ('Employee', 'Leave Application')
and role in ('HR User', 'HR Manager') and permlevel=0 and `read`=1""")
webnotes.model.doctype.clear_cache()
# add Employee restrictions (in on_update method)
for employee in webnotes.conn.sql_list("""select name from `tabEmployee`
where exists(select leave_approver from `tabEmployee Leave Approver`
where `tabEmployee Leave Approver`.parent=`tabEmployee`.name)
or ifnull(`reports_to`, '')!=''"""):
webnotes.bean("Employee", employee).save()
def update_permissions():
# clear match conditions other than owner
webnotes.conn.sql("""update tabDocPerm set `match`=''
where ifnull(`match`,'') not in ('', 'owner')""")
def remove_duplicate_restrictions():
# remove duplicate restrictions (if they exist)
for d in webnotes.conn.sql("""select parent, defkey, defvalue,
count(*) as cnt from tabDefaultValue
where parent not in ('__global', 'Control Panel')
for d in webnotes.conn.sql("""select parent, defkey, defvalue,
count(*) as cnt from tabDefaultValue
where parent not in ('__global', 'Control Panel')
group by parent, defkey, defvalue""", as_dict=1):
if d.cnt > 1:
webnotes.conn.sql("""delete from tabDefaultValue where parent=%s, defkey=%s,
defvalue=%s limit %s""", (d.parent, d.defkey, d.defvalue, d.cnt-1))
# order by parenttype so that restriction does not get removed!
webnotes.conn.sql("""delete from tabDefaultValue where parent=%s, defkey=%s,
defvalue=%s order by parenttype limit %s""", (d.parent, d.defkey, d.defvalue, d.cnt-1))