[FIX] mail: mass mailing to same mail adress

Steps to repoduce:
- Accounting > Customers > Invoices:
	 select several invoices to send
- Action > Send & Print > (deselect Print) > Send & Print

Issue:
- It sends only one invoice per company

Cause:
- the mail_compose_message sets the status of an email as `cancel` when a mail has already been sent to a specific adress mail in the batch

Solution:
- If the use of mass mailing is document-based (e.g.: sending multiple invoices) it will allow to send multiple emails to the same adress

opw-2775121

closes odoo/odoo#88992

X-original-commit: f08685020f6a00d4e10e30ccbcf70c9eb1a764d5
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Yolann Sabaux
2022-04-19 11:12:11 +02:00
committed by Thibault Delavallée
parent 4809d8f596
commit 3c1e464589
5 changed files with 41 additions and 7 deletions
@@ -116,7 +116,10 @@ class AccountInvoiceSend(models.TransientModel):
def _send_email(self):
if self.is_email:
# with_context : we don't want to reimport the file we just exported.
self.composer_id.with_context(no_new_invoice=True, mail_notify_author=self.env.user.partner_id in self.composer_id.partner_ids)._action_send_mail()
self.composer_id.with_context(no_new_invoice=True,
mail_notify_author=self.env.user.partner_id in self.composer_id.partner_ids,
mailing_document_based=True,
)._action_send_mail()
if self.env.context.get('mark_invoice_as_sent'):
#Salesman send posted invoice, without the right to write
#but they should have the right to change this flag
+4 -2
View File
@@ -473,6 +473,8 @@ class MailComposer(models.TransientModel):
blacklist_ids = self._get_blacklist_record_ids(mail_values_dict)
optout_emails = self._get_optout_emails(mail_values_dict)
done_emails = self._get_done_emails(mail_values_dict)
# in case of an invoice e.g.
mailing_document_based = self.env.context.get('mailing_document_based')
for record_id, mail_values in mail_values_dict.items():
recipients = recipients_info[record_id]
@@ -495,7 +497,7 @@ class MailComposer(models.TransientModel):
elif optout_emails and mail_to in optout_emails:
mail_values['state'] = 'cancel'
mail_values['failure_type'] = 'mail_optout'
elif done_emails and mail_to in done_emails:
elif done_emails and mail_to in done_emails and not mailing_document_based:
mail_values['state'] = 'cancel'
mail_values['failure_type'] = 'mail_dup'
# void of falsy values -> error
@@ -505,7 +507,7 @@ class MailComposer(models.TransientModel):
elif not mail_to_normalized or not email_re.findall(mail_to):
mail_values['state'] = 'cancel'
mail_values['failure_type'] = 'mail_email_invalid'
elif done_emails is not None:
elif done_emails is not None and not mailing_document_based:
done_emails.append(mail_to)
return mail_values_dict
@@ -8,6 +8,8 @@ class MailComposeMessage(models.TransientModel):
_inherit = 'mail.compose.message'
def _action_send_mail(self, auto_commit=False):
if self.env.context.get('mark_rfq_as_sent') and self.model == 'purchase.order':
self = self.with_context(mail_notify_author=self.env.user.partner_id in self.partner_ids)
if self.model == 'purchase.order':
self = self.with_context(mailing_document_based=True)
if self.env.context.get('mark_rfq_as_sent'):
self = self.with_context(mail_notify_author=self.env.user.partner_id in self.partner_ids)
return super(MailComposeMessage, self)._action_send_mail(auto_commit=auto_commit)
+4 -2
View File
@@ -8,6 +8,8 @@ class MailComposeMessage(models.TransientModel):
_inherit = 'mail.compose.message'
def _action_send_mail(self, auto_commit=False):
if self.env.context.get('mark_so_as_sent') and self.model == 'sale.order':
self = self.with_context(mail_notify_author=self.env.user.partner_id in self.partner_ids)
if self.model == 'sale.order':
self = self.with_context(mailing_document_based=True)
if self.env.context.get('mark_so_as_sent'):
self = self.with_context(mail_notify_author=self.env.user.partner_id in self.partner_ids)
return super(MailComposeMessage, self)._action_send_mail(auto_commit=auto_commit)
@@ -701,6 +701,31 @@ class TestComposerResultsComment(TestMailComposer):
""" Test global output of composer used in comment mode. Test notably
notification and emails generated during this process. """
@users('employee')
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
def test_mail_composer_document_based(self):
""" Tests a document-based mass mailing with the same address mails
This should be allowed and not considered as duplicate in this context
"""
attachment_data = self._generate_attachments_data(2)
email_to_1 = self.test_record.customer_id.email
self.template.write({
'auto_delete': False, # keep sent emails to check content
'attachment_ids': [(0, 0, a) for a in attachment_data],
'email_to': '%s, %s' % (email_to_1, email_to_1),
'report_name': 'TestReport for {{ object.name }}', # test cursor forces html
'report_template': self.test_report.id,
})
# launch composer in mass mode
composer_form = Form(self.env['mail.compose.message'].with_context(
self._get_web_context(self.test_record, add_web=True,
default_template_id=self.template.id)
))
composer = composer_form.save()
with self.mock_mail_gateway(mail_unlink_sent=False), self.mock_mail_app():
composer.with_context(mailing_document_based=True)._action_send_mail()
self.assertEqual(len(self._mails), 2, 'Should have sent 2 emails.')
@users('employee')
@mute_logger('odoo.tests', 'odoo.addons.mail.models.mail_mail', 'odoo.models.unlink')
def test_mail_composer_notifications_delete(self):