270 lines
12 KiB
Python
270 lines
12 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import babel.dates
|
|
import re
|
|
import werkzeug
|
|
from datetime import datetime, timedelta
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
from flectra import fields, http, _
|
|
from flectra.addons.http_routing.models.ir_http import slug
|
|
from flectra.http import request
|
|
|
|
|
|
class WebsiteEventController(http.Controller):
|
|
|
|
def sitemap_event(env, rule, qs):
|
|
if not qs or qs.lower() in '/events':
|
|
yield {'loc': '/events'}
|
|
|
|
@http.route(['/event', '/event/page/<int:page>', '/events', '/events/page/<int:page>'], type='http', auth="public", website=True, sitemap=sitemap_event)
|
|
def events(self, page=1, **searches):
|
|
Event = request.env['event.event']
|
|
EventType = request.env['event.type']
|
|
|
|
searches.setdefault('date', 'all')
|
|
searches.setdefault('type', 'all')
|
|
searches.setdefault('country', 'all')
|
|
|
|
domain_search = {}
|
|
|
|
def sdn(date):
|
|
return fields.Datetime.to_string(date.replace(hour=23, minute=59, second=59))
|
|
|
|
def sd(date):
|
|
return fields.Datetime.to_string(date)
|
|
today = datetime.today()
|
|
dates = [
|
|
['all', _('Next Events'), [("date_end", ">", sd(today))], 0],
|
|
['today', _('Today'), [
|
|
("date_end", ">", sd(today)),
|
|
("date_begin", "<", sdn(today))],
|
|
0],
|
|
['week', _('This Week'), [
|
|
("date_end", ">=", sd(today + relativedelta(days=-today.weekday()))),
|
|
("date_begin", "<", sdn(today + relativedelta(days=6-today.weekday())))],
|
|
0],
|
|
['nextweek', _('Next Week'), [
|
|
("date_end", ">=", sd(today + relativedelta(days=7-today.weekday()))),
|
|
("date_begin", "<", sdn(today + relativedelta(days=13-today.weekday())))],
|
|
0],
|
|
['month', _('This month'), [
|
|
("date_end", ">=", sd(today.replace(day=1))),
|
|
("date_begin", "<", (today.replace(day=1) + relativedelta(months=1)).strftime('%Y-%m-%d 00:00:00'))],
|
|
0],
|
|
['nextmonth', _('Next month'), [
|
|
("date_end", ">=", sd(today.replace(day=1) + relativedelta(months=1))),
|
|
("date_begin", "<", (today.replace(day=1) + relativedelta(months=2)).strftime('%Y-%m-%d 00:00:00'))],
|
|
0],
|
|
['old', _('Old Events'), [
|
|
("date_end", "<", today.strftime('%Y-%m-%d 00:00:00'))],
|
|
0],
|
|
]
|
|
|
|
# search domains
|
|
# TDE note: WTF ???
|
|
current_date = None
|
|
current_type = None
|
|
current_country = None
|
|
for date in dates:
|
|
if searches["date"] == date[0]:
|
|
domain_search["date"] = date[2]
|
|
if date[0] != 'all':
|
|
current_date = date[1]
|
|
if searches["type"] != 'all':
|
|
current_type = EventType.browse(int(searches['type']))
|
|
domain_search["type"] = [("event_type_id", "=", int(searches["type"]))]
|
|
|
|
if searches["country"] != 'all' and searches["country"] != 'online':
|
|
current_country = request.env['res.country'].browse(int(searches['country']))
|
|
domain_search["country"] = ['|', ("country_id", "=", int(searches["country"])), ("country_id", "=", False)]
|
|
elif searches["country"] == 'online':
|
|
domain_search["country"] = [("country_id", "=", False)]
|
|
|
|
def dom_without(without):
|
|
domain = [('state', "in", ['draft', 'confirm', 'done'])]
|
|
domain += [('website_id', '=', request.website.id)] if \
|
|
not request.env.user.has_group('website.group_website_publisher') else []
|
|
for key, search in domain_search.items():
|
|
if key != without:
|
|
domain += search
|
|
return domain
|
|
|
|
# count by domains without self search
|
|
for date in dates:
|
|
if date[0] != 'old':
|
|
date[3] = Event.search_count(dom_without('date') + date[2])
|
|
|
|
domain = dom_without('type')
|
|
types = Event.read_group(domain, ["id", "event_type_id"], groupby=["event_type_id"], orderby="event_type_id")
|
|
types.insert(0, {
|
|
'event_type_id_count': sum([int(type['event_type_id_count']) for type in types]),
|
|
'event_type_id': ("all", _("All Categories"))
|
|
})
|
|
|
|
domain = dom_without('country')
|
|
countries = Event.read_group(domain, ["id", "country_id"], groupby="country_id", orderby="country_id")
|
|
countries.insert(0, {
|
|
'country_id_count': sum([int(country['country_id_count']) for country in countries]),
|
|
'country_id': ("all", _("All Countries"))
|
|
})
|
|
|
|
step = 10 # Number of events per page
|
|
event_count = Event.search_count(dom_without("none"))
|
|
pager = request.website.pager(
|
|
url="/event",
|
|
url_args={'date': searches.get('date'), 'type': searches.get('type'), 'country': searches.get('country')},
|
|
total=event_count,
|
|
page=page,
|
|
step=step,
|
|
scope=5)
|
|
|
|
order = 'website_published desc, date_begin'
|
|
if searches.get('date', 'all') == 'old':
|
|
order = 'website_published desc, date_begin desc'
|
|
events = Event.search(dom_without("none"), limit=step, offset=pager['offset'], order=order)
|
|
|
|
values = {
|
|
'current_date': current_date,
|
|
'current_country': current_country,
|
|
'current_type': current_type,
|
|
'event_ids': events, # event_ids used in website_event_track so we keep name as it is
|
|
'dates': dates,
|
|
'types': types,
|
|
'countries': countries,
|
|
'pager': pager,
|
|
'searches': searches,
|
|
'search_path': "?%s" % werkzeug.url_encode(searches),
|
|
}
|
|
|
|
return request.render("website_event.index", values)
|
|
|
|
@http.route(['/event/<model("event.event"):event>/page/<path:page>'], type='http', auth="public", website=True, sitemap=False)
|
|
def event_page(self, event, page, **post):
|
|
values = {
|
|
'event': event,
|
|
'main_object': event
|
|
}
|
|
|
|
if '.' not in page:
|
|
page = 'website_event.%s' % page
|
|
|
|
try:
|
|
request.website.get_template(page)
|
|
except ValueError:
|
|
# page not found
|
|
values['path'] = re.sub(r"^website_event\.", '', page)
|
|
values['from_template'] = 'website_event.default_page' # .strip('website_event.')
|
|
page = 'website.%s' % (request.website.is_publisher() and 'page_404' or '404')
|
|
|
|
return request.render(page, values)
|
|
|
|
@http.route(['/event/<model("event.event"):event>'], type='http', auth="public", website=True)
|
|
def event(self, event, **post):
|
|
if event.menu_id and event.menu_id.child_id:
|
|
target_url = event.menu_id.child_id[0].url
|
|
else:
|
|
target_url = '/event/%s/register' % str(event.id)
|
|
if post.get('enable_editor') == '1':
|
|
target_url += '?enable_editor=1'
|
|
return request.redirect(target_url)
|
|
|
|
@http.route(['/event/<model("event.event"):event>/register'], type='http', auth="public", website=True, sitemap=False)
|
|
def event_register(self, event, **post):
|
|
if not request.env.user.has_group('website.group_website_publisher') \
|
|
and request.website != event.website_id:
|
|
return request.render('website.404')
|
|
values = {
|
|
'event': event,
|
|
'main_object': event,
|
|
'range': range,
|
|
'registrable': event.sudo()._is_event_registrable()
|
|
}
|
|
return request.render("website_event.event_description_full", values)
|
|
|
|
@http.route('/event/add_event', type='json', auth="user", methods=['POST'], website=True)
|
|
def add_event(self, event_name="New Event", **kwargs):
|
|
event = self._add_event(event_name, request.context)
|
|
return "/event/%s/register?enable_editor=1" % slug(event)
|
|
|
|
def _add_event(self, event_name=None, context=None, **kwargs):
|
|
if not event_name:
|
|
event_name = _("New Event")
|
|
date_begin = datetime.today() + timedelta(days=(14))
|
|
vals = {
|
|
'name': event_name,
|
|
'date_begin': fields.Date.to_string(date_begin),
|
|
'date_end': fields.Date.to_string((date_begin + timedelta(days=(1)))),
|
|
'seats_available': 1000,
|
|
}
|
|
return request.env['event.event'].with_context(context or {}).create(vals)
|
|
|
|
def get_formated_date(self, event):
|
|
start_date = fields.Datetime.from_string(event.date_begin).date()
|
|
end_date = fields.Datetime.from_string(event.date_end).date()
|
|
month = babel.dates.get_month_names('abbreviated', locale=event.env.context.get('lang') or 'en_US')[start_date.month]
|
|
return ('%s %s%s') % (month, start_date.strftime("%e"), (end_date != start_date and ("-" + end_date.strftime("%e")) or ""))
|
|
|
|
@http.route('/event/get_country_event_list', type='json', auth='public', website=True)
|
|
def get_country_events(self, **post):
|
|
Event = request.env['event.event']
|
|
country_code = request.session['geoip'].get('country_code')
|
|
result = {'events': [], 'country': False}
|
|
events = None
|
|
if country_code:
|
|
country = request.env['res.country'].search([('code', '=', country_code)], limit=1)
|
|
events = Event.search(['|', ('address_id', '=', None), ('country_id.code', '=', country_code), ('date_begin', '>=', '%s 00:00:00' % fields.Date.today()), ('state', '=', 'confirm')], order="date_begin")
|
|
if not events:
|
|
events = Event.search([('date_begin', '>=', '%s 00:00:00' % fields.Date.today()), ('state', '=', 'confirm')], order="date_begin")
|
|
for event in events:
|
|
if country_code and event.country_id.code == country_code:
|
|
result['country'] = country
|
|
result['events'].append({
|
|
"date": self.get_formated_date(event),
|
|
"event": event,
|
|
"url": event.website_url})
|
|
return request.env['ir.ui.view'].render_template("website_event.country_events_list", result)
|
|
|
|
def _process_tickets_details(self, data):
|
|
nb_register = int(data.get('nb_register-0', 0))
|
|
if nb_register:
|
|
return [{'id': 0, 'name': 'Registration', 'quantity': nb_register, 'price': 0}]
|
|
return []
|
|
|
|
@http.route(['/event/<model("event.event"):event>/registration/new'], type='json', auth="public", methods=['POST'], website=True)
|
|
def registration_new(self, event, **post):
|
|
tickets = self._process_tickets_details(post)
|
|
if not tickets:
|
|
return False
|
|
return request.env['ir.ui.view'].render_template("website_event.registration_attendee_details", {'tickets': tickets, 'event': event})
|
|
|
|
def _process_registration_details(self, details):
|
|
''' Process data posted from the attendee details form. '''
|
|
registrations = {}
|
|
global_values = {}
|
|
for key, value in details.items():
|
|
counter, field_name = key.split('-', 1)
|
|
if counter == '0':
|
|
global_values[field_name] = value
|
|
else:
|
|
registrations.setdefault(counter, dict())[field_name] = value
|
|
for key, value in global_values.items():
|
|
for registration in registrations.values():
|
|
registration[key] = value
|
|
return list(registrations.values())
|
|
|
|
@http.route(['/event/<model("event.event"):event>/registration/confirm'], type='http', auth="public", methods=['POST'], website=True)
|
|
def registration_confirm(self, event, **post):
|
|
Attendees = request.env['event.registration']
|
|
registrations = self._process_registration_details(post)
|
|
|
|
for registration in registrations:
|
|
registration['event_id'] = event
|
|
Attendees += Attendees.sudo().create(
|
|
Attendees._prepare_attendee_values(registration))
|
|
|
|
return request.render("website_event.registration_complete", {
|
|
'attendees': Attendees.sudo(),
|
|
'event': event,
|
|
})
|