Ejemplo n.º 1
0
    def before_update_object(self, event_topic, data, view_kwargs):
        """
        method to save image urls before updating event object
        :param event_topic:
        :param data:
        :param view_kwargs:
        :return:
        """
        if data.get('system_image_url'):
            try:
                uploaded_image = create_system_image(
                    data['system_image_url'], unique_identifier=event_topic.id)
            except (urllib.error.HTTPError, urllib.error.URLError):
                raise UnprocessableEntityError(
                    {'source': 'attributes/system-image-url'},
                    'Invalid Image URL')
            except IOError:
                raise UnprocessableEntityError(
                    {'source': 'attributes/system-image-url'},
                    'Image is absent at URL')
        else:
            try:
                uploaded_image = create_system_image(
                    unique_identifier=event_topic.id)
            except IOError:
                raise UnprocessableEntityError(
                    {'source': ''}, 'Default Image is absent in server')

            data['system_image_url'] = uploaded_image['system_image_url']
Ejemplo n.º 2
0
 def before_update_object(self, ticket, data, view_kwargs):
     """
     method to check if paid ticket has payment method before updating ticket object
     :param ticket:
     :param data:
     :param view_kwargs:
     :return:
     """
     if ticket.type == 'paid' or ticket.type == 'donation':
         try:
             event = (
                 db.session.query(Event)
                 .filter_by(id=ticket.event.id, deleted_at=None)
                 .one()
             )
         except NoResultFound:
             raise UnprocessableEntityError(
                 {'event_id': ticket.event.id}, "Event does not exist"
             )
         if not event.is_payment_enabled():
             raise UnprocessableEntityError(
                 {'event_id': ticket.event.id},
                 "Event having paid ticket must have a payment method",
             )
     
     if (data.get('deleted_at') and ticket.has_current_orders):
         raise ForbiddenError(
             {'param': 'ticket_id'},
             "Can't delete a ticket that has sales",
         )
Ejemplo n.º 3
0
    def validate_quantity(self, data):
        if 'max_order' in data and 'min_order' in data:
            if data['max_order'] < data['min_order']:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/max-order'},
                    "max-order should be greater than or equal to min-order",
                )

        if 'quantity' in data and 'min_order' in data:
            if data['quantity'] < data['min_order']:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/quantity'},
                    "quantity should be greater than or equal to min-order",
                )

        if 'min_price' in data and 'max_price' in data and data['type'] == 'donation':
            if data['min_price'] > data['max_price']:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/min-price'},
                    "minimum price should be lesser than or equal to maximum price",
                )

        if 'quantity' in data and 'max_order' in data:
            if data['quantity'] < data['max_order']:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/quantity'},
                    "quantity should be greater than or equal to max-order",
                )
Ejemplo n.º 4
0
 def validate_satus(self, data, original_data):
     if 'role' in data and 'role_name' in data:
         try:
             role = Role.query.filter_by(id=data['role']).one()
         except NoResultFound:
             raise ObjectNotFound({'source': '/data/role'},
                                  "Role not found")
         if role.name != data['role_name']:
             raise UnprocessableEntityError(
                 {'pointer': '/data/attributes/role'},
                 "Role id do not match role name")
     if 'id' in original_data['data']:
         try:
             role_invite = RoleInvite.query.filter_by(
                 id=original_data['data']['id']).one()
         except NoResultFound:
             raise ObjectNotFound({'source': '/data/id'},
                                  "Role invite not found")
         if 'role' not in data:
             data['role'] = role_invite.role.id
         if 'role_name' in data:
             try:
                 role = Role.query.filter_by(id=data['role']).one()
             except NoResultFound:
                 raise ObjectNotFound({'source': '/data/role'},
                                      "Role not found")
             if role.name != data['role_name']:
                 raise UnprocessableEntityError(
                     {'pointer': '/data/attributes/role'},
                     "Role id do not match role name",
                 )
