From 4c6012f756b6ebeb440419a16eb5a46ba57c161c Mon Sep 17 00:00:00 2001 From: Joseph Schorr Date: Mon, 18 Nov 2013 14:49:54 -0500 Subject: [PATCH 1/2] Add ability to download receipts in PDF form --- endpoints/web.py | 24 +++++++++++++++++++++--- requirements.txt | 1 + static/partials/org-admin.html | 12 +++++++++--- util/invoice.py | 16 ++++++++++++++++ 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/endpoints/web.py b/endpoints/web.py index 9f8712629..ff6f1790a 100644 --- a/endpoints/web.py +++ b/endpoints/web.py @@ -1,15 +1,16 @@ import logging import requests +import stripe from flask import (abort, redirect, request, url_for, render_template, - make_response) + make_response, Response) from flask.ext.login import login_user, UserMixin, login_required from flask.ext.principal import identity_changed, Identity, AnonymousIdentity from data import model from app import app, login_manager, mixpanel -from auth.permissions import QuayDeferredPermissionUser - +from auth.permissions import QuayDeferredPermissionUser, AdministerOrganizationPermission +from util.invoice import renderInvoiceToPdf logger = logging.getLogger(__name__) @@ -102,6 +103,23 @@ def privacy(): return render_template('privacy.html') +@app.route('/receipt', methods=['GET']) +def receipt(): + id = request.args.get('id') + if id: + invoice = stripe.Invoice.retrieve(id) + if invoice: + org = model.get_user_or_org_by_customer_id(invoice.customer) + if org and org.organization: + admin_org = AdministerOrganizationPermission(org.username) + if admin_org.can(): + file_data = renderInvoiceToPdf(invoice, org) + return Response(file_data, + mimetype="application/pdf", + headers={"Content-Disposition": + "attachment;filename=receipt.pdf"}) + abort(404) + def common_login(db_user): if login_user(_LoginWrappedDBUser(db_user.username, db_user)): logger.debug('Successfully signed in as: %s' % db_user.username) diff --git a/requirements.txt b/requirements.txt index 494ed9198..dc2c2a6ec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -31,3 +31,4 @@ requests==2.0.0 six==1.4.1 stripe==1.9.8 wsgiref==0.1.2 +xhtml2pdf \ No newline at end of file diff --git a/static/partials/org-admin.html b/static/partials/org-admin.html index 46e3af4ea..d31d10279 100644 --- a/static/partials/org-admin.html +++ b/static/partials/org-admin.html @@ -49,12 +49,13 @@ Billing Date/Time Amount Due Status + - - {{ invoice.date * 1000 | date:'medium' }} - {{ invoice.amount_due / 100 }} + + {{ invoice.date * 1000 | date:'medium' }} + {{ invoice.amount_due / 100 }} Paid - Thank you! @@ -63,6 +64,11 @@ Payment pending + + + + + diff --git a/util/invoice.py b/util/invoice.py index 773c428f1..86dd2eea4 100644 --- a/util/invoice.py +++ b/util/invoice.py @@ -1,5 +1,7 @@ from datetime import datetime from jinja2 import Environment, FileSystemLoader +from xhtml2pdf import pisa +import StringIO jinja_options = { "loader": FileSystemLoader('util'), @@ -7,6 +9,20 @@ jinja_options = { env = Environment(**jinja_options) + +def renderInvoiceToPdf(invoice, user): + """ Renders a nice PDF display for the given invoice. """ + sourceHtml = renderInvoiceToHtml(invoice, user) + output = StringIO.StringIO() + pisaStatus = pisa.CreatePDF(sourceHtml, dest=output) + if pisaStatus.err: + return None + + value = output.getvalue() + output.close() + return value + + def renderInvoiceToHtml(invoice, user): """ Renders a nice HTML display for the given invoice. """ def get_price(price): From bde0a29296262a49409e30383e451d012d1bb7da Mon Sep 17 00:00:00 2001 From: yackob03 Date: Mon, 18 Nov 2013 15:00:08 -0500 Subject: [PATCH 2/2] Switcht the requirements and -nover files to the standard formatting. --- requirements-nover.txt | 3 ++- requirements.txt | 16 ++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/requirements-nover.txt b/requirements-nover.txt index 8d95e3e48..dc0d069a0 100644 --- a/requirements-nover.txt +++ b/requirements-nover.txt @@ -16,4 +16,5 @@ marisa-trie apscheduler python-daemon paramiko -python-digitalocean \ No newline at end of file +python-digitalocean +xhtml2pdf \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index dc2c2a6ec..48a6fffa3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,30 +5,34 @@ Flask-Mail==0.9.0 Flask-Principal==0.4.0 Jinja2==2.7.1 MarkupSafe==0.18 +Pillow==2.2.1 PyMySQL==0.6.1 Werkzeug==0.9.4 argparse==1.2.1 beautifulsoup4==4.3.2 blinker==1.3 -boto==2.15.0 +boto==2.17.0 distribute==0.6.34 ecdsa==0.10 eventlet==0.14.0 greenlet==0.4.1 gunicorn==18.0 +html5lib==1.0b3 itsdangerous==0.23 lockfile==0.9.1 marisa-trie==0.5.1 mixpanel-py==3.0.0 paramiko==1.12.0 -peewee==2.1.4 +peewee==2.1.5 py-bcrypt==0.4 +pyPdf==1.13 pycrypto==2.6.1 python-daemon==1.6 -python-dateutil==2.1 -python-digitalocean==0.5 -requests==2.0.0 +python-dateutil==2.2 +python-digitalocean==0.5.1 +reportlab==2.7 +requests==2.0.1 six==1.4.1 stripe==1.9.8 wsgiref==0.1.2 -xhtml2pdf \ No newline at end of file +xhtml2pdf==0.0.5