Implementation of Organizer Invoicing in Open Event

This blog post emphasizes on the workflow of event invoicing for organizers in Open Event. The Open Event Project, popularly known as Eventyay is an event management solution which provides a robust platform to manage events, schedules multi-track sessions and supports many other features.

Organizer invoicing in layman terms is the fee paid by an organizer for hosting an event on the platform. This is calculated every month and respective emails/notifications are sent to the user. An event invoice in the form a PDF is generated monthly based on the sales generated. The organizer can pay the invoice via a credit/debit card through PayPal.

This feature was divided into a set of sub-features namely:

  1. Integration of ember tables for event invoices
  2. Implementing the review route & corresponding logic
  3. Creating a compatible paypal component to work with invoice workflow
  4. Creation of a payment completion page on successful invoice payments

Navigating to Account > Billing Info > Invoices, we are presented with a table of all the invoices which are due, paid & upcoming. You can review your due invoices and pay them. Adding to that, you can also view any past invoices which were paid or the upcoming ones which would have a draft status with the information about the current sales. 

                                                         Event Invoice Overview – Organizers

For an invoice which is due, an organizer will be able to navigate to the review route by clicking on the Review Payment Action. In this route, details pertaining to Admin billing details, User billing details, total number of tickets sold and total invoice amount will be depicted. The Organizer can have a look at the total invoice amount here.

                                              Review Route – Invoice Payment

The Invoice details and Billing Info components were built using ui segments. 

After reviewing the information, the organizer can click on pay via PayPal to initiate the transaction process via PayPal. The challenge here was the lack of proper API routing(sandbox/live) present in the system. To overcome this, the env variable in the PayPal component was given the value of the current environment enabled.

def send_monthly_event_invoice():
    from app import current_app as app
    with app.app_context():
        events = Event.query.filter_by(deleted_at=None, state='published').all()
        for event in events:
            # calculate net & gross revenues
            user = event.owner
            admin_info = get_settings()
            currency = event.payment_currency
            ticket_fee_object = db.session.query(TicketFees).filter_by(currency=currency).one()
            ticket_fee_percentage = ticket_fee_object.service_fee
            ticket_fee_maximum = ticket_fee_object.maximum_fee
            orders = Order.query.filter_by(event=event).all()
            gross_revenue = event.calc_monthly_revenue()
            ticket_fees = event.tickets_sold * (ticket_fee_percentage / 100)
            if ticket_fees > ticket_fee_maximum:
                ticket_fees = ticket_fee_maximum
            net_revenue = gross_revenue - ticket_fees
            payment_details = {
                'tickets_sold': event.tickets_sold,
                'gross_revenue': gross_revenue,
                'net_revenue': net_revenue,
                'amount_payable': ticket_fees
            }
            # save invoice as pdf
            pdf = create_save_pdf(render_template('pdf/event_invoice.html', orders=orders, user=user,
                                  admin_info=admin_info, currency=currency, event=event,
                                  ticket_fee_object=ticket_fee_object, payment_details=payment_details,
                                  net_revenue=net_revenue), UPLOAD_PATHS['pdf']['event_invoice'],
                                  dir_path='/static/uploads/pdf/event_invoices/', identifier=event.identifier)
            # save event_invoice info to DB

            event_invoice = EventInvoice(amount=net_revenue, invoice_pdf_url=pdf, event_id=event.id)
            save_to_db(event_invoice)

                                Invoice generation and calculation logic as a cron job

The event invoice PDFs along with the amount calculation was done on the server side by taking the product of the number of tickets multiplied by eventyay fees. The invoice generation, amount calculation and the task of marking invoices as due were implemented as cron jobs which are scheduled every month from the time the event was created.

def event_invoices_mark_due():
    from app import current_app as app
    with app.app_context():
        db.session.query(EventInvoice).\
                    filter(EventInvoice.status == 'upcoming',
                           EventInvoice.event.ends_at >= datetime.datetime.now(),
                           (EventInvoice.created_at + datetime.timedelta(days=30) <=
                            datetime.datetime.now())).\
                    update({'status': 'due'})

        db.session.commit()

                                            Cron job to mark invoices as due

As soon as the payment succeeds, the organizer is routed to the paid route where the information alluding to the PayPal ID, Amount can be found. The organizer can also download their invoice using the route action similar to tickets and order invoices generation on Eventyay.

                                           Organizer View – Paid Invoice Route

Resources:

Related work and code repo:

Tags:

Eventyay, FOSSASIA, Flask, Ember.js, Open Event, API

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.