Ejemplo n.º 5
0
    def before_create_object(self, data, view_kwargs):
        """
        before create method to check if paid ticket has a paymentMethod enabled
        :param data:
        :param view_kwargs:
        :return:
        """
        if data.get('event'):
            try:
                event = (
                    db.session.query(Event)
                    .filter_by(id=data['event'], deleted_at=None)
                    .one()
                )
            except NoResultFound:
                raise UnprocessableEntityError(
                    {'event_id': data['event']}, "Event does not exist"
                )

            if data.get('type') == 'paid' or data.get('type') == 'donation':
                if not event.is_payment_enabled():
                    raise UnprocessableEntityError(
                        {'event_id': data['event']},
                        "Event having paid ticket must have a payment method",
                    )

            if data.get('sales_ends_at') > event.ends_at:
                raise UnprocessableEntityError(
                    {'sales_ends_at': '/data/attributes/sales-ends-at'},
                    "Ticket end date cannot be greater than event end date",
                )
Ejemplo n.º 6
0
def validate_custom_form_constraints(form, obj):
    form_fields = CustomForms.query.filter_by(
        form=form,
        event_id=obj.event_id,
        is_included=True,
    ).all()
    required_form_fields = filter(lambda field: field.is_required, form_fields)
    missing_required_fields = []
    for field in required_form_fields:
        if not field.is_complex:
            if not getattr(obj, field.identifier):
                missing_required_fields.append(field.identifier)
        else:
            if not (obj.complex_field_values or {}).get(field.identifier):
                missing_required_fields.append(field.identifier)

    if len(missing_required_fields) > 0:
        raise UnprocessableEntityError(
            {'pointer': '/data/attributes'},
            f'Missing required fields {missing_required_fields}',
        )

    if obj.complex_field_values:
        complex_form_fields = filter(lambda field: field.is_complex,
                                     form_fields)
        schema = get_schema(complex_form_fields)()

        data, errors = schema.load(obj.complex_field_values)

        if errors:
            raise UnprocessableEntityError({'errors': errors},
                                           'Schema Validation Error')

        # We need to save null if resultant dictionary is empty
        return data if data else None
Ejemplo n.º 7
0
    def validate_order_quantity(self, data, original_data):
        if 'id' in original_data['data']:
            access_code = AccessCode.query.filter_by(
                id=original_data['data']['id']).one()

            if 'min_quantity' not in data:
                data['min_quantity'] = access_code.min_quantity

            if 'max_quantity' not in data:
                data['max_quantity'] = access_code.max_quantity

            if 'tickets_number' not in data:
                data['tickets_number'] = access_code.tickets_number

        min_quantity = data.get('min_quantity', None)
        max_quantity = data.get('max_quantity', None)
        tickets_number = data.get('tickets_number', None)
        if min_quantity and max_quantity and (min_quantity > max_quantity):
            raise UnprocessableEntityError(
                {'pointer': '/data/attributes/min-quantity'},
                "min-quantity should be less than max-quantity",
            )

        if tickets_number and max_quantity and (tickets_number < max_quantity):
            raise UnprocessableEntityError(
                {'pointer': '/data/attributes/tickets-number'},
                "tickets-number should be greater than max-quantity",
            )
Ejemplo n.º 8
0
def validate_date(event, data):
    if event:
        if 'starts_at' not in data:
            data['starts_at'] = event.starts_at

        if 'ends_at' not in data:
            data['ends_at'] = event.ends_at

    if not data.get('starts_at') or not data.get('ends_at'):
        raise UnprocessableEntityError(
            {'pointer': '/data/attributes/date'},
            "enter required fields starts-at/ends-at",
        )

    if data['starts_at'] >= data['ends_at']:
        raise UnprocessableEntityError({'pointer': '/data/attributes/ends-at'},
                                       "ends-at should be after starts-at")

    if datetime.timestamp(data['starts_at']) <= datetime.timestamp(
            datetime.now()):
        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 UnprocessableEntityError(
                {'pointer': '/data/attributes/starts-at'},
                "starts-at should be after current date-time",
            )
Ejemplo n.º 9
0
    def after_create_object(self, event_topic, data, view_kwargs):
        """
        after create method to save roles for users and add the user as an accepted role(organizer)
        :param event_topic:
        :param data:
        :param view_kwargs:
        :return:
        """
        if data.get('system_image_url'):
            try:
                uploaded_image = create_system_image(
                    data['system_image_url'], unique_identifier=event_topic.id)
            except (urllib.error.HTTPError, urllib.error.URLError):
                raise UnprocessableEntityError(
                    {'source': 'attributes/system-image-url'},
                    'Invalid Image URL')
            except IOError:
                raise UnprocessableEntityError(
                    {'source': 'attributes/system-image-url'},
                    'Image is absent at URL')
        else:
            try:
                uploaded_image = create_system_image(
                    unique_identifier=event_topic.id)
            except IOError:
                raise UnprocessableEntityError(
                    {'source': ''}, 'Default Image is absent in server')

        self.session.query(EventTopic).filter_by(
            id=event_topic.id).update(uploaded_image)
        self.session.commit()
