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:
            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)):
            abort(
                make_response(jsonify(error="You need to be the event organizer or order buyer to send receipts."), 403)
            )
        elif order.status != 'completed':
            abort(
                make_response(jsonify(error="Cannot send receipt for an incomplete order"), 409)
            )
        else:
            send_email_to_attendees(order, current_identity.id)
            return jsonify(message="receipt sent to attendees")
    else:
        abort(
            make_response(jsonify(error="Order identifier missing"), 422)
        )
Exemple #2
0
    def after_update_object(self, order, data, view_kwargs):
        """
        :param order:
        :param data:
        :param view_kwargs:
        :return:
        """
        # create pdf tickets.
        create_pdf_tickets_for_holder(order)

        if order.status == 'cancelled':
            send_order_cancel_email(order)
            send_notif_ticket_cancel(order)

            # delete the attendees so that the tickets are unlocked.
            delete_related_attendees_for_order(order)

        elif order.status == 'completed':
            send_email_to_attendees(order, current_user.id)
            send_notif_to_attendees(order, current_user.id)

            order_url = make_frontend_url(path='/orders/{identifier}'.format(
                identifier=order.identifier))
            for organizer in order.event.organizers:
                send_notif_ticket_purchase_organizer(organizer,
                                                     order.invoice_number,
                                                     order_url,
                                                     order.event.name,
                                                     order.identifier)
    def charge_paypal_order_payment(order, paypal_payer_id, paypal_payment_id):
        """
        Charge the user through paypal.
        :param order: Order for which to charge for.
        :param paypal_payment_id: payment_id
        :param paypal_payer_id: payer_id
        :return:
        """

        # save the paypal payment_id with the order
        order.paypal_token = paypal_payment_id
        save_to_db(order)

        # create the transaction.
        status, error = PayPalPaymentsManager.execute_payment(
            paypal_payer_id, paypal_payment_id
        )

        if status:
            # successful transaction hence update the order details.
            order.paid_via = 'paypal'
            order.status = 'completed'
            order.transaction_id = paypal_payment_id
            order.completed_at = datetime.utcnow()
            save_to_db(order)

            # create tickets
            create_pdf_tickets_for_holder(order)

            # send email and notifications
            send_email_to_attendees(order, order.user_id)
            send_notif_to_attendees(order, order.user_id)

            order_url = make_frontend_url(
                path='/orders/{identifier}'.format(identifier=order.identifier)
            )
            for organizer in order.event.organizers:
                send_notif_ticket_purchase_organizer(
                    organizer, order.invoice_number, order_url, order.event.name, order.id
                )
            if order.event.owner:
                send_notif_ticket_purchase_organizer(
                    order.event.owner,
                    order.invoice_number,
                    order_url,
                    order.event.name,
                    order.id,
                )

            return True, 'Charge successful'
        else:
            # payment failed hence expire the order
            order.status = 'expired'
            save_to_db(order)

            # delete related attendees to unlock the tickets
            delete_related_attendees_for_order(order)

            # return the error message from Paypal
            return False, error
Exemple #4
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:
            raise ObjectNotFound({'parameter': '{identifier}'},
                                 "Order not found")

        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))
        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:
        abort(make_response(jsonify(error="Order identifier missing"), 422))
