Private
Public Access
1
0

edit and create team sessions

This commit is contained in:
Sander Roosendaal
2018-02-09 16:40:47 +01:00
parent c22740002c
commit cd134a40fd
12 changed files with 612 additions and 23 deletions

View File

@@ -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()

View File

@@ -523,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()

View File

@@ -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)

View File

@@ -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>

View File

@@ -39,15 +39,10 @@
</div>
</div>
{% if user.is_authenticated and user|is_manager %}
<div class="grid_2 dropdown">
<button class="grid_2 alpha button green small dropbtn">
Change Rower
</button>
<div class="dropdown-content">
{% for member in user|team_rowers %}
<a class="button green small" href="/rowers/sessions/create/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
<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>

View File

@@ -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>

View File

@@ -60,8 +60,8 @@
<a class="button green small" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ member.id }}">{{ member.user.first_name }} {{ member.user.last_name }}</a>
{% endfor %}
</div>
{% endif %}
</div>
{% endif %}
</div>
<div class="grid_12 alpha">
<p>Select one session on the left, and one or more workouts on the right
@@ -92,8 +92,6 @@
{% csrf_token %}
<input class="button green" type="submit" value="Submit">
</div>
</form>
</form>

View File

@@ -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>&nbsp;</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 %}

View File

@@ -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>&nbsp;</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 %}

View File

@@ -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 %}
&nbsp;
{% endif %}
</div>

View File

@@ -398,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),

View File

@@ -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
@@ -11809,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):
@@ -11841,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),
@@ -11850,6 +12058,7 @@ def plannedsessions_view(request,timeperiod='thisweek',rowerid=0):
'completeness':completeness,
'actualvalue':actualvalue,
'completiondate':completiondate,
'unmatchedworkouts':unmatchedworkouts,
})
@login_required()
@@ -11926,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)
@@ -11997,6 +12209,9 @@ 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
@@ -12007,7 +12222,10 @@ def plannedsession_clone_view(request,id=0,rowerid=0,
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 = {
@@ -12046,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():