Ejemplo n.º 10
0
    def before_create_object(self, data, view_kwargs):
        """
        method to check if there is an existing user with same email which is received in data to create a new user
        and if the password is at least 8 characters long
        :param data:
        :param view_kwargs:
        :return:
        """
        if len(data['password']) < 8:
            logging.error('Password should be at least 8 characters long')
            raise UnprocessableEntityError(
                {'source': '/data/attributes/password'},
                'Password should be at least 8 characters long',
            )
        if (db.session.query(
                User.id).filter_by(email=data['email'].strip()).scalar()
                is not None):
            logging.error('Email already exists')
            raise ConflictError({'pointer': '/data/attributes/email'},
                                "Email already exists")

        if data.get('is_verified'):
            logging.error("You are not allowed to submit this field")
            raise UnprocessableEntityError(
                {'pointer': '/data/attributes/is-verified'},
                "You are not allowed to submit this field",
            )
Ejemplo n.º 11
0
def check_billing_info(data):
    if (data.get('amount') and data.get('amount') > 0
            and not data.get('is_billing_enabled')):
        raise UnprocessableEntityError(
            {'pointer': '/data/attributes/is_billing_enabled'},
            "Billing information is mandatory for this order",
        )
    if data.get('is_billing_enabled') and not (
            data.get('company') and data.get('address') and data.get('city')
            and data.get('zipcode') and data.get('country')):
        raise UnprocessableEntityError(
            {'pointer': '/data/attributes/is_billing_enabled'},
            "Billing information incomplete",
        )
Ejemplo n.º 12
0
    def validate_value(self, data, original_data):
        if 'id' in original_data['data']:
            try:
                discount_code = DiscountCode.query.filter_by(
                    id=original_data['data']['id']).one()
            except NoResultFound:
                raise ObjectNotFound({'parameter': '{code}'},
                                     "DiscountCode: not found")

            if 'type' not in data:
                data['type'] = discount_code.type

            if 'value' not in data:
                data['value'] = discount_code.value

        if data['type'] == "percent":
            if 'tickets' in data:
                for ticket in data['tickets']:
                    ticket_object = Ticket.query.filter_by(id=ticket).one()
                    if not ticket_object.price:
                        raise UnprocessableEntityError(
                            {'pointer': '/data/attributes/tickets'},
                            "discount code cannot be applied on free tickets",
                        )
            if data['value'] < 0 or data['value'] > 100:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/value'},
                    "discount percent must be within range of 0 and 100",
                )

        if data['type'] == "amount":
            if 'tickets' in data:
                for ticket in data['tickets']:
                    ticket_object = Ticket.query.filter_by(id=ticket).one()
                    if not ticket_object.price:
                        raise UnprocessableEntityError(
                            {'pointer': '/data/attributes/tickets'},
                            "discount code cannot be applied on free tickets",
                        )
                    if ticket_object.price < data['value']:
                        raise UnprocessableEntityError(
                            {'pointer': '/data/attributes/value'},
                            "discount amount cannot be more than ticket amount",
                        )
            if data['value'] < 0:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/value'},
                    "discount amount cannot be less than zero",
                )
Ejemplo n.º 13
0
    def before_post(self, args, kwargs, data):
        """
        Before post method to check for required relationship and proper permissions
        :param args:
        :param kwargs:
        :param data:
        :return:
        """
        require_relationship(['ticket', 'event'], data)

        ticket = (
            db.session.query(Ticket)
            .filter_by(id=int(data['ticket']), deleted_at=None)
            .first()
        )
        if ticket is None:
            raise UnprocessableEntityError(
                {'pointer': '/data/relationships/ticket'}, "Invalid Ticket"
            )
        if ticket.event_id != int(data['event']):
            raise UnprocessableEntityError(
                {'pointer': '/data/relationships/ticket'},
                "Ticket belongs to a different Event",
            )
        # Check if the ticket is already sold out or not.
        ticket.raise_if_unavailable()

        if 'device_name_checkin' in data and data['device_name_checkin'] is not None:
            if 'is_checked_in' not in data or not data['is_checked_in']:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/device_name_checkin'},
                    "Attendee needs to be checked in first",
                )
            if 'checkin_times' not in data or data['checkin_times'] is None:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/device_name_checkin'},
                    "Check in Times missing",
                )
            if len(data['checkin_times'].split(",")) != len(
                data['device_name_checkin'].split(",")
            ):
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/device_name_checkin'},
                    "Check in Times missing for the corresponding device name",
                )

        if 'checkin_times' in data:
            if 'device_name_checkin' not in data or data['device_name_checkin'] is None:
                data['device_name_checkin'] = '-'
