如何在Odoo 13中实现员工全层级下属自动填充至Many2many字段?
Odoo 13员工档案全层级下属Many2many字段计算方案
问题背景
在Odoo 13员工档案模块中,需实现:
- 新增Many2one字段关联员工自身(上级),配套One2many字段
reportee_ids关联直接下属 - 新增Many2many字段
employee_child_ids,自动填充当前员工的所有层级下属(含子级、孙级等)
员工层级结构
A B C D | | | | / | \ / | \ / | \ / \ E F G H I J K L M N O /|\ /|\ | /\ P Q R S T U V W X
预期效果
- A的
employee_child_ids:E,F,G,P,Q,R,S,T,U - B的
employee_child_ids:H,I,J - C的
employee_child_ids:K,L,M,V - E的
employee_child_ids:P,Q,R - N的
employee_child_ids:W,X
现有代码缺陷
原代码逻辑方向错误(从下往上递归)、数据处理混乱、错误操作关联用户记录,无法实现需求:
reportee_ids = fields.One2many('hr.employee','reporting_officer_id',string="Reportees") employee_child_ids = fields.Many2many('hr.employee') def compute_reportees(self,emp,list1=None): rm_id = emp.reporting_officer_id if list1 is None: list1 = [] if emp.id != rm_id.id: list1 += emp.reportee_ids.ids + rm_id.reportee_ids.ids rm_id.user_id.write({'employee_child_ids':list1}) self.compute_reportees(rm_id,list1) else: return list1
修正方案
核心思路
采用从上往下递归的方式,从当前员工开始,逐层收集所有直接、间接下属的ID,最终赋值给Many2many字段。使用Odoo标准的计算字段模式,确保数据自动更新。
修正后代码
from odoo import models, fields, api class HrEmployee(models.Model): _inherit = 'hr.employee' reporting_officer_id = fields.Many2one('hr.employee', string='上级') reportee_ids = fields.One2many('hr.employee', 'reporting_officer_id', string='直接下属') employee_child_ids = fields.Many2many( 'hr.employee', compute='_compute_all_subordinates', store=True, string='所有下属' ) @api.depends('reportee_ids', 'reportee_ids.reportee_ids') def _compute_all_subordinates(self): """计算所有层级下属的计算方法,依赖字段确保数据自动更新""" for emp in self: subordinate_ids = [] self._collect_subordinates_recursive(emp, subordinate_ids) # 去重后赋值,避免层级异常导致的重复ID emp.employee_child_ids = [(6, 0, list(set(subordinate_ids)))] def _collect_subordinates_recursive(self, emp, subordinate_list): """递归收集所有层级下属ID""" # 添加当前员工的直接下属ID subordinate_list.extend(emp.reportee_ids.ids) # 递归处理每个直接下属的下属 for reportee in emp.reportee_ids: self._collect_subordinates_recursive(reportee, subordinate_list)
代码说明
- 字段定义:明确
reporting_officer_id为上级关联字段,reportee_ids为直接下属的One2many关联,employee_child_ids设为计算字段并开启store=True持久化存储 - 依赖配置:通过
@api.depends指定依赖字段,确保下属层级变动时自动触发计算 - 计算逻辑:
_compute_all_subordinates遍历当前记录集,初始化下属ID列表后调用递归函数_collect_subordinates_recursive先收集当前员工的直接下属,再对每个下属递归调用自身,收集其所有层级下属
- 赋值方式:使用Odoo Many2many字段标准赋值格式
[(6, 0, ids_list)],直接替换所有关联记录 - 去重处理:通过
list(set(subordinate_ids))避免因异常层级结构导致的重复ID
优化建议
- 若员工层级变动频繁,保留
store=True可提升查询性能;若变动极少,可移除store=True改为实时计算 - 如需批量更新历史员工数据,可新增按钮触发批量计算:
def action_batch_update_subordinates(self): all_employees = self.env['hr.employee'].search([]) all_employees._compute_all_subordinates()
内容的提问来源于stack exchange,提问作者KbiR
相关产品推荐
相关产品推荐

