diff --git a/addons/mail/models/mail_thread.py b/addons/mail/models/mail_thread.py index c9058f9db63..6b4ffcd2ecc 100644 --- a/addons/mail/models/mail_thread.py +++ b/addons/mail/models/mail_thread.py @@ -2212,7 +2212,14 @@ class MailThread(models.AbstractModel): } base_mail_values = self._notify_by_email_add_values(base_mail_values) - Mail = self.env['mail.mail'].sudo() + # Clean the context to get rid of residual default_* keys that could cause issues during + # the mail.mail creation. + # Example: 'default_state' would refer to the default state of a previously created record + # from another model that in turns triggers an assignation notification that ends up here. + # This will lead to a traceback when trying to create a mail.mail with this state value that + # doesn't exist. + SafeMail = self.env['mail.mail'].sudo().with_context(clean_context(self._context)) + SafeNotification = self.env['mail.notification'].sudo().with_context(clean_context(self._context)) emails = self.env['mail.mail'].sudo() # loop on groups (customer, portal, user, ... + model specific like group_sale_salesman) @@ -2245,7 +2252,7 @@ class MailThread(models.AbstractModel): if email_to: create_values['email_to'] = email_to create_values.update(base_mail_values) # mail_message_id, mail_server_id, auto_delete, references, headers - email = Mail.create(create_values) + email = SafeMail.create(create_values) if email and recipient_ids: tocreate_recipient_ids = list(recipient_ids) @@ -2272,7 +2279,7 @@ class MailThread(models.AbstractModel): emails |= email if notif_create_values: - self.env['mail.notification'].sudo().create(notif_create_values) + SafeNotification.create(notif_create_values) # NOTE: # 1. for more than 50 followers, use the queue system diff --git a/addons/test_mail/tests/test_mail_followers.py b/addons/test_mail/tests/test_mail_followers.py index fe8c5f38d96..ba2ef2074c8 100644 --- a/addons/test_mail/tests/test_mail_followers.py +++ b/addons/test_mail/tests/test_mail_followers.py @@ -270,6 +270,51 @@ class AdvancedFollowersTest(TestMailCommon): all_defaults) +class AdvancedResponsibleNotifiedTest(TestMailCommon): + def setUp(self): + super(AdvancedResponsibleNotifiedTest, self).setUp() + + # patch registry to simulate a ready environment so that _message_auto_subscribe_notify + # will be executed with the associated notification + old = self.env.registry.ready + self.env.registry.ready = True + self.addCleanup(setattr, self.env.registry, 'ready', old) + + def test_auto_subscribe_notify_email(self): + """ Responsible is notified when assigned """ + partner = self.env['res.partner'].create({"name": "demo1", "email": "demo1@test.com"}) + notified_user = self.env['res.users'].create({ + 'login': 'demo1', + 'partner_id': partner.id, + 'notification_type': 'email', + }) + + # TODO master: add a 'state' selection field on 'mail.test.track' with a 'done' value to have a complete test + # check that 'default_state' context does not collide with mail.mail default values + sub = self.env['mail.test.track'].with_user(self.user_employee).with_context({ + 'default_state': 'done', + 'mail_notify_force_send': False + }).create({ + 'name': 'Test', + 'user_id': notified_user.id, + }) + + self.assertEqual(sub.message_partner_ids, (self.user_employee.partner_id | notified_user.partner_id)) + # fetch created "You have been assigned to 'Test'" mail.message + mail_message = self.env['mail.message'].search([ + ('model', '=', 'mail.test.track'), + ('res_id', '=', sub.id), + ('partner_ids', 'in', partner.id), + ]) + self.assertEqual(1, len(mail_message)) + + # verify that a mail.mail is attached to it with the correct state ('outgoing') + mail_notification = mail_message.notification_ids + self.assertEqual(1, len(mail_notification)) + self.assertTrue(bool(mail_notification.mail_id)) + self.assertEqual('outgoing', mail_notification.mail_id.state) + + @tagged('post_install', '-at_install') class DuplicateNotificationTest(TestMailCommon): def test_no_duplicate_notification(self):