Private
Public Access
1
0

implemented Pro trial period

This commit is contained in:
Sander Roosendaal
2018-02-09 10:26:54 +01:00
parent 9df9969939
commit 71ad6a0dee
13 changed files with 149 additions and 66 deletions

View File

@@ -502,6 +502,8 @@ class Rower(models.Model):
planexpires = models.DateField(default=timezone.now)
teamplanexpires = models.DateField(default=timezone.now)
clubsize = models.IntegerField(default=0)
protrialexpires = models.DateField(blank=True,null=True)
plantrialexpires = models.DateField(blank=True,null=True)
# Friends/Team

View File

@@ -60,7 +60,7 @@
<div class="grid_6 alpha">
<div class="grid_2 alpha">
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/compare/{{ workout.id }}">Compare Workouts</a>
{% else %}
<a class="button blue small" href="/rowers/promembership/">Compare Workouts</a>
@@ -80,7 +80,7 @@
<div class="grid_2 omega tooltip">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/editintervals">Edit Intervals</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Edit Intervals</a>
@@ -97,7 +97,7 @@
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/adddistanceplot2">Dist Metrics Plot</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Dist Metrics Plot</a>
@@ -109,7 +109,7 @@
</div>
<div class="grid_2">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/addtimeplot2">Time Metrics Plot</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Time Metrics Plot</a>
@@ -121,7 +121,7 @@
</div>
<div class="grid_2 omega">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/histo">Power Histogram</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Power Histogram</a>
@@ -135,7 +135,7 @@
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workouts-join-select">Glue</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Glue</a>
@@ -148,7 +148,7 @@
<div class="grid_2">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/fusion/{{ workout.id }}/">Sensor Fusion</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Sensor Fusion</a>
@@ -160,7 +160,7 @@
</div>
<div class="grid_2 omega">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/split">Split Workout</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Split Workout</a>

View File

@@ -56,7 +56,7 @@
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/compare/{{ workout.id }}">Compare Workouts</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Compare Workouts</a>
@@ -78,7 +78,7 @@
<div class="grid_2 omega tooltip">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/editintervals">Edit Intervals</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Edit Intervals</a>
@@ -95,7 +95,7 @@
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small"href="/rowers/workout/{{ workout.id }}/crewnerdsummary">CrewNerd Summary</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">CrewNerd Summary</a>
@@ -109,7 +109,7 @@
<div class="grid_2 tooltip">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/forcecurve">Stroke Profile (Empower)</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Stroke Profile (Empower)</a>
@@ -122,7 +122,7 @@
<div class="grid_2 omega tooltip">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/addotwpowerplot">OTW Power Plot</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">OTW Power Plot</a>
@@ -142,7 +142,7 @@
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/geeky">Geeky Stuff</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Geeky Stuff</a>
@@ -157,7 +157,7 @@
<div class="grid_2 tooltip">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small"href="/rowers/workout/{{ workout.id }}/smoothenpace">Smooth out Pace Data</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Smooth out Pace Data</a>
@@ -174,7 +174,7 @@
<div class="grid_2 omega">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small"href="/rowers/workout/{{ workout.id }}/undosmoothenpace">Raw Data</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Reset Smoothing</a>
@@ -189,7 +189,7 @@
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workouts-join-select">Glue</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Glue</a>
@@ -201,7 +201,7 @@
</div>
<div class="grid_2">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/fusion/{{ workout.id }}/">Sensor Fusion</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Sensor Fusion</a>
@@ -213,7 +213,7 @@
</div>
<div class="grid_2 omega">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/split">Split Workout</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Split Workout</a>

View File

@@ -41,7 +41,7 @@
<h2>Pro</h2>
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/histo">Power Histogram</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Power Histogram</a>
@@ -53,7 +53,7 @@
</div>
<div class="grid_2">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/cumstats">Statistics</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Statistics</a>
@@ -65,7 +65,7 @@
</div>
<div class="grid_2 omega">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/user-boxplot-select">Box Chart</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Box Chart</a>
@@ -90,7 +90,7 @@
<div class="grid_6 omega">
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/otw-bests">OTW Critical Power</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">OTW Critical Power</a>
@@ -102,7 +102,7 @@
</div>
<div class="grid_2">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/team-compare-select/team/0/">Multi Compare</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Multi Compare</a>
@@ -114,7 +114,7 @@
</div>
<div class="grid_2 omega">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/user-multiflex-select">Trend Flex</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">Trend Flex</a>
@@ -128,7 +128,7 @@
<div class="grid_6 prefix_6 alpha">
<div class="grid_2 suffix_4 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/ote-ranking">OTE Critical Power</a>
{% else %}
<a class="button blue small" href="/rowers/promembership">OTE Critical Power</a>