Ejemplo n.º 14
0
    def validate_fields(self, data, original_data):
        is_patch_request = 'id' in original_data['data']
        if is_patch_request:
            try:
                session = Session.query.filter_by(
                    id=original_data['data']['id']).one()
            except NoResultFound:
                raise ObjectNotFound({'parameter': '{id}'},
                                     "Session: not found")

            if 'starts_at' not in data:
                data['starts_at'] = session.starts_at

            if 'ends_at' not in data:
                data['ends_at'] = session.ends_at

            if 'event' not in data:
                data['event'] = session.event_id

        if data['starts_at'] and data['ends_at']:
            if data['starts_at'] >= data['ends_at']:
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/ends-at'},
                    "ends-at should be after starts-at",
                )
            if not is_patch_request and datetime.timestamp(
                    data['starts_at']) <= datetime.timestamp(datetime.now()):
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/starts-at'},
                    "starts-at should be after current date-time",
                )

        if 'state' in data:
            if data['state'] not in ('draft', 'pending'):
                if not has_access('is_coorganizer', event_id=data['event']):
                    raise ForbiddenError({'source': ''},
                                         'Co-organizer access is required.')

        if 'track' in data:
            if not has_access('is_coorganizer', event_id=data['event']):
                raise ForbiddenError({'source': ''},
                                     'Co-organizer access is required.')

        if 'microlocation' in data:
            if not has_access('is_coorganizer', event_id=data['event']):
                raise ForbiddenError({'source': ''},
                                     'Co-organizer access is required.')

        validate_complex_fields_json(self, data, original_data)
Ejemplo n.º 15
0
def resend_emails():
    """
    Sends confirmation email for pending and completed orders on organizer request
    :param order_identifier:
    :return: JSON response if the email was succesfully sent
    """
    order_identifier = request.json['data']['order']
    order = safe_query(db, Order, 'identifier', order_identifier, 'identifier')
    if (has_access('is_coorganizer', event_id=order.event_id)):
        if order.status == 'completed' or order.status == 'placed':
            # fetch tickets attachment
            order_identifier = order.identifier
            key = UPLOAD_PATHS['pdf']['tickets_all'].format(identifier=order_identifier)
            ticket_path = 'generated/tickets/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'
            key = UPLOAD_PATHS['pdf']['order'].format(identifier=order_identifier)
            invoice_path = 'generated/invoices/{}/{}/'.format(key, generate_hash(key)) + order_identifier + '.pdf'

            # send email.
            send_email_to_attendees(order=order, purchaser_id=current_user.id, attachments=[ticket_path, invoice_path])
            return jsonify(status=True, message="Verification emails for order : {} has been sent succesfully".
                           format(order_identifier))
        else:
            return UnprocessableEntityError({'source': 'data/order'},
                                            "Only placed and completed orders have confirmation").respond()
    else:
        return ForbiddenError({'source': ''}, "Co-Organizer Access Required").respond()
Ejemplo n.º 16
0
def test_email_setup():
    recipient = request.json.get('recipient')
    if not recipient:
        return UnprocessableEntityError({'source': 'recipient'},
                                        'Required parameter recipient not found').respond()
    send_test_email(recipient)
    return make_response(jsonify(message='Test mail sent, please verify delivery'), 200)
