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': [ 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') +
+ + + + + + + +
+ + ${object.company_id.name} + + + % 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?

+
Please contact the organizer at ${object.event_id.organizer_id.email}
+
+ % endif + + + + +
+ Add this event to your calendar + Google + Outlook + Yahoo +
+
+
+ + + +
+ + + + + + +
+
This email was sent to ${object.email}
+

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') +
+ + + + + + + +
+ + ${object.company_id.name} + + + % 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?

+
Please contact the organizer at ${object.event_id.organizer_id.email}
+
+ % endif + + + + +
+ Add this event to your calendar + Google + Outlook + Yahoo +
+
+
+ + + +
+ + + + + + +
+
This email was sent to ${object.email}
+

Copyright © ${object.company_id.name}

+
+
+ ]]>
diff --git a/addons/event/models/event.py b/addons/event/models/event.py index ef9684230e9..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 @@ -367,9 +378,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): @@ -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/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..6e2f0406357 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,17 @@ 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=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 d1ac9c51465..90a4a99f20b 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,31 @@ 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() + + 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']