Currently, the usability for unpublished exhibitor is not optimum. For example, on `/exhibitors` page, we show the exhibitors in random order where sometimes unpublished ones might come before the published ones. And on the sidebar of the exhibitors, there's no visual indication for unpublished record and they do not always appear after the published ones. Same for the sponsor/exhibitor list that appears at he bottom of almost all event pages. This commit does the following improvements: - For `/exhibitors` page, now first there will be random published exhibitors, and after that, there will be random unpublished exhibitors (class used to lower opacity is now removed as it will be handled by publish management related data attributes). - Clicking on any of this exhibitors, on the left sidebar, now we display unpublished exhibitors at the last, with lower opacity and 'Unpublished' tag. - The 'Connect' button on exhibitors is now positioned absolutely so that the opacity does not apply on it for unpublished exhibitors. - For the sponsors list appearing at the bottom of almost all event pages, now the unpublished sponsors will appear at last with lower opacity and 'Unpublished' tag below them. - In a special case of sponsor list appearing in `/community` page, the unpublished sponsors were displayed to all the users, because the event record was passed with sudo. We remove this sudo attribute, which seems not necessary. taskID-2346612
240 lines
11 KiB
Python
240 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 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')
|
|
sponsors = request.env['event.sponsor'].sudo().search(search_domain)
|
|
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 = dict()
|
|
sponsor_categories = []
|
|
is_event_user = request.env.user.has_group('event.group_event_registration_desk')
|
|
for sponsor in 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_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
|
|
if sponsor.sponsor_type_id:
|
|
sponsor_data['sponsor_type_name'] = sponsor.sponsor_type_id.name
|
|
sponsor_data['sponsor_type_id'] = sponsor.sponsor_type_id.id
|
|
else:
|
|
sponsor_data['sponsor_type_name'] = False
|
|
sponsor_data['sponsor_type_id'] = False
|
|
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))])
|