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
118 lines
5.5 KiB
Python
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
|