[IMP] {website_}event_sale: add pricelist picker

Purpose
=======
As an Event seller, I might not use the /shop page
because I do not sell goods, only tickets.
That being said, I do this in multi-currency for example,
and need visitors to be able to pick the relevant pricelists.

Specifications
============
Adding the price currency on the event ticket
so that users will know which currency is used.

Adding a pricelist picker on the website event
front-end and on the ticket registration page
to allow the user to display the prices depending
on a selected pricelist.

Task-3081384

closes odoo/odoo#106980

Signed-off-by: Stéphane Debauche (std) <std@odoo.com>
This commit is contained in:
Odoo's Mergebot
2023-01-11 09:38:47 +01:00
committed by GitHub
10 changed files with 79 additions and 12 deletions
+1
View File
@@ -20,6 +20,7 @@ class EventTemplateTicket(models.Model):
product_id = fields.Many2one(
'product.product', string='Product', required=True,
domain=[("detailed_type", "=", "event")], default=_default_product_id)
currency_id = fields.Many2one(related="product_id.currency_id", string="Currency")
price = fields.Float(
string='Price', compute='_compute_price',
digits='Product Price', readonly=False, store=True)
@@ -46,7 +46,8 @@
<field name="product_id" context="{'default_detailed_type': 'event'}"/>
</field>
<field name="description" position="after">
<field name="price"/>
<field name="currency_id" invisible="1"/>
<field name="price" widget="monetary" options="{'currency_field': 'currency_id'}"/>
</field>
</field>
</record>
@@ -150,7 +150,7 @@ class TestEventPerformance(EventPerformanceCase):
has_social = 'social_menu' in self.env['event.event'] # otherwise view may crash in enterprise
# type and website
with freeze_time(self.reference_now), self.assertQueryCount(event_user=445): # tef 400 / com 406
with freeze_time(self.reference_now), self.assertQueryCount(event_user=450): # tef 402 / com 408
self.env.cr._now = self.reference_now # force create_date to check schedulers
# Require for `website_menu` to be visible
# <div name="event_menu_configuration" groups="base.group_no_one">
@@ -453,7 +453,7 @@ class TestOnlineEventPerformance(EventPerformanceCase, UtilPerf):
# website customer data
with freeze_time(self.reference_now):
self.authenticate('user_eventmanager', 'user_eventmanager')
with self.assertQueryCount(default=39): # tef 38
with self.assertQueryCount(default=42): # tef 41
self._test_url_open('/event')
@warmup
@@ -461,7 +461,7 @@ class TestOnlineEventPerformance(EventPerformanceCase, UtilPerf):
# website customer data
with freeze_time(self.reference_now):
self.authenticate(None, None)
with self.assertQueryCount(default=28):
with self.assertQueryCount(default=38):
self._test_url_open('/event')
# @warmup
@@ -12,10 +12,10 @@
<field name="name" placeholder="e.g. &quot;Conference for Architects&quot;" string="Event Name"/>
<field name="address_id" context="{'show_address': 1}" options='{"always_reload": True}'/>
<label for="date_begin" string="Start &#8594; End"/>
<div class="o_row w-100">
<field name="date_begin" widget="daterange" nolabel="1" options="{'related_end_date': 'date_end'}"/>
<div class="d-flex flex-column flex-sm-row align-items-baseline w-100">
<field name="date_begin" style="width: 17ch" widget="daterange" nolabel="1" options="{'related_end_date': 'date_end'}"/>
<i class="fa fa-long-arrow-right mx-2" aria-label="Arrow icon" title="Arrow"/>
<field name="date_end" widget="daterange" nolabel="1" options="{'related_start_date': 'date_begin'}"/>
<field name="date_end" style="width: 17ch" widget="daterange" nolabel="1" options="{'related_start_date': 'date_begin'}"/>
</div>
</group>
</form>
@@ -48,7 +48,7 @@
<nav class="navbar navbar-light border-top shadow-sm d-print-none">
<div class="container">
<div class="d-flex flex-column flex-sm-row justify-content-between w-100">
<span class="navbar-brand h4 my-0 me-auto">Events</span>
<span class="navbar-brand h4 my-0 me-auto pe-sm-4">Events</span>
<ul class="o_wevent_index_topbar_filters nav">
<t t-foreach="categories" t-as="category">
<li t-if="category.is_published and category.tag_ids and any(tag.color for tag in category.tag_ids)" class="nav-item dropdown me-2 my-1">
@@ -22,6 +22,10 @@ Sell event tickets through eCommerce app.
'web.assets_tests': [
'website_event_sale/static/tests/**/*',
],
'web.assets_frontend': [
'website_event_sale/static/src/scss/*.scss',
'website_event_sale/static/src/js/*.js',
],
},
'license': 'LGPL-3',
}
@@ -0,0 +1,16 @@
/** @odoo-module **/
import publicWidget from 'web.public.widget';
publicWidget.registry.ticketDetailsWidget.include({
/**
* Overriding the method to toggle the tickets registration
* pricelist dropdown visibility on ticket details click
*/
_onTicketDetailsClick: function(ev) {
this._super(...arguments);
if (this.foldedByDefault){
$(ev.currentTarget).siblings('#o_wevent_tickets_pricelist').toggleClass('collapse');
}
}
});
@@ -0,0 +1,16 @@
#o_wevent_tickets .o_pricelist_dropdown {
.dropdown-toggle {
color: $gray-600; // text-muted
font-style: italic;
}
.dropdown-toggle:focus {
outline: none;
box-shadow: none;
}
.dropdown-toggle:hover {
text-decoration: underline;
}
.dropdown-item {
font-size: small;
}
}
@@ -2,6 +2,16 @@
<odoo>
<template id="registration_template" inherit_id="website_event.registration_template">
<!-- Change pricelist -->
<xpath expr="//div[hasclass('o_wevent_price_range')]" position="after">
<div id="o_wevent_tickets_pricelist" class="collapse show">
<t t-set="website_sale_pricelists" t-value="website.get_pricelist_available(show_visible=True)" />
<t t-set="hasPricelistDropdown" t-value="website_sale_pricelists and len(website_sale_pricelists)&gt;1"/>
<t t-call="website_sale.pricelist_list">
<t t-set="_classes" t-valuef="d-none d-lg-inline p-0 ms-2 my-1"/>
</t>
</div>
</xpath>
<!-- Add price information on tickets (multi tickets, aka in collapse) -->
<xpath expr="//div[hasclass('o_wevent_registration_multi_select')]" position="inside">
<t t-if="ticket.price">
@@ -20,13 +30,16 @@
<span t-else="" class="fw-bold text-uppercase">Free</span>
</xpath>
<xpath expr="//div[hasclass('o_wevent_price_range')]" position="inside">
<t t-if="event.event_ticket_ids[-1].price_reduce > 0">
<t t-set="all_prices" t-value="event.event_ticket_ids.mapped('price_reduce')"/>
<t t-set="lowest_price" t-value="min(all_prices)"/>
<t t-set="highest_price" t-value="max(all_prices)"/>
<t t-if="highest_price > 0">
<span class="text-dark">
From
<span t-out="event.event_ticket_ids[0].price_reduce" t-options="{'widget': 'monetary', 'from_currency': event.company_id.sudo().currency_id, 'display_currency': website.pricelist_id.currency_id}"/>
<t t-if="event.event_ticket_ids[-1].price_reduce != event.event_ticket_ids[0].price_reduce">
<span t-out="lowest_price" t-options="{'widget': 'monetary', 'from_currency': event.company_id.sudo().currency_id, 'display_currency': website.pricelist_id.currency_id}"/>
<t t-if="lowest_price != highest_price">
to
<span t-out="event.event_ticket_ids[-1].price_reduce" t-options="{'widget': 'monetary', 'from_currency': event.company_id.sudo().currency_id, 'display_currency': website.pricelist_id.currency_id}"/>
<span t-out="highest_price" t-options="{'widget': 'monetary', 'from_currency': event.company_id.sudo().currency_id, 'display_currency': website.pricelist_id.currency_id}"/>
</t>
</span>
</t>
@@ -65,4 +78,10 @@
</xpath>
</template>
<template id="fold_register_details" inherit_id="website_event.fold_register_details" name="Fold ticket details">
<xpath expr="//div[@id='o_wevent_tickets_pricelist']" position="attributes">
<attribute name="class">collapse</attribute>
</xpath>
</template>
</odoo>
@@ -1,6 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="index_topbar" inherit_id="website_event.index_topbar">
<xpath expr="//ul[hasclass('o_wevent_index_topbar_filters')]" position="inside">
<t t-set="website_sale_pricelists" t-value="website.get_pricelist_available(show_visible=True)" />
<t t-set="hasPricelistDropdown" t-value="website_sale_pricelists and len(website_sale_pricelists)&gt;1"/>
<t t-call="website_sale.pricelist_list">
<t t-set="_classes" t-valuef="d-none d-lg-inline me-2 my-1"/>
</t>
</xpath>
</template>
<!-- If the sale order line concerns an event, we want the "product" link to point to the event itself and not to the product on the ecommerce -->
<template id="cart_line_product_link_inherit_website_event_sale" inherit_id="website_sale.cart_line_product_link" name="Event Shopping Cart Line Product Link">
<xpath expr="//a" position="attributes">