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 @@
-
+