Restrict Employee and Leave Approver to relevant Employee and Leave Application records
diff --git a/hr/doctype/employee/employee.py b/hr/doctype/employee/employee.py
index 46f46da..6684951 100644
--- a/hr/doctype/employee/employee.py
+++ b/hr/doctype/employee/employee.py
@@ -7,13 +7,11 @@
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 @@
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
diff --git a/hr/doctype/employee/employee.txt b/hr/doctype/employee/employee.txt
index 225b485..f8b08e0 100644
--- a/hr/doctype/employee/employee.txt
+++ b/hr/doctype/employee/employee.txt
@@ -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
}
diff --git a/hr/doctype/leave_application/leave_application.txt b/hr/doctype/leave_application/leave_application.txt
index 10c0429..24de6a8 100644
--- a/hr/doctype/leave_application/leave_application.txt
+++ b/hr/doctype/leave_application/leave_application.txt
@@ -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
diff --git a/patches/1312/p02_update_user_properties.py b/patches/1312/p02_update_user_properties.py
index 4ac1ab9..70c500f 100644
--- a/patches/1312/p02_update_user_properties.py
+++ b/patches/1312/p02_update_user_properties.py
@@ -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 @@
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))
\ No newline at end of file
+ # 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))