diff --git a/app/api/events.py b/app/api/events.py index 4409761721..4878c209a1 100644 --- a/app/api/events.py +++ b/app/api/events.py @@ -7,7 +7,7 @@ from flask_rest_jsonapi.exceptions import ObjectNotFound from marshmallow_jsonapi import fields from marshmallow_jsonapi.flask import Schema -from sqlalchemy import or_, and_ +from sqlalchemy import and_, or_ from sqlalchemy.orm.exc import NoResultFound from app.api.bootstrap import api diff --git a/app/api/helpers/scheduled_jobs.py b/app/api/helpers/scheduled_jobs.py index 7bf121de91..0490fb8455 100644 --- a/app/api/helpers/scheduled_jobs.py +++ b/app/api/helpers/scheduled_jobs.py @@ -267,54 +267,8 @@ def send_monthly_event_invoice(): 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 - try: - ticket_fee_object = ( - db.session.query(TicketFees).filter_by(currency=currency).one() - ) - except NoResultFound: - logger.error('Ticket Fee not found for event id {id}'.format(id=event.id)) - continue - - 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() - invoice_amount = gross_revenue * (ticket_fee_percentage / 100) - if invoice_amount > ticket_fee_maximum: - invoice_amount = ticket_fee_maximum - net_revenue = gross_revenue - invoice_amount - payment_details = { - 'tickets_sold': event.tickets_sold, - 'gross_revenue': gross_revenue, - 'net_revenue': net_revenue, - 'amount_payable': invoice_amount, - } - # 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=invoice_amount, invoice_pdf_url=pdf, event_id=event.id - ) + event_invoice = EventInvoice(event=event) + event_invoice.populate() save_to_db(event_invoice) diff --git a/app/models/event_invoice.py b/app/models/event_invoice.py index 5536b408ef..25caecd5fc 100644 --- a/app/models/event_invoice.py +++ b/app/models/event_invoice.py @@ -1,10 +1,22 @@ +import logging import time +from flask.templating import render_template from sqlalchemy.sql import func from app.api.helpers.db import get_new_identifier +from app.api.helpers.files import create_save_pdf +from app.api.helpers.storage import UPLOAD_PATHS from app.models import db from app.models.base import SoftDeletionModel +from app.models.order import Order +from app.models.ticket_fee import TicketFees +from app.settings import get_settings +from app.api.helpers.utilities import monthdelta +from app.api.helpers.mail import send_email_for_monthly_fee_payment +from app.api.helpers.notification import send_notif_monthly_fee_payment + +logger = logging.getLogger(__name__) def get_new_id(): @@ -26,6 +38,8 @@ class EventInvoice(SoftDeletionModel): event_id = db.Column(db.Integer, db.ForeignKey('events.id', ondelete='SET NULL')) created_at = db.Column(db.DateTime(timezone=True), default=func.now()) + + # Payment Fields completed_at = db.Column(db.DateTime(timezone=True), nullable=True, default=None) transaction_id = db.Column(db.String) paid_via = db.Column(db.String) @@ -37,6 +51,7 @@ class EventInvoice(SoftDeletionModel): stripe_token = db.Column(db.String) paypal_token = db.Column(db.String) status = db.Column(db.String, default='due') + invoice_pdf_url = db.Column(db.String) event = db.relationship('Event', backref='invoices') @@ -49,3 +64,75 @@ def get_invoice_number(self): def __repr__(self): return '' % self.invoice_pdf_url + + def populate(self): + assert self.event is not None + + self.user = self.event.owner + self.generate_pdf() + + def generate_pdf(self): + admin_info = get_settings() + currency = self.event.payment_currency + ticket_fee_object = db.session.query(TicketFees).filter_by(currency=currency).first() + if not ticket_fee_object: + logger.error('Ticket Fee not found for event id {id}'.format(id=event.id)) + return + + ticket_fee_percentage = ticket_fee_object.service_fee + ticket_fee_maximum = ticket_fee_object.maximum_fee + gross_revenue = self.event.calc_monthly_revenue() + invoice_amount = gross_revenue * (ticket_fee_percentage / 100) + if invoice_amount > ticket_fee_maximum: + invoice_amount = ticket_fee_maximum + self.amount = invoice_amount + net_revenue = gross_revenue - invoice_amount + payment_details = { + 'tickets_sold': self.event.tickets_sold, + 'gross_revenue': gross_revenue, + 'net_revenue': net_revenue, + 'amount_payable': invoice_amount, + } + # save invoice as pdf + self.invoice_pdf_url = create_save_pdf( + render_template( + 'pdf/event_invoice.html', + user=self.user, + admin_info=admin_info, + currency=currency, + event=self.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=self.event.identifier, + ) + + return self.invoice_pdf_url + + def send_notification(self): + prev_month = monthdelta(self.created_at, 1).strftime( + "%b %Y" + ) # Displayed as Aug 2016 + app_name = get_settings()['app_name'] + frontend_url = get_settings()['frontend_url'] + link = '{}/invoices/{}'.format(frontend_url, self.identifier) + send_email_for_monthly_fee_payment( + self.user.email, + event.name, + prev_month, + self.amount, + app_name, + link, + ) + send_notif_monthly_fee_payment( + self.user, + event.name, + prev_month, + self.amount, + app_name, + link, + self.event_id, + )