attach workouts to sessions version 0
This commit is contained in:
@@ -602,3 +602,29 @@ class FusionMetricChoiceForm(ModelForm):
|
|||||||
metricchoices = list(sorted(formaxlabels2.items(), key = lambda x:x[1]))
|
metricchoices = list(sorted(formaxlabels2.items(), key = lambda x:x[1]))
|
||||||
self.fields['columns'].choices = metricchoices
|
self.fields['columns'].choices = metricchoices
|
||||||
|
|
||||||
|
class PlannedSessionSelectForm(forms.Form):
|
||||||
|
|
||||||
|
def __init__(self, sessionchoices, *args, **kwargs):
|
||||||
|
|
||||||
|
super(PlannedSessionSelectForm, self).__init__(*args,**kwargs)
|
||||||
|
|
||||||
|
self.fields['plannedsession'] = forms.ChoiceField(
|
||||||
|
label='Sessions',
|
||||||
|
choices = sessionchoices,
|
||||||
|
widget = forms.RadioSelect,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class WorkoutSessionSelectForm(forms.Form):
|
||||||
|
|
||||||
|
def __init__(self, workoutdata, *args, **kwargs):
|
||||||
|
|
||||||
|
super(WorkoutSessionSelectForm, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
self.fields['workouts'] = forms.MultipleChoiceField(
|
||||||
|
label='Workouts',
|
||||||
|
choices = workoutdata['choices'],
|
||||||
|
initial=workoutdata['initial'],
|
||||||
|
widget = forms.CheckboxSelectMultiple,
|
||||||
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -855,10 +855,6 @@ class PlannedSession(models.Model):
|
|||||||
choices=verificationchoices
|
choices=verificationchoices
|
||||||
)
|
)
|
||||||
|
|
||||||
# 0 = incomplete, 1 = complete, >1 = partial (details could
|
|
||||||
# be defined later)
|
|
||||||
sessioncompleted = models.IntegerField(default=0)
|
|
||||||
|
|
||||||
team = models.ManyToManyField(Team,blank=True)
|
team = models.ManyToManyField(Team,blank=True)
|
||||||
rower = models.ManyToManyField(Rower,blank=True)
|
rower = models.ManyToManyField(Rower,blank=True)
|
||||||
|
|
||||||
|
|||||||
@@ -26,14 +26,28 @@ import numpy as np
|
|||||||
import dataprep
|
import dataprep
|
||||||
|
|
||||||
# Low Level functions - to be called by higher level methods
|
# Low Level functions - to be called by higher level methods
|
||||||
|
|
||||||
# dummies for now
|
|
||||||
def add_workouts_plannedsession(ws,ps):
|
def add_workouts_plannedsession(ws,ps):
|
||||||
for w in ws:
|
result = 0
|
||||||
w.plannedsession = ps
|
comments = []
|
||||||
w.save()
|
errors = []
|
||||||
|
|
||||||
return 1
|
# check if all sessions have same date
|
||||||
|
dates = [w.date for w in ws]
|
||||||
|
if (not all(d == dates[0] for d in dates)) and ps.sessiontype != 'challenge':
|
||||||
|
errors.append('For tests and training sessions, selected workouts must all be done on the same date')
|
||||||
|
return result,comments,errors
|
||||||
|
|
||||||
|
# start adding sessions
|
||||||
|
for w in ws:
|
||||||
|
if w.date>=ps.startdate and w.date<=ps.enddate:
|
||||||
|
w.plannedsession = ps
|
||||||
|
w.save()
|
||||||
|
result += 1
|
||||||
|
comments.append('Attached workout %i to session' % w.id)
|
||||||
|
else:
|
||||||
|
errors.append('Workout %i did not match session dates' % w.id)
|
||||||
|
|
||||||
|
return result,comments,errors
|
||||||
|
|
||||||
|
|
||||||
def remove_workout_plannedsession(w,ps):
|
def remove_workout_plannedsession(w,ps):
|
||||||
@@ -57,8 +71,20 @@ def timefield_to_seconds_duration(t):
|
|||||||
|
|
||||||
return duration
|
return duration
|
||||||
|
|
||||||
def is_session_complete(ps):
|
def is_session_complete(r,ps):
|
||||||
ws = Workout.objects.filter(plannedsession=ps)
|
status = 'not done'
|
||||||
|
|
||||||
|
ws = Workout.objects.filter(user=r,plannedsession=ps)
|
||||||
|
|
||||||
|
if len(ws)==0:
|
||||||
|
today = date.today()
|
||||||
|
if today > ps.enddate:
|
||||||
|
status = 'missed'
|
||||||
|
ratio = 0
|
||||||
|
return ratio,status
|
||||||
|
else:
|
||||||
|
return 0,'not done'
|
||||||
|
|
||||||
score = 0
|
score = 0
|
||||||
for w in ws:
|
for w in ws:
|
||||||
if ps.sessionmode == 'distance':
|
if ps.sessionmode == 'distance':
|
||||||
@@ -73,12 +99,55 @@ def is_session_complete(ps):
|
|||||||
rscore = dataprep.workout_rscore(w)
|
rscore = dataprep.workout_rscore(w)
|
||||||
score += rscore
|
score += rscore
|
||||||
|
|
||||||
ratio = score/float(ps.value)
|
value = ps.sessionvalue
|
||||||
|
if ps.sessionunit == 'min':
|
||||||
|
value *= 60.
|
||||||
|
elif ps.sessionunit == 'km':
|
||||||
|
value *= 1000.
|
||||||
|
|
||||||
if ratio>0.8 and ratio<1.2:
|
print score,value,ps.sessionvalue,ps.sessionunit
|
||||||
return True
|
|
||||||
|
|
||||||
return False
|
ratio = score/float(value)
|
||||||
|
|
||||||
|
status = 'partial'
|
||||||
|
|
||||||
|
if ps.sessiontype == 'training':
|
||||||
|
if ps.sessioncriterium == 'exact':
|
||||||
|
if ratio == 1.0:
|
||||||
|
return ratio,'completed'
|
||||||
|
else:
|
||||||
|
return ratio,'partial'
|
||||||
|
elif ps.sessioncriterium == 'minimum':
|
||||||
|
if ratio > 1.0:
|
||||||
|
return ratio,'completed'
|
||||||
|
else:
|
||||||
|
return ratio,'partial'
|
||||||
|
else:
|
||||||
|
if ratio>0.8 and ratio<1.2:
|
||||||
|
return ratio,'completed'
|
||||||
|
else:
|
||||||
|
return ratio,'partial'
|
||||||
|
elif ps.sessiontype == 'test':
|
||||||
|
if ratio==1.0:
|
||||||
|
return ratio,'completed'
|
||||||
|
else:
|
||||||
|
return ratio,'partial'
|
||||||
|
elif ps.sessiontype == 'challenge':
|
||||||
|
if ps.sessioncriterium == 'exact':
|
||||||
|
if ratio == 1.0:
|
||||||
|
return ratio,'completed'
|
||||||
|
else:
|
||||||
|
return ratio,'partial'
|
||||||
|
elif ps.sessioncriterium == 'minimum':
|
||||||
|
if ratio > 1.0:
|
||||||
|
return ratio,'completed'
|
||||||
|
else:
|
||||||
|
return ratio,'partial'
|
||||||
|
else:
|
||||||
|
return ratio,'partial'
|
||||||
|
|
||||||
|
else:
|
||||||
|
return ratio,status
|
||||||
|
|
||||||
def rank_results(ps):
|
def rank_results(ps):
|
||||||
return 1
|
return 1
|
||||||
@@ -105,17 +174,58 @@ def remove_rower_session(r,ps):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def get_dates_timeperiod(timeperiod):
|
||||||
|
# set start end date according timeperiod
|
||||||
|
if timeperiod=='today':
|
||||||
|
startdate=date.today()
|
||||||
|
enddate=date.today()
|
||||||
|
elif timeperiod=='tomorrow':
|
||||||
|
startdate=date.today()+timezone.timedelta(days=1)
|
||||||
|
enddate=date.today()+timezone.timedelta(days=1)
|
||||||
|
elif timeperiod=='thisweek':
|
||||||
|
today = date.today()
|
||||||
|
startdate = date.today()-timezone.timedelta(days=today.weekday())
|
||||||
|
enddate = startdate+timezone.timedelta(days=6)
|
||||||
|
elif timeperiod=='thismonth':
|
||||||
|
today = date.today()
|
||||||
|
startdate = today.replace(day=1)
|
||||||
|
enddate = startdate+timezone.timedelta(days=32)
|
||||||
|
enddate = enddate.replace(day=1)
|
||||||
|
enddate = enddate-timezone.timedelta(days=1)
|
||||||
|
elif timeperiod=='lastweek':
|
||||||
|
today = date.today()
|
||||||
|
enddate = today-timezone.timedelta(days=today.weekday())-timezone.timedelta(days=1)
|
||||||
|
startdate = enddate-timezone.timedelta(days=6)
|
||||||
|
elif timeperiod=='lastmonth':
|
||||||
|
today = date.today()
|
||||||
|
startdate = today.replace(day=1)
|
||||||
|
startdate = startdate-timezone.timedelta(days=3)
|
||||||
|
startdate = startdate.replace(day=1)
|
||||||
|
enddate = startdate+timezone.timedelta(days=32)
|
||||||
|
enddate = enddate.replace(day=1)
|
||||||
|
enddate = enddate-timezone.timedelta(days=1)
|
||||||
|
else:
|
||||||
|
startdate = date.today()
|
||||||
|
enddate = date.today()
|
||||||
|
|
||||||
|
return startdate,enddate
|
||||||
|
|
||||||
def get_sessions(r,startdate=date.today(),
|
def get_sessions(r,startdate=date.today(),
|
||||||
enddate=date.today()+timezone.timedelta(+1000)):
|
enddate=date.today()+timezone.timedelta(+1000)):
|
||||||
|
|
||||||
sps = PlannedSession.objects.filter(
|
sps = PlannedSession.objects.filter(
|
||||||
rower__in=[r],
|
rower__in=[r],
|
||||||
startdate__gte=startdate,
|
startdate__lte=enddate,
|
||||||
enddate__lte=enddate,
|
enddate__gte=startdate,
|
||||||
).order_by("startdate","enddate")
|
).order_by("startdate","enddate")
|
||||||
|
|
||||||
return sps
|
return sps
|
||||||
|
|
||||||
|
def get_workouts_session(r,ps):
|
||||||
|
ws = Workout.objects.filter(user=r,plannedsession=ps)
|
||||||
|
|
||||||
|
return ws
|
||||||
|
|
||||||
def update_plannedsession(ps,cd):
|
def update_plannedsession(ps,cd):
|
||||||
for attr, value in cd.items():
|
for attr, value in cd.items():
|
||||||
setattr(ps, attr, value)
|
setattr(ps, attr, value)
|
||||||
|
|||||||
1
rowers/templates/.#list_workouts.html
Normal file
1
rowers/templates/.#list_workouts.html
Normal file
@@ -0,0 +1 @@
|
|||||||
|
e408191@CZ27LT9RCGN72.19768:1517816528
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<p>
|
<p>
|
||||||
Click on session name to view
|
Click on session name to view
|
||||||
</p>
|
</p>
|
||||||
<table class="listtable shortpadded">
|
<table class="listtable shortpadded" width="80%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>After</th>
|
<th>After</th>
|
||||||
|
|||||||
@@ -21,7 +21,10 @@
|
|||||||
{{ form.as_table }}
|
{{ form.as_table }}
|
||||||
</table>
|
</table>
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div id="formbutton" class="grid_1 prefix_4 suffix_1">
|
<div class="grid_1 prefix_3 alpha">
|
||||||
|
<a class="red button small" href="/rowers/sessions/{{ thesession.id }}/deleteconfirm">Delete</a>
|
||||||
|
</div>
|
||||||
|
<div id="formbutton" class="grid_1 suffix_1 omega">
|
||||||
<input class="button green" type="submit" value="Submit">
|
<input class="button green" type="submit" value="Submit">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,7 +33,7 @@
|
|||||||
<p>
|
<p>
|
||||||
Click on session name to view
|
Click on session name to view
|
||||||
</p>
|
</p>
|
||||||
<table class="listtable shortpadded">
|
<table class="listtable shortpadded" width="80%">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>After</th>
|
<th>After</th>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
{% block title %}Planned Sessions{% endblock %}
|
{% block title %}Planned Sessions{% endblock %}
|
||||||
|
|
||||||
@@ -36,8 +37,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid_12 alpha">
|
<div class="grid_12 alpha">
|
||||||
|
{% if plannedsessions %}
|
||||||
<p>
|
<p>
|
||||||
Click on session name to view
|
Click on session name to view, edit to change the session and on the
|
||||||
|
traffic light symbol to add workouts to the session
|
||||||
</p>
|
</p>
|
||||||
<table width="80%" class="listtable shortpadded">
|
<table width="80%" class="listtable shortpadded">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -45,10 +48,11 @@
|
|||||||
<th>After</th>
|
<th>After</th>
|
||||||
<th>Before</th>
|
<th>Before</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
|
<th>Edit</th>
|
||||||
<th>Value</th>
|
<th>Value</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
<th>Type</th>
|
<th>Type</th>
|
||||||
<th>Done</th>
|
<th>Status</th>
|
||||||
<th>
|
<th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@@ -66,13 +70,37 @@
|
|||||||
href="/rowers/sessions/{{ ps.id }}">Unnamed Session</a>
|
href="/rowers/sessions/{{ ps.id }}">Unnamed Session</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if ps.manager == request.user %}
|
||||||
|
<a class="small"
|
||||||
|
href="/rowers/sessions/{{ ps.id }}/edit">Edit</a>
|
||||||
|
{% else %}
|
||||||
|
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
<td> {{ ps.sessionvalue }} </td>
|
<td> {{ ps.sessionvalue }} </td>
|
||||||
<td> {{ ps.sessionunit }} </td>
|
<td> {{ ps.sessionunit }} </td>
|
||||||
<td> {{ ps.sessiontype }} </td>
|
<td> {{ ps.sessiontype }} </td>
|
||||||
|
<td>
|
||||||
|
{% if completeness|lookup:ps.id == 'not done' %}
|
||||||
|
<a class="white dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}"> </a>
|
||||||
|
{% elif completeness|lookup:ps.id == 'completed' %}
|
||||||
|
<a class="green dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}"> </a>
|
||||||
|
{% elif completeness|lookup:ps.id == 'partial' %}
|
||||||
|
<a class="orange dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}"> </a>
|
||||||
|
{% else %}
|
||||||
|
<a class="red dot" href="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}"> </a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
{% else %}
|
||||||
|
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 %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
74
rowers/templates/plannedsessionsmanage.html
Normal file
74
rowers/templates/plannedsessionsmanage.html
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block title %}Planned Sessions{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="grid_12 alpha">
|
||||||
|
{% include "planningbuttons.html" %}
|
||||||
|
</div>
|
||||||
|
<div class="grid_6 alpha">
|
||||||
|
<h1>Manage Plan Execution for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="timeperiod" class="grid_2 dropdown">
|
||||||
|
<button class="grid_2 alpha button gray small dropbtn">Time Period</button>
|
||||||
|
<div class="dropdown-content">
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/manage/today/rower/{{ rower.id }}">
|
||||||
|
Today
|
||||||
|
</a>
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/manage/thisweek/rower/{{ rower.id }}">
|
||||||
|
This Week
|
||||||
|
</a>
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/manage/thismonth/rower/{{ rower.id }}">
|
||||||
|
This Month
|
||||||
|
</a>
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/manage/lastweek/rower/{{ rower.id }}">
|
||||||
|
Last Week
|
||||||
|
</a>
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/manage/lastmonth/rower/{{ rower.id }}">
|
||||||
|
Last Month
|
||||||
|
</a>
|
||||||
|
</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,
|
||||||
|
the selected workouts must be done on the same date. For all sessions,
|
||||||
|
the workout dates must be between the start and end date for the
|
||||||
|
session.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you select a workout that has already been matched to another session,
|
||||||
|
it will change to match this session.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
We will make this form smarter in the near future.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<form id="session_form" action="/rowers/sessions/manage/{{ timeperiod }}/rower/{{ rower.id }}"
|
||||||
|
method="post">
|
||||||
|
<div class="grid_12 alpha">
|
||||||
|
<div class="grid_6 alpha">
|
||||||
|
{{ ps_form.as_table}}
|
||||||
|
</div>
|
||||||
|
<div class="grid_6 omega">
|
||||||
|
{{ w_form.as_table}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid_2 prefix_2 suffix_8">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input class="button green" type="submit" value="Submit">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
{% block title %}Planned Session{% endblock %}
|
{% block title %}Planned Session{% endblock %}
|
||||||
|
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="left" class="grid_6 alpha">
|
<div id="left" class="grid_6 alpha">
|
||||||
<h1>Session {{ psdict.name.1 }}</h1>
|
<h1>Session {{ psdict.name.1 }}</h1>
|
||||||
<table class="listtable shortpadded">
|
<table class="listtable shortpadded" width="80%">
|
||||||
{% for attr in attrs %}
|
{% for attr in attrs %}
|
||||||
{% for key,value in psdict.items %}
|
{% for key,value in psdict.items %}
|
||||||
{% if key == attr %}
|
{% if key == attr %}
|
||||||
@@ -21,9 +22,36 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
<h1>Result</h1>
|
||||||
|
<p>Status: {{ status }}</p>
|
||||||
|
<p>Percentage complete: {{ ratio }} </p>
|
||||||
</div>
|
</div>
|
||||||
<div id="right" class="grid_6 omega">
|
<div id="right" class="grid_6 omega">
|
||||||
<p> </p>
|
<h1>Workouts attached</h1>
|
||||||
|
<table class="listtable shortpadded" width="80%">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Date</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Distance</th>
|
||||||
|
<th>Duration</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for workout in workouts %}
|
||||||
|
<tr>
|
||||||
|
<td> {{ workout.date|date:"Y-m-d" }} </td>
|
||||||
|
<td>
|
||||||
|
<a href={% url manager.defaultlandingpage id=workout.id %}>
|
||||||
|
{{ workout.name }}
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td> {{ workout.distance }}m</td>
|
||||||
|
<td> {{ workout.duration |durationprint:"%H:%M:%S.%f" }} </td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
48
rowers/templates/plannedsssionsmanage.html
Normal file
48
rowers/templates/plannedsssionsmanage.html
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load rowerfilters %}
|
||||||
|
|
||||||
|
{% block title %}Planned Sessions{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="grid_12 alpha">
|
||||||
|
{% include "planningbuttons.html" %}
|
||||||
|
</div>
|
||||||
|
<div class="grid_6 alpha">
|
||||||
|
<h1>Plan for {{ rower.user.first_name }} {{ rower.user.last_name }}</h1>
|
||||||
|
</div>
|
||||||
|
<div id="timeperiod" class="grid_2 dropdown">
|
||||||
|
<button class="grid_2 alpha button gray small dropbtn">Time Period</button>
|
||||||
|
<div class="dropdown-content">
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/today/rower/{{ rower.id }}">
|
||||||
|
Today
|
||||||
|
</a>
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/thisweek/rower/{{ rower.id }}">
|
||||||
|
This Week
|
||||||
|
</a>
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/thismonth/rower/{{ rower.id }}">
|
||||||
|
This Month
|
||||||
|
</a>
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/lastweek/rower/{{ rower.id }}">
|
||||||
|
Last Week
|
||||||
|
</a>
|
||||||
|
<a class="button gray small alpha"
|
||||||
|
href="/rowers/sessions/lastmonth/rower/{{ rower.id }}">
|
||||||
|
Last Month
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid_12 alpha">
|
||||||
|
<p>
|
||||||
|
Click on session name to view
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
@@ -401,6 +401,14 @@ urlpatterns = [
|
|||||||
url(r'^sessions/(?P<id>\d+)$',views.plannedsession_view),
|
url(r'^sessions/(?P<id>\d+)$',views.plannedsession_view),
|
||||||
url(r'^sessions/(?P<id>\d+)/deleteconfirm$',views.plannedsession_deleteconfirm_view),
|
url(r'^sessions/(?P<id>\d+)/deleteconfirm$',views.plannedsession_deleteconfirm_view),
|
||||||
url(r'^sessions/(?P<id>\d+)/delete$',views.plannedsession_delete_view),
|
url(r'^sessions/(?P<id>\d+)/delete$',views.plannedsession_delete_view),
|
||||||
|
url(r'^sessions/manage/?$',
|
||||||
|
views.plannedsessions_manage_view),
|
||||||
|
url(r'^sessions/manage/rower/(?P<rowerid>\d+)$',
|
||||||
|
views.plannedsessions_manage_view),
|
||||||
|
url(r'^sessions/manage/(?P<timeperiod>[\w\ ]+.*)/rower/(?P<rowerid>\d+)$',
|
||||||
|
views.plannedsessions_manage_view),
|
||||||
|
url(r'^sessions/manage/(?P<timeperiod>[\w\ ]+.*)$',
|
||||||
|
views.plannedsessions_manage_view),
|
||||||
url(r'^sessions/?$',views.plannedsessions_view),
|
url(r'^sessions/?$',views.plannedsessions_view),
|
||||||
url(r'^sessions/rower/(?P<rowerid>\d+)$',views.plannedsessions_view),
|
url(r'^sessions/rower/(?P<rowerid>\d+)$',views.plannedsessions_view),
|
||||||
url(r'^sessions/(?P<timeperiod>[\w\ ]+.*)/rower/(?P<rowerid>\d+)$',views.plannedsessions_view),
|
url(r'^sessions/(?P<timeperiod>[\w\ ]+.*)/rower/(?P<rowerid>\d+)$',views.plannedsessions_view),
|
||||||
|
|||||||
159
rowers/views.py
159
rowers/views.py
@@ -30,7 +30,7 @@ from rowers.forms import (
|
|||||||
LoginForm,DocumentsForm,UploadOptionsForm,ImageForm,
|
LoginForm,DocumentsForm,UploadOptionsForm,ImageForm,
|
||||||
TeamUploadOptionsForm,WorkFlowLeftPanelForm,WorkFlowMiddlePanelForm,
|
TeamUploadOptionsForm,WorkFlowLeftPanelForm,WorkFlowMiddlePanelForm,
|
||||||
WorkFlowLeftPanelElement,WorkFlowMiddlePanelElement,
|
WorkFlowLeftPanelElement,WorkFlowMiddlePanelElement,
|
||||||
LandingPageForm,
|
LandingPageForm,PlannedSessionSelectForm,WorkoutSessionSelectForm
|
||||||
)
|
)
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
@@ -606,6 +606,7 @@ def rowhascoordinates(row):
|
|||||||
if rowdata != 0:
|
if rowdata != 0:
|
||||||
try:
|
try:
|
||||||
latitude = rowdata.df[' latitude']
|
latitude = rowdata.df[' latitude']
|
||||||
|
|
||||||
if not latitude.std():
|
if not latitude.std():
|
||||||
hascoordinates = 0
|
hascoordinates = 0
|
||||||
except KeyError,AttributeError:
|
except KeyError,AttributeError:
|
||||||
@@ -11765,46 +11766,108 @@ def plannedsessions_view(request,timeperiod='today',rowerid=0):
|
|||||||
if not checkaccessuser(request.user,r):
|
if not checkaccessuser(request.user,r):
|
||||||
raise Http404("You don't have access to this plan")
|
raise Http404("You don't have access to this plan")
|
||||||
|
|
||||||
# set start end date according timeperiod
|
startdate,enddate = get_dates_timeperiod(timeperiod)
|
||||||
if timeperiod=='today':
|
|
||||||
startdate=datetime.date.today()
|
|
||||||
enddate=datetime.date.today()
|
|
||||||
elif timeperiod=='tomorrow':
|
|
||||||
startdate=datetime.date.today()+timezone.timedelta(days=1)
|
|
||||||
enddate=datetime.date.today()+timezone.timedelta(days=1)
|
|
||||||
elif timeperiod=='thisweek':
|
|
||||||
today = datetime.date.today()
|
|
||||||
startdate = datetime.date.today()-timezone.timedelta(days=today.weekday())
|
|
||||||
enddate = startdate+timezone.timedelta(weeks=1)
|
|
||||||
elif timeperiod=='thismonth':
|
|
||||||
today = datetime.date.today()
|
|
||||||
startdate = today.replace(day=1)
|
|
||||||
enddate = startdate+timezone.timedelta(days=32)
|
|
||||||
enddate = enddate.replace(day=1)
|
|
||||||
elif timeperiod=='lastweek':
|
|
||||||
today = datetime.date.today()
|
|
||||||
enddate = today-timezone.timedelta(days=today.weekday())
|
|
||||||
startdate = enddate-timezone.timedelta(days=7)
|
|
||||||
elif timeperiod=='lastmonth':
|
|
||||||
today = datetime.date.today()
|
|
||||||
startdate = today.replace(day=1)
|
|
||||||
startdate = startdate-timezone.timedelta(days=3)
|
|
||||||
startdate = startdate.replace(day=1)
|
|
||||||
enddate = startdate+timezone.timedelta(days=32)
|
|
||||||
enddate = enddate.replace(day=1)
|
|
||||||
else:
|
|
||||||
startdate = datetime.date.today()
|
|
||||||
enddate = datetime.date.today()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
sps = get_sessions(r,startdate=startdate,enddate=enddate)
|
sps = get_sessions(r,startdate=startdate,enddate=enddate)
|
||||||
|
|
||||||
|
completeness = {}
|
||||||
|
|
||||||
|
for ps in sps:
|
||||||
|
ratio,status = is_session_complete(r,ps)
|
||||||
|
completeness[ps.id] = status
|
||||||
|
|
||||||
return render(request,'plannedsessions.html',
|
return render(request,'plannedsessions.html',
|
||||||
{
|
{
|
||||||
'teams':get_my_teams(request.user),
|
'teams':get_my_teams(request.user),
|
||||||
'plannedsessions':sps,
|
'plannedsessions':sps,
|
||||||
'rower':r,
|
'rower':r,
|
||||||
|
'timeperiod':timeperiod,
|
||||||
|
'completeness':completeness,
|
||||||
|
})
|
||||||
|
|
||||||
|
@login_required()
|
||||||
|
def plannedsessions_manage_view(request,timeperiod='today',rowerid=0):
|
||||||
|
|
||||||
|
if rowerid==0:
|
||||||
|
r = getrower(request.user)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
r = Rower.objects.get(id=rowerid)
|
||||||
|
except Rower.DoesNotExist:
|
||||||
|
raise Http404("This rower doesn't exist")
|
||||||
|
if not checkaccessuser(request.user,r):
|
||||||
|
raise Http404("You don't have access to this plan")
|
||||||
|
|
||||||
|
startdate,enddate = get_dates_timeperiod(timeperiod)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sps = get_sessions(r,startdate=startdate,enddate=enddate)
|
||||||
|
|
||||||
|
ws = Workout.objects.filter(
|
||||||
|
user=r,date__gte=startdate,
|
||||||
|
date__lte=enddate
|
||||||
|
).order_by(
|
||||||
|
"date","id"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
plannedsessionstuple = []
|
||||||
|
|
||||||
|
for ps in sps:
|
||||||
|
sessiontpl = (ps.id,ps.__unicode__())
|
||||||
|
plannedsessionstuple.append(sessiontpl)
|
||||||
|
|
||||||
|
plannedsessionstuple = tuple(plannedsessionstuple)
|
||||||
|
|
||||||
|
workoutdata = {}
|
||||||
|
workoutdata['initial'] = []
|
||||||
|
|
||||||
|
choices = []
|
||||||
|
|
||||||
|
for w in ws:
|
||||||
|
wtpl = (w.id, w.__unicode__())
|
||||||
|
choices.append(wtpl)
|
||||||
|
|
||||||
|
workoutdata['choices'] = tuple(choices)
|
||||||
|
|
||||||
|
if request.method == 'POST':
|
||||||
|
ps_form = PlannedSessionSelectForm(plannedsessionstuple,request.POST)
|
||||||
|
w_form = WorkoutSessionSelectForm(workoutdata,request.POST)
|
||||||
|
|
||||||
|
if ps_form.is_valid():
|
||||||
|
ps = PlannedSession.objects.get(id=ps_form.cleaned_data['plannedsession'])
|
||||||
|
if w_form.is_valid():
|
||||||
|
selectedworkouts = w_form.cleaned_data['workouts']
|
||||||
|
else:
|
||||||
|
selectedworkouts = []
|
||||||
|
|
||||||
|
|
||||||
|
if selectedworkouts:
|
||||||
|
workouts = Workout.objects.filter(user=r,id__in=selectedworkouts)
|
||||||
|
for w in ws:
|
||||||
|
if w.id not in selectedworkouts:
|
||||||
|
remove_workout_plannedsession(w,ps)
|
||||||
|
|
||||||
|
result,comments,errors = add_workouts_plannedsession(workouts,ps)
|
||||||
|
for c in comments:
|
||||||
|
messages.info(request,c)
|
||||||
|
for er in errors:
|
||||||
|
messages.error(request,er)
|
||||||
|
|
||||||
|
|
||||||
|
ps_form = PlannedSessionSelectForm(plannedsessionstuple)
|
||||||
|
w_form = WorkoutSessionSelectForm(workoutdata=workoutdata)
|
||||||
|
|
||||||
|
return render(request,'plannedsessionsmanage.html',
|
||||||
|
{
|
||||||
|
'teams':get_my_teams(request.user),
|
||||||
|
'plannedsessions':sps,
|
||||||
|
'workouts':ws,
|
||||||
|
'timeperiod':timeperiod,
|
||||||
|
'rower':r,
|
||||||
|
'ps_form':ps_form,
|
||||||
|
'w_form':w_form,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -11864,9 +11927,14 @@ def plannedsession_edit_view(request,id=0):
|
|||||||
|
|
||||||
|
|
||||||
@login_required()
|
@login_required()
|
||||||
def plannedsession_view(request,id=0):
|
def plannedsession_view(request,id=0,rowerid=0):
|
||||||
|
|
||||||
r = getrower(request.user)
|
m = getrower(request.user)
|
||||||
|
|
||||||
|
if not rowerid:
|
||||||
|
r = m
|
||||||
|
else:
|
||||||
|
r = Rower.objects.get(id=rowerid)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ps = PlannedSession.objects.get(id=id)
|
ps = PlannedSession.objects.get(id=id)
|
||||||
@@ -11880,12 +11948,26 @@ def plannedsession_view(request,id=0):
|
|||||||
|
|
||||||
psdict = my_dict_from_instance(ps,PlannedSession)
|
psdict = my_dict_from_instance(ps,PlannedSession)
|
||||||
|
|
||||||
|
ws = get_workouts_session(r,ps)
|
||||||
|
|
||||||
|
ratio,status = is_session_complete(r,ps)
|
||||||
|
|
||||||
|
print ratio
|
||||||
|
|
||||||
|
ratio = int(100.*ratio)
|
||||||
|
|
||||||
return render(request,'plannedsessionview.html',
|
return render(request,'plannedsessionview.html',
|
||||||
{
|
{
|
||||||
'psdict': psdict,
|
'psdict': psdict,
|
||||||
'attrs':[
|
'attrs':[
|
||||||
'name','startdate','enddate','sessiontype',
|
'name','startdate','enddate','sessiontype',
|
||||||
]
|
'sessionvalue','sessionunit'
|
||||||
|
],
|
||||||
|
'workouts': ws,
|
||||||
|
'manager':m,
|
||||||
|
'rower':r,
|
||||||
|
'ratio':ratio,
|
||||||
|
'status':status
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -11902,6 +11984,11 @@ def plannedsession_delete_view(request,id=0):
|
|||||||
if ps.manager != request.user:
|
if ps.manager != request.user:
|
||||||
raise Http404("You are not allowed to delete this planned session")
|
raise Http404("You are not allowed to delete this planned session")
|
||||||
|
|
||||||
|
ws = Workout.objects.filter(plannedsession=ps)
|
||||||
|
for w in ws:
|
||||||
|
w.plannedsession=None
|
||||||
|
w.save()
|
||||||
|
|
||||||
ps.delete()
|
ps.delete()
|
||||||
|
|
||||||
url = reverse(plannedsessions_view)
|
url = reverse(plannedsessions_view)
|
||||||
|
|||||||
@@ -291,6 +291,19 @@ th.rotate > div > span {
|
|||||||
border: solid 1px #333;
|
border: solid 1px #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dot {
|
||||||
|
border-radius: 50%;
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
border: solid 1px #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
font: 1.1em/1.5em sans-serif;
|
font: 1.1em/1.5em sans-serif;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|||||||
Reference in New Issue
Block a user