[FIX] mail: send emails only once for each batch
If a list of emails is bigger than 500, the email was sent several time to some people. The mail_values content was not reset between each batch, so if 1200 emails are sent, 3 mail.mail records were created for the emails in the first group. closes odoo/odoo#93658 X-original-commit: f838a0cc36e51e0f47daeec6522df8e9832aad2c Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -18,6 +18,7 @@ from odoo.tools import email_normalize, hmac, generate_tracking_message_id
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
# TODO remove me master
|
||||
GROUP_SEND_BATCH_SIZE = 500
|
||||
|
||||
|
||||
@@ -407,7 +408,6 @@ class MailGroup(models.Model):
|
||||
base_url = self.get_base_url()
|
||||
body = self.env['mail.render.mixin']._replace_local_links(message.body)
|
||||
access_token = self._generate_group_access_token()
|
||||
mail_values = []
|
||||
|
||||
# Email added in a dict to be sure to send only once the email to each address
|
||||
member_emails = {
|
||||
@@ -415,7 +415,9 @@ class MailGroup(models.Model):
|
||||
for member in self.member_ids
|
||||
}
|
||||
|
||||
for batch_email_member in tools.split_every(GROUP_SEND_BATCH_SIZE, member_emails.items()):
|
||||
batch_size = int(self.env['ir.config_parameter'].sudo().get_param('mail.session.batch.size', GROUP_SEND_BATCH_SIZE))
|
||||
for batch_email_member in tools.split_every(batch_size, member_emails.items()):
|
||||
mail_values = []
|
||||
for email_member_normalized, email_member in batch_email_member:
|
||||
if email_member_normalized == message.email_from_normalized:
|
||||
# Do not send the email to their author
|
||||
|
||||
@@ -8,6 +8,42 @@ from odoo.tools import mute_logger
|
||||
|
||||
|
||||
class TestMailGroupMessage(TestMailListCommon):
|
||||
|
||||
def test_batch_send(self):
|
||||
"""Test that when someone sends an email to a large group that it is
|
||||
delivered exactly to those people"""
|
||||
self.test_group.write({
|
||||
'access_mode': 'members',
|
||||
'alias_contact': 'followers',
|
||||
'moderation': False,
|
||||
})
|
||||
self.test_group.member_ids.unlink()
|
||||
|
||||
for num in range(42):
|
||||
self.env['mail.group.member'].create({
|
||||
'email': f'emu-{num}@example.com',
|
||||
'mail_group_id': self.test_group.id,
|
||||
})
|
||||
|
||||
self.assertEqual(len(self.test_group.member_ids), 42)
|
||||
|
||||
# force a batch split with a low limit
|
||||
self.env['ir.config_parameter'].sudo().set_param('mail.session.batch.size', 10)
|
||||
|
||||
with self.mock_mail_gateway():
|
||||
self.format_and_process(
|
||||
GROUP_TEMPLATE, self.test_group.member_ids[0].email,
|
||||
self.test_group.alias_id.display_name,
|
||||
subject='Never Surrender', msg_id='<glory.to.the.hypnotoad@localhost>', target_model='mail.group')
|
||||
|
||||
message = self.env['mail.group.message'].search([('mail_message_id.message_id', '=', '<glory.to.the.hypnotoad@localhost>')])
|
||||
self.assertEqual(message.subject, 'Never Surrender', 'Should have created a <mail.group.message>')
|
||||
|
||||
mails = self.env['mail.mail'].search([('mail_message_id', '=', message.mail_message_id.id)])
|
||||
|
||||
# 42 -1 as the sender doesn't get an email
|
||||
self.assertEqual(len(mails), 41, 'Should have send one and only one email per recipient')
|
||||
|
||||
@mute_logger('odoo.addons.mail.models.mail_thread', 'odoo.addons.mail_group.models.mail_group_message')
|
||||
def test_email_duplicated(self):
|
||||
""" Test gateway does not accept two times same incoming email """
|
||||
|
||||
Reference in New Issue
Block a user