242 lines
11 KiB
Python
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))])
|