From 75261118c2a7aaf7ed070d5b300695adaf84fbec Mon Sep 17 00:00:00 2001
From: Sander Roosendaal Rowsandall.com offers free data and analysis for rowers, by rowers.
+ Of course, offering this service is not free. To help cover the
+ hosting costs, we have created paid plans offering extended
+ functionality.
+
+ Paid Membership Plans
+
+
+
+
+
+
+
+
+
+
+ BASIC
+ PRO
+ SELF-COACH
+ COACH
+
+
+ Basic rowing metrics (spm, time, distance, heart rate, power)
+ ✔
+ ✔
+ ✔
+ ✔
+
+
+ Manual Import, Export, Synchronization and download of all your data
+ ✔
+ ✔
+ ✔
+ ✔
+
+
+ Automatic Synchronization with other fitness sites
+
+ ✔
+ ✔
+ ✔
+
+
+ Heart rate and power zones
+ ✔
+ ✔
+ ✔
+ ✔
+
+
+ Ranking Pieces, Stroke Analysis
+ ✔
+ ✔
+ ✔
+ ✔
+
+
+ Advanced Analysis (Critical Power, Stats, Box Chart, Trend Flex)
+
+ ✔
+ ✔
+ ✔
+
+
+ Compare Workouts
+
+ ✔
+ ✔
+ ✔
+
+
+ Empower Stroke Profile
+
+ ✔
+ ✔
+ ✔
+
+
+ Sensor Fusion, Split Workout, In-stroke metrics
+
+ ✔
+ ✔
+ ✔
+
+
+ Create Training plans, tests and challenges for yourself. Track your performance
+ against plan.
+
+
+ ✔
+ ✔
+
+
+ Create Training plans, tests and challenges for your athletes. Track their performance
+ against plan.
+
+
+
+ ✔
+
+
+ Create and manage teams.
+
+
+
+ ✔
+
+
+ Manage your athlete's workouts
+
+
+
+ ✔
+
+
+ {% if rower %}
+ Pricing
+ FREE
+ From 15€/year
+ From 65€/year
+ From 90€/year
+
+
+ {% endif %}
+ Your current plan
+
+ {% if rower.rowerplan == 'basic' %}
+
+ BASIC
+ {% else %}
+
+ {% endif %}
+
+ {% if rower.rowerplan == 'pro' %}
+ PRO
+ {% else %}
+
+ {% endif %}
+
+
+ {% if rower.rowerplan == 'plan' %}
+ SELF-COACH
+ {% else %}
+
+ {% endif %}
+
+
+ {% if rower.rowerplan == 'coach' %}
+ COACH
+ {% else %}
+
+ {% endif %}
+
+
+
+
+ Available trials
+
+
+
+
+
+ {% if user.is_anonymous %}
+
+ {% elif rower and rower.rowerplan == 'basic' and rower.protrialexpires|date_dif == 1 %}
+
+ {% else %}
+
+ {% endif %}
+
+
+ {% if user.is_anonymous %}
+
+ {% elif rower and rower.rowerplan == 'basic' and rower.plantrialexpires|date_dif == 1 %}
+
+ {% else %}
+
+ {% endif %}
+
+
+
+
+
+
+
+
+ Available upgrades
+
+
+
+
+ {% if user.is_anonymous %}
+
+
+
+ {% elif rower and rower.rowerplan == 'basic' %}
+
+
+
+ {% elif rower and rower.rowerplan == 'pro' %}
+
+
+
+
+ {% elif rower and rower.rowerplan == 'plan' %}
+
+
+
+
+
+ {% else %}
+
+
+
+ {% endif %}
+
The Coach plan functionality listed is available to the coach only. Individual athletes + can purchase upgrades to "Pro" and "Self-Coach" plans. +
+ +Rowsandall.com's Training Planning functionality + is part of the paid "Self-Coach" and "Coach" plans.
+ +On the "Self-Coach" plan, you can plan your own sessions.
+ +On the "Coach" plan, you can establish teams, see workouts done by + athletes on your team, and plan individual and group sessions for your + athletes. +
+ +If you would like to find a coach who helps you plan your training + through rowsandall.com, contact me throught the contact form.
+ + + + +{% endblock %} + +{% block sidebar %} +{% include 'menu_help.html' %} +{% endblock %} + diff --git a/rowers/urls.py b/rowers/urls.py index 87312e90..a74d085d 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'^paidplans',views.paidplans_view,name='paidplans'), url(r'^checkouts',views.checkouts_view,name='checkouts'), url(r'^payments',views.payments_view,name='payments'), url(r'^planrequired',views.planrequired_view), diff --git a/rowers/utils.py b/rowers/utils.py index cb9fbaae..eb5627b3 100644 --- a/rowers/utils.py +++ b/rowers/utils.py @@ -426,6 +426,13 @@ class NoTokenError(Exception): def __str__(self): return repr(self.value) +class ProcessorCustomerError(Exception): + def __init__(self, value): + self.value=value + + def __str__(self): + return repr(self.value) + # Custom exception handler, returns a 401 HTTP message # with exception details in the json data def custom_exception_handler(exc,message): diff --git a/rowers/views.py b/rowers/views.py index d0110059..069773d8 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -51,7 +51,7 @@ from rowers.forms import ( RaceResultFilterForm,PowerIntervalUpdateForm,FlexAxesForm, FlexOptionsForm,DataFrameColumnsForm,OteWorkoutTypeForm, MetricsForm,DisqualificationForm,disqualificationreasons, - disqualifiers,SearchForm,BrainTreeForm + disqualifiers,SearchForm,BillingForm ) from django.core.urlresolvers import reverse, reverse_lazy @@ -1029,6 +1029,17 @@ 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}) + # Experimental - Payments @login_required() def payments_view(request): @@ -1091,7 +1102,7 @@ def checkouts_view(request): ) ) - form = BrainTreeForm(request.POST) + form = BillingForm(request.POST) if form.is_valid(): nonce_from_the_client = form.cleaned_data['payment_method_nonce'] amount = form.cleaned_data['amount'] diff --git a/static/css/rowsandall.css b/static/css/rowsandall.css index 95fd1d8b..86682c66 100644 --- a/static/css/rowsandall.css +++ b/static/css/rowsandall.css @@ -170,6 +170,15 @@ cox { text-align: center; } +.plantable { + border-collapse: collapse; +} + +.plantable > td { + text-align: center; +} + + th.rotate { /* Something you can count on */ height: 78px; @@ -220,6 +229,7 @@ th.rotate > div > span { background-color: #fee; } + .successmessage { border: 1px solid #000; background-color: #8f8; @@ -907,3 +917,21 @@ a.wh:hover { hyphens: auto; } + +.upgradebutton { + background-color: #4CAF50; + border: none; + color: white; + padding: 20px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin: 4px 2px; +} + +.buttonr2 {border-radius: 2px;} +.buttonr4 {border-radius: 4px;} +.buttonr8 {border-radius: 8px;} +.buttonr12 {border-radius: 12px;} +.buttonround {border-radius: 50%;}