From a003e4d566b15d1d291204f9e070386acd627ce6 Mon Sep 17 00:00:00 2001 From: karuna Date: Tue, 14 Jul 2026 15:19:59 +0530 Subject: [PATCH] updation on project lead from single to many users --- .../project_task_timesheet_extended/hooks.py | 2 +- .../models/project.py | 43 +++++++++++++++++-- .../models/project_task.py | 28 +++++++----- .../security/project_stage_visibility.xml | 2 +- .../security/security.xml | 12 +++--- .../view/project.xml | 2 +- 6 files changed, 66 insertions(+), 23 deletions(-) diff --git a/addons_extensions/project_task_timesheet_extended/hooks.py b/addons_extensions/project_task_timesheet_extended/hooks.py index 7ccc66901..cc55ab674 100644 --- a/addons_extensions/project_task_timesheet_extended/hooks.py +++ b/addons_extensions/project_task_timesheet_extended/hooks.py @@ -117,7 +117,7 @@ def post_init_hook(env): ('project_id.privacy_visibility', '=', 'followers'), '|', '|', - ('project_id.project_lead', '=', user.id), + ('project_id.project_lead', 'in', [user.id]), ('project_id.user_id', '=', user.id), '|', '&', diff --git a/addons_extensions/project_task_timesheet_extended/models/project.py b/addons_extensions/project_task_timesheet_extended/models/project.py index 34bc07c7d..7c751df39 100644 --- a/addons_extensions/project_task_timesheet_extended/models/project.py +++ b/addons_extensions/project_task_timesheet_extended/models/project.py @@ -7,6 +7,37 @@ import pytz class ProjectProject(models.Model): _inherit = 'project.project' + def init(self): + super().init() + self.env.cr.execute(""" + SELECT 1 + FROM information_schema.columns + WHERE table_name = 'project_project' + AND column_name = 'project_lead' + """) + if not self.env.cr.fetchone(): + return + + self.env.cr.execute(""" + SELECT 1 + FROM information_schema.tables + WHERE table_name = 'project_project_lead_rel' + """) + if not self.env.cr.fetchone(): + return + + self.env.cr.execute(""" + INSERT INTO project_project_lead_rel (project_id, user_id) + SELECT project.id, project.project_lead + FROM project_project project + WHERE project.project_lead IS NOT NULL + AND NOT EXISTS ( + SELECT 1 + FROM project_project_lead_rel rel + WHERE rel.project_id = project.id + AND rel.user_id = project.project_lead + ) + """) @api.constrains('name') def _check_duplicate_project_name(self): @@ -340,7 +371,7 @@ class ProjectProject(models.Model): if project.user_id: users_list.append(project.user_id.id) if project.project_lead: - users_list.append(project.project_lead.id) + users_list.extend(project.project_lead.ids) if project.type_ids: for task_stage in project.type_ids: if task_stage.team_id: @@ -1083,8 +1114,14 @@ class ProjectProject(models.Model): return self._get_default_task_stage_templates() - project_lead = fields.Many2one("res.users", string="Project Lead", - domain=lambda self: [('id','in',self.env.ref('project_task_timesheet_extended.role_project_lead').user_ids.ids)]) + project_lead = fields.Many2many( + "res.users", + "project_project_lead_rel", + "project_id", + "user_id", + string="Project Lead", + domain=lambda self: [('id', 'in', self.env.ref('project_task_timesheet_extended.role_project_lead').user_ids.ids)], + ) members_ids = fields.Many2many('res.users', 'project_user_rel', 'project_id', 'user_id', 'Project Members', help="""Project's members are users who can have an access to diff --git a/addons_extensions/project_task_timesheet_extended/models/project_task.py b/addons_extensions/project_task_timesheet_extended/models/project_task.py index ea70716d9..aef6b6633 100644 --- a/addons_extensions/project_task_timesheet_extended/models/project_task.py +++ b/addons_extensions/project_task_timesheet_extended/models/project_task.py @@ -279,7 +279,11 @@ class projectTask(models.Model): administrative_users = self.env['project.role'].search([('role_level','=','administrative')]) first_stage = self.project_id.type_ids.sorted(key=lambda r: r.sequence)[0] create_access_users = first_stage.team_id.team_lead + first_stage.involved_user_ids + administrative_users.user_ids - if (self.project_id.user_id.id != self.env.user.id) and (self.project_id.project_lead.id != self.env.user.id) and self.env.user.id not in list(set(create_access_users.ids)): + if ( + self.project_id.user_id.id != self.env.user.id + and self.env.user not in self.project_id.project_lead + and self.env.user.id not in list(set(create_access_users.ids)) + ): raise ValidationError( "Only Project Manager/Lead can assign/remove assignees" ) @@ -538,7 +542,7 @@ class projectTask(models.Model): create_access_users = administrative_users.user_ids - if current_user.has_group("project.group_project_manager") or current_user == task.project_id.user_id or current_user == task.project_id.project_lead or (current_user.id in list(set(create_access_users.ids)) and task.stage_id.id == first_stage.id): + if current_user.has_group("project.group_project_manager") or current_user == task.project_id.user_id or current_user in task.project_id.project_lead or (current_user.id in list(set(create_access_users.ids)) and task.stage_id.id == first_stage.id): task.has_supervisor_access = True @@ -553,7 +557,7 @@ class projectTask(models.Model): and ( is_admin or current_user == task.project_id.user_id - or current_user == task.project_id.project_lead + or current_user in task.project_id.project_lead ) ) @api.depends('assignees_timelines.estimated_time', 'show_approval_flow') @@ -680,7 +684,7 @@ class projectTask(models.Model): record.can_edit_approval_flow_stages = True current_user = self.env.user if record.project_id: - if record.project_id.user_id != current_user and record.project_id.project_lead != current_user and not current_user.has_group( + if record.project_id.user_id != current_user and current_user not in record.project_id.project_lead and not current_user.has_group( 'project.group_project_manager'): raise UserError(_("Access denied: You do not have sufficient privileges to use this feature.")) record.record_paused = not record.record_paused @@ -721,7 +725,8 @@ class projectTask(models.Model): approval_not_required = False can_skip_approval_stage = ( user in task.involved_user_ids - or user in [project_manager, project_lead] + or user == project_manager + or user in project_lead or user.has_group("project.group_project_manager") or user.has_group("base.group_system") ) @@ -1845,7 +1850,7 @@ class projectTaskTimelines(models.Model): current_user = self.env.user task.has_edit_access = False if current_user.has_group( - "project.group_project_manager") or current_user == task.project_id.user_id or current_user == task.responsible_lead or current_user == task.project_id.project_lead: + "project.group_project_manager") or current_user == task.project_id.user_id or current_user == task.responsible_lead or current_user in task.project_id.project_lead: task.has_edit_access = True @api.depends("project_id", "task_id") @@ -1863,8 +1868,11 @@ class projectTaskTimelines(models.Model): is_first_stage = stage_sequences and task.stage_id.sequence == min(stage_sequences) is_project_user = current_user == project.user_id - is_authorized_user = current_user in [project.user_id, project.project_lead, - record.assigned_to, record.responsible_lead] + is_authorized_user = ( + current_user == project.user_id + or current_user in project.project_lead + or current_user in (record.assigned_to | record.responsible_lead) + ) can_edit = (is_first_stage or is_project_user) and is_authorized_user record.estimated_time_readonly = not can_edit @@ -1893,13 +1901,11 @@ class projectTaskTimelines(models.Model): project_members = rec.project_id.members_ids.filtered(lambda u: u.exists()) partners = rec.project_id.message_partner_ids.mapped('user_ids').filtered(lambda u: u.exists()) project_user = rec.project_id.user_id if rec.project_id.user_id.exists() else False - project_lead = rec.project_id.project_lead if rec.project_id.project_lead.exists() else False - all_ids = ( project_members.ids + partners.ids + ([project_user.id] if project_user else []) + - ([project_lead.id] if project_lead else []) + rec.project_id.project_lead.ids ) rec.team_all_member_ids = list(set(all_ids)) diff --git a/addons_extensions/project_task_timesheet_extended/security/project_stage_visibility.xml b/addons_extensions/project_task_timesheet_extended/security/project_stage_visibility.xml index 2b85be326..b8329f6ec 100644 --- a/addons_extensions/project_task_timesheet_extended/security/project_stage_visibility.xml +++ b/addons_extensions/project_task_timesheet_extended/security/project_stage_visibility.xml @@ -15,7 +15,7 @@ ('involved_users', 'in', user.id), '|', ('project_id.user_id', '=', user.id), - ('project_id.project_lead', '=', user.id) + ('project_id.project_lead', 'in', [user.id]) ] diff --git a/addons_extensions/project_task_timesheet_extended/security/security.xml b/addons_extensions/project_task_timesheet_extended/security/security.xml index 644877c0c..a25b65853 100644 --- a/addons_extensions/project_task_timesheet_extended/security/security.xml +++ b/addons_extensions/project_task_timesheet_extended/security/security.xml @@ -109,7 +109,7 @@ [ '&', '&', '&', ('project_id', '!=', False), - ('project_id.project_lead', '=', user.id), + ('project_id.project_lead', 'in', [user.id]), '|', ('is_generic', '=', True), ('is_generic', '=', False), '|', ('user_ids', 'in', user.id), ('user_ids', 'not in', user.id) ] @@ -221,7 +221,7 @@ ('project_id.privacy_visibility', '=', 'followers'), '|', '|', - ('project_id.project_lead', '=', user.id), + ('project_id.project_lead', 'in', [user.id]), ('project_id.user_id', '=', user.id), '|', '&', @@ -273,7 +273,7 @@ [ '|', '|', - ('project_id.project_lead', '=', user.id), + ('project_id.project_lead', 'in', [user.id]), ('user_id', '=', user.id), ('project_id.user_id', '=', user.id), ] @@ -302,7 +302,7 @@ - + @@ -327,7 +327,7 @@ - + @@ -347,7 +347,7 @@ - + diff --git a/addons_extensions/project_task_timesheet_extended/view/project.xml b/addons_extensions/project_task_timesheet_extended/view/project.xml index de47e0371..e185bbf97 100644 --- a/addons_extensions/project_task_timesheet_extended/view/project.xml +++ b/addons_extensions/project_task_timesheet_extended/view/project.xml @@ -18,7 +18,7 @@ - +