Now that we're closer to switching to P3 for good, these helpers have outlived their usefulness, and mostly add noise. All remaining dict.iter*() or dict.view*() must be converted to the normal keys(), values() or items() calls. Whenever the result is likely to be used for more than the scope of a loop, or when the dict needs to be modified during iteration, the calls must be wrapped in a ``list()``, to protect the new P3 semantics. Those cases are very exceptional. Also removed some dead code or improved the API to remove unnecessary conversions.
261 lines
11 KiB
Python
261 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import babel.dates
|
|
import re
|
|
import werkzeug
|
|
from datetime import datetime, timedelta
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
from odoo import fields, http, _
|
|
from odoo.addons.website.models.website import slug
|
|
from odoo.http import request
|
|
|
|
|
|
class WebsiteEventController(http.Controller):
|
|
|
|
@http.route(['/event', '/event/page/<int:page>', '/events', '/events/page/<int:page>'], type='http', auth="public", website=True)
|
|
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'])]
|
|
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)
|
|
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.page_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)
|
|
def event_register(self, event, **post):
|
|
values = {
|
|
'event': event,
|
|
'main_object': event,
|
|
'range': range,
|
|
'registrable': event._is_event_registrable()
|
|
}
|
|
return request.render("website_event.event_description_full", values)
|
|
|
|
@http.route('/event/add_event', type='http', auth="user", methods=['POST'], website=True)
|
|
def add_event(self, event_name="New Event", **kwargs):
|
|
event = self._add_event(event_name, request.context)
|
|
return request.redirect("/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', '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='http', 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.render("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,
|
|
'event': event,
|
|
})
|