Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
832c755
feat: restricts unverified user for buying free tickets (#6140)
prateekj117 Jul 12, 2019
f352525
fix: order deletion triggers emails (#6184)
uds5501 Jul 12, 2019
59291ff
chore: back up current docker compose
abhinavk96 Jul 12, 2019
dcc365e
feat: Serving event invoices through a protected route (#6145)
mrsaicharan1 Jul 12, 2019
336ec2d
feat: add a resend email route for organizers (#6163)
uds5501 Jul 12, 2019
faf208e
fix: Add citext extension in migration if not exists (#6188) (#6189)
iamareebjamal Jul 13, 2019
8a01b62
chore(deps): update sqlalchemy-utils requirement (#6194)
dependabot-preview[bot] Jul 15, 2019
4ea611e
fix: allows only owner and organizer to delete role-invites (#6190)
shreyanshdwivedi Jul 16, 2019
a258111
feat: Add required fields for merge of invoices & order models (#6196)
mrsaicharan1 Jul 16, 2019
367836d
Revert "feat: Add required fields for merge of invoices & order… (#6198)
iamareebjamal Jul 16, 2019
7b54d2a
fix: Making Event Name mandatory for publishing of event (#6203)
kushthedude Jul 16, 2019
23c83c1
fix: handle padding error for verification token (#6206)
uds5501 Jul 17, 2019
7d6399d
feat: Added order foreign keys & relationships in API (#6199)
mrsaicharan1 Jul 17, 2019
5802c42
feat: add field for email exception in speaker schema (#6209)
shreyanshdwivedi Jul 19, 2019
42f14d5
chore(deps): update apscheduler requirement from ~=3.6.0 to ~=3.6.1 (…
dependabot-preview[bot] Jul 20, 2019
ff408e5
chore: Remove sudo tag from travis config (#6219)
cclauss Jul 20, 2019
027a2c9
fix: state logic error in sessions.py (#6220)
cclauss Jul 20, 2019
5a3ea1a
chore: Migrate to flask_jwt_extended (#6216)
iamareebjamal Jul 20, 2019
1f91603
fix: Change discount-code route to use event ID (#6208)
prateekj117 Jul 21, 2019
4467fe3
refactor: Rewrite empty_string & add more test cases (#6222)
mrsaicharan1 Jul 22, 2019
ff378ac
chore(deps): update sqlalchemy requirement from ~=1.3.5 to ~=1.… (#6227)
dependabot-preview[bot] Jul 23, 2019
0a1849a
chore: Moved utility unit tests to appropriate folder (#6226)
mrsaicharan1 Jul 23, 2019
fc02893
docs: Update order expiry time Admin Only tag (#6230)
sameshl Jul 23, 2019
100ad5b
fix: restoration of deleted event (#6218)
shreyanshdwivedi Jul 24, 2019
0ed4363
fix: Replaced hardcoded with FE URL from settings (#6233)
mrsaicharan1 Jul 24, 2019
ec24c30
fix: Make discount code & access code URL follow json api conventions…
abhinavk96 Jul 26, 2019
7dd5282
fix: send mail only if SMTP was configured(Event Export) (#6228)
mrsaicharan1 Jul 26, 2019
5563826
fix: add tax information in event copy action (#6241)
uds5501 Jul 27, 2019
92d001b
chore(deps): Including python-dotenv in requirements (#6237)
kushthedude Jul 29, 2019
3c747b0
feat: Make discount codes & access codes support event_identifier (#6…
abhinavk96 Jul 29, 2019
78fb877
feat: verify unverified user if he resets password (#6254)
abhinavk96 Jul 29, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
language: python

sudo: required

services:
- docker

Expand Down
13 changes: 7 additions & 6 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from flask_login import current_user
from flask_jwt import JWT
from flask_jwt_extended import JWTManager
from flask_limiter import Limiter
from datetime import timedelta
from flask_cors import CORS
Expand All @@ -26,7 +26,7 @@
import stripe
from app.settings import get_settings
from app.models import db
from app.api.helpers.jwt import jwt_authenticate, jwt_identity
from app.api.helpers.jwt import jwt_user_loader
from app.api.helpers.cache import cache
from werkzeug.middleware.profiler import ProfilerMiddleware
from app.views import BlueprintsManager
Expand Down Expand Up @@ -102,10 +102,11 @@ def create_app():
app.logger.setLevel(logging.ERROR)

# set up jwt
app.config['JWT_AUTH_USERNAME_KEY'] = 'email'
app.config['JWT_EXPIRATION_DELTA'] = timedelta(seconds=24 * 60 * 60)
app.config['JWT_AUTH_URL_RULE'] = '/auth/session'
_jwt = JWT(app, jwt_authenticate, jwt_identity)
app.config['JWT_HEADER_TYPE'] = 'JWT'
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(days=1)
app.config['JWT_ERROR_MESSAGE_KEY'] = 'error'
_jwt = JWTManager(app)
_jwt.user_loader_callback_loader(jwt_user_loader)

# setup celery
app.config['CELERY_BROKER_URL'] = app.config['REDIS_URL']
Expand Down
152 changes: 79 additions & 73 deletions app/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,90 +1,90 @@
from app.api.access_codes import AccessCodeList, AccessCodeListPost, AccessCodeDetail, AccessCodeRelationshipRequired, \
AccessCodeRelationshipOptional
from app.api.activities import ActivityList, ActivityDetail
from app.api.admin_sales.discounted import AdminSalesDiscountedList
from app.api.admin_sales.events import AdminSalesByEventsList
from app.api.admin_sales.fees import AdminSalesFeesList
from app.api.admin_sales.invoices import AdminSalesInvoicesList
from app.api.admin_sales.locations import AdminSalesByLocationList
from app.api.admin_sales.marketer import AdminSalesByMarketerList
from app.api.admin_sales.organizer import AdminSalesByOrganizersList
from app.api.admin_statistics_api.events import AdminStatisticsEventDetail
from app.api.admin_statistics_api.mails import AdminStatisticsMailDetail
from app.api.admin_statistics_api.sessions import AdminStatisticsSessionDetail
from app.api.admin_statistics_api.users import AdminStatisticsUserDetail
from app.api.attendees import AttendeeList, AttendeeDetail, AttendeeRelationshipOptional, \
AttendeeRelationshipRequired, AttendeeListPost
from app.api.bootstrap import api
from app.api.event_orga import EventOrgaDetail
from app.api.stripe_authorization import StripeAuthorizationDetail, StripeAuthorizationRelationship, \
StripeAuthorizationListPost
from app.api.ticket_fees import TicketFeeList, TicketFeeDetail
from app.api.users import UserList, UserDetail, UserRelationship
from app.api.user_emails import UserEmailListAdmin, UserEmailListPost, UserEmailList, UserEmailDetail, \
UserEmailRelationship
from app.api.user_favourite_events import UserFavouriteEventListPost, UserFavouriteEventList, \
UserFavouriteEventDetail, UserFavouriteEventRelationship
from app.api.notifications import NotificationList, NotificationListAdmin, NotificationDetail,\
NotificationRelationship, NotificationActionDetail, NotificationActionRelationship, NotificationActionList
from app.api.custom_forms import CustomFormList, CustomFormListPost, CustomFormDetail, CustomFormRelationshipRequired
from app.api.custom_placeholders import CustomPlaceholderList, CustomPlaceholderDetail, CustomPlaceholderRelationship
from app.api.custom_system_roles import CustomSystemRoleList, CustomSystemRoleDetail, CustomSystemRoleRelationship
from app.api.discount_codes import DiscountCodeList, DiscountCodeDetail, DiscountCodeRelationshipOptional, \
DiscountCodeRelationshipRequired, DiscountCodeListPost
from app.api.email_notifications import EmailNotificationList, EmailNotificationListAdmin, EmailNotificationDetail, \
EmailNotificationRelationshipOptional, EmailNotificationRelationshipRequired
from app.api.tickets import TicketList, TicketListPost, TicketDetail, TicketRelationshipRequired, \
TicketRelationshipOptional
from app.api.events import EventList, EventDetail, EventRelationship, EventCopyResource
from app.api.event_types import EventTypeList, EventTypeDetail, EventTypeRelationship
from app.api.event_copyright import EventCopyrightListPost, EventCopyrightDetail, EventCopyrightRelationshipRequired
from app.api.event_image_sizes import EventImageSizeDetail
from app.api.event_invoices import EventInvoiceList, EventInvoiceDetail, \
EventInvoiceRelationshipRequired, EventInvoiceRelationshipOptional
from app.api.event_locations import EventLocationList
from app.api.event_topics import EventTopicList, EventTopicDetail, EventTopicRelationship
from app.api.event_orga import EventOrgaDetail
from app.api.event_statistics import EventStatisticsGeneralDetail
from app.api.event_sub_topics import EventSubTopicList, EventSubTopicListPost, EventSubTopicDetail, \
EventSubTopicRelationshipRequired, EventSubTopicRelationshipOptional
from app.api.event_topics import EventTopicList, EventTopicDetail, EventTopicRelationship
from app.api.event_types import EventTypeList, EventTypeDetail, EventTypeRelationship
from app.api.events import EventList, EventDetail, EventRelationship, EventCopyResource

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'app.api.events.EventCopyResource' imported but unused

from app.api.events_role_permission import EventsRolePermissionList, EventsRolePermissionDetail, \
EventsRolePermissionRelationship
from app.api.faq_types import FaqTypeList, FaqTypeListPost, FaqTypeDetail, FaqTypeRelationshipOptional, \
FaqTypeRelationshipRequired
from app.api.faqs import FaqListPost, FaqList, FaqDetail, FaqRelationshipRequired, FaqRelationshipOptional
from app.api.feedbacks import FeedbackListPost, FeedbackList, FeedbackDetail, \
FeedbackRelationship
from app.api.full_text_search.events import EventSearchResultList
from app.api.import_jobs import ImportJobList, ImportJobDetail
from app.api.mails import MailList, MailDetail
from app.api.message_settings import MessageSettingsList, MessageSettingsDetail
from app.api.microlocations import MicrolocationList, MicrolocationListPost, MicrolocationDetail, \
MicrolocationRelationshipRequired, MicrolocationRelationshipOptional
from app.api.modules import ModuleDetail
from app.api.notifications import NotificationList, NotificationListAdmin, NotificationDetail, \
NotificationRelationship, NotificationActionDetail, NotificationActionRelationship, NotificationActionList
from app.api.order_statistics.events import OrderStatisticsEventDetail
from app.api.order_statistics.tickets import OrderStatisticsTicketDetail
from app.api.orders import OrdersList, OrderDetail, OrderRelationship, ChargeList, OrdersListPost
from app.api.pages import PageList, PageDetail
from app.api.panel_permissions import PanelPermissionList, PanelPermissionDetail, \
PanelPermissionRelationship
from app.api.role_invites import RoleInviteListPost, RoleInviteList, RoleInviteDetail, RoleInviteRelationship
from app.api.roles import RoleList, RoleDetail
from app.api.service import ServiceList, ServiceDetail
from app.api.session_types import SessionTypeList, SessionTypeListPost, SessionTypeDetail, \
SessionTypeRelationshipRequired, SessionTypeRelationshipOptional
from app.api.sessions import SessionList, SessionListPost, SessionDetail, SessionRelationshipRequired, \
SessionRelationshipOptional
from app.api.settings import SettingDetail
from app.api.social_links import SocialLinkList, SocialLinkListPost, SocialLinkDetail, SocialLinkRelationship
from app.api.speaker_image_sizes import SpeakerImageSizeDetail
from app.api.speakers import SpeakerList, SpeakerListPost, SpeakerDetail, SpeakerRelationshipRequired, \
SpeakerRelationshipOptional
from app.api.service import ServiceList, ServiceDetail
from app.api.social_links import SocialLinkList, SocialLinkListPost, SocialLinkDetail, SocialLinkRelationship
from app.api.sponsors import SponsorList, SponsorListPost, SponsorDetail, SponsorRelationship
from app.api.tracks import TrackList, TrackListPost, TrackDetail, TrackRelationshipOptional, TrackRelationshipRequired
from app.api.speakers_calls import SpeakersCallList, SpeakersCallDetail, SpeakersCallRelationship
from app.api.event_invoices import EventInvoiceList, EventInvoiceDetail, \
EventInvoiceRelationshipRequired, EventInvoiceRelationshipOptional
from app.api.role_invites import RoleInviteListPost, RoleInviteList, RoleInviteDetail, RoleInviteRelationship
from app.api.event_image_sizes import EventImageSizeDetail
from app.api.speaker_image_sizes import SpeakerImageSizeDetail
from app.api.roles import RoleList, RoleDetail
from app.api.custom_system_roles import CustomSystemRoleList, CustomSystemRoleDetail, CustomSystemRoleRelationship
from app.api.session_types import SessionTypeList, SessionTypeListPost, SessionTypeDetail, \
SessionTypeRelationshipRequired, SessionTypeRelationshipOptional
from app.api.event_copyright import EventCopyrightListPost, EventCopyrightDetail, EventCopyrightRelationshipRequired
from app.api.pages import PageList, PageDetail
from app.api.user_permission import UserPermissionList, UserPermissionDetail
from app.api.events_role_permission import EventsRolePermissionList, EventsRolePermissionDetail, \
EventsRolePermissionRelationship
from app.api.panel_permissions import PanelPermissionList, PanelPermissionDetail, \
PanelPermissionRelationship
from app.api.message_settings import MessageSettingsList, MessageSettingsDetail
from app.api.sponsors import SponsorList, SponsorListPost, SponsorDetail, SponsorRelationship
from app.api.stripe_authorization import StripeAuthorizationDetail, StripeAuthorizationRelationship, \
StripeAuthorizationListPost
from app.api.tax import TaxList, TaxDetail, TaxRelationship
from app.api.settings import SettingDetail
from app.api.discount_codes import DiscountCodeList, DiscountCodeDetail, DiscountCodeRelationshipOptional, \
DiscountCodeRelationshipRequired, DiscountCodeListPost
from app.api.ticket_fees import TicketFeeList, TicketFeeDetail
from app.api.ticket_tags import TicketTagList, TicketTagListPost, TicketTagDetail, TicketTagRelationshipOptional, \
TicketTagRelationshipRequired
from app.api.attendees import AttendeeList, AttendeeDetail, AttendeeRelationshipOptional, \
AttendeeRelationshipRequired, AttendeeListPost
from app.api.access_codes import AccessCodeList, AccessCodeListPost, AccessCodeDetail, AccessCodeRelationshipRequired, \
AccessCodeRelationshipOptional
from app.api.custom_forms import CustomFormList, CustomFormListPost, CustomFormDetail, CustomFormRelationshipRequired
from app.api.faqs import FaqListPost, FaqList, FaqDetail, FaqRelationshipRequired, FaqRelationshipOptional
from app.api.feedbacks import FeedbackListPost, FeedbackList, FeedbackDetail, \
FeedbackRelationship
from app.api.modules import ModuleDetail
from app.api.custom_placeholders import CustomPlaceholderList, CustomPlaceholderDetail, CustomPlaceholderRelationship
from app.api.activities import ActivityList, ActivityDetail
from app.api.orders import OrdersList, OrderDetail, OrderRelationship, ChargeList, OrdersListPost
from app.api.event_statistics import EventStatisticsGeneralDetail
from app.api.mails import MailList, MailDetail
from app.api.admin_statistics_api.sessions import AdminStatisticsSessionDetail
from app.api.admin_statistics_api.events import AdminStatisticsEventDetail
from app.api.admin_statistics_api.users import AdminStatisticsUserDetail
from app.api.admin_statistics_api.mails import AdminStatisticsMailDetail
from app.api.order_statistics.events import OrderStatisticsEventDetail
from app.api.order_statistics.tickets import OrderStatisticsTicketDetail
from app.api.faq_types import FaqTypeList, FaqTypeListPost, FaqTypeDetail, FaqTypeRelationshipOptional, \
FaqTypeRelationshipRequired
from app.api.admin_sales.events import AdminSalesByEventsList
from app.api.admin_sales.organizer import AdminSalesByOrganizersList
from app.api.admin_sales.locations import AdminSalesByLocationList
from app.api.admin_sales.marketer import AdminSalesByMarketerList
from app.api.admin_sales.discounted import AdminSalesDiscountedList
from app.api.admin_sales.fees import AdminSalesFeesList
from app.api.admin_sales.invoices import AdminSalesInvoicesList
from app.api.full_text_search.events import EventSearchResultList
from app.api.import_jobs import ImportJobList, ImportJobDetail
from app.api.tickets import TicketList, TicketListPost, TicketDetail, TicketRelationshipRequired, \
TicketRelationshipOptional
from app.api.tracks import TrackList, TrackListPost, TrackDetail, TrackRelationshipOptional, TrackRelationshipRequired
from app.api.user_emails import UserEmailListAdmin, UserEmailListPost, UserEmailList, UserEmailDetail, \
UserEmailRelationship
from app.api.user_favourite_events import UserFavouriteEventListPost, UserFavouriteEventList, \
UserFavouriteEventDetail, UserFavouriteEventRelationship
from app.api.user_permission import UserPermissionList, UserPermissionDetail
from app.api.users import UserList, UserDetail, UserRelationship

# users
api.route(UserList, 'user_list', '/users')
Expand Down Expand Up @@ -462,6 +462,8 @@
'/event-invoices/<int:id>/relationships/user')
api.route(EventInvoiceRelationshipRequired, 'event_invoice_event',
'/event-invoices/<int:id>/relationships/event')
api.route(EventInvoiceRelationshipRequired, 'event_invoice_order',
'/event-invoices/<int:id>/relationships/order')
api.route(EventInvoiceRelationshipOptional, 'event_invoice_discount_code',
'/event-invoices/<int:id>/relationships/discount-code')

Expand All @@ -472,7 +474,8 @@
'/tickets/<int:ticket_id>/discount-codes')
api.route(DiscountCodeDetail, 'discount_code_detail', '/discount-codes/<int:id>',
'/events/<int:event_id>/discount-code', '/event-invoices/<int:event_invoice_id>/discount-code',
'/discount-codes/<code>')
'/events/<int:discount_event_id>/discount-codes/<code>',
'/events/<discount_event_identifier>/discount-codes/<code>')
api.route(DiscountCodeRelationshipRequired, 'discount_code_event',
'/discount-codes/<int:id>/relationships/event')
api.route(DiscountCodeRelationshipOptional, 'discount_code_events',
Expand Down Expand Up @@ -539,7 +542,9 @@
api.route(AccessCodeList, 'access_code_list', '/events/<int:event_id>/access-codes',
'/events/<event_identifier>/access-codes', '/users/<int:user_id>/access-codes',
'/tickets/<int:ticket_id>/access-codes')
api.route(AccessCodeDetail, 'access_code_detail', '/access-codes/<int:id>', '/access-codes/<code>')
api.route(AccessCodeDetail, 'access_code_detail', '/access-codes/<int:id>',
'/events/<int:access_event_id>/access-codes/<code>',
'/events/<int:access_event_identifier>/access-codes/<code>',)
api.route(AccessCodeRelationshipRequired, 'access_code_event',
'/access-codes/<int:id>/relationships/event')
api.route(AccessCodeRelationshipOptional, 'access_code_user',
Expand Down Expand Up @@ -600,6 +605,7 @@
api.route(OrderRelationship, 'order_event', '/orders/<order_identifier>/relationships/event')
api.route(OrderRelationship, 'order_marketer', '/orders/<order_identifier>/relationships/marketer')
api.route(OrderRelationship, 'order_discount', '/orders/<order_identifier>/relationships/discount-code')
api.route(OrderRelationship, 'order_event_invoice', '/orders/<order_identifier>/relationships/event-invoice/')

# Event Statistics API
api.route(EventStatisticsGeneralDetail, 'event_statistics_general_detail', '/events/<int:id>/general-statistics',
Expand Down
14 changes: 11 additions & 3 deletions app/api/access_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from app.models.access_code import AccessCode
from app.models.ticket import Ticket
from app.models.user import User
from app.models.event import Event


class AccessCodeListPost(ResourceList):
Expand Down Expand Up @@ -110,9 +111,16 @@ def before_get(self, args, kwargs):
:param kwargs:
:return:
"""
# Any registered user can fetch access code details using the code.
if kwargs.get('code'):
access = db.session.query(AccessCode).filter_by(code=kwargs.get('code')).first()
# Any user can fetch access code details using the code.

if kwargs.get('access_event_identifier'):
event = safe_query(
db, Event, 'identifier', kwargs['discount_event_identifier'],
'event_identifier')
kwargs['access_event_id'] = event.id
if kwargs.get('code') and kwargs.get('access_event_id'):
access = db.session.query(AccessCode).filter_by(code=kwargs.get('code'),
event_id=kwargs.get('access_event_id')).first()
if access:
kwargs['id'] = access.id
else:
Expand Down
6 changes: 3 additions & 3 deletions app/api/admin_statistics_api/events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from flask_rest_jsonapi import ResourceDetail
from flask import jsonify, Blueprint
from flask_jwt import jwt_required
from flask_jwt_extended import jwt_required
from sqlalchemy.sql import text

from app.api.bootstrap import api
Expand All @@ -12,7 +12,7 @@


@event_statistics.route('/event-topics', methods=['GET'])
@jwt_required()
@jwt_required
def event_topic_count():
result_set = db.engine.execute(text(
"SELECT event_topics.name AS name, event_topics.id AS id, " +
Expand All @@ -25,7 +25,7 @@ def event_topic_count():


@event_statistics.route('/event-types', methods=['GET'])
@jwt_required()
@jwt_required
def event_types_count():
result_set = db.engine.execute(text(
"SELECT event_types.name AS name, event_types.id AS id, " +
Expand Down
12 changes: 6 additions & 6 deletions app/api/attendees.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from datetime import datetime

from flask import Blueprint, request, jsonify, abort, make_response
from flask_jwt import current_identity, jwt_required
from flask_jwt_extended import current_user
from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
from flask_rest_jsonapi.exceptions import ObjectNotFound
from sqlalchemy.orm.exc import NoResultFound
Expand Down Expand Up @@ -146,7 +146,7 @@ def before_get_object(self, view_kwargs):
:return:
"""
attendee = safe_query(self, TicketHolder, 'id', view_kwargs['id'], 'attendee_id')
if not has_access('is_registrar_or_user_itself', user_id=current_identity.id, event_id=attendee.event_id):
if not has_access('is_registrar_or_user_itself', user_id=current_user.id, event_id=attendee.event_id):
raise ForbiddenException({'source': 'User'}, 'You are not authorized to access this.')

def before_delete_object(self, obj, kwargs):
Expand All @@ -171,10 +171,10 @@ def before_update_object(self, obj, data, kwargs):
# raise ForbiddenException({'source': 'User'}, 'You are not authorized to access this.')

if 'ticket' in data:
user = safe_query(self, User, 'id', current_identity.id, 'user_id')
user = safe_query(self, User, 'id', current_user.id, 'user_id')
ticket = db.session.query(Ticket).filter_by(
id=int(data['ticket']), deleted_at=None
).first()
).first()
if ticket is None:
raise UnprocessableEntity(
{'pointer': '/data/relationships/ticket'}, "Invalid Ticket"
Expand Down Expand Up @@ -278,7 +278,7 @@ def send_receipt():
except NoResultFound:
raise ObjectNotFound({'parameter': '{identifier}'}, "Order not found")

if (order.user_id != current_identity.id) and (not has_access('is_registrar', event_id=order.event_id)):
if (order.user_id != current_user.id) and (not has_access('is_registrar', event_id=order.event_id)):
abort(
make_response(jsonify(error="You need to be the event organizer or order buyer to send receipts."), 403)
)
Expand All @@ -287,7 +287,7 @@ def send_receipt():
make_response(jsonify(error="Cannot send receipt for an incomplete order"), 409)
)
else:
send_email_to_attendees(order, current_identity.id)
send_email_to_attendees(order, current_user.id)
return jsonify(message="receipt sent to attendees")
else:
abort(
Expand Down
Loading