Private
Public Access
1
0
Files
rowsandall/rowers/views/planviews.py
Sander Roosendaal 5513020ea3 bug fix
2020-07-07 10:54:15 +02:00

3059 lines
98 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
@permission_required('plannedsession.view_session',fn=get_session_by_pk,raise_exception=True)
def plannedsession_comment_view(request,id=0,userid=0):
r = getrequestplanrower(request,userid=userid)
ps = get_object_or_404(PlannedSession,pk=id)
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:
try:
a_messages.info(u,message)
except ValueError:
pass
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
)
if ps.sessiontype in ['race','indoorrace']:
followers = VirtualRaceFollower.objects.filter(race__id=ps.id)
for follower in followers:
othername = ''
if follower.user:
othername = follower.user.first_name+' '+follower.user.last_name
email = follower.emailaddress
res = myqueue(queuelow,
handle_sendemailnewresponse,
othername,'',email,
request.user.first_name,
request.user.last_name,
comment,
ps.name,ps.id,c.id,
emailbounced = False,
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,
})
@login_required
@permission_required('virtualevent.change_race',fn=get_session_by_pk,raise_exception=True)
def plannedsession_message_view(request,id=0,userid=0):
r = getrequestplanrower(request,userid=userid)
ps = get_object_or_404(PlannedSession,pk=id)
userform = VirtualRaceAthleteForm(instance=ps)
if request.method == 'POST':
userform = VirtualRaceAthleteForm(request.POST,instance=ps)
if userform.is_valid():
subject = userform.cleaned_data['subject']
message = userform.cleaned_data['message']
rowers = userform.cleaned_data['rower']
for participant in rowers:
rowername = participant.user.first_name
fromemail = ps.manager.email
job = myqueue(
queue,
handle_send_template_email,
'virtualracemessage.html',
participant.user.email,
fromemail,
rowername,
subject,
message,
)
url = reverse('virtualevent_view',kwargs={'id':ps.id})
return HttpResponseRedirect(url)
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_message.html',
{'plannedsession':ps,
'rower':r,
'breadcrumbs':breadcrumbs,
'active':active,
'userform':userform,
})
# Cloning sessions
@user_passes_test(can_plan,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)
teamid = get_team(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],
is_template=False,
startdate__lte=enddate,
enddate__gte=startdate).order_by(
"startdate","preferreddate","enddate").exclude(
sessiontype='race')
if teamid:
sps = sps.filter(team__in=[teamid])
try:
team = Team.objects.get(id=teamid)
if team.manager != request.user:
team = None
except Team.DoesNotExist:
team = None
else:
team = None
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,
})
if Team.objects.filter(manager=request.user).count()>=1:
teamform = RowerTeamForm(request.user)
if teamid:
teamform = RowerTeamForm(request.user,initial={'team':teamid})
else:
teamform = None
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,
'team':team,
'teamform':teamform,
}
)
# Individual user creates training for himself
@user_passes_test(can_plan,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:
try:
preferreddate = startdate.date()
except AttributeError:
preferreddate = startdate
if preferreddate < timezone.now().date():
preferreddate = timezone.now().date()
try:
enddate = enddate.date()
except AttributeError:
pass
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')
sessiontemplates = PlannedSession.objects.filter(
manager=request.user,
is_template=True).order_by("name")
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,
'sessiontemplates':sessiontemplates,
'rower':r,
'timeperiod':timeperiod,
})
@user_passes_test(can_plan,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)
teamid = get_team(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')
if teamid:
qset = qset.filter(team__in=[teamid])
try:
team = Team.objects.get(id=teamid)
if team.manager != request.user:
team = None
except Team.DoesNotExist:
team = None
else:
team = None
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)
if team:
add_team_session(team,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
if team:
url += '&team={teamid}'.format(teamid=team.id)
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
})
if Team.objects.filter(manager=request.user).count()>=1:
teamform = RowerTeamForm(request.user)
if teamid:
teamform = RowerTeamForm(request.user,initial={'team':teamid})
else:
teamform = None
context = {
'ps_formset':ps_formset,
'breadcrumbs':breadcrumbs,
'rower':r,
'active':'nav-plan',
'dateform':dateform,
'teamform':teamform,
'plan':trainingplan,
'timeperiod':timeperiod,
'teams':get_my_teams(request.user),
'extrasessions': extrasessions+1,
'team':team,
}
return render(request,'plannedsession_multicreate.html',context)
# Manager creates sessions for entire team
@user_passes_test(can_plan,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 teams.count()>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")
sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True)
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]).exclude(rowerplan='freecoach')
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
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
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,
'sessiontemplates':sessiontemplates,
'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,
'sessiontemplates':sessiontemplates,
'teamform':sessionteamselectform,
'timeperiod':timeperiod,
'plannedsessions':sps,
'rower':therower,
'active':'nav-plan'
})
# Manager edits sessions for entire team
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
def plannedsession_teamedit_view(request,
id=0,userid=0):
r = getrequestplanrower(request,userid=userid)
ps = get_object_or_404(PlannedSession,pk=id)
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 = {
'id':id,
})
startdatestring = startdate.strftime('%Y-%m-%d')
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
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 'coach' in request.user.rower.rowerplan:
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)
if therower.rowerplan != 'freecoach':
rowers = [therower]
else:
rowers = []
for ps in sps:
if 'coach' in request.user.rower.rowerplan:
rowers += ps.rower.all().exclude(rowerplan='freecoach')
else:
rowers += ps.rower.filter(team__in=rteams).exclude(rowerplan='freecoach')
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,
})
ttemplate = 'plannedsessionscoach.html'
if len(rowers) > 5 and len(rowers) > len(sps):
ttemplate = 'plannedsessionscoach2.html'
return render(request,ttemplate,
{
'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,checkscores
@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,
})
@allow_shares
#@login_required()
def plannedsessions_print_view(request,userid=0,startdatestring='',enddatestring=''):
r = getrequestplanrower(request,userid=userid)
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 = {}
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()
@permission_required('rower.is_coach',fn=get_user_by_userid,raise_exception=True)
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
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan,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
ps = get_object_or_404(PlannedSession,pk=id)
rowers = ps.rower.all()
teams = ps.team.all()
ps.pk = None
ps.id = None
if not ps.is_template:
ps.name += ' (copy)'
ps.is_template = False
deltadays = ps.preferreddate-ps.startdate
ps.startdate = startdate
ps.enddate = enddate
ps.preferreddate = ps.startdate+deltadays
ps.save()
if rowers:
for rower in rowers:
add_rower_session(rower,ps)
else:
add_rower_session(r,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
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
# Clone an existing planned session
# need clarity on cloning behavior time shift
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan,login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_teamclone_view(request,id=0):
r = getrequestplanrower(request)
teams = Team.objects.filter(manager=request.user)
if teams.count()>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)
try:
trainingplan = TrainingPlan.objects.filter(
startdate__lte = startdate,
rowers = r,
enddate__gte = enddate)[0]
except IndexError:
trainingplan = None
ps = get_object_or_404(PlannedSession,pk=id)
ps.pk = None
ps.id = None
if not ps.is_template:
ps.name += ' (copy)'
ps.is_template = False
deltadays = ps.preferreddate-ps.startdate
ps.startdate = startdate
ps.enddate = enddate
ps.preferreddate = startdate+deltadays
ps.save()
url = reverse(plannedsession_teamedit_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
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan, login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_templateedit_view(request,id=0):
r = getrequestrower(request)
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 not ps.is_template:
ps.pk = None
ps.id = None
ps.is_template = True
ps.startdate = datetime.date(1970,1,1)
ps.enddate = datetime.date(1970,1,1)
ps.team.clear()
ps.save()
sessioncreateform = PlannedSessionTemplateForm(instance=ps)
if request.method == 'POST':
sessioncreateform = PlannedSessionTemplateForm(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_templateedit_view,
kwargs = {
'id':int(ps.id),
})
startdatestring = startdate.strftime('%Y-%m-%d')
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
breadcrumbs = [
{
'url': reverse(plannedsessions_view),
'name': 'Sessions'
},
{
'url':reverse(plannedsession_templateedit_view,
kwargs={
'id':id,
}
),
'name': 'Edit'
}
]
sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True)
return render(request,'plannedsessiontemplateedit.html',
{
'teams':get_my_teams(request.user),
'plan': trainingplan,
'breadcrumbs': breadcrumbs,
'form': sessioncreateform,
'active':'nav-plan',
'thesession': ps,
'sessiontemplates': sessiontemplates,
'rower': r,
})
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan, login_url="/rowers/paidplans/",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def plannedsession_totemplate_view(request,id=0):
r = getrequestplanrower(request)
startdate, enddate = get_dates_timeperiod(request)
ps = get_object_or_404(PlannedSession,pk=id)
ps.pk = None
ps.id = None
ps.is_template = True
ps.startdate = datetime.date(1970,1,1)
ps.enddate = datetime.date(1970,1,1)
ps.save()
url = reverse(plannedsession_create_view,kwargs={'userid':r.user.id})
startdatestring = startdate.strftime('%Y-%m-%d')
enddatestring = enddate.strftime('%Y-%m-%d')
url += '?when='+startdatestring+'/'+enddatestring
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
# Edit an existing planned session
@permission_required('plannedsession.change_session',fn=get_session_by_pk,raise_exception=True)
@user_passes_test(can_plan,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
ps = get_object_or_404(PlannedSession,pk=id)
if ps.team.all() or ps.rower.all().count()>1:
url = reverse(plannedsession_teamedit_view,
kwargs={
'id':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'
}
]
sessiontemplates = PlannedSession.objects.filter(manager=request.user,is_template=True)
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,
'sessiontemplates':sessiontemplates,
'rower':r,
'timeperiod':timeperiod,
})
@permission_required('workout.change_workout',fn=get_workout_by_opaqueid,raise_exception=True)
def plannedsession_detach_view(request,id=0,psid=0):
r = getrequestrower(request)
ps = get_object_or_404(PlannedSession,pk=psid)
w = get_workout(id)
remove_workout_plannedsession(w,ps)
url = reverse(plannedsession_view,kwargs={'id':psid})
next = request.GET.get('next', url)
return HttpResponseRedirect(next)
@login_required()
@permission_required('plannedsession.view_session',fn=get_session_by_pk,raise_exception=True)
def plannedsession_view(request,id=0,userid=0):
r = getrequestplanrower(request,userid=userid)
ps = get_object_or_404(PlannedSession,pk=id)
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)
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,
w.user.user.email,w.user.user.first_name,
mode='coursetest')
intsecs = 0
microsecs = 0
# taking workout duration plus 1 minute penalty
wdict['time'] = datetime.timedelta(
hours=w.duration.hour,
minutes=w.duration.minute,
seconds=w.duration.second,
)
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)
next = self.request.GET.get('next',url)
return next
def get_object(self, *args, **kwargs):
obj = super(PlannedSessionDelete, self).get_object(*args, **kwargs)
if not can_delete_session(self.request.user,obj):
raise PermissionDenied('You are not allowed to delete this planned session')
return obj
@user_passes_test(can_plan,login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def rower_create_trainingplan(request,id=0):
therower = getrequestrower(request,userid=id)
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']
try:
rowers = targetform.cleaned_data['rowers']
except KeyError:
rowers = [therower]
t = TrainingTarget(
name=name,
date=date,
manager=themanager,
notes=notes)
t.save()
for athlete in rowers:
t.rowers.add(athlete)
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']
status = form.cleaned_data['status']
enddate = form.cleaned_data['enddate']
notes = form.cleaned_data['notes']
try:
athletes = form.cleaned_data['rowers']
except KeyError:
athletes = [therower]
p = TrainingPlan(
name=name,
target=target,
manager=themanager,
startdate=startdate,
enddate=enddate,status=status,
notes=notes,
)
p.save()
for athlete in athletes:
if can_plan_user(request.user,athlete):
p.rowers.add(athlete)
targets = TrainingTarget.objects.filter(
rowers=therower,
date__gte=datetime.date.today(),
).order_by("date")
old_targets = TrainingTarget.objects.filter(
rowers=therower,
date__lt=datetime.date.today(),
).order_by("-date")
targetform = TrainingTargetForm(user=request.user)
plans = TrainingPlan.objects.filter(rowers=therower).order_by("-startdate")
plans_to_deactivate = TrainingPlan.objects.filter(
rowers=therower,
enddate__lt=datetime.date.today(),
status=True,
).order_by("-startdate")
for p in plans_to_deactivate:
p.status = False
p.save()
form = TrainingPlanForm(targets=targets,
initial={'status':False,'rowers':[therower]},
user=request.user)
breadcrumbs = [
{
'url':reverse(plannedsessions_view,
kwargs={'userid':id}),
'name': 'Plan'
},
{
'url':reverse(rower_create_trainingplan,
kwargs={'id':id}),
'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,
'old_targets':old_targets,
})
@user_passes_test(can_plan,login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
@permission_required('target.delete_target',fn=get_target_by_pk,raise_exception=True)
def rower_delete_trainingtarget(request,id=0):
target = get_object_or_404(TrainingTarget,pk=id)
target.delete()
url = reverse(rower_create_trainingplan)
return HttpResponseRedirect(url)
@user_passes_test(can_plan,login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
@permission_required('target.delete_plan',fn=get_plan_by_pk,raise_exception=True)
def rower_delete_trainingplan(request,id=0):
plan = get_object_or_404(TrainingPlan,pk=id)
plan.delete()
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 can_delete_plan(self.request.user,obj):
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 can_delete_cycle(self.request.user,obj):
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 can_delete_cycle(self.request.user,obj):
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 can_delete_cycle(self.request.user,obj):
raise PermissionDenied('You are not allowed to delete this training plan cycle')
return obj
@user_passes_test(can_plan,login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
def rower_trainingplan_execution_view(request,
id=0,
userid=0):
startdate,enddate = get_dates_timeperiod(request)
r = getrequestrower(request,userid=userid)
if int(id)>0:
try:
plan = TrainingPlan.objects.get(id=id)
except TrainingPlan.DoesNotExist:
raise Http404("Training Plan Does Not Exist")
if not is_coach_user(request.user,plan.manager.user):
if request.user.rower not in plan.rowers.all():
raise PermissionDenied("Access denied")
if not startdate or not enddate:
if int(id)>0:
startdate = plan.startdate
enddate = plan.enddate
else:
startdate,enddate = get_dates_timeperiod(request)
else:
startdate,enddate = get_dates_timeperiod(request)
if int(id)>0:
data,message = get_execution_report(r,startdate,enddate,plan=plan)
else:
data,message = get_execution_report(r,startdate,enddate)
if not data.empty:
script, div = interactive_planchart(data,startdate,enddate)
else:
script = ''
div = ''
messages.error(request,'The plan does not cover this time range')
if int(id):
breadcrumbs = [
{
'url':reverse(plannedsessions_view,
kwargs={'userid':userid}),
'name': 'Plan'
},
{
'url':reverse(rower_trainingplan_view,
kwargs={'userid':userid,
'id':id}),
'name': plan.name
},
{
'url':reverse(rower_trainingplan_execution_view,
kwargs={'userid':userid,
'id':id}),
'name': 'Execution'
}
]
else:
breadcrumbs = [
{
'url':reverse(plannedsessions_view,
kwargs={'userid':userid}),
'name': 'Plan'
},
{
'url':reverse(rower_trainingplan_execution_view,
kwargs={'userid':userid,
'id':id}),
'name': 'Execution'
}
]
return render(request,'trainingplan_chart.html',
{
'todays_date': timezone.now().date(),
'active': 'nav-plan',
'breadcrumbs':breadcrumbs,
'rower':r,
'the_script':script,
'the_div':div
}
)
#@user_passes_test(can_plan,login_url="/rowers/paidplans",
# message="This functionality requires a Coach or Self-Coach plan",
# redirect_field_name=None)
@login_required()
@permission_required('plan.view_plan',fn=get_plan_by_pk,raise_exception=True)
def rower_trainingplan_view(request,
id=0,
userid=0,
thismicroid=0,
thismacroid=0,
thismesoid=0):
startdate,enddate = get_dates_timeperiod(request)
plan = get_object_or_404(TrainingPlan,pk=id)
r = getrequestrower(request,userid=userid)
createmacrofillers(plan)
macrocycles = TrainingMacroCycle.objects.filter(
plan=plan,
type='userdefined').order_by("startdate")
checkscores(r,macrocycles)
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,
'todays_date': timezone.now().date(),
'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 not can_change_cycle(self.request.user,obj):
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 not can_change_cycle(self.request.user,obj):
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 not can_change_cycle(self.request.user,obj):
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 not can_change_plan(self.request.user,obj):
raise PermissionDenied('You are not allowed to edit this training plan cycle')
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 not can_change_target(self.request.user,obj):
raise PermissionDenied('You are not allowed to edit this training plan cycle')
return obj
from rowers.utils import allsundays
@user_passes_test(can_plan,login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
@permission_required('cycle.change_cycle',fn=get_meso_by_pk,raise_exception=True)
def planmesocyclebyweek(request,id=0,userid=0):
cycle = get_object_or_404(TrainingMesoCycle,pk=id)
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(can_plan,login_url="/rowers/paidplans",
message="This functionality requires a Coach or Self-Coach plan",
redirect_field_name=None)
@permission_required('cycle.change_cycle',fn=get_macro_by_pk,raise_exception=True)
def planmacrocyclebymonth(request,id=0,userid=0):
cycle = get_object_or_404(TrainingMacroCycle,pk=id)
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)