summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorMahendra barad <mba@openerp.com>2014-08-11 19:08:37 +0530
committerThibault Delavallée <tde@openerp.com>2014-10-17 16:48:29 +0200
commitad48bf6d7d7f3c1678b0cd2d55fe64163ad10c38 (patch)
treec4e46963793ed04cda930503aac9ce56aca318d5 /addons
parentfd54df5c7cb4fe2fd606baef347b23ee911f0e2f (diff)
[IMP] [ADD] event: mail schedulign system.
This commit adds a way to configure scheduled emails on events. It replaces existing automatic emails at confirmation and subscription. It proposes to configure some schedulers, based on subscription or event, using a template and a configurable timedelta. A cron is added that regularly checks for event mailing schedulers to execute and launch them. The granularity of send emails is therefore limited to the granularity of the cron, aka 1 hour. [TEST] Added tests for this feature. Also cleaned a bit event, country_id is now a pure related instead of a computed field trying to be a related. Also removed default templates on event category. Configuration in the event itself should be easy enough for most use cases.
Diffstat (limited to 'addons')
-rw-r--r--addons/event/__init__.py1
-rw-r--r--addons/event/email_template.xml79
-rw-r--r--addons/event/event.py102
-rw-r--r--addons/event/event_data.xml19
-rw-r--r--addons/event/event_mail.py111
-rw-r--r--addons/event/event_view.xml75
-rw-r--r--addons/event/security/ir.model.access.csv6
-rw-r--r--addons/event/tests/__init__.py3
-rw-r--r--addons/event/tests/common.py4
-rw-r--r--addons/event/tests/test_event_flow.py4
-rw-r--r--addons/event/tests/test_mail_schedule.py78
11 files changed, 354 insertions, 128 deletions
diff --git a/addons/event/__init__.py b/addons/event/__init__.py
index 9e0115a7300..bf40e48d681 100644
--- a/addons/event/__init__.py
+++ b/addons/event/__init__.py
@@ -20,6 +20,7 @@
##############################################################################
import event
+import event_mail
import wizard
import report
import res_config
diff --git a/addons/event/email_template.xml b/addons/event/email_template.xml
index d4479bcfc87..4a561d38e72 100644
--- a/addons/event/email_template.xml
+++ b/addons/event/email_template.xml
@@ -1,51 +1,48 @@
<?xml version="1.0"?>
<openerp>
<data>
- <record id="confirmation_event" model="email.template">
- <field name="name">Confirmation of the Event</field>
- <field name="model_id" ref="event.model_event_registration"/>
- <field name="email_from" >${(object.user_id.email or object.company_id.email or 'noreply@' + object.company_id.name + '.com')|safe}</field>
- <field name="email_to" >${object.email|safe}</field>
- <field name="subject">Your registration at ${object.event_id.name}</field>
- <field name="body_html"><![CDATA[
- <p>Hello ${object.name},</p>
- <p>The event ${object.event_id.name} that you registered for is confirmed and will be held from ${object.event_id.date_begin_located.strftime('%Y-%m-%d %H:%M:%S (%Z)')} to ${object.event_id.date_end_located.strftime('%Y-%m-%d %H:%M:%S (%Z)')}.
- For any further information please contact our event department.</p>
- <p>Thank you for your participation!</p>
- <p>Best regards</p>]]></field>
- </record>
- </data>
- <data>
-
- <record id="confirmation_registration" model="email.template">
- <field name="name">Confirmation of the Registration</field>
- <field name="model_id" ref="event.model_event_registration"/>
- <field name="email_from" >${(object.user_id.email or object.company_id.email or 'noreply@' + object.company_id.name + '.com')|safe}</field>
- <field name="email_to" >${object.email|safe}</field>
- <field name="subject">Your registration at ${object.event_id.name}</field>
- <field name="body_html"><![CDATA[
- <p>Hello ${object.name},</p>
- <p>We confirm that your registration to the event ${object.event_id.name} has been recorded.
- You will automatically receive an email providing you more practical information (such as the schedule, the agenda...) as soon as the event is confirmed.</p>
- <p>Thank you for your participation!</p>
- <p>Best regards</p>]]></field>
+ <record id="event_subscription" model="email.template">
+ <field name="name">Event subscription</field>
+ <field name="model_id" ref="event.model_event_registration"/>
+ <field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field>
+ <field name="email_to" >${object.email|safe}</field>
+ <field name="subject">Your subscription at ${object.event_id.name}</field>
+ <field name="body_html"><![CDATA[<p>Hello ${object.name},</p>
+<p>We confirm that your subscription to the event ${object.event_id.name} has been recorded.
+You will automatically receive an email providing you more practical information (such as the schedule, the agenda...) as soon as the event is confirmed.</p>
+<p>Thank you for your participation!</p>
+<p>Best regards</p>]]></field>
</record>
- <!-- Default Values -->
- <record model="ir.values" id="default_value_event_mail_confirmation">
- <field name="name">default_email_event</field>
- <field name="key">default</field>
- <field name="key2"></field>
- <field eval="ref('confirmation_event')" name="value_unpickle"/>
- <field name="model">event.type</field>
+ <record id="event_reminder" model="email.template">
+ <field name="name">Event: reminder</field>
+ <field name="model_id" ref="event.model_event_registration"/>
+ <field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field>
+ <field name="email_to" >${object.partner_id.email or object.email|safe}</field>
+ <field name="subject">Reminder of event ${object.event_id.name}</field>
+ <field name="body_html"><![CDATA[<p>Hello ${object.name},</p>
+<p>This is a reminder for ${object.event_id.name} that you registered for is confirmed and will be held from ${object.event_id.date_begin_located} to ${object.event_id.date_end_located}.
+For any further information please contact our event department.</p>
+<p>Thank you for your participation!</p>
+<p>Best regards</p>]]></field>
</record>
- <record model="ir.values" id="default_value_registration_mail_confirmation">
- <field name="name">default_email_registration</field>
- <field name="key">default</field>
- <field name="key2"></field>
- <field eval="ref('confirmation_registration')" name="value_unpickle"/>
- <field name="model">event.type</field>
+
+ <record id="event_thanks" model="email.template">
+ <field name="name">Event: thanks for attending</field>
+ <field name="model_id" ref="event.model_event_registration"/>
+ <field name="email_from">${(object.event_id.organizer_id.email or object.event_id.user_id.email or '')|safe}</field>
+ <field name="email_to" >${object.partner_id.email or object.email|safe}</field>
+ <field name="subject">Thanks for attending ${object.event_id.name}</field>
+ <field name="body_html"><![CDATA[<p>Hello ${object.name},</p>
+<p>We would like to thank you for your presence at our event ${object.event_id.name}.
+<br/><br/>
+ % if object.event_id.organizer_id and object.event_id.organizer_id.is_company:
+ <strong>The ${object.event_id.organizer_id.name} Team</strong>
+ % elif object.event_id.organizer_id:
+ <strong>${object.event_id.organizer_id.name}</strong>
+ % endif
+</p>]]></field>
</record>
</data>
diff --git a/addons/event/event.py b/addons/event/event.py
index 5fded7e15c9..603886906e2 100644
--- a/addons/event/event.py
+++ b/addons/event/event.py
@@ -2,7 +2,7 @@
import pytz
-from openerp import models, fields, api, _
+from openerp import _, api, fields, models
from openerp.exceptions import Warning
@@ -11,21 +11,13 @@ class event_type(models.Model):
_name = 'event.type'
_description = 'Event Type'
- name = fields.Char(string='Event Type', required=True)
- default_reply_to = fields.Char(
- string='Default Reply-To',
- help="The email address of the organizer which is put in the 'Reply-To' of all emails sent automatically at event or registrations confirmation. You can also put your email address of your mail gateway if you use one.")
- default_email_event = fields.Many2one(
- 'email.template', string='Event Confirmation Email',
- help="It will select this default confirmation event mail value when you choose this event")
- default_email_registration = fields.Many2one(
- 'email.template', string='Registration Confirmation Email',
- help="It will select this default confirmation registration mail value when you choose this event")
+ name = fields.Char('Event Type', required=True)
+ default_reply_to = fields.Char('Reply To')
default_registration_min = fields.Integer(
- string='Default Minimum Registration', default=0,
+ 'Default Minimum Registration', default=0,
help="It will select this default minimum value when you choose this event")
default_registration_max = fields.Integer(
- string='Default Maximum Registration', default=0,
+ 'Default Maximum Registration', default=0,
help="It will select this default maximum value when you choose this event")
@@ -54,6 +46,15 @@ class event_event(models.Model):
'event.type', string='Category',
readonly=False, states={'done': [('readonly', True)]})
color = fields.Integer('Kanban Color Index')
+ event_mail_ids = fields.One2many('event.mail', 'event_id', string='Mail Schedule', default=lambda self: self._default_event_mail_ids())
+
+ @api.model
+ def _default_event_mail_ids(self):
+ return [(0, 0, {
+ 'interval_unit': 'now',
+ 'interval_type': 'after_sub',
+ 'template_id': self.env['ir.model.data'].xmlid_to_res_id('event.event_subscription')
+ })]
# Seats and computation
seats_max = fields.Integer(
@@ -154,11 +155,6 @@ class event_event(models.Model):
else:
self.date_end_located = False
- @api.one
- @api.depends('address_id')
- def _compute_country(self):
- self.country_id = self.address_id.country_id
-
state = fields.Selection([
('draft', 'Unconfirmed'), ('cancel', 'Cancelled'),
('confirm', 'Confirmed'), ('done', 'Done')],
@@ -170,23 +166,13 @@ class event_event(models.Model):
def _compute_auto_confirm(self):
self.auto_confirm = self.env['ir.values'].get_default('marketing.config.settings', 'auto_confirmation')
- # Mailing
- email_registration_id = fields.Many2one(
- 'email.template', string='Registration Confirmation Email',
- domain=[('model', '=', 'event.registration')],
- help='This field contains the template of the mail that will be automatically sent each time a registration for this event is confirmed.')
- email_confirmation_id = fields.Many2one(
- 'email.template', string='Event Confirmation Email',
- domain=[('model', '=', 'event.registration')],
- help="If you set an email template, each participant will receive this email announcing the confirmation of the event.")
reply_to = fields.Char(
- string='Reply-To Email', readonly=False, states={'done': [('readonly', True)]},
+ 'Reply-To Email', readonly=False, states={'done': [('readonly', True)]},
help="The email address of the organizer is likely to be put here, with the effect to be in the 'Reply-To' of the mails sent automatically at event or registrations confirmation. You can also put the email address of your mail gateway if you use one.")
address_id = fields.Many2one(
'res.partner', string='Location', default=lambda self: self.env.user.company_id.partner_id,
readonly=False, states={'done': [('readonly', True)]})
- country_id = fields.Many2one('res.country', string='Country',
- store=True, compute='_compute_country')
+ country_id = fields.Many2one('res.country', 'Country', related='address_id.country_id', store=True)
description = fields.Html(
string='Description', oldname='note', translate=True,
readonly=False, states={'done': [('readonly', True)]})
@@ -217,7 +203,7 @@ class event_event(models.Model):
def create(self, vals):
res = super(event_event, self).create(vals)
if res.auto_confirm:
- res.confirm_event()
+ res.button_confirm()
return res
@api.one
@@ -237,26 +223,15 @@ class event_event(models.Model):
self.state = 'done'
@api.one
- def confirm_event(self):
- if self.email_confirmation_id:
- # send reminder that will confirm the event for all the people that were already confirmed
- regs = self.registration_ids.filtered(lambda reg: reg.state not in ('draft', 'cancel'))
- regs.mail_user_confirm()
- self.state = 'confirm'
-
- @api.one
def button_confirm(self):
- """ Confirm Event and send confirmation email to all register peoples """
- self.confirm_event()
+ self.state = 'confirm'
@api.onchange('type')
def _onchange_type(self):
if self.type:
- self.reply_to = self.type.default_reply_to
- self.email_registration_id = self.type.default_email_registration
- self.email_confirmation_id = self.type.default_email_event
self.seats_min = self.type.default_registration_min
self.seats_max = self.type.default_registration_max
+ self.reply_to = self.type.default_reply_to
@api.multi
def action_event_registration_report(self):
@@ -267,6 +242,11 @@ class event_event(models.Model):
}
return res
+ @api.one
+ def mail_attendees(self, template_id, force_send=False, filter_func=lambda self: True):
+ for attendee in self.registration_ids.filtered(filter_func):
+ self.env['email.template'].browse(template_id).send_mail(attendee.id, force_send=force_send)
+
class event_registration(models.Model):
_name = 'event.registration'
@@ -283,9 +263,8 @@ class event_registration(models.Model):
partner_id = fields.Many2one(
'res.partner', string='Contact',
states={'done': [('readonly', True)]})
- date_open = fields.Datetime(string='Registration Date', readonly=True)
+ date_open = fields.Datetime(string='Registration Date', readonly=True, default=lambda self: fields.datetime.now()) # weird crash is directly now
date_closed = fields.Datetime(string='Attended Date', readonly=True)
- reply_to = fields.Char(string='Reply-to Email', related='event_id.reply_to', readonly=True)
event_begin_date = fields.Datetime(string="Event Start Date", related='event_id.date_begin', readonly=True)
event_end_date = fields.Datetime(string="Event End Date", related='event_id.date_end', readonly=True)
company_id = fields.Many2one(
@@ -315,10 +294,10 @@ class event_registration(models.Model):
@api.model
def create(self, vals):
- res = super(event_registration, self).create(vals)
- if res._check_auto_confirmation()[0]:
- res.sudo().confirm_registration()
- return res
+ registration = super(event_registration, self).create(vals)
+ if registration._check_auto_confirmation():
+ registration.sudo().confirm_registration()
+ return registration
@api.one
def do_draft(self):
@@ -332,12 +311,6 @@ class event_registration(models.Model):
self.state = 'open'
@api.one
- def registration_open(self):
- """ Open Registration """
- self.confirm_registration()
- self.mail_user()
-
- @api.one
def button_reg_close(self):
""" Close Registration """
today = fields.Datetime.now()
@@ -350,23 +323,6 @@ class event_registration(models.Model):
def button_reg_cancel(self):
self.state = 'cancel'
- @api.one
- def mail_user(self):
- """Send email to user with email_template when registration is done """
- if self.event_id.state == 'confirm' and self.event_id.email_confirmation_id:
- self.mail_user_confirm()
- else:
- template = self.event_id.email_registration_id
- if template:
- template.send_mail(self.id)
-
- @api.one
- def mail_user_confirm(self):
- """Send email to user when the event is confirmed """
- template = self.event_id.email_confirmation_id
- if template:
- template.send_mail(self.id)
-
@api.onchange('partner_id')
def _onchange_partner(self):
if self.partner_id:
diff --git a/addons/event/event_data.xml b/addons/event/event_data.xml
index 823d6428993..2419132f409 100644
--- a/addons/event/event_data.xml
+++ b/addons/event/event_data.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
+
<!-- After installation of the module, open the related menu -->
<record id="action_client_event_menu" model="ir.actions.client">
<field name="name">Open Event Menu</field>
@@ -21,11 +22,27 @@
<!-- notify all employees of module installation -->
<function model="mail.group" name="message_post">
- <!-- ids, subject, body, parent_id=False, type='notification', content_subtype='html' -->
<value eval="[ref('mail.group_all_employees')]"/>
<value>From the top menu Events, you can organize events, manage registrations, automate communication around your event and sell events through your quotations.</value>
<value>Module Events has been installed</value>
</function>
+
+ <!-- Automatic confirmation of events by default -->
<function id="default_auto_confirmation" model="ir.values" name="set_default" eval="('marketing.config.settings', 'auto_confirmation', True)"/>
+
+ <!-- Event Mail Scheduler-->
+ <record model="ir.cron" forcecreate="True" id="event_mail_scheduler">
+ <field name="name">[event] mail scheduler</field>
+ <field name="active">True</field>
+ <field name="user_id" ref="base.user_root"/>
+ <field name="interval_number">1</field>
+ <field name="interval_type">hours</field>
+ <field name="numbercall">-1</field>
+ <field name="doall" eval="False" />
+ <field eval="'()'" name="args"/>
+ <field name="model">event.mail</field>
+ <field name="function">run</field>
+ </record>
+
</data>
</openerp>
diff --git a/addons/event/event_mail.py b/addons/event/event_mail.py
new file mode 100644
index 00000000000..ea4a9a81e93
--- /dev/null
+++ b/addons/event/event_mail.py
@@ -0,0 +1,111 @@
+# -*- 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, readonly=True, ondelete='cascade')
+ interval_nbr = fields.Integer('Timing', 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(
+ 'email.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):
+ 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)
diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml
index 9371dbe25e9..0991c4bb7af 100644
--- a/addons/event/event_view.xml
+++ b/addons/event/event_view.xml
@@ -16,9 +16,7 @@
<field name="name"/>
<field name="default_reply_to"/>
<field name="default_registration_min"/>
- <field name="default_email_event" domain="[('model_id.model','=','event.registration')]"/>
<field name="default_registration_max"/>
- <field name="default_email_registration" domain="[('model_id.model','=','event.registration')]"/>
</group>
</form>
</field>
@@ -103,12 +101,17 @@
</group>
</group>
</page>
- <page string='Event Details' groups="base.group_no_one">
- <group colspan="4">
- <field name="reply_to"/>
- <field name="email_registration_id"/>
- <field name="email_confirmation_id"/>
- </group>
+ <page string="Email Schedule">
+ <field name="reply_to"/>
+ <field name="event_mail_ids">
+ <tree string="Email Schedule" editable="bottom">
+ <field name="template_id" />
+ <field name="interval_nbr"/>
+ <field name="interval_unit"/>
+ <field name="interval_type"/>
+ <field name="done"/>
+ </tree>
+ </field>
</page>
</notebook>
</sheet>
@@ -294,7 +297,7 @@
<field name="arch" type="xml">
<form string="Event Registration">
<header>
- <button name="registration_open" string="Confirm" states="draft" type="object" class="oe_highlight"/>
+ <button name="confirm_registration" string="Confirm" states="draft" type="object" class="oe_highlight"/>
<button name="button_reg_close" string="Attended" states="open" type="object" class="oe_highlight"/>
<button string="Set To Unconfirmed" name="do_draft" states="cancel,done" type="object" />
<button name="button_reg_cancel" string="Cancel Registration" states="draft,open" type="object"/>
@@ -382,5 +385,59 @@
id="menu_action_registration" parent="event.event_main_menu"
action="action_registration" groups="event.group_event_manager,event.group_event_user"/>
+ <!-- EVENT.MAIL VIEWS -->
+ <record model="ir.ui.view" id="view_event_mail_form">
+ <field name="name">event.mail.form</field>
+ <field name="model">event.mail</field>
+ <field name="arch" type="xml">
+ <form string="Event Mail Scheduler">
+ <group>
+ <field name="event_id"/>
+ <field name="template_id"/>
+ <field name="mail_sent"/>
+ </group>
+ <group>
+ <field name="interval_nbr"/>
+ <field name="interval_unit"/>
+ <field name="interval_type"/>
+ <field name="scheduled_date"/>
+ </group>
+ <notebook>
+ <page string="Registration Mails">
+ <field name="mail_registration_ids">
+ <tree string="Registration mail" editable="bottom">
+ <field name="registration_id"/>
+ <field name="scheduled_date"/>
+ <field name="mail_sent"/>
+ </tree>
+ </field>
+ </page>
+ </notebook>
+ </form>
+ </field>
+ </record>
+
+ <record model="ir.ui.view" id="view_event_mail_tree">
+ <field name="name">event.mail.tree</field>
+ <field name="model">event.mail</field>
+ <field name="arch" type="xml">
+ <tree string="Event Mail Schedulers">
+ <field name="event_id"/>
+ <field name="template_id"/>
+ <field name="scheduled_date"/>
+ <field name="mail_sent"/>
+ <field name="done"/>
+ </tree>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_event_mail">
+ <field name="name">Events Mail Schedulers</field>
+ <field name="res_model">event.mail</field>
+ <field name="view_type">form</field>
+ </record>
+
+ <menuitem name="Events Mail Schedulers" id="menu_event_type" action="action_event_mail" parent="event.event_configuration" groups="base.group_no_one"/>
+
</data>
</openerp>
diff --git a/addons/event/security/ir.model.access.csv b/addons/event/security/ir.model.access.csv
index 1d803796007..8801c173f17 100644
--- a/addons/event/security/ir.model.access.csv
+++ b/addons/event/security/ir.model.access.csv
@@ -5,4 +5,8 @@ access_event_event,event.event,model_event_event,event.group_event_user,1,1,1,1
access_event_registration,event.registration,model_event_registration,event.group_event_user,1,1,1,1
access_report_event_registration,report.event.registration,model_report_event_registration,event.group_event_user,1,1,1,1
access_event_event_portal,event.event,model_event_event,,1,0,0,0
-access_event_registration_portal,event.registration,model_event_registration,,1,0,0,0 \ No newline at end of file
+access_event_registration_portal,event.registration,model_event_registration,,1,0,0,0
+access_event_mail,event.mail,model_event_mail,event.group_event_user,1,0,0,0
+access_event_mail_manager,event.mail manager,model_event_mail,event.group_event_manager,1,1,1,1
+access_event_mail_registration,event.mail.registration,model_event_mail_registration,event.group_event_user,1,0,0,0
+access_event_mail_registration_manager,event.mail.registration.manager,model_event_mail_registration,event.group_event_manager,1,1,1,1 \ No newline at end of file
diff --git a/addons/event/tests/__init__.py b/addons/event/tests/__init__.py
index d1ddc66c11c..abcc4a3ca2b 100644
--- a/addons/event/tests/__init__.py
+++ b/addons/event/tests/__init__.py
@@ -1,7 +1,8 @@
# -*- coding: utf-8 -*-
-from openerp.addons.event.tests import test_event_flow
+from openerp.addons.event.tests import test_event_flow, test_mail_schedule
checks = [
test_event_flow,
+ test_mail_schedule,
]
diff --git a/addons/event/tests/common.py b/addons/event/tests/common.py
index bcf0a1e5df0..1b59c662da6 100644
--- a/addons/event/tests/common.py
+++ b/addons/event/tests/common.py
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
+from dateutil.relativedelta import relativedelta
+
+from openerp import fields
from openerp.tests import common
@@ -12,6 +15,7 @@ class TestEventCommon(common.TransactionCase):
self.Users = self.env['res.users']
self.Event = self.env['event.event']
self.Registration = self.env['event.registration']
+ self.EventMail = self.env['event.mail']
# User groups
self.group_employee_id = self.env['ir.model.data'].xmlid_to_res_id('base.group_user')
diff --git a/addons/event/tests/test_event_flow.py b/addons/event/tests/test_event_flow.py
index 3af0fb9185c..ed5219d4d0a 100644
--- a/addons/event/tests/test_event_flow.py
+++ b/addons/event/tests/test_event_flow.py
@@ -16,7 +16,7 @@ class TestEventFlow(TestEventCommon):
self.env['ir.values'].set_default('marketing.config.settings', 'auto_confirmation', True)
# EventUser creates a new event: ok
- test_event = self.Event.sudo(self.user_eventuser).create({
+ test_event = self.Event.sudo(self.user_eventmanager).create({
'name': 'TestEvent',
'date_begin': datetime.datetime.now() + relativedelta(days=-1),
'date_end': datetime.datetime.now() + relativedelta(days=1),
@@ -68,7 +68,7 @@ class TestEventFlow(TestEventCommon):
self.env['ir.values'].set_default('marketing.config.settings', 'auto_confirmation', False)
# EventUser creates a new event: ok
- test_event = self.Event.sudo(self.user_eventuser).create({
+ test_event = self.Event.sudo(self.user_eventmanager).create({
'name': 'TestEvent',
'date_begin': datetime.datetime.now() + relativedelta(days=-1),
'date_end': datetime.datetime.now() + relativedelta(days=1),
diff --git a/addons/event/tests/test_mail_schedule.py b/addons/event/tests/test_mail_schedule.py
new file mode 100644
index 00000000000..752403ed22b
--- /dev/null
+++ b/addons/event/tests/test_mail_schedule.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+
+import datetime
+from dateutil.relativedelta import relativedelta
+
+from openerp import fields, tools
+from openerp.addons.event.tests.common import TestEventCommon
+from openerp.tools import mute_logger
+
+
+class TestMailSchedule(TestEventCommon):
+
+ @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
+ def test_00_event_mail_schedule(self):
+ """ Test mail scheduling for events """
+ self.env['ir.values'].set_default('marketing.config.settings', 'auto_confirmation', True)
+ now = fields.datetime.now()
+ event_date_begin = now + relativedelta(days=1)
+ event_date_end = now + relativedelta(days=3)
+
+ test_event = self.Event.sudo(self.user_eventmanager).create({
+ 'name': 'TestEventMail',
+ 'date_begin': event_date_begin,
+ 'date_end': event_date_end,
+ 'seats_max': 10,
+ 'event_mail_ids': [
+ (0, 0, { # right at subscription
+ 'interval_unit': 'now',
+ 'interval_type': 'after_sub',
+ 'template_id': self.env['ir.model.data'].xmlid_to_res_id('event.event_subscription')}),
+ (0, 0, { # 2 days before event
+ 'interval_nbr': 2,
+ 'interval_unit': 'days',
+ 'interval_type': 'before_event',
+ 'template_id': self.env['ir.model.data'].xmlid_to_res_id('event.event_reminder')}),
+ ]
+ })
+
+ # create some registrations
+ self.Registration.sudo(self.user_eventuser).create({
+ 'event_id': test_event.id,
+ 'name': 'Reg0',
+ 'email': 'reg0@example.com',
+ })
+ self.Registration.sudo(self.user_eventuser).create({
+ 'event_id': test_event.id,
+ 'name': 'Reg1',
+ 'email': 'reg1@example.com',
+ })
+
+ # check before event scheduler
+ schedulers = self.EventMail.search([('event_id', '=', test_event.id), ('interval_type', '=', 'before_event')])
+ self.assertEqual(len(schedulers), 1, 'event: wrong scheduler creation')
+ self.assertEqual(schedulers[0].scheduled_date, datetime.datetime.strftime(event_date_begin + relativedelta(days=-2), tools.DEFAULT_SERVER_DATETIME_FORMAT), 'event: incorrect scheduled date')
+
+ # execute event reminder scheduler
+ schedulers[0].execute()
+
+ self.assertTrue(schedulers[0].mail_sent, 'event: reminder scheduler should have sent an email')
+ self.assertTrue(schedulers[0].done, 'event: reminder scheduler should be done')
+
+ mails = self.env['mail.mail'].search([('subject', 'ilike', 'reminder'), ('date', '>=', datetime.datetime.strftime(now, tools.DEFAULT_SERVER_DATETIME_FORMAT))], order='date DESC', limit=3)
+ self.assertEqual(len(mails), 2, 'event: wrong number of reminder mail sent')
+
+ # check subscription scheduler
+ schedulers = self.EventMail.search([('event_id', '=', test_event.id), ('interval_type', '=', 'after_sub')])
+ self.assertEqual(len(schedulers), 1, 'event: wrong scheduler creation')
+ self.assertEqual(schedulers[0].scheduled_date, test_event.create_date, 'event: incorrect scheduled date for checking controller')
+
+ # execute subscription scheduler
+ schedulers[0].execute()
+ self.assertEqual(len(schedulers[0].mail_registration_ids), 2, 'event: incorrect number of mail scheduled date')
+
+ mails = self.env['mail.mail'].search([('subject', 'ilike', 'subscription'), ('date', '>=', datetime.datetime.strftime(now, tools.DEFAULT_SERVER_DATETIME_FORMAT))], order='date DESC', limit=3)
+ self.assertEqual(len(mails), 2, 'event: wrong number of subscription mail sent')
+
+ for registration in schedulers[0].mail_registration_ids:
+ self.assertTrue(registration.mail_sent, 'event: wrongly confirmed mailing on subscription')