Private
Public Access
1
0

Merge branch 'feature/braintree' into develop

This commit is contained in:
Sander Roosendaal
2018-12-21 10:46:01 +01:00
36 changed files with 2789 additions and 43 deletions

View File

@@ -28,6 +28,8 @@ import isodate
import re
import cgi
from icalendar import Calendar, Event
import rowers.braintreestuff as braintreestuff
import rowers.payments as payments
from django.shortcuts import render
from django.template.loader import render_to_string
@@ -50,7 +52,7 @@ from rowers.forms import (
RaceResultFilterForm,PowerIntervalUpdateForm,FlexAxesForm,
FlexOptionsForm,DataFrameColumnsForm,OteWorkoutTypeForm,
MetricsForm,DisqualificationForm,disqualificationreasons,
disqualifiers,SearchForm,
disqualifiers,SearchForm,BillingForm,PlanSelectForm
)
from django.core.urlresolvers import reverse, reverse_lazy
@@ -83,7 +85,7 @@ from rowers.models import (
createmicrofillers, createmesofillers,
microcyclecheckdates,mesocyclecheckdates,macrocyclecheckdates,
TrainingMesoCycleForm, TrainingMicroCycleForm,
RaceLogo,
RaceLogo,RowerBillingAddressForm,PaidPlan,
)
from rowers.models import (
RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm,
@@ -139,6 +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,
PAYMENT_PROCESSING_ON
)
from rowers.tasks_standalone import addcomment2
@@ -736,8 +740,27 @@ def deactivate_user(request):
if request.method == "POST":
user_form = DeactivateUserForm(request.POST, instance=user)
if user_form.is_valid():
r = Rower.objects.get(user=user)
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
try:
subscriptions = braintreestuff.find_subscriptions(r)
for subscription in subscriptions:
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
for message in themessages:
messages.info(request,message)
except ProcessorCustomerError:
pass
r.paidplan = None
r.teamplanexpires = timezone.now()
r.planexpires = timezone.now()
r.clubsize = 0
r.rowerplan = 'basic'
r.save()
deactivate_user = user_form.save(commit=False)
user.is_active = False
user.save()
deactivate_user.save()
# url = reverse(auth_views.logout_then_login)
url = '/logout/?next=/login'
@@ -788,7 +811,17 @@ def remove_user(request):
name = user.first_name+' '+user.last_name
email = user.email
r = Rower.objects.get(user=user)
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
try:
subscriptions = braintreestuff.find_subscriptions(r)
for subscription in subscriptions:
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
for message in themessages:
messages.info(request,message)
except ProcessorCustomerError:
pass
if cd['delete_user']:
user.delete()
res = myqueue(queuehigh,
@@ -996,7 +1029,7 @@ def hasplannedsessions(user):
return result
from rowers.utils import isprorower
from rowers.utils import isprorower,ProcessorCustomerError
# Check if a user is a Pro member
def ispromember(user):
@@ -1027,6 +1060,413 @@ def add_defaultfavorites(r):
f.save()
return 1
def paidplans_view(request):
if not request.user.is_anonymous():
r = getrequestrower(request)
else:
r = None
return render(request,
'paidplans.html',
{'rower':r})
@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):
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
if request.method == 'POST':
billingaddressform = RowerBillingAddressForm(request.POST)
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
if billingaddressform.is_valid():
cd = billingaddressform.cleaned_data
for attr, value in cd.items():
setattr(r, attr, value)
r.save()
if planselectform.is_valid():
plan = planselectform.cleaned_data['plan']
if billingaddressform.is_valid():
try:
customer_id = braintreestuff.create_customer(r)
except ProcessorCustomerError:
messages.error(request,"Something went wrong registering you as a customer.")
url = reverse(billing_view)
return HttpResponseRedirect(url)
url = reverse(payment_confirm_view,
kwargs={
'planid':plan.id
})
return HttpResponseRedirect(url)
else:
billingaddressform = RowerBillingAddressForm(instance=r)
planselectform = PlanSelectForm(paymentprocessor='braintree')
return render(request,
'billing.html',
{'rower':r,
'billingaddressform':billingaddressform,
'planselectform':planselectform,
})
@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 == '':
url = reverse(billing_view)
return HttpResponseRedirect(url)
if request.method == 'POST':
billingaddressform = RowerBillingAddressForm(request.POST)
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
if billingaddressform.is_valid():
cd = billingaddressform.cleaned_data
for attr, value in cd.items():
setattr(r, attr, value)
r.save()
if planselectform.is_valid():
plan = planselectform.cleaned_data['plan']
if billingaddressform.is_valid():
url = reverse(upgrade_confirm_view,
kwargs={
'planid':plan.id
})
return HttpResponseRedirect(url)
else:
billingaddressform = RowerBillingAddressForm(instance=r)
planselectform = PlanSelectForm(paymentprocessor='braintree',
rower=r)
return render(request,
'upgrade.html',
{'rower':r,
'billingaddressform':billingaddressform,
'planselectform':planselectform,
})
@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 == '':
url = reverse(billing_view)
return HttpResponseRedirect(url)
if request.method == 'POST':
billingaddressform = RowerBillingAddressForm(request.POST)
planselectform = PlanSelectForm(request.POST,paymentprocessor='braintree')
if billingaddressform.is_valid():
cd = billingaddressform.cleaned_data
for attr, value in cd.items():
setattr(r, attr, value)
r.save()
if planselectform.is_valid():
plan = planselectform.cleaned_data['plan']
if plan.price > r.paidplan.price:
nextview = upgrade_confirm_view
elif plan.price == r.paidplan.price:
messages.info(request,'You did not select a new plan')
url = reverse(downgrade_view)
return HttpResponseRedirect(url)
else:
nextview = downgrade_confirm_view
if billingaddressform.is_valid():
url = reverse(nextview,
kwargs={
'planid':plan.id
})
return HttpResponseRedirect(url)
else:
billingaddressform = RowerBillingAddressForm(instance=r)
planselectform = PlanSelectForm(paymentprocessor='braintree',
rower=r,includeall=True, initial={'plan':r.paidplan})
return render(request,
'downgrade.html',
{'rower':r,
'billingaddressform':billingaddressform,
'planselectform':planselectform,
})
@login_required()
def plan_stop_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
subscriptions = []
if r.paidplan is not None and r.paidplan.paymentprocessor == 'braintree':
try:
subscriptions = braintreestuff.find_subscriptions(r)
except ProcessorCustomerError:
r.paymentprocessor = None
r.save()
return render(request,
'subscriptions_cancel.html',
{'rower':r,
'subscriptions':subscriptions
})
@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':
success, themessages,errormessages = braintreestuff.cancel_subscription(r,id)
for message in themessages:
messages.info(request,message)
for message in errormessages:
messages.error(request,message)
url = reverse(plan_stop_view)
return HttpResponseRedirect(url)
@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:
messages.error(request,"Something went wrong. Please try again.")
url = reverse(billing_view)
return HttpResponseRedirect(url)
r = getrequestrower(request)
client_token = braintreestuff.get_client_token(r)
return render(request,
"upgradeconfirm.html",
{
'plan':plan,
'client_token':client_token,
'rower':r,
})
@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:
messages.error(request,"Something went wrong. Please try again.")
url = reverse(billing_view)
return HttpResponseRedirect(url)
r = getrequestrower(request)
client_token = braintreestuff.get_client_token(r)
return render(request,
"downgradeconfirm.html",
{
'plan':plan,
'client_token':client_token,
'rower':r,
})
@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:
messages.error(request,"Something went wrong. Please try again.")
url = reverse(billing_view)
return HttpResponseRedirect(url)
r = getrequestrower(request)
client_token = braintreestuff.get_client_token(r)
return render(request,
"paymentconfirm.html",
{
'plan':plan,
'client_token':client_token,
'rower':r,
})
@login_required()
def checkouts_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if request.method != 'POST':
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
form = BillingForm(request.POST)
if form.is_valid():
data = form.cleaned_data
success = braintreestuff.create_subscription(r,data)
if success:
messages.info(request,"Your payment has succeeded and your plan has been updated")
url = reverse(payment_completed_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was a problem with your payment")
url = reverse(billing_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was an error in the payment form")
url = reverse(billing_view)
return HttpResponseRedirect(url)
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
@login_required()
def upgrade_checkouts_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if request.method != 'POST':
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
form = BillingForm(request.POST)
if form.is_valid():
data = form.cleaned_data
success = braintreestuff.update_subscription(r,data)
if success:
messages.info(request,"Your payment has succeeded and your plan has been updated")
url = reverse(payment_completed_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was a problem with your payment")
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was an error in the payment form")
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
@login_required()
def downgrade_checkouts_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
if request.method != 'POST':
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
form = BillingForm(request.POST)
if form.is_valid():
data = form.cleaned_data
success = braintreestuff.update_subscription(r,data,method='down')
if success:
messages.info(request,"Your plan has been updated")
url = reverse(downgrade_completed_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was a problem with your transaction")
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
else:
messages.error(request,"There was an error in the payment form")
url = reverse(upgrade_view)
return HttpResponseRedirect(url)
url = reverse(paidplans_view)
return HttpResponseRedirect(url)
@login_required()
def payment_completed_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
return render(request,
"payment_completed.html",
{
'rower':r
})
@login_required()
def downgrade_completed_view(request):
if not PAYMENT_PROCESSING_ON:
url = reverse('promembership')
return HttpResponseRedirect(url)
r = getrequestrower(request)
return render(request,
"downgrade_completed.html",
{
'rower':r
})
# User registration
def rower_register_view(request):
@@ -1477,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):