View File

@@ -1,3 +1,4 @@
{% load rowerfilters %}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
@@ -19,7 +20,7 @@
<body>
<div class="container_12">
<div id="logo" class="grid_2">
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<p><a href="/"><img src="/static/img/logocroppedpro.gif"
alt="Rowsandall logo" width="110" heigt="110"></a></p>
{% else %}
@@ -44,7 +45,7 @@
<p>Free Data and Analysis. For Rowers. By Rowers.</p>
</div>
<div class="grid_3">
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<h6>Pro Member</h6>
{% else %}
<p>&nbsp;</p>

View File

@@ -56,24 +56,24 @@
{{ interactiveplot |safe }}
<script>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
// Set things up to resize the plot on a window resize. You can play with
// the arguments of resize_width_height() to change the plot's behavior.
var plot_resize_setup = function () {
var plotid = Object.keys(Bokeh.index)[0]; // assume we have just one plot
var plot = Bokeh.index[plotid];
var plotresizer = function() {
// arguments: use width, use height, maintain aspect ratio
plot.resize_width_height(true, false, false);
};
window.addEventListener('resize', plotresizer);
plotresizer();
};
window.addEventListener('load', plot_resize_setup);
</script>
<style>
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
html, body {height: 100%; margin:5px;}
</style>
<div id="title" class="grid_12 alpha">
@@ -97,8 +97,8 @@
</div>
{% else %}
&nbsp;
{% endif %}
</div>
{% endif %}
</div>
<div class="grid_12 alpha">
@@ -144,7 +144,7 @@
</div>
</div>
</div>
<div id="summary" class="grid_6 suffix_6 alpha">
<p>Summary for {{ theuser.first_name }} {{ theuser.last_name }}
@@ -153,9 +153,9 @@
</div>
<div id="graph" class="grid_12 alpha">
{{ the_div|safe }}
{{ the_div|safe }}
</div>
{% endblock %}

View File

@@ -57,7 +57,7 @@
<div class="grid_6 alpha">
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/wind">Edit Wind Data</a>
{% else %}
<a class="button blue small" href="/rowers/about">Edit Wind Data</a>
@@ -70,7 +70,7 @@
</div>
<div class="grid_2">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/stream">Edit Stream Data</a>
{% else %}
<a class="button blue small" href="/rowers/about">Edit Stream Data</a>
@@ -83,7 +83,7 @@
</div>
<div class="grid_2 omega">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/otwsetpower">OTW Power</a>
{% else %}
<a class="button blue small" href="/rowers/about">OTW Power</a>
@@ -100,7 +100,7 @@
<div class="grid_2 alpha">
<p>
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
{% if user|is_promember %}
<a class="button blue small" href="/rowers/workout/{{ workout.id }}/interactiveotwplot">Corrected Pace Plot</a>
{% else %}
<a class="button blue small" href="/rowers/about">Corrected Pace Plot</a>

View File

@@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block title %}About us{% endblock title %}
{% block title %}Rowsandall Plan Membership{% endblock title %}
{% block content %}
<div class="grid_6 alpha">

View File

@@ -1,7 +1,8 @@
{% extends "base.html" %}
{% block title %}About us{% endblock title %}
{% block title %}Rowsandall Pro Membership{% endblock title %}
{% block content %}
{% load rowerfilters %}
<div class="grid_6 alpha">
<h2>Pro Membership</h2>
@@ -24,12 +25,21 @@ website. </p>
Your payment will be valid for one year with automatic renewal which you can stop at any time.
You will be taken to the secure PayPal payment site.
</p>
{% if user.rower.rowerplan == 'basic' and user.rower.protrialexpires|date_dif == 1 %}
<p>
You qualify for a 14 day free trial. No credit card needed.
Try out Pro membership for two weeks. Click the button below to
sign up for the trial. After your trial period expires, you will be
automatically reset to the Basic plan, unless you upgrade to Pro.
</p>
<div class="grid_6"><p><a class="button green small" href="/rowers/starttrial">Yes, I want to try Pro membership for 14 days for free. No strings attached.</a></p></div>
{% endif %}
</div>
<div class="grid_6 omega">
<h2>Recurring Payment</h2>
<p>You need a Paypal account for this</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<p><form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="964GLEXX3THAW">
{% if user.is_authenticated %}
@@ -38,16 +48,16 @@ You will be taken to the secure PayPal payment site.
{% endif %}
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_subscribeCC_LG_global.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
</form></p>
<h2>One Year Subscription</h2>
<p>Only a credit card needed. Will not automatically renew</p>
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<p><form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="2YB32HQTF96QW">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>
</form></p>
<h2>Payment Processing</h2>
<p>After you do the payment, we will manually change your membership to

