|
1 | | -from datetime import datetime |
| 1 | +import datetime |
2 | 2 |
|
3 | | -from flask import Blueprint, request, jsonify, abort, make_response |
4 | 3 | from flask_jwt_extended import current_user |
5 | 4 | from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship |
6 | | -from flask_rest_jsonapi.exceptions import ObjectNotFound |
7 | | -from sqlalchemy.orm.exc import NoResultFound |
| 5 | +from sqlalchemy import or_, and_ |
8 | 6 |
|
9 | 7 | from app.api.bootstrap import api |
10 | 8 | from app.api.helpers.db import safe_query, get_count |
|
13 | 11 | ForbiddenException, |
14 | 12 | UnprocessableEntity, |
15 | 13 | ) |
16 | | -from app.api.helpers.mail import send_email_to_attendees |
17 | 14 | from app.api.helpers.permission_manager import has_access |
18 | 15 | from app.api.helpers.permissions import jwt_required |
19 | 16 | from app.api.helpers.query import event_query |
|
25 | 22 | from app.models.ticket_holder import TicketHolder |
26 | 23 | from app.models.user import User |
27 | 24 |
|
28 | | -attendee_misc_routes = Blueprint('attendee_misc', __name__, url_prefix='/v1') |
| 25 | +from app.settings import get_settings |
| 26 | + |
| 27 | + |
| 28 | +def get_sold_and_reserved_tickets_count(event_id): |
| 29 | + order_expiry_time = get_settings()['order_expiry_time'] |
| 30 | + return db.session.query(TicketHolder.id).join(Order).filter(TicketHolder.order_id == Order.id) \ |
| 31 | + .filter(Order.event_id == int(event_id), |
| 32 | + Order.deleted_at.is_(None), |
| 33 | + or_(Order.status == 'placed', |
| 34 | + Order.status == 'completed', |
| 35 | + and_(Order.status == 'initializing', |
| 36 | + Order.created_at + datetime.timedelta( |
| 37 | + minutes=order_expiry_time) > datetime.datetime.utcnow()), |
| 38 | + and_(Order.status == 'pending', |
| 39 | + Order.created_at + datetime.timedelta( |
| 40 | + minutes=30 + order_expiry_time) > (datetime.datetime.utcnow())) |
| 41 | + )).count() |
29 | 42 |
|
30 | 43 |
|
31 | 44 | class AttendeeListPost(ResourceList): |
@@ -56,8 +69,7 @@ def before_post(self, args, kwargs, data): |
56 | 69 | "Ticket belongs to a different Event" |
57 | 70 | ) |
58 | 71 | # 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: |
| 72 | + if get_sold_and_reserved_tickets_count(ticket.event_id) >= ticket.quantity: |
61 | 73 | raise ConflictException( |
62 | 74 | {'pointer': '/data/attributes/ticket_id'}, |
63 | 75 | "Ticket already sold out" |
@@ -257,34 +269,3 @@ class AttendeeRelationshipOptional(ResourceRelationship): |
257 | 269 | schema = AttendeeSchema |
258 | 270 | data_layer = {'session': db.session, |
259 | 271 | 'model': TicketHolder} |
260 | | - |
261 | | - |
262 | | -@attendee_misc_routes.route('/attendees/send-receipt', methods=['POST']) |
263 | | -@jwt_required |
264 | | -def send_receipt(): |
265 | | - """ |
266 | | - Send receipts to attendees related to the provided order. |
267 | | - :return: |
268 | | - """ |
269 | | - order_identifier = request.json.get('order-identifier') |
270 | | - if order_identifier: |
271 | | - try: |
272 | | - order = db.session.query(Order).filter_by(identifier=order_identifier).one() |
273 | | - except NoResultFound: |
274 | | - raise ObjectNotFound({'parameter': '{identifier}'}, "Order not found") |
275 | | - |
276 | | - if (order.user_id != current_user.id) and (not has_access('is_registrar', event_id=order.event_id)): |
277 | | - abort( |
278 | | - make_response(jsonify(error="You need to be the event organizer or order buyer to send receipts."), 403) |
279 | | - ) |
280 | | - elif order.status != 'completed': |
281 | | - abort( |
282 | | - make_response(jsonify(error="Cannot send receipt for an incomplete order"), 409) |
283 | | - ) |
284 | | - else: |
285 | | - send_email_to_attendees(order, current_user.id) |
286 | | - return jsonify(message="receipt sent to attendees") |
287 | | - else: |
288 | | - abort( |
289 | | - make_response(jsonify(error="Order identifier missing"), 422) |
290 | | - ) |
0 commit comments