[FIX] event_sale: reducing quantity from cart cancel extra registrations

Issue: When purchasing tickets for an event, if the quantity of tickets
is reduced directly from the cart, payment can be processed for the
reduced number of tickets while the excess registrations remain
incorrectly open in the database.

Steps to Reproduce:

1 Install Events Online Ticketing.
2 Create or select an event with open registrations.
3 Add 3 registrations to your cart and proceed to checkout.
4 In the payment process, go to 'Review Order' and reduce the quantity
of tickets.
5 Complete the checkout and payment.
6 Upon inspecting the database for the same event, you'll notice an
inconsistency: the number of attendees is higher than it should be.

Solution:
This issue arises from the implementation of
`_compute_registration_status`, which only considers the sale order line
and marks registrations as cancelled only if the entire order line is
cancelled. This means either all 3 registrations are cancelled, or none.
The solution introduced here addresses this by checking for
registrations already marked as cancelled and incorporating them into
the cancellation logic, ensuring accurate tracking of active and
cancelled registrations.

opw-3653452

closes odoo/odoo#150463

Signed-off-by: Jérémy Hennecart (jeh) <jeh@odoo.com>
This commit is contained in:
Maruan Aguerdouh (magm)
2024-02-12 12:31:10 +00:00
parent cb613bc606
commit 23b43b09ad
2 changed files with 37 additions and 3 deletions
@@ -28,13 +28,14 @@ class EventRegistration(models.Model):
def _compute_registration_status(self):
self.filtered(lambda reg: not reg.state).state = 'draft'
for so_line, registrations in self.grouped('sale_order_line_id').items():
cancelled_registrations = registrations.filtered(lambda reg: reg.sale_order_id.state == 'cancel')
cancelled_registrations.state = 'cancel'
cancelled_so_registrations = registrations.filtered(lambda reg: reg.sale_order_id.state == 'cancel')
cancelled_so_registrations.state = 'cancel'
cancelled_registrations = cancelled_so_registrations | registrations.filtered(lambda reg: reg.state == 'cancel')
if not so_line or float_is_zero(so_line.price_total, precision_digits=so_line.currency_id.rounding):
registrations.sale_status = 'free'
registrations.filtered(lambda reg: reg.state == 'draft').write({"state": "open"})
else:
sold_registrations = registrations.filtered(lambda reg: reg.sale_order_id.state == 'sale')
sold_registrations = registrations.filtered(lambda reg: reg.sale_order_id.state == 'sale') - cancelled_registrations
sold_registrations.sale_status = 'sold'
(registrations - sold_registrations).sale_status = 'to_pay'
sold_registrations.filtered(lambda reg: reg.state in {'draft', 'cancel'}).write({"state": "open"})
@@ -73,6 +73,39 @@ class TestEventSale(TestEventSaleCommon):
{'name': 'Test Account Tax Group', 'company_id': cls.env.company.id}
)
@users('user_sales_salesman')
def test_adjusted_quantity_in_sale_order(self):
""" This test ensures that when reducing the quantity of tickets for an event, we will cancel the
registrations for those tickets too.
"""
customer_so = self.customer_so.with_user(self.env.user)
ticket = self.event_0.event_ticket_ids[0]
customer_so.write({
'order_line': [
(0, 0, {
'event_id': self.event_0.id,
'event_ticket_id': ticket.id,
'product_id': ticket.product_id.id,
'product_uom_qty': 3,
'price_unit': 10,
})
]
})
editor = self.env['registration.editor'].with_context({'default_sale_order_id': customer_so.id}).create({})
editor.action_make_registration()
registration_to_cancel = self.event_0.registration_ids[0]
registration_to_cancel.action_cancel()
registrations = self.env['event.registration'].search([('sale_order_id', '=', customer_so.id)])
expected_states = ['draft', 'draft', 'cancel']
actual_states = registrations.sorted('id').mapped('state')
self.assertListEqual(actual_states, expected_states, "One of the registrations should be cancelled.")
@users('user_sales_salesman')
def test_event_crm_sale(self):
TICKET1_COUNT, TICKET2_COUNT = 3, 1