fossasia/open-event-orga-server

View on GitHub
app/api/custom/invoices.py

Summary

Maintainability
A
1 hr
Test Coverage
import os

from flask import Blueprint
from flask.helpers import send_from_directory
from flask_jwt_extended import current_user, jwt_required
from flask_rest_jsonapi.exceptions import ObjectNotFound
from sqlalchemy.orm.exc import NoResultFound

from app.api.auth import return_file
from app.api.custom.orders import order_blueprint
from app.api.helpers.errors import ForbiddenError, NotFoundError
from app.api.helpers.order import create_pdf_tickets_for_holder
from app.api.helpers.permission_manager import has_access
from app.api.helpers.storage import UPLOAD_PATHS, generate_hash
from app.models.event_invoice import EventInvoice
from app.models.order import Order

event_blueprint = Blueprint('event_blueprint', __name__, url_prefix='/v1/events')


@event_blueprint.route('/invoices/<string:invoice_identifier>')
@jwt_required
def event_invoices(invoice_identifier):
    if not current_user:
        raise ForbiddenError({'source': ''}, 'Authentication Required to access Invoice')
    try:
        event_invoice = EventInvoice.query.filter_by(
            identifier=invoice_identifier
        ).first()
        event_id = event_invoice.event_id
    except NoResultFound:
        raise NotFoundError({'source': ''}, 'Event Invoice not found')
    if not current_user.is_organizer(event_id) and not current_user.is_staff:
        raise ForbiddenError({'source': ''}, 'Unauthorized Access')
    key = UPLOAD_PATHS['pdf']['event_invoices'].format(identifier=invoice_identifier)
    file_path = (
        f'../generated/invoices/{key}/{generate_hash(key)}/{invoice_identifier}.pdf'
    )
    try:
        return return_file('event-invoice', file_path, invoice_identifier)
    except FileNotFoundError:
        raise ObjectNotFound(
            {'source': ''},
            "The Event Invoice isn't available at the moment. \
                             Invoices are usually issued on the 1st of every month",
        )


@order_blueprint.route('/invoices/<string:order_identifier>')
@jwt_required
def order_invoices(order_identifier):
    if current_user:
        try:
            order = Order.query.filter_by(identifier=order_identifier).first()
        except NoResultFound:
            raise NotFoundError({'source': ''}, 'Order Invoice not found')
        if has_access(
            'is_coorganizer_or_user_itself',
            event_id=order.event_id,
            user_id=order.user_id,
        ) or order.is_attendee(current_user):
            file_path = order.invoice_pdf_path
            if not os.path.isfile(file_path):
                create_pdf_tickets_for_holder(order)
            return send_from_directory('../', file_path, as_attachment=True)
        else:
            raise ForbiddenError({'source': ''}, 'Unauthorized Access')
    else:
        raise ForbiddenError({'source': ''}, 'Authentication Required to access Invoice')