242 lines
11 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from ast import literal_eval
from collections import OrderedDict
from random import randint, sample
from werkzeug.exceptions import NotFound, Forbidden
from odoo import exceptions, http
from odoo.addons.website_event.controllers.main import WebsiteEventController
from odoo.http import request
from odoo.osv import expression
from odoo.tools import format_duration
class ExhibitorController(WebsiteEventController):
def _get_event_sponsors_base_domain(self, event):
search_domain_base = [
('event_id', '=', event.id),
('exhibitor_type', 'in', ['exhibitor', 'online']),
]
if not request.env.user.has_group('event.group_event_registration_desk'):
search_domain_base = expression.AND([search_domain_base, [('is_published', '=', True)]])
return search_domain_base
# ------------------------------------------------------------
# MAIN PAGE
# ------------------------------------------------------------
@http.route([
# TDE BACKWARD: exhibitors is actually a typo
'/event/<model("event.event"):event>/exhibitors',
# TDE BACKWARD: matches event/event-1/exhibitor/exhib-1 sub domain
'/event/<model("event.event"):event>/exhibitor'
], type='http', auth="public", website=True, sitemap=False, methods=['GET', 'POST'])
def event_exhibitors(self, event, **searches):
return request.render(
"website_event_exhibitor.event_exhibitors",
self._event_exhibitors_get_values(event, **searches)
)
def _event_exhibitors_get_values(self, event, **searches):
# init and process search terms
searches.setdefault('search', '')
searches.setdefault('countries', '')
searches.setdefault('sponsorships', '')
search_domain_base = self._get_event_sponsors_base_domain(event)
search_domain = search_domain_base
# search on content
if searches.get('search'):
search_domain = expression.AND([
search_domain,
['|', ('name', 'ilike', searches['search']), ('website_description', 'ilike', searches['search'])]
])
# search on countries
search_countries = self._get_search_countries(searches['countries'])
if search_countries:
search_domain = expression.AND([
search_domain,
[('partner_id.country_id', 'in', search_countries.ids)]
])
# search on sponsor types
search_sponsorships = self._get_search_sponsorships(searches['sponsorships'])
if search_sponsorships:
search_domain = expression.AND([
search_domain,
[('sponsor_type_id', 'in', search_sponsorships.ids)]
])
# fetch data to display; use sudo to allow reading partner info, be sure domain is correct
event = event.with_context(tz=event.date_tz or 'UTC')
sorted_sponsors = request.env['event.sponsor'].sudo().search(
search_domain
).sorted(lambda sponsor: (sponsor.sponsor_type_id.sequence, sponsor.sequence))
sponsors_all = request.env['event.sponsor'].sudo().search(search_domain_base)
sponsor_types = sponsors_all.mapped('sponsor_type_id')
sponsor_countries = sponsors_all.mapped('partner_id.country_id').sorted('name')
# organize sponsors into categories to help display
sponsor_categories_dict = OrderedDict()
sponsor_categories = []
is_event_user = request.env.user.has_group('event.group_event_registration_desk')
for sponsor in sorted_sponsors:
if not sponsor_categories_dict.get(sponsor.sponsor_type_id):
sponsor_categories_dict[sponsor.sponsor_type_id] = request.env['event.sponsor'].sudo()
sponsor_categories_dict[sponsor.sponsor_type_id] |= sponsor
for sponsor_category, sponsors in sponsor_categories_dict.items():
# To display random published sponsors first and random unpublished sponsors last
if is_event_user:
published_sponsors = sponsors.filtered(lambda s: s.website_published)
unpublished_sponsors = sponsors - published_sponsors
random_sponsors = sample(published_sponsors, len(published_sponsors)) + sample(unpublished_sponsors, len(unpublished_sponsors))
else:
random_sponsors = sample(sponsors, len(sponsors))
sponsor_categories.append({
'sponsorship': sponsor_category,
'sponsors': random_sponsors,
})
# return rendering values
return {
# event information
'event': event,
'main_object': event,
'sponsor_categories': sponsor_categories,
'hide_sponsors': True,
# search information
'searches': searches,
'search_count': len(sorted_sponsors),
'search_key': searches['search'],
'search_countries': search_countries,
'search_sponsorships': search_sponsorships,
'sponsor_types': sponsor_types,
'sponsor_countries': sponsor_countries,
# environment
'hostname': request.httprequest.host.split(':')[0],
'is_event_user': is_event_user,
}
# ------------------------------------------------------------
# FRONTEND FORM
# ------------------------------------------------------------
@http.route(['''/event/<model("event.event", "[('exhibitor_menu', '=', True)]"):event>/exhibitor/<model("event.sponsor", "[('event_id', '=', event.id)]"):sponsor>'''],
type='http', auth="public", website=True, sitemap=True)
def event_exhibitor(self, event, sponsor, **options):
try:
sponsor.check_access_rule('read')
except exceptions.AccessError:
raise Forbidden()
sponsor = sponsor.sudo()
if 'widescreen' not in options and sponsor.chat_room_id and sponsor.is_in_opening_hours:
options['widescreen'] = True
return request.render(
"website_event_exhibitor.event_exhibitor_main",
self._event_exhibitor_get_values(event, sponsor, **options)
)
def _event_exhibitor_get_values(self, event, sponsor, **options):
# search for exhibitor list
search_domain_base = self._get_event_sponsors_base_domain(event)
search_domain_base = expression.AND([
search_domain_base,
[('id', '!=', sponsor.id)]
])
sponsors_other = request.env['event.sponsor'].sudo().search(search_domain_base)
current_country = sponsor.partner_id.country_id
sponsors_other = sponsors_other.sorted(key=lambda sponsor: (
sponsor.website_published,
sponsor.is_in_opening_hours,
sponsor.partner_id.country_id == current_country,
-1 * sponsor.sponsor_type_id.sequence,
randint(0, 20)
), reverse=True)
option_widescreen = options.get('widescreen', False)
option_widescreen = bool(option_widescreen) if option_widescreen != '0' else False
return {
# event information
'event': event,
'main_object': sponsor,
'sponsor': sponsor,
'hide_sponsors': True,
# sidebar
'sponsors_other': sponsors_other[:30],
# options
'option_widescreen': option_widescreen,
'option_can_edit': request.env.user.has_group('event.group_event_user'),
# environment
'hostname': request.httprequest.host.split(':')[0],
'is_event_user': request.env.user.has_group('event.group_event_registration_desk'),
}
# ------------------------------------------------------------
# BUSINESS / MISC
# ------------------------------------------------------------
@http.route('/event_sponsor/<int:sponsor_id>/read', type='json', auth='public', website=True)
def event_sponsor_read(self, sponsor_id):
""" Marshmalling data for "event not started / sponsor not available" modal """
sponsor = request.env['event.sponsor'].browse(sponsor_id)
sponsor_data = sponsor.read([
'name', 'subtitle',
'url', 'email', 'phone',
'website_description', 'website_image_url',
'hour_from', 'hour_to', 'is_in_opening_hours',
'event_date_tz', 'country_flag_url',
])[0]
if sponsor.country_id:
sponsor_data['country_name'] = sponsor.country_id.name
sponsor_data['country_id'] = sponsor.country_id.id
else:
sponsor_data['country_name'] = False
sponsor_data['country_id'] = False
# needs sudo access as public users can't read the model
sponsor_type_sudo = sponsor.sponsor_type_id.sudo()
sponsor_data['sponsor_type_name'] = sponsor_type_sudo.name
sponsor_data['sponsor_type_id'] = sponsor_type_sudo.id
sponsor_data['event_name'] = sponsor.event_id.name
sponsor_data['event_is_ongoing'] = sponsor.event_id.is_ongoing
sponsor_data['event_is_done'] = sponsor.event_id.is_done
sponsor_data['event_start_today'] = sponsor.event_id.start_today
sponsor_data['event_start_remaining'] = sponsor.event_id.start_remaining
sponsor_data['event_date_begin_located'] = sponsor.event_id.date_begin_located
sponsor_data['event_date_end_located'] = sponsor.event_id.date_end_located
sponsor_data['hour_from_str'] = format_duration(sponsor_data['hour_from'])
sponsor_data['hour_to_str'] = format_duration(sponsor_data['hour_to'])
return sponsor_data
# ------------------------------------------------------------
# TOOLS
# ------------------------------------------------------------
def _get_search_countries(self, country_search):
# TDE FIXME: make me generic (slides, event, ...)
country_ids = set(request.httprequest.form.getlist('sponsor_country'))
try:
country_ids.update(literal_eval(country_search))
except Exception:
pass
# perform a search to filter on existing / valid tags implicitly
return request.env['res.country'].sudo().search([('id', 'in', list(country_ids))])
def _get_search_sponsorships(self, sponsorship_search):
# TDE FIXME: make me generic (slides, event, ...)
sponsorship_ids = set(request.httprequest.form.getlist('sponsor_type'))
try:
sponsorship_ids.update(literal_eval(sponsorship_search))
except Exception:
pass
# perform a search to filter on existing / valid tags implicitly
return request.env['event.sponsor.type'].sudo().search([('id', 'in', list(sponsorship_ids))])