# Copyright 2018 Tecnativa - Pedro M. Baeza # Copyright 2019 Brainbean Apps (https://brainbeanapps.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from odoo import _, api, exceptions, fields, models class ProjectTask(models.Model): _inherit = "project.task" employee_ids = fields.Many2many( comodel_name="hr.employee", string="Linked employees", compute="_compute_employee_ids", store=True, ) hr_category_ids = fields.Many2many( comodel_name="hr.employee.category", string="Employee Categories", domain="[('id', 'in', allowed_hr_category_ids)]", help="Here you can select the employee category suitable to perform " "this task, limiting the selectable users to be assigned to " "those that belongs to that category.", ) allowed_hr_category_ids = fields.Many2many( comodel_name="hr.employee.category", string="Allowed HR categories", compute="_compute_allowed_hr_category_ids", help="Technical field for computing allowed employee categories " "according categories at project level.", ) # This field could have been named allowed_user_ids but a field with # that name already exists in the Odoo core 'project' module allowed_assigned_user_ids = fields.Many2many( comodel_name="res.users", string="Allowed users", compute="_compute_allowed_assigned_user_ids", help="Technical field for computing allowed users according employee " "category.", ) @api.depends("user_ids", "company_id") def _compute_employee_ids(self): for task in self.filtered("user_ids"): task.employee_ids = task.user_ids.employee_ids.filtered( lambda x: x.company_id == task.company_id ) @api.depends("project_id", "project_id.hr_category_ids") def _compute_allowed_hr_category_ids(self): hr_category_obj = self.env["hr.employee.category"] for task in self: if task.project_id.hr_category_ids: task.allowed_hr_category_ids = task.project_id.hr_category_ids else: task.allowed_hr_category_ids = hr_category_obj.search([]) @api.depends("hr_category_ids", "company_id") def _compute_allowed_assigned_user_ids(self): user_obj = self.env["res.users"] for task in self: domain = [] if task.hr_category_ids: domain = [ ("employee_ids.company_id", "=", task.company_id.id), ("employee_ids.category_ids", "in", task.hr_category_ids.ids), ] task.allowed_assigned_user_ids = user_obj.search(domain) @api.constrains("hr_category_ids", "user_ids") def _check_employee_category_user(self): """Check user's employee belong to the selected category.""" for task in self.filtered(lambda x: x.hr_category_ids and x.user_ids): if any( x not in task.employee_ids.category_ids for x in task.hr_category_ids ): raise exceptions.ValidationError( _( "You can't assign a user not belonging to the selected " "employee category." ) ) @api.constrains("hr_category_ids", "project_id") def _check_employee_category_project(self): for task in self.filtered("hr_category_ids"): if task.project_id.hr_category_ids and bool( task.hr_category_ids - task.project_id.hr_category_ids ): raise exceptions.ValidationError( _( "You can't assign a category that is not allowed at " "project level." ) )