event: - added tip - default subscription/reminder/thanks templates for registrations are now using the reply_to defined on the event - fixed check of available seats: use seats_availability field, unlimited events should never trigger the constraint - added a sequence on scheduled emails on events - config: wording improvements - various improvements in event, registration, event_mail and event_report views event_sale: - removed override of seats_max: should not depend on available seats in tickets. Indeed you may have less available places than the sum of seats for each ticket type, for example if you have 0-10 VIP and 0-20 Standard tickets for a 20-seats event. - removed a duplicated view override - added a seats_availability field on tickets, same meaning as on event. - improved event form view: registration tab is now replaced by the tickets tab when tickets are used website_event: - better management of sold-out event in the front-end, when doing registrations website_event_sale: - removed register link on the event kanban view. There is no need to to from the back-end to the front-end from the kanban view. The published button on the event form view already allows to go to the front-end view on the event - better management of sold-out event in the front-end, when doing registrations - fixed a template that was in customize and should not website_event_track: - wording improvements - small improvements in the front-end of tracks
116 lines
5.4 KiB
Python
116 lines
5.4 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:
|
|
self.scheduled_date = datetime.strptime(self.registration_id.date_open, tools.DEFAULT_SERVER_DATETIME_FORMAT) + _INTERVALS[self.scheduler_id.interval_unit](self.scheduler_id.interval_nbr)
|
|
else:
|
|
self.scheduled_date = False
|