From 450aa05cc6610e3a03fbc05d1c2949ce0b41f039 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?=
Date: Thu, 11 Aug 2016 10:06:12 +0200
Subject: [PATCH 1/4] [FIX] event: go to 1.0 (he deserves it) and fix typos in
manifest
---
addons/event/__openerp__.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/addons/event/__openerp__.py b/addons/event/__openerp__.py
index 23c8d0926de..095bf9ad377 100644
--- a/addons/event/__openerp__.py
+++ b/addons/event/__openerp__.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
{
- 'name': 'Events Organisation',
- 'version': '0.1',
+ 'name': 'Events Organization',
+ 'version': '1.0',
'website': 'https://www.odoo.com/page/events',
'category': 'Marketing',
'summary': 'Trainings, Conferences, Meetings, Exhibitions, Registrations',
@@ -9,13 +9,13 @@
Organization and management of Events.
======================================
-The event module allows you to efficiently organise events and all related tasks: planification, registration tracking,
+The event module allows you to efficiently organize events and all related tasks: planning, registration tracking,
attendances, etc.
Key Features
------------
* Manage your Events and Registrations
-* Use emails to automatically confirm and send acknowledgements for any event registration
+* Use emails to automatically confirm and send acknowledgments for any event registration
""",
'depends': ['base_setup', 'mail', 'report'],
'data': [
From 5916583885b495aca8cbd74a296416db17150ffd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?=
Date: Thu, 11 Aug 2016 15:33:43 +0200
Subject: [PATCH 2/4] [FIX] event: take contact data when changing contact
registration.onchange_partner_id() method updates registration contact data
(phone, email, name) based on the partner_id field. However the onchange
currently works only when no existing contact data is stored on the
registration. A second change of partner_id does not update the contact
data.
The condition is now inversed. This way when changing the partner, if it
has valid contact data, it will replace existing information.
---
addons/event/models/event.py | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/addons/event/models/event.py b/addons/event/models/event.py
index ef9684230e9..c87c2947bef 100644
--- a/addons/event/models/event.py
+++ b/addons/event/models/event.py
@@ -367,9 +367,9 @@ class EventRegistration(models.Model):
contact_id = self.partner_id.address_get().get('contact', False)
if contact_id:
contact = self.env['res.partner'].browse(contact_id)
- self.name = self.name or contact.name
- self.email = self.email or contact.email
- self.phone = self.phone or contact.phone
+ self.name = contact.name or self.name
+ self.email = contact.email or self.email
+ self.phone = contact.phone or self.phone
@api.multi
def message_get_suggested_recipients(self):
From 6b87c731fb3daa4204c3679e9dfb2569902cbb55 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?=
Date: Thu, 11 Aug 2016 10:49:16 +0200
Subject: [PATCH 3/4] [FIX] event: fix access right issues
* Limitate rights of event user to reading an event
Event user should not be able to create events. Its rights should be limited
to reading events, creating and updating registrations. Only event managers
are allowed to create and modify events.
* Sudo access on ir.values in event config settings
Configuring events imply modifying auto confirmation parameter which is stored
into an ir.values. As this model is limited to values with user_id = uid we
have to sudo the access here as it is not a user-defined value.
* Add some tests for the various fixed issues
---
addons/event/models/event_config_settings.py | 6 +++-
addons/event/security/ir.model.access.csv | 9 +++---
addons/event/tests/common.py | 15 ++++++++-
addons/event/tests/test_event_flow.py | 32 ++++++++++++++++++--
4 files changed, 54 insertions(+), 8 deletions(-)
diff --git a/addons/event/models/event_config_settings.py b/addons/event/models/event_config_settings.py
index 786b7ee461c..92ec85ef4b4 100644
--- a/addons/event/models/event_config_settings.py
+++ b/addons/event/models/event_config_settings.py
@@ -37,4 +37,8 @@ class event_config_settings(models.TransientModel):
@api.multi
def set_default_auto_confirmation(self):
- self.env['ir.values'].set_default('event.config.settings', 'auto_confirmation', self.auto_confirmation)
+ if self.env.user._is_admin() or self.env['res.users'].has_group('event.group_event_manager'):
+ IrValues = self.env['ir.values'].sudo()
+ else:
+ IrValues = self.env['ir.values']
+ IrValues.set_default('event.config.settings', 'auto_confirmation', self.auto_confirmation)
diff --git a/addons/event/security/ir.model.access.csv b/addons/event/security/ir.model.access.csv
index 8801c173f17..ac13c583b55 100644
--- a/addons/event/security/ir.model.access.csv
+++ b/addons/event/security/ir.model.access.csv
@@ -1,12 +1,13 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_event_type,event.type,model_event_type,event.group_event_user,1,0,0,0
access_event_type_manager,event.type manager,model_event_type,event.group_event_manager,1,1,1,1
-access_event_event,event.event,model_event_event,event.group_event_user,1,1,1,1
+access_event_event_portal,event.event.portal,model_event_event,,1,0,0,0
+access_event_event_user,event.event.user,model_event_event,event.group_event_user,1,0,0,0
+access_event_event_manager,event.event.manager,model_event_event,event.group_event_manager,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
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
+access_event_mail_registration_manager,event.mail.registration.manager,model_event_mail_registration,event.group_event_manager,1,1,1,1
+access_report_event_registration,report.event.registration,model_report_event_registration,event.group_event_user,1,1,1,1
\ No newline at end of file
diff --git a/addons/event/tests/common.py b/addons/event/tests/common.py
index a1a3ec2f981..15ad898e565 100644
--- a/addons/event/tests/common.py
+++ b/addons/event/tests/common.py
@@ -1,5 +1,8 @@
# -*- coding: utf-8 -*-
+from datetime import datetime, timedelta
+
+from odoo import fields
from odoo.tests import common
@@ -18,6 +21,7 @@ class TestEventCommon(common.TransactionCase):
self.group_employee_id = self.env['ir.model.data'].xmlid_to_res_id('base.group_user')
self.group_event_user_id = self.env['ir.model.data'].xmlid_to_res_id('event.group_event_user')
self.group_event_manager_id = self.env['ir.model.data'].xmlid_to_res_id('event.group_event_manager')
+ group_system = self.env.ref('base.group_system')
# Test users to use through the various tests
self.user_eventuser = self.Users.with_context({'no_reset_password': True}).create({
@@ -34,5 +38,14 @@ class TestEventCommon(common.TransactionCase):
'alias_name': 'bastien',
'email': 'bastien.eventmanager@example.com',
'tz': 'Europe/Brussels',
- 'groups_id': [(6, 0, [self.group_employee_id, self.group_event_manager_id])]
+ 'groups_id': [(6, 0, [
+ self.group_employee_id,
+ self.group_event_manager_id,
+ group_system.id])]
+ })
+
+ self.event_0 = self.env['event.event'].create({
+ 'name': 'TestEvent',
+ 'date_begin': fields.Datetime.to_string(datetime.today() - timedelta(days=5)),
+ 'date_end': fields.Datetime.to_string(datetime.today() + timedelta(days=5)),
})
diff --git a/addons/event/tests/test_event_flow.py b/addons/event/tests/test_event_flow.py
index d1ac9c51465..c35d03088df 100644
--- a/addons/event/tests/test_event_flow.py
+++ b/addons/event/tests/test_event_flow.py
@@ -4,7 +4,7 @@ import datetime
from dateutil.relativedelta import relativedelta
from odoo.addons.event.tests.common import TestEventCommon
-from odoo.exceptions import ValidationError, UserError
+from odoo.exceptions import ValidationError, UserError, AccessError
from odoo.tools import mute_logger
@@ -13,7 +13,10 @@ class TestEventFlow(TestEventCommon):
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
def test_00_basic_event_auto_confirm(self):
""" Basic event management with auto confirmation """
- self.env['ir.values'].set_default('event.config.settings', 'auto_confirmation', True)
+ event_config = self.env['event.config.settings'].sudo(self.user_eventmanager).create({
+ 'auto_confirmation': 1
+ })
+ event_config.execute()
# EventUser creates a new event: ok
test_event = self.Event.sudo(self.user_eventmanager).create({
@@ -87,3 +90,28 @@ class TestEventFlow(TestEventCommon):
self.assertEqual(
test_reg1.state, 'draft',
'Event: new registration should not be confirmed with auto_confirmation parameter being False')
+
+ def test_event_access_rights(self):
+ # EventManager required to create or update events
+ with self.assertRaises(AccessError):
+ self.Event.sudo(self.user_eventuser).create({
+ 'name': 'TestEvent',
+ 'date_begin': datetime.datetime.now() + relativedelta(days=-1),
+ 'date_end': datetime.datetime.now() + relativedelta(days=1),
+ 'seats_max': 10,
+ })
+ with self.assertRaises(AccessError):
+ self.event_0.sudo(self.user_eventuser).write({
+ 'name': 'TestEvent Modified',
+ })
+
+ # Settings access rights required to enable some features
+ self.user_eventmanager.write({'groups_id': [
+ (3, self.env.ref('base.group_system').id),
+ (4, self.env.ref('base.group_erp_manager').id)
+ ]})
+ with self.assertRaises(AccessError):
+ event_config = self.env['event.config.settings'].sudo(self.user_eventmanager).create({
+ 'auto_confirmation': 1
+ })
+ event_config.execute()
From 9f7d7c680930207c7989df8d8ae07731b523907a Mon Sep 17 00:00:00 2001
From: Jigar Patel
Date: Wed, 22 Jun 2016 16:08:26 +0530
Subject: [PATCH 4/4] [IMP] event: improve emails sent by event
* improve layout of confirmation and reminder emails
* add default mails configuration on events: 2 reminders are added
J-2 and J_15
---
addons/event/data/email_template_data.xml | 255 ++++++++++++++++++++--
addons/event/models/event.py | 31 +++
addons/event/tests/common.py | 7 +-
addons/event/tests/test_event_flow.py | 3 +
addons/website_event/models/event.py | 1 -
5 files changed, 279 insertions(+), 18 deletions(-)
diff --git a/addons/event/data/email_template_data.xml b/addons/event/data/email_template_data.xml
index 8e33d116881..aa49de0995c 100644
--- a/addons/event/data/email_template_data.xml
+++ b/addons/event/data/email_template_data.xml
@@ -29,11 +29,123 @@
${object.event_id.reply_to|safe}
Your registration at ${object.event_id.name}
Dear ${object.name},
-Thank you for your inquiry.
-We confirm your registration to the event ${object.event_id.name}. You will receive emails with practical information.
-If you have any questions, please let us know.
-Best regards,
]]>
+% set date_begin = format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%SZ')
+% set date_end = format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%SZ')
+
+
+
+
+
+
+
+
+ |
+
+ % if 'website_url' in object.event_id and object.event_id.website_url:
+ More Events
+ % endif
+ |
+
+
+
+
+
+
+
+
+ Hi ${object.name}, here is your order confirmation for
+ % if 'website_url' in object.event_id and object.event_id.website_url:
+ ${object.event_id.name}
+ % else:
+ ${object.event_id.name}
+ % endif
+
+ |
+
+
+
+
+
+
+
+ |
+
+ % if object.event_id.address_id.street:
+ ${object.event_id.address_id.street},
+ % set location = object.event_id.address_id.street
+ % endif
+ % if object.event_id.address_id.street2:
+ ${object.event_id.address_id.street2},
+ % set location = '%s, %s' % (location, object.event_id.address_id.street2)
+ % endif
+ % if object.event_id.address_id.city:
+ ${object.event_id.address_id.city},
+ % set location = '%s, %s' % (location, object.event_id.address_id.city)
+ % endif
+ % if object.event_id.address_id.state_id.name:
+ ${object.event_id.address_id.state_id.name},
+ % set location = '%s, %s' % (location, object.event_id.address_id.state_id.name)
+ % endif
+ % if object.event_id.address_id.zip:
+ ${object.event_id.address_id.zip},
+ % set location = '%s, %s' % (location, object.event_id.address_id.zip)
+ % endif
+ % if object.event_id.address_id.country_id.name:
+ ${object.event_id.address_id.country_id.name}
+ % set location = '%s, %s' % (location, object.event_id.address_id.country_id.name)
+ % endif
+ |
+
+
+ |
+
+ From ${object.event_id.date_begin_located}
+ To ${object.event_id.date_end_located}
+ TZ ${object.event_id.date_tz}
+ |
+
+
+ % if object.event_id.organizer_id.email:
+
+
+
+ Questions about this event?
+
+ |
+
+
+ % endif
+
+ |
+
+
+
+
+
+
+
+ |
+
+ Copyright © ${object.company_id.name}
+ |
+
+
+
+
+ ]]>
@@ -43,17 +155,130 @@
${object.partner_id.email or object.email|safe}
${object.partner_id.lang}
${object.event_id.reply_to|safe}
- Reminder of event ${object.event_id.name}
+ Reminder for ${object.event_id.name}
Dear ${object.name},
-Thank you for your registration to the event ${object.event_id.name}.
-The event will take place at ${object.event_id.address_id.city}
-% if object.event_id.address_id.street
-, ${object.event_id.address_id.street}
-% endif
-from ${object.event_id.date_begin_located} to ${object.event_id.date_end_located}.
-If you have any questions, please let us know.
-Best regards,
]]>
+% set date_begin = format_tz(object.event_id.date_begin, tz='UTC', format='%Y%m%dT%H%M%SZ')
+% set date_end = format_tz(object.event_id.date_end, tz='UTC', format='%Y%m%dT%H%M%SZ')
+
+
+
+
+
+
+
+
+ |
+
+ % if 'website_url' in object.event_id and object.event_id.website_url:
+ More Events
+ % endif
+ |
+
+
+
+
+
+
+
+
+ Hi ${object.name},
+
+
+ Please keep in mind that the event
+ % if 'website_url' in object.event_id and object.event_id.website_url:
+ ${object.event_id.name}
+ % else:
+ ${object.event_id.name}
+ % endif
+ takes place on
+ ${object.get_date_range_str()}
+
+ |
+
+
+
+
+
+
+
+ |
+
+ % if object.event_id.address_id.street:
+ ${object.event_id.address_id.street},
+ % set location = object.event_id.address_id.street
+ % endif
+ % if object.event_id.address_id.street2:
+ ${object.event_id.address_id.street2},
+ % set location = '%s, %s' % (location, object.event_id.address_id.street2)
+ % endif
+ % if object.event_id.address_id.city:
+ ${object.event_id.address_id.city},
+ % set location = '%s, %s' % (location, object.event_id.address_id.city)
+ % endif
+ % if object.event_id.address_id.state_id.name:
+ ${object.event_id.address_id.state_id.name},
+ % set location = '%s, %s' % (location, object.event_id.address_id.state_id.name)
+ % endif
+ % if object.event_id.address_id.zip:
+ ${object.event_id.address_id.zip},
+ % set location = '%s, %s' % (location, object.event_id.address_id.zip)
+ % endif
+ % if object.event_id.address_id.country_id.name:
+ ${object.event_id.address_id.country_id.name}
+ % set location = '%s, %s' % (location, object.event_id.address_id.country_id.name)
+ % endif
+ |
+
+
+ |
+
+ From ${object.event_id.date_begin_located}
+ To ${object.event_id.date_end_located}
+ TZ ${object.event_id.date_tz}
+ |
+
+
+ % if object.event_id.organizer_id.email:
+
+
+
+ Questions about this event?
+
+ |
+
+
+ % endif
+
+ |
+
+
+
+
+
+
+
+ |
+
+ Copyright © ${object.company_id.name}
+ |
+
+
+
+
+ ]]>
diff --git a/addons/event/models/event.py b/addons/event/models/event.py
index c87c2947bef..707866af345 100644
--- a/addons/event/models/event.py
+++ b/addons/event/models/event.py
@@ -3,6 +3,7 @@
import pytz
from odoo import _, api, fields, models
+from odoo.addons.mail.models.mail_template import format_tz
from odoo.exceptions import AccessError, UserError, ValidationError
from odoo.tools.translate import html_translate
@@ -57,6 +58,16 @@ class EventEvent(models.Model):
'interval_unit': 'now',
'interval_type': 'after_sub',
'template_id': self.env.ref('event.event_subscription')
+ }), (0, 0, {
+ 'interval_nbr': 2,
+ 'interval_unit': 'days',
+ 'interval_type': 'before_event',
+ 'template_id': self.env.ref('event.event_reminder')
+ }), (0, 0, {
+ 'interval_nbr': 15,
+ 'interval_unit': 'days',
+ 'interval_type': 'before_event',
+ 'template_id': self.env.ref('event.event_reminder')
})]
# Seats and computation
@@ -410,3 +421,23 @@ class EventRegistration(models.Model):
'target': 'new',
'context': ctx,
}
+
+ @api.multi
+ def get_date_range_str(self):
+ self.ensure_one()
+ today = fields.Datetime.from_string(fields.Datetime.now())
+ event_date = fields.Datetime.from_string(self.event_begin_date)
+
+ if today.month == event_date.month:
+ if event_date.day == today.day:
+ return _('Today')
+ elif event_date.day - today.day == 1:
+ return _('Tomorrow')
+ elif event_date.isocalendar()[1] == today.isocalendar()[1]:
+ return _('This week')
+ else:
+ return _('This month')
+ elif event_date.month - today.month == 1:
+ return _('Next month')
+ else:
+ return format_tz(self.event_begin_date, tz='UTC', format='%Y%m%dT%H%M%SZ')
diff --git a/addons/event/tests/common.py b/addons/event/tests/common.py
index 15ad898e565..6e2f0406357 100644
--- a/addons/event/tests/common.py
+++ b/addons/event/tests/common.py
@@ -46,6 +46,9 @@ class TestEventCommon(common.TransactionCase):
self.event_0 = self.env['event.event'].create({
'name': 'TestEvent',
- 'date_begin': fields.Datetime.to_string(datetime.today() - timedelta(days=5)),
- 'date_end': fields.Datetime.to_string(datetime.today() + timedelta(days=5)),
+ 'date_begin': fields.Datetime.to_string(datetime.today() + timedelta(days=1)),
+ 'date_end': fields.Datetime.to_string(datetime.today() + timedelta(days=15)),
+ 'registration_ids': [(0, 0, {
+ 'partner_id': self.user_eventuser.partner_id.id,
+ })]
})
diff --git a/addons/event/tests/test_event_flow.py b/addons/event/tests/test_event_flow.py
index c35d03088df..90a4a99f20b 100644
--- a/addons/event/tests/test_event_flow.py
+++ b/addons/event/tests/test_event_flow.py
@@ -115,3 +115,6 @@ class TestEventFlow(TestEventCommon):
'auto_confirmation': 1
})
event_config.execute()
+
+ def test_event_data(self):
+ self.assertEqual(self.event_0.registration_ids.get_date_range_str(), u'Tomorrow')
diff --git a/addons/website_event/models/event.py b/addons/website_event/models/event.py
index 82cc834f1eb..1fdc7bb8ff6 100644
--- a/addons/website_event/models/event.py
+++ b/addons/website_event/models/event.py
@@ -7,7 +7,6 @@ from odoo.addons.website.models.website import slug
class Event(models.Model):
-
_name = 'event.event'
_inherit = ['event.event', 'website.seo.metadata', 'website.published.mixin']