Skip to content

Commit cdcb0ac

Browse files
committed
fix:count query of sold tickets
1 parent 03fa0ea commit cdcb0ac

File tree

3 files changed

+132
-9
lines changed

3 files changed

+132
-9
lines changed

app/api/attendees.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
from datetime import datetime
1+
import datetime
22

33
from flask import Blueprint, request, jsonify, abort, make_response
44
from flask_jwt_extended import current_user
55
from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
66
from flask_rest_jsonapi.exceptions import ObjectNotFound
77
from sqlalchemy.orm.exc import NoResultFound
8+
from sqlalchemy import or_, and_
89

910
from app.api.bootstrap import api
1011
from app.api.helpers.db import safe_query, get_count
@@ -25,6 +26,9 @@
2526
from app.models.ticket_holder import TicketHolder
2627
from app.models.user import User
2728

29+
from app.settings import get_settings
30+
31+
2832
attendee_misc_routes = Blueprint('attendee_misc', __name__, url_prefix='/v1')
2933

3034

@@ -56,8 +60,12 @@ def before_post(self, args, kwargs, data):
5660
"Ticket belongs to a different Event"
5761
)
5862
# Check if the ticket is already sold out or not.
59-
if get_count(db.session.query(TicketHolder.id).
60-
filter_by(ticket_id=int(data['ticket']), deleted_at=None)) >= ticket.quantity:
63+
order_expiry_time = get_settings()['order_expiry_time']
64+
if get_count(db.session.query(Order.id).filter(Order.event_id == int(ticket.event_id),
65+
Order.deleted_at.is_(None),or_(Order.status == 'placed', Order.status == 'completed',
66+
and_(Order.status == 'initializing',Order.created_at + datetime.timedelta(minutes=order_expiry_time) >
67+
datetime.datetime.utcnow()))))>= ticket.quantity:
68+
6169
raise ConflictException(
6270
{'pointer': '/data/attributes/ticket_id'},
6371
"Ticket already sold out"

app/factories/attendee.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,11 @@
77
from app.models.ticket_holder import db, TicketHolder
88

99

10-
class AttendeeFactory(factory.alchemy.SQLAlchemyModelFactory):
10+
class AttendeeFactoryBase(factory.alchemy.SQLAlchemyModelFactory):
1111
class Meta:
1212
model = TicketHolder
1313
sqlalchemy_session = db.session
1414

15-
event = factory.RelatedFactory(EventFactoryBasic)
16-
ticket = factory.RelatedFactory(TicketFactory)
17-
order = factory.RelatedFactory(OrderFactory)
1815
firstname = common.string_
1916
lastname = common.string_
2017
email = common.email_
@@ -29,3 +26,8 @@ class Meta:
2926
order_id = None
3027
created_at = common.date_
3128
modified_at = common.date_
29+
30+
class AttendeeFactory(AttendeeFactoryBase):
31+
event = factory.RelatedFactory(EventFactoryBasic)
32+
ticket = factory.RelatedFactory(TicketFactory)
33+
order = factory.RelatedFactory(OrderFactory)

tests/all/integration/api/helpers/test_order.py

Lines changed: 115 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,16 @@
33

44
from app.settings import get_settings
55
from app import current_app as app, db
6-
from app.api.helpers.db import save_to_db
76
from app.api.helpers.order import set_expiry_for_order, delete_related_attendees_for_order
8-
from app.factories.attendee import AttendeeFactory
7+
import app.factories.common as common
8+
from app.factories.attendee import AttendeeFactoryBase, AttendeeFactory
99
from app.factories.event import EventFactoryBasic
10+
from app.factories.ticket import TicketFactory
1011
from app.factories.order import OrderFactory
1112
from app.models.order import Order
1213
from app.api.helpers.db import save_to_db
1314
from tests.all.integration.setup_database import Setup
15+
from sqlalchemy import or_, and_
1416
from tests.all.integration.utils import OpenEventTestCase
1517

1618

@@ -54,6 +56,117 @@ def test_should_delete_related_attendees(self):
5456
order = db.session.query(Order).filter(Order.id == obj.id).first()
5557
self.assertEqual(len(order.ticket_holders), 0)
5658

59+
def test_count_sold_tickets(self):
60+
"""Method to test the count query of sold tickets"""
61+
62+
with app.test_request_context():
63+
# import logging
64+
#
65+
# logger = logging.getLogger('sqlalchemy.engine')
66+
# logger.setLevel(logging.INFO)
67+
ticket = TicketFactory()
68+
69+
first_completed_order = OrderFactory()
70+
first_completed_order.status = 'completed'
71+
second_completed_order = OrderFactory()
72+
second_completed_order.status = 'completed'
73+
third_completed_order = OrderFactory()
74+
third_completed_order.status = 'completed'
75+
fourth_completed_order = OrderFactory()
76+
fourth_completed_order.status = 'completed'
77+
fifth_completed_order = OrderFactory()
78+
fifth_completed_order.status = 'completed'
79+
sixth_completed_order = OrderFactory()
80+
sixth_completed_order.status = 'completed'
81+
82+
placed_order = OrderFactory()
83+
placed_order.status = 'placed'
84+
85+
first_initialized_order = OrderFactory()
86+
first_initialized_order.created_at = datetime.utcnow()
87+
second_initialized_order = OrderFactory()
88+
second_initialized_order.created_at = datetime.utcnow() - timedelta(minutes=1)
89+
third_initialized_order = OrderFactory()
90+
third_initialized_order.created_at = datetime.utcnow() - timedelta(minutes=2)
91+
fourth_initialized_order = OrderFactory()
92+
fourth_initialized_order.created_at = datetime.utcnow() - timedelta(minutes=3)
93+
94+
first_expired_time_order = OrderFactory()
95+
first_expired_time_order.created_at = common.date_
96+
second_expired_time_order = OrderFactory()
97+
second_expired_time_order.created_at = common.date_
98+
third_expired_time_order = OrderFactory()
99+
third_expired_time_order.created_at = common.date_
100+
101+
first_expired_order = OrderFactory()
102+
first_expired_order.status = 'expired'
103+
second_expired_order = OrderFactory()
104+
second_expired_order.status = 'expired'
105+
third_expired_order = OrderFactory()
106+
third_expired_order.status = 'expired'
107+
fourth_expired_order = OrderFactory()
108+
fourth_expired_order.status = 'expired'
109+
fifth_expired_order = OrderFactory()
110+
fifth_expired_order.status = 'expired'
111+
112+
db.session.commit()
113+
114+
first_att_with_no_order_id = AttendeeFactoryBase()
115+
second_att_with_no_order_id = AttendeeFactoryBase()
116+
117+
first_att_with_completed_order = AttendeeFactoryBase()
118+
first_att_with_completed_order.order_id = first_completed_order.id
119+
second_att_with_completed_order = AttendeeFactoryBase()
120+
second_att_with_completed_order.order_id = second_completed_order.id
121+
third_att_with_completed_order = AttendeeFactoryBase()
122+
third_att_with_completed_order.order_id = third_completed_order.id
123+
fourth_att_with_completed_order = AttendeeFactoryBase()
124+
fourth_att_with_completed_order.order_id = fourth_completed_order.id
125+
fifth_att_with_completed_order = AttendeeFactoryBase()
126+
fifth_att_with_completed_order.order_id = fifth_completed_order.id
127+
sixth_att_with_completed_order = AttendeeFactoryBase()
128+
sixth_att_with_completed_order.order_id = sixth_completed_order.id
129+
130+
att_with_placed_order = AttendeeFactoryBase()
131+
att_with_placed_order.order_id = placed_order.id
132+
133+
first_att_with_init_order = AttendeeFactoryBase()
134+
first_att_with_init_order.order_id = first_initialized_order.id
135+
second_att_with_init_order = AttendeeFactoryBase()
136+
second_att_with_init_order.order_id = second_initialized_order.id
137+
third_att_with_init_order = AttendeeFactoryBase()
138+
third_att_with_init_order.order_id = third_initialized_order.id
139+
fourth_att_with_init_order = AttendeeFactoryBase()
140+
fourth_att_with_init_order.order_id = fourth_initialized_order.id
141+
142+
first_att_with_expired_time = AttendeeFactoryBase()
143+
first_att_with_expired_time.order_id = first_expired_time_order.id
144+
second_att_with_expired_time = AttendeeFactoryBase()
145+
second_att_with_expired_time.order_id = second_expired_time_order.id
146+
third_att_with_expired_time = AttendeeFactoryBase()
147+
third_att_with_expired_time.order_id = third_expired_time_order.id
148+
149+
first_att_with_expired_order = AttendeeFactoryBase()
150+
first_att_with_expired_order.order_id = first_expired_order.id
151+
second_att_with_expired_order = AttendeeFactoryBase()
152+
second_att_with_expired_order.order_id = second_expired_order.id
153+
third_att_with_expired_order = AttendeeFactoryBase()
154+
third_att_with_expired_order.order_id = third_expired_order.id
155+
fourth_att_with_expired_order = AttendeeFactoryBase()
156+
fourth_att_with_expired_order.order_id = fourth_expired_order.id
157+
fifth_att_with_expired_order = AttendeeFactoryBase()
158+
fifth_att_with_expired_order.order_id = fifth_expired_order.id
159+
160+
db.session.commit()
161+
162+
order_expiry_time = get_settings()['order_expiry_time']
163+
count = db.session.query(Order.id).filter(Order.event_id == int(ticket.event_id),
164+
Order.deleted_at.is_(None),or_(Order.status == 'placed', Order.status == 'completed',
165+
and_(Order.status == 'initializing',Order.created_at + timedelta(minutes=order_expiry_time) >
166+
datetime.utcnow()))).count()
167+
168+
self.assertEqual(count, 11)
169+
57170

58171
if __name__ == '__main__':
59172
unittest.main()

0 commit comments

Comments
 (0)