mail/wizard/mail_resend_message.py

139 lines
6.7 KiB
Python
Raw Permalink Normal View History

2024-05-03 12:40:35 +03:00
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _, Command
from odoo.exceptions import UserError
class MailResendMessage(models.TransientModel):
_name = 'mail.resend.message'
_description = 'Email resend wizard'
mail_message_id = fields.Many2one('mail.message', 'Message', readonly=True)
partner_ids = fields.One2many('mail.resend.partner', 'resend_wizard_id', string='Recipients')
notification_ids = fields.Many2many('mail.notification', string='Notifications', readonly=True)
can_cancel = fields.Boolean(compute='_compute_can_cancel')
can_resend = fields.Boolean(compute='_compute_can_resend')
partner_readonly = fields.Boolean(compute='_compute_partner_readonly')
@api.depends("partner_ids")
def _compute_can_cancel(self):
self.can_cancel = self.partner_ids.filtered(lambda p: not p.resend)
@api.depends('partner_ids.resend')
def _compute_can_resend(self):
self.can_resend = any([partner.resend for partner in self.partner_ids])
def _compute_partner_readonly(self):
self.partner_readonly = not self.env['res.partner'].check_access_rights('write', raise_exception=False)
@api.model
def default_get(self, fields):
rec = super(MailResendMessage, self).default_get(fields)
message_id = self._context.get('mail_message_to_resend')
if message_id:
mail_message_id = self.env['mail.message'].browse(message_id)
notification_ids = mail_message_id.notification_ids.filtered(lambda notif: notif.notification_type == 'email' and notif.notification_status in ('exception', 'bounce'))
partner_values = [({
"notification_id": notif.id,
"resend": True,
"message": notif.format_failure_reason(),
}) for notif in notification_ids]
# mail.resend.partner need to exist to be able to execute an action
partner_ids = self.env['mail.resend.partner'].create(partner_values).ids
partner_commands = [Command.link(partner_id) for partner_id in partner_ids]
has_user = any(notif.res_partner_id.user_ids for notif in notification_ids)
if has_user:
partner_readonly = not self.env['res.users'].check_access_rights('write', raise_exception=False)
else:
partner_readonly = not self.env['res.partner'].check_access_rights('write', raise_exception=False)
rec['partner_readonly'] = partner_readonly
rec['notification_ids'] = [Command.set(notification_ids.ids)]
rec['mail_message_id'] = mail_message_id.id
rec['partner_ids'] = partner_commands
else:
raise UserError(_('No message_id found in context'))
return rec
def resend_mail_action(self):
""" Process the wizard content and proceed with sending the related
email(s), rendering any template patterns on the fly if needed. """
for wizard in self:
"If a partner disappeared from partner list, we cancel the notification"
to_cancel = wizard.partner_ids.filtered(lambda p: not p.resend).mapped("partner_id")
to_send = wizard.partner_ids.filtered(lambda p: p.resend)
notif_to_cancel = wizard.notification_ids.filtered(lambda notif: notif.notification_type == 'email' and notif.res_partner_id in to_cancel and notif.notification_status in ('exception', 'bounce'))
notif_to_cancel.sudo().write({'notification_status': 'canceled'})
if to_send:
# this will update the notification already
to_send.action_resend()
else:
self.mail_message_id._notify_message_notification_update()
return {'type': 'ir.actions.act_window_close'}
def cancel_mail_action(self):
for wizard in self:
for notif in wizard.notification_ids:
notif.filtered(lambda notif: notif.notification_type == 'email' and notif.notification_status in ('exception', 'bounce')).sudo().write({'notification_status': 'canceled'})
wizard.mail_message_id._notify_message_notification_update()
return {'type': 'ir.actions.act_window_close'}
class PartnerResend(models.TransientModel):
_name = 'mail.resend.partner'
_description = 'Partner with additional information for mail resend'
notification_id = fields.Many2one('mail.notification', string='Notification', required=True, ondelete='cascade')
partner_id = fields.Many2one('res.partner', string='Partner', related='notification_id.res_partner_id')
name = fields.Char(related='partner_id.name', string='Recipient Name', related_sudo=False, readonly=False)
email = fields.Char(related='partner_id.email', string='Email Address', related_sudo=False, readonly=False)
failure_reason = fields.Text('Failure Reason', related='notification_id.failure_reason')
resend = fields.Boolean(string='Try Again', default=True)
resend_wizard_id = fields.Many2one('mail.resend.message', string="Resend wizard")
message = fields.Char(string='Error message')
partner_readonly = fields.Boolean('Partner Readonly', related='resend_wizard_id.partner_readonly')
def action_open_record(self):
self.ensure_one()
message = self.notification_id.mail_message_id
return {
'type': 'ir.actions.act_window',
'res_model': message.model,
'res_id': message.res_id,
'view_ids': [(False, 'form')],
'view_mode': 'form',
'target': 'current',
}
def action_open_resend_partner(self):
self.ensure_one()
action = self.env['ir.actions.act_window']._for_xml_id('mail.mail_resend_partner_action')
action['res_id'] = self.id
return action
def action_resend(self):
message = self.resend_wizard_id.mail_message_id
if len(message) != 1:
raise UserError(_('All partners must belong to the same message'))
recipients_data = self.env['mail.followers']._get_recipient_data(None, 'comment', False, pids=self.partner_id.ids)
email_partners_data = [
pdata
for pid, pdata in recipients_data[0].items()
if pid and pdata.get('notif', 'email') == 'email'
]
record = self.env[message.model].browse(message.res_id) if message.is_thread_message() else self.env['mail.thread']
record._notify_thread_by_email(
message, email_partners_data,
resend_existing=True,
send_after_commit=False
)
message._notify_message_notification_update()
if len(self) == 1:
return self.action_open_record()