[IMP] project: adjust portal visibility followers behavior
Currently, portal followers of a project and its tasks are removed when the project visibility is changed to something else than portal. => We want to keep the behavior, but only when changing the visibility from portal to something else. When the project visibility is changed to portal, we currently add its customer to its followers. => In that case, we also want to add the customer of the tasks to the followers of the corresponding task. When the customer of a project in portal visibility is changed, the new customer is added to the followers of the project. => We want to remove this behavior. When a project is created with a customer and the portal visibility, the customer is added to the followers of the project. => We want to remove this behavior to avoid mistakenly showing a project that is not ready yet to the customer. This commit implements those changes, and also adds a warning when changing the visibility of the project if that change will automatically add/remove followers to the project and its tasks. Related: https://github.com/odoo/enterprise/pull/25800 Task-2812551 closes odoo/odoo#87747 Related: odoo/enterprise#25800 Signed-off-by: Laurent Stukkens (ltu) <ltu@odoo.com>
This commit is contained in:
@@ -340,6 +340,7 @@ class Project(models.Model):
|
||||
"When a project is shared in edit, the portal user is redirected to the kanban and list views of the tasks. They can modify a selected number of fields on the tasks.\n\n"
|
||||
"In any case, an internal user with no project access rights can still access a task, "
|
||||
"provided that they are given the corresponding URL (and that they are part of the followers if the project is private).")
|
||||
privacy_visibility_warning = fields.Char('Privacy Visibility Warning', compute='_compute_privacy_visibility_warning')
|
||||
doc_count = fields.Integer(compute='_compute_attached_docs_count', string="Number of documents attached")
|
||||
date_start = fields.Date(string='Start Date')
|
||||
date = fields.Date(string='Expiration Date', index=True, tracking=True)
|
||||
@@ -510,6 +511,18 @@ class Project(models.Model):
|
||||
for project in self:
|
||||
project.collaborator_count = collaborator_count_by_project.get(project.id, 0)
|
||||
|
||||
@api.depends('privacy_visibility')
|
||||
def _compute_privacy_visibility_warning(self):
|
||||
for project in self:
|
||||
if not project.ids:
|
||||
project.privacy_visibility_warning = ''
|
||||
elif project.privacy_visibility == 'portal' and project._origin.privacy_visibility != 'portal':
|
||||
project.privacy_visibility_warning = _('Customers will be added to the followers of their project and tasks.')
|
||||
elif project.privacy_visibility != 'portal' and project._origin.privacy_visibility == 'portal':
|
||||
project.privacy_visibility_warning = _('Portal users will be removed from the followers of the project and its tasks.')
|
||||
else:
|
||||
project.privacy_visibility_warning = ''
|
||||
|
||||
@api.model
|
||||
def _map_tasks_default_valeus(self, task, project):
|
||||
""" get the default value for the copied task on project duplication """
|
||||
@@ -567,9 +580,6 @@ class Project(models.Model):
|
||||
# Prevent double project creation
|
||||
self = self.with_context(mail_create_nosubscribe=True)
|
||||
projects = super().create(vals_list)
|
||||
for project in projects:
|
||||
if project.privacy_visibility == 'portal' and project.partner_id:
|
||||
project.message_subscribe(project.partner_id.ids)
|
||||
return projects
|
||||
|
||||
def write(self, vals):
|
||||
@@ -587,6 +597,9 @@ class Project(models.Model):
|
||||
'status': vals.get('last_update_status'),
|
||||
})
|
||||
vals.pop('last_update_status')
|
||||
if vals.get('privacy_visibility'):
|
||||
self._change_privacy_visibility(vals['privacy_visibility'])
|
||||
|
||||
res = super(Project, self).write(vals) if vals else True
|
||||
|
||||
if 'allow_recurring_tasks' in vals and not vals.get('allow_recurring_tasks'):
|
||||
@@ -595,11 +608,6 @@ class Project(models.Model):
|
||||
if 'active' in vals:
|
||||
# archiving/unarchiving a project does it on its tasks, too
|
||||
self.with_context(active_test=False).mapped('tasks').write({'active': vals['active']})
|
||||
if vals.get('partner_id') or vals.get('privacy_visibility'):
|
||||
for project in self.filtered(lambda project: project.privacy_visibility == 'portal'):
|
||||
project.message_subscribe(project.partner_id.ids)
|
||||
if vals.get('privacy_visibility'):
|
||||
self._change_privacy_visibility()
|
||||
if 'name' in vals and self.analytic_account_id:
|
||||
projects_read_group = self.env['project.project']._read_group(
|
||||
[('analytic_account_id', 'in', self.analytic_account_id.ids)],
|
||||
@@ -952,15 +960,23 @@ class Project(models.Model):
|
||||
# Privacy
|
||||
# ---------------------------------------------------
|
||||
|
||||
def _change_privacy_visibility(self):
|
||||
def _change_privacy_visibility(self, new_visibility):
|
||||
"""
|
||||
Unsubscribe non-internal users from the project and tasks if the project privacy visibility
|
||||
goes to a value different than 'portal'
|
||||
goes from 'portal' to a different value.
|
||||
If the privacy visibility is set to 'portal', subscribe back project and tasks partners.
|
||||
"""
|
||||
for project in self.filtered(lambda p: p.privacy_visibility != 'portal'):
|
||||
portal_users = project.message_partner_ids.user_ids.filtered('share')
|
||||
project.message_unsubscribe(partner_ids=portal_users.partner_id.ids)
|
||||
project.mapped('tasks')._change_project_privacy_visibility()
|
||||
for project in self:
|
||||
if project.privacy_visibility == new_visibility:
|
||||
continue
|
||||
if new_visibility == 'portal':
|
||||
project.message_subscribe(partner_ids=project.partner_id.ids)
|
||||
for task in project.task_ids.filtered('partner_id'):
|
||||
task.message_subscribe(partner_ids=task.partner_id.ids)
|
||||
elif project.privacy_visibility == 'portal':
|
||||
portal_users = project.message_partner_ids.user_ids.filtered('share')
|
||||
project.message_unsubscribe(partner_ids=portal_users.partner_id.ids)
|
||||
project.tasks._unsubscribe_portal_users()
|
||||
|
||||
# ---------------------------------------------------
|
||||
# Project sharing
|
||||
@@ -2535,10 +2551,8 @@ class Task(models.Model):
|
||||
# ---------------------------------------------------
|
||||
# Privacy
|
||||
# ---------------------------------------------------
|
||||
def _change_project_privacy_visibility(self):
|
||||
for task in self.filtered(lambda t: t.project_privacy_visibility != 'portal'):
|
||||
portal_users = task.message_partner_ids.user_ids.filtered('share')
|
||||
task.message_unsubscribe(partner_ids=portal_users.partner_id.ids)
|
||||
def _unsubscribe_portal_users(self):
|
||||
self.message_unsubscribe(partner_ids=self.message_partner_ids.filtered('user_ids.share').ids)
|
||||
|
||||
# ---------------------------------------------------
|
||||
# Analytic accounting
|
||||
|
||||
@@ -39,6 +39,7 @@ class TestProjectSharingCommon(TestProjectCommon):
|
||||
'partner_id': cls.user_portal.partner_id.id,
|
||||
'type_ids': project_sharing_stages_vals_list,
|
||||
})
|
||||
cls.project_portal.message_subscribe(partner_ids=[cls.partner_portal.id])
|
||||
|
||||
cls.task_cow = cls.env['project.task'].with_context({'mail_create_nolog': True}).create({
|
||||
'name': 'Cow UserTask',
|
||||
|
||||
@@ -544,6 +544,10 @@
|
||||
<field name="analytic_account_id" domain="['|', ('company_id', '=', company_id), ('company_id', '=', False)]" context="{'default_partner_id': partner_id}" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="analytic_tag_ids" groups="analytic.group_analytic_tags" widget="many2many_tags"/>
|
||||
<field name="privacy_visibility" widget="radio"/>
|
||||
<span colspan="2" class="text-muted" attrs="{'invisible':[('privacy_visibility_warning', '=', '')]}">
|
||||
<i class="fa fa-warning">&nbsp;</i>
|
||||
<field name="privacy_visibility_warning" nolabel="1"/>
|
||||
</span>
|
||||
</group>
|
||||
<group>
|
||||
<div name="alias_def" colspan="2" class="pb-2" attrs="{'invisible': [('alias_domain', '=', False)]}">
|
||||
|
||||
Reference in New Issue
Block a user