summaryrefslogtreecommitdiff
path: root/addons/mail/models/mail_notification.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/mail/models/mail_notification.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/mail/models/mail_notification.py')
-rw-r--r--addons/mail/models/mail_notification.py110
1 files changed, 110 insertions, 0 deletions
diff --git a/addons/mail/models/mail_notification.py b/addons/mail/models/mail_notification.py
new file mode 100644
index 00000000..5e87c6ac
--- /dev/null
+++ b/addons/mail/models/mail_notification.py
@@ -0,0 +1,110 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from dateutil.relativedelta import relativedelta
+
+from odoo import api, fields, models
+from odoo.exceptions import AccessError
+from odoo.tools.translate import _
+
+
+class MailNotification(models.Model):
+ _name = 'mail.notification'
+ _table = 'mail_message_res_partner_needaction_rel'
+ _rec_name = 'res_partner_id'
+ _log_access = False
+ _description = 'Message Notifications'
+
+ # origin
+ mail_message_id = fields.Many2one('mail.message', 'Message', index=True, ondelete='cascade', required=True)
+ mail_id = fields.Many2one('mail.mail', 'Mail', index=True, help='Optional mail_mail ID. Used mainly to optimize searches.')
+ # recipient
+ res_partner_id = fields.Many2one('res.partner', 'Recipient', index=True, ondelete='cascade')
+ # status
+ notification_type = fields.Selection([
+ ('inbox', 'Inbox'), ('email', 'Email')
+ ], string='Notification Type', default='inbox', index=True, required=True)
+ notification_status = fields.Selection([
+ ('ready', 'Ready to Send'),
+ ('sent', 'Sent'),
+ ('bounce', 'Bounced'),
+ ('exception', 'Exception'),
+ ('canceled', 'Canceled')
+ ], string='Status', default='ready', index=True)
+ is_read = fields.Boolean('Is Read', index=True)
+ read_date = fields.Datetime('Read Date', copy=False)
+ failure_type = fields.Selection(selection=[
+ ("SMTP", "Connection failed (outgoing mail server problem)"),
+ ("RECIPIENT", "Invalid email address"),
+ ("BOUNCE", "Email address rejected by destination"),
+ ("UNKNOWN", "Unknown error"),
+ ], string='Failure type')
+ failure_reason = fields.Text('Failure reason', copy=False)
+
+ _sql_constraints = [
+ # email notification;: partner is required
+ ('notification_partner_required',
+ "CHECK(notification_type NOT IN ('email', 'inbox') OR res_partner_id IS NOT NULL)",
+ 'Customer is required for inbox / email notification'),
+ ]
+
+ def init(self):
+ self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = %s',
+ ('mail_notification_res_partner_id_is_read_notification_status_mail_message_id',))
+ if not self._cr.fetchone():
+ self._cr.execute("""
+ CREATE INDEX mail_notification_res_partner_id_is_read_notification_status_mail_message_id
+ ON mail_message_res_partner_needaction_rel (res_partner_id, is_read, notification_status, mail_message_id)
+ """)
+
+ @api.model_create_multi
+ def create(self, vals_list):
+ messages = self.env['mail.message'].browse(vals['mail_message_id'] for vals in vals_list)
+ messages.check_access_rights('read')
+ messages.check_access_rule('read')
+ for vals in vals_list:
+ if vals.get('is_read'):
+ vals['read_date'] = fields.Datetime.now()
+ return super(MailNotification, self).create(vals_list)
+
+ def write(self, vals):
+ if ('mail_message_id' in vals or 'res_partner_id' in vals) and not self.env.is_admin():
+ raise AccessError(_("Can not update the message or recipient of a notification."))
+ if vals.get('is_read'):
+ vals['read_date'] = fields.Datetime.now()
+ return super(MailNotification, self).write(vals)
+
+ def format_failure_reason(self):
+ self.ensure_one()
+ if self.failure_type != 'UNKNOWN':
+ return dict(type(self).failure_type.selection).get(self.failure_type, _('No Error'))
+ else:
+ return _("Unknown error") + ": %s" % (self.failure_reason or '')
+
+ @api.model
+ def _gc_notifications(self, max_age_days=180):
+ domain = [
+ ('is_read', '=', True),
+ ('read_date', '<', fields.Datetime.now() - relativedelta(days=max_age_days)),
+ ('res_partner_id.partner_share', '=', False),
+ ('notification_status', 'in', ('sent', 'canceled'))
+ ]
+ return self.search(domain).unlink()
+
+ def _filtered_for_web_client(self):
+ """Returns only the notifications to show on the web client."""
+ return self.filtered(lambda n:
+ n.notification_type != 'inbox' and
+ (n.notification_status in ['bounce', 'exception', 'canceled'] or n.res_partner_id.partner_share)
+ )
+
+ def _notification_format(self):
+ """Returns the current notifications in the format expected by the web
+ client."""
+ return [{
+ 'id': notif.id,
+ 'notification_type': notif.notification_type,
+ 'notification_status': notif.notification_status,
+ 'failure_type': notif.failure_type,
+ 'res_partner_id': [notif.res_partner_id.id, notif.res_partner_id.display_name] if notif.res_partner_id else False,
+ } for notif in self]