Merge branch 'feature/coachfunctions' into develop
This commit is contained in:
@@ -172,7 +172,7 @@ def update_subscription(rower,data,method='up'):
|
||||
|
||||
if rower.paidplan != 'coach':
|
||||
try:
|
||||
coachgroup = coach.mycoachgroup
|
||||
coachgroup = rower.mycoachgroup
|
||||
except CoachingGroup.DoesNotExist:
|
||||
coachgroup = CoachingGroup()
|
||||
coachgroup.save()
|
||||
|
||||
@@ -1023,6 +1023,33 @@ def checkworkoutuser(user,workout):
|
||||
except Rower.DoesNotExist:
|
||||
return False
|
||||
|
||||
def checkviewworkouts(user,rower):
|
||||
try:
|
||||
r = user.rower
|
||||
if rower == r:
|
||||
return True
|
||||
teams = Team.objects.filter(manager=user)
|
||||
print Rower.objects.filter(team__in=teams)
|
||||
if rower in Rower.objects.filter(team__in=teams):
|
||||
return True
|
||||
except Rower.DoesNotExist:
|
||||
return False
|
||||
|
||||
# check if user is plan and rower is in his group
|
||||
def checkaccessplanuser(user,rower):
|
||||
try:
|
||||
r = Rower.objects.get(user=user)
|
||||
if rower == r:
|
||||
return True
|
||||
team_managers = [t.manager for t in rower.team.all() if t.manager.rower.rowerplan in ['plan','coach']]
|
||||
if user.rower.rowerplan != 'basic':
|
||||
return user in team_managers
|
||||
else:
|
||||
return False
|
||||
|
||||
return False
|
||||
except Rower.DoesNotExist:
|
||||
return False
|
||||
|
||||
# Check if user is coach or rower
|
||||
def checkaccessuser(user,rower):
|
||||
|
||||
@@ -189,7 +189,7 @@
|
||||
</td>
|
||||
<td> {{ workout.date|date:"Y-m-d" }} </td>
|
||||
<td> {{ workout.starttime|date:"H:i" }} </td>
|
||||
{% if workout.user.user == user or user == team.manager %}
|
||||
{% if workout|may_edit:request %}
|
||||
{% if workout.name != '' %}
|
||||
<td>
|
||||
<a href={% url rower.defaultlandingpage id=workout.id|encode %}>
|
||||
@@ -215,18 +215,27 @@
|
||||
<td> {{ workout.maxhr }} </td>
|
||||
{% if team %}
|
||||
<td colspan="2">
|
||||
{% if workout|may_edit:request %}
|
||||
<a class="small" href="/rowers/{{ workout.user.id }}/list-workouts/">
|
||||
{{ workout.user.user.first_name }}
|
||||
{{ workout.user.user.last_name }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ workout.user.user.first_name }}
|
||||
{{ workout.user.user.last_name }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
<td>
|
||||
{% if workout|may_edit:request %}
|
||||
<a class="small"
|
||||
href="/rowers/workout/{{ workout.id|encode }}/edit/"
|
||||
title="Edit">
|
||||
<i class="fas fa-pencil-alt fa-fw"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
<a class="small"
|
||||
@@ -236,17 +245,25 @@
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{% if workout|may_edit:request %}
|
||||
<a class="small"
|
||||
href="/rowers/workout/{{ workout.id|encode }}/stats/"
|
||||
title="Stats">
|
||||
<i class="fal fa-table fa-fw"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if workout.user.user == user or user == team.manager %}
|
||||
<a class="small" href="/rowers/workout/{{ workout.id|encode }}/delete/"
|
||||
title="Delete">
|
||||
<i class="fas fa-trash-alt fa-fw"></i>
|
||||
</a>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
</li>
|
||||
<li id="sessions-coach">
|
||||
<a href="/rowers/sessions/coach/?when={{ timeperiod }}">
|
||||
<i class="fas fa-bullhorn fa-fw"></i> Coach View
|
||||
<i class="fas fa-bullhorn fa-fw"></i> Training Group View
|
||||
</a>
|
||||
</li>
|
||||
<li id="sessions-print">
|
||||
@@ -82,27 +82,26 @@
|
||||
|
||||
<p> </p>
|
||||
|
||||
|
||||
|
||||
{% if user.is_authenticated and user|is_manager %}
|
||||
{% if user.is_authenticated and user|is_planmember %}
|
||||
<p> </p>
|
||||
|
||||
{% if user|coach_rowers %}
|
||||
{% if user|team_members %}
|
||||
<ul class="cd-accordion-menu animated">
|
||||
<li class="has-children" id="athletes">
|
||||
<input type="checkbox" name="athlete-selector" id="athlete-selector">
|
||||
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i> Athletes</label>
|
||||
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i> Group Members</label>
|
||||
<ul>
|
||||
{% for member in user|coach_rowers %}
|
||||
<a href={{ request.path|userurl:member.user }}?when={{ timeperiod }}>
|
||||
<i class="fas fa-user fa-fw"></i>
|
||||
{% if member.user == rower.user %}
|
||||
•
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
{{ member.user.first_name }} {{ member.user.last_name }}
|
||||
</a>
|
||||
{% for member in user|team_members %}
|
||||
<li>
|
||||
<a href={{ request.path|userurl:member }}>
|
||||
<i class="fas fa-user fa-fw"></i>
|
||||
{% if member == rower.user%}
|
||||
•
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
{{ member.first_name }} {{ member.last_name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -45,8 +45,11 @@
|
||||
</li>
|
||||
</ul> <!-- cd-accordion-menu -->
|
||||
|
||||
|
||||
|
||||
{% if user.is_authenticated and user|is_manager %}
|
||||
<p> </p>
|
||||
|
||||
{% if user|coach_rowers %}
|
||||
<ul class="cd-accordion-menu animated">
|
||||
<li class="has-children" id="athletes">
|
||||
@@ -54,17 +57,15 @@
|
||||
<label for="athlete-selector"><i class="fas fa-users fa-fw"></i> Athletes</label>
|
||||
<ul>
|
||||
{% for member in user|coach_rowers %}
|
||||
<li>
|
||||
<a href={{ request.path|userurl:member.user }}>
|
||||
<i class="fas fa-user fa-fw"></i>
|
||||
{% if member.user == rower.user and not team %}
|
||||
•
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
{{ member.user.first_name }} {{ member.user.last_name }}
|
||||
</a>
|
||||
</li>
|
||||
<a href={{ request.path|userurl:member.user }}?when={{ timeperiod }}>
|
||||
<i class="fas fa-user fa-fw"></i>
|
||||
{% if member == rower.user %}
|
||||
•
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
{{ member.user.first_name }} {{ member.user.last_name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@@ -346,7 +346,7 @@ def has_teams(user):
|
||||
def team_members(user):
|
||||
try:
|
||||
therower = Rower.objects.get(user=user)
|
||||
if therower.rowerplan != 'coach':
|
||||
if therower.rowerplan == 'basic':
|
||||
return []
|
||||
teams = Team.objects.filter(manager=user)
|
||||
members = Rower.objects.filter(
|
||||
@@ -364,7 +364,7 @@ def team_members(user):
|
||||
def team_rowers(user):
|
||||
try:
|
||||
therower = Rower.objects.get(user=user)
|
||||
if therower.rowerplan != 'coach':
|
||||
if therower.rowerplan == 'basic':
|
||||
return []
|
||||
teams = Team.objects.filter(manager=user)
|
||||
members = Rower.objects.filter(team__in=teams).distinct().order_by(
|
||||
@@ -464,11 +464,11 @@ def is_final(race):
|
||||
|
||||
@register.filter
|
||||
def userurl(path,member):
|
||||
pattern = re.compile('user\/\d+')
|
||||
pattern = re.compile('user\/\d+/')
|
||||
userstring = 'user/%s/' % member.id
|
||||
|
||||
# remove team
|
||||
tpattern = re.compile('\/team\/\d+')
|
||||
tpattern = re.compile('\/team\/\d+/')
|
||||
if tpattern.search(path) is not None:
|
||||
path = tpattern.sub('',path)
|
||||
|
||||
@@ -481,11 +481,11 @@ def userurl(path,member):
|
||||
|
||||
@register.filter
|
||||
def teamurl(path,team):
|
||||
pattern = re.compile('team\/\d+')
|
||||
pattern = re.compile('team\/\d+/')
|
||||
teamstring = 'team/%s/' % team.id
|
||||
|
||||
# remove user
|
||||
upattern = re.compile('\/user\/\d+')
|
||||
upattern = re.compile('\/user\/\d+/')
|
||||
if upattern.search(path) is not None:
|
||||
path = upattern.sub('',path)
|
||||
|
||||
|
||||
@@ -1414,3 +1414,10 @@ class PermissionsCoachingTests(TestCase):
|
||||
## Basic and Pro users can create races
|
||||
|
||||
## Basic users can subscribe to any race
|
||||
|
||||
|
||||
# group related
|
||||
|
||||
## group members can see but not edit each other's workouts and charts
|
||||
|
||||
## group members can see but not edit each other's plans
|
||||
|
||||
BIN
Binary file not shown.
+1
-1
@@ -638,7 +638,7 @@ urlpatterns = [
|
||||
name='plannedsessions_manage_view'),
|
||||
url(r'^sessions/coach/$',views.plannedsessions_coach_view,
|
||||
name='plannedsessions_coach_view'),
|
||||
url(r'^sessions/coach/user/\d+/$',views.plannedsessions_coach_view,
|
||||
url(r'^sessions/coach/user/(?P<userid>\d+)/$',views.plannedsessions_coach_view,
|
||||
name='plannedsessions_coach_view'),
|
||||
url(r'^sessions/print/?/$',views.plannedsessions_print_view,
|
||||
name='plannedsessions_print_view'),
|
||||
|
||||
+15
-13
@@ -2,7 +2,7 @@ from statements import *
|
||||
|
||||
@login_required()
|
||||
def plannedsession_comment_view(request,id=0,userid=0):
|
||||
r = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
try:
|
||||
ps = PlannedSession.objects.get(id=id)
|
||||
@@ -170,7 +170,7 @@ def plannedsession_multiclone_view(
|
||||
request,
|
||||
userid=0,):
|
||||
|
||||
r = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
startdate,enddate = get_dates_timeperiod(request)
|
||||
@@ -301,7 +301,7 @@ def plannedsession_create_view(request,
|
||||
startdatestring='',
|
||||
enddatestring=''):
|
||||
|
||||
r = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
|
||||
@@ -442,7 +442,7 @@ def plannedsession_multicreate_view(request,
|
||||
|
||||
extrasessions=int(extrasessions)
|
||||
|
||||
r = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
startdate,enddate = get_dates_timeperiod(request)
|
||||
@@ -547,12 +547,13 @@ def plannedsession_multicreate_view(request,
|
||||
return render(request,'plannedsession_multicreate.html',context)
|
||||
|
||||
# Manager creates sessions for entire team
|
||||
@user_passes_test(iscoachmember,login_url="/rowers/paidplans/",
|
||||
@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 = getrequestrower(request,userid=userid)
|
||||
therower = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
|
||||
@@ -716,11 +717,12 @@ def plannedsession_teamcreate_view(request,
|
||||
|
||||
# Manager edits sessions for entire team
|
||||
@user_passes_test(iscoachmember,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 = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
try:
|
||||
@@ -880,7 +882,7 @@ def plannedsessions_coach_view(request,
|
||||
teamid=0,userid=0):
|
||||
|
||||
|
||||
therower = getrower(request.user)
|
||||
therower = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
startdate,enddate = get_dates_timeperiod(request)
|
||||
@@ -984,7 +986,7 @@ from rowers.plannedsessions import cratiocolors
|
||||
def plannedsessions_view(request,
|
||||
userid=0,startdatestring='',enddatestring=''):
|
||||
|
||||
r = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
if startdatestring:
|
||||
try:
|
||||
@@ -1127,7 +1129,7 @@ def plannedsessions_view(request,
|
||||
@login_required()
|
||||
def plannedsessions_print_view(request,userid=0):
|
||||
|
||||
r = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
|
||||
@@ -1330,7 +1332,7 @@ def plannedsessions_manage_view(request,userid=0,
|
||||
redirect_field_name=None)
|
||||
def plannedsession_clone_view(request,id=0,userid=0):
|
||||
|
||||
r = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
startdate,enddate = get_dates_timeperiod(request)
|
||||
@@ -1391,7 +1393,7 @@ def plannedsession_clone_view(request,id=0,userid=0):
|
||||
redirect_field_name=None)
|
||||
def plannedsession_edit_view(request,id=0,userid=0):
|
||||
|
||||
r = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
|
||||
@@ -1536,7 +1538,7 @@ def plannedsession_detach_view(request,id=0,psid=0):
|
||||
@login_required()
|
||||
def plannedsession_view(request,id=0,userid=0):
|
||||
|
||||
r = getrequestrower(request,userid=userid)
|
||||
r = getrequestplanrower(request,userid=userid)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -88,7 +88,7 @@ from rowers.models import (
|
||||
microcyclecheckdates,mesocyclecheckdates,macrocyclecheckdates,
|
||||
TrainingMesoCycleForm, TrainingMicroCycleForm,
|
||||
RaceLogo,RowerBillingAddressForm,PaidPlan,
|
||||
PlannedSessionComment,CoachRequest,CoachOffer,
|
||||
PlannedSessionComment,CoachRequest,CoachOffer,checkaccessplanuser
|
||||
)
|
||||
from rowers.models import (
|
||||
RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm,
|
||||
@@ -300,6 +300,39 @@ def getrequestrower(request,rowerid=0,userid=0,notpermanent=False):
|
||||
|
||||
return r
|
||||
|
||||
def getrequestplanrower(request,rowerid=0,userid=0,notpermanent=False):
|
||||
|
||||
userid = int(userid)
|
||||
rowerid = int(rowerid)
|
||||
|
||||
if notpermanent == False:
|
||||
if rowerid == 0 and 'rowerid' in request.session:
|
||||
rowerid = request.session['rowerid']
|
||||
|
||||
if userid != 0:
|
||||
rowerid = 0
|
||||
|
||||
try:
|
||||
|
||||
if rowerid != 0:
|
||||
r = Rower.objects.get(id=rowerid)
|
||||
elif userid != 0:
|
||||
u = User.objects.get(id=userid)
|
||||
r = getrower(u)
|
||||
else:
|
||||
r = getrower(request.user)
|
||||
|
||||
except Rower.DoesNotExist:
|
||||
raise Http404("Rower doesn't exist")
|
||||
|
||||
if not checkaccessplanuser(request.user,r):
|
||||
raise PermissionDenied("You have no access to this user")
|
||||
|
||||
if notpermanent == False:
|
||||
request.session['rowerid'] = r.id
|
||||
|
||||
return r
|
||||
|
||||
|
||||
def getrower(user):
|
||||
try:
|
||||
@@ -911,7 +944,7 @@ from rowers.utils import (
|
||||
|
||||
import rowers.datautils as datautils
|
||||
|
||||
from rowers.models import checkworkoutuser,checkaccessuser
|
||||
from rowers.models import checkworkoutuser,checkaccessuser,checkviewworkouts
|
||||
|
||||
# Check if a user is a Coach member
|
||||
def iscoachmember(user):
|
||||
|
||||
@@ -186,15 +186,22 @@ def rower_teams_view(request,message='',successmessage=''):
|
||||
invitedcoaches = [rekwest.coach for rekwest in mycoachrequests]
|
||||
|
||||
coaches = teams.rower_get_coaches(r)
|
||||
potentialcoaches = [t.manager for t in memberteams if t.manager not in coaches ]
|
||||
potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches]
|
||||
print coaches,'aap'
|
||||
|
||||
potentialcoaches = [t.manager for t in memberteams if t.manager not in coaches and t.manager.rower.rowerplan == 'coach']
|
||||
potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches+coaches]
|
||||
|
||||
|
||||
coachees = teams.coach_getcoachees(r)
|
||||
|
||||
potentialathletes = Rower.objects.filter(
|
||||
team__in=myteams).exclude(
|
||||
user__in=invitedathletes).exclude(
|
||||
user=request.user
|
||||
).exclude(coachinggroups__in=[request.user.rower.mycoachgroup])
|
||||
if request.user.rower.rowerplan == 'coach':
|
||||
potentialathletes = Rower.objects.filter(
|
||||
team__in=myteams).exclude(
|
||||
user__in=invitedathletes).exclude(
|
||||
user=request.user
|
||||
).exclude(coachinggroups__in=[request.user.rower.mycoachgroup])
|
||||
else:
|
||||
potentialathletes = []
|
||||
|
||||
|
||||
# clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user)
|
||||
|
||||
@@ -856,7 +856,7 @@ def virtualevent_compare_view(request,id=0):
|
||||
workouts = []
|
||||
for id in workoutids:
|
||||
try:
|
||||
workouts.append(Workout.objects.get(id=encode.decode_hex(id)))
|
||||
workouts.append(Workout.objects.get(id=id))
|
||||
except Workout.DoesNotExist:
|
||||
pass
|
||||
|
||||
@@ -1157,7 +1157,7 @@ def workouts_view(request,message='',successmessage='',
|
||||
r = getrequestrower(request,rowerid=rowerid,userid=userid)
|
||||
|
||||
# check if access is allowed
|
||||
if not checkaccessuser(request.user,r):
|
||||
if not checkviewworkouts(request.user,r):
|
||||
raise PermissionDenied("Access denied")
|
||||
|
||||
if startdatestring:
|
||||
|
||||
@@ -75,6 +75,7 @@ urlpatterns += [
|
||||
url(r'^twitter\_callback',rowersviews.rower_process_twittercallback),
|
||||
url(r'^i18n/', include('django.conf.urls.i18n')),
|
||||
url(r'^tz_detect/', include('tz_detect.urls')),
|
||||
url(r'^jsi18n/', 'django.views.i18n.javascript_catalog',name='jsi18n'),
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<title>{% block title %}Rowsandall Rowing Data Analytics{% endblock %}</title>
|
||||
{% block scripts %} {% endblock %}
|
||||
|
||||
<script type="text/javascript" src="/admin/jsi18n/"></script>
|
||||
<script type="text/javascript" src="/jsi18n/"></script>
|
||||
<script type="text/javascript" src="/static/admin/js/core.js"></script>
|
||||
<script type="text/javascript" src="/static/admin/js/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="/static/admin/js/jquery.init.js"></script>
|
||||
@@ -31,7 +31,9 @@
|
||||
|
||||
<link rel="stylesheet" href="/static/css/bokeh-0.12.3.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="/static/css/bokeh-widgets-0.12.3.min.css" type="text/css" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/static/admin/css/forms.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/static/admin/css/widgets.css"/>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" >
|
||||
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon" />
|
||||
<link rel="icon" sizes="32x32" href="/static/img/favicon-32x32.png" type="image/png"/>
|
||||
<link rel="icon" sizes="64x64" href="/static/img/favicon-64x64.png" type="image/png"/>
|
||||
|
||||
Reference in New Issue
Block a user