Ejemplo n.º 17
0
def reject_invite(speaker_invite_id):
    try:
        speaker_invite = SpeakerInvite.query.filter_by(
            id=speaker_invite_id).one()
    except NoResultFound:
        raise NotFoundError({'source': ''}, 'Speaker Invite Not Found')
    else:
        if not current_user.email == speaker_invite.email:
            raise ForbiddenError({'source': ''}, 'Invitee access is required.')
        elif speaker_invite.status == 'accepted':
            raise ConflictError(
                {'pointer': '/data/status'},
                'Accepted speaker invite can not be rejected.',
            )
        elif speaker_invite.status == 'rejected':
            raise ConflictError(
                {'pointer': '/data/status'},
                'Speaker invite is already rejected.',
            )
        try:
            speaker_invite.status = 'rejected'
            save_to_db(speaker_invite, {'speaker invite rejected'})
        except Exception:
            raise UnprocessableEntityError(
                {'source': ''}, 'error while rejecting speaker invite.')
    return jsonify(
        success=True,
        message="Speaker invite rejected successfully",
    )
def require_relationship(resource_list, data):
    for resource in resource_list:
        if resource not in data:
            raise UnprocessableEntityError(
                {'pointer': '/data/relationships/{}'.format(resource)},
                "A valid relationship with {} resource is required".format(resource),
            )
Ejemplo n.º 19
0
    def validate_quantity(self, data, original_data):
        if 'id' in original_data['data']:
            try:
                discount_code = DiscountCode.query.filter_by(
                    id=original_data['data']['id']
                ).one()
            except NoResultFound:
                raise ObjectNotFound({'parameter': '{code}'}, "DiscountCode: not found")
            if 'min_quantity' not in data:
                data['min_quantity'] = discount_code.min_quantity

            if 'max_quantity' not in data:
                data['max_quantity'] = discount_code.max_quantity

            if 'tickets_number' not in data:
                data['tickets_number'] = discount_code.tickets_number

        DiscountCodeSchemaEvent.quantity_validation_helper(data)

        if data.get('tickets_number') and data.get('max_quantity'):
            if (
                data['max_quantity'] >= 0
                and data['tickets_number'] < data['max_quantity']
            ):
                raise UnprocessableEntityError(
                    {'pointer': '/data/attributes/tickets-number'},
                    "tickets-number should be greater than max-quantity",
                )
Ejemplo n.º 20
0
    def test_errors(self):
        """Method to test the status code of all errors"""

        with app.test_request_context():
            # Forbidden Error
            forbidden_error = ForbiddenError({'source': ''},
                                             'Super admin access is required')
            self.assertEqual(forbidden_error.status, 403)

            # Not Found Error
            not_found_error = NotFoundError({'source': ''},
                                            'Object not found.')
            self.assertEqual(not_found_error.status, 404)

            # Server Error
            server_error = ServerError({'source': ''}, 'Internal Server Error')
            self.assertEqual(server_error.status, 500)

            # UnprocessableEntity Error
            unprocessable_entity_error = UnprocessableEntityError(
                {'source': ''}, 'Entity cannot be processed')
            self.assertEqual(unprocessable_entity_error.status, 422)

            # Bad Request Error
            bad_request_error = BadRequestError({'source': ''},
                                                'Request cannot be served')
            self.assertEqual(bad_request_error.status, 400)
Ejemplo n.º 21
0
def require_relationship(resource_list, data):
    for resource in resource_list:
        if resource not in data:
            raise UnprocessableEntityError(
                {'pointer': f'/data/relationships/{resource}'},
                f"A valid relationship with {resource} resource is required",
            )
Ejemplo n.º 22
0
def send_receipt():
    """
    Send receipts to attendees related to the provided order.
    :return:
    """
    order_identifier = request.json.get('order-identifier')
    if order_identifier:
        try:
            order = db.session.query(Order).filter_by(
                identifier=order_identifier).one()
        except NoResultFound:
            return NotFoundError({
                'parameter': '{order_identifier}'
            }, "Order not found").respond()

        if (order.user_id != current_user.id) and (not has_access(
                'is_registrar', event_id=order.event_id)):
            return ForbiddenError({
                'source': ''
            }, 'You need to be the event organizer or order buyer to send receipts.'
                                  ).respond()
        elif order.status != 'completed':
            abort(
                make_response(
                    jsonify(
                        error="Cannot send receipt for an incomplete order"),
                    409))
        else:
            send_email_to_attendees(order, current_user.id)
            return jsonify(message="receipt sent to attendees")
    else:
        return UnprocessableEntityError({
            'source': ''
        }, 'Order identifier missing').respond()
