From b0e7cf9ebed8634a8fc9319fd321cfaa3d846df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Thu, 26 Nov 2020 15:01:13 +0000 Subject: [PATCH] [FW][FIX] mail: fix auto subscribe subtypes computation This commit contains a followup / rewrite / backport of #34150 : * odoo/odoo@16dd3da * odoo/odoo@0b11ed8 Fix: propagate generic internal subtypes from parent to childs with auto subscribe. With this commit, when the user subscribes to internal subtypes like activities on a parent record (e.g. a project) then the user follows them by default on every sub record creation (e.g. all new tasks of this project). Fix: do not reset existing subtypes when changing parent of a record using auto subscribe mechanism. With this commit, when changing subtype subscription from a parent record (e.g. project) avoid resetting all subtypes subscription on existing sub records (e.g. all new tasks of this project). Only new records will use the parent chosen subtypes. This is done through propagation of followers existing policy (see Follower._insert_followers() for more details); Note that fix done here is slightly different from the one done in odoo/odoo@16dd3da as there was some mismatch with internal model-related subtypes. Thix fix will be forward ported and improve the previous one. Task ID-2205643 COM PR #47336 X-original-commit: 01254f06e8ea37887e190758cc479a098591ab8e X-original-pr: odoo/odoo#47336 Co-authored-by: Thibault Delavallee Co-authored-by: Alexandre Khun Co-authored-by: Priyanka kakadiya --- addons/mail/models/mail_message_subtype.py | 20 +++++++++++++------- addons/mail/models/mail_thread.py | 19 +++++++++++++------ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/addons/mail/models/mail_message_subtype.py b/addons/mail/models/mail_message_subtype.py index ee754acdbed..a634c9d61c0 100644 --- a/addons/mail/models/mail_message_subtype.py +++ b/addons/mail/models/mail_message_subtype.py @@ -57,6 +57,9 @@ class MailMessageSubtype(models.Model): @tools.ormcache('model_name') def _get_auto_subscription_subtypes(self, model_name): """ Return data related to auto subscription based on subtype matching. + Here model_name indicates child model (like a task) on which we want to + make subtype matching based on its parents (like a project). + Example with tasks and project : * generic: discussion, res_model = False @@ -65,13 +68,15 @@ class MailMessageSubtype(models.Model): Returned data - * all_ids: all subtypes that are generic or related to task and project - * def_ids: for task, default subtypes ids - * int_ids: for task, internal-only default subtypes ids + * child_ids: all subtypes that are generic or related to task (res_model = False or model_name) + * def_ids: default subtypes ids (either generic or task specific) + * all_int_ids: all internal-only subtypes ids (generic or task or project) * parent: dict(parent subtype id, child subtype id), i.e. {task_new.id: new.id} * relation: dict(parent_model, relation_fields), i.e. {'project.project': ['project_id']} """ - all_ids, def_ids, int_ids, parent, relation = list(), list(), list(), dict(), dict() + child_ids, def_ids = list(), list() + all_int_ids = list() + parent, relation = dict(), dict() subtypes = self.sudo().search([ '|', '|', ('res_model', '=', False), ('res_model', '=', model_name), @@ -79,15 +84,16 @@ class MailMessageSubtype(models.Model): ]) for subtype in subtypes: if not subtype.res_model or subtype.res_model == model_name: - all_ids += subtype.ids + child_ids += subtype.ids if subtype.default: def_ids += subtype.ids elif subtype.relation_field: parent[subtype.id] = subtype.parent_id.id relation.setdefault(subtype.res_model, set()).add(subtype.relation_field) + # required for backward compatibility if subtype.internal: - int_ids += subtype.ids - return all_ids, def_ids, int_ids, parent, relation + all_int_ids += subtype.ids + return child_ids, def_ids, all_int_ids, parent, relation @api.model def default_subtypes(self, model_name): diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 2ea9f9ed872..57f47d94a27 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -2784,9 +2784,10 @@ class MailThread(models.AbstractModel): new_partners, new_channels = dict(), dict() - # fetch auto subscription subtypes data + # return data related to auto subscription based on subtype matching (aka: + # default task subtypes or subtypes from project triggering task subtypes) updated_relation = dict() - all_ids, def_ids, int_ids, parent, relation = self.env['mail.message.subtype']._get_auto_subscription_subtypes(self._name) + child_ids, def_ids, all_int_ids, parent, relation = self.env['mail.message.subtype']._get_auto_subscription_subtypes(self._name) # check effectively modified relation field for res_model, fnames in relation.items(): @@ -2795,15 +2796,21 @@ class MailThread(models.AbstractModel): udpated_fields = [fname for fnames in updated_relation.values() for fname in fnames if updated_values.get(fname)] if udpated_fields: + # fetch "parent" subscription data (aka: subtypes on project to propagate on task) doc_data = [(model, [updated_values[fname] for fname in fnames]) for model, fnames in updated_relation.items()] res = self.env['mail.followers']._get_subscription_data(doc_data, None, None, include_pshare=True, include_active=True) for fid, rid, pid, cid, subtype_ids, pshare, active in res: + # use project.task_new -> task.new link sids = [parent[sid] for sid in subtype_ids if parent.get(sid)] - sids += [sid for sid in subtype_ids if sid not in parent and sid in def_ids or sid in int_ids] + # add checked subtypes matching model_name + sids += [sid for sid in subtype_ids if sid not in parent and sid in child_ids] if pid and active: # auto subscribe only active partners - new_partners[pid] = (set(sids) & set(all_ids)) - set(int_ids) if pshare else set(sids) & set(all_ids) - if cid: - new_channels[cid] = (set(sids) & set(all_ids)) - set(int_ids) + if pshare: # remove internal subtypes for customers + new_partners[pid] = set(sids) - set(all_int_ids) + else: + new_partners[pid] = set(sids) + if cid: # never subscribe channels to internal subtypes + new_channels[cid] = set(sids) - set(all_int_ids) notify_data = dict() res = self._message_auto_subscribe_followers(updated_values, def_ids)