diff --git a/addons/calendar/models/calendar_alarm_manager.py b/addons/calendar/models/calendar_alarm_manager.py
index f67a32d5d5e..916ddd7fdc9 100644
--- a/addons/calendar/models/calendar_alarm_manager.py
+++ b/addons/calendar/models/calendar_alarm_manager.py
@@ -183,7 +183,6 @@ class AlarmManager(models.AbstractModel):
for alarm in alarms:
alarm_attendees = attendees.filtered(lambda attendee: attendee.event_id.id in events_by_alarm[alarm.id])
alarm_attendees.with_context(
- mail_notify_force_send=True,
calendar_template_ignore_recurrence=True
)._send_mail_to_attendees(
alarm.mail_template_id,
diff --git a/addons/mail/wizard/mail_compose_message.py b/addons/mail/wizard/mail_compose_message.py
index ac2fde727a2..b2b1ee98b3d 100644
--- a/addons/mail/wizard/mail_compose_message.py
+++ b/addons/mail/wizard/mail_compose_message.py
@@ -104,6 +104,12 @@ class MailComposer(models.TransientModel):
# comment mode by default removes emails
if 'auto_delete' in fields_list and 'auto_delete' not in result and result.get('composition_mode') == 'comment':
result['auto_delete'] = True
+ # batch post mode by default use queues for notifications
+ if 'force_send' in fields_list and 'force_send' not in result:
+ result['force_send'] = (
+ result.get('composition_mode') != 'comment' or
+ len(self._parse_res_ids(result.get('res_ids') or [])) <= 1
+ )
return {
fname: result[fname]
@@ -181,6 +187,8 @@ class MailComposer(models.TransientModel):
auto_delete_keep_log = fields.Boolean(
'Keep Message Copy', default=True,
help='Keep a copy of the email content if emails are removed (mass mailing only)')
+ force_send = fields.Boolean(
+ 'Send mailing or notifications directly')
mail_server_id = fields.Many2one('ir.mail_server', 'Outgoing mail server')
scheduled_date = fields.Char(
'Scheduled Date',
@@ -463,10 +471,8 @@ class MailComposer(models.TransientModel):
post_values_all = self._prepare_mail_values(res_ids)
ActiveModel = self.env[self.model] if self.model and hasattr(self.env[self.model], 'message_post') else self.env['mail.thread']
if self.composition_batch:
- # do not send emails directly but use the queue instead
# add context key to avoid subscribing the author
ActiveModel = ActiveModel.with_context(
- mail_notify_force_send=False,
mail_create_nosubscribe=True,
)
@@ -510,6 +516,8 @@ class MailComposer(models.TransientModel):
# as 'send' does not filter out scheduled mails (only 'process_email_queue'
# does) we need to do it manually
+ if not self.force_send:
+ continue
iter_mails_sudo_tosend = iter_mails_sudo.filtered(
lambda mail: (
not mail.scheduled_date or
@@ -563,6 +571,7 @@ class MailComposer(models.TransientModel):
MAIL
STA - 'auto_delete',
DYN - 'body_html',
+ STA - 'force_send', (notify parameter)
STA - 'model',
DYN - 'recipient_ids', (from partner_ids)
DYN - 'res_id',
@@ -667,6 +676,7 @@ class MailComposer(models.TransientModel):
values.update(
email_add_signature=not bool(self.template_id) and self.email_add_signature,
email_layout_xmlid=self.email_layout_xmlid,
+ force_send=self.force_send,
mail_auto_delete=self.auto_delete,
model_description=model_description,
)
diff --git a/addons/mail/wizard/mail_compose_message_views.xml b/addons/mail/wizard/mail_compose_message_views.xml
index 93078b739ce..bb4f0e31233 100644
--- a/addons/mail/wizard/mail_compose_message_views.xml
+++ b/addons/mail/wizard/mail_compose_message_views.xml
@@ -15,6 +15,7 @@
TemplateBody %s
' % self.test_record.name) + self.assertEqual(composer_form.body, f'TemplateBody {self.test_record.name}
') self.assertFalse(composer_form.composition_batch) self.assertEqual(composer_form.composition_mode, 'comment') self.assertEqual(composer_form.email_from, self.user_employee_2.email_formatted) + self.assertTrue(composer_form.force_send, 'MailComposer: single record post send notifications right away') self.assertEqual(composer_form.mail_server_id, self.mail_server_domain) self.assertEqual(composer_form.model, self.test_record._name) self.assertEqual(composer_form.partner_ids[:], self.partner_1) @@ -219,7 +221,7 @@ class TestComposerForm(TestMailComposer): self.assertFalse(composer_form.reply_to_force_new) self.assertEqual(literal_eval(composer_form.res_ids), self.test_record.ids) self.assertEqual(composer_form.scheduled_date, FieldDatetime.to_string(self.reference_now + timedelta(days=2))) - self.assertEqual(composer_form.subject, 'TemplateSubject %s' % self.test_record.name) + self.assertEqual(composer_form.subject, f'TemplateSubject {self.test_record.name}') self.assertEqual(composer_form.subtype_id, self.env.ref('mail.mt_comment')) self.assertFalse(composer_form.subtype_is_log) @@ -242,6 +244,7 @@ class TestComposerForm(TestMailComposer): self.assertEqual(composer_form.composition_mode, 'comment') self.assertEqual(composer_form.email_from, self.template.email_from, 'MailComposer: comment in batch mode should have template raw email_from if template') + self.assertFalse(composer_form.force_send, 'MailComposer: batch record post use email queue for notifications') self.assertEqual(composer_form.mail_server_id, self.mail_server_domain) self.assertEqual(composer_form.model, self.test_record._name) self.assertFalse(composer_form.record_name, 'MailComposer: comment in batch mode should have void record name') @@ -270,6 +273,7 @@ class TestComposerForm(TestMailComposer): self.assertFalse(composer_form.composition_batch) self.assertEqual(composer_form.composition_mode, 'comment') self.assertEqual(composer_form.email_from, self.env.user.partner_id.email_formatted) + self.assertTrue(composer_form.force_send) self.assertEqual(composer_form.mail_server_id, self.mail_server_domain) self.assertEqual(composer_form.model, self.test_record._name) self.assertFalse(composer_form.partner_ids[:]) @@ -296,6 +300,7 @@ class TestComposerForm(TestMailComposer): self.assertTrue(composer_form.composition_batch) self.assertEqual(composer_form.composition_mode, 'mass_mail') self.assertEqual(composer_form.email_from, self.env.user.email_formatted) + self.assertTrue(composer_form.force_send, 'MailComposer: mass mode sends emails right away') self.assertFalse(composer_form.mail_server_id) self.assertEqual(composer_form.model, self.test_records._name) self.assertFalse(composer_form.record_name, 'MailComposer: mass mode should have void record name') @@ -321,6 +326,7 @@ class TestComposerForm(TestMailComposer): self.assertEqual(composer_form.composition_mode, 'mass_mail') self.assertEqual(composer_form.email_from, self.template.email_from, 'MailComposer: mass mode should have template raw email_from if template') + self.assertTrue(composer_form.force_send, 'MailComposer: mass mode sends emails right away') self.assertEqual(composer_form.mail_server_id, self.mail_server_domain) self.assertEqual(composer_form.model, self.test_records._name) self.assertFalse(composer_form.record_name, 'MailComposer: mass mode should have void record name') @@ -351,6 +357,7 @@ class TestComposerForm(TestMailComposer): self.assertEqual(composer_form.composition_mode, 'mass_mail') self.assertEqual(composer_form.email_from, self.template.email_from, 'MailComposer: mass mode should have template raw email_from if template') + self.assertTrue(composer_form.force_send, 'MailComposer: mass mode sends emails right away') self.assertEqual(composer_form.mail_server_id, self.mail_server_domain) self.assertEqual(composer_form.model, self.test_records._name) self.assertFalse(composer_form.record_name, 'MailComposer: mass mode should have void record name') @@ -1347,9 +1354,16 @@ class TestComposerResultsComment(TestMailComposer, CronMixinCase): # and 5 emails, and 1 inbox notification (admin) self.assertEqual(len(self._new_mails), 2 * len(test_records), 'Should have created 1 mail.mail per group per record') - self.assertEqual(self._new_mails.mapped('state'), ['sent'] * len(self._new_mails)) - self.assertEqual(len(self._mails), 5 * len(test_records), - 'Should have sent 5 emails, one per recipient per record') + if not batch: + self.assertEqual(self._new_mails.mapped('state'), ['sent'] * len(self._new_mails)) + self.assertEqual(len(self._mails), 5, + 'Should have sent 5 emails, one per recipient per record') + else: + self.assertEqual(self._new_mails.mapped('state'), ['outgoing'] * len(self._new_mails)) + self.assertEqual(len(self._mails), 0, + 'Should have kept force_send False parameter, and not sent any email') + # simulate cron sending emails + self.env['mail.mail'].sudo().process_email_queue() # template is sent only to partners (email_to are transformed) for test_record in test_records: