Beispiel #1
0
class Ticket(APIView):
    events_repository = EventsRepository()
    users_service = UsersService()
    ticket_pdf_generator = TicketPdfGenerator()

    file_response = openapi.Response('File Attachment', schema=openapi.Schema(type=openapi.TYPE_FILE))
    authorization_token = openapi.Parameter('Authorization', openapi.IN_HEADER,
                                            description="Authorization token which starts with Bearer",
                                            type=openapi.TYPE_STRING)

    @swagger_auto_schema(operation_description='Endpoint for retrieving ticket',
                         responses={200: file_response, 403: None},
                         manual_parameters=[authorization_token])
    def get(self, request, event_id):
        jwt = request.headers['Authorization']
        user = self.users_service.fetch_by_jwt(jwt)
        event = self.events_repository.get_event_by_id(event_id)

        if not event.is_participant(user):
            return JsonResponse(data={'error': 'User is not a participant'}, status=status.HTTP_403_FORBIDDEN,
                                safe=False)

        if event.price is not None:
            if not user_paid_for_event(user, event):
                return JsonResponse(data={'error': 'The participant did not pay for the ticket'},
                                    status=status.HTTP_403_FORBIDDEN,
                                    safe=False)

        pdf = self.ticket_pdf_generator.generate(user, event)

        return FileResponse(pdf, as_attachment=True, filename='ticket.pdf')
class PlaceChecker:
    events_repository = EventsRepository()

    def __init__(self, place_id):
        self.place_id = place_id

    def check_if_place_available(self, start_datetime, end_datetime):
        events = self.events_repository.get_events_for_given_place_and_time_brakcet(
            self.place_id, start_datetime, end_datetime)

        if events:
            return False
        else:
            return True
Beispiel #3
0
class JoinEvent(APIView):
    events_repository = EventsRepository()
    users_service = UsersService()
    events_service = EventsService()

    authorization_token = openapi.Parameter('Authorization', openapi.IN_HEADER,
                                            description="Authorization token which starts with Bearer",
                                            type=openapi.TYPE_STRING)

    @swagger_auto_schema(operation_description='Endpoint for joining to event.',
                         manual_parameters=[authorization_token])
    def post(self, request, event_id):
        jwt = request.headers['Authorization']
        user = self.users_service.fetch_by_jwt(jwt)
        event = self.events_repository.get_event_by_id(event_id)
        return self.events_service.join(user, event)
Beispiel #4
0
class Event(APIView):
    events_repository = EventsRepository()
    users_service = UsersService()
    events_service = EventsService()

    event_response = openapi.Response('response description', EventSerializer(many=False))
    authorization_token = openapi.Parameter('Authorization', openapi.IN_HEADER,
                                            description="Authorization token which starts with Bearer",
                                            type=openapi.TYPE_STRING)

    @swagger_auto_schema(operation_description='Endpoint for retrieving single event given event id.',
                         responses={200: event_response, 404: None},
                         manual_parameters=[authorization_token])
    def get(self, request, event_id):
        jwt = request.headers['Authorization']
        user = self.users_service.fetch_by_jwt(jwt)
        event = self.events_repository.get_event_by_id(event_id)
        if not self.events_service.does_user_meet_requirements(event, user):
            return JsonResponse(dict(error="User does not meet requirements to preview this event"),
                                status=status.HTTP_404_NOT_FOUND, safe=False)
        serializer = EventSerializer(event, context=dict(user=user), many=False)
        response = serializer.data
        return JsonResponse(response, safe=False)
Beispiel #5
0
class PaymentsURL(APIView):
    events_repository = EventsRepository()
    users_service = UsersService()
    payments_repository = PaymentsRepository()

    payment_url_response = openapi.Response('response description',
                                            PaymentURLSerializer)

    event_id = openapi.Parameter('event_id',
                                 openapi.IN_QUERY,
                                 description="Event id",
                                 type=openapi.TYPE_INTEGER)

    authorization_token = openapi.Parameter(
        'Authorization',
        openapi.IN_HEADER,
        description="Authorization token which starts with Bearer",
        type=openapi.TYPE_STRING)

    @swagger_auto_schema(
        operation_description='Endpoint for acquiring urls for payments.',
        manual_parameters=[authorization_token, event_id],
        responses={
            404: None,
            200: payment_url_response,
            409: 'Payment already made',
            400: 'Event does not require payment',
            403: 'User is not a participant'
        },
    )
    def get(self, request):
        jwt = request.headers['Authorization']
        user = self.users_service.fetch_by_jwt(jwt)
        request_data = dict(request.GET)
        event_id = request_data.get('event_id', None)

        if event_id is None:
            return JsonResponse(data=None,
                                status=status.HTTP_404_NOT_FOUND,
                                safe=False)

        event_id = int(event_id[0])

        event = self.events_repository.get_event_by_id(event_id)

        payment = self.payments_repository.get_payment_for_user_and_event(
            user, event)

        if not event:
            return JsonResponse(data=None,
                                status=status.HTTP_404_NOT_FOUND,
                                safe=False)
        if event.price is None:
            return JsonResponse(
                data={'error': 'Event does not require payment'},
                status=status.HTTP_400_BAD_REQUEST,
                safe=False)
        if payment:
            return JsonResponse(data={'error': 'User already payed'},
                                status=status.HTTP_409_CONFLICT,
                                safe=False)
        if not event.participants.filter(id=user.id).exists():
            return JsonResponse(data={'error': 'User is not a participant'},
                                status=status.HTTP_403_FORBIDDEN,
                                safe=False)

        serializer = PaymentURLSerializer({
            'event_id': event_id,
            'price': event.price
        })
        response = serializer.data
        return JsonResponse(response, safe=False)
Beispiel #6
0
class Payments(APIView):
    events_repository = EventsRepository()
    users_service = UsersService()
    payments_repository = PaymentsRepository()

    authorization_token = openapi.Parameter(
        'Authorization',
        openapi.IN_HEADER,
        description="Authorization token which starts with Bearer",
        type=openapi.TYPE_STRING)

    payments_response = openapi.Response('response description',
                                         PaymentSerializer(many=True))

    @swagger_auto_schema(
        operation_description='Endpoint for confirming payments.',
        request_body=CreatePaymentSerializer,
        manual_parameters=[authorization_token],
        responses={
            202: 'Payment confirmed',
            400: 'Event does not require payment',
            403: 'User is not a participant',
            404: 'Event not found',
            409: 'User already payed'
        })
    def post(self, request):
        jwt = request.headers['Authorization']
        event_id = request.data['event_id']

        user = self.users_service.fetch_by_jwt(jwt)
        event = self.events_repository.get_event_by_id(event_id)

        payment = self.payments_repository.get_payment_for_user_and_event(
            user, event)

        if not event:
            return JsonResponse(data={'error': 'Event not found'},
                                status=status.HTTP_404_NOT_FOUND,
                                safe=False)
        if event.price is None:
            return JsonResponse(
                data={'error': 'Event does not require payment'},
                status=status.HTTP_400_BAD_REQUEST,
                safe=False)
        if payment:
            return JsonResponse(data={'error': 'User already payed'},
                                status=status.HTTP_409_CONFLICT,
                                safe=False)
        if not event.participants.filter(id=user.id):
            return JsonResponse(data={'error': 'User is not a participant'},
                                status=status.HTTP_400_BAD_REQUEST,
                                safe=False)

        serializer = CreatePaymentSerializer(data=request.data,
                                             context=dict(user=user,
                                                          event=event,
                                                          price=event.price))

        if serializer.is_valid(raise_exception=True):
            payment_to_save = serializer.save()
            self.events_repository.save(payment_to_save)
            return JsonResponse(data={'status': 'Payment confirmed'},
                                status=status.HTTP_202_ACCEPTED,
                                safe=False)
        return HttpResponseBadRequest()

    @swagger_auto_schema(
        responses={200: payments_response},
        operation_description='Endpoint for retrieving users payments.',
        manual_parameters=[authorization_token])
    def get(self, request):
        jwt = request.headers['Authorization']
        user = self.users_service.fetch_by_jwt(jwt)

        users_payments = self.payments_repository.get_payments_for_user(user)

        serializer = PaymentSerializer(users_payments,
                                       many=True,
                                       context=dict(user=user))
        response = serializer.data

        return JsonResponse(response, safe=False)
Beispiel #7
0
class Events(APIView):
    cyclic_events_generator = CyclicEventGenerator()
    events_repository = EventsRepository()
    users_service = UsersService()
    events_service = EventsService()
    events_response = openapi.Response('response description', EventSerializer(many=True))
    authorization_token = openapi.Parameter('Authorization', openapi.IN_HEADER,
                                            description="Authorization token which starts with Bearer",
                                            type=openapi.TYPE_STRING)
    price = openapi.Parameter('price', openapi.IN_QUERY, description="Returns events with lower or equal price",
                              type=openapi.FORMAT_FLOAT)
    date_from = openapi.Parameter('date_from', openapi.IN_QUERY,
                                  description="Returns events that started after given datetime (example: 2019-12-12T11:07:20+00:00)",
                                  type=openapi.FORMAT_DATETIME)
    date_to = openapi.Parameter('date_to', openapi.IN_QUERY,
                                description="Returns events that ended before given datetime (example: 2019-12-12T11:07:20+00:00)",
                                type=openapi.FORMAT_DATETIME)
    name_contains = openapi.Parameter('name_contains', openapi.IN_QUERY,
                                      description="Returns events that contain given name", type=openapi.TYPE_STRING)
    past_events = openapi.Parameter('past_events', openapi.IN_QUERY,
                                    description="Returns also events that already ended", type=openapi.TYPE_STRING)
    place = openapi.Parameter('place', openapi.IN_QUERY, description="Returns events that are happening at given place",
                              type=openapi.TYPE_STRING)
    user_signed_up = openapi.Parameter('user_signed_up', openapi.IN_QUERY,
                                       description="Returns only those events that user is signed up for",
                                       type=openapi.TYPE_BOOLEAN, default=False)

    user_is_assigned_lecturer = openapi.Parameter('user_is_assigned_lecturer', openapi.IN_QUERY,
                                                  description="Returns only those events that user is assigned as lecturer",
                                                  type=openapi.TYPE_BOOLEAN, default=False)

    only_not_cyclical_and_roots = openapi.Parameter('only_not_cyclical_and_roots', openapi.IN_QUERY,
                                                    description="Returns only those events that are not cyclical or are cyclic events roots",
                                                    type=openapi.TYPE_BOOLEAN, default=False)

    @swagger_auto_schema(operation_description='Endpoint for retrieving filtered events.',
                         responses={200: events_response, 404: []},
                         manual_parameters=[authorization_token, price, date_from, date_to, name_contains, past_events,
                                            place, user_signed_up, user_is_assigned_lecturer,
                                            only_not_cyclical_and_roots])
    def get(self, request):
        jwt = request.headers['Authorization']
        user = self.users_service.fetch_by_jwt(jwt)
        events = self.events_repository.find_events_for_given_with_respect_to_filters(self, user)
        available_events = list(
            filter(lambda event: self.events_service.does_user_meet_requirements(event, user), events))
        serializer = EventSerializer(available_events, context=dict(user=user), many=True)
        response = serializer.data
        return JsonResponse(response, safe=False)

    @swagger_auto_schema(request_body=CreateEventSerializer, operation_description='Endpoint for adding event.',
                         manual_parameters=[authorization_token],
                         responses={200: 'id',
                                    403: 'Only lecturers can create events',
                                    400: 'Frequency of event occurrence must be defined',
                                    409: 'This place is already booked for given time bracket'
                                    })
    def put(self, request):
        jwt = request.headers['Authorization']
        user = self.users_service.fetch_by_jwt(jwt)

        if not user.groups.filter(name='Lecturer').exists():
            return JsonResponse(data={"error": "Only lecturers can create events."},
                                status=status.HTTP_403_FORBIDDEN,
                                safe=False)

        frequency = request.data.get('frequency', None)
        place_id = request.data.get('place', None)
        start_datetime = request.data.get('start', None)
        end_datetime = request.data.get('end', None)

        if frequency is None or frequency not in ['ONCE', 'DAILY', 'WEEKLY', 'MONTHLY'] \
                or place_id is None or start_datetime is None or end_datetime is None:
            return JsonResponse(data={"error": "One of the parameters is not defined"},
                                status=status.HTTP_400_BAD_REQUEST,
                                safe=False)

        if not is_place_free_in_time_bracket(place_id, start_datetime, end_datetime):
            return JsonResponse(data={"error": "This place is already booked for given time"},
                                status=status.HTTP_409_CONFLICT,
                                safe=False)

        if not is_start_and_end_in_the_same_day_and_in_right_order(start_datetime, end_datetime):
            return JsonResponse(data={
                "error": "Event must start and end on the same day and the start must be before end of the event "},
                status=status.HTTP_400_BAD_REQUEST,
                safe=False)

        if frequency == 'ONCE':
            serializer = CreateEventSerializer(data=request.data, context=dict(root=None, is_cyclic=False, user=user))

            if serializer.is_valid(raise_exception=True):
                event_to_save = serializer.save()
                id = self.events_repository.save(event_to_save).pk
                return JsonResponse({'id': id}, safe=False)
            return HttpResponseBadRequest()

        else:
            cyclic_boundary = request.data.get('cyclic_boundary', None)

            if not is_cyclic_boundary_after_event_end(end_datetime, cyclic_boundary):
                return JsonResponse(data={"error": "Cyclic boundary cant be before events end"},
                                    status=status.HTTP_400_BAD_REQUEST,
                                    safe=False)

            # Creating root
            serializer = CreateEventSerializer(data=request.data, context=dict(root=None, is_cyclic=True, user=user))
            if serializer.is_valid(raise_exception=True):
                root_event = serializer.save()

            data_copy = deepcopy(request.data)
            cyclic_events = self.cyclic_events_generator.generate_events(data_copy)
            for event in cyclic_events:
                print(event)

            if not place_is_free_for_cyclic_event(cyclic_events):
                root_event.delete()

                return JsonResponse(data={"error": "This place is already booked for given time"},
                                    status=status.HTTP_409_CONFLICT,
                                    safe=False)
            else:
                serializer = CreateEventSerializer(data=cyclic_events, many=True,
                                                   context=dict(root=root_event, is_cyclic=True, user=user))

                if serializer.is_valid(raise_exception=True):
                    events_to_save = serializer.save()
                    events_ids = [root_event.id]
                    events_ids.extend([event.id for event in events_to_save])
                    return JsonResponse({'ids': events_ids}, safe=False)
                else:
                    root_event.delete()

                return HttpResponseBadRequest()
 def __init__(self):
     self.events_repository = EventsRepository()
class EventsService:
    def __init__(self):
        self.events_repository = EventsRepository()

    def join(self, user, event):
        if event.is_cyclic:
            if event.root:
                cyclic_events = self.events_repository.find_all_cyclic_events_for_given_root(
                    event.root)
            else:
                cyclic_events = self.events_repository.find_all_cyclic_events_for_given_root(
                    event)

            validations = [self.can_join(user, e) for e in cyclic_events]

            if self.there_are_failures(validations):
                return validations[0]
            else:
                [self.join_event(e, user) for e in cyclic_events]
                return HttpResponse(status=status.HTTP_201_CREATED)

        validation = self.can_join(user, event)
        if type(validation) is not JsonResponse:
            return self.join_event(event, user)
        else:
            return validation

    def there_are_failures(self, validations):
        return len(list(filter(lambda x: x is True,
                               validations))) != len(validations)

    def join_event(self, event, user):
        event.number_of_participants = event.number_of_participants + 1
        event.participants.add(user)
        event.save()
        return HttpResponse(status=status.HTTP_201_CREATED)

    def can_join(self, user, event):
        serialized_event = EventSerializer(event,
                                           context=dict(user=user),
                                           many=False).data
        if serialized_event['limit_of_participants'] <= serialized_event[
                'amount_of_participants']:
            return JsonResponse(dict(error='Event is full.'),
                                safe=False,
                                status=400)

        if serialized_event['is_signed_up_for']:
            return JsonResponse(
                dict(error='User is already signed up for this event'),
                safe=False,
                status=400)

        if not self.does_user_meet_requirements(event, user):
            return JsonResponse(dict(error='User does not meet requirements'),
                                safe=False,
                                status=400)

        return True

    def does_user_meet_requirements(self, event, user):
        return RequirementsChecker(event.requirements).check(user)