# -*- 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.http_routing.models.ir_http import slug from odoo.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/', '/events', '/events/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'])] 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//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/'], 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//register'], type='http', auth="public", website=True, sitemap=False) 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='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//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//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, })