From 2b78d430b869f6a0a327bf7e02e2398f1a103a25 Mon Sep 17 00:00:00 2001 From: William Braeckman Date: Wed, 15 Dec 2021 11:25:14 +0000 Subject: [PATCH] [IMP] hr: add a new field to query members of department Adds a new non stored field to make it easier to query all employees from the active user's department and it's children department(s). The result is guaranteed to always contain the active user's employee. task-2700231 closes odoo/odoo#81472 Related: odoo/enterprise#22724 Signed-off-by: Laurent Stukkens (ltu) --- addons/hr/models/hr_employee_base.py | 32 +++++++++++++++++- addons/hr/tests/test_hr_employee.py | 50 ++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/addons/hr/models/hr_employee_base.py b/addons/hr/models/hr_employee_base.py index 3c9b116c276..d0329245d8e 100644 --- a/addons/hr/models/hr_employee_base.py +++ b/addons/hr/models/hr_employee_base.py @@ -3,10 +3,11 @@ from ast import literal_eval -from odoo import api, fields, models from pytz import timezone, UTC, utc from datetime import timedelta +from odoo import _, api, fields, models +from odoo.exceptions import UserError from odoo.tools import format_time @@ -19,6 +20,8 @@ class HrEmployeeBase(models.AbstractModel): active = fields.Boolean("Active") color = fields.Integer('Color Index', default=0) department_id = fields.Many2one('hr.department', 'Department', domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") + member_of_department = fields.Boolean("Member of department", compute='_compute_part_of_department', search='_search_part_of_department', + help="Whether the employee is a member of the active user's department or one of it's child department.") job_id = fields.Many2one('hr.job', 'Job Position', domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") job_title = fields.Char("Job Title", compute="_compute_job_title", store=True, readonly=False) company_id = fields.Many2one('res.company', 'Company') @@ -63,6 +66,33 @@ class HrEmployeeBase(models.AbstractModel): ], string='Employee Type', default='employee', required=True, help="The employee type. Although the primary purpose may seem to categorize employees, this field has also an impact in the Contract History. Only Employee type is supposed to be under contract and will have a Contract History.") + @api.depends_context('uid', 'company') + @api.depends('department_id') + def _compute_part_of_department(self): + active_department = self.env.user.employee_id.department_id + if not active_department: + self.member_of_department = False + else: + def get_all_children(department): + children = department.child_ids + if not children: + return self.env['hr.department'] + return children + get_all_children(children) + + child_departments = active_department + get_all_children(active_department) + for employee in self: + employee.member_of_department = employee.department_id in child_departments + + def _search_part_of_department(self, operator, value): + if operator not in ('=', '!=') or not isinstance(value, bool): + raise UserError(_('Operation not supported')) + # Double negation + if not value: + operator = '=' if operator == '!=' else '=' + if not self.env.user.employee_id.department_id: + return [('id', operator, self.env.user.employee_id.id)] + return (['!'] if operator == '!=' else []) + [('department_id', 'child_of', self.env.user.employee_id.department_id.id)] + @api.depends('user_id.im_status') def _compute_presence_state(self): """ diff --git a/addons/hr/tests/test_hr_employee.py b/addons/hr/tests/test_hr_employee.py index 642aa233409..83d8bf73b95 100644 --- a/addons/hr/tests/test_hr_employee.py +++ b/addons/hr/tests/test_hr_employee.py @@ -69,3 +69,53 @@ class TestHrEmployee(TestHrCommon): def test_employee_has_same_avatar_as_corresponding_user(self): self.assertEqual(self.employee_without_image.avatar_1920, self.user_without_image.avatar_1920) + + def test_employee_member_of_department(self): + dept, dept_sub, dept_sub_sub, dept_other, dept_parent = self.env['hr.department'].create([ + { + 'name': 'main', + }, + { + 'name': 'sub', + }, + { + 'name': 'sub-sub', + }, + { + 'name': 'other', + }, + { + 'name': 'parent', + }, + ]) + dept_sub.parent_id = dept + dept_sub_sub.parent_id = dept_sub + dept.parent_id = dept_parent + emp, emp_sub, emp_sub_sub, emp_other, emp_parent = self.env['hr.employee'].with_user(self.res_users_hr_officer).create([ + { + 'name': 'employee', + 'department_id': dept.id, + }, + { + 'name': 'employee sub', + 'department_id': dept_sub.id, + }, + { + 'name': 'employee sub sub', + 'department_id': dept_sub_sub.id, + }, + { + 'name': 'employee other', + 'department_id': dept_other.id, + }, + { + 'name': 'employee parent', + 'department_id': dept_parent.id, + }, + ]) + self.res_users_hr_officer.employee_id = emp + self.assertTrue(emp.member_of_department) + self.assertTrue(emp_sub.member_of_department) + self.assertTrue(emp_sub_sub.member_of_department) + self.assertFalse(emp_other.member_of_department) + self.assertFalse(emp_parent.member_of_department)