mail_resend_message.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. from odoo import api, fields, models, _, Command
  4. from odoo.exceptions import UserError
  5. class MailResendMessage(models.TransientModel):
  6. _name = 'mail.resend.message'
  7. _description = 'Email resend wizard'
  8. mail_message_id = fields.Many2one('mail.message', 'Message', readonly=True)
  9. partner_ids = fields.One2many('mail.resend.partner', 'resend_wizard_id', string='Recipients')
  10. notification_ids = fields.Many2many('mail.notification', string='Notifications', readonly=True)
  11. can_cancel = fields.Boolean(compute='_compute_can_cancel')
  12. can_resend = fields.Boolean(compute='_compute_can_resend')
  13. partner_readonly = fields.Boolean(compute='_compute_partner_readonly')
  14. @api.depends("partner_ids")
  15. def _compute_can_cancel(self):
  16. self.can_cancel = self.partner_ids.filtered(lambda p: not p.resend)
  17. @api.depends('partner_ids.resend')
  18. def _compute_can_resend(self):
  19. self.can_resend = any([partner.resend for partner in self.partner_ids])
  20. def _compute_partner_readonly(self):
  21. self.partner_readonly = not self.env['res.partner'].check_access_rights('write', raise_exception=False)
  22. @api.model
  23. def default_get(self, fields):
  24. rec = super(MailResendMessage, self).default_get(fields)
  25. message_id = self._context.get('mail_message_to_resend')
  26. if message_id:
  27. mail_message_id = self.env['mail.message'].browse(message_id)
  28. notification_ids = mail_message_id.notification_ids.filtered(lambda notif: notif.notification_type == 'email' and notif.notification_status in ('exception', 'bounce'))
  29. partner_ids = [Command.create({
  30. "partner_id": notif.res_partner_id.id,
  31. "name": notif.res_partner_id.name,
  32. "email": notif.res_partner_id.email,
  33. "resend": True,
  34. "message": notif.format_failure_reason(),
  35. }) for notif in notification_ids]
  36. has_user = any(notif.res_partner_id.user_ids for notif in notification_ids)
  37. if has_user:
  38. partner_readonly = not self.env['res.users'].check_access_rights('write', raise_exception=False)
  39. else:
  40. partner_readonly = not self.env['res.partner'].check_access_rights('write', raise_exception=False)
  41. rec['partner_readonly'] = partner_readonly
  42. rec['notification_ids'] = [Command.set(notification_ids.ids)]
  43. rec['mail_message_id'] = mail_message_id.id
  44. rec['partner_ids'] = partner_ids
  45. else:
  46. raise UserError(_('No message_id found in context'))
  47. return rec
  48. def resend_mail_action(self):
  49. """ Process the wizard content and proceed with sending the related
  50. email(s), rendering any template patterns on the fly if needed. """
  51. for wizard in self:
  52. "If a partner disappeared from partner list, we cancel the notification"
  53. to_cancel = wizard.partner_ids.filtered(lambda p: not p.resend).mapped("partner_id")
  54. to_send = wizard.partner_ids.filtered(lambda p: p.resend).mapped("partner_id")
  55. 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'))
  56. notif_to_cancel.sudo().write({'notification_status': 'canceled'})
  57. if to_send:
  58. message = wizard.mail_message_id
  59. record = self.env[message.model].browse(message.res_id) if message.is_thread_message() else self.env['mail.thread']
  60. email_partners_data = []
  61. recipients_data = self.env['mail.followers']._get_recipient_data(None, 'comment', False, pids=to_send.ids)[0]
  62. for pid, pdata in recipients_data.items():
  63. if pid and pdata.get('notif', 'email') == 'email':
  64. email_partners_data.append(pdata)
  65. record._notify_thread_by_email(
  66. message, email_partners_data,
  67. resend_existing=True,
  68. send_after_commit=False
  69. )
  70. self.mail_message_id._notify_message_notification_update()
  71. return {'type': 'ir.actions.act_window_close'}
  72. def cancel_mail_action(self):
  73. for wizard in self:
  74. for notif in wizard.notification_ids:
  75. notif.filtered(lambda notif: notif.notification_type == 'email' and notif.notification_status in ('exception', 'bounce')).sudo().write({'notification_status': 'canceled'})
  76. wizard.mail_message_id._notify_message_notification_update()
  77. return {'type': 'ir.actions.act_window_close'}
  78. class PartnerResend(models.TransientModel):
  79. _name = 'mail.resend.partner'
  80. _description = 'Partner with additional information for mail resend'
  81. partner_id = fields.Many2one('res.partner', string='Partner', required=True, ondelete='cascade')
  82. name = fields.Char(related='partner_id.name', string='Recipient Name', related_sudo=False, readonly=False)
  83. email = fields.Char(related='partner_id.email', string='Email Address', related_sudo=False, readonly=False)
  84. resend = fields.Boolean(string='Try Again', default=True)
  85. resend_wizard_id = fields.Many2one('mail.resend.message', string="Resend wizard")
  86. message = fields.Char(string='Error message')