diff --git a/addons/mail/models/mail_followers.py b/addons/mail/models/mail_followers.py index f3398fad2fc..9dc23cb713e 100644 --- a/addons/mail/models/mail_followers.py +++ b/addons/mail/models/mail_followers.py @@ -29,7 +29,7 @@ class Followers(models.Model): res_id = fields.Many2oneReference( 'Related Document ID', index=True, help='Id of the followed resource', model_field='res_model') partner_id = fields.Many2one( - 'res.partner', string='Related Partner', index=True, ondelete='cascade', required=True) + 'res.partner', string='Related Partner', index=True, ondelete='cascade', required=True, domain=[('type', '!=', 'private')]) subtype_ids = fields.Many2many( 'mail.message.subtype', string='Subtype', help="Message subtypes followed, meaning subtypes that will be pushed onto the user's Wall.") diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index 97313b06cc8..b8661a70be6 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -2560,9 +2560,9 @@ class MailThread(models.AbstractModel): self.check_access_rights('write') self.check_access_rule('write') - # filter inactive + # filter inactive and private addresses if partner_ids and not adding_current: - partner_ids = self.env['res.partner'].sudo().search([('id', 'in', partner_ids), ('active', '=', True)]).ids + partner_ids = self.env['res.partner'].sudo().search([('id', 'in', partner_ids), ('active', '=', True), ('type', '!=', 'private')]).ids return self._message_subscribe(partner_ids, subtype_ids, customer_ids=customer_ids) diff --git a/addons/mail/models/res_partner.py b/addons/mail/models/res_partner.py index 0fbad5d9a5e..d31d6846c6c 100644 --- a/addons/mail/models/res_partner.py +++ b/addons/mail/models/res_partner.py @@ -133,7 +133,7 @@ class Partner(models.Model): The return format is a list of partner data (as per returned by `mail_partner_format()`). """ search_dom = expression.OR([[('name', 'ilike', search)], [('email', 'ilike', search)]]) - search_dom = expression.AND([[('active', '=', True)], search_dom]) + search_dom = expression.AND([[('active', '=', True), ('type', '!=', 'private')], search_dom]) if channel_id: search_dom = expression.AND([[('channel_ids', 'in', channel_id)], search_dom]) diff --git a/addons/mail/wizard/invite.py b/addons/mail/wizard/invite.py index 5d31761a929..ffafa2788be 100644 --- a/addons/mail/wizard/invite.py +++ b/addons/mail/wizard/invite.py @@ -39,7 +39,8 @@ class Invite(models.TransientModel): res_model = fields.Char('Related Document Model', required=True, index=True, help='Model of the followed resource') res_id = fields.Integer('Related Document ID', index=True, help='Id of the followed resource') - partner_ids = fields.Many2many('res.partner', string='Recipients', help="List of partners that will be added as follower of the current document.") + partner_ids = fields.Many2many('res.partner', string='Recipients', help="List of partners that will be added as follower of the current document.", + domain=[('type', '!=', 'private')]) message = fields.Html('Message') send_mail = fields.Boolean('Send Email', default=True, help="If checked, the partners will receive an email warning they have been added in the document's followers.") diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py index a3c386cd91c..adb4d701b39 100644 --- a/addons/mail/wizard/mail_compose_message.py +++ b/addons/mail/wizard/mail_compose_message.py @@ -131,7 +131,8 @@ class MailComposer(models.TransientModel): help='Whether the message is an internal note (comment mode only)') partner_ids = fields.Many2many( 'res.partner', 'mail_compose_message_res_partner_rel', - 'wizard_id', 'partner_id', 'Additional Contacts') + 'wizard_id', 'partner_id', 'Additional Contacts', + domain=[('type', '!=', 'private')]) # mass mode options notify = fields.Boolean('Notify followers', help='Notify followers of the document (mass post only)') auto_delete = fields.Boolean('Delete Emails', diff --git a/addons/test_mail/tests/test_mail_followers.py b/addons/test_mail/tests/test_mail_followers.py index ace318df519..bd40e61123b 100644 --- a/addons/test_mail/tests/test_mail_followers.py +++ b/addons/test_mail/tests/test_mail_followers.py @@ -147,6 +147,21 @@ class BaseFollowersTest(TestMailCommon): self.assertEqual(document.message_partner_ids, self.partner_portal, 'No active test: customer not visible') self.assertEqual(document.message_follower_ids.partner_id, self.partner_portal | customer) + @users('employee') + def test_followers_private_address(self): + """ Test standard API does not subscribe private addresses """ + private_address = self.env['res.partner'].sudo().create({ + 'name': 'Private Address', + 'type': 'private', + }) + document = self.env['mail.test.simple'].browse(self.test_record.id) + document.message_subscribe(partner_ids=(self.partner_portal | private_address).ids) + self.assertEqual(document.message_follower_ids.partner_id, self.partner_portal) + + # works through low-level API + document._message_subscribe(partner_ids=(self.partner_portal | private_address).ids) + self.assertEqual(document.message_follower_ids.partner_id, self.partner_portal | private_address) + @tagged('mail_followers') class AdvancedFollowersTest(TestMailCommon):