Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name-template: v$NEXT_PATCH_VERSION 🌈
tag-template: v$NEXT_PATCH_VERSION
name-template: Release v$NEXT_MINOR_VERSION 🌈
tag-template: v$NEXT_MINOR_VERSION
categories:
- title: 🚀 Features
label: feature
Expand Down
28 changes: 18 additions & 10 deletions app/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
from app.api.users import UserList, UserDetail, UserRelationship

# users
api.route(UserList, 'user_list', '/users')
api.route(UserList, 'user_list', '/users', '/events/<int:event_id>/organizers')
api.route(UserDetail, 'user_detail', '/users/<int:id>', '/notifications/<int:notification_id>/user',
'/event-invoices/<int:event_invoice_id>/user', '/speakers/<int:speaker_id>/user',
'/access-codes/<int:access_code_id>/marketer', '/email-notifications/<int:email_notification_id>/user',
Expand All @@ -102,12 +102,12 @@
api.route(UserRelationship, 'user_access_codes', '/users/<int:id>/relationships/access-codes')
api.route(UserRelationship, 'user_discount_codes', '/users/<int:id>/relationships/discount-codes')
api.route(UserRelationship, 'user_email_notifications', '/users/<int:id>/relationships/email-notifications')
api.route(UserRelationship, 'user_owner_event', '/users/<int:id>/relationships/owner-events')
api.route(UserRelationship, 'user_organizer_event', '/users/<int:id>/relationships/organizer-events')
api.route(UserRelationship, 'user_coorganizer_event', '/users/<int:id>/relationships/coorganizer-events')
api.route(UserRelationship, 'user_track_organizer_event', '/users/<int:id>/relationships/track-organizer-events')
api.route(UserRelationship, 'user_registrar_event', '/users/<int:id>/relationships/registrar-events')
api.route(UserRelationship, 'user_moderator_event', '/users/<int:id>/relationships/moderator-events')
api.route(UserRelationship, 'user_owner_events', '/users/<int:id>/relationships/owner-events')
api.route(UserRelationship, 'user_organizer_events', '/users/<int:id>/relationships/organizer-events')
api.route(UserRelationship, 'user_coorganizer_events', '/users/<int:id>/relationships/coorganizer-events')
api.route(UserRelationship, 'user_track_organizer_events', '/users/<int:id>/relationships/track-organizer-events')
api.route(UserRelationship, 'user_registrar_events', '/users/<int:id>/relationships/registrar-events')
api.route(UserRelationship, 'user_moderator_events', '/users/<int:id>/relationships/moderator-events')
api.route(UserRelationship, 'user_attendees', '/users/<int:id>/relationships/attendees')
api.route(UserRelationship, 'user_events', '/users/<int:id>/relationships/events')
api.route(UserRelationship, 'user_orders', '/users/<int:id>/relationships/orders')
Expand Down Expand Up @@ -200,7 +200,6 @@
api.route(PanelPermissionRelationship, 'panel_permissions_custom_system_roles',
'/panel-permissions/<int:id>/relationships/custom-system-roles')


# roles
api.route(RoleList, 'role_list', '/roles')
api.route(RoleDetail, 'role_detail', '/roles/<int:id>', '/role-invites/<int:role_invite_id>/role')
Expand Down Expand Up @@ -246,7 +245,16 @@
api.route(EventList, 'event_list', '/events', '/event-types/<int:event_type_id>/events',
'/event-topics/<int:event_topic_id>/events',
'/event-sub-topics/<int:event_sub_topic_id>/events', '/discount-codes/<int:discount_code_id>/events',
'/users/<int:user_id>/events')
'/users/<int:user_id>/events',
'/users/<int:user_owner_id>/owner-events',
'/users/<int:user_organizer_id>/organizer-events',
'/users/<int:user_coorganizer_id>/coorganizer-events',
'/users/<int:user_track_organizer_id>/track-organizer-events',
'/users/<int:user_registrar_id>/registrar-events',
'/users/<int:user_moderator_id>/moderator-events',
'/users/<int:user_marketer_id>/marketer-events',
'/users/<int:user_sales_admin_id>/sales-admin-events')

api.route(EventDetail, 'event_detail', '/events/<int:id>', '/events/<identifier>',
'/tickets/<int:ticket_id>/event', '/microlocations/<int:microlocation_id>/event',
'/social-links/<int:social_link_id>/event',
Expand Down Expand Up @@ -544,7 +552,7 @@
'/tickets/<int:ticket_id>/access-codes')
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>',)
'/events/<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
2 changes: 1 addition & 1 deletion app/api/access_codes.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def before_get(self, args, kwargs):

if kwargs.get('access_event_identifier'):
event = safe_query(
db, Event, 'identifier', kwargs['discount_event_identifier'],
db, Event, 'identifier', kwargs['access_event_identifier'],
'event_identifier')
kwargs['access_event_id'] = event.id
if kwargs.get('code') and kwargs.get('access_event_id'):
Expand Down
5 changes: 4 additions & 1 deletion app/api/custom_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ def before_get_object(self, view_kwargs):
fetch_as="event_id", model=CustomForms, methods="PATCH,DELETE"), )
schema = CustomFormSchema
data_layer = {'session': db.session,
'model': CustomForms}
'model': CustomForms,
'methods': {
'before_get_object': before_get_object
}}


class CustomFormRelationshipRequired(ResourceRelationship):
Expand Down
5 changes: 4 additions & 1 deletion app/api/custom_system_roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,10 @@ def before_get_object(self, view_kwargs):
decorators = (api.has_permission('is_admin', methods="PATCH,DELETE"),)
schema = CustomSystemRoleSchema
data_layer = {'session': db.session,
'model': CustomSysRole}
'model': CustomSysRole,
'methods': {
'before_get_object': before_get_object
}}


class CustomSystemRoleRelationship(ResourceRelationship):
Expand Down
79 changes: 74 additions & 5 deletions app/api/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@
from app.models.ticket_holder import TicketHolder
from app.models.track import Track
from app.models.user_favourite_event import UserFavouriteEvent
from app.models.user import User, ATTENDEE, OWNER, ORGANIZER, COORGANIZER
from app.models.user import User, ATTENDEE, OWNER, ORGANIZER, COORGANIZER, TRACK_ORGANIZER, REGISTRAR, MODERATOR, \
SALES_ADMIN, MARKETER
from app.models.users_events_role import UsersEventsRoles
from app.models.stripe_authorization import StripeAuthorization


def validate_event(user, modules, data):
if not user.can_create_event():
raise ForbiddenException({'source': ''},
Expand Down Expand Up @@ -105,8 +107,13 @@ def validate_date(event, data):
"ends-at should be after starts-at")

if datetime.timestamp(data['starts_at']) <= datetime.timestamp(datetime.now()):
raise UnprocessableEntity({'pointer': '/data/attributes/starts-at'},
"starts-at should be after current date-time")
if event and event.deleted_at and not data.get('deleted_at'):
data['state'] = 'draft'
elif event and not event.deleted_at and data.get('deleted_at'):
pass
else:
raise UnprocessableEntity({'pointer': '/data/attributes/starts-at'},
"starts-at should be after current date-time")

class EventList(ResourceList):
def before_get(self, args, kwargs):
Expand Down Expand Up @@ -142,6 +149,62 @@ def query(self, view_kwargs):
query_ = query_.join(Event.roles).filter_by(user_id=user.id).join(UsersEventsRoles.role). \
filter(Role.name != ATTENDEE)

if view_kwargs.get('user_owner_id') and 'GET' in request.method:
if not has_access('is_user_itself', user_id=int(view_kwargs['user_owner_id'])):
raise ForbiddenException({'source': ''}, 'Access Forbidden')
user = safe_query(db, User, 'id', view_kwargs['user_owner_id'], 'user_owner_id')
query_ = query_.join(Event.roles).filter_by(user_id=user.id).join(UsersEventsRoles.role). \
filter(Role.name == OWNER)

if view_kwargs.get('user_organizer_id') and 'GET' in request.method:
if not has_access('is_user_itself', user_id=int(view_kwargs['user_organizer_id'])):
raise ForbiddenException({'source': ''}, 'Access Forbidden')
user = safe_query(db, User, 'id', view_kwargs['user_organizer_id'], 'user_organizer_id')
query_ = query_.join(Event.roles).filter_by(user_id=user.id).join(UsersEventsRoles.role). \
filter(Role.name == ORGANIZER)

if view_kwargs.get('user_coorganizer_id') and 'GET' in request.method:
if not has_access('is_user_itself', user_id=int(view_kwargs['user_coorganizer_id'])):
raise ForbiddenException({'source': ''}, 'Access Forbidden')
user = safe_query(db, User, 'id', view_kwargs['user_coorganizer_id'], 'user_coorganizer_id')
query_ = query_.join(Event.roles).filter_by(user_id=user.id).join(UsersEventsRoles.role). \
filter(Role.name == COORGANIZER)

if view_kwargs.get('user_track_organizer_id') and 'GET' in request.method:
if not has_access('is_user_itself', user_id=int(view_kwargs['user_track_organizer_id'])):
raise ForbiddenException({'source': ''}, 'Access Forbidden')
user = safe_query(db, User, 'id', view_kwargs['user_track_organizer_id'], 'user_organizer_id')
query_ = query_.join(Event.roles).filter_by(user_id=user.id).join(UsersEventsRoles.role). \
filter(Role.name == TRACK_ORGANIZER)

if view_kwargs.get('user_registrar_id') and 'GET' in request.method:
if not has_access('is_user_itself', user_id=int(view_kwargs['user_registrar_id'])):
raise ForbiddenException({'source': ''}, 'Access Forbidden')
user = safe_query(db, User, 'id', view_kwargs['user_registrar_id'], 'user_registrar_id')
query_ = query_.join(Event.roles).filter_by(user_id=user.id).join(UsersEventsRoles.role). \
filter(Role.name == REGISTRAR)

if view_kwargs.get('user_moderator_id') and 'GET' in request.method:
if not has_access('is_user_itself', user_id=int(view_kwargs['user_moderator_id'])):
raise ForbiddenException({'source': ''}, 'Access Forbidden')
user = safe_query(db, User, 'id', view_kwargs['user_moderator_id'], 'user_moderator_id')
query_ = query_.join(Event.roles).filter_by(user_id=user.id).join(UsersEventsRoles.role). \
filter(Role.name == MODERATOR)

if view_kwargs.get('user_marketer_id') and 'GET' in request.method:
if not has_access('is_user_itself', user_id=int(view_kwargs['user_marketer_id'])):
raise ForbiddenException({'source': ''}, 'Access Forbidden')
user = safe_query(db, User, 'id', view_kwargs['user_marketer_id'], 'user_marketer_id')
query_ = query_.join(Event.roles).filter_by(user_id=user.id).join(UsersEventsRoles.role). \
filter(Role.name == MARKETER)

if view_kwargs.get('user_sales_admin_id') and 'GET' in request.method:
if not has_access('is_user_itself', user_id=int(view_kwargs['user_sales_admin_id'])):
raise ForbiddenException({'source': ''}, 'Access Forbidden')
user = safe_query(db, User, 'id', view_kwargs['user_sales_admin_id'], 'user_sales_admin_id')
query_ = query_.join(Event.roles).filter_by(user_id=user.id).join(UsersEventsRoles.role). \
filter(Role.name == SALES_ADMIN)

if view_kwargs.get('event_type_id') and 'GET' in request.method:
query_ = self.session.query(Event).filter(
getattr(Event, 'event_type_id') == view_kwargs['event_type_id'])
Expand Down Expand Up @@ -175,7 +238,8 @@ def before_post(self, args, kwargs, data=None):
user = User.query.filter_by(id=kwargs['user_id']).first()
modules = Module.query.first()
validate_event(user, modules, data)
validate_date(None, data)
if data['state'] != 'draft':
validate_date(None, data)

def after_create_object(self, event, data, view_kwargs):
"""
Expand Down Expand Up @@ -492,7 +556,11 @@ def before_update_object(self, event, data, view_kwargs):
:param view_kwargs:
:return:
"""
if data.get('starts_at') != event.starts_at or data.get('ends_at') != event.ends_at:
is_date_updated = (data.get('starts_at') != event.starts_at or data.get('ends_at') != event.ends_at)
is_draft_published = (event.state == "draft" and data.get('state') == "published")
is_event_restored = (event.deleted_at and not data.get('deleted_at'))

if is_date_updated or is_draft_published or is_event_restored:
validate_date(event, data)

if has_access('is_admin') and data.get('deleted_at') != event.deleted_at:
Expand Down Expand Up @@ -522,6 +590,7 @@ def after_update_object(self, event, data, view_kwargs):
'model': Event,
'methods': {
'before_update_object': before_update_object,
'before_get_object': before_get_object,
'after_update_object': after_update_object,
'before_patch': before_patch
}}
Expand Down
5 changes: 4 additions & 1 deletion app/api/feedbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ def before_update_object(self, feedback, data, view_kwargs):
schema = FeedbackSchema
data_layer = {'session': db.session,
'model': Feedback,
'methods': {'before_update_object': before_update_object}}
'methods': {
'before_update_object': before_update_object,
'before_get_object': before_get_object
}}


class FeedbackRelationship(ResourceRelationship):
Expand Down
8 changes: 6 additions & 2 deletions app/api/helpers/notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,11 +304,15 @@ def send_notif_ticket_cancel(order):
send_notification(
user=order.event.owner,
title=NOTIFS[TICKET_CANCELLED_ORGANIZER]['title'].format(
invoice_id=order.invoice_number
invoice_id=order.invoice_number,
event_name=order.event.name
),
message=NOTIFS[TICKET_CANCELLED_ORGANIZER]['message'].format(
cancel_note=order.cancel_note,
invoice_id=order.invoice_number
invoice_id=order.invoice_number,
event_name=order.event.name,
cancel_order_page=make_frontend_url('/events/{identifier}/tickets/orders/cancelled'
.format(identifier=order.event.identifier))
)
)

Expand Down
Loading