Merge branch 'release/v5.80'
This commit is contained in:
+3
-3
@@ -2226,11 +2226,11 @@ def workout_trimp(workout):
|
||||
return trimp
|
||||
|
||||
def workout_rscore(w):
|
||||
r = workout.user
|
||||
df,row = getrowdata_db(id=workout.id)
|
||||
r = w.user
|
||||
df,row = getrowdata_db(id=w.id)
|
||||
df = clean_df_stats(df)
|
||||
if df.empty:
|
||||
df,row = getrowdata_db(id=workout.id)
|
||||
df,row = getrowdata_db(id=w.id)
|
||||
df = clean_df_stats(df,workstrokesonly=False)
|
||||
|
||||
duration = df['time'].max()-df['time'].min()
|
||||
|
||||
+24
-1
@@ -1,6 +1,6 @@
|
||||
from django import forms
|
||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
||||
from rowers.models import Workout
|
||||
from rowers.models import Workout,Rower,Team
|
||||
from rowers.rows import validate_file_extension,must_be_csv,validate_image_extension
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from django.contrib.auth.models import User
|
||||
@@ -629,3 +629,26 @@ class WorkoutSessionSelectForm(forms.Form):
|
||||
widget = forms.CheckboxSelectMultiple,
|
||||
)
|
||||
|
||||
class PlannedSessionTeamForm(forms.Form):
|
||||
team = forms.ModelMultipleChoiceField(
|
||||
queryset=Team.objects.all(),
|
||||
required=False,
|
||||
widget=forms.CheckboxSelectMultiple())
|
||||
|
||||
def __init__(self, user, *args, **kwargs):
|
||||
super(PlannedSessionTeamForm,self).__init__(*args, **kwargs)
|
||||
|
||||
self.fields['team'].queryset = Team.objects.filter(manager=user)
|
||||
|
||||
|
||||
class PlannedSessionTeamMemberForm(forms.Form):
|
||||
members = forms.ModelMultipleChoiceField(
|
||||
queryset=Rower.objects.all(),
|
||||
widget=forms.CheckboxSelectMultiple())
|
||||
|
||||
def __init__(self, thesession, *args, **kwargs):
|
||||
super(PlannedSessionTeamMemberForm,self).__init__(*args,**kwargs)
|
||||
|
||||
self.fields['members'].queryset = thesession.rower.all()
|
||||
|
||||
|
||||
|
||||
+6
-1
@@ -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
|
||||
@@ -521,7 +523,10 @@ class Rower(models.Model):
|
||||
verbose_name='Show Notes for Favorite Charts')
|
||||
|
||||
def __str__(self):
|
||||
return self.user.username
|
||||
return self.user.firstname+' '+self.user.last_name
|
||||
|
||||
def __unicode__(self):
|
||||
return self.user.first_name+' '+self.user.last_name
|
||||
|
||||
def clean_email(self):
|
||||
return self.user.email.lower()
|
||||
|
||||
@@ -219,6 +219,17 @@ def get_sessions(r,startdate=date.today(),
|
||||
|
||||
return sps
|
||||
|
||||
def get_sessions_manager(manager,startdate=date.today(),
|
||||
enddate=date.today()+timezone.timedelta(+1000)):
|
||||
|
||||
sps = PlannedSession.objects.filter(
|
||||
manager=manager,
|
||||
startdate__lte=enddate,
|
||||
enddate__gte=startdate,
|
||||
).order_by("startdate","enddate").exclude(team__isnull=True)
|
||||
|
||||
return sps
|
||||
|
||||
def get_workouts_session(r,ps):
|
||||
ws = Workout.objects.filter(user=r,plannedsession=ps)
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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> </p>
|
||||
|
||||
@@ -69,11 +69,11 @@
|
||||
plotresizer();
|
||||
};
|
||||
window.addEventListener('load', plot_resize_setup);
|
||||
</script>
|
||||
<style>
|
||||
</script>
|
||||
<style>
|
||||
/* Need this to get the page in "desktop mode"; not having an infinite height.*/
|
||||
html, body {height: 100%; margin:5px;}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
|
||||
<div id="title" class="grid_12 alpha">
|
||||
@@ -97,8 +97,8 @@
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="grid_12 alpha">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
{% block content %}
|
||||
<div class="grid_12 alpha">
|
||||
{% include "planningbuttons.html" %}
|
||||
|
||||
</div>
|
||||
|
||||
<div class="grid_12 alpha">
|
||||
<div id="left" class="grid_6 alpha">
|
||||
<h1>Create Session for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
|
||||
@@ -119,7 +119,7 @@
|
||||
</table>
|
||||
{% csrf_token %}
|
||||
<div id="formbutton" class="grid_1 prefix_4 suffix_1">
|
||||
<input class="button green" type="submit" value="Submit">
|
||||
<input class="button green" type="submit" value="Save">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}Update Planned Session{% endblock %}
|
||||
|
||||
@@ -13,7 +14,7 @@
|
||||
<h1>Edit Session {{ thesession.name }}</h1>
|
||||
</div>
|
||||
<div id="timeperiod" class="grid_2 dropdown">
|
||||
<button class="grid_2 alpha button gray small dropbtn">Time Period</button>
|
||||
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
|
||||
<div class="dropdown-content">
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/today/rower/{{ rower.id }}">
|
||||
@@ -37,6 +38,13 @@
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% if user.is_authenticated and user|is_manager %}
|
||||
<div class="grid_2">
|
||||
<a class="button green small alpha" href="/rowers/sessions/teamedit/{{ thesession.id }}/{{ timeperiod}}">
|
||||
Assign to my Teams
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="grid_12 alpha">
|
||||
<div class="grid_6 alpha">
|
||||
|
||||
@@ -117,6 +117,57 @@
|
||||
You have no planned workouts for this period. Planned workouts are created
|
||||
by your coach if you are part of a team. You can create your own
|
||||
planned workouts by purchasing the "Coach" or "Self-Coach" plans.
|
||||
{% endif %}
|
||||
{% if unmatchedworkouts %}
|
||||
<h1>Workouts that are not linked to any session</h1>
|
||||
<table width="90%" class="listtable shortpadded">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:80"> Date</th>
|
||||
<th> Time</th>
|
||||
<th> Name</th>
|
||||
<th> Type</th>
|
||||
<th> Distance </th>
|
||||
<th> Duration </th>
|
||||
<th> Avg HR </th>
|
||||
<th> Max HR </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for workout in unmatchedworkouts %}
|
||||
<tr>
|
||||
<td> {{ workout.date|date:"Y-m-d" }} </td>
|
||||
<td> {{ workout.starttime|date:"H:i" }} </td>
|
||||
{% if workout.user.user == user or user == team.manager %}
|
||||
{% if workout.name != '' %}
|
||||
<td>
|
||||
<a href={% url rower.defaultlandingpage id=workout.id %}>
|
||||
{{ workout.name }}
|
||||
</a>
|
||||
</td>
|
||||
{% else %}
|
||||
<td>
|
||||
<a href={% url rower.defaultlandingpage id=workout.id %}>No Name
|
||||
</a></td>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if workout.name != '' %}
|
||||
<td><a href="/rowers/workout/{{ workout.id }}/">{{ workout.name }}</a></td>
|
||||
{% else %}
|
||||
<td><a href="/rowers/workout/{{ workout.id }}/">No Name</a> </td>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<td> {{ workout.workouttype }} </td>
|
||||
<td> {{ workout.distance }}m</td>
|
||||
<td> {{ workout.duration |durationprint:"%H:%M:%S.%f" }} </td>
|
||||
<td> {{ workout.averagehr }} </td>
|
||||
<td> {{ workout.maxhr }} </td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -59,10 +59,10 @@
|
||||
{% for member in user|team_rowers %}
|
||||
<a class="button green small" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="grid_12 alpha">
|
||||
<p>Select one session on the left, and one or more workouts on the right
|
||||
to match the workouts to the session. For tests and training sessions,
|
||||
@@ -92,8 +92,6 @@
|
||||
{% csrf_token %}
|
||||
<input class="button green" type="submit" value="Submit">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
{% extends "base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}New Planned Session{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="grid_12 alpha">
|
||||
{% include "planningbuttons.html" %}
|
||||
</div>
|
||||
|
||||
<div class="grid_12 alpha">
|
||||
<div id="left" class="grid_6 alpha">
|
||||
<h1>Create Team Session</h1>
|
||||
</div>
|
||||
<div id="timeperiod" class="grid_2 dropdown">
|
||||
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
|
||||
<div class="dropdown-content">
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/today/rower/{{ rower.id }}">
|
||||
Today
|
||||
</a>
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/thisweek/rower/{{ rower.id }}">
|
||||
This Week
|
||||
</a>
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/thismonth/rower/{{ rower.id }}">
|
||||
This Month
|
||||
</a>
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/lastweek/rower/{{ rower.id }}">
|
||||
Last Week
|
||||
</a>
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}">
|
||||
Last Month
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid_12 alpha">
|
||||
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
|
||||
{% if form.errors %}
|
||||
<p style="color: red;">
|
||||
Please correct the error{{ form.errors|pluralize }} below.
|
||||
</p>
|
||||
{% endif %}
|
||||
{% csrf_token %}
|
||||
|
||||
<div id="right" class="grid_6 alpha">
|
||||
<h1>Select Team</h1>
|
||||
<p>
|
||||
<table>
|
||||
{{ teamform.as_table }}
|
||||
</table></p>
|
||||
{% if plannedsessions %}
|
||||
<h1>Team Plan Sessions</h1>
|
||||
<p>
|
||||
<table class="listtable shortpadded" width="80%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>After</th>
|
||||
<th>Before</th>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
<th> </th>
|
||||
<th>Edit</th>
|
||||
<th>Clone</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for ps in plannedsessions %}
|
||||
<tr>
|
||||
<td> {{ ps.startdate|date:"Y-m-d" }} </td>
|
||||
<td> {{ ps.enddate|date:"Y-m-d" }} </td>
|
||||
<td>
|
||||
{% if ps.name != '' %}
|
||||
<a class="small"
|
||||
href="/rowers/sessions/{{ ps.id }}">{{ ps.name }}</a>
|
||||
{% else %}
|
||||
<a class="small"
|
||||
href="/rowers/sessions/{{ ps.id }}">Unnamed Session</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td> {{ ps.sessionvalue }} </td>
|
||||
<td> {{ ps.sessionunit }} </td>
|
||||
<td>
|
||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/edit">Edit</a>
|
||||
</td>
|
||||
<td>
|
||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/clone">Clone</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="grid_6 omega">
|
||||
<h1>New Session</h1>
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
<div id="formbutton" class="grid_1 prefix_4 suffix_1">
|
||||
<input class="button green" type="submit" value="Save">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,137 @@
|
||||
{% extends "base.html" %}
|
||||
{% load staticfiles %}
|
||||
{% load rowerfilters %}
|
||||
|
||||
{% block title %}New Planned Session{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="grid_12 alpha">
|
||||
{% include "planningbuttons.html" %}
|
||||
</div>
|
||||
|
||||
<div class="grid_12 alpha">
|
||||
<div id="left" class="grid_6 alpha">
|
||||
<h1>Edit Team Session</h1>
|
||||
</div>
|
||||
<div id="timeperiod" class="grid_2 dropdown">
|
||||
<button class="grid_2 alpha button gray small dropbtn">Select Time Period ({{ timeperiod|verbosetimeperiod }})</button>
|
||||
<div class="dropdown-content">
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/today/rower/{{ rower.id }}">
|
||||
Today
|
||||
</a>
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/thisweek/rower/{{ rower.id }}">
|
||||
This Week
|
||||
</a>
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/thismonth/rower/{{ rower.id }}">
|
||||
This Month
|
||||
</a>
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/lastweek/rower/{{ rower.id }}">
|
||||
Last Week
|
||||
</a>
|
||||
<a class="button gray small alpha"
|
||||
href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}">
|
||||
Last Month
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid_12 alpha">
|
||||
<form enctype="multipart/form-data" action="{{ formloc }}" method="post">
|
||||
{% if form.errors %}
|
||||
<p style="color: red;">
|
||||
Please correct the error{{ form.errors|pluralize }} below.
|
||||
</p>
|
||||
{% endif %}
|
||||
{% csrf_token %}
|
||||
|
||||
<div id="right" class="grid_6 alpha">
|
||||
<h1>Select Team</h1>
|
||||
<p>
|
||||
Selecting a team assigns this session to all members of the team.
|
||||
Unselecting a team does not remove rowers
|
||||
who are already assigned to this session. Use the Rowers selection for that.
|
||||
</p><p>
|
||||
<table>
|
||||
{{ teamform.as_table }}
|
||||
</table></p>
|
||||
<h1>Select Rowers</h1>
|
||||
<p>
|
||||
<table>
|
||||
{{ rowersform.as_table }}
|
||||
</table>
|
||||
</p>
|
||||
{% if plannedsessions %}
|
||||
<h1>Team Plan Sessions</h1>
|
||||
<p>
|
||||
<table class="listtable shortpadded" width="80%">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>After</th>
|
||||
<th>Before</th>
|
||||
<th>Name</th>
|
||||
<th>Value</th>
|
||||
<th> </th>
|
||||
<th>Edit</th>
|
||||
<th>Clone</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for ps in plannedsessions %}
|
||||
<tr>
|
||||
<td> {{ ps.startdate|date:"Y-m-d" }} </td>
|
||||
<td> {{ ps.enddate|date:"Y-m-d" }} </td>
|
||||
<td>
|
||||
{% if ps.name != '' %}
|
||||
<a class="small"
|
||||
href="/rowers/sessions/{{ ps.id }}">{{ ps.name }}</a>
|
||||
{% else %}
|
||||
<a class="small"
|
||||
href="/rowers/sessions/{{ ps.id }}">Unnamed Session</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td> {{ ps.sessionvalue }} </td>
|
||||
<td> {{ ps.sessionunit }} </td>
|
||||
<td>
|
||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/edit">Edit</a>
|
||||
</td>
|
||||
<td>
|
||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/clone">Clone</a>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
<a class="small" href="/rowers/sessions/{{ ps.id }}/deleteconfirm">Delete</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="grid_6 omega">
|
||||
<h1>Session {{ plannedsession.name }}</h1>
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
<div class="grid_1 prefix_2 alpha">
|
||||
<a class="red button small" href="/rowers/sessions/{{ plannedsession.id }}/deleteconfirm">Delete</a>
|
||||
</div>
|
||||
<div class="grid_1">
|
||||
<a class="gray button small" href="/rowers/sessions/{{ plannedsession.id }}/clone">Clone</a>
|
||||
</div>
|
||||
<div id="formbutton" class="grid_1 suffix_1 omega">
|
||||
<input class="button green" type="submit" value="Save">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -21,7 +21,7 @@
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid_2 suffix_6 omega">
|
||||
<div class="grid_2">
|
||||
<p>
|
||||
{% if timeperiod and rower %}
|
||||
<a class="button gray small" href="/rowers/sessions/create/{{ timeperiod }}/rower/{{ rower.id }}">Add Session</a>
|
||||
@@ -32,3 +32,15 @@
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="grid_2 omega">
|
||||
{% if user.is_authenticated and user|is_manager %}
|
||||
{% if timeperiod %}
|
||||
<a class="button gray small" href="/rowers/sessions/teamcreate/{{ timeperiod }}">Add Team Session</a>
|
||||
{% else %}
|
||||
<a class="button gray small" href="/rowers/session/teamcreate">Add Team Session</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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'),
|
||||
@@ -397,6 +398,18 @@ urlpatterns = [
|
||||
url(r'^workout/compare/(?P<id1>\d+)/(?P<id2>\d+)/(?P<xparam>\w+.*)/(?P<yparam>[\w\ ]+.*)/$',views.workout_comparison_view2),
|
||||
url(r'^test\_callback',views.rower_process_testcallback),
|
||||
url(r'^workout/(?P<id>\d+)/test\_strokedata$',views.strokedataform),
|
||||
|
||||
url(r'^sessions/teamcreate$',views.plannedsession_teamcreate_view),
|
||||
url(r'^sessions/teamcreate/(?P<timeperiod>[\w\ ]+.*)$',
|
||||
views.plannedsession_teamcreate_view),
|
||||
url(r'^sessions/teamcreate/(?P<timeperiod>[\w\ ]+.*)/team/(?P<teamid>\d+)$',
|
||||
views.plannedsession_teamcreate_view),
|
||||
url(r'^sessions/teamcreate/team/(?P<teamid>\d+)$',
|
||||
views.plannedsession_teamcreate_view),
|
||||
|
||||
url(r'^sessions/teamedit/(?P<sessionid>\d+)$',views.plannedsession_teamedit_view),
|
||||
url(r'^sessions/teamedit/(?P<sessionid>\d+)/(?P<timeperiod>[\w\ ]+.*)$',views.plannedsession_teamedit_view),
|
||||
|
||||
url(r'^sessions/create$',views.plannedsession_create_view),
|
||||
url(r'^sessions/create/rower/(?P<rowerid>\d+)$',
|
||||
views.plannedsession_create_view),
|
||||
|
||||
+261
-3
@@ -30,7 +30,8 @@ from rowers.forms import (
|
||||
LoginForm,DocumentsForm,UploadOptionsForm,ImageForm,
|
||||
TeamUploadOptionsForm,WorkFlowLeftPanelForm,WorkFlowMiddlePanelForm,
|
||||
WorkFlowLeftPanelElement,WorkFlowMiddlePanelElement,
|
||||
LandingPageForm,PlannedSessionSelectForm,WorkoutSessionSelectForm
|
||||
LandingPageForm,PlannedSessionSelectForm,WorkoutSessionSelectForm,
|
||||
PlannedSessionTeamForm,PlannedSessionTeamMemberForm,
|
||||
)
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.exceptions import PermissionDenied
|
||||
@@ -800,6 +801,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 +933,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,6 +5090,7 @@ def team_comparison_select(request,
|
||||
theteam = 0
|
||||
|
||||
if r.rowerplan == 'basic' and theteam==0:
|
||||
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):
|
||||
@@ -11779,6 +11810,208 @@ def plannedsession_create_view(request,timeperiod='thisweek',rowerid=0):
|
||||
'timeperiod':timeperiod,
|
||||
})
|
||||
|
||||
# Manager creates sessions for entire team
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/planmembership/",
|
||||
redirect_field_name=None)
|
||||
def plannedsession_teamcreate_view(request,timeperiod='thisweek',
|
||||
teamid=0):
|
||||
|
||||
|
||||
teams = Team.objects.filter(manager=request.user)
|
||||
teamchoices = [(team.id, team.name) for team in teams]
|
||||
teaminitial = [str(teams[0].id)]
|
||||
|
||||
startdate,enddate = get_dates_timeperiod(timeperiod)
|
||||
|
||||
sps = []
|
||||
for team in teams:
|
||||
res = get_sessions_manager(request.user,startdate=startdate,enddate=enddate)
|
||||
sps += res
|
||||
|
||||
sps = list(set(sps))
|
||||
|
||||
if request.method == 'POST':
|
||||
sessioncreateform = PlannedSessionForm(request.POST)
|
||||
sessionteamselectform = PlannedSessionTeamForm(
|
||||
request.user,request.POST
|
||||
)
|
||||
if sessioncreateform.is_valid():
|
||||
cd = sessioncreateform.cleaned_data
|
||||
startdate = cd['startdate']
|
||||
enddate = cd['enddate']
|
||||
sessiontype = cd['sessiontype']
|
||||
sessionmode = cd['sessionmode']
|
||||
criterium = cd['criterium']
|
||||
sessionvalue = cd['sessionvalue']
|
||||
sessionunit = cd['sessionunit']
|
||||
comment = cd['comment']
|
||||
name = cd['name']
|
||||
|
||||
if sessionunit == 'min':
|
||||
sessionmode = 'time'
|
||||
elif sessionunit in ['km','m']:
|
||||
sessionmode = 'distance'
|
||||
|
||||
ps = PlannedSession(
|
||||
name=name,
|
||||
startdate=startdate,
|
||||
enddate=enddate,
|
||||
sessiontype=sessiontype,
|
||||
sessionmode=sessionmode,
|
||||
sessionvalue=sessionvalue,
|
||||
sessionunit=sessionunit,
|
||||
comment=comment,
|
||||
criterium=criterium,
|
||||
manager=request.user)
|
||||
|
||||
ps.save()
|
||||
|
||||
# some logic when to add all selected rowers
|
||||
if sessionteamselectform.is_valid():
|
||||
cd = sessionteamselectform.cleaned_data
|
||||
teams = cd['team']
|
||||
for team in teams:
|
||||
add_team_session(team,ps)
|
||||
rs = Rower.objects.filter(team__in=[team])
|
||||
for r in rs:
|
||||
add_rower_session(r,ps)
|
||||
|
||||
|
||||
url = reverse(plannedsession_teamcreate_view,
|
||||
kwargs = {
|
||||
'timeperiod':timeperiod,
|
||||
})
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
sessioncreateform = PlannedSessionForm()
|
||||
sessionteamselectform = PlannedSessionTeamForm(
|
||||
request.user
|
||||
)
|
||||
|
||||
return render(request,'plannedsessionteamcreate.html',
|
||||
{
|
||||
'teams':get_my_teams(request.user),
|
||||
'form':sessioncreateform,
|
||||
'teamform':sessionteamselectform,
|
||||
'timeperiod':timeperiod,
|
||||
'plannedsessions':sps,
|
||||
})
|
||||
|
||||
# Manager edits sessions for entire team
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/planmembership/",
|
||||
redirect_field_name=None)
|
||||
def plannedsession_teamedit_view(request,timeperiod='thisweek',
|
||||
sessionid=0):
|
||||
|
||||
try:
|
||||
ps = PlannedSession.objects.get(id=sessionid)
|
||||
except PlannedSession.DoesNotExist:
|
||||
raise Http404("This session doesn't exist")
|
||||
if not ps.manager == request.user:
|
||||
raise Http404("You are not the manager of this session")
|
||||
|
||||
teams = Team.objects.filter(manager=request.user)
|
||||
teamchoices = [(team.id, team.name) for team in teams]
|
||||
|
||||
teaminitial = ps.team.all()
|
||||
|
||||
startdate,enddate = get_dates_timeperiod(timeperiod)
|
||||
|
||||
sps = []
|
||||
rowers = []
|
||||
for team in teams:
|
||||
res = get_sessions_manager(request.user,startdate=startdate,enddate=enddate)
|
||||
sps += res
|
||||
rowers += Rower.objects.filter(team__in=[team])
|
||||
|
||||
rowers = list(set(rowers))
|
||||
|
||||
|
||||
sps = list(set(sps))
|
||||
|
||||
if request.method == 'POST':
|
||||
sessioncreateform = PlannedSessionForm(request.POST,instance=ps)
|
||||
sessionteamselectform = PlannedSessionTeamForm(
|
||||
request.user,request.POST
|
||||
)
|
||||
sessionrowerform = PlannedSessionTeamMemberForm(ps,request.POST)
|
||||
if sessioncreateform.is_valid():
|
||||
cd = sessioncreateform.cleaned_data
|
||||
|
||||
if cd['sessionunit'] == 'min':
|
||||
cd['sessionmode'] = 'time'
|
||||
elif cd['sessionunit'] in ['km','m']:
|
||||
cd['sessionmode'] = 'distance'
|
||||
|
||||
|
||||
res,message = update_plannedsession(ps,cd)
|
||||
|
||||
if res:
|
||||
messages.info(request,message)
|
||||
else:
|
||||
messages.error(request,message)
|
||||
|
||||
|
||||
# some logic when to add all selected rowers
|
||||
if sessionteamselectform.is_valid():
|
||||
cd = sessionteamselectform.cleaned_data
|
||||
selectedteams = cd['team']
|
||||
for team in teams:
|
||||
if team in selectedteams:
|
||||
add_team_session(team,ps)
|
||||
rs = Rower.objects.filter(team__in=[team])
|
||||
for r in rs:
|
||||
add_rower_session(r,ps)
|
||||
else:
|
||||
remove_team_session(team,ps)
|
||||
else:
|
||||
selectedteams = []
|
||||
|
||||
|
||||
if sessionrowerform.is_valid():
|
||||
cd = sessionrowerform.cleaned_data
|
||||
selectedrowers = cd['members']
|
||||
for r in rowers:
|
||||
if r in selectedrowers:
|
||||
add_rower_session(r,ps)
|
||||
else:
|
||||
remove_rower_session(r,ps)
|
||||
for t in selectedteams:
|
||||
if t in r.team.all():
|
||||
add_rower_session(r,ps)
|
||||
|
||||
|
||||
url = reverse(plannedsession_teamedit_view,
|
||||
kwargs = {
|
||||
'sessionid':sessionid,
|
||||
'timeperiod':timeperiod,
|
||||
})
|
||||
return HttpResponseRedirect(url)
|
||||
else:
|
||||
sessioncreateform = PlannedSessionForm(instance=ps)
|
||||
sessionteamselectform = PlannedSessionTeamForm(
|
||||
request.user
|
||||
)
|
||||
sessionteamselectform.fields['team'].initial = teaminitial
|
||||
sessionrowerform = PlannedSessionTeamMemberForm(
|
||||
ps
|
||||
)
|
||||
|
||||
|
||||
sessionrowerform.fields['members'].initial = ps.rower.all()
|
||||
|
||||
return render(request,'plannedsessionteamedit.html',
|
||||
{
|
||||
'plannedsession':ps,
|
||||
'teams':get_my_teams(request.user),
|
||||
'form':sessioncreateform,
|
||||
'teamform':sessionteamselectform,
|
||||
'rowersform':sessionrowerform,
|
||||
'timeperiod':timeperiod,
|
||||
'plannedsessions':sps,
|
||||
})
|
||||
|
||||
|
||||
@login_required()
|
||||
def plannedsessions_view(request,timeperiod='thisweek',rowerid=0):
|
||||
|
||||
@@ -11811,6 +12044,11 @@ def plannedsessions_view(request,timeperiod='thisweek',rowerid=0):
|
||||
else:
|
||||
completiondate[ps.id] = ''
|
||||
|
||||
unmatchedworkouts = Workout.objects.filter(
|
||||
user=r,
|
||||
plannedsession=None,
|
||||
date__gte=startdate,date__lte=enddate)
|
||||
|
||||
return render(request,'plannedsessions.html',
|
||||
{
|
||||
'teams':get_my_teams(request.user),
|
||||
@@ -11820,6 +12058,7 @@ def plannedsessions_view(request,timeperiod='thisweek',rowerid=0):
|
||||
'completeness':completeness,
|
||||
'actualvalue':actualvalue,
|
||||
'completiondate':completiondate,
|
||||
'unmatchedworkouts':unmatchedworkouts,
|
||||
})
|
||||
|
||||
@login_required()
|
||||
@@ -11896,6 +12135,9 @@ def plannedsessions_manage_view(request,timeperiod='thisweek',rowerid=0,
|
||||
else:
|
||||
selectedworkouts = []
|
||||
|
||||
if len(selectedworkouts)==0:
|
||||
for w in ws:
|
||||
remove_workout_plannedsession(w,ps)
|
||||
|
||||
if selectedworkouts:
|
||||
workouts = Workout.objects.filter(user=r,id__in=selectedworkouts)
|
||||
@@ -11967,15 +12209,23 @@ def plannedsession_clone_view(request,id=0,rowerid=0,
|
||||
if ps.manager != request.user:
|
||||
raise Http404("You are not allowed to clone this planned session")
|
||||
|
||||
rowers = ps.rower.all()
|
||||
teams = ps.team.all()
|
||||
|
||||
ps.pk = None
|
||||
|
||||
deltadays = ps.enddate-ps.startdate
|
||||
|
||||
ps.startdate = timezone.now()
|
||||
ps.enddate = timezone.now()
|
||||
ps.enddate = timezone.now()+deltadays
|
||||
ps.name += ' (copy)'
|
||||
|
||||
ps.save()
|
||||
|
||||
add_rower_session(r,ps)
|
||||
for rower in rowers:
|
||||
add_rower_session(rower,ps)
|
||||
for team in teams:
|
||||
add_team_session(team,ps)
|
||||
|
||||
url = reverse(plannedsession_edit_view,
|
||||
kwargs = {
|
||||
@@ -12014,6 +12264,14 @@ def plannedsession_edit_view(request,id=0,timeperiod='thisweek',rowerid=0):
|
||||
if ps.manager != request.user:
|
||||
raise Http404("You are not allowed to edit this planned session")
|
||||
|
||||
if ps.team.all() or len(ps.rower.all())>1:
|
||||
url = reverse(plannedsession_teamedit_view,
|
||||
kwargs={
|
||||
'timeperiod':timeperiod,
|
||||
'sessionid':id,
|
||||
})
|
||||
return HttpResponseRedirect(url)
|
||||
|
||||
if request.method == 'POST':
|
||||
sessioncreateform = PlannedSessionForm(request.POST,instance=ps)
|
||||
if sessioncreateform.is_valid():
|
||||
|
||||
+11
-3
@@ -1,6 +1,6 @@
|
||||
{% load leaflet_tags %}
|
||||
{% load cookielaw_tags %}
|
||||
|
||||
{% load rowerfilters %}
|
||||
{% load tz_detect %}
|
||||
{% tz_detect %}
|
||||
{% load analytical %}
|
||||
@@ -101,7 +101,7 @@
|
||||
</div>
|
||||
<div class="grid_12">
|
||||
<div id="logo" class="grid_6 alpha">
|
||||
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
|
||||
{% if user|is_promember %}
|
||||
<p><a href="/"><img src="/static/img/logo7.png"
|
||||
alt="Rowsandall logo" height="80"></a></p>
|
||||
{% else %}
|
||||
@@ -157,7 +157,10 @@
|
||||
{% if user.rower.rowerplan == 'pro' or user.rower.rowerplan == 'coach' %}
|
||||
<h6 class="graytext">Pro Member</h6>
|
||||
{% else %}
|
||||
<div class="grid_1"><a class="button green small" href="/rowers/promembership">Upgrade to Pro</a></div>
|
||||
<div class="grid_1"><p><a class="button green small" href="/rowers/promembership">Upgrade to Pro</a></p></div>
|
||||
{% endif %}
|
||||
{% if user.rower.rowerplan == 'basic' and user.rower.protrialexpires|date_dif == 1 %}
|
||||
<div class="grid_1"><p><a class="button green small" href="/rowers/promembership">Start Free Pro trial</a></p></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -238,6 +241,11 @@
|
||||
{{ WARNING_MESSAGE }}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if user.rower.protrialexpires and user.rower.protrialexpires|is_future_date %}
|
||||
<p class="successmessage">
|
||||
{{ user.rower.protrialexpires|date_dif|ddays }} days left in Pro trial
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
{% if message.level == DEFAULT_MESSAGE_LEVELS.ERROR %}
|
||||
|
||||
Reference in New Issue
Block a user