From 23b43b09ad410b3ef74e3087935a7254d65700ff Mon Sep 17 00:00:00 2001 From: "Maruan Aguerdouh (magm)" Date: Mon, 22 Jan 2024 17:12:50 +0100 Subject: [PATCH] [FIX] event_sale: reducing quantity from cart cancel extra registrations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- .../event_sale/models/event_registration.py | 7 ++-- addons/event_sale/tests/test_event_sale.py | 33 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/addons/event_sale/models/event_registration.py b/addons/event_sale/models/event_registration.py index e765e016035..9300d610790 100644 --- a/addons/event_sale/models/event_registration.py +++ b/addons/event_sale/models/event_registration.py @@ -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"}) diff --git a/addons/event_sale/tests/test_event_sale.py b/addons/event_sale/tests/test_event_sale.py index 4fd177dc438..e47a45bbe3f 100644 --- a/addons/event_sale/tests/test_event_sale.py +++ b/addons/event_sale/tests/test_event_sale.py @@ -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