Merge branch 'master' of https://bitbucket.org/yackob03/quay
This commit is contained in:
commit
a3f40f2a90
5 changed files with 58 additions and 12 deletions
|
@ -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)
|
||||
|
|
|
@ -17,3 +17,4 @@ apscheduler
|
|||
python-daemon
|
||||
paramiko
|
||||
python-digitalocean
|
||||
xhtml2pdf
|
|
@ -5,29 +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==0.0.5
|
||||
|
|
|
@ -49,12 +49,13 @@
|
|||
<th>Billing Date/Time</th>
|
||||
<th>Amount Due</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
|
||||
<tbody class="invoice" ng-repeat="invoice in invoices">
|
||||
<tr class="invoice-title" ng-click="toggleInvoice(invoice.id)">
|
||||
<td><span class="invoice-datetime">{{ invoice.date * 1000 | date:'medium' }}</span></td>
|
||||
<td><span class="invoice-amount">{{ invoice.amount_due / 100 }}</span></td>
|
||||
<tr class="invoice-title">
|
||||
<td ng-click="toggleInvoice(invoice.id)"><span class="invoice-datetime">{{ invoice.date * 1000 | date:'medium' }}</span></td>
|
||||
<td ng-click="toggleInvoice(invoice.id)"><span class="invoice-amount">{{ invoice.amount_due / 100 }}</span></td>
|
||||
<td>
|
||||
<span class="invoice-status">
|
||||
<span class="success" ng-show="invoice.paid">Paid - Thank you!</span>
|
||||
|
@ -63,6 +64,11 @@
|
|||
<span class="pending" ng-show="!invoice.paid && !invoice.attempted">Payment pending</span>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<a ng-show="invoice.paid" href="/receipt?id={{ invoice.id }}" download="receipt.pdf" target="_new">
|
||||
<i class="fa fa-download" title="Download Receipt" bs-tooltip="tooltip.title"></i>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr ng-class="invoiceExpanded[invoice.id] ? 'in' : 'out'" class="invoice-details panel-collapse collapse">
|
||||
|
|
|
@ -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):
|
||||
|
|
Reference in a new issue