[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:
Jérémy Hennecart (jeh)
2023-10-13 07:33:49 +00:00
parent 4a20cb320b
commit 24ec9e824a
6 changed files with 45 additions and 23 deletions
+7 -16
View File
@@ -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">
+12 -3
View File
@@ -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) &gt; 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>