[IMP] mail: improve subscription low-level API readability

Purpose of this commit is to make low-level API of subscribe process a bit
easier to understand and use. Notably some parameters are now defined as
named parameters in order to better understand calls.

LINKS

Task ID-2070632 (main task)
Task ID-2419762 (followup task)
COM PR odoo/odoo#62859
ENT PR odoo/enterprise#15172
UPG PR odoo/upgrade#2005
This commit is contained in:
Thibault Delavallée
2021-03-17 18:22:15 +00:00
parent e5338146e7
commit d08e3676ea
2 changed files with 25 additions and 22 deletions
+10 -9
View File
@@ -205,19 +205,20 @@ GROUP BY fol.id%s%s""" % (
# Private tools methods to generate new subscription
# --------------------------------------------------
def _insert_followers(self, res_model, res_ids, partner_ids, partner_subtypes,
def _insert_followers(self, res_model, res_ids,
partner_ids, subtypes=None,
customer_ids=None, check_existing=True, existing_policy='skip'):
""" Main internal method allowing to create or update followers for documents, given a
res_model and the document res_ids. This method does not handle access rights. This is the
role of the caller to ensure there is no security breach.
:param partner_subtypes: see ``_add_followers``. If not given, default ones are computed.
:param subtypes: see ``_add_followers``. If not given, default ones are computed.
:param customer_ids: see ``_add_default_followers``
:param check_existing: see ``_add_followers``;
:param existing_policy: see ``_add_followers``;
"""
sudo_self = self.sudo().with_context(default_partner_id=False)
if not partner_subtypes: # no subtypes -> default computation, no force, skip existing
if not subtypes: # no subtypes -> default computation, no force, skip existing
new, upd = self._add_default_followers(
res_model, res_ids, partner_ids,
customer_ids=customer_ids,
@@ -226,7 +227,7 @@ GROUP BY fol.id%s%s""" % (
else:
new, upd = self._add_followers(
res_model, res_ids,
partner_ids, partner_subtypes,
partner_ids, subtypes,
check_existing=check_existing,
existing_policy=existing_policy)
if new:
@@ -263,7 +264,7 @@ GROUP BY fol.id%s%s""" % (
return self._add_followers(res_model, res_ids, partner_ids, p_stypes, check_existing=check_existing, existing_policy=existing_policy)
def _add_followers(self, res_model, res_ids, partner_ids, partner_subtypes,
def _add_followers(self, res_model, res_ids, partner_ids, subtypes,
check_existing=False, existing_policy='skip'):
""" Internal method that generates values to insert or update followers. Callers have to
handle the result, for example by making a valid ORM command, inserting or updating directly
@@ -274,7 +275,7 @@ GROUP BY fol.id%s%s""" % (
* second one is a dict which keys are follower ids. Value is a dict of values valid for
updating the related follower record;
:param partner_subtypes: optional subtypes for new partner followers. This
:param subtypes: optional subtypes for new partner followers. This
is a dict whose keys are partner IDs and value subtype IDs for that
partner.
:param channel_subtypes: optional subtypes for new channel followers. This
@@ -312,12 +313,12 @@ GROUP BY fol.id%s%s""" % (
new.setdefault(res_id, list()).append({
'res_model': res_model,
'partner_id': partner_id,
'subtype_ids': [Command.set(partner_subtypes[partner_id])],
'subtype_ids': [Command.set(subtypes[partner_id])],
})
elif existing_policy in ('replace', 'update'):
fol_id, sids = next(((key, val[2]) for key, val in data_fols.items() if val[0] == res_id and val[1] == partner_id), (False, []))
new_sids = set(partner_subtypes[partner_id]) - set(sids)
old_sids = set(sids) - set(partner_subtypes[partner_id])
new_sids = set(subtypes[partner_id]) - set(sids)
old_sids = set(sids) - set(subtypes[partner_id])
update_cmd = []
if fol_id and new_sids:
update_cmd += [Command.link(sid) for sid in new_sids]
+15 -13
View File
@@ -245,7 +245,8 @@ class MailThread(models.AbstractModel):
if not self._context.get('mail_create_nosubscribe'):
for thread in threads:
self.env['mail.followers']._insert_followers(
thread._name, thread.ids, self.env.user.partner_id.ids, None,
thread._name, thread.ids,
self.env.user.partner_id.ids, subtypes=None,
customer_ids=[],
check_existing=False
)
@@ -2581,12 +2582,13 @@ class MailThread(models.AbstractModel):
if not subtype_ids:
self.env['mail.followers']._insert_followers(
self._name, self.ids, partner_ids, None,
self._name, self.ids,
partner_ids, subtypes=None,
customer_ids=customer_ids, check_existing=True, existing_policy='skip')
else:
self.env['mail.followers']._insert_followers(
self._name, self.ids,
partner_ids, dict((pid, subtype_ids) for pid in partner_ids),
partner_ids, subtypes=dict((pid, subtype_ids) for pid in partner_ids),
customer_ids=customer_ids, check_existing=True, existing_policy='replace')
return True
@@ -2698,7 +2700,7 @@ class MailThread(models.AbstractModel):
if not self:
return True
new_partners = dict()
new_partner_subtypes = dict()
# return data related to auto subscription based on subtype matching (aka:
# default task subtypes or subtypes from project triggering task subtypes)
@@ -2715,29 +2717,29 @@ class MailThread(models.AbstractModel):
# 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, include_pshare=True, include_active=True)
for fid, rid, pid, subtype_ids, pshare, active in res:
for _fol_id, _res_id, partner_id, 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)]
# 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
if partner_id and active: # auto subscribe only active partners
if pshare: # remove internal subtypes for customers
new_partners[pid] = set(sids) - set(all_int_ids)
new_partner_subtypes[partner_id] = set(sids) - set(all_int_ids)
else:
new_partners[pid] = set(sids)
new_partner_subtypes[partner_id] = set(sids)
notify_data = dict()
res = self._message_auto_subscribe_followers(updated_values, def_ids)
for pid, sids, template in res:
new_partners.setdefault(pid, sids)
for partner_id, sids, template in res:
new_partner_subtypes.setdefault(partner_id, sids)
if template:
partner = self.env['res.partner'].browse(pid)
partner = self.env['res.partner'].browse(partner_id)
lang = partner.lang if partner else None
notify_data.setdefault((template, lang), list()).append(pid)
notify_data.setdefault((template, lang), list()).append(partner_id)
self.env['mail.followers']._insert_followers(
self._name, self.ids,
list(new_partners), new_partners,
list(new_partner_subtypes), subtypes=new_partner_subtypes,
check_existing=True, existing_policy=followers_existing_policy)
# notify people from auto subscription, for example like assignation