[FW][MERGE] (website_)event(_*): improve customer flow

PURPOSE

Provide some fixes after internal test deployment of event online features.
Notably: user registration flow, clean various access rules, improve copy
writing and typography in various templates.

See sub commits for more details.

UPDATE

  * event.access_event_tag
  * website_event.access_event_type_public
  * website_event.index_topbar
  * website_event.layout
  * website_event_track.track_view
  * website_event_questions.registration_attendee_details_questions
  * website_event_meet.community_main
  * website_event_meet.meeting_room_card
  * website_event_meet.community_aside
  * website_event_meet_quiz.community_leaderboard_small

New records
  * event.ir_rule_event_event_ticket_company
  * event.access_event_registration_all
  * website_event_online.ir_rule_event_tag_public
  * website_event_questions.ir_rule_event_question_published
  * website_event_questions.ir_rule_event_question_event_user
  * website_event_questions.ir_rule_event_question_answer_published
  * website_event_questions.ir_rule_event_question_answer_event_user
  * website_event_track.ir_rule_event_track_tag_public

Remove
  * event.access_event_registration_employee
  * event.access_event_registration_portal
  * website_event_sale.access_event_product_product_public
  * website_event_sale.access_event_product_template_public

LINKS

Task ID-2169118
Task ID-2314778
odoo/odoo#55967
odoo/enterprise#12438

closes odoo/odoo#56007

