2750 lines
90 KiB
Python
2750 lines
90 KiB
Python
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
from __future__ import unicode_literals
|
|
|
|
from rowers.views.statements import *
|
|
|
|
@login_required()
|
|
def plannedsession_comment_view(request,id=0,userid=0):
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
try:
|
|
ps = PlannedSession.objects.get(id=id)
|
|
except PlannedSession.DoesNotExist:
|
|
raise Http404("Planned Session does not exist")
|
|
|
|
m = ps.manager
|
|
mm = Rower.objects.get(user=m)
|
|
|
|
if ps.manager != request.user and ps.sessiontype not in ['race','indoorrace']:
|
|
if r.rowerplan == 'coach' and r not in ps.rower.all():
|
|
teams = Team.objects.filter(manager=request.user)
|
|
members = Rower.objects.filter(team__in=teams).distinct()
|
|
teamusers = [m.user for m in members]
|
|
if ps.manager not in teamusers:
|
|
raise PermissionDenied("You do not have access to this session")
|
|
elif r not in ps.rower.all():
|
|
raise PermissionDenied("You do not have access to this session")
|
|
|
|
comments = PlannedSessionComment.objects.filter(plannedsession=ps).order_by("created")
|
|
|
|
if request.method == 'POST':
|
|
manager = ps.manager
|
|
form = PlannedSessionCommentForm(request.POST)
|
|
if form.is_valid():
|
|
cd = form.cleaned_data
|
|
comment = cd['comment']
|
|
comment = bleach.clean(comment)
|
|
try:
|
|
if isinstance(comment,unicode):
|
|
comment = comment.encode('utf8')
|
|
elif isinstance(comment, str):
|
|
comment = comment.decode('utf8')
|
|
except:
|
|
pass
|
|
|
|
notification = cd['notification']
|
|
c = PlannedSessionComment(plannedsession=ps,user=request.user,comment=comment,
|
|
notification=notification)
|
|
c.save()
|
|
url = reverse('plannedsession_comment_view',
|
|
kwargs={
|
|
'id':id
|
|
})
|
|
message = '{name} says: <a href="{url}">{comment}</a>'.format(
|
|
name = request.user.first_name,
|
|
comment = comment,
|
|
url = url,
|
|
)
|
|
if request.user != manager:
|
|
a_messages.info(r.user,message.encode('ascii','ignore'))
|
|
|
|
sessiontype = 'training session'
|
|
if ps.sessiontype == 'race':
|
|
sessiontype = 'online virtual race'
|
|
elif ps.sessiontype == 'indoorrace':
|
|
sessiontype = 'indoor online virtual race'
|
|
|
|
res = myqueue(queuehigh,
|
|
handle_sendemailnewcomment,r.user.first_name,
|
|
r.user.last_name,
|
|
r.user.email,
|
|
request.user.first_name,
|
|
request.user.last_name,
|
|
comment,ps.name,ps.id,
|
|
emailbounced = r.emailbounced,
|
|
sessiontype = sessiontype,
|
|
commentlink = url
|
|
)
|
|
|
|
commenters = {oc.user for oc in comments if oc.notification}
|
|
if ps.sessiontype=='race':
|
|
registrations = VirtualRaceResult.objects.filter(
|
|
race__id=ps.id,
|
|
emailnotifications=True)
|
|
ids = [rg.userid for rg in registrations]
|
|
rwrs = Rower.objects.filter(id__in= ids)
|
|
rowers = {u.user for u in rwrs}
|
|
elif ps.sessiontype=='indoorrace':
|
|
registrations = IndoorVirtualRaceResult.objects.filter(
|
|
race__id=ps.id,
|
|
emailnotifications=True)
|
|
ids = [rg.userid for rg in registrations]
|
|
rwrs = Rower.objects.filter(id__in= ids)
|
|
rowers = {u.user for u in rwrs}
|
|
else:
|
|
rowers = {r.user for r in ps.rower.all()}
|
|
commenters = set(list(commenters)+list(rowers))
|
|
for u in commenters:
|
|
a_messages.info(u,message)
|
|
if u != request.user and u != r.user:
|
|
ocr = Rower.objects.get(user=u)
|
|
res = myqueue(queuelow,
|
|
handle_sendemailnewresponse,
|
|
u.first_name,
|
|
u.last_name,
|
|
u.email,
|
|
request.user.first_name,
|
|
request.user.last_name,
|
|
comment,
|
|
ps.name,
|
|
ps.id,
|
|
c.id,
|
|
emailbounced = ocr.emailbounced,
|
|
sessiontype = sessiontype,
|
|
commentlink = url
|
|
)
|
|
|
|
url = reverse('plannedsession_comment_view',kwargs={'id':ps.id})
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
form = WorkoutCommentForm()
|
|
|
|
rower = getrower(request.user)
|
|
|
|
if ps.sessiontype in ['race','indoorrace']:
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse('virtualevents_view'),
|
|
'name': 'Races'
|
|
},
|
|
{
|
|
'url': reverse('virtualevent_view',kwargs={'id':ps.id}),
|
|
'name': ps.name
|
|
},
|
|
{
|
|
'url':reverse('plannedsession_comment_view',kwargs={'id':ps.id}),
|
|
'name': 'Comments'
|
|
}
|
|
]
|
|
|
|
active = 'nav-racing'
|
|
|
|
else:
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse('plannedsessions_view'),
|
|
'name': 'Sessions'
|
|
},
|
|
{
|
|
'url': reverse('plannedsession_view',kwargs={'id':ps.id}),
|
|
'name': ps.name
|
|
},
|
|
{
|
|
'url':reverse('plannedsession_comment_view',kwargs={'id':ps.id}),
|
|
'name': 'Comments'
|
|
}
|
|
]
|
|
|
|
active = 'nav-plan'
|
|
|
|
return render(request,
|
|
'plannedsession_comments.html',
|
|
{'plannedsession':ps,
|
|
'rower':rower,
|
|
'breadcrumbs':breadcrumbs,
|
|
'active':active,
|
|
'comments':comments,
|
|
'form':form,
|
|
})
|
|
|
|
# Cloning sessions
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def plannedsession_multiclone_view(
|
|
request,
|
|
userid=0,):
|
|
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
|
|
|
|
if request.method == 'POST' and 'daterange' in request.POST:
|
|
dateform = DateRangeForm(request.POST)
|
|
if dateform.is_valid():
|
|
startdate = dateform.cleaned_data['startdate']
|
|
enddate = dateform.cleaned_data['enddate']
|
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
|
request.session['startdate'] = startdatestring
|
|
request.session['enddate'] = enddatestring
|
|
else:
|
|
dateform = DateRangeForm(initial={
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
})
|
|
|
|
if request.method == 'POST' and 'plannedsessions' in request.POST:
|
|
form = PlannedSessionMultipleCloneForm(request.POST)
|
|
dateshiftform = SessionDateShiftForm(request.POST)
|
|
if form.is_valid() and dateshiftform.is_valid():
|
|
cd = form.cleaned_data
|
|
sps = cd['plannedsessions']
|
|
std = min([ps.startdate for ps in sps])
|
|
shiftstartdate = dateshiftform.cleaned_data['shiftstartdate']
|
|
delta = shiftstartdate-std
|
|
lastdate = shiftstartdate
|
|
for ps in sps:
|
|
rowers = ps.rower.all()
|
|
teams = ps.team.all()
|
|
ps.pk = None
|
|
ps.startdate += delta
|
|
ps.preferreddate += delta
|
|
ps.enddate += delta
|
|
if ps.enddate > lastdate:
|
|
lastdate = ps.enddate
|
|
ps.save()
|
|
for rower in rowers:
|
|
add_rower_session(rower,ps)
|
|
for team in teams:
|
|
add_team_session(team,ps)
|
|
|
|
startdatestring = shiftstartdate.strftime('%Y-%m-%d')
|
|
enddatestring = lastdate.strftime('%Y-%m-%d')
|
|
|
|
url = reverse(plannedsessions_view,
|
|
kwargs = {
|
|
'userid':r.user.id,
|
|
})
|
|
|
|
|
|
url+='?when='+startdatestring+'/'+enddatestring
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
sps = PlannedSession.objects.filter(
|
|
manager=request.user,
|
|
rower__in=[r],
|
|
startdate__lte=enddate,
|
|
enddate__gte=startdate).order_by(
|
|
"startdate","preferreddate","enddate").exclude(
|
|
sessiontype='race')
|
|
|
|
query = request.GET.get('q')
|
|
if query:
|
|
query_list = query.split()
|
|
sps = sps.filter(
|
|
reduce(operator.and_,
|
|
(Q(name__icontains=q) for q in query_list)) |
|
|
reduce(operator.and_,
|
|
(Q(comment__icontains=q) for q in query_list))
|
|
)
|
|
|
|
form = PlannedSessionMultipleCloneForm()
|
|
form.fields["plannedsessions"].queryset = sps
|
|
|
|
dateshiftform = SessionDateShiftForm()
|
|
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
breadcrumbs = [
|
|
{
|
|
'url': reverse(plannedsessions_view),
|
|
'name': 'Planned Sessions'
|
|
},
|
|
{
|
|
'url': reverse(plannedsession_multiclone_view),
|
|
'name': 'Clone Multiple Sessions'
|
|
}
|
|
]
|
|
|
|
dateform = DateRangeForm(initial={
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
})
|
|
|
|
return render(request, 'plannedsessions_multiclone_select.html',
|
|
{'plannedsessions':sps,
|
|
'breadcrumbs':breadcrumbs,
|
|
'plan':trainingplan,
|
|
'dateform':dateform,
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
'form':form,
|
|
'dateshiftform':dateshiftform,
|
|
'rower':r,
|
|
'active':'nav-plan',
|
|
'timeperiod':timeperiod,
|
|
}
|
|
)
|
|
|
|
# Individual user creates training for himself
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def plannedsession_create_view(request,
|
|
userid=0,
|
|
startdatestring='',
|
|
enddatestring=''):
|
|
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
|
|
|
|
startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring,
|
|
enddatestring=enddatestring)
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
sessioncreateform = PlannedSessionForm(request.POST)
|
|
if sessioncreateform.is_valid():
|
|
cd = sessioncreateform.cleaned_data
|
|
startdate = cd['startdate']
|
|
enddate = cd['enddate']
|
|
preferreddate = cd['preferreddate']
|
|
sessiontype = cd['sessiontype']
|
|
sessionmode = cd['sessionmode']
|
|
criterium = cd['criterium']
|
|
sessionvalue = cd['sessionvalue']
|
|
sessionunit = cd['sessionunit']
|
|
comment = cd['comment']
|
|
course = cd['course']
|
|
name = cd['name']
|
|
|
|
if sessionunit == 'min':
|
|
sessionmode = 'time'
|
|
elif sessionunit in ['km','m']:
|
|
sessionmode = 'distance'
|
|
|
|
ps = PlannedSession(
|
|
name=name,
|
|
startdate=startdate,
|
|
enddate=enddate,
|
|
preferreddate=preferreddate,
|
|
course=course,
|
|
sessiontype=sessiontype,
|
|
sessionmode=sessionmode,
|
|
sessionvalue=sessionvalue,
|
|
sessionunit=sessionunit,
|
|
comment=comment,
|
|
criterium=criterium,
|
|
manager=request.user)
|
|
|
|
ps.save()
|
|
|
|
add_rower_session(r,ps)
|
|
|
|
|
|
request.session['fstartdate'] = str(arrow.get(startdate))
|
|
request.session['fenddate'] = str(arrow.get(enddate))
|
|
request.session['fprefdate'] = str(arrow.get(preferreddate))
|
|
|
|
else:
|
|
if 'fstartdate' in request.session:
|
|
try:
|
|
fstartdate = arrow.get(request.session['fstartdate']).date()
|
|
except KeyError:
|
|
fstartdate = timezone.now().date()
|
|
if fstartdate < startdate:
|
|
fstartdate = startdate
|
|
try:
|
|
fenddate = arrow.get(request.session['fenddate']).date()
|
|
except KeyError:
|
|
fenddate = timezone.now().date()
|
|
if fenddate > enddate:
|
|
fenddate = enddate
|
|
try:
|
|
fprefdate = arrow.get(request.session['fprefdate']).date()
|
|
except KeyError:
|
|
fprefdate = timezone.now().date()
|
|
|
|
if fprefdate < startdate:
|
|
fprefdate = startdate
|
|
|
|
if fprefdate > enddate:
|
|
fprefdate = enddate
|
|
|
|
|
|
forminitial = {
|
|
'startdate':fstartdate,
|
|
'enddate':fenddate,
|
|
'preferreddate':fprefdate
|
|
}
|
|
else:
|
|
preferreddate = startdate
|
|
if preferreddate < timezone.now().date():
|
|
preferreddate = timezone.now().date()
|
|
|
|
if preferreddate > enddate:
|
|
preferreddate = enddate
|
|
|
|
forminitial = {
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
'preferreddate':preferreddate,
|
|
}
|
|
|
|
sessioncreateform = PlannedSessionForm(initial=forminitial)
|
|
|
|
if request.GET.get('startdate') or request.GET.get('when'):
|
|
startdate, enddate = get_dates_timeperiod(request)
|
|
|
|
sps = get_sessions(r,startdate=startdate,enddate=enddate).exclude(
|
|
sessiontype='race')
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
|
|
dateform = DateRangeForm(initial={
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
})
|
|
|
|
return render(request,'plannedsessioncreate.html',
|
|
{
|
|
'teams':get_my_teams(request.user),
|
|
'plan':trainingplan,
|
|
'dateform':dateform,
|
|
'form':sessioncreateform,
|
|
'active':'nav-plan',
|
|
'plannedsessions':sps,
|
|
'rower':r,
|
|
'timeperiod':timeperiod,
|
|
})
|
|
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def plannedsession_multicreate_view(request,
|
|
teamid=0,userid=0,extrasessions=0):
|
|
|
|
extrasessions=int(extrasessions)
|
|
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
m = Rower.objects.get(user=request.user)
|
|
|
|
qset = PlannedSession.objects.filter(
|
|
rower__in=[r],
|
|
manager = request.user,
|
|
startdate__lte=enddate,
|
|
enddate__gte=startdate,
|
|
).order_by("startdate","preferreddate","enddate").exclude(
|
|
sessiontype='race')
|
|
|
|
|
|
|
|
initial = {
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
'sessionvalue':60,
|
|
'manager':request.user,
|
|
'name': 'NEW SESSION'
|
|
}
|
|
|
|
|
|
|
|
initials = [initial for i in range(extrasessions)]
|
|
|
|
PlannedSessionFormSet = modelformset_factory(
|
|
PlannedSession,
|
|
form=PlannedSessionFormSmall,
|
|
can_delete=True,
|
|
extra=extrasessions,
|
|
)
|
|
if request.method == "POST":
|
|
ps_formset = PlannedSessionFormSet(queryset = qset,
|
|
data = request.POST)
|
|
if ps_formset.is_valid():
|
|
instances = ps_formset.save(commit=False)
|
|
for ps in instances:
|
|
ps.save()
|
|
add_rower_session(r,ps)
|
|
messages.info(request,"Saved changes for Planned Session "+str(ps))
|
|
for obj in ps_formset.deleted_objects:
|
|
messages.info(request,"Deleted Planned Session "+str(obj))
|
|
obj.delete()
|
|
|
|
url = reverse(plannedsession_multicreate_view,
|
|
kwargs = {
|
|
'userid':r.user.id,
|
|
}
|
|
)
|
|
|
|
|
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
|
url += '?when='+startdatestring+'/'+enddatestring
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
ps_formset = PlannedSessionFormSet(queryset = qset,
|
|
initial=initials)
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
breadcrumbs = [
|
|
{
|
|
'url': reverse(plannedsessions_view),
|
|
'name': 'Planned Sessions'
|
|
},
|
|
{
|
|
'url': reverse(plannedsession_multicreate_view),
|
|
'name': 'Plan MicroCycle'
|
|
}
|
|
]
|
|
|
|
dateform = DateRangeForm(initial={
|
|
'startdate':startdate,
|
|
'enddate':enddate
|
|
})
|
|
|
|
context = {
|
|
'ps_formset':ps_formset,
|
|
'breadcrumbs':breadcrumbs,
|
|
'rower':r,
|
|
'active':'nav-plan',
|
|
'dateform':dateform,
|
|
'plan':trainingplan,
|
|
'timeperiod':timeperiod,
|
|
'teams':get_my_teams(request.user),
|
|
'extrasessions': extrasessions+1
|
|
}
|
|
|
|
|
|
return render(request,'plannedsession_multicreate.html',context)
|
|
|
|
# Manager creates sessions for entire team
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def plannedsession_teamcreate_view(request,
|
|
teamid=0,userid=0):
|
|
|
|
therower = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
|
|
teams = Team.objects.filter(manager=request.user)
|
|
if len(teams)>0:
|
|
teamchoices = [(team.id, team.name) for team in teams]
|
|
teaminitial = [str(teams[0].id)]
|
|
else:
|
|
messages.info(request,"You have no teams established yet. We are redirecting you to the Team Management page.")
|
|
url = reverse('rower_teams_view')
|
|
return HttpResponseRedirect(url)
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
|
|
trainingplan = None
|
|
|
|
sps = []
|
|
for team in teams:
|
|
res = get_sessions_manager(request.user,startdate=startdate,enddate=enddate)
|
|
sps += res
|
|
|
|
sps = list(set(sps))
|
|
ids = [ps.id for ps in sps]
|
|
sps = PlannedSession.objects.filter(id__in=ids).order_by(
|
|
"preferreddate","startdate","enddate")
|
|
|
|
if request.method == 'POST':
|
|
sessioncreateform = PlannedSessionForm(request.POST)
|
|
sessionteamselectform = PlannedSessionTeamForm(
|
|
request.user,request.POST
|
|
)
|
|
|
|
if sessioncreateform.is_valid() and sessionteamselectform.is_valid():
|
|
cd = sessioncreateform.cleaned_data
|
|
startdate = cd['startdate']
|
|
enddate = cd['enddate']
|
|
preferreddate = cd['preferreddate']
|
|
sessiontype = cd['sessiontype']
|
|
sessionmode = cd['sessionmode']
|
|
criterium = cd['criterium']
|
|
sessionvalue = cd['sessionvalue']
|
|
sessionunit = cd['sessionunit']
|
|
comment = cd['comment']
|
|
course = cd['course']
|
|
name = cd['name']
|
|
|
|
if sessionunit == 'min':
|
|
sessionmode = 'time'
|
|
elif sessionunit in ['km','m']:
|
|
sessionmode = 'distance'
|
|
|
|
ps = PlannedSession(
|
|
name=name,
|
|
startdate=startdate,
|
|
enddate=enddate,
|
|
preferreddate=preferreddate,
|
|
sessiontype=sessiontype,
|
|
sessionmode=sessionmode,
|
|
sessionvalue=sessionvalue,
|
|
sessionunit=sessionunit,
|
|
comment=comment,
|
|
criterium=criterium,
|
|
course=course,
|
|
manager=request.user)
|
|
|
|
ps.save()
|
|
|
|
cd = sessionteamselectform.cleaned_data
|
|
teams = cd['team']
|
|
request.session['teams'] = [team.id for team in teams]
|
|
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)
|
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
|
url += '?when='+startdatestring+'/'+enddatestring
|
|
|
|
return HttpResponseRedirect(url)
|
|
else:
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
breadcrumbs = [
|
|
{
|
|
'url': reverse(plannedsessions_view),
|
|
'name': 'Planned Sessions'
|
|
},
|
|
{
|
|
'url': reverse(plannedsession_teamcreate_view),
|
|
'name': 'Add Team Session'
|
|
}
|
|
]
|
|
|
|
return render(request,'plannedsessionteamcreate.html',
|
|
{
|
|
'teams':get_my_teams(request.user),
|
|
'plan':trainingplan,
|
|
'breadcrumbs':breadcrumbs,
|
|
'form':sessioncreateform,
|
|
'teamform':sessionteamselectform,
|
|
'timeperiod':timeperiod,
|
|
'plannedsessions':sps,
|
|
'rower':therower,
|
|
'active':'nav-plan'
|
|
})
|
|
|
|
else:
|
|
initial = {
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
'preferreddate':startdate,
|
|
}
|
|
|
|
if 'teams' in request.session:
|
|
teams = request.session['teams']
|
|
theteams = Team.objects.filter(id__in=teams)
|
|
initialteam = {
|
|
'team':theteams
|
|
}
|
|
else:
|
|
initialteam = {}
|
|
|
|
sessioncreateform = PlannedSessionForm(initial=initial)
|
|
sessionteamselectform = PlannedSessionTeamForm(
|
|
request.user,initial=initialteam
|
|
)
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
breadcrumbs = [
|
|
{
|
|
'url': reverse(plannedsessions_view),
|
|
'name': 'Planned Sessions'
|
|
},
|
|
{
|
|
'url': reverse(plannedsession_teamcreate_view),
|
|
'name': 'Add Team Session'
|
|
}
|
|
]
|
|
|
|
dateform = DateRangeForm(initial={
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
})
|
|
|
|
return render(request,'plannedsessionteamcreate.html',
|
|
{
|
|
'teams':get_my_teams(request.user),
|
|
'plan':trainingplan,
|
|
'dateform':dateform,
|
|
'breadcrumbs':breadcrumbs,
|
|
'form':sessioncreateform,
|
|
'teamform':sessionteamselectform,
|
|
'timeperiod':timeperiod,
|
|
'plannedsessions':sps,
|
|
'rower':therower,
|
|
'active':'nav-plan'
|
|
})
|
|
|
|
# Manager edits sessions for entire team
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def plannedsession_teamedit_view(request,
|
|
sessionid=0,userid=0):
|
|
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
try:
|
|
ps = PlannedSession.objects.get(id=sessionid)
|
|
except PlannedSession.DoesNotExist:
|
|
raise Http404("This session doesn't exist")
|
|
if not ps.manager == request.user:
|
|
raise PermissionDenied("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(request)
|
|
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
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))
|
|
ids = [pps.id for pps in sps]
|
|
sps = PlannedSession.objects.filter(id__in=ids).order_by(
|
|
"preferreddate","startdate","enddate")
|
|
|
|
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 = []
|
|
for team in teams:
|
|
remove_team_session(team,ps)
|
|
|
|
|
|
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,
|
|
})
|
|
|
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
|
url += '?when='+startdatestring+'/'+enddatestring
|
|
|
|
|
|
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()
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
breadcrumbs = [
|
|
{
|
|
'url': reverse(plannedsessions_view),
|
|
'name': 'Planned Sessions'
|
|
},
|
|
{
|
|
'url': reverse(plannedsession_teamcreate_view),
|
|
'name': 'Add Team Session'
|
|
}
|
|
]
|
|
|
|
dateform = DateRangeForm(initial={
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
})
|
|
|
|
return render(request,'plannedsessionteamedit.html',
|
|
{
|
|
'plannedsession':ps,
|
|
'plan':trainingplan,
|
|
'dateform':dateform,
|
|
'breadcrumbs':breadcrumbs,
|
|
'rower':r,
|
|
'active':'nav-plan',
|
|
'teams':get_my_teams(request.user),
|
|
'form':sessioncreateform,
|
|
'teamform':sessionteamselectform,
|
|
'rowersform':sessionrowerform,
|
|
'timeperiod':timeperiod,
|
|
'plannedsessions':sps,
|
|
})
|
|
|
|
#@user_passes_test(iscoachmember,login_url="/rowers/paidplans/",
|
|
# redirect_field_name=None)
|
|
@login_required()
|
|
def plannedsessions_coach_view(request,
|
|
teamid=0,userid=0):
|
|
|
|
|
|
therower = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
|
|
|
|
trainingplan = None
|
|
|
|
if teamid != 0:
|
|
try:
|
|
theteam = Team.objects.get(id=teamid)
|
|
except Team.DoesNotExist:
|
|
theteam = False
|
|
else:
|
|
theteam = False
|
|
|
|
if request.user.rower.rowerplan == 'coach':
|
|
sps = get_sessions_manager(request.user,teamid=teamid,
|
|
enddate=enddate,
|
|
startdate=startdate)
|
|
else:
|
|
rteams = therower.team.filter(viewing='allmembers')
|
|
sps = get_sessions(therower,startdate=startdate,enddate=enddate)
|
|
|
|
rowers = [therower]
|
|
for ps in sps:
|
|
if request.user.rower.rowerplan == 'coach':
|
|
rowers += ps.rower.all()
|
|
else:
|
|
rowers += ps.rower.filter(team__in=rteams)
|
|
|
|
rowers = list(set(rowers))
|
|
|
|
statusdict = []
|
|
|
|
for ps in sps:
|
|
rowerstatus = {}
|
|
rowercolor = {}
|
|
for r in rowers:
|
|
ratio, status,completiondate = is_session_complete(r,ps)
|
|
rowerstatus[r.id] = status
|
|
rowercolor[r.id] = cratiocolors[status]
|
|
sessiondict = {
|
|
'id': ps.id,
|
|
'results':rowerstatus,
|
|
'name': ps.name,
|
|
'startdate': ps.startdate,
|
|
'color': rowercolor,
|
|
'preferreddate': ps.preferreddate,
|
|
'enddate': ps.enddate,
|
|
}
|
|
statusdict.append(sessiondict)
|
|
|
|
unmatchedworkouts = []
|
|
for r in rowers:
|
|
unmatchedworkouts += Workout.objects.filter(
|
|
user=r,
|
|
plannedsession=None,
|
|
date__gte=startdate,date__lte=enddate)
|
|
|
|
|
|
myteams = Team.objects.filter(manager=request.user)
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
breadcrumbs = [
|
|
{
|
|
'url': reverse(plannedsessions_view),
|
|
'name': 'Planned Sessions'
|
|
},
|
|
{
|
|
'url': reverse(plannedsessions_coach_view),
|
|
'name': 'Coach View'
|
|
}
|
|
]
|
|
|
|
dateform = DateRangeForm(initial={
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
})
|
|
|
|
return render(request,'plannedsessionscoach.html',
|
|
{
|
|
'myteams':myteams,
|
|
'plannedsessions':sps,
|
|
'breadcrumbs':breadcrumbs,
|
|
'plan':trainingplan,
|
|
'statusdict':statusdict,
|
|
'dateform':dateform,
|
|
'timeperiod':timeperiod,
|
|
'rowers':rowers,
|
|
'rower':therower,
|
|
'active':'nav-plan',
|
|
'theteam':theteam,
|
|
'unmatchedworkouts':unmatchedworkouts,
|
|
'rower':getrower(request.user)
|
|
}
|
|
)
|
|
|
|
from rowers.plannedsessions import cratiocolors
|
|
|
|
@login_required()
|
|
def plannedsessions_view(request,
|
|
userid=0,startdatestring='',enddatestring=''):
|
|
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
if startdatestring:
|
|
try:
|
|
startdate = iso8601.parse_date(startdatestring)
|
|
except ParseError:
|
|
pass
|
|
|
|
if enddatestring:
|
|
try:
|
|
enddate = iso8601.parse_date(enddatestring)
|
|
except ParseError:
|
|
pass
|
|
|
|
|
|
|
|
startdate,enddate = get_dates_timeperiod(
|
|
request,
|
|
startdatestring=startdatestring,
|
|
enddatestring=enddatestring)
|
|
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
|
|
sps = get_sessions(r,startdate=startdate,enddate=enddate)
|
|
|
|
completeness = {}
|
|
actualvalue = {}
|
|
completiondate = {}
|
|
sessioncolor = {}
|
|
|
|
totals = {
|
|
'trimp':0,
|
|
'rscore':0,
|
|
'distance':0,
|
|
'time':0,
|
|
'plannedtime':0,
|
|
'planneddistance':0,
|
|
'plannedtrimp':0,
|
|
'plannedrscore':0,
|
|
'actualtime':0,
|
|
'actualdistance':0,
|
|
'actualtrimp':0,
|
|
'actualrscore':0,
|
|
}
|
|
|
|
ws = Workout.objects.filter(
|
|
user=r,
|
|
date__gte=startdate,date__lte=enddate)
|
|
|
|
for w in ws:
|
|
thetrimp,hrtss = dataprep.workout_trimp(w)
|
|
totals['trimp'] += thetrimp
|
|
tss = dataprep.workout_rscore(w)[0]
|
|
if not np.isnan(tss) and tss != 0:
|
|
totals['rscore'] += tss
|
|
elif tss == 0:
|
|
totals['rscore'] += hrtss
|
|
tss = hrtss
|
|
totals['distance'] += w.distance
|
|
totals['time'] += timefield_to_seconds_duration(w.duration)
|
|
if w.plannedsession:
|
|
if w.plannedsession.sessionmode == 'distance':
|
|
totals['actualdistance'] += w.distance
|
|
elif w.plannedsession.sessionmode == 'time':
|
|
totals['actualtime'] += timefield_to_seconds_duration(w.duration)
|
|
elif w.plannedsession.sessionmode == 'rScore':
|
|
totals['actualrscore'] += tss
|
|
elif w.plannedsession.sessionmode == 'TRIMP':
|
|
totals['actualtrimp'] += thetrimp
|
|
|
|
if not sps and request.user.rower.rowerplan == 'basic':
|
|
messages.error(request,
|
|
"You must purchase Coach or Self-coach plans or be part of a team to get planned sessions")
|
|
|
|
for ps in sps:
|
|
ratio,status,cdate = is_session_complete(r,ps)
|
|
actualvalue[ps.id] = int(ps.sessionvalue*ratio)
|
|
completeness[ps.id] = status
|
|
sessioncolor[ps.id] = cratiocolors[status]
|
|
ws = Workout.objects.filter(user=r,plannedsession=ps)
|
|
completiondate[ps.id] = cdate
|
|
if ps.sessionmode == 'distance':
|
|
totals['planneddistance'] += ps.sessionvalue
|
|
elif ps.sessionmode == 'time':
|
|
totals['plannedtime'] += ps.sessionvalue
|
|
elif ps.sessionmode == 'rScore':
|
|
totals['plannedrscore'] += ps.sessionvalue
|
|
elif ps.sessionmode == 'TRIMP':
|
|
totals['plannedtrimp'] += ps.sessionvalue
|
|
|
|
totals['time'] = int(totals['time']/60.)
|
|
totals['actualtime'] = int(totals['actualtime']/60.)
|
|
totals['plannedtime'] = int(totals['plannedtime'])
|
|
|
|
unmatchedworkouts = Workout.objects.filter(
|
|
user=r,
|
|
plannedsession=None,
|
|
date__gte=startdate,date__lte=enddate)
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
breadcrumbs = [
|
|
{
|
|
'url': reverse(plannedsessions_view),
|
|
'name': 'Planned Sessions'
|
|
},
|
|
]
|
|
|
|
initial = {
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
}
|
|
|
|
dateform = DateRangeForm(initial=initial)
|
|
|
|
|
|
return render(request,'plannedsessions.html',
|
|
{
|
|
'teams':get_my_teams(request.user),
|
|
'breadcrumbs':breadcrumbs,
|
|
'plannedsessions':sps,
|
|
'plan':trainingplan,
|
|
'active': 'nav-plan',
|
|
'dateform':dateform,
|
|
'totals':totals,
|
|
'rower':r,
|
|
'timeperiod':timeperiod,
|
|
'completeness':completeness,
|
|
'sessioncolor':sessioncolor,
|
|
'actualvalue':actualvalue,
|
|
'completiondate':completiondate,
|
|
'unmatchedworkouts':unmatchedworkouts,
|
|
})
|
|
|
|
@login_required()
|
|
def plannedsessions_print_view(request,userid=0):
|
|
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
sps = get_sessions(r,startdate=startdate,enddate=enddate)
|
|
|
|
completeness = {}
|
|
actualvalue = {}
|
|
completiondate = {}
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
return render(request,'plannedsessions_print.html',
|
|
{
|
|
'teams':get_my_teams(request.user),
|
|
'plan':trainingplan,
|
|
'plannedsessions':sps,
|
|
'rower':r,
|
|
'active':'nav-plan',
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
'timeperiod':timeperiod,
|
|
})
|
|
|
|
|
|
@login_required()
|
|
def plannedsessions_manage_view(request,userid=0,
|
|
initialsession=0):
|
|
|
|
is_ajax = False
|
|
if request.is_ajax():
|
|
is_ajax = True
|
|
|
|
|
|
|
|
r = getrequestrower(request,userid=userid)
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
sps = get_sessions(r,startdate=startdate,enddate=enddate)
|
|
if initialsession==0:
|
|
try:
|
|
initialsession=sps[0].id
|
|
except IndexError:
|
|
initialsession=0
|
|
|
|
if initialsession:
|
|
try:
|
|
ps0 = PlannedSession.objects.get(id=initialsession)
|
|
except PlannedSession.DoesNotExist:
|
|
ps0 = None
|
|
else:
|
|
ps0 = None
|
|
|
|
ws = Workout.objects.filter(
|
|
user=r,date__gte=startdate,
|
|
date__lte=enddate
|
|
).order_by(
|
|
"date","startdatetime","id"
|
|
)
|
|
|
|
|
|
initialworkouts = [w.id for w in Workout.objects.filter(user=r,plannedsession=ps0)]
|
|
|
|
linkedworkouts = []
|
|
for w in ws:
|
|
if w.plannedsession is not None:
|
|
linkedworkouts.append(w.id)
|
|
|
|
plannedsessionstuple = []
|
|
|
|
for ps in sps:
|
|
sessiontpl = (ps.id,ps.__str__())
|
|
plannedsessionstuple.append(sessiontpl)
|
|
|
|
plannedsessionstuple = tuple(plannedsessionstuple)
|
|
|
|
workoutdata = {}
|
|
workoutdata['initial'] = []
|
|
|
|
choices = []
|
|
|
|
for w in ws:
|
|
wtpl = (w.id, w.__str__())
|
|
choices.append(wtpl)
|
|
if w.id in initialworkouts:
|
|
workoutdata['initial'].append(w.id)
|
|
|
|
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 len(selectedworkouts)==0:
|
|
for w in ws:
|
|
remove_workout_plannedsession(w,ps)
|
|
|
|
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,r)
|
|
for c in comments:
|
|
messages.info(request,c)
|
|
for er in errors:
|
|
messages.error(request,er)
|
|
|
|
|
|
ps_form = PlannedSessionSelectForm(plannedsessionstuple,
|
|
initialsession=initialsession)
|
|
w_form = WorkoutSessionSelectForm(workoutdata=workoutdata)
|
|
|
|
|
|
if is_ajax:
|
|
ajax_workouts = []
|
|
for id,name in workoutdata['choices']:
|
|
ininitial = id in initialworkouts
|
|
inlinked = id in linkedworkouts
|
|
ajax_workouts.append((id,name,ininitial,inlinked))
|
|
|
|
ajax_response = {
|
|
'workouts':ajax_workouts,
|
|
'plannedsessionstuple':plannedsessionstuple,
|
|
}
|
|
|
|
|
|
return JSONResponse(ajax_response)
|
|
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(plannedsessions_manage_view,
|
|
kwargs={
|
|
'userid':userid,
|
|
'initialsession':initialsession,
|
|
}
|
|
),
|
|
'name': 'Link Sessions to Workouts'
|
|
},
|
|
]
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
|
|
dateform = DateRangeForm(initial={
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
})
|
|
|
|
return render(request,'plannedsessionsmanage.html',
|
|
{
|
|
'teams':get_my_teams(request.user),
|
|
'plan':trainingplan,
|
|
'dateform':dateform,
|
|
'plannedsessions':sps,
|
|
'workouts':ws,
|
|
'active':'nav-plan',
|
|
'breadcrumbs':breadcrumbs,
|
|
'timeperiod':timeperiod,
|
|
'rower':r,
|
|
'ps_form':ps_form,
|
|
'w_form':w_form,
|
|
})
|
|
|
|
|
|
# Clone an existing planned session
|
|
# need clarity on cloning behavior time shift
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def plannedsession_clone_view(request,id=0,userid=0):
|
|
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
try:
|
|
ps = PlannedSession.objects.get(id=id)
|
|
except PlannedSession.DoesNotExist:
|
|
raise Http404("Planned Session does not exist")
|
|
|
|
if ps.manager != request.user:
|
|
raise PermissionDenied("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().date()
|
|
ps.enddate = (timezone.now()+deltadays).date()
|
|
ps.preferreddate = ps.preferreddate+deltadays
|
|
ps.name += ' (copy)'
|
|
|
|
ps.save()
|
|
|
|
for rower in rowers:
|
|
add_rower_session(rower,ps)
|
|
for team in teams:
|
|
add_team_session(team,ps)
|
|
|
|
url = reverse(plannedsession_edit_view,
|
|
kwargs = {
|
|
'id':ps.id,
|
|
'userid':r.user.id,
|
|
}
|
|
)
|
|
|
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
|
url += '?when='+startdatestring+'/'+enddatestring
|
|
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
# Edit an existing planned session
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans/",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def plannedsession_edit_view(request,id=0,userid=0):
|
|
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
|
|
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
try:
|
|
ps = PlannedSession.objects.get(id=id)
|
|
except PlannedSession.DoesNotExist:
|
|
raise Http404("Planned Session does not exist")
|
|
|
|
if ps.manager != request.user:
|
|
raise PermissionDenied("You are not allowed to edit this planned session")
|
|
|
|
if ps.sessiontype in ['race','indoorrace']:
|
|
raise PermissionDenied("You are not allowed to edit this planned session because it is a race")
|
|
|
|
if ps.team.all() or len(ps.rower.all())>1:
|
|
url = reverse(plannedsession_teamedit_view,
|
|
kwargs={
|
|
'sessionid':id,
|
|
})
|
|
return HttpResponseRedirect(url)
|
|
|
|
if request.method == 'POST':
|
|
sessioncreateform = PlannedSessionForm(request.POST,instance=ps)
|
|
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)
|
|
|
|
url = reverse(plannedsession_edit_view,
|
|
kwargs={
|
|
'id':int(ps.id),
|
|
'userid':r.user.id,
|
|
})
|
|
|
|
startdatestring = startdate.strftime('%Y-%m-%d')
|
|
enddatestring = enddate.strftime('%Y-%m-%d')
|
|
url += '?when='+startdatestring+'/'+enddatestring
|
|
|
|
return HttpResponseRedirect(url)
|
|
else:
|
|
sessioncreateform = PlannedSessionForm(instance=ps)
|
|
|
|
sps = get_sessions(r,startdate=startdate,enddate=enddate)
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url': reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Sessions'
|
|
},
|
|
{
|
|
'url':reverse(plannedsession_view,
|
|
kwargs={
|
|
'userid':userid,
|
|
'id':id,
|
|
}
|
|
),
|
|
'name': ps.id
|
|
},
|
|
{
|
|
'url':reverse(plannedsession_edit_view,
|
|
kwargs={
|
|
'userid':userid,
|
|
'id':id,
|
|
}
|
|
),
|
|
'name': 'Edit'
|
|
}
|
|
]
|
|
|
|
|
|
dateform = DateRangeForm(initial={
|
|
'startdate':startdate,
|
|
'enddate':enddate,
|
|
})
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
|
|
return render(request,'plannedsessionedit.html',
|
|
{
|
|
'teams':get_my_teams(request.user),
|
|
'plan':trainingplan,
|
|
'breadcrumbs':breadcrumbs,
|
|
'form':sessioncreateform,
|
|
'active':'nav-plan',
|
|
'plannedsessions':sps,
|
|
'thesession':ps,
|
|
'dateform':dateform,
|
|
'rower':r,
|
|
'timeperiod':timeperiod,
|
|
})
|
|
|
|
|
|
@login_required()
|
|
def plannedsession_detach_view(request,id=0,psid=0):
|
|
|
|
r = getrequestrower(request)
|
|
|
|
try:
|
|
ps = PlannedSession.objects.get(id=psid)
|
|
except PlannedSession.DoesNotExist:
|
|
raise Http404("Planned Session does not exist")
|
|
|
|
w = get_workout(id)
|
|
|
|
if (checkworkoutuser(request.user,w)==False):
|
|
return HttpResponseForbidden("Permission Error")
|
|
|
|
remove_workout_plannedsession(w,ps)
|
|
|
|
url = reverse(plannedsession_view,kwargs={'id':psid})
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
@login_required()
|
|
def plannedsession_view(request,id=0,userid=0):
|
|
|
|
r = getrequestplanrower(request,userid=userid)
|
|
|
|
|
|
|
|
try:
|
|
ps = PlannedSession.objects.get(id=id)
|
|
except PlannedSession.DoesNotExist:
|
|
raise Http404("Planned Session does not exist")
|
|
|
|
if ps.sessiontype in ['race','indoorrace']:
|
|
url = reverse('virtualevent_view',
|
|
kwargs={'id':ps.id}
|
|
)
|
|
return HttpResponseRedirect(url)
|
|
|
|
if ps.course:
|
|
coursescript,coursediv = course_map(ps.course)
|
|
else:
|
|
coursescript = ''
|
|
coursediv = ''
|
|
|
|
m = ps.manager
|
|
mm = Rower.objects.get(user=m)
|
|
|
|
if ps.manager != request.user:
|
|
if r.rowerplan == 'coach' and r not in ps.rower.all():
|
|
teams = Team.objects.filter(manager=request.user)
|
|
members = Rower.objects.filter(team__in=teams).distinct()
|
|
teamusers = [m.user for m in members]
|
|
if ps.manager not in teamusers:
|
|
raise PermissionDenied("You do not have access to this session")
|
|
elif r not in ps.rower.all():
|
|
raise PermissionDenied("You do not have access to this session")
|
|
|
|
resultsdict = get_session_metrics(ps)
|
|
resultsdict = pd.DataFrame(resultsdict).transpose().to_dict()
|
|
|
|
psdict = my_dict_from_instance(ps,PlannedSession)
|
|
|
|
ws = get_workouts_session(r,ps)
|
|
|
|
ratio,status,completiondate = is_session_complete(r,ps)
|
|
|
|
ratio = int(100.*ratio)
|
|
|
|
# ranking for test
|
|
ranking = []
|
|
|
|
if ps.sessiontype in ['test','coursetest']:
|
|
if ps.sessionmode == 'distance':
|
|
rankws = Workout.objects.filter(
|
|
plannedsession=ps).order_by("duration")
|
|
else:
|
|
rankws = Workout.objects.filter(
|
|
plannedsession=ps).order_by("-distance")
|
|
for w in rankws:
|
|
dd = w.duration
|
|
dddelta = datetime.timedelta(hours=dd.hour,
|
|
minutes=dd.minute,
|
|
seconds=dd.second,
|
|
microseconds=dd.microsecond)
|
|
wdict = {
|
|
'name': w.user.user.first_name+' '+w.user.user.last_name,
|
|
'date': w.date,
|
|
'distance': w.distance,
|
|
'time': dddelta,
|
|
'type': w.workouttype,
|
|
'coursecompleted':True,
|
|
}
|
|
if ps.sessiontype == 'coursetest':
|
|
vs = CourseTestResult.objects.filter(plannedsession=ps,
|
|
workoutid=w.id)
|
|
|
|
if vs:
|
|
for record in vs:
|
|
if record.workoutid == w.id:
|
|
coursemeters = record.distance
|
|
coursecompleted = record.coursecompleted
|
|
t = record.duration
|
|
wdict['time'] = datetime.timedelta(
|
|
hours=t.hour,
|
|
seconds=t.second,
|
|
minutes=t.minute,
|
|
microseconds=t.microsecond
|
|
)
|
|
wdict['distance'] = int(round(coursemeters))
|
|
wdict['coursecompleted'] = coursecompleted
|
|
else:
|
|
record = CourseTestResult(
|
|
userid=w.user.id,
|
|
workoutid=w.id,
|
|
plannedsession=ps,
|
|
duration=w.duration,
|
|
coursecompleted=False,
|
|
)
|
|
record.save()
|
|
job = myqueue(queue,handle_check_race_course,
|
|
w.csvfilename,w.id,ps.course.id,
|
|
record.id,mode='coursetest')
|
|
|
|
intsecs = 0
|
|
microsecs = 0
|
|
|
|
# taking workout duration plus 1 minute penalty
|
|
wdict['time'] = w.duration
|
|
wdict['distance'] = ps.course.distance
|
|
wdict['coursecompleted'] = False
|
|
|
|
|
|
ranking.append(wdict)
|
|
if ps.sessiontype == 'coursetest':
|
|
ranking = sorted(ranking, key=lambda k: k['time'])
|
|
|
|
# if coursetest, need to reorder the ranking
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
try:
|
|
trainingplan = TrainingPlan.objects.filter(
|
|
startdate__lte = startdate,
|
|
rowers = r,
|
|
enddate__gte = enddate)[0]
|
|
except IndexError:
|
|
trainingplan = None
|
|
|
|
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url': reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Sessions'
|
|
},
|
|
{
|
|
'url':reverse(plannedsession_view,
|
|
kwargs={
|
|
'userid':userid,
|
|
'id':id,
|
|
}
|
|
),
|
|
'name': ps.id
|
|
}
|
|
]
|
|
|
|
comments = PlannedSessionComment.objects.filter(plannedsession=ps).order_by("created")
|
|
|
|
return render(request,'plannedsessionview.html',
|
|
{
|
|
'psdict': psdict,
|
|
'attrs':[
|
|
'name','startdate','enddate','preferreddate',
|
|
'sessiontype',
|
|
'sessionmode','criterium',
|
|
'sessionvalue','sessionunit','comment',
|
|
],
|
|
'workouts': ws,
|
|
'active':'nav-plan',
|
|
'breadcrumbs':breadcrumbs,
|
|
'manager':mm,
|
|
'rower':r,
|
|
'ratio':ratio,
|
|
'plan':trainingplan,
|
|
'status':status,
|
|
'results':resultsdict,
|
|
'plannedsession':ps,
|
|
'timeperiod':timeperiod,
|
|
'ranking':ranking,
|
|
'coursescript': coursescript,
|
|
'coursediv': coursediv,
|
|
'comments': comments,
|
|
}
|
|
)
|
|
|
|
class PlannedSessionDelete(DeleteView):
|
|
model = PlannedSession
|
|
template_name = 'plannedsessiondeleteconfirm.html'
|
|
|
|
# extra parameters
|
|
def get_context_data(self, **kwargs):
|
|
context = super(PlannedSessionDelete,self).get_context_data(**kwargs)
|
|
|
|
if 'userid' in kwargs:
|
|
userid = kwargs['userid']
|
|
else:
|
|
userid = 0
|
|
|
|
context['active']= 'nav-plan'
|
|
context['rower'] = getrequestrower(self.request,userid=userid)
|
|
context['ps'] = self.object
|
|
|
|
psdict = my_dict_from_instance(self.object,PlannedSession)
|
|
|
|
context['psdict'] = psdict
|
|
|
|
context['attrs'] = ['name','startdate','enddate','sessiontype']
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url': reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Sessions'
|
|
},
|
|
{
|
|
'url':reverse(plannedsession_view,
|
|
kwargs={
|
|
'userid':userid,
|
|
'id':self.object.pk,
|
|
}
|
|
),
|
|
'name': self.object.pk
|
|
},
|
|
{
|
|
'url':reverse('plannedsession_delete_view',
|
|
kwargs={'pk':self.object.pk}),
|
|
'name': 'Delete'
|
|
}
|
|
]
|
|
|
|
context['breadcrumbs'] = breadcrumbs
|
|
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
ws = Workout.objects.filter(plannedsession=self.object)
|
|
for w in ws:
|
|
w.plannedsession = None
|
|
w.save()
|
|
|
|
url = reverse(plannedsessions_view)
|
|
|
|
return url
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(PlannedSessionDelete, self).get_object(*args, **kwargs)
|
|
m = Rower.objects.get(user=obj.manager)
|
|
if not checkaccessuser(self.request.user,m):
|
|
raise PermissionDenied('You are not allowed to delete this planned session')
|
|
|
|
return obj
|
|
|
|
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def rower_create_trainingplan(request,userid=0):
|
|
|
|
therower = getrequestrower(request,userid=userid)
|
|
theuser = therower.user
|
|
themanager = getrower(request.user)
|
|
|
|
if request.method == 'POST' and 'date' in request.POST:
|
|
targetform = TrainingTargetForm(request.POST,user=request.user)
|
|
if targetform.is_valid():
|
|
name = targetform.cleaned_data['name']
|
|
date = targetform.cleaned_data['date']
|
|
notes = targetform.cleaned_data['notes']
|
|
|
|
t = TrainingTarget(
|
|
name=name,
|
|
date=date,
|
|
manager=themanager,
|
|
notes=notes)
|
|
|
|
|
|
t.save()
|
|
t.rowers.add(therower)
|
|
t.save()
|
|
|
|
elif request.method == 'POST' and 'startdate' in request.POST:
|
|
form = TrainingPlanForm(request.POST,user=request.user)
|
|
|
|
|
|
if form.is_valid():
|
|
name = form.cleaned_data['name']
|
|
try:
|
|
target = form.cleaned_data['target']
|
|
except KeyError:
|
|
try:
|
|
targetid = request.POST['target']
|
|
if targetid != '':
|
|
target = TrainingTarget.objects.get(id=int(targetid))
|
|
else:
|
|
target = None
|
|
except KeyError:
|
|
target = None
|
|
startdate = form.cleaned_data['startdate']
|
|
enddate = form.cleaned_data['enddate']
|
|
|
|
try:
|
|
athletes = form.cleaned_data['rowers']
|
|
except KeyError:
|
|
athletes = [therower]
|
|
|
|
p = TrainingPlan(
|
|
name=name,
|
|
target=target,
|
|
manager=themanager,
|
|
startdate=startdate,
|
|
enddate=enddate,
|
|
)
|
|
|
|
p.save()
|
|
|
|
for athlete in athletes:
|
|
p.rowers.add(athlete)
|
|
|
|
|
|
targets = TrainingTarget.objects.filter(
|
|
rowers=therower,
|
|
date__gte=datetime.date.today(),
|
|
).order_by("date")
|
|
targetform = TrainingTargetForm(user=request.user)
|
|
|
|
plans = TrainingPlan.objects.filter(rowers=therower).order_by("-startdate")
|
|
|
|
|
|
form = TrainingPlanForm(targets=targets,
|
|
initial={'status':False,'rowers':[therower]},
|
|
user=request.user)
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(rower_create_trainingplan,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Manage Plans and Targets'
|
|
}
|
|
]
|
|
|
|
|
|
return render(request,'trainingplan_create.html',
|
|
{
|
|
'form':form,
|
|
'rower':therower,
|
|
'breadcrumbs':breadcrumbs,
|
|
'plans':plans,
|
|
'active':'nav-plan',
|
|
'targets':targets,
|
|
'targetform':targetform,
|
|
})
|
|
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def rower_delete_trainingtarget(request,id=0):
|
|
try:
|
|
target = TrainingTarget.objects.get(id=id)
|
|
except TrainingPlan.DoesNotExist:
|
|
raise Http404("Training Plan Does Not Exist")
|
|
|
|
if checkaccessuser(request.user,target.manager):
|
|
target.delete()
|
|
messages.info(request,"We have deleted the training target")
|
|
else:
|
|
raise PermissionDenied("Access denied")
|
|
|
|
url = reverse(rower_create_trainingplan)
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def rower_delete_trainingplan(request,id=0):
|
|
try:
|
|
plan = TrainingPlan.objects.get(id=id)
|
|
except TrainingPlan.DoesNotExist:
|
|
raise Http404("Training Plan Does Not Exist")
|
|
|
|
if checkaccessuser(request.user,plan.manager):
|
|
plan.delete()
|
|
messages.info(request,"We have deleted the training plan")
|
|
else:
|
|
raise PermissionDenied("Access denied")
|
|
|
|
url = reverse(rower_create_trainingplan)
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
class TrainingPlanDelete(DeleteView):
|
|
model = TrainingPlan
|
|
template_name = 'trainingplan_delete.html'
|
|
success_url = reverse_lazy(rower_create_trainingplan)
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs)
|
|
if not checkaccessuser(self.request.user,obj.manager):
|
|
raise PermissionDenied('You are not allowed to delete this training plan')
|
|
|
|
return obj
|
|
|
|
class MicroCycleDelete(DeleteView):
|
|
model = TrainingMicroCycle
|
|
template_name = 'trainingplan_delete.html'
|
|
|
|
# extra parameters
|
|
def get_context_data(self, **kwargs):
|
|
context = super(MicroCycleDelete, self).get_context_data(**kwargs)
|
|
|
|
if 'userid' in kwargs:
|
|
userid = kwargs['userid']
|
|
else:
|
|
userid=0
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(rower_trainingplan_view,
|
|
kwargs={'userid':userid,
|
|
'id':self.object.plan.plan.plan.id}),
|
|
'name': self.object.plan.plan.plan.name
|
|
},
|
|
{
|
|
'url':reverse('macrocycle_update_view',
|
|
kwargs={'pk':self.object.plan.plan.pk}),
|
|
'name': self.object.plan.plan.name
|
|
},
|
|
{
|
|
'url':reverse('mesocycle_update_view',
|
|
kwargs={'pk':self.object.plan.pk}),
|
|
'name': self.object.plan.name
|
|
},
|
|
{
|
|
'url':reverse('microcycle_update_view',
|
|
kwargs={'pk':self.object.pk}),
|
|
'name': self.object.name
|
|
}
|
|
|
|
]
|
|
|
|
context['active'] = 'nav-plan'
|
|
context['breadcrumbs'] = breadcrumbs
|
|
context['rower'] = getrequestrower(self.request,userid=userid)
|
|
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
plan = self.object.plan.plan.plan
|
|
createmacrofillers(plan)
|
|
thismesoid = self.object.plan.pk
|
|
return reverse(rower_trainingplan_view,
|
|
kwargs = {
|
|
'id':plan.id,
|
|
'thismesoid':thismesoid
|
|
})
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(MicroCycleDelete, self).get_object(*args, **kwargs)
|
|
if not checkaccessuser(self.request.user,obj.plan.plan.plan.manager):
|
|
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
|
return obj
|
|
|
|
|
|
class MesoCycleDelete(DeleteView):
|
|
model = TrainingMesoCycle
|
|
template_name = 'trainingplan_delete.html'
|
|
|
|
# extra parameters
|
|
def get_context_data(self, **kwargs):
|
|
context = super(MesoCycleDelete, self).get_context_data(**kwargs)
|
|
|
|
if 'userid' in kwargs:
|
|
userid = kwargs['userid']
|
|
else:
|
|
userid=0
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(rower_trainingplan_view,
|
|
kwargs={'userid':userid,
|
|
'id':self.object.plan.plan.id}),
|
|
'name': self.object.plan.plan.name
|
|
},
|
|
{
|
|
'url':reverse('macrocycle_update_view',
|
|
kwargs={'pk':self.object.plan.pk}),
|
|
'name': self.object.plan.name
|
|
},
|
|
{
|
|
'url':reverse('mesocycle_update_view',
|
|
kwargs={'pk':self.object.pk}),
|
|
'name': self.object.name
|
|
}
|
|
|
|
]
|
|
|
|
context['active'] = 'nav-plan'
|
|
context['breadcrumbs'] = breadcrumbs
|
|
context['rower'] = getrequestrower(self.request,userid=userid)
|
|
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
plan = self.object.plan.plan
|
|
thismacroid = self.object.plan.pk
|
|
createmacrofillers(plan)
|
|
return reverse(rower_trainingplan_view,
|
|
kwargs = {
|
|
'id':plan.id,
|
|
'thismacroid':thismacroid,
|
|
})
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(MesoCycleDelete, self).get_object(*args, **kwargs)
|
|
|
|
if not checkaccessuser(self.request.user,obj.plan.plan.manager):
|
|
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
|
|
|
return obj
|
|
|
|
|
|
class MacroCycleDelete(DeleteView):
|
|
model = TrainingMacroCycle
|
|
template_name = 'trainingplan_delete.html'
|
|
|
|
# extra parameters
|
|
def get_context_data(self, **kwargs):
|
|
context = super(MacroCycleDelete, self).get_context_data(**kwargs)
|
|
|
|
if 'userid' in kwargs:
|
|
userid = kwargs['userid']
|
|
else:
|
|
userid=0
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(rower_trainingplan_view,
|
|
kwargs={'userid':userid,
|
|
'id':self.object.plan.id}),
|
|
'name': self.object.plan.name
|
|
},
|
|
{
|
|
'url':reverse('macrocycle_update_view',
|
|
kwargs={'pk':self.object.pk}),
|
|
'name': self.object.name
|
|
}
|
|
]
|
|
|
|
context['active'] = 'nav-plan'
|
|
context['breadcrumbs'] = breadcrumbs
|
|
context['rower'] = getrequestrower(self.request,userid=userid)
|
|
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
plan = self.object.plan
|
|
createmacrofillers(plan)
|
|
return reverse(rower_trainingplan_view,
|
|
kwargs = {
|
|
'id':plan.id
|
|
})
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(MacroCycleDelete, self).get_object(*args, **kwargs)
|
|
if not checkaccessuser(self.request.user,obj.plan.manager):
|
|
raise PermissionDenied('You are not allowed to delete this training plan cycle')
|
|
|
|
return obj
|
|
|
|
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def rower_trainingplan_view(request,
|
|
id=0,
|
|
userid=0,
|
|
thismicroid=0,
|
|
thismacroid=0,
|
|
thismesoid=0):
|
|
|
|
|
|
startdate,enddate = get_dates_timeperiod(request)
|
|
|
|
|
|
try:
|
|
plan = TrainingPlan.objects.get(id=id)
|
|
except TrainingPlan.DoesNotExist:
|
|
raise Http404("Training Plan Does Not Exist")
|
|
|
|
r = getrequestrower(request,userid=userid)
|
|
|
|
if not checkaccessuser(request.user,plan.manager):
|
|
if request.user.rower not in plan.rowers.all():
|
|
raise PermissionDenied("Access denied")
|
|
|
|
createmacrofillers(plan)
|
|
macrocycles = TrainingMacroCycle.objects.filter(
|
|
plan=plan,
|
|
type='userdefined').order_by("startdate")
|
|
|
|
|
|
for m in macrocycles:
|
|
createmesofillers(m)
|
|
m.plantime = 0
|
|
m.actualtime = 0
|
|
m.plandistance = 0
|
|
m.actualdistance = 0
|
|
m.planrscore = 0
|
|
m.actualrscore = 0
|
|
m.plantrimp = 0
|
|
m.actualtrimp = 0
|
|
|
|
|
|
mesocycles = TrainingMesoCycle.objects.filter(
|
|
plan=m,
|
|
type='userdefined').order_by("startdate")
|
|
|
|
for me in mesocycles:
|
|
me.plantime = 0
|
|
me.actualtime = 0
|
|
me.plandistance = 0
|
|
me.actualdistance = 0
|
|
me.planrscore = 0
|
|
me.actualrscore = 0
|
|
me.plantrimp = 0
|
|
me.actualtrimp = 0
|
|
|
|
microcycles = TrainingMicroCycle.objects.filter(
|
|
plan=me,
|
|
type='userdefined').order_by("startdate")
|
|
|
|
for mm in microcycles:
|
|
sps = get_sessions(r,startdate=mm.startdate,enddate=mm.enddate)
|
|
|
|
# sps = PlannedSession.objects.filter(
|
|
# rower = r,
|
|
# startdate__lte=mm.enddate,
|
|
# enddate__gte=mm.startdate)
|
|
|
|
|
|
mm.plantime = 0
|
|
mm.actualtime = 0
|
|
mm.plandistance = 0
|
|
mm.actualdistance = 0
|
|
mm.planrscore = 0
|
|
mm.actualrscore = 0
|
|
mm.plantrimp = 0
|
|
mm.actualtrimp = 0
|
|
|
|
|
|
if mm.type == 'userdefined':
|
|
for ps in sps:
|
|
ratio, status, cdate = is_session_complete(r,ps)
|
|
if ps.sessionmode == 'time':
|
|
mm.plantime += ps.sessionvalue
|
|
mm.actualtime += int(ps.sessionvalue*ratio)
|
|
elif ps.sessionmode == 'distance' and ps.sessiontype != 'race':
|
|
mm.plandistance += ps.sessionvalue
|
|
mm.actualdistance += int(ps.sessionvalue*ratio)
|
|
elif ps.sessionmode == 'rScore':
|
|
mm.planrscore += ps.sessionvalue
|
|
mm.actualrscore += int(ps.sessionvalue*ratio)
|
|
elif ps.sessionmode == 'TRIMP':
|
|
mm.plantrimp += ps.sessionvalue
|
|
mm.actualtrimp += int(ps.sessionvalue*ratio)
|
|
|
|
mm.save()
|
|
|
|
me.plantime += mm.plantime
|
|
me.actualtime += mm.actualtime
|
|
me.plandistance += mm.plandistance
|
|
me.actualdistance += mm.actualdistance
|
|
me.planrscore += mm.planrscore
|
|
me.actualrscore += mm.actualrscore
|
|
me.plantrimp += mm.plantrimp
|
|
me.actualtrimp += mm.actualtrimp
|
|
|
|
if me.type == 'userdefined':
|
|
me.save()
|
|
|
|
m.plantime += me.plantime
|
|
m.actualtime += me.actualtime
|
|
m.plandistance += me.plandistance
|
|
m.actualdistance += me.actualdistance
|
|
m.planrscore += me.planrscore
|
|
m.actualrscore += me.actualrscore
|
|
m.plantrimp += me.plantrimp
|
|
m.actualtrimp += me.actualtrimp
|
|
|
|
|
|
|
|
if m.type == 'userdefined':
|
|
m.save()
|
|
|
|
createmacrofillers(plan)
|
|
macrocycles = TrainingMacroCycle.objects.filter(plan=plan).order_by("startdate")
|
|
|
|
count = 0
|
|
cycles = {}
|
|
|
|
for m in macrocycles:
|
|
createmesofillers(m)
|
|
mesocycles = TrainingMesoCycle.objects.filter(plan=m).order_by("startdate")
|
|
mesos = {}
|
|
count2 = 0
|
|
for me in mesocycles:
|
|
createmicrofillers(me)
|
|
microcycles = TrainingMicroCycle.objects.filter(plan=me).order_by("startdate")
|
|
|
|
mesos[count2] = (me, microcycles)
|
|
count2 += 1
|
|
|
|
cycles[count] = (m,mesos)
|
|
count += 1
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(rower_trainingplan_view,
|
|
kwargs={'userid':userid,
|
|
'id':id}),
|
|
'name': plan.name
|
|
}
|
|
]
|
|
|
|
if not thismicroid and not thismacroid and not thismesoid:
|
|
try:
|
|
thismicro = get_todays_micro(plan,thedate=startdate)
|
|
thismicroid = thismicro.pk
|
|
except AttributeError:
|
|
thismicroid = None
|
|
|
|
|
|
return render(request,'trainingplan.html',
|
|
{
|
|
'plan':plan,
|
|
'active':'nav-plan',
|
|
'breadcrumbs':breadcrumbs,
|
|
'rower':r,
|
|
'cycles':cycles,
|
|
'thismicroid':thismicroid,
|
|
'thismacroid':thismacroid,
|
|
'thismesoid':thismesoid,
|
|
}
|
|
)
|
|
|
|
class TrainingMacroCycleUpdate(UpdateView):
|
|
model = TrainingMacroCycle
|
|
template_name = 'trainingplan_edit.html'
|
|
form_class = TrainingMacroCycleForm
|
|
|
|
# extra parameters
|
|
def get_context_data(self, **kwargs):
|
|
context = super(TrainingMacroCycleUpdate, self).get_context_data(**kwargs)
|
|
|
|
if 'userid' in kwargs:
|
|
userid = kwargs['userid']
|
|
else:
|
|
userid=0
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(rower_trainingplan_view,
|
|
kwargs={'userid':userid,
|
|
'id':self.object.plan.id}),
|
|
'name': self.object.plan.name
|
|
},
|
|
{
|
|
'url':reverse('macrocycle_update_view',
|
|
kwargs={'pk':self.object.pk}),
|
|
'name': self.object.name
|
|
}
|
|
]
|
|
|
|
context['active'] = 'nav-plan'
|
|
context['breadcrumbs'] = breadcrumbs
|
|
context['rower'] = getrequestrower(self.request,userid=userid)
|
|
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
plan = self.object.plan
|
|
createmacrofillers(plan)
|
|
return reverse(rower_trainingplan_view,
|
|
kwargs = {
|
|
'id':plan.id,
|
|
'thismacroid':self.object.id,
|
|
}
|
|
)
|
|
|
|
def form_valid(self, form):
|
|
form.instance.user = self.request.user
|
|
form.instance.post_date = datetime.datetime.now()
|
|
macrocycle = form.save()
|
|
mesocyclecheckdates(macrocycle)
|
|
return super(TrainingMacroCycleUpdate, self).form_valid(form)
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(TrainingMacroCycleUpdate, self).get_object(*args, **kwargs)
|
|
if obj.plan.manager is not None and self.request.user.rower != obj.plan.manager:
|
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
|
|
|
if not checkaccessuser(self.request.user,obj.plan.manager):
|
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
|
else:
|
|
obj.type = 'userdefined'
|
|
obj.save()
|
|
return obj
|
|
|
|
class TrainingMesoCycleUpdate(UpdateView):
|
|
model = TrainingMesoCycle
|
|
template_name = 'trainingplan_edit.html'
|
|
form_class = TrainingMesoCycleForm
|
|
|
|
# extra parameters
|
|
def get_context_data(self, **kwargs):
|
|
context = super(TrainingMesoCycleUpdate, self).get_context_data(**kwargs)
|
|
|
|
if 'userid' in kwargs:
|
|
userid = kwargs['userid']
|
|
else:
|
|
userid=0
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(rower_trainingplan_view,
|
|
kwargs={'userid':userid,
|
|
'id':self.object.plan.plan.id}),
|
|
'name': self.object.plan.plan.name
|
|
},
|
|
{
|
|
'url':reverse('macrocycle_update_view',
|
|
kwargs={'pk':self.object.plan.pk}),
|
|
'name': self.object.plan.name
|
|
},
|
|
{
|
|
'url':reverse('mesocycle_update_view',
|
|
kwargs={'pk':self.object.pk}),
|
|
'name': self.object.name
|
|
}
|
|
|
|
]
|
|
|
|
context['active'] = 'nav-plan'
|
|
context['breadcrumbs'] = breadcrumbs
|
|
context['rower'] = getrequestrower(self.request,userid=userid)
|
|
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
plan = self.object.plan
|
|
createmesofillers(plan)
|
|
return reverse(rower_trainingplan_view,
|
|
kwargs = {
|
|
'id':plan.plan.id,
|
|
'thismesoid':self.object.id,
|
|
}
|
|
)
|
|
|
|
def form_valid(self, form):
|
|
form.instance.user = self.request.user
|
|
form.instance.post_date = datetime.datetime.now()
|
|
mesocycle = form.save()
|
|
microcyclecheckdates(mesocycle)
|
|
return super(TrainingMesoCycleUpdate, self).form_valid(form)
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(TrainingMesoCycleUpdate, self).get_object(*args, **kwargs)
|
|
if obj.plan.plan.manager is not None and self.request.user.rower != obj.plan.plan.manager:
|
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
|
|
|
else:
|
|
obj.type = 'userdefined'
|
|
obj.save()
|
|
obj.plan.type = 'userdefined'
|
|
obj.plan.save()
|
|
return obj
|
|
|
|
class TrainingMicroCycleUpdate(UpdateView):
|
|
model = TrainingMicroCycle
|
|
template_name = 'trainingplan_edit.html'
|
|
form_class = TrainingMicroCycleForm
|
|
|
|
# extra parameters
|
|
def get_context_data(self, **kwargs):
|
|
context = super(TrainingMicroCycleUpdate, self).get_context_data(**kwargs)
|
|
|
|
if 'userid' in kwargs:
|
|
userid = kwargs['userid']
|
|
else:
|
|
userid=0
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(rower_trainingplan_view,
|
|
kwargs={'userid':userid,
|
|
'id':self.object.plan.plan.plan.id}),
|
|
'name': self.object.plan.plan.plan.name
|
|
},
|
|
{
|
|
'url':reverse('macrocycle_update_view',
|
|
kwargs={'pk':self.object.plan.plan.pk}),
|
|
'name': self.object.plan.plan.name
|
|
},
|
|
{
|
|
'url':reverse('mesocycle_update_view',
|
|
kwargs={'pk':self.object.plan.pk}),
|
|
'name': self.object.plan.name
|
|
},
|
|
{
|
|
'url':reverse('microcycle_update_view',
|
|
kwargs={'pk':self.object.pk}),
|
|
'name': self.object.name
|
|
}
|
|
|
|
]
|
|
|
|
context['active'] = 'nav-plan'
|
|
context['breadcrumbs'] = breadcrumbs
|
|
context['rower'] = getrequestrower(self.request,userid=userid)
|
|
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
plan = self.object.plan
|
|
createmicrofillers(plan)
|
|
return reverse(rower_trainingplan_view,
|
|
kwargs = {
|
|
'id':plan.plan.plan.id,
|
|
'thismicroid':self.object.pk
|
|
}
|
|
)
|
|
def form_valid(self, form):
|
|
form.instance.user = self.request.user
|
|
form.instance.post_date = datetime.datetime.now()
|
|
microcycle = form.save()
|
|
|
|
return super(TrainingMicroCycleUpdate, self).form_valid(form)
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(TrainingMicroCycleUpdate, self).get_object(*args, **kwargs)
|
|
if obj.plan.plan.plan.manager is not None and self.request.user.rower != obj.plan.plan.plan.manager:
|
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
|
|
|
|
|
else:
|
|
obj.type = 'userdefined'
|
|
obj.save()
|
|
obj.plan.type = 'userdefined'
|
|
obj.plan.save()
|
|
return obj
|
|
|
|
class TrainingPlanUpdate(UpdateView):
|
|
model = TrainingPlan
|
|
template_name = 'trainingplan_edit.html'
|
|
form_class = TrainingPlanForm
|
|
|
|
# extra parameters
|
|
def get_context_data(self, **kwargs):
|
|
context = super(TrainingPlanUpdate, self).get_context_data(**kwargs)
|
|
|
|
if 'userid' in kwargs:
|
|
userid = kwargs['userid']
|
|
else:
|
|
userid=0
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse(rower_trainingplan_view,
|
|
kwargs={'userid':userid,
|
|
'id':self.object.id}),
|
|
'name': self.object.name
|
|
},
|
|
{
|
|
'url':reverse('trainingplan_update_view',
|
|
kwargs={'pk':self.object.pk}),
|
|
'name': 'Edit'
|
|
}
|
|
|
|
]
|
|
|
|
context['active'] = 'nav-plan'
|
|
context['breadcrumbs'] = breadcrumbs
|
|
context['rower'] = getrequestrower(self.request,userid=userid)
|
|
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
return reverse(rower_create_trainingplan)
|
|
|
|
def form_valid(self, form):
|
|
form.instance.user = self.request.user
|
|
form.instance.post_date = datetime.datetime.now()
|
|
plan = form.save()
|
|
plan.manager = self.request.user.rower
|
|
plan.save()
|
|
macrocyclecheckdates(plan)
|
|
return super(TrainingPlanUpdate, self).form_valid(form)
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(TrainingPlanUpdate, self).get_object(*args, **kwargs)
|
|
if obj.manager is not None and self.request.user.rower != obj.manager:
|
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
|
if obj.manager.rowerplan not in ['coach','plan']:
|
|
raise PermissionDenied('You are not allowed to edit this training plan')
|
|
|
|
return obj
|
|
|
|
class TrainingTargetUpdate(UpdateView):
|
|
model = TrainingTarget
|
|
template_name = 'trainingplan_edit.html'
|
|
form_class = TrainingTargetForm
|
|
|
|
# extra parameters
|
|
def get_context_data(self, **kwargs):
|
|
context = super(TrainingTargetUpdate, self).get_context_data(**kwargs)
|
|
|
|
if 'userid' in kwargs:
|
|
userid = kwargs['userid']
|
|
else:
|
|
userid=0
|
|
|
|
breadcrumbs = [
|
|
{
|
|
'url':reverse(plannedsessions_view,
|
|
kwargs={'userid':userid}),
|
|
'name': 'Plan'
|
|
},
|
|
{
|
|
'url':reverse('trainingtarget_update_view',
|
|
kwargs={'pk':self.object.pk}),
|
|
'name': 'Edit'
|
|
}
|
|
|
|
]
|
|
|
|
context['active'] = 'nav-plan'
|
|
context['breadcrumbs'] = breadcrumbs
|
|
context['rower'] = getrequestrower(self.request,userid=userid)
|
|
|
|
return context
|
|
|
|
def get_success_url(self):
|
|
return reverse(rower_create_trainingplan)
|
|
|
|
def form_valid(self, form):
|
|
form.instance.user = self.request.user
|
|
form.instance.post_date = datetime.datetime.now()
|
|
target = form.save()
|
|
return super(TrainingTargetUpdate, self).form_valid(form)
|
|
|
|
def get_object(self, *args, **kwargs):
|
|
obj = super(TrainingTargetUpdate, self).get_object(*args, **kwargs)
|
|
if obj.manager is not None and self.request.user.rower != obj.manager:
|
|
raise PermissionDenied('You are not allowed to edit this training plan cycle')
|
|
|
|
return obj
|
|
|
|
from rowers.utils import allsundays
|
|
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def planmesocyclebyweek(request,id=0,userid=0):
|
|
try:
|
|
cycle = TrainingMesoCycle.objects.get(id=id)
|
|
except TrainingMesoCycle.DoesNotExist:
|
|
raise Http404("Training Cycle does not exist")
|
|
|
|
if not checkaccessuser(request.user,cycle.plan.plan.manager):
|
|
raise PermissionDenied("You are not allowed to do this")
|
|
|
|
micros = TrainingMicroCycle.objects.filter(plan=cycle)
|
|
for m in micros:
|
|
m.delete()
|
|
|
|
cycle.type = 'userdefined'
|
|
cycle.save()
|
|
|
|
#we're still here. We have permission
|
|
sundays = [s for s in allsundays(cycle.startdate,cycle.enddate)]
|
|
|
|
if sundays and sundays[-1] < cycle.enddate:
|
|
sundays = sundays+[cycle.enddate]
|
|
elif not sundays:
|
|
sundays = [cycle.enddate]
|
|
|
|
for i in range(len(sundays)):
|
|
if i==0:
|
|
monday = cycle.startdate
|
|
else:
|
|
monday = sundays[i]-timedelta(days=6)
|
|
if monday < cycle.startdate:
|
|
monday = cycle.startdate
|
|
|
|
nextsunday = sundays[i]
|
|
|
|
micro = TrainingMicroCycle(startdate = monday,
|
|
enddate = nextsunday,
|
|
plan = cycle,
|
|
name = 'Week %s' % monday.isocalendar()[1],
|
|
type = 'userdefined')
|
|
micro.save()
|
|
|
|
micros = TrainingMicroCycle.objects.filter(plan=cycle)
|
|
|
|
url = reverse(rower_trainingplan_view,
|
|
kwargs = {'userid':str(userid),
|
|
'id':str(cycle.plan.plan.id),
|
|
'thismicroid':str(micros[0].id)})
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
from rowers.utils import allmonths
|
|
|
|
@user_passes_test(hasplannedsessions,login_url="/rowers/paidplans",
|
|
message="This functionality requires a Coach or Self-Coach plan",
|
|
redirect_field_name=None)
|
|
def planmacrocyclebymonth(request,id=0,userid=0):
|
|
try:
|
|
cycle = TrainingMacroCycle.objects.get(id=id)
|
|
except TrainingMacroCycle.DoesNotExist:
|
|
raise Http404("Training Cycle does not exist")
|
|
|
|
if not checkaccessuser(request.user,cycle.plan.manager):
|
|
raise PermissionDenied("You are not allowed to do this")
|
|
|
|
mesos = TrainingMesoCycle.objects.filter(plan=cycle)
|
|
for m in mesos:
|
|
m.delete()
|
|
|
|
cycle.type = 'userdefined'
|
|
cycle.save()
|
|
|
|
#we're still here. We have permission
|
|
monthstarts = [d for d in allmonths(cycle.startdate,cycle.enddate)]
|
|
monthstarts.append(cycle.enddate)
|
|
for i in range(len(monthstarts)-1):
|
|
firstday = monthstarts[i]
|
|
lastday = monthstarts[i+1]-timedelta(days=1)
|
|
if lastday < cycle.enddate and i == len(monthstarts)-2:
|
|
lastday = cycle.enddate
|
|
|
|
|
|
meso = TrainingMesoCycle(startdate = firstday,
|
|
enddate = lastday,
|
|
plan = cycle,
|
|
name = '%s' % firstday.strftime("%B"),
|
|
type = 'userdefined')
|
|
meso.save()
|
|
|
|
mesos = TrainingMesoCycle.objects.filter(plan=cycle)
|
|
|
|
url = reverse(rower_trainingplan_view,
|
|
kwargs = {'userid':str(userid),
|
|
'id':str(cycle.plan.id),
|
|
'thismesoid':str(mesos[0].id)})
|
|
|
|
return HttpResponseRedirect(url)
|
|
|
|
|
|
|