Skip to content

Commit

Permalink
[FIX] event_sale: failed payment on soldout events
Browse files Browse the repository at this point in the history
When there's a quotation for events registrations and the seats are
limited, if the customer pays the quoutation the payment will fail when
the quoutation gets confirmed.

With this change we prevent the customer from paying that event that is
soldout.

Steps to reproduce:

- Limit the seats for a given event.
- Set autoconfirmation on.
- Create a quotation for a ticket in that event.
- Use the customer preview link to go to the portal view.
- Pay the quotation (i.e. with demo payment method)
- The confirmation crashes as there aren't seats available.

This is an issue as well as the payment is already fulfilled at bank
level, but as the system crashes the callback isn't confirmed at Odoo.
  • Loading branch information
chienandalu committed Jan 21, 2025
1 parent ebba5c2 commit 862ac93
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
1 change: 1 addition & 0 deletions addons/event_sale/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
'views/event_registration_views.xml',
'views/event_views.xml',
'views/sale_order_views.xml',
'views/templates.xml',
'data/event_sale_data.xml',
'data/mail_data.xml',
'report/event_event_templates.xml',
Expand Down
16 changes: 16 additions & 0 deletions addons/event_sale/models/sale_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class SaleOrder(models.Model):
_inherit = "sale.order"

attendee_count = fields.Integer('Attendee Count', compute='_compute_attendee_count')
has_soldout_event = fields.Boolean(compute="_compute_has_soldout_event")

def write(self, vals):
""" Synchronize partner from SO to registrations. This is done notably
Expand Down Expand Up @@ -52,6 +53,21 @@ def _compute_attendee_count(self):
for sale_order in self:
sale_order.attendee_count = attendee_count_data.get(sale_order.id, 0)

def _compute_has_soldout_event(self):
"""Meant to be used in the portal to prevent customers from paying for an event
that is sold out. Not only because we'd overbook the event, but also because it
will probably crash on the confirmation of the order when the registrations
are created."""
self.has_soldout_event = False
for order in self.filtered(lambda x: x.state in ["draft", "sent"]):
order.has_soldout_event = bool(order.order_line.event_id.filtered(
lambda x: x.seats_limited and x.seats_max and x.seats_available <= 0
))

def has_to_be_paid(self, include_draft=False):
has_to_be_paid = super().has_to_be_paid(include_draft=include_draft)
return has_to_be_paid and not self.has_soldout_event

def unlink(self):
self.order_line._unlink_associated_registrations()
return super(SaleOrder, self).unlink()
Expand Down
11 changes: 11 additions & 0 deletions addons/event_sale/views/templates.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="sale_order_portal_template" inherit_id="sale.sale_order_portal_template" name="Event sale order portal">
<xpath expr="//div[@t-if='sale_order.is_expired']" position="before">
<div t-if="sale_order.has_soldout_event" class="alert alert-warning alert-dismissable d-print-none" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"></button>
<strong>The event is sold out!</strong> <a role="button" href="#discussion"><i class="fa fa-comment"/> Contact us for more information.</a>
</div>
</xpath>
</template>
</odoo>

0 comments on commit 862ac93

Please sign in to comment.