Forward-port-of: odoo/odoo#55967
Related: odoo/enterprise#12458
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Odoo's Mergebot
2020-08-17 19:43:40 +02:00
committed by GitHub
41 changed files with 442 additions and 121 deletions
+7 -16
View File
@@ -29,27 +29,18 @@
<record model="ir.rule" id="event_event_company_rule">
<field name="name">Event: multi-company</field>
<field name="model_id" ref="model_event_event"/>
<field name="domain_force">['|',
('company_id', '=', False),
('company_id', 'in', company_ids),
]
</field>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
</record>
<record model="ir.rule" id="event_registration_company_rule">
<field name="name">Event/Registration: multi-company</field>
<field name="model_id" ref="model_event_registration"/>
<field name="domain_force">['|',
('company_id', '=', False),
('company_id', 'in', company_ids),
]
</field>
<field name="domain_force">['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
</record>
<record model="ir.rule" id="event_registration_portal">
<field name="name">Event/Registration: Portal</field>
<field name="model_id" ref="model_event_registration"/>
<field name="groups" eval="[(4, ref('base.group_portal'))]"/>
<field name="domain_force">['|', ('email', '=', user.partner_id.email), ('partner_id', '=', user.partner_id.id)]
</field>
<record id="ir_rule_event_event_ticket_company" model="ir.rule">
<field name="name">Event/Ticket: multi-company</field>
<field name="model_id" ref="model_event_event_ticket"/>
<field name="domain_force">['|', ('event_id.company_id', '=', False), ('event_id.company_id', 'in', company_ids)]</field>
</record>
</data>
</odoo>
+2 -3
View File
@@ -9,8 +9,7 @@ access_event_event_manager,event.event.manager,model_event_event,event.group_eve
access_event_event_ticket_user,event.event.ticket.user,model_event_event_ticket,event.group_event_user,1,0,0,0
access_event_event_ticket_manager,event.event.ticket.manager,model_event_event_ticket,event.group_event_manager,1,1,1,1
access_event_registration,event.registration,model_event_registration,event.group_event_user,1,1,1,1
access_event_registration_employee,event.registration,model_event_registration,base.group_user,1,0,0,0
access_event_registration_portal,event.registration,model_event_registration,base.group_portal,1,0,0,0
access_event_registration_all,event.registration,model_event_registration,,0,0,0,0
access_event_mail,event.mail,model_event_mail,event.group_event_user,1,0,0,0
access_event_mail_manager,event.mail manager,model_event_mail,event.group_event_manager,1,1,1,1
access_event_mail_registration,event.mail.registration,model_event_mail_registration,event.group_event_user,1,0,0,0
@@ -21,5 +20,5 @@ access_event_stage_user,event.stage.user,model_event_stage,event.group_event_use
access_event_stage_manager,event.stage.manager,model_event_stage,event.group_event_manager,1,1,1,1
access_event_category,event.tag.category,model_event_tag_category,event.group_event_user,1,0,0,0
access_event_category_manager,event.tag.category manager,model_event_tag_category,event.group_event_manager,1,1,1,1
access_event_tag,event.tag,model_event_tag,event.group_event_user,1,0,0,0
access_event_tag,event.tag,model_event_tag,event.group_event_user,1,1,0,0
access_event_tag_manager,event.tag manager,model_event_tag,event.group_event_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
9 access_event_event_ticket_user event.event.ticket.user model_event_event_ticket event.group_event_user 1 0 0 0
10 access_event_event_ticket_manager event.event.ticket.manager model_event_event_ticket event.group_event_manager 1 1 1 1
11 access_event_registration event.registration model_event_registration event.group_event_user 1 1 1 1
12 access_event_registration_employee access_event_registration_all event.registration model_event_registration base.group_user 1 0 0 0 0
access_event_registration_portal event.registration model_event_registration base.group_portal 1 0 0 0
13 access_event_mail event.mail model_event_mail event.group_event_user 1 0 0 0
14 access_event_mail_manager event.mail manager model_event_mail event.group_event_manager 1 1 1 1
15 access_event_mail_registration event.mail.registration model_event_mail_registration event.group_event_user 1 0 0 0
20 access_event_stage_manager event.stage.manager model_event_stage event.group_event_manager 1 1 1 1
21 access_event_category event.tag.category model_event_tag_category event.group_event_user 1 0 0 0
22 access_event_category_manager event.tag.category manager model_event_tag_category event.group_event_manager 1 1 1 1
23 access_event_tag event.tag model_event_tag event.group_event_user 1 0 1 0 0
24 access_event_tag_manager event.tag manager model_event_tag event.group_event_manager 1 1 1 1
@@ -96,6 +96,7 @@ tour.register('event_tour', {
}, {
trigger: 'button.o_kanban_add',
content: _t("Click <b>add</b> to create a new stage."),
position: 'bottom',
width: 200,
run: 'click',
}].filter(Boolean));
@@ -58,11 +58,6 @@ class TestEventSecurity(TestEventCommon):
'name': 'TestEvent Modified',
})
# with self.assertRaises(AccessError):
# self.env['event.stage'].create({
# 'name': 'TestStage',
# })
@users('user_eventmanager')
@mute_logger('odoo.models.unlink', 'odoo.addons.base.models.ir_model')
def test_event_access_event_manager(self):
+9 -7
View File
@@ -24,7 +24,7 @@ class EventTemplateTicket(models.Model):
digits='Product Price', readonly=False, store=True)
price_reduce = fields.Float(
string="Price Reduce", compute="_compute_price_reduce",
digits='Product Price')
compute_sudo=True, digits='Product Price')
@api.depends('product_id')
def _compute_price(self):
@@ -47,7 +47,7 @@ class EventTemplateTicket(models.Model):
def _compute_price_reduce(self):
for ticket in self:
product = ticket.product_id
discount = product.lst_price and (product.lst_price - product.price) / product.lst_price or 0.0
discount = (product.lst_price - product.price) / product.lst_price if product.lst_price else 0.0
ticket.price_reduce = (1.0 - discount) * ticket.price
def _init_column(self, column_name):
@@ -97,14 +97,16 @@ class EventTicket(models.Model):
_order = "event_id, price"
# product
price_reduce_taxinc = fields.Float(string='Price Reduce Tax inc', compute='_compute_price_reduce_taxinc')
price_reduce_taxinc = fields.Float(
string='Price Reduce Tax inc', compute='_compute_price_reduce_taxinc',
compute_sudo=True)
def _compute_price_reduce_taxinc(self):
for record in self:
for event in self:
# sudo necessary here since the field is most probably accessed through the website
tax_ids = record.sudo().product_id.taxes_id.filtered(lambda r: r.company_id == record.event_id.company_id)
taxes = tax_ids.compute_all(record.price_reduce, record.event_id.company_id.currency_id, 1.0, product=record.product_id)
record.price_reduce_taxinc = taxes['total_included']
tax_ids = event.product_id.taxes_id.filtered(lambda r: r.company_id == event.event_id.company_id)
taxes = tax_ids.compute_all(event.price_reduce, event.event_id.company_id.currency_id, 1.0, product=event.product_id)
event.price_reduce_taxinc = taxes['total_included']
@api.depends('product_id.active')
def _compute_sale_available(self):
@@ -91,9 +91,12 @@ var registerSteps = [{
$("input[name='1-name']").val("Raoulette Poiluchette");
$("input[name='1-phone']").val("0456112233");
$("input[name='1-email']").val("raoulette@example.com");
$("select[name*='question_answer-1']").val($("select[name*='question_answer-1'] option:contains('Consumers')").val());
$("input[name='2-name']").val("Michel Tractopelle");
$("input[name='2-phone']").val("0456332211");
$("input[name='2-email']").val("michel@example.com");
$("select[name*='question_answer-2']").val($("select[name*='question_answer-1'] option:contains('Research')").val());
$("textarea[name*='question_answer']").text("An unicorn told me about you. I ate it afterwards.");
},
}, {
content: "Validate attendees details",
@@ -101,8 +104,15 @@ var registerSteps = [{
trigger: 'button:contains("Continue")',
run: 'click',
}, {
trigger: 'h3:contains("Registration confirmed!")',
trigger: 'div.o_wereg_confirmed_attendees span:contains("Raoulette Poiluchette")',
run: function () {} // check
}, {
trigger: 'div.o_wereg_confirmed_attendees span:contains("Michel Tractopelle")',
run: function () {} // check
}, {
content: "Click on 'register favorites talks' button",
trigger: 'a:contains("register to your favorites talks now")',
run: 'click',
}];
/**
+5 -15
View File
@@ -3,7 +3,6 @@
from datetime import datetime, timedelta, time
from odoo import fields
from odoo.addons.base.tests.common import HttpCaseWithUserDemo, HttpCaseWithUserPortal
from odoo.addons.event_crm.tests.common import TestEventCrmCommon
from odoo.addons.sales_team.tests.common import TestSalesCommon
@@ -209,27 +208,18 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, EventDtPatc
# ------------------------------------------------------------
self.event_question_1 = self.env['event.question'].create({
'title': 'Question1',
'title': 'Which field are you working in',
'question_type': 'simple_choice',
'event_id': self.event.id,
'once_per_order': False,
'answer_ids': [
(0, 0, {'name': 'Q1-Answer1'}),
(0, 0, {'name': 'Q1-Answer2'})
(0, 0, {'name': 'Consumers'}),
(0, 0, {'name': 'Sales'}),
(0, 0, {'name': 'Research'}),
],
})
self.event_question_2 = self.env['event.question'].create({
'title': 'Question2',
'question_type': 'simple_choice',
'event_id': self.event.id,
'once_per_order': True,
'answer_ids': [
(0, 0, {'name': 'Q2-Answer1'}),
(0, 0, {'name': 'Q2-Answer2'})
],
})
self.event_question_3 = self.env['event.question'].create({
'title': 'Question3',
'title': 'How did you hear about us ?',
'question_type': 'text_box',
'event_id': self.event.id,
'once_per_order': True,
@@ -16,3 +16,29 @@ class TestWEventRegister(TestWEventCommon):
'odoo.__DEBUG__.services["web_tour.tour"].tours.wevent_register.ready',
login=None
)
new_registrations = self.event.registration_ids
visitor = new_registrations.visitor_id
# check registration content
self.assertEqual(len(new_registrations), 2)
self.assertEqual(
set(new_registrations.mapped("name")),
set(["Raoulette Poiluchette", "Michel Tractopelle"])
)
self.assertEqual(
set(new_registrations.mapped("phone")),
set(["0456112233", "0456332211"])
)
self.assertEqual(
set(new_registrations.mapped("email")),
set(["raoulette@example.com", "michel@example.com"])
)
# check visitor stored information
self.assertEqual(visitor.name, "Raoulette Poiluchette")
self.assertEqual(visitor.event_registration_ids, new_registrations)
self.assertEqual(visitor.partner_id, self.env['res.partner'])
self.assertEqual(visitor.mobile, "0456112233")
self.assertEqual(visitor.email, "raoulette@example.com")
self.assertFalse(visitor.parent_id)
self.assertTrue(visitor.active)
+1
View File
@@ -16,6 +16,7 @@
'views/event_templates.xml',
'views/event_templates_misc_pages.xml',
'views/event_templates_registration.xml',
'views/website_templates.xml',
'views/event_views.xml',
'security/ir.model.access.csv',
'security/event_security.xml',
+19 -10
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
import collections
import babel.dates
import re
import werkzeug
from werkzeug.datastructures import OrderedMultiDict
from werkzeug.exceptions import NotFound
from ast import literal_eval
from collections import defaultdict
@@ -13,6 +15,7 @@ from dateutil.relativedelta import relativedelta
from odoo import fields, http, _
from odoo.addons.http_routing.models.ir_http import slug
from odoo.addons.website.controllers.main import QueryURL
from odoo.addons.event.controllers.main import EventController
from odoo.http import request
from odoo.osv import expression
from odoo.tools.misc import get_lang, format_date
@@ -27,7 +30,7 @@ class WebsiteEventController(http.Controller):
@http.route(['/event', '/event/page/<int:page>', '/events', '/events/page/<int: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']
SudoEventType = request.env['event.type'].sudo()
searches.setdefault('search', '')
searches.setdefault('date', 'all')
@@ -95,7 +98,7 @@ class WebsiteEventController(http.Controller):
current_date = date[1]
if searches["type"] != 'all':
current_type = EventType.browse(int(searches['type']))
current_type = SudoEventType.browse(int(searches['type']))
domain_search["type"] = [("event_type_id", "=", int(searches["type"]))]
if searches["country"] != 'all' and searches["country"] != 'online':
@@ -296,6 +299,9 @@ class WebsiteEventController(http.Controller):
@http.route(['/event/<model("event.event"):event>/registration/new'], type='json', auth="public", methods=['POST'], website=True)
def registration_new(self, event, **post):
if not event.can_access_from_current_website():
raise werkzeug.exceptions.NotFound()
tickets = self._process_tickets_form(event, post)
availability_check = True
if event.seats_limited:
@@ -311,14 +317,16 @@ class WebsiteEventController(http.Controller):
def _process_attendees_form(self, event, form_details):
""" Process data posted from the attendee details form.
:param details: posted data from frontend registration form, like
:param form_details: posted data from frontend registration form, like
{'1-name': 'r', '1-email': 'r@r.com', '1-phone': '', '1-event_ticket_id': '1'}
"""
registration_fields = request.env['event.registration']._fields
allowed_fields = {'name', 'phone', 'email', 'mobile', 'event_id', 'partner_id', 'event_ticket_id'}
registration_fields = {key: v for key, v in request.env['event.registration']._fields.items() if key in allowed_fields}
registrations = {}
global_values = {}
for key, value in form_details.items():
counter, field_name = key.split('-', 1)
counter, attr_name = key.split('-', 1)
field_name = attr_name.split('-')[0]
if field_name not in registration_fields:
continue
elif isinstance(registration_fields[field_name], (fields.Many2one, fields.Integer)):
@@ -327,12 +335,13 @@ class WebsiteEventController(http.Controller):
value = value
if counter == '0':
global_values[field_name] = value
global_values[attr_name] = value
else:
registrations.setdefault(counter, dict())[field_name] = value
registrations.setdefault(counter, dict())[attr_name] = value
for key, value in global_values.items():
for registration in registrations.values():
registration[key] = value
return list(registrations.values())
def _create_attendees_from_registration_post(self, event, registration_data):
@@ -351,11 +360,11 @@ class WebsiteEventController(http.Controller):
raise werkzeug.exceptions.NotFound()
registrations = self._process_attendees_form(event, post)
attendees = self._create_attendees_from_registration_post(event, registrations)
attendees_sudo = self._create_attendees_from_registration_post(event, registrations)
urls = event._get_event_resource_urls()
return request.render("website_event.registration_complete", {
'attendees': attendees,
'attendees': attendees_sudo,
'event': event,
'google_url': urls.get('google_url'),
'iCal_url': urls.get('iCal_url')
@@ -369,6 +378,6 @@ class WebsiteEventController(http.Controller):
except:
pass
else:
# perform a search to filter on existing / valid tags implicitely
# perform a search to filter on existing / valid tags implicitely + apply rules on color
tags = request.env['event.tag'].search([('id', 'in', tag_ids)])
return tags
+21 -9
View File
@@ -131,7 +131,9 @@ msgstr ""
#. module: website_event
#: model_terms:ir.ui.view,arch_db:website_event.layout
msgid "<i class=\"fa fa-long-arrow-left text-primary mr-2\"/>All Events"
msgid ""
"<i class=\"fa fa-long-arrow-left text-primary mr-2\"/>\n"
" <span>All Events</span>"
msgstr ""
#. module: website_event
@@ -165,6 +167,14 @@ msgstr ""
msgid "<span class=\"navbar-brand h4 my-0 mr-auto\">Events</span>"
msgstr ""
#. module: website_event
#: model_terms:ir.ui.view,arch_db:website_event.registration_template
msgid ""
"<span class=\"o_wevent_badge badge badge-success ml-3\">\n"
" <i class=\"fa fa-check mr-2\"/>Registered\n"
" </span>"
msgstr ""
#. module: website_event
#: model_terms:ir.ui.view,arch_db:website_event.registration_template
msgid ""
@@ -177,14 +187,6 @@ msgstr ""
msgid "<span class=\"text-dark font-weight-bold align-middle pr-2\">Qty</span>"
msgstr ""
#. module: website_event
#: model_terms:ir.ui.view,arch_db:website_event.registration_template
msgid ""
"<span class=\"text-success ml-3\">\n"
" <i class=\"fa fa-check mr-2\"/>Registered\n"
" </span>"
msgstr ""
#. module: website_event
#: model_terms:ir.ui.view,arch_db:website_event.registration_template
msgid ""
@@ -628,6 +630,16 @@ msgstr ""
msgid "Sales start on"
msgstr ""
#. module: website_event
#: model_terms:ir.ui.view,arch_db:website_event.layout
msgid "Search an event ..."
msgstr ""
#. module: website_event
#: model_terms:ir.ui.view,arch_db:website_event.index_topbar
msgid "Search an event..."
msgstr ""
#. module: website_event
#: model_terms:ir.ui.view,arch_db:website_event.country_events_list
msgid "See all events from"
+5 -1
View File
@@ -45,7 +45,7 @@ class Event(models.Model):
email = self.env.user.partner_id.email
for event in self:
domain = ['&', '|', ('email', '=', email), ('partner_id', '=', self.env.user.partner_id.id), ('event_id', '=', event.id)]
event.is_participating = self.env['event.registration'].search_count(domain)
event.is_participating = self.env['event.registration'].sudo().search_count(domain)
else:
self.is_participating = False
@@ -193,6 +193,10 @@ class Event(models.Model):
# ------------------------------------------------------------
def google_map_link(self, zoom=8):
""" Temporary method for stable """
return self._google_map_link(zoom=zoom)
def _google_map_link(self, zoom=8):
self.ensure_one()
if self.address_id:
return self.sudo().address_id.google_map_link(zoom=zoom)
@@ -2,7 +2,7 @@
<odoo>
<data noupdate="1">
<record id="event_event_public" model="ir.rule">
<field name="name">event: Public</field>
<field name="name">Event: public/portal: published read</field>
<field name="model_id" ref="event.model_event_event"/>
<field name="domain_force">[('website_published', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal'))]"/>
@@ -13,7 +13,7 @@
</record>
<record id="ir_rule_event_event_ticket_public" model="ir.rule">
<field name="name">Event ticket: public/portal may read published</field>
<field name="name">Event Ticket: public/portal: published read</field>
<field name="model_id" ref="event.model_event_event_ticket"/>
<field name="domain_force">[('event_id.website_published', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal'))]"/>
@@ -1,7 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_event_event_public,event.event.public,event.model_event_event,base.group_public,1,0,0,0
access_event_event_portal,event.event.portal,event.model_event_event,base.group_portal,1,0,0,0
access_event_type_public,event.type.public,event.model_event_type,,1,0,0,0
access_event_type_public,event.type.public,event.model_event_type,,0,0,0,0
access_event_event_ticket_public,event.event.ticket.public,event.model_event_event_ticket,base.group_public,1,0,0,0
access_event_event_ticket_portal,event.event.ticket.portal,event.model_event_event_ticket,base.group_portal,1,0,0,0
access_event_category_public,event.tag.category.public,event.model_event_tag_category,,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_event_event_public event.event.public event.model_event_event base.group_public 1 0 0 0
3 access_event_event_portal event.event.portal event.model_event_event base.group_portal 1 0 0 0
4 access_event_type_public event.type.public event.model_event_type 1 0 0 0 0
5 access_event_event_ticket_public event.event.ticket.public event.model_event_event_ticket base.group_public 1 0 0 0
6 access_event_event_ticket_portal event.event.ticket.portal event.model_event_event_ticket base.group_portal 1 0 0 0
7 access_event_category_public event.tag.category.public event.model_event_tag_category 1 0 0 0
@@ -151,7 +151,7 @@
// Multi-line event title, even in mobile mode
nav > div > a.navbar-brand {
text-overflow: revert;
white-space: break-spaces;
white-space: normal;
overflow: hidden;
max-width: calc(100% - 80px);
}
+1
View File
@@ -5,3 +5,4 @@ from . import common
from . import test_event_internals
from . import test_ui
from . import test_website_event
from . import test_website_event_access
@@ -0,0 +1,126 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from functools import partial
from datetime import datetime, timedelta
from odoo.tests import HttpCase, new_test_user, tagged
from odoo.tools import mute_logger
@tagged('post_install', '-at_install')
class TestWebsiteEventAccess(HttpCase):
def setUp(self):
super(TestWebsiteEventAccess, self).setUp()
self.events = self.env['event.event'].create([{
'name': 'Event 0 - Sitemap test',
'website_published': True,
'date_begin': datetime.today() - timedelta(days=1),
'date_end': datetime.today() + timedelta(days=1),
}, {
'name': 'Event 1 - Sitemap test',
'website_published': True,
'date_begin': datetime.today() - timedelta(days=1),
'date_end': datetime.today() + timedelta(days=1),
}, {
'name': 'Event 2 - Sitemap test',
'date_begin': datetime.today() - timedelta(days=1),
'date_end': datetime.today() + timedelta(days=1),
}])
event_new_test_user = partial(new_test_user, context={'mail_create_nolog': True, 'mail_create_nosubscribe': True, 'mail_notrack': True, 'no_reset_password': True})
self.event_manager = event_new_test_user(
self.env, name='Gandalf le blanc', login='event_manager', password='event_manager', email='event.manager@example.com',
groups='event.group_event_manager,base.group_user'
)
self.event_user = event_new_test_user(
self.env, name='Frodon Sacquet', login='event_user', password='event_user', email='event.user@example.com',
groups='event.group_event_user,base.group_user'
)
self.portal_user = event_new_test_user(
self.env, name='Smeagol', login='user_portal', password='user_portal', email='portal@example.com',
groups='base.group_portal'
)
def test_sitemap(self):
resp = self.url_open('/sitemap.xml')
self.assertTrue('/event/event-0' in resp.text, 'Published events must be present in the sitemap')
self.assertTrue('/event/event-1' in resp.text, 'Published events must be present in the sitemap')
self.assertFalse('/event/event-2' in resp.text, 'Unpublished events must not be present in the sitemap')
def test_events_access_1(self):
"""Access to a published event with public user."""
published_events = self.events.filtered(lambda event: event.website_published)
resp = self.url_open('/event/%i' % published_events[0].id)
self.assertEqual(resp.status_code, 200, 'We must have access to published event')
def test_events_access_2(self):
"""Access to an unpublished event with public user."""
with mute_logger('odoo.addons.http_routing.models.ir_http'):
unpublished_events = self.events.filtered(lambda event: not event.website_published)
resp = self.url_open('/event/%i' % unpublished_events[0].id)
self.assertEqual(resp.status_code, 403, 'We must not have access to unpublished event')
def test_events_access_3(self):
"""Access to an published event with admin user."""
self.authenticate('event_manager', 'event_manager')
published_events = self.events.filtered(lambda event: event.website_published)
resp = self.url_open('/event/%i' % published_events[0].id)
self.assertEqual(resp.status_code, 200, 'Admin must have access to published event.')
def test_events_access_4(self):
"""Access to an unpublished event with admin user."""
self.authenticate('event_manager', 'event_manager')
unpublished_events = self.events.filtered(lambda event: not event.website_published)
resp = self.url_open('/event/%i' % unpublished_events[0].id)
self.assertEqual(resp.status_code, 200, 'Admin must have access to unpublished event.')
def test_events_access_5(self):
"""Access to an published event with event user."""
self.authenticate('event_user', 'event_user')
published_events = self.events.filtered(lambda event: event.website_published)
resp = self.url_open('/event/%i' % published_events[0].id)
self.assertEqual(resp.status_code, 200, 'Event user must have access to published event.')
def test_events_access_6(self):
"""Access to an unpublished event with event user."""
self.authenticate('event_user', 'event_user')
unpublished_events = self.events.filtered(lambda event: not event.website_published)
resp = self.url_open('/event/%i' % unpublished_events[0].id)
self.assertEqual(resp.status_code, 200, 'Event user must have access to unpublished event.')
def test_events_access_7(self):
"""Access to an published event with portal user."""
self.authenticate('user_portal', 'user_portal')
published_events = self.events.filtered(lambda event: event.website_published)
resp = self.url_open('/event/%i' % published_events[0].id)
self.assertEqual(resp.status_code, 200, 'Portal user must have access to published event.')
def test_events_access_8(self):
"""Access to an unpublished event with portal user."""
with mute_logger('odoo.addons.http_routing.models.ir_http'):
self.authenticate('user_portal', 'user_portal')
unpublished_events = self.events.filtered(lambda event: not event.website_published)
resp = self.url_open('/event/%i' % unpublished_events[0].id)
self.assertEqual(resp.status_code, 403, 'Portal user must not have access to unpublished event.')
def test_events_home_page_1(self):
"""Portal can only view the published events."""
self.authenticate('user_portal', 'user_portal')
published_event = self.events.filtered(lambda event: event.website_published)[0]
unpublished_event = self.events.filtered(lambda event: not event.website_published)[0]
resp = self.url_open('/event')
self.assertTrue(unpublished_event.name not in resp.text, 'Portal should not see the unpublished events.')
self.assertTrue(published_event.name in resp.text, 'Portal must see the published events.')
def test_events_home_page_2(self):
"""Admin can see all the events."""
self.authenticate('event_manager', 'event_manager')
published_event = self.events.filtered(lambda event: event.website_published)[0]
unpublished_event = self.events.filtered(lambda event: not event.website_published)[0]
resp = self.url_open('/event')
self.assertTrue(unpublished_event.name in resp.text, 'Admin must see the unpublished events.')
self.assertTrue(published_event.name in resp.text, 'Admin must see the published events.')
+19 -13
View File
@@ -51,7 +51,7 @@
<div class="d-flex align-items-center flex-wrap pl-sm-3 pr-0">
<t t-call="website_event.events_search_box">
<t t-set="_searches" t-value="searches"/>
<t t-set="_placeholder" t-value="'Search an event ...'"/>
<t t-set="_placeholder">Search an event...</t>
</t>
</div>
</div>
@@ -346,29 +346,35 @@
<!-- Event -->
<template id="layout" name="Event">
<t t-call="website.layout">
<!-- Options -->
<t t-set="opt_events_list_categories" t-value="request.website.viewref('website_event.opt_events_list_categories').active"/>
<div id="wrap" class="o_wevent_event js_event">
<t t-if="not event.menu_id">
<nav class="navbar navbar-light border-top shadow-sm d-print-none">
<div class="container">
<a href="/event" class="navbar-brand h4 my-0 mr-4">
<i class="fa fa-long-arrow-left text-primary mr-2"/>All Events
<div class="container align-items-baseline justify-content-start">
<a href="/event" class="navbar-brand h4 my-0 mr-0 mr-md-4">
<i class="fa fa-long-arrow-left text-primary mr-2"/>
<span>All Events</span>
</a>
<ul class="navbar-nav flex-row">
<li class="nav-item mr-3">
<ul class="navbar-nav flex-row ml-md-auto ml-0">
<li t-if="opt_events_list_categories" class="nav-item mr-3">
<a t-attf-href="/event?type=#{event.event_type_id.id}" t-if="event.event_type_id" class="nav-link">
<i class="fa fa-folder-open text-primary mr-2"/><t t-esc="event.event_type_id.name"/>
<i class="fa fa-folder-open text-primary mr-2"/><span t-field="event.event_type_id"/>
</a>
</li>
<li class="nav-item mr-3">
<a t-if="event.country_id" t-attf-href="/event?country=#{event.country_id.id}" class="nav-link">
<i class="fa fa-map-marker text-primary mr-2"/><t t-esc="event.country_id.name"/>
<i class="fa fa-map-marker text-primary mr-2"/><span t-field="event.country_id"/>
</a>
</li>
</ul>
<t t-call="website_event.events_search_box">
<t t-set="_classes" t-value="'ml-auto'"/>
<t t-set="_searches" t-value="searches"/>
</t>
<div class="d-flex align-items-centerflex-wrap pl-sm-3 pr-0">
<t t-call="website_event.events_search_box">
<t t-set="_classes" t-value="'ml-auto'"/>
<t t-set="_searches" t-value="searches"/>
<t t-set="_placeholder">Search an event ...</t>
</t>
</div>
</div>
</nav>
</t>
@@ -461,7 +467,7 @@
"fields": ["phone", "mobile", "email"]
}'/>
<i class="fa fa-map-marker fa-fw" role="img"/>
<a t-att-href="event.google_map_link()" target="_blank">Get the direction</a>
<a t-att-href="event._google_map_link()" target="_blank">Get the direction</a>
</div>
<!-- Organizer -->
<div t-if="event.organizer_id" class="o_wevent_sidebar_block">
@@ -54,4 +54,18 @@
</t>
</template>
<template id="404" name="Event 404">
<t t-call="website.layout">
<div id="wrap">
<div class="oe_structure oe_empty">
<div class="container">
<h1 class="mt-4">Event not found!</h1>
<p>Sorry, the requested event is not available anymore.</p>
<p><a t-attf-href="/event">Return to the event list.</a></p>
</div>
</div>
</div>
</t>
</template>
</odoo>
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- User Navbar -->
<template id="user_navbar_inherit_website_event" inherit_id="website.user_navbar">
<xpath expr="//div[@id='o_new_content_menu_choices']//div[@name='module_website_event']" position="attributes">
<attribute name="name"/>
<attribute name="t-att-data-module-id"/>
<attribute name="t-att-data-module-shortdesc"/>
<attribute name="groups">event.group_event_manager</attribute>
</xpath>
</template>
<!-- User Navbar - Edit Options -->
<template id="event_edit_options" inherit_id="website.user_navbar" name="Edit Event Options">
<xpath expr="//li[@id='edit-page-menu']" position="after">
<t t-if="main_object._name == 'event.event'" t-set="action" t-value="'event.action_event_view'"/>
</xpath>
</template>
</odoo>
@@ -10,6 +10,7 @@
class="text-dark"
method="POST">
<h2>Launch a new topic</h2>
<p>Be sure you are ready to spend at least 10 minutes in the room if you want to initiate a new topic.</p>
<div class="row m-2">
<label class="col-4 mt-2 text-left">Room Topic</label>
<input class="form-control col-8" maxlength="50" name="name" placeholder="e.g. Finance" required="1"/>
@@ -26,10 +26,10 @@
<!-- Meeting Rooms Main Display -->
<template id="community_main" name="Meeting Rooms: Main Display">
<div class="col-12 col-md-8 pl-0 pr-0 pr-md-3 mt-3">
<h1 class="d-flex flex-row justify-content-between">
<h2 class="d-flex flex-row justify-content-between">
<span>Join a room</span>
<div class="dropdown">
<a class="dropdown-toggle o-no-caret btn pr-0" title="Languages Menu"
<a class="dropdown-toggle o-no-caret btn p-0" title="Languages Menu"
aria-label="Dropdown menu" data-display="static" data-toggle="dropdown" href="#" role="button">
<span t-esc="current_lang.name if current_lang else 'All Languages'"/> ▼</a>
<div class="dropdown-menu" role="menu">
@@ -38,7 +38,7 @@
<a class="dropdown-item" role="menuitem" t-as="language" t-attf-href="/event/#{slug(event)}/community?lang=#{language.id}" t-esc="language.name" t-foreach="available_languages"/>
</div>
</div>
</h1>
</h2>
<hr class="mt-2 mb-3"/>
<p class="mt-">Choose a topic that interests you and start talking with the community. <br/> Don't forget to setup your camera and microphone.</p>
<div class="d-flex flex-column justify-content-start align-items-start">
@@ -130,7 +130,7 @@
</button>
</div>
</div>
<span t-esc="meeting_room.summary" class="h5 text-muted"/>
<span class="text-muted" t-field="meeting_room.summary"/>
<div class="d-flex flex-row justify-content-between align-items-center">
<span class="h6 m-0 row">
<span t-esc="meeting_room.room_participant_count"/>&amp;nbsp;
@@ -151,10 +151,9 @@
<template id="community_aside" name="Community: Aside">
<div class="col-md-4 p-0 mt-3 o_wevent_community_aside">
<div class="d-none d-md-block mb-3" t-if="event.meeting_room_allow_creation">
<h1>Launch a new topic</h1>
<h2>Start a topic</h2>
<hr class="mt-2 mb-3"/>
<p>Want to create your own discussion room ?</p>
<p>Be sure you are ready to spend at least 10 minutes in the room if you want to initiate a new topic.</p>
<a href="#" role="button"
class="btn btn-primary o_wevent_create_room_button"
t-if="event.is_ongoing or event.start_today or is_event_manager"
@@ -9,7 +9,7 @@
<template id="community_leaderboard_small" name="Small Leaderboard">
<div class="w-100 d-flex justify-content-between align-items-end o_page_header">
<h1 class="m-0">Leaderboard</h1>
<h2>Leaderboard</h2>
<a t-attf-href="#{'/event/%s/community/leaderboard' % (slug(event))}">View all</a>
</div>
<t t-call="website_event_meet_quiz.visitor_quiz_points_card"/>
@@ -15,6 +15,7 @@
],
'data': [
'security/ir.model.access.csv',
'security/event_security.xml',
'views/assets.xml',
'views/event_event_views.xml',
'views/event_registration_views.xml',
@@ -43,7 +43,7 @@ class WebsiteVisitor(models.Model):
self.flush()
for visitor in self.filtered(lambda visitor: not visitor.email or not visitor.mobile):
linked_registrations = visitor.event_registration_ids.sorted('create_date', reverse=True)
linked_registrations = visitor.event_registration_ids.sorted(lambda reg: (reg.create_date, reg.id), reverse=False)
if not visitor.email:
visitor.email = next((reg.email for reg in linked_registrations if reg.email), False)
if not visitor.mobile:
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo><data noupdate="1">
<record id="ir_rule_event_tag_public" model="ir.rule">
<field name="name">Event Tag: public/portal: color = published</field>
<field name="model_id" ref="event.model_event_tag"/>
<field name="domain_force">['&amp;', ('color', '!=', False), ('color', '!=', 0)]</field>
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
</data></odoo>
@@ -13,6 +13,7 @@
'views/event_registration_views.xml',
'views/event_question_views.xml',
'views/event_templates.xml',
'security/security.xml',
'security/ir.model.access.csv',
],
'demo': [
@@ -23,14 +23,14 @@ class WebsiteEvent(WebsiteEventController):
for key, value in form_details.items():
if 'question_answer' in key and value:
dummy, registration_index, question_id = key.split('-')
question = request.env['event.question'].browse(int(question_id))
question_sudo = request.env['event.question'].browse(int(question_id))
answer_values = None
if question.question_type == 'simple_choice':
if question_sudo.question_type == 'simple_choice':
answer_values = {
'question_id': int(question_id),
'value_answer_id': int(value)
}
elif question.question_type == 'text_box':
elif question_sudo.question_type == 'text_box':
answer_values = {
'question_id': int(question_id),
'value_text_box': value
@@ -66,4 +66,34 @@
<field name="sequence">3</field>
<field name="question_id" ref="website_event_questions.event_0_question_2"/>
</record>
<!-- Questions of: "OpenWood: Furniture Collection Online Reveal" -->
<record id="event_7_question_0" model="event.question">
<field name="title">Which field are you working in</field>
<field name="question_type">simple_choice</field>
<field name="once_per_order" eval="False"/>
<field name="event_id" ref="event.event_7"/>
</record>
<record id="event_7_question_0_answer_0" model="event.question.answer">
<field name="name">Consumers</field>
<field name="sequence">1</field>
<field name="question_id" ref="website_event_questions.event_7_question_0"/>
</record>
<record id="event_7_question_0_answer_1" model="event.question.answer">
<field name="name">Sales</field>
<field name="sequence">2</field>
<field name="question_id" ref="website_event_questions.event_7_question_0"/>
</record>
<record id="event_7_question_0_answer_2" model="event.question.answer">
<field name="name">Research</field>
<field name="sequence">3</field>
<field name="question_id" ref="website_event_questions.event_7_question_0"/>
</record>
<record id="event_7_question_1" model="event.question">
<field name="title">How did you hear about us ?</field>
<field name="question_type">text_box</field>
<field name="once_per_order" eval="True"/>
<field name="event_id" ref="event.event_7"/>
</record>
</data></odoo>
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo><data noupdate="1">
<record id="ir_rule_event_question_published" model="ir.rule">
<field name="name">Event Question: not event groups: event published read</field>
<field name="model_id" ref="website_event_questions.model_event_question"/>
<field name="domain_force">[('event_id.is_published', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
<record id="ir_rule_event_question_event_user" model="ir.rule">
<field name="name">Event Question: event user: read all</field>
<field name="model_id" ref="website_event_questions.model_event_question"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('event.group_event_user'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
<record id="ir_rule_event_question_answer_published" model="ir.rule">
<field name="name">Event Question Answer: not event groups: event published read</field>
<field name="model_id" ref="website_event_questions.model_event_question_answer"/>
<field name="domain_force">[('question_id.event_id.is_published', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal')), (4, ref('base.group_user'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
<record id="ir_rule_event_question_answer_event_user" model="ir.rule">
<field name="name">Event Question Answer: event user: read all</field>
<field name="model_id" ref="website_event_questions.model_event_question_answer"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('event.group_event_user'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
</data></odoo>
@@ -44,7 +44,7 @@ tour.register('test_tickets_questions', {
trigger: 'div:contains("Ticket #2").modal-body select[name*="question_answer"]',
run: 'text Pastafarian'
}, {
trigger: 'div:contains("General questions").modal-body select[name*="question_answer"]',
trigger: 'div.o_wevent_registration_question_global select[name*="question_answer"]',
run: 'text A friend'
}, {
trigger: 'button:contains("Continue")',
@@ -17,8 +17,7 @@
<!-- Generic questions -->
<xpath expr="//*[hasclass('modal-footer')]" position="before">
<t t-if="event.general_question_ids">
<div class="modal-body bg-light border-bottom">
<h5>General questions</h5>
<div class="modal-body bg-light border-bottom o_wevent_registration_question_global">
<div t-foreach="event.general_question_ids" t-as="question" class="row">
<div class="col-lg-6 mt-2">
<t t-call="website_event_questions.registration_event_question">
@@ -15,7 +15,6 @@ Sell event tickets through eCommerce app.
'views/event_event_views.xml',
'views/website_event_templates.xml',
'views/website_sale_templates.xml',
'security/ir.model.access.csv',
'security/website_event_sale_security.xml',
],
'auto_install': True
@@ -1,3 +0,0 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_event_product_product_public,event.product.product.public,product.model_product_product,base.group_public,1,0,0,0
access_event_product_template_public,event.product.template.public,product.model_product_template,base.group_public,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_event_product_product_public event.product.product.public product.model_product_product base.group_public 1 0 0 0
3 access_event_product_template_public event.product.template.public product.model_product_template base.group_public 1 0 0 0
@@ -19,6 +19,7 @@ class TestUi(HttpCaseWithUserDemo):
'user_id': self.env.ref('base.user_admin').id,
'date_begin': (Datetime.today() + timedelta(days=5)).strftime('%Y-%m-%d 07:00:00'),
'date_end': (Datetime.today() + timedelta(days=5)).strftime('%Y-%m-%d 16:30:00'),
'website_published': True,
})
self.env['event.event.ticket'].create([{
@@ -1,15 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record id="event_track_public" model="ir.rule">
<field name="name">event tracks: Public</field>
<field name="model_id" ref="website_event_track.model_event_track"/>
<field name="domain_force">[('website_published', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
<record id="event_track_public" model="ir.rule">
<field name="name">Event Tracks: public/portal: published</field>
<field name="model_id" ref="website_event_track.model_event_track"/>
<field name="domain_force">[('website_published', '=', True)]</field>
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
<record id="ir_rule_event_track_tag_public" model="ir.rule">
<field name="name">Event Track Tag: public/portal: color = published</field>
<field name="model_id" ref="event.model_event_tag"/>
<field name="domain_force">['&amp;', ('color', '!=', False), ('color', '!=', 0)]</field>
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal'))]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_unlink" eval="False"/>
</record>
</odoo>
@@ -1,6 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_event_track_manager,event.track manager,model_event_track,event.group_event_manager,1,1,1,1
access_event_track_tag_public,event.track.tag public,model_event_track_tag,,1,0,0,0
access_event_track_tag_user,event.track.tag public,model_event_track_tag,event.group_event_user,1,1,0,0
access_event_track_tag_manager,event.track.tag manager,model_event_track_tag,event.group_event_manager,1,1,1,1
access_event_track_location_public,event.track.location public,model_event_track_location,,1,0,0,0
access_event_track_location_manager,event.track.location manager,model_event_track_location,event.group_event_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_event_track_manager event.track manager model_event_track event.group_event_manager 1 1 1 1
3 access_event_track_tag_public event.track.tag public model_event_track_tag 1 0 0 0
4 access_event_track_tag_user event.track.tag public model_event_track_tag event.group_event_user 1 1 0 0
5 access_event_track_tag_manager event.track.tag manager model_event_track_tag event.group_event_manager 1 1 1 1
6 access_event_track_location_public event.track.location public model_event_track_location 1 0 0 0
7 access_event_track_location_manager event.track.location manager model_event_track_location event.group_event_manager 1 1 1 1
@@ -239,8 +239,10 @@
<h4 class="card-header">Practical Info</h4>
<div class="card-body">
<b>Date</b><br/>
<span t-field="track.date" t-options='{"hide_seconds":"True"}'/>
<t t-if="event.date_tz">(<span t-field="event.date_tz"/>)</t>
<span t-field="track.date" t-options='{"hide_seconds":"True", "format": "short"}'/>
<t t-if="event.date_tz">
(<span t-field="track.date" t-options='{"format": "zzz"}'/>)
</t>
<br/>
<b>Duration</b><br/>
<span t-field="track.duration" t-options='{"widget": "duration", "unit": "hour", "round": "minute"}'/><br/>
@@ -331,7 +331,7 @@
<field name="model">event.track.stage</field>
<field name="arch" type="xml">
<tree string="Track Stage">
<field name="sequence" widget="handle"/>
<field name="sequence" widget="handle" groups="event.group_event_manager"/>
<field name="name"/>
<field name="fold"/>
</tree>
@@ -2,7 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from ast import literal_eval
from random import randint
from random import randint, sample
from werkzeug.exceptions import NotFound, Forbidden
from odoo import exceptions, http
@@ -82,7 +82,7 @@ class ExhibitorController(WebsiteEventTrackController):
sponsor_categories = [
dict({
'sponsorship': sponsor_category,
'sponsors': sponsors,
'sponsors': sample(sponsors, len(sponsors)),
}) for sponsor_category, sponsors in sponsor_categories.items()]
# return rendering values
@@ -154,7 +154,7 @@ class ExhibitorController(WebsiteEventTrackController):
'sponsor': sponsor,
'hide_sponsors': True,
# sidebar
'sponsors_other': sponsors_other,
'sponsors_other': sponsors_other[:30],
# options
'option_widescreen': option_widescreen,
'option_can_edit': request.env.user.has_group('event.group_event_manager'),
@@ -142,7 +142,7 @@
<template id="exhibitors_display_cards" name="Exhibitors Cards">
<div t-foreach="sponsor_categories" t-as="sponsor_category" class="row mb-3">
<div class="col-12">
<h5 class="m-0" t-esc="sponsor_category['sponsorship'].name"/>
<h2 class="m-0" t-esc="sponsor_category['sponsorship'].name"/>
<hr class="mt-2 pb-1 mb-1"/>
</div>
<div t-foreach="sponsor_category['sponsors']" t-as="sponsor" class="col-md-6 col-lg-3 mb-4">
@@ -176,7 +176,12 @@
<div t-if="sponsor_image_url" class="card-img-top position-static o_wesponsor_bg_image"
t-attf-style="padding-top: 50%; background-image: url(#{sponsor_image_url});">
<div class="o_wesponsor_connect_button">
<a href="#" class="btn btn-primary h3">Connect</a>
<a href="#" class="btn btn-primary h3">
<t t-if="not user_event_manager and not sponsor.event_id.is_ongoing and not event.is_participating">
Register
</t>
<t t-else="">Connect</t>
</a>
</div>
<img class="position-absolute mr-2 mt-2"
style="right: 0; top: 0; max-height: 20px;"
@@ -187,7 +192,12 @@
<div t-else="" class="o_wesponsor_gradient card-img-top position-relative"
style="padding-top: 50%">
<div class="o_wesponsor_connect_button">
<a href="#" class="btn btn-primary h3">Connect</a>
<a href="#" class="btn btn-primary h3">
<t t-if="not user_event_manager and not sponsor.event_id.is_ongoing and not event.is_participating">
Register
</t>
<t t-else="">Connect</t>
</a>
</div>
</div>
</div>