Ejemplo n.º 23
0
def resend_verification_email():
    try:
        email = request.json['data']['email']
    except TypeError:
        logging.error('Bad Request')
        raise BadRequestError({'source': ''}, 'Bad Request Error')

    try:
        user = User.query.filter_by(email=email).one()
    except NoResultFound:
        logging.info('User with email: ' + email + ' not found.')
        raise UnprocessableEntityError(
            {'source': ''}, 'User with email: ' + email + ' not found.'
        )
    else:
        serializer = get_serializer()
        hash_ = str(
            base64.b64encode(
                str(serializer.dumps([user.email, str_generator()])).encode()
            ),
            'utf-8',
        )
        link = make_frontend_url('/verify', {'token': hash_})
        send_email_confirmation(user.email, link)
        logging.info('Verification email resent')
        return make_response(jsonify(message="Verification email resent"), 200)
 def before_create_object(self, data, view_kwargs):
     """
     method to check if stripe authorization object already exists for an event.
     Raises ConflictError if it already exists.
     If it doesn't, then uses the StripePaymentManager to get the other credentials from Stripe.
     :param data:
     :param view_kwargs:
     :return:
     """
     try:
         self.session.query(StripeAuthorization).filter_by(
             event_id=data['event'], deleted_at=None).one()
     except NoResultFound:
         credentials = StripePaymentsManager.get_event_organizer_credentials_from_stripe(
             data['stripe_auth_code'])
         if 'error' in credentials:
             raise UnprocessableEntityError(
                 {'pointer': '/data/stripe_auth_code'},
                 credentials['error_description'],
             )
         data['stripe_secret_key'] = credentials['access_token']
         data['stripe_refresh_token'] = credentials['refresh_token']
         data['stripe_publishable_key'] = credentials[
             'stripe_publishable_key']
         data['stripe_user_id'] = credentials['stripe_user_id']
     else:
         raise ConflictError(
             {'pointer': '/data/relationships/event'},
             "Stripe Authorization already exists for this event",
         )
Ejemplo n.º 25
0
    def test_exceptions(self):
        """Method to test all exceptions."""

        # Unprocessable Entity Exception
        with self.assertRaises(UnprocessableEntityError):
            raise UnprocessableEntityError(
                {'pointer': '/data/attributes/min-quantity'},
                "min-quantity should be less than max-quantity",
            )

        # Conflict Exception
        with self.assertRaises(ConflictError):
            raise ConflictError({'pointer': '/data/attributes/email'},
                                "Email already exists")

        # Forbidden Exception
        with self.assertRaises(ForbiddenError):
            raise ForbiddenError({'source': ''}, "Access Forbidden")

        # Not Found Error
        with self.assertRaises(NotFoundError):
            raise NotFoundError({'source': ''}, "Not Found")

        # Server Error
        with self.assertRaises(ServerError):
            raise ServerError({'source': ''}, "Internal Server Error")

        # Bad Request Error
        with self.assertRaises(BadRequestError):
            raise BadRequestError({'source': ''}, "Bad Request")

        # Method Not Allowed Exception
        with self.assertRaises(MethodNotAllowed):
            raise MethodNotAllowed({'source': ''}, "Method Not Allowed")
Ejemplo n.º 26
0
    def before_update_object(self, discount, data, view_kwargs):
        """
        Method to edit object
        :param discount:
        :param data:
        :param view_kwargs:
        :return:
        """
        if 'used_for' in data:
            used_for = data['used_for']
        else:
            used_for = discount.used_for
        if (
            discount.used_for == 'ticket'
            and has_access('is_coorganizer', event_id=view_kwargs.get('event_id'))
            and used_for != 'event'
        ):
            self.schema = DiscountCodeSchemaTicket
            self.resource.schema = DiscountCodeSchemaTicket

        elif (
            discount.used_for == 'event'
            and has_access('is_admin')
            and used_for != 'ticket'
        ):
            self.schema = DiscountCodeSchemaEvent
            self.resource.schema = DiscountCodeSchemaEvent
        else:
            raise UnprocessableEntityError(
                {'source': ''}, "Please verify your permission"
            )
