跳转至内容
  • 版块
  • 标签
  • 热门
  • 用户
  • 群组
皮肤
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • 默认(Flatly)
  • 不使用皮肤
折叠

Odoo 中文社区

  1. 主页
  2. 版块
  3. Odoo 开发与实施交流
  4. 对HR模块的一些扩展(用户和部门之间的关系)

对HR模块的一些扩展(用户和部门之间的关系)

已定时 已固定 已锁定 已移动 Odoo 开发与实施交流
12 帖子 7 发布者 10.4k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • B 离线
    B 离线
    bingsun8208
    写于 最后由 编辑
    #1

    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 />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&#039;department_ids&#039;&nbsp;: fields.function(_get_self_department_ids, type=&#039;many2many&#039;&nbsp;, relation=&nbsp;&quot;hr.department&quot;, string=&nbsp;&quot;部门&quot;&nbsp;),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;child_department_ids&#039;&nbsp;: fields.function(_get_child_ids, type=&#039;many2many&#039;&nbsp;, relation=&nbsp;&quot;hr.department&quot;, string=&nbsp;&quot;子部门集合&quot;&nbsp;),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;parent_department_ids&#039;&nbsp;: fields.function(_get_parent_ids, type=&#039;many2many&#039;&nbsp;, relation=&nbsp;&quot;hr.department&quot;, string=&nbsp;&quot;父部门集合&quot;&nbsp;),<br />
    



    完整代码如下

    <br />class&nbsp;res_users(osv.osv):<br />&nbsp;&nbsp;&nbsp; _name =&nbsp;&#039;res.users&#039;<br />&nbsp;&nbsp;&nbsp; _inherit =&nbsp;&#039;res.users&#039;<br />&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;create(self, cr, uid, data, context=&nbsp;None):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; user_id = super(res_users,&nbsp;self).create(cr, uid, data, context=context)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# add shortcut unless &#039;noshortcut&#039; is True in context<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;not(context&nbsp;and&nbsp;context.get(&#039;noshortcut&#039;,&nbsp;False)):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data_obj =&nbsp;self.pool.get(&#039;ir.model.data&#039;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; data_id = data_obj._get_id(cr, uid,&nbsp;&#039;hr&nbsp;&#039;,&nbsp;&#039;ir_ui_view_sc_employee&#039;&nbsp;)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; view_id&nbsp; = data_obj.browse(cr, uid, data_id, context=context).res_id<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.pool.get(&#039;ir.ui.view_sc&#039;).copy(cr, uid, view_id, default = {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;user_id&#039;: user_id}, context=context)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;except:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Tolerate a missing shortcut. See product/product.py for similar code.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _logger.debug(&nbsp;&#039;Skipped meetings shortcut for user &quot;%s&quot;.&#039;, data.get(&#039;name&#039;,&nbsp;&#039;&lt;new&#039;))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;user_id<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;# 获取用户关联的部门<br />&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;_get_self_department_ids(self, cr, uid, ids, field_name, arg, context=None):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = {}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;user&nbsp;in&nbsp;self.browse(cr, uid, ids, context=context):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;user.employee_ids:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; departs = &#91;]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;emp&nbsp;in&nbsp;user.employee_ids:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; departs.append(emp.department_id)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result[user.id] = departs<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;result<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;# 向下递归,寻找所有子节点<br />&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;_get_child_ids(self, cr, uid, ids, field_name, arg, context=None):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = {}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;user&nbsp;in&nbsp;self.browse(cr, uid, ids, context=context):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;user.employee_ids:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; departs = &#91;]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;emp&nbsp;in&nbsp;user.employee_ids:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sql =&nbsp;&#039;&#039;&#039;<br />WITH RECURSIVE r AS (<br />SELECT * FROM hr_department WHERE id = %d<br />union&nbsp;&nbsp; ALL<br />SELECT hr_department.* FROM hr_department, r WHERE hr_department.parent_id = r.id<br />)<br />SELECT * FROM r where r.id &lt;&gt; %d<br />ORDER BY id;&#039;&#039;&#039;&nbsp;% (emp.department_id.id, emp.department_id.id)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cr.execute(sql)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;depart&nbsp;in&nbsp;cr.fetchall():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; departs.append(depart)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result[user.id] = departs<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;result<br />&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;# 向上递归,寻找所有父节点<br />&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;_get_parent_ids(self, cr, uid, ids, field_name, arg, context=None):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result = {}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;user&nbsp;in&nbsp;self.browse(cr, uid, ids, context=context):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;user.employee_ids:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; departs = &#91;]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;emp&nbsp;in&nbsp;user.employee_ids:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sql =&nbsp;&#039;&#039;&#039;<br />WITH RECURSIVE r AS (<br />SELECT parent_id FROM hr_department WHERE id = %d<br />union&nbsp;&nbsp; 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)&#039;&#039;&#039;&nbsp;% (emp.department_id.id, )<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cr.execute(sql)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;depart&nbsp;in&nbsp;cr.fetchall():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; departs.append(depart)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result[user.id] = departs<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;result<br />&nbsp;&nbsp;&nbsp; _columns = {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;employee_ids&#039;: fields.one2many(&#039;hr.employee&#039;,&nbsp;&#039;user_id&#039;,&nbsp;&#039;Related employees&#039;&nbsp;),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;department_ids&#039;: fields.function(_get_self_department_ids, type=&#039;many2many&#039;&nbsp;, relation=&quot;hr.department&quot;, string=&nbsp;&quot;部门&quot;),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;child_department_ids&#039;: fields.function(_get_child_ids, type=&#039;many2many&#039;&nbsp;, relation=&quot;hr.department&quot;, string=&nbsp;&quot;子部门集合&quot;&nbsp;),<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#039;parent_department_ids&#039;: fields.function(_get_parent_ids, type=&#039;many2many&#039;&nbsp;, relation=&quot;hr.department&quot;, string=&nbsp;&quot;父部门集合&quot;&nbsp;),<br />&nbsp;&nbsp;&nbsp; }<br />res_users()<br />
    


    做完这些工作后,继续对规则进行定义,现在有这样一个场景。
    公司部门结构为上下三层,自己可以看到自己,经理可以看到部门内其他员工但普通员工之间不可互相看到,上级部门的员工可以看到所有下级部门的员工。
    开动,在"设置-技术-安全设定-记录规则"中新建一个全局规则,名字随便取,对象选择为hr.employee,在规则定义( Domain 过滤器)文本框内写入规则:

    <br />&#91;&#039;|&#039;, &#039;|&#039;, (&#039;users_id&#039;, &#039;=&#039;, user.id), (&#039;department_id.manager_id.users_id&#039;, &#039;=&#039;, user.id), (&#039;department_id.id&#039;, &#039;in&#039;, [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个条件都是或者的关系。
    这样,用户再次登录后,规则生效。

    1 条回复 最后回复
    0
    • X 离线
      X 离线
      xiaobaixy
      写于 最后由 编辑
      #2

      这个是谁啊?新手上路就写这么猛的代码...

      1 条回复 最后回复
      0
      • C 离线
        C 离线
        ccdos
        写于 最后由 编辑
        #3

        这 domain写得猛,学习了

        1 条回复 最后回复
        0
        • B 离线
          B 离线
          bingsun8208
          写于 最后由 编辑
          #4

          各位过奖了,呵呵,我就是在群里潜水,还经常问你们问题的。

          这个只是总结了下。

          1 条回复 最后回复
          0
          • J 离线
            J 离线
            Joshua 管理员
            写于 最后由 编辑
            #5

            谢谢分享。看了下代码,res.users继承create方法是用来自动添加shortcut吗?
            对于求所有的子部门,可以直接用[b]child_of[/b]

            child_ids = self.pool.get(&#039;hr.department&#039;).search(cr, uid, [(&#039;id&#039;, &#039;child_of&#039;, emps)])
            

            【上海先安科技】(joshua AT openerp.cn),欢迎关注公众号:openerp_cn

            1 条回复 最后回复
            0
            • B 离线
              B 离线
              bingsun8208
              写于 最后由 编辑
              #6

              谢谢Joshua。child_of我也研究过,但是一直没思路,所以我就自己递归出来的。

              您的这个代码里,emps是一个数组吗,员工本身部门的ID集合?

              res.users里的这个create方法是原来就有的,我只是一起copy出来了。

              1 条回复 最后回复
              0
              • J 离线
                J 离线
                Joshua 管理员
                写于 最后由 编辑
                #7

                [quote author=bingsun8208 link=topic=8095.msg18860#msg18860 date=1375081535]
                您的这个代码里,emps是一个数组吗,员工本身部门的ID集合?
                [/quote]
                是的

                【上海先安科技】(joshua AT openerp.cn),欢迎关注公众号:openerp_cn

                1 条回复 最后回复
                0
                • X 离线
                  X 离线
                  xvweirong
                  写于 最后由 编辑
                  #8

                  Domain规则是Lisp语法吗?

                  1 条回复 最后回复
                  0
                  • Q 离线
                    Q 离线
                    qq342406169
                    写于 最后由 编辑
                    #9

                    Mark,还没研究到HR这块

                    1 条回复 最后回复
                    0
                    • C 离线
                      C 离线
                      ccdos
                      写于 最后由 编辑
                      #10

                      [quote author=xvweirong link=topic=8095.msg18867#msg18867 date=1375150804]
                      Domain规则是Lisp语法吗?
                      [/quote]

                      前缀表达式

                      1 条回复 最后回复
                      0
                      • R 离线
                        R 离线
                        rufeng1199
                        写于 最后由 编辑
                        #11

                        学习了,非常好的实践教学啊

                        1 条回复 最后回复
                        0

                        • 登录

                        • 没有帐号? 注册

                        • 登录或注册以进行搜索。
                        • 第一个帖子
                          最后一个帖子
                        0
                        • 版块
                        • 标签
                        • 热门
                        • 用户
                        • 群组