Files
odoo_source/addons/event/event_mail.py
T
Denis Ledoux 54eff11470 [FIX] event: send event mails for registration without date_open
date_open is not a required field of event.registration.
There is therefore very likely that this field could
not be defined. We should therefore not rely on the fact
it is always defined.

When trying to sent an event mail for an event registration
with a date_open not set (false), the email wasn't sent,
and it prevented the rest of the event mail queue to be
sent as well.

opw-632549
2015-04-10 17:31:47 +02:00

118 lines
5.5 KiB
Python

# -*- coding: utf-8 -*-
from datetime import datetime
from dateutil.relativedelta import relativedelta
from openerp import api, fields, models, tools
_INTERVALS = {
'hours': lambda interval: relativedelta(hours=interval),
'days': lambda interval: relativedelta(days=interval),
'weeks': lambda interval: relativedelta(days=7*interval),
'months': lambda interval: relativedelta(months=interval),
'now': lambda interval: relativedelta(hours=0),
}
class EventMailScheduler(models.Model):
""" Event automated mailing. This model replaces all existing fields and
configuration allowing to send emails on events since Odoo 9. A cron exists
that periodically checks for mailing to run. """
_name = 'event.mail'
event_id = fields.Many2one('event.event', string='Event', required=True, ondelete='cascade')
sequence = fields.Integer('Display order')
interval_nbr = fields.Integer('Interval', default=1)
interval_unit = fields.Selection([
('now', 'Immediately'),
('hours', 'Hour(s)'), ('days', 'Day(s)'),
('weeks', 'Week(s)'), ('months', 'Month(s)')],
string='Unit', default='hours', required=True)
interval_type = fields.Selection([
('after_sub', 'After each subscription'),
('before_event', 'Before the event'),
('after_event', 'After the event')],
string='When to Run ', default="before_event", required=True)
template_id = fields.Many2one(
'mail.template', string='Email to Send',
domain=[('model', '=', 'event.registration')], required=True, ondelete='restrict',
help='This field contains the template of the mail that will be automatically sent')
scheduled_date = fields.Datetime('Scheduled Sent Mail', compute='_compute_scheduled_date', store=True)
mail_registration_ids = fields.One2many('event.mail.registration', 'scheduler_id')
mail_sent = fields.Boolean('Mail Sent on Event')
done = fields.Boolean('Sent', compute='_compute_done', store=True)
@api.one
@api.depends('mail_sent', 'interval_type', 'event_id.registration_ids', 'mail_registration_ids')
def _compute_done(self):
if self.interval_type in ['before_event', 'after_event']:
self.done = self.mail_sent
else:
self.done = len(self.mail_registration_ids) == len(self.event_id.registration_ids) and all(filter(lambda line: line.mail_sent, self.mail_registration_ids))
@api.one
@api.depends('event_id.state', 'event_id.date_begin', 'interval_type', 'interval_unit', 'interval_nbr')
def _compute_scheduled_date(self):
if self.event_id.state not in ['confirm', 'done']:
self.scheduled_date = False
else:
if self.interval_type == 'after_sub':
date, sign = self.event_id.create_date, 1
elif self.interval_type == 'before_event':
date, sign = self.event_id.date_begin, -1
else:
date, sign = self.event_id.date_end, 1
self.scheduled_date = datetime.strptime(date, tools.DEFAULT_SERVER_DATETIME_FORMAT) + _INTERVALS[self.interval_unit](sign * self.interval_nbr)
@api.one
def execute(self):
if self.interval_type == 'after_sub':
# update registration lines
lines = []
for registration in filter(lambda item: item not in [mail_reg.registration_id for mail_reg in self.mail_registration_ids], self.event_id.registration_ids):
lines.append((0, 0, {'registration_id': registration.id}))
if lines:
self.write({'mail_registration_ids': lines})
# execute scheduler on registrations
self.mail_registration_ids.filtered(lambda reg: reg.scheduled_date and reg.scheduled_date <= datetime.strftime(fields.datetime.now(), tools.DEFAULT_SERVER_DATETIME_FORMAT)).execute()
else:
if not self.mail_sent:
self.event_id.mail_attendees(self.template_id.id)
self.write({'mail_sent': True})
return True
@api.model
def run(self):
schedulers = self.search([('done', '=', False), ('scheduled_date', '<=', datetime.strftime(fields.datetime.now(), tools.DEFAULT_SERVER_DATETIME_FORMAT))])
return schedulers.execute()
class EventMailRegistration(models.Model):
_name = 'event.mail.registration'
_description = 'Registration Mail Scheduler'
_rec_name = 'scheduler_id'
_order = 'scheduled_date DESC'
scheduler_id = fields.Many2one('event.mail', 'Mail Scheduler', required=True, ondelete='cascade')
registration_id = fields.Many2one('event.registration', 'Attendee', required=True, ondelete='cascade')
scheduled_date = fields.Datetime('Scheduled Time', compute='_compute_scheduled_date', store=True)
mail_sent = fields.Boolean('Mail Sent')
@api.one
def execute(self):
if self.registration_id.state in ['open', 'done'] and not self.mail_sent:
self.scheduler_id.template_id.send_mail(self.registration_id.id)
self.write({'mail_sent': True})
@api.one
@api.depends('registration_id', 'scheduler_id.interval_unit', 'scheduler_id.interval_type')
def _compute_scheduled_date(self):
if self.registration_id:
date_open = self.registration_id.date_open
date_open_datetime = date_open and datetime.strptime(date_open, tools.DEFAULT_SERVER_DATETIME_FORMAT) or fields.datetime.now()
self.scheduled_date = date_open_datetime + _INTERVALS[self.scheduler_id.interval_unit](self.scheduler_id.interval_nbr)
else:
self.scheduled_date = False