对HR模块的一些扩展(用户和部门之间的关系)
-
HR模块主要包含了hr.employee(员工), hr.department(部门), hr.job(岗位), hr.employee.category(员工分类)对象,以及扩展继承了res.users(用户)对象。
其中hr.employee和res.users对象之间的关系是,hr.employee -> resource.resource -> res.users。但是,在HR模块里,res.users扩展了一个属性,employee_ids用来记录用户关联了哪些员工。
现在我们做些扩展,需要知道用户属于哪些部门,他的上级有哪些部门,下级有哪些部门。
对res_users类进行扩展,_get_self_department_ids函数是用来获取用户关联部门的,_get_parent_ids函数是用来获取用户关联部门的所有父节点(所有的上级部门),_get_child_ids函数是用来获取用户关联部门的所有子节点(所有的下级部门)。
写完这三个函数后,我们在columns中扩展出对应的属性即可。<br /> 'department_ids' : fields.function(_get_self_department_ids, type='many2many' , relation= "hr.department", string= "部门" ),<br /> 'child_department_ids' : fields.function(_get_child_ids, type='many2many' , relation= "hr.department", string= "子部门集合" ),<br /> 'parent_department_ids' : fields.function(_get_parent_ids, type='many2many' , relation= "hr.department", string= "父部门集合" ),<br />
完整代码如下<br />class res_users(osv.osv):<br /> _name = 'res.users'<br /> _inherit = 'res.users'<br /> def create(self, cr, uid, data, context= None):<br /> user_id = super(res_users, self).create(cr, uid, data, context=context)<br /> # add shortcut unless 'noshortcut' is True in context<br /> if not(context and context.get('noshortcut', False)):<br /> data_obj = self.pool.get('ir.model.data')<br /> try:<br /> data_id = data_obj._get_id(cr, uid, 'hr ', 'ir_ui_view_sc_employee' )<br /> view_id = data_obj.browse(cr, uid, data_id, context=context).res_id<br /> self.pool.get('ir.ui.view_sc').copy(cr, uid, view_id, default = {<br /> 'user_id': user_id}, context=context)<br /> except:<br /> # Tolerate a missing shortcut. See product/product.py for similar code.<br /> _logger.debug( 'Skipped meetings shortcut for user "%s".', data.get('name', '<new'))<br /> return user_id<br /> <br /> # 获取用户关联的部门<br /> def _get_self_department_ids(self, cr, uid, ids, field_name, arg, context=None):<br /> result = {}<br /> for user in self.browse(cr, uid, ids, context=context):<br /> if user.employee_ids:<br /> departs = []<br /> for emp in user.employee_ids:<br /> departs.append(emp.department_id)<br /> result[user.id] = departs<br /> return result<br /> <br /> # 向下递归,寻找所有子节点<br /> def _get_child_ids(self, cr, uid, ids, field_name, arg, context=None):<br /> result = {}<br /> for user in self.browse(cr, uid, ids, context=context):<br /> if user.employee_ids:<br /> departs = []<br /> for emp in user.employee_ids:<br /> sql = '''<br />WITH RECURSIVE r AS (<br />SELECT * FROM hr_department WHERE id = %d<br />union ALL<br />SELECT hr_department.* FROM hr_department, r WHERE hr_department.parent_id = r.id<br />)<br />SELECT * FROM r where r.id <> %d<br />ORDER BY id;''' % (emp.department_id.id, emp.department_id.id)<br /> cr.execute(sql)<br /> for depart in cr.fetchall():<br /> departs.append(depart)<br /> result[user.id] = departs<br /> return result<br /> <br /> # 向上递归,寻找所有父节点<br /> def _get_parent_ids(self, cr, uid, ids, field_name, arg, context=None):<br /> result = {}<br /> for user in self.browse(cr, uid, ids, context=context):<br /> if user.employee_ids:<br /> departs = []<br /> for emp in user.employee_ids:<br /> sql = '''<br />WITH RECURSIVE r AS (<br />SELECT parent_id FROM hr_department WHERE id = %d<br />union ALL<br />SELECT hr_department.parent_id FROM hr_department, r WHERE hr_department.id = r.parent_id<br />)<br />SELECT * FROM hr_department where id in (select parent_id from r)''' % (emp.department_id.id, )<br /> cr.execute(sql)<br /> for depart in cr.fetchall():<br /> departs.append(depart)<br /> result[user.id] = departs<br /> return result<br /> _columns = {<br /> 'employee_ids': fields.one2many('hr.employee', 'user_id', 'Related employees' ),<br /> 'department_ids': fields.function(_get_self_department_ids, type='many2many' , relation="hr.department", string= "部门"),<br /> 'child_department_ids': fields.function(_get_child_ids, type='many2many' , relation="hr.department", string= "子部门集合" ),<br /> 'parent_department_ids': fields.function(_get_parent_ids, type='many2many' , relation="hr.department", string= "父部门集合" ),<br /> }<br />res_users()<br />
做完这些工作后,继续对规则进行定义,现在有这样一个场景。
公司部门结构为上下三层,自己可以看到自己,经理可以看到部门内其他员工但普通员工之间不可互相看到,上级部门的员工可以看到所有下级部门的员工。
开动,在"设置-技术-安全设定-记录规则"中新建一个全局规则,名字随便取,对象选择为hr.employee,在规则定义( Domain 过滤器)文本框内写入规则:<br />['|', '|', ('users_id', '=', user.id), ('department_id.manager_id.users_id', '=', user.id), ('department_id.id', 'in', [depart.id[0] for depart in user.child_department_ids])]<br />
我们来解读一下
('users_id', '=', user.id),这个是自己能看到自己
('department_id.manager_id.users_id', '=', user.id),这个是部门经理可以看到部门的所有
('department_id.id', 'in', [depart.id[0] for depart in user.child_department_ids]),这个是员工可以看到所属部门的所有下级部门
两个'|'表示这3个条件都是或者的关系。
这样,用户再次登录后,规则生效。 -
各位过奖了,呵呵,我就是在群里潜水,还经常问你们问题的。
这个只是总结了下。 -
谢谢Joshua。child_of我也研究过,但是一直没思路,所以我就自己递归出来的。
您的这个代码里,emps是一个数组吗,员工本身部门的ID集合?
res.users里的这个create方法是原来就有的,我只是一起copy出来了。 -
Mark,还没研究到HR这块
-
学习了,非常好的实践教学啊