Ejemplo n.º 27
0
def create_onsite_attendees_for_order(data):
    """
    Creates on site ticket holders for an order and adds it into the request data.
    :param data: data initially passed in the POST request for order.
    :return:
    """
    on_site_tickets = data.get('on_site_tickets')

    if not on_site_tickets:
        raise UnprocessableEntityError(
            {'pointer': 'data/attributes/on_site_tickets'},
            'on_site_tickets info missing')

    data['ticket_holders'] = []

    for on_site_ticket in on_site_tickets:
        ticket_id = on_site_ticket['id']
        quantity = int(on_site_ticket['quantity'])

        ticket = safe_query_without_soft_deleted_entries(
            Ticket, 'id', ticket_id, 'ticket_id')

        ticket_sold_count = get_count(
            db.session.query(TicketHolder.id).filter_by(ticket_id=int(
                ticket.id),
                                                        deleted_at=None))

        # Check if the ticket is already sold out or not.
        if ticket_sold_count + quantity > ticket.quantity:
            # delete the already created attendees.
            for holder in data['ticket_holders']:
                ticket_holder = (db.session.query(TicketHolder).filter(
                    id == int(holder)).one())
                db.session.delete(ticket_holder)
                try:
                    db.session.commit()
                except Exception:
                    logging.exception('DB Exception!')
                    db.session.rollback()

            raise ConflictError(
                {'pointer': '/data/attributes/on_site_tickets'},
                "Ticket with id: {} already sold out. You can buy at most {} tickets"
                .format(ticket_id, ticket.quantity - ticket_sold_count),
            )

        for _ in range(1, quantity):
            ticket_holder = TicketHolder(
                firstname='onsite',
                lastname='attendee',
                email='*****@*****.**',
                ticket_id=ticket.id,
                event_id=data.get('event'),
            )
            save_to_db(ticket_holder)
            data['ticket_holders'].append(ticket_holder.id)

    # delete from the data.
    del data['on_site_tickets']
Ejemplo n.º 28
0
 def validate_length(self, data):
     try:
         datetime.strptime(data['length'], '%H:%M')
     except ValueError:
         raise UnprocessableEntityError(
             {'pointer': '/data/attributes/length'},
             "Length should be in the format %H:%M",
         )
Ejemplo n.º 29
0
 def validate_price(self, data):
     if 'type' not in data:
         return
     if data['type'] == 'paid' and ('price' not in data or data['price'] <= 0):
         raise UnprocessableEntityError(
             {'pointer': 'data/attributes/price'},
             "paid ticket price should be greater than 0",
         )
Ejemplo n.º 30
0
def create_order():
    data, errors = OrderAmountInputSchema().load(request.get_json())
    if errors:
        return make_response(jsonify(errors), 422)

    tickets_dict = data['tickets']
    order_amount = calculate_order_amount(tickets_dict, data.get('discount_code'))
    ticket_ids = {ticket['id'] for ticket in tickets_dict}
    ticket_map = {int(ticket['id']): ticket for ticket in tickets_dict}
    tickets = (
        Ticket.query.filter_by(deleted_at=None).filter(Ticket.id.in_(ticket_ids)).all()
    )

    if not tickets:
        raise UnprocessableEntityError(
            {'source': 'tickets'},
            "Tickets missing in Order request",
        )

    event = tickets[0].event

    try:
        attendees = []
        for ticket in tickets:
            for _ in range(ticket_map[ticket.id]['quantity']):
                ticket.raise_if_unavailable()
                attendees.append(
                    TicketHolder(firstname='', lastname='', ticket=ticket, event=event)
                )
                db.session.commit()
    except Exception as e:
        db.session.rollback()
        raise e

    validate_attendees({attendee.id for attendee in attendees})

    if data.get('amount') is not None and (
        current_user.is_staff or has_access('is_coorganizer', event_id=event.id)
    ):
        # If organizer or admin has overrided the amount of order
        order_amount['total'] = data['amount']

    order = Order(
        amount=order_amount['total'],
        event=event,
        discount_code_id=data.get('discount_code'),
        ticket_holders=attendees,
    )
    db.session.commit()
    order.populate_and_save()

    order_tickets = OrderTicket.query.filter_by(order_id=order.id).all()
    for order_ticket in order_tickets:
        ticket_info = ticket_map[order_ticket.ticket.id]
        order_ticket.price = ticket_info.get('price')
        save_to_db(order_ticket)
    
    return OrderSchema().dump(order)