8000 [FIX] website_event_sale: don't remind people of unavailable tickets · odoo-dev/odoo@33c7146 · GitHub
[go: up one dir, main page]

Skip to content

Commit 33c7146

Browse files
committed
[FIX] website_event_sale: don't remind people of unavailable tickets
Versions -------- - 16.0+ Steps ----- 1. Enable abandoned cart reminder emails; 2. have an event with a limited number of seats; 3. open a cart for a ticket to the event; 4. abandon the cart; 5. have available seats fill up. Issue ----- You still get an email reminding you to buy the ticket, even though it's no longer avaialble. As a consequence, you can still pay the sales order, but it won't get confirmed. Cause ----- There is no custom logic in place for `website_event_sale` to filter out abandoned carts with tickets that are no longer eligible. Additionally, the `is_sold_out` field of tickets can be `False` while the event's `event_registrations_sold_out` field is `True`. Solution -------- - Add the event's `event_registrations_sold_out` field as a dependency to `event.event.ticket`'s `_comute_is_sold_out` method. - Add an override for `_filter_can_send_abandoned_cart_mail` which filters out carts with tickets that are sold out, or events with no free places remaining. opw-4453539 closes odoo#210236 X-original-commit: 21b2fbe Signed-off-by: Jérémy Hennecart (jeh) <jeh@odoo.com> Signed-off-by: Levi Siuzdak <sile@odoo.com>
1 parent 3c224ee commit 33c7146

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

addons/event/models/event_ticket.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,13 @@ def _compute_seats(self):
105105
ticket.seats_available = ticket.seats_max - (ticket.seats_reserved + ticket.seats_used)
106106
ticket.seats_taken = ticket.seats_reserved + ticket.seats_used
107107

108-
@api.depends('seats_limited', 'seats_available')
108+
@api.depends('seats_limited', 'seats_available', 'event_id.event_registrations_sold_out')
109109
def _compute_is_sold_out(self):
110110
for ticket in self:
111-
ticket.is_sold_out = ticket.seats_limited and not ticket.seats_available
111+
ticket.is_sold_out = (
112+
(ticket.seats_limited and not ticket.seats_available)
113+
or ticket.event_id.event_registrations_sold_out
114+
)
112115

113116
@api.constrains('start_sale_datetime', 'end_sale_datetime')
114117
def _constrains_dates_coherency(self):

addons/website_event_sale/models/sale_order.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ def _cart_update_order_line(self, order_line, quantity, **kwargs):
108108

109109
return updated_line
110110

111+
def _filter_can_send_abandoned_cart_mail(self):
112+
# Prevent carts with expired/sold out tickets from being subject of reminder emails
113+
return super()._filter_can_send_abandoned_cart_mail().filtered(
114+
lambda so: all(ticket.sale_available for ticket in so.order_line.event_ticket_id),
115+
)
116+
111117

112118
class SaleOrderLine(models.Model):
113119
_inherit = "sale.order.line"
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# -*- coding: utf-8 -*-
21
# Part of Odoo. See LICENSE file for full copyright and licensing details.
32

43
from . import common
54
from . import test_frontend_buy_tickets
5+
from . import test_website_event_sale_cart
66
from . import test_website_event_sale_pricelist
77
from . import test_website_event_sale
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
from datetime import datetime, timedelta
2+
3+
from odoo import Command
4+
from odoo.tests import tagged
5+
6+
from odoo.addons.website_event_sale.tests.common import TestWebsiteEventSaleCommon
7+
from odoo.addons.website_sale.tests.test_website_sale_cart_abandoned import (
8+
TestWebsiteSaleCartAbandonedCommon,
9+
)
10+
11+
12+
@tagged('post_install', '-at_install')
13+
class TestWebsiteEventSaleCart(TestWebsiteEventSaleCommon, TestWebsiteSaleCartAbandonedCommon):
14+
15+
@classmethod
16+
def setUpClass(cls):
17+
super().setUpClass()
18+
19+
cls.website.write({
20+
'send_abandoned_cart_email': True,
21+
'cart_abandoned_delay': 1.0, # 1 hour
22+
})
23+
cls.website.send_abandoned_cart_email_activation_time -= timedelta(weeks=1)
24+
25+
cls.partner_admin = cls.env.ref('base.partner_admin')
26+
if not cls.partner_admin.email:
27+
cls.partner_admin.email = 'base@partner.admin'
28+
29+
def test_sold_out_event_cart_reminder(self):
30+
"""Check that abandoned cart emails aren't sent for sold out tickets."""
31+
cart1, cart2 = self.env['sale.order'].create([{
32+
'partner_id': partner.id,
33+
'website_id': self.website.id,
34+
'date_order': datetime.now() - timedelta(hours=2),
35+
} for partner in (self.partner_admin, self.partner_portal)])
36+
37+
self.ticket.write({
38+
'seats_limited': True,
39+
'seats_max': 1,
40+
})
41+
42+
create_order_line = [Command.create({
43+
'product_id': self.product_event.id,
44+
'event_id': self.event.id,
45+
'event_ticket_id': self.ticket.id,
46+
})]
47+
cart1.order_line = create_order_line
48+
cart2.order_line = create_order_line
49+
self.assertTrue(
50+
self.send_mail_patched(cart1.id),
51+
"Abandoned cart email should be sent for availlable tickets",
52+
)
53+
54+
# Create registrations & confirm first order
55+
editor = self.env['registration.editor'].new()
56+
editor.with_context(default_sale_order_id=cart1.id).action_make_registration()
57+
cart1.action_confirm()
58+
self.assertEqual(self.ticket.seats_available, 0)
59+
self.assertFalse(
60+
self.send_mail_patched(cart2.id),
61+
"Abandoned cart email should not be sent when ticket has no seats available",
62+
)
63+
64+
# Reset sent state, increase seat limit, and try again
65+
cart2.cart_recovery_email_sent = False
66+
self.ticket.seats_max = 2
67+
se 443D lf.assertTrue(
68+
self.send_mail_patched(cart2.id),
69+
"Abandoned cart email can be sent after increasing seat count",
70+
)

0 commit comments

Comments
 (0)
0