View File

@@ -3,7 +3,7 @@ from django.utils.safestring import mark_safe
from time import strftime
import dateutil.parser
import json
import datetime
register = template.Library()
def strfdelta(tdelta):
@@ -41,6 +41,10 @@ def secondstotimestring(tdelta):
return res
@register.filter
def ddays(ddelta):
return ddelta.days+1
@register.filter
def spacetohtml(t):
return t.replace(" ","%20")
@@ -107,6 +111,11 @@ def get_field_id(id,s,form):
from rowers.models import Rower,Team
from rowers.views import ispromember
@register.filter
def is_promember(user):
return ispromember(user)
@register.filter
def is_manager(user):
r = Rower.objects.get(user=user)
@@ -183,3 +192,25 @@ def verbosetimeperiod(timeperiod):
return verbose
from datetime import date
@ register.filter
def future_date_only(the_date):
if the_date > date.today():
return the_date
else:
return None
@register.filter
def is_future_date(the_date):
return the_date >= date.today()
@register.filter
def date_dif(the_date):
if the_date:
return the_date - date.today()
else:
return 1

View File

@@ -382,6 +382,7 @@ urlpatterns = [
url(r'^videos', TemplateView.as_view(template_name='videos.html'),name='videos'),
url(r'^analysis', TemplateView.as_view(template_name='analysis.html'),name='analysis'),
url(r'^promembership', TemplateView.as_view(template_name='promembership.html'),name='promembership'),
url(r'^starttrial$',views.start_trial_view),
url(r'^planmembership', TemplateView.as_view(template_name='planmembership.html'),name='planmembership'),
url(r'^paypaltest', TemplateView.as_view(template_name='paypaltest.html'),name='paypaltest'),
url(r'^legal', TemplateView.as_view(template_name='legal.html'),name='legal'),

View File

@@ -800,6 +800,8 @@ def ispromember(user):
r.save()
result = user.is_authenticated() and (r.rowerplan=='pro' or r.rowerplan=='coach' or r.rowerplan=='plan')
if not result and r.protrialexpires:
result = user.is_authenticated() and r.rowerplan=='basic' and r.protrialexpires >= datetime.date.today()
else:
result = False
return result
@@ -930,6 +932,33 @@ def sendmail(request):
else:
return HttpResponseRedirect('/rowers/email/')
@login_required()
def start_trial_view(request):
r = getrower(request.user)
if r.protrialexpires is not None:
messages.error(request,'You do not qualify for a trial')
url = '/rowers/promembership'
return HttpResponseRedirect(url)
r.protrialexpires = datetime.date.today()+datetime.timedelta(13)
r.save()
url = reverse(workouts_view)
messages.info(request,'We have started your 14 day trial period')
subject2 = "User started Pro Trial"
message2 = "User Started Pro Trial.\n"
message2 += request.user.email + "\n"
message2 += "User name: "+request.user.username
send_mail(subject2, message2,
'Rowsandall Server <info@rowsandall.com>',
['roosendaalsander@gmail.com'])
return HttpResponseRedirect(url)
# Create workout data from Strava or Concept2
# data and create the associated Workout object and save it
def add_workout_from_strokedata(user,importid,data,strokedata,
@@ -5060,7 +5089,8 @@ def team_comparison_select(request,
theteam = 0
if r.rowerplan == 'basic' and theteam==0:
raise Http404("Not allowed")
if r.protrialexpires is None or r.protrialexpires<datetime.date.today():
raise Http404("Not allowed")
if theteam and (theteam.viewing == 'allmembers' or theteam.manager == request.user):
workouts = Workout.objects.filter(team=theteam,