diff --git a/rowers/forms.py b/rowers/forms.py
index effeadf1..b4f03bb9 100644
--- a/rowers/forms.py
+++ b/rowers/forms.py
@@ -2,7 +2,8 @@ from django import forms
from django.contrib.admin.widgets import FilteredSelectMultiple
from rowers.models import (
Workout,Rower,Team,PlannedSession,GeoCourse,
- VirtualRace,VirtualRaceResult,IndoorVirtualRaceResult
+ VirtualRace,VirtualRaceResult,IndoorVirtualRaceResult,
+ PaidPlan
)
from rowers.rows import validate_file_extension,must_be_csv,validate_image_extension,validate_kml
from django.contrib.auth.forms import UserCreationForm
@@ -712,7 +713,19 @@ class StatsOptionsForm(forms.Form):
for type in mytypes.checktypes:
self.fields[type] = forms.BooleanField(initial=True,required=False)
+class PlanSelectForm(forms.Form):
+ plan = forms.ModelChoiceField(queryset=PaidPlan.objects.all(),
+ widget=forms.RadioSelect,required=True)
+ def __init__(self, *args, **kwargs):
+ paymentprocessor = kwargs.pop('paymentprocessor',None)
+ super(PlanSelectForm, self).__init__(*args, **kwargs)
+ self.fields['plan'].empty_label = None
+ if paymentprocessor:
+ self.fields['plan'].queryset = PaidPlan.objects.filter(
+ paymentprocessor=paymentprocessor
+ ).exclude(shortname="basic").order_by("price","clubsize","shortname")
+
class CourseSelectForm(forms.Form):
course = forms.ModelChoiceField(queryset=GeoCourse.objects.all())
diff --git a/rowers/models.py b/rowers/models.py
index a6d84e94..50fb9cc1 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -571,14 +571,14 @@ class PaidPlan(models.Model):
clubsize = models.IntegerField(default=0)
def __unicode__(self):
- return '{name} - {shortname} at {price} EURO ({paymenttype} payment) / {paymentprocessor}'.format(
+ return '{name} - {shortname} at {price} EURO ({paymenttype} payment)'.format(
name = self.name,
shortname = self.shortname,
price = self.price,
paymenttype = self.paymenttype,
paymentprocessor = self.paymentprocessor,
)
-
+
# Extension of User with rowing specific data
class Rower(models.Model):
@@ -3002,6 +3002,20 @@ class RowerImportExportForm(ModelForm):
'trainingpeaks_auto_export',
]
+# Form to collect rower's Billing Info
+class RowerBillingAddressForm(ModelForm):
+ class Meta:
+ model = Rower
+ fields = [
+ 'street_address',
+ 'city',
+ 'postal_code',
+ 'country'
+ ]
+
+ def __init__(self, *args, **kwargs):
+ super(RowerBillingAddressForm, self).__init__(*args, **kwargs)
+ self.fields['country'].required = True
# Form to set rower's Email and Weight category
diff --git a/rowers/payments.py b/rowers/payments.py
index da477b0b..ecc5691d 100644
--- a/rowers/payments.py
+++ b/rowers/payments.py
@@ -27,4 +27,9 @@ def setrowerplans():
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 r.country != '':
+ return True
+
+ return False
diff --git a/rowers/templates/billing.html b/rowers/templates/billing.html
new file mode 100644
index 00000000..ea725daa
--- /dev/null
+++ b/rowers/templates/billing.html
@@ -0,0 +1,36 @@
+{% extends "newbase.html" %}
+{% block title %}Rowsandall Paid Membership{% endblock title %}
+{% load rowerfilters %}
+{% block main %}
+
+
Upgrade
+
+
+
+{% endblock %}
+
+{% block sidebar %}
+{% include 'menu_help.html' %}
+{% endblock %}
+
diff --git a/rowers/templates/paidplans.html b/rowers/templates/paidplans.html
index 0cd4a34f..1c3c30e4 100644
--- a/rowers/templates/paidplans.html
+++ b/rowers/templates/paidplans.html
@@ -211,14 +211,22 @@
{% elif rower and rower.rowerplan == 'basic' %}
|
{% elif rower and rower.rowerplan == 'pro' %}
|
|
{% elif rower and rower.rowerplan == 'plan' %}
@@ -226,7 +234,11 @@
|
|
{% else %}
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index c9b81bd3..e2329849 100644
--- a/rowers/templatetags/rowerfilters.py
+++ b/rowers/templatetags/rowerfilters.py
@@ -24,6 +24,8 @@ from rowers.models import checkaccessuser
from rowers.mytypes import otwtypes
from rowers.utils import NoTokenError
+import rowers.payments as payments
+
def strfdelta(tdelta):
minutes,seconds = divmod(tdelta.seconds,60)
tenths = int(tdelta.microseconds/1e5)
@@ -59,6 +61,13 @@ def secondstotimestring(tdelta):
return res
+@register.filter
+def existing_customer(user):
+ if user.is_anonymous():
+ return False
+ else:
+ return payments.is_existing_customer(user.rower)
+
@register.filter
def aantalcomments(workout):
try:
diff --git a/rowers/urls.py b/rowers/urls.py
index a74d085d..63504a03 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -438,6 +438,7 @@ urlpatterns = [
url(r'^analysis/$', views.analysis_view,name='analysis'),
url(r'^laboratory/$', views.laboratory_view,name='laboratory'),
url(r'^promembership', TemplateView.as_view(template_name='promembership.html'),name='promembership'),
+ url(r'^billing',views.billing_view,name='billing'),
url(r'^paidplans',views.paidplans_view,name='paidplans'),
url(r'^checkouts',views.checkouts_view,name='checkouts'),
url(r'^payments',views.payments_view,name='payments'),
diff --git a/rowers/views.py b/rowers/views.py
index 069773d8..5aba8d49 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -28,7 +28,7 @@ import isodate
import re
import cgi
from icalendar import Calendar, Event
-import braintree
+import rowers.braintreestuff as braintreestuff
from django.shortcuts import render
from django.template.loader import render_to_string
@@ -51,7 +51,7 @@ from rowers.forms import (
RaceResultFilterForm,PowerIntervalUpdateForm,FlexAxesForm,
FlexOptionsForm,DataFrameColumnsForm,OteWorkoutTypeForm,
MetricsForm,DisqualificationForm,disqualificationreasons,
- disqualifiers,SearchForm,BillingForm
+ disqualifiers,SearchForm,BillingForm,PlanSelectForm
)
from django.core.urlresolvers import reverse, reverse_lazy
@@ -84,7 +84,7 @@ from rowers.models import (
createmicrofillers, createmesofillers,
microcyclecheckdates,mesocyclecheckdates,macrocyclecheckdates,
TrainingMesoCycleForm, TrainingMicroCycleForm,
- RaceLogo,
+ RaceLogo,RowerBillingAddressForm,
)
from rowers.models import (
RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm,
@@ -1034,12 +1034,41 @@ def paidplans_view(request):
r = getrequestrower(request)
else:
r = None
-
+
+
return render(request,
'paidplans.html',
{'rower':r})
+@login_required()
+def billing_view(request):
+ r = getrequestrower(request)
+
+ 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']
+ else:
+ billingaddressform = RowerBillingAddressForm(instance=r)
+ planselectform = PlanSelectForm(paymentprocessor='braintree')
+
+ return render(request,
+ 'billing.html',
+ {'rower':r,
+ 'billingaddressform':billingaddressform,
+ 'planselectform':planselectform,
+ })
+
+
+
# Experimental - Payments
@login_required()
def payments_view(request):