From 8bca1f1bcef3e23d024c84bf32f645f11d8d6b5d Mon Sep 17 00:00:00 2001 From: Areeb Jamal Date: Mon, 2 Mar 2020 22:24:49 +0530 Subject: [PATCH] fix: Ticket sold count query (#6871) --- app/api/attendees.py | 11 +++-- .../all/integration/api/helpers/test_order.py | 41 +++++++++++++++---- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/app/api/attendees.py b/app/api/attendees.py index a703ae7254..035aea59e3 100644 --- a/app/api/attendees.py +++ b/app/api/attendees.py @@ -24,14 +24,17 @@ from app.settings import get_settings -def get_sold_and_reserved_tickets_count(event_id): +def get_sold_and_reserved_tickets_count(ticket_id): order_expiry_time = get_settings()['order_expiry_time'] return ( db.session.query(TicketHolder.id) .join(Order) - .filter(TicketHolder.order_id == Order.id) .filter( - Order.event_id == int(event_id), + TicketHolder.ticket_id == ticket_id, + TicketHolder.order_id == Order.id, + TicketHolder.deleted_at.is_(None), + ) + .filter( Order.deleted_at.is_(None), or_( Order.status == 'placed', @@ -82,7 +85,7 @@ def before_post(self, args, kwargs, data): "Ticket belongs to a different Event", ) # Check if the ticket is already sold out or not. - if get_sold_and_reserved_tickets_count(ticket.event_id) >= ticket.quantity: + if get_sold_and_reserved_tickets_count(ticket.id) >= ticket.quantity: raise ConflictException( {'pointer': '/data/attributes/ticket_id'}, "Ticket already sold out" ) diff --git a/tests/all/integration/api/helpers/test_order.py b/tests/all/integration/api/helpers/test_order.py index c2848f69bf..68a40fe95a 100644 --- a/tests/all/integration/api/helpers/test_order.py +++ b/tests/all/integration/api/helpers/test_order.py @@ -62,6 +62,7 @@ def test_count_sold_and_reserved_tickets(self): with self.app.test_request_context(): ticket = TicketFactory() + other_ticket = TicketFactory() completed_order = OrderFactory(status='completed') placed_order = OrderFactory(status='placed') @@ -79,24 +80,48 @@ def test_count_sold_and_reserved_tickets(self): db.session.commit() # will not be counted as they have no order_id - AttendeeFactoryBase.create_batch(2) + AttendeeFactoryBase.create_batch(2, ticket_id=ticket.id) # will be counted as attendee have valid orders - AttendeeFactoryBase.create_batch(6, order_id=completed_order.id) + AttendeeFactoryBase.create_batch( + 6, order_id=completed_order.id, ticket_id=ticket.id + ) # will be counted as attendee has valid placed order - AttendeeFactoryBase(order_id=placed_order.id) + AttendeeFactoryBase(order_id=placed_order.id, ticket_id=ticket.id) + # will not be counted as they are deleted + AttendeeFactoryBase.create_batch( + 3, + order_id=placed_order.id, + ticket_id=ticket.id, + deleted_at=datetime.utcnow(), + ) # will be counted as attendee has initializing order under order expiry time - AttendeeFactoryBase.create_batch(4, order_id=initializing_order.id) + AttendeeFactoryBase.create_batch( + 4, order_id=initializing_order.id, ticket_id=ticket.id + ) # will be counted as attendee has pending order under 30+order expiry time - AttendeeFactoryBase.create_batch(2, order_id=pending_order.id) + AttendeeFactoryBase.create_batch( + 2, order_id=pending_order.id, ticket_id=ticket.id + ) # will not be counted as the order is not under order expiry time - AttendeeFactoryBase.create_batch(3, order_id=expired_time_order.id) + AttendeeFactoryBase.create_batch( + 3, order_id=expired_time_order.id, ticket_id=ticket.id + ) # will not be counted as the order has an expired state - AttendeeFactoryBase.create_batch(5, order_id=expired_order.id) + AttendeeFactoryBase.create_batch( + 5, order_id=expired_order.id, ticket_id=ticket.id + ) + # will not be counted as the attendees have different ticket ID + AttendeeFactoryBase.create_batch( + 2, order_id=completed_order.id, ticket_id=other_ticket.id + ) - count = get_sold_and_reserved_tickets_count(ticket.event_id) + count = get_sold_and_reserved_tickets_count(ticket.id) self.assertEqual(count, 13) + # Last 2 attendees belong to other ticket + self.assertEqual(get_sold_and_reserved_tickets_count(other_ticket.id), 2) + if __name__ == '__main__': unittest.main()