diff --git a/rowers/braintreestuff.py b/rowers/braintreestuff.py
index 01fda581..7477ddbe 100644
--- a/rowers/braintreestuff.py
+++ b/rowers/braintreestuff.py
@@ -15,6 +15,7 @@ from rowers.tasks import (
handle_send_email_failed_cancel,
)
+import pandas as pd
from rowsandall_app.settings import (
BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY
@@ -314,5 +315,76 @@ def find_subscriptions(rower):
result.append(thedict)
return result
-
+
+def get_transactions(start_date,end_date):
+ results = gateway.transaction.search(
+ braintree.TransactionSearch.created_at.between(
+ start_date,
+ end_date,
+ )
+ )
+
+ amounts = []
+ countries = []
+ card_countries = []
+ names = []
+ emails = []
+ dates = []
+ currencies = []
+ statuses = []
+ ids = []
+ usernames = []
+
+ for transaction in results:
+ try:
+ r = Rower.objects.filter(
+ customer_id=transaction.customer['id'],
+ paymentprocessor='braintree')[0]
+ countries.append(r.country)
+ names.append('{f} {l}'.format(
+ f = r.user.first_name,
+ l = r.user.last_name,
+ )
+ )
+ emails.append(r.user.email)
+ ids.append(r.id)
+ usernames.append(r.user.username)
+
+ except KeyError:
+ countries.append(
+ transaction.credit_card_details.country_of_issuance)
+ names.append('{f} {l}'.format(
+ f = transaction.customer['first_name'],
+ l = transaction.customer['last_name']
+ )
+ )
+ emails.append(transaction.customer.email)
+ ids.append(transaction.customer['id'])
+ usernames.append('unknown')
+
+
+ amounts.append(transaction.amount)
+ dates.append(transaction.created_at)
+ currencies.append(transaction.currency_iso_code)
+ card_countries.append(
+ transaction.credit_card_details.country_of_issuance)
+ statuses.append(transaction.status)
+
+
+ df = pd.DataFrame({
+ 'name':names,
+ 'email':emails,
+ 'date':dates,
+ 'amount':amounts,
+ 'currency':currencies,
+ 'country':countries,
+ 'card_country':card_countries,
+ 'status':statuses,
+ 'username':usernames,
+ 'user_id':ids,
+ }
+ )
+
+ return df
+
diff --git a/rowers/payments.py b/rowers/payments.py
index 488191c1..7e71aad5 100644
--- a/rowers/payments.py
+++ b/rowers/payments.py
@@ -10,22 +10,27 @@ def planstopaypal():
plan.external_id = None
plan.save()
+def initiaterowerplans():
+ rowers = Rower.objects.filter(paymenttype = 'recurring',paidplan = None)
+ for r in rowers:
+ r.paymentprocessor = 'paypal'
+ r.save()
+
def setrowerplans():
rowers = Rower.objects.all()
for r in rowers:
- if r.rowerplan != 'basic':
- paidplans = PaidPlan.objects.filter(
- shortname = r.rowerplan,
- paymenttype = r.paymenttype,
- clubsize = r.clubsize)
+ paidplans = PaidPlan.objects.filter(
+ shortname = r.rowerplan,
+ paymenttype = r.paymenttype,
+ clubsize = r.clubsize,
+ paymentprocessor=r.paymentprocessor)
- if paidplans:
- r.paidplan = paidplans[0]
- r.paymentprocessor = 'paypal'
- r.save()
- else:
- print 'Could not set plan for ',r
+ if paidplans:
+ r.paidplan = paidplans[0]
+ r.save()
+ else:
+ print 'Could not set plan for ',r
def is_existing_customer(rower):
if rower.country is not None and rower.customer_id is not None and rower.country != '':
diff --git a/rowers/templates/menu_profile.html b/rowers/templates/menu_profile.html
index d3dd90b0..90bd73b9 100644
--- a/rowers/templates/menu_profile.html
+++ b/rowers/templates/menu_profile.html
@@ -27,8 +27,16 @@
Manage Workflow
+ {% if user.is_authenticated and user.is_staff %}
+
+
+ Transactions
+
+
+ {% endif %}
+
{% if user.is_authenticated and user|is_manager %}
{% if user|team_members %}
diff --git a/rowers/templates/transactions.html b/rowers/templates/transactions.html
new file mode 100644
index 00000000..08cd6a0a
--- /dev/null
+++ b/rowers/templates/transactions.html
@@ -0,0 +1,24 @@
+{% extends "newbase.html" %}
+{% load staticfiles %}
+{% load rowerfilters %}
+
+{% block main %}
+Download Transactions
+
+
+
+{% endblock %}
+
+{% block sideheader %}
+Profile
+{% endblock %}
+
+{% block sidebar %}
+{% include 'menu_profile.html' %}
+{% endblock %}
diff --git a/rowers/urls.py b/rowers/urls.py
index 474946e3..f37951da 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -404,6 +404,7 @@ urlpatterns = [
url(r'^me/edit/$',views.rower_edit_view),
url(r'^me/edit/user/(?P\d+)$',views.rower_edit_view),
url(r'^me/preferences/$',views.rower_prefs_view),
+ url(r'^me/transactions/$',views.transactions_view),
url(r'^me/preferences/user/(?P\d+)$',views.rower_prefs_view),
url(r'^me/edit/(.+.*)/$',views.rower_edit_view),
url(r'^me/c2authorize/$',views.rower_c2_authorize),
diff --git a/rowers/views.py b/rowers/views.py
index d44d47de..1b46512f 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -141,7 +141,8 @@ from rowsandall_app.settings import (
UNDERARMOUR_CLIENT_SECRET,UNDERARMOUR_CLIENT_KEY,
RUNKEEPER_CLIENT_ID,RUNKEEPER_REDIRECT_URI,RUNKEEPER_CLIENT_SECRET,
TP_CLIENT_ID,TP_REDIRECT_URI,TP_CLIENT_KEY,TP_CLIENT_SECRET,
- BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY
+ BRAINTREE_MERCHANT_ID,BRAINTREE_PUBLIC_KEY,BRAINTREE_PRIVATE_KEY,
+ PAYMENT_PROCESSING_ON
)
from rowers.tasks_standalone import addcomment2
@@ -1073,6 +1074,10 @@ def paidplans_view(request):
@login_required()
def billing_view(request):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
if payments.is_existing_customer(r):
@@ -1116,6 +1121,10 @@ def billing_view(request):
@login_required()
def upgrade_view(request):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
if r.subscription_id is None or r.subscription_id == '':
@@ -1154,6 +1163,10 @@ def upgrade_view(request):
@login_required()
def downgrade_view(request):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
if r.subscription_id is None or r.subscription_id == '':
@@ -1202,6 +1215,10 @@ def downgrade_view(request):
@login_required()
def plan_stop_view(request):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
subscriptions = []
@@ -1223,6 +1240,10 @@ def plan_stop_view(request):
@login_required()
def plan_tobasic_view(request,id=0):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
if r.paidplan.paymentprocessor == 'braintree':
@@ -1241,6 +1262,10 @@ def plan_tobasic_view(request,id=0):
@login_required()
def upgrade_confirm_view(request,planid = 0):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
try:
plan = PaidPlan.objects.get(id=planid)
except PaidPlan.DoesNotExist:
@@ -1262,6 +1287,10 @@ def upgrade_confirm_view(request,planid = 0):
@login_required()
def downgrade_confirm_view(request,planid = 0):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
try:
plan = PaidPlan.objects.get(id=planid)
except PaidPlan.DoesNotExist:
@@ -1284,6 +1313,10 @@ def downgrade_confirm_view(request,planid = 0):
@login_required()
def payment_confirm_view(request,planid = 0):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
try:
plan = PaidPlan.objects.get(id=planid)
except PaidPlan.DoesNotExist:
@@ -1306,6 +1339,10 @@ def payment_confirm_view(request,planid = 0):
@login_required()
def checkouts_view(request):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
@@ -1336,6 +1373,10 @@ def checkouts_view(request):
@login_required()
def upgrade_checkouts_view(request):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
@@ -1366,6 +1407,10 @@ def upgrade_checkouts_view(request):
@login_required()
def downgrade_checkouts_view(request):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
@@ -1397,6 +1442,10 @@ def downgrade_checkouts_view(request):
@login_required()
def payment_completed_view(request):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
return render(request,
@@ -1407,6 +1456,10 @@ def payment_completed_view(request):
@login_required()
def downgrade_completed_view(request):
+ if not PAYMENT_PROCESSING_ON:
+ url = reverse('promembership')
+ return HttpResponseRedirect(url)
+
r = getrequestrower(request)
return render(request,
@@ -1864,6 +1917,33 @@ def plannedsessions_icsemail_view(request,userid=0):
return response
+@login_required()
+def transactions_view(request):
+ if not request.user.is_staff:
+ raise PermissionDenied("Not Allowed")
+
+ if request.method == 'POST':
+ dateform = DateRangeForm(request.POST)
+ if dateform.is_valid():
+ startdate = dateform.cleaned_data['startdate']
+ enddate = dateform.cleaned_data['enddate']
+
+ df = braintreestuff.get_transactions(startdate,enddate)
+ filename="transactions_{s}_{e}.csv".format(s = startdate, e = enddate)
+ response = HttpResponse(df.to_csv())
+ response['Content-Disposition'] = 'attachment; filename="%s"' % filename
+ response['Content-Type'] = 'application/octet-stream'
+
+ return response
+
+ else:
+ dateform = DateRangeForm()
+
+ return render(request,
+ 'transactions.html',
+ {
+ 'dateform':dateform
+ })
@login_required()
def course_kmlemail_view(request,id=0):
diff --git a/rowsandall_app/settings.py b/rowsandall_app/settings.py
index 7aedf773..b96c3f66 100644
--- a/rowsandall_app/settings.py
+++ b/rowsandall_app/settings.py
@@ -439,3 +439,8 @@ try:
BRAINTREE_PRIVATE_KEY = CFG['braintree_private_key']
except KeyError:
BRAINTREE_PRIVATE_KEY = ''
+
+try:
+ PAYMENT_PROCESSING_ON = CFG['payment_processing_on']
+except KeyError:
+ PAYMENT_PROCESSING_ON = False