Exemple #5
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()
Exemple #6
0
    def after_update_object(self, order, data, view_kwargs):
        """
        :param order:
        :param data:
        :param view_kwargs:
        :return:
        """
        # create pdf tickets.
        create_pdf_tickets_for_holder(order)

        if order.status == 'cancelled' and order.deleted_at is None:
            send_order_cancel_email(order)
            send_notif_ticket_cancel(order)

            # delete the attendees so that the tickets are unlocked.
            delete_related_attendees_for_order(order)

        elif (order.status == 'completed'
              or order.status == 'placed') and order.deleted_at is None:
            # Send email to attendees with invoices and tickets attached
            order_identifier = order.identifier

            key = UPLOAD_PATHS['pdf']['ticket_attendee'].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 and notifications.
            send_email_to_attendees(order=order,
                                    purchaser_id=current_user.id,
                                    attachments=[ticket_path, invoice_path])

            send_notif_to_attendees(order, current_user.id)

            if order.payment_mode in ['free', 'bank', 'cheque', 'onsite']:
                order.completed_at = datetime.utcnow()

            order_url = make_frontend_url(path='/orders/{identifier}'.format(
                identifier=order.identifier))
            for organizer in order.event.organizers:
                send_notif_ticket_purchase_organizer(organizer,
                                                     order.invoice_number,
                                                     order_url,
                                                     order.event.name,
                                                     order.identifier)
            if order.event.owner:
                send_notif_ticket_purchase_organizer(order.event.owner,
                                                     order.invoice_number,
                                                     order_url,
                                                     order.event.name,
                                                     order.identifier)
Exemple #7
0
    def after_create_object(self, order, data, view_kwargs):
        """
        after create object method for OrderListPost Class
        :param order: Object created from mashmallow_jsonapi
        :param data:
        :param view_kwargs:
        :return:
        """
        order_tickets = {}
        for holder in order.ticket_holders:
            save_to_db(holder)
            if not order_tickets.get(holder.ticket_id):
                order_tickets[holder.ticket_id] = 1
            else:
                order_tickets[holder.ticket_id] += 1

        order.user = current_user

        # create pdf tickets.
        create_pdf_tickets_for_holder(order)

        for ticket in order_tickets:
            od = OrderTicket(order_id=order.id,
                             ticket_id=ticket,
                             quantity=order_tickets[ticket])
            save_to_db(od)

        order.quantity = order.tickets_count
        save_to_db(order)
        #         if not has_access('is_coorganizer', event_id=data['event']):
        #             TicketingManager.calculate_update_amount(order)

        # send e-mail and notifications if the order status is completed
        if order.status == 'completed':
            send_email_to_attendees(order, current_user.id)
            send_notif_to_attendees(order, current_user.id)

            order_url = make_frontend_url(path='/orders/{identifier}'.format(
                identifier=order.identifier))
            for organizer in order.event.organizers:
                send_notif_ticket_purchase_organizer(organizer,
                                                     order.invoice_number,
                                                     order_url,
                                                     order.event.name,
                                                     order.identifier)

        data['user_id'] = current_user.id
    def after_create_object(self, order, data, view_kwargs):
        """
        after create object method for OrderListPost Class
        :param order:
        :param data:
        :param view_kwargs:
        :return:
        """
        order_tickets = {}
        for holder in order.ticket_holders:
            if holder.id != current_user.id:
                pdf = create_save_pdf(
                    render_template('/pdf/ticket_attendee.html',
                                    order=order,
                                    holder=holder))
            else:
                pdf = create_save_pdf(
                    render_template('/pdf/ticket_purchaser.html', order=order))
            holder.pdf_url = pdf
            save_to_db(holder)
            if order_tickets.get(holder.ticket_id) is None:
                order_tickets[holder.ticket_id] = 1
            else:
                order_tickets[holder.ticket_id] += 1
        for ticket in order_tickets:
            od = OrderTicket(order_id=order.id,
                             ticket_id=ticket,
                             quantity=order_tickets[ticket])
            save_to_db(od)
        order.quantity = order.get_tickets_count()
        save_to_db(order)
        if not has_access('is_coorganizer', event_id=data['event']):
            TicketingManager.calculate_update_amount(order)
        send_email_to_attendees(order, current_user.id)
        send_notif_to_attendees(order, current_user.id)

        order_url = make_frontend_url(path='/orders/{identifier}'.format(
            identifier=order.identifier))
        for organizer in order.event.organizers:
            send_notif_ticket_purchase_organizer(organizer,
                                                 order.invoice_number,
                                                 order_url, order.event.name)

        data['user_id'] = current_user.id
def on_order_completed(order):
    # send e-mail and notifications if the order status is completed
    if not (order.status == 'completed' or order.status == 'placed'):
        return
    # 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 and notifications.
    send_email_to_attendees(
        order=order,
        purchaser_id=current_user.id,
        attachments=[ticket_path, invoice_path],
    )

    send_notif_to_attendees(order, current_user.id)

    if order.payment_mode in ['free', 'bank', 'cheque', 'onsite']:
        order.completed_at = datetime.utcnow()

    order_url = make_frontend_url(path='/orders/{identifier}'.format(
        identifier=order.identifier))
    for organizer in set(order.event.organizers + order.event.coorganizers +
                         [order.event.owner]):
        if not organizer:
            continue
        send_notif_ticket_purchase_organizer(
            organizer,
            order.invoice_number,
            order_url,
            order.event.name,
            order.identifier,
        )
def on_order_completed(order):
    # send e-mail and notifications if the order status is completed
    if not (order.status == 'completed' or order.status == 'placed'):
        return

    create_pdf_tickets_for_holder(order)

    # send email and notifications.
    send_email_to_attendees(order)
    notify_ticket_purchase_attendee(order)

    if order.payment_mode in ['free', 'bank', 'cheque', 'onsite']:
        order.completed_at = datetime.utcnow()

    organizer_set = set(
        filter(
            bool, order.event.organizers + order.event.coorganizers +
            [order.event.owner]))
    send_order_purchase_organizer_email(order, organizer_set)
    notify_ticket_purchase_organizer(order)
    def after_create_object(self, order, data, view_kwargs):
        """
        after create object method for OrderListPost Class
        :param order: Object created from mashmallow_jsonapi
        :param data:
        :param view_kwargs:
        :return:
        """
        order_tickets = {}
        for holder in order.ticket_holders:
            save_to_db(holder)
            if not order_tickets.get(holder.ticket_id):
                order_tickets[holder.ticket_id] = 1
            else:
                order_tickets[holder.ticket_id] += 1

        order.user = current_user

        # create pdf tickets.
        create_pdf_tickets_for_holder(order)

        for ticket in order_tickets:
            od = OrderTicket(order_id=order.id, ticket_id=ticket, quantity=order_tickets[ticket])
            save_to_db(od)

        order.quantity = order.tickets_count
        save_to_db(order)
        if not has_access('is_coorganizer', event_id=data['event']):
            TicketingManager.calculate_update_amount(order)

        # send e-mail and notifications if the order status is completed
        if order.status == 'completed':
            send_email_to_attendees(order, current_user.id)
            send_notif_to_attendees(order, current_user.id)

            order_url = make_frontend_url(path='/orders/{identifier}'.format(identifier=order.identifier))
            for organizer in order.event.organizers:
                send_notif_ticket_purchase_organizer(organizer, order.invoice_number, order_url, order.event.name,
                                                     order.identifier)

        data['user_id'] = current_user.id
Exemple #12
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 successfully sent
    """
    order_identifier = request.json['data']['order']
    order = safe_query(Order, 'identifier', order_identifier, 'identifier')
    if has_access('is_coorganizer', event_id=order.event_id):
        if order.status == 'completed' or order.status == 'placed':
            send_email_to_attendees(order)
            return jsonify(
                status=True,
                message=
                "Verification emails for order : {} has been sent successfully"
                .format(order_identifier),
            )
        raise UnprocessableEntityError(
            {'source': 'data/order'},
            "Only placed and completed orders have confirmation",
        )
    raise ForbiddenError({'source': ''}, "Co-Organizer Access Required")
    def charge_stripe_order_payment(order, token_id):
        """
        Charge the user through Stripe
        :param order: Order for which to charge for
        :param token_id: Stripe token
        :return:
        """
        # save the stripe token with the order
        order.stripe_token = token_id
        save_to_db(order)

        # charge the user
        try:
            charge = StripePaymentsManager.capture_payment(order)
        except ConflictError as e:
            # payment failed hence expire the order
            order.status = 'expired'
            save_to_db(order)

            # delete related attendees to unlock the tickets
            delete_related_attendees_for_order(order)

            raise e

        # charge.paid is true if the charge succeeded, or was successfully authorized for later capture.
        if charge.paid:
            # update the order in the db.
            order.paid_via = charge.source.object
            order.brand = charge.source.brand
            order.exp_month = charge.source.exp_month
            order.exp_year = charge.source.exp_year
            order.last4 = charge.source.last4
            order.transaction_id = charge.id
            order.status = 'completed'
            order.completed_at = datetime.utcnow()
            save_to_db(order)

            # create tickets.
            create_pdf_tickets_for_holder(order)

            # send email and notifications.
            send_email_to_attendees(order, current_user.id)
            send_notif_to_attendees(order, current_user.id)

            order_url = make_frontend_url(path=f'/orders/{order.identifier}')
            for organizer in order.event.organizers:
                send_notif_ticket_purchase_organizer(organizer,
                                                     order.invoice_number,
                                                     order_url,
                                                     order.event.name,
                                                     order.id)
            if order.event.owner:
                send_notif_ticket_purchase_organizer(
                    order.event.owner,
                    order.invoice_number,
                    order_url,
                    order.event.name,
                    order.id,
                )

            return True, 'Charge successful'
        # payment failed hence expire the order
        order.status = 'expired'
        save_to_db(order)

        # delete related attendees to unlock the tickets
        delete_related_attendees_for_order(order)

        # return the failure message from stripe.
        return False, charge.failure_message
Exemple #14
0
    def after_create_object(self, order, data, view_kwargs):
        """
        after create object method for OrderListPost Class
        :param order: Object created from mashmallow_jsonapi
        :param data:
        :param view_kwargs:
        :return:
        """
        order_tickets = {}
        for holder in order.ticket_holders:
            save_to_db(holder)
            if not order_tickets.get(holder.ticket_id):
                order_tickets[holder.ticket_id] = 1
            else:
                order_tickets[holder.ticket_id] += 1

        order.user = current_user

        # create pdf tickets.
        create_pdf_tickets_for_holder(order)

        for ticket in order_tickets:
            od = OrderTicket(order_id=order.id,
                             ticket_id=ticket,
                             quantity=order_tickets[ticket])
            save_to_db(od)

        order.quantity = order.tickets_count
        save_to_db(order)
        #         if not has_access('is_coorganizer', event_id=data['event']):
        #             TicketingManager.calculate_update_amount(order)

        # send e-mail and notifications if the order status is completed
        if order.status == 'completed' or order.status == 'placed':
            # fetch tickets attachment
            order_identifier = order.identifier

            key = UPLOAD_PATHS['pdf']['ticket_attendee'].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 and notifications.
            send_email_to_attendees(order=order,
                                    purchaser_id=current_user.id,
                                    attachments=[ticket_path, invoice_path])

            send_notif_to_attendees(order, current_user.id)

            if order.payment_mode in ['free', 'bank', 'cheque', 'onsite']:
                order.completed_at = datetime.utcnow()

            order_url = make_frontend_url(path='/orders/{identifier}'.format(
                identifier=order.identifier))
            for organizer in order.event.organizers:
                send_notif_ticket_purchase_organizer(organizer,
                                                     order.invoice_number,
                                                     order_url,
                                                     order.event.name,
                                                     order.identifier)

        data['user_id'] = current_user.id
Exemple #15
0
def complete_order(order_id):
    data = request.get_json()
    for attribute in data:
        data[attribute.replace('-', '_')] = data.pop(attribute)
    order = Order.query.filter_by(id=order_id).first()
    order_schema = OrderSchema()
    if (not has_access('is_coorganizer', event_id=order.event_id)) and (
            not current_user.id == order.user_id):
        return make_response(
            jsonify(status='Access Forbidden',
                    error='You cannot update an order.'), 403)
    if has_access('is_coorganizer',
                  event_id=order.event_id) and 'status' in data:
        if data['status'] != 'cancelled':
            return make_response(
                jsonify(status='Access Forbidden',
                        error='You can only cancel an order.'),
                403,
            )
        elif data['status'] == 'cancelled':
            order.status = 'cancelled'
            db.session.add(order)
            attendees = (db.session.query(TicketHolder).filter_by(
                order_id=order_id, deleted_at=None).all())
            for attendee in attendees:
                attendee.deleted_at = datetime.now(pytz.utc)
                db.session.add(attendee)
            db.session.commit()
            send_order_cancel_email(order)
            send_notif_ticket_cancel(order)
            return order_schema.dump(order)
    updated_attendees = data['attendees']
    for updated_attendee in updated_attendees:
        for attribute in updated_attendee:
            updated_attendee[attribute.replace(
                '-', '_')] = updated_attendee.pop(attribute)
    if get_count(db.session.query(TicketHolder).filter_by(
            order_id=order_id)) != len(updated_attendees):
        return make_response(
            jsonify(
                status='Unprocessable Entity',
                error='You need to provide info of all attendees.',
            ),
            422,
        )
    else:
        attendees = (db.session.query(TicketHolder).filter_by(
            order_id=order_id, deleted_at=None).all())
    form_fields = (db.session.query(CustomForms).filter_by(
        event_id=order.event_id, form='attendee', is_included=True).all())
    for attendee, updated_attendee in zip(attendees, updated_attendees):
        for field in form_fields:
            if (field.is_required is True
                    and field.field_identifier not in updated_attendee):
                return make_response(
                    jsonify(
                        status='Unprocessable Entity',
                        error='{} is a required field.'.format(
                            field.field_identifier),
                    ),
                    422,
                )
            if field.field_identifier in updated_attendee:
                setattr(
                    attendee,
                    field.field_identifier,
                    updated_attendee[field.field_identifier],
                )
        db.session.add(attendee)
    # modified_at not getting filled
    if order.amount == 0:
        order.status = 'completed'
        order.completed_at = datetime.utcnow()
    elif order.amount > 0:
        if 'payment_mode' not in data:
            return make_response(
                jsonify(status='Unprocessable Entity',
                        error='Payment mode not specified.'),
                422,
            )
        if data['payment_mode'] in ['bank', 'cheque', 'onsite']:
            order.status = 'placed'
            order.completed_at = datetime.utcnow()
        else:
            order.status = 'pending'
        if 'is_billing_enabled' in data:
            if data['is_billing_enabled']:
                if (('company' not in data) or ('address' not in data)
                        or ('city' not in data) or ('zipcode' not in data)
                        or ('country' not in data)):
                    return make_response(
                        jsonify(
                            status='Unprocessable Entity',
                            error='Billing information incomplete.',
                        ),
                        422,
                    )
            else:
                return make_response(
                    jsonify(
                        status='Unprocessable Entity',
                        error='Billing information incomplete.',
                    ),
                    422,
                )
        else:
            return make_response(
                jsonify(
                    status='Unprocessable Entity',
                    error='Billing information is mandatory '
                    'for this order.',
                ),
                422,
            )
        order.company = data['company']
        order.address = data['address']
        order.city = data['city']
        order.zipcode = data['zipcode']
        order.country = data['country']
        order.payment_mode = data['payment_mode']
        if 'state' in data:
            order.state = data['state']
        if 'tax_business_info' in data:
            order.tax_business_info = data['tax_business_info']
    db.session.add(order)
    db.session.commit()
    create_pdf_tickets_for_holder(order)
    if (order.status == 'completed'
            or order.status == 'placed') and (order.deleted_at is None):
        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 and notifications.
        send_email_to_attendees(
            order=order,
            purchaser_id=current_user.id,
            attachments=[ticket_path, invoice_path],
        )

        send_notif_to_attendees(order, current_user.id)
        order_url = make_frontend_url(path='/orders/{identifier}'.format(
            identifier=order.identifier))
        for organizer in order.event.organizers:
            send_notif_ticket_purchase_organizer(
                organizer,
                order.invoice_number,
                order_url,
                order.event.name,
                order.identifier,
            )
        if order.event.owner:
            send_notif_ticket_purchase_organizer(
                order.event.owner,
                order.invoice_number,
                order_url,
                order.event.name,
                order.identifier,
            )

    return order_schema.dump(order)