[IMP] {website_}event{_sale}: improve general design
Following the removal of the auto_confirm field on event and the payment_status computation, we improve the design and flow of the event module. - Adapt and simplify the kanban view for event - Add the payment_status on graph view - Improve the payment_status field in registration views (banners) - Fallback on the registration page if there is not enough seats after filling the registrations info with an error message. task-3061849 Part-of: odoo/odoo#126431
This commit is contained in:
@@ -212,24 +212,15 @@
|
||||
<div class="o_kanban_record_title o_text_overflow" t-att-title="record.name.value">
|
||||
<field name="name"/>
|
||||
</div>
|
||||
<div t-if="record.address_id.value" class="d-flex">
|
||||
<i class="fa fa-map-marker mt-1 me-1" title="Location"/>
|
||||
<span t-esc="record.address_id.value"/>
|
||||
<div t-if="record.address_id.value" class="d-flex ps-1">
|
||||
<i class="fa fa-map-marker mt-1 me-2 text-center ps-1" title="Location"/>
|
||||
<span t-esc="record.address_id.value" class="ms-1"/>
|
||||
</div>
|
||||
<div class="d-flex ps-1">
|
||||
<i class="fa fa-group mt-1 me-2 text-center" title="Attendees"/>
|
||||
<span t-out="record.seats_taken.raw_value" class="me-1"/> Attendees
|
||||
</div>
|
||||
</div>
|
||||
<h5 class="p-0">
|
||||
<a name="%(event_registration_action_stats_from_event)d"
|
||||
type="action"
|
||||
context="{'search_default_expected': True}">
|
||||
<t t-esc="record.seats_taken.raw_value"/> Attendees
|
||||
</a>
|
||||
<t t-set="total_seats" t-value="record.seats_reserved.raw_value + record.seats_used.raw_value"/>
|
||||
<div class="pt-2 pt-md-0" t-if="total_seats > 0"><br/>
|
||||
<a class="ps-2" name="%(event_registration_action_stats_from_event)d" type="action" context="{'search_default_confirmed': True}">
|
||||
<i class="fa fa-level-up fa-rotate-90" title="Confirmed"/><span class="ps-2"><t t-esc="total_seats"/> Confirmed</span>
|
||||
</a>
|
||||
</div>
|
||||
</h5>
|
||||
<div class="o_kanban_record_bottom">
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<field name="activity_ids" widget="kanban_activity"/>
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
<field name="arch" type="xml">
|
||||
<field name="event_id" position="after">
|
||||
<field name="sale_order_id" optional="hide"/>
|
||||
<field name="sale_status" optional="hide"/>
|
||||
</field>
|
||||
<field name="state" position="after">
|
||||
<field name="sale_status" optional="show" widget="badge"
|
||||
decoration-success="sale_status == 'sold'"
|
||||
decoration-danger="sale_status == 'to_pay'"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
@@ -31,6 +35,17 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="event_registration_view_graph" model="ir.ui.view">
|
||||
<field name="name">event.registration.graph.inherit.event.sale</field>
|
||||
<field name="model">event.registration</field>
|
||||
<field name="inherit_id" ref="event.view_event_registration_graph"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="event_id" position="after">
|
||||
<field name="sale_status"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="event_registration_ticket_view_form" model="ir.ui.view">
|
||||
<field name="name">event.registration.form.inherit</field>
|
||||
<field name="model">event.registration</field>
|
||||
@@ -49,7 +64,10 @@
|
||||
</xpath>
|
||||
<xpath expr="//group" position="before">
|
||||
<field name="sale_status" invisible="1"/>
|
||||
<widget name="web_ribbon" title="Sold" bg_color="text-bg-success" invisible="sale_status != 'sold'"/>
|
||||
<widget name="web_ribbon" title="Sold" bg_color="text-bg-success"
|
||||
invisible="sale_status != 'sold'"/>
|
||||
<widget name="web_ribbon" title="Not Sold" bg_color="text-bg-danger"
|
||||
invisible="sale_status in ('sold', 'free') or not id"/>
|
||||
</xpath>
|
||||
<group name="utm_link" position="before">
|
||||
<group string="Transaction" groups="base.group_no_one">
|
||||
|
||||
@@ -185,6 +185,7 @@ class WebsiteEventController(http.Controller):
|
||||
'range': range,
|
||||
'google_url': lazy(lambda: urls.get('google_url')),
|
||||
'iCal_url': lazy(lambda: urls.get('iCal_url')),
|
||||
'registration_error_code': post.get('registration_error_code'),
|
||||
}
|
||||
|
||||
def _process_tickets_form(self, event, form_details):
|
||||
@@ -240,7 +241,7 @@ class WebsiteEventController(http.Controller):
|
||||
visitor = request.env['website.visitor']._get_visitor_from_request()
|
||||
if visitor.email:
|
||||
default_first_attendee = {
|
||||
"name": visitor.name,
|
||||
"name": visitor.display_name,
|
||||
"email": visitor.email,
|
||||
"phone": visitor.mobile,
|
||||
}
|
||||
@@ -352,8 +353,16 @@ class WebsiteEventController(http.Controller):
|
||||
|
||||
@http.route(['''/event/<model("event.event"):event>/registration/confirm'''], type='http', auth="public", methods=['POST'], website=True)
|
||||
def registration_confirm(self, event, **post):
|
||||
registrations = self._process_attendees_form(event, post)
|
||||
attendees_sudo = self._create_attendees_from_registration_post(event, registrations)
|
||||
""" Check before creating and finalize the creation of the registrations
|
||||
that we have enough seats for all selected tickets.
|
||||
If we don't, the user is instead redirected to page to register with a
|
||||
formatted error message. """
|
||||
registrations_data = self._process_attendees_form(event, post)
|
||||
event_ticket_ids = {registration['event_ticket_id'] for registration in registrations_data}
|
||||
event_tickets = request.env['event.event.ticket'].browse(event_ticket_ids)
|
||||
if any(event_ticket.seats_limited and event_ticket.seats_available < len(registrations_data) for event_ticket in event_tickets):
|
||||
return request.redirect('/event/%s/register?registration_error_code=insufficient_seats' % event.id)
|
||||
attendees_sudo = self._create_attendees_from_registration_post(event, registrations_data)
|
||||
|
||||
return request.redirect(('/event/%s/registration/success?' % event.id) + werkzeug.urls.url_encode({'registration_ids': ",".join([str(id) for id in attendees_sudo.ids])}))
|
||||
|
||||
|
||||
@@ -148,6 +148,11 @@
|
||||
itemscope="itemscope" itemprop="offers" itemtype="http://schema.org/AggregateOffer">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<div id="o_wevent_tickets" class="o_wevent_theme_bg_base shadow-sm o_wevent_js_ticket_details" data-folded-by-default="0">
|
||||
<div t-if="registration_error_code == 'insufficient_seats'" class="alert alert-danger" role="alert">
|
||||
<p class="mb-0">
|
||||
Registration failed! These tickets are not available anymore.
|
||||
</p>
|
||||
</div>
|
||||
<t t-set="tickets" t-value="event.event_ticket_ids.filtered(lambda ticket: not ticket.is_expired)"/>
|
||||
<!-- If some tickets expired and there is only one type left, we keep the same layout -->
|
||||
<t t-if="len(event.event_ticket_ids) > 1">
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from collections import defaultdict
|
||||
from odoo import _
|
||||
from odoo.http import request, route
|
||||
|
||||
from odoo.addons.website_event.controllers.main import WebsiteEventController
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
<span t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'format': 'LLL'}" class="o_wevent_event_month" />
|
||||
<span t-field="event.with_context(tz=event.date_tz).date_begin" t-options="{'format': 'dd'}" class="o_wevent_event_day oe_hide_on_date_edit" />
|
||||
</div>
|
||||
<small class="o_wevent_participating text-bg-success">
|
||||
<small t-if="event.is_participating" class="o_wevent_participating text-bg-success">
|
||||
<i class="fa fa-check me-2" />
|
||||
Registered
|
||||
</small>
|
||||
|
||||
Reference in New Issue
Block a user