Skip to content
Snippets Groups Projects
Commit 7862b2b7 authored by Sanjay Jamod's avatar Sanjay Jamod Committed by RomainLibert
Browse files

[IMP] website_event: quick add to Outlook/Google Calendar

In order for the user to easily add the date of the events to his
calendar we need to facilitate the integration with Outlook/ Google
Calendar.

For this we add two buttons at the end of the subscription phase (one
for Google Calendar and one for Outlook [ics file download])

Task ID: 39315
Closes #21854
parent 71f80c13
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,8 @@
import babel.dates
import re
import werkzeug
import json
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
......@@ -258,7 +260,23 @@ class WebsiteEventController(http.Controller):
Attendees += Attendees.sudo().create(
Attendees._prepare_attendee_values(registration))
urls = event._get_event_resource_urls(Attendees.ids)
return request.render("website_event.registration_complete", {
'attendees': Attendees,
'event': event,
'google_url': urls.get('google_url'),
'iCal_url': urls.get('iCal_url')
})
@http.route(['/event/<model("event.event"):event>/ics/<string:name>.ics'], type='http', auth="public", website=True)
def make_event_ics_file(self, event, **kwargs):
if not event or not event.registration_ids:
return request.not_found()
attendee_ids = list(json.loads(kwargs.get('attendees', '{}').replace("'", '"')).values())
files = event.get_ics_file(attendee_ids)
content = files[event.id]
return request.make_response(content, [
('Content-Type', 'application/octet-stream'),
('Content-Length', len(content)),
('Content-Disposition', 'attachment; filename=' + event.name + '.ics')
])
# -*- coding: utf-8 -*-
import logging
import pytz
import werkzeug
from datetime import datetime
from odoo import api, fields, models, _
from odoo.addons.http_routing.models.ir_http import slug
from odoo.exceptions import UserError
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
_logger = logging.getLogger(__name__)
try:
import vobject
except ImportError:
_logger.warning("`vobject` Python module not found, iCal file generation disabled. Consider installing this module if you want to generate iCal files")
vobject = None
GOOGLE_CALENDAR_URL = 'https://www.google.com/calendar/render?'
class EventType(models.Model):
_name = 'event.type'
......@@ -115,3 +134,49 @@ class Event(models.Model):
'target': 'new',
'url': '/report/html/%s/%s?enable_editor' % ('event.event_event_report_template_badge', self.id),
}
@api.multi
def get_ics_file(self, attendee_ids):
""" Returns iCalendar file for the event invitation.
:returns a dict of .ics file content for each event
"""
result = {}
if not vobject:
return result
for event in self:
cal = vobject.iCalendar()
cal_event = cal.add('vevent')
if not event.date_begin or not event.date_end:
raise UserError(_("No date has been specified for the event, no file will be generated."))
cal_event.add('created').value = fields.Datetime.from_string(fields.Datetime.now()).replace(tzinfo=pytz.timezone('UTC'))
cal_event.add('dtstart').value = fields.Datetime.from_string(event.date_begin).replace(tzinfo=pytz.timezone('UTC'))
cal_event.add('dtend').value = fields.Datetime.from_string(event.date_end).replace(tzinfo=pytz.timezone('UTC'))
cal_event.add('summary').value = event.name
if event.address_id:
cal_event.add('location').value = event.sudo().address_id.contact_address
attendees = self.env['event.registration'].browse(attendee_ids)
for attendee in attendees:
attendee_add = cal_event.add('attendee')
attendee_add.value = u'MAILTO:' + (attendee.email or u'')
result[event.id] = cal.serialize().encode('utf-8')
return result
def _get_event_resource_urls(self, attendees):
url_date_start = datetime.strptime(self.date_begin, DEFAULT_SERVER_DATETIME_FORMAT).strftime('%Y%m%dT%H%M%SZ')
url_date_stop = datetime.strptime(self.date_end, DEFAULT_SERVER_DATETIME_FORMAT).strftime('%Y%m%dT%H%M%SZ')
params = werkzeug.url_encode({
'action': 'TEMPLATE',
'text': self.name,
'dates': url_date_start + '/' + url_date_stop,
'location': self.sudo().address_id.contact_address.replace('\n', ' '),
'details': self.name,
})
google_url = GOOGLE_CALENDAR_URL + params
params = werkzeug.url_encode({
'attendees': dict(('attendee_%s' % attendee, attendee) for attendee in attendees)
})
iCal_url = '/event/%s/ics/%s.ics?' % (slug(self), self.name) + params
return {'google_url': google_url, 'iCal_url': iCal_url}
......@@ -594,6 +594,14 @@
<div class="col-md-9 mt16">
<h4><a t-attf-href="/event/#{slug(event)}"><t t-esc="event.name"/></a></h4>
<i class="fa fa-clock-o"></i> <span itemprop="startDate" t-esc="event.date_begin_located"> </span> <i>to</i> <span itemprop="endDate" t-esc="event.date_end_located"> </span>
<div id="add_to_calendar" class="mt4">
<a class="btn btn-primary mr8" t-att-href="iCal_url">
<i class="fa fa-fw fa-arrow-right"/>Add to iCal/Outlook
</a>
<a class="btn btn-primary" t-att-href="google_url" target='_blank'>
<i class="fa fa-fw fa-arrow-right"/>Add to Google Calendar
</a>
</div>
<div itemprop="location" class="mt16 mb8" t-field="event.address_id" t-options='{
"widget": "contact",
"fields": ["name", "address", "phone", "mobile", "email"]
......
......@@ -42,9 +42,12 @@ class WebsiteEventSaleController(WebsiteEventController):
attendees = request.env['event.registration'].browse(list(attendee_ids))
# clean context and session, then redirect to the confirmation page
request.website.sale_reset()
urls = event._get_event_resource_urls(list(attendee_ids))
return request.render("website_event.registration_complete", {
'attendees': attendees,
'event': event,
'google_url': urls.get('google_url'),
'iCal_url': urls.get('iCal_url')
})
return request.redirect("/shop/checkout")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment