Private
Public Access
1
0

athlete edit permissions in place

This commit is contained in:
Sander Roosendaal
2019-02-16 10:31:47 +01:00
parent 259d6f28bb
commit 6afde11b7c
8 changed files with 121 additions and 13 deletions

View File

@@ -167,6 +167,11 @@ def update_subscription(rower,data,method='up'):
l = rower.user.last_name,
)
if rower.paidplan != 'coach':
coachees = Rower.objects.filter(coach__in=[rower]).distinct()
for coachee in coachees:
coachee.coaches.remove(rower)
if method == 'up':
transactions = result.subscription.transactions

View File

@@ -340,6 +340,7 @@ class Team(models.Model):
viewing = models.CharField(max_length=30,choices=viewchoices,default='allmembers',verbose_name='Sharing Behavior')
def __unicode__(self):
return self.name
@@ -831,6 +832,7 @@ class Rower(models.Model):
# Friends/Team
friends = models.ManyToManyField("self",blank=True)
coaches = models.ManyToManyField("self",blank=True)
privacy = models.CharField(default='visible',max_length=30,
choices=privacychoices)
@@ -986,12 +988,12 @@ def checkworkoutuser(user,workout):
return False
try:
r = Rower.objects.get(user=user)
teams = workout.team.all()
coaches = user.rower.coaches.filter(rowerplan='coach')
if workout.user == r:
return True
elif teams:
for team in teams:
if user == team.manager and workout.privacy == 'visible':
elif coaches:
for coach in coaches:
if user.rower == coach and workout.privacy == 'visible':
return True
else:
return False
@@ -1003,17 +1005,17 @@ def checkworkoutuser(user,workout):
def checkaccessuser(user,rower):
try:
r = Rower.objects.get(user=user)
teams = Team.objects.filter(manager=user)
if rower == r:
return True
elif teams:
for team in teams:
if team in rower.team.all():
coaches = rower.coaches.filter(rowerplan='coach')
if coaches:
for coach in coaches:
if user.rower == coach:
return True
else:
return False
except Rower.DoesNotExist:
return False
return False
timezones = (
(x,x) for x in pytz.common_timezones

View File

@@ -102,6 +102,11 @@ def remove_team(id):
return (1,'Updated rower team expiry')
def add_coach(manager,rower):
rower.coaches.add(m)
return (1,"Added Coach")
def add_member(id,rower):
t= Team.objects.get(id=id)
try:
@@ -414,6 +419,7 @@ def process_request_code(manager,code):
result = add_member(t.id,r)
if not result:
return (result,"The member couldn't be added")
send_request_accept_email(rekwest)
@@ -439,6 +445,7 @@ def process_invite_code(user,code):
if not result:
return (result,"The member couldn't be added")
send_invite_accept_email(invitation)
invitation.delete()
return result

View File

@@ -376,6 +376,15 @@ def team_rowers(user):
return []
@register.filter
def coach_rowers(user):
try:
members = Rower.objects.filter(coaches__in=user.rower).distinct().order_by(
"user__last_name","user__last_name"
)
return members
except TypeError:
return []
@register.filter
def verbosetimeperiod(timeperiod):

View File

@@ -455,9 +455,10 @@ class PermissionsViewTests(TestCase):
## Coach can edit on behalf of athlete
## Coach can edit on behalf of athlete if permitted
def test_coach_edit_athlete_settings(self):
self.rbasic.team.add(self.teamcoach)
self.rbasic.coaches.add(self.rcoach)
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
self.assertTrue(login)
@@ -467,10 +468,22 @@ class PermissionsViewTests(TestCase):
response = self.c.get(url)
self.assertEqual(response.status_code,200)
def test_coach_edit_athlete_settings_not(self):
self.rbasic.team.add(self.teamcoach)
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
self.assertTrue(login)
url = reverse('rower_prefs_view',kwargs={'userid':self.ubasic.id})
response = self.c.get(url)
self.assertEqual(response.status_code,403)
## Coach can run analytics for athlete
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
def test_coach_edit_athlete_analysis(self,mocked_df):
self.rbasic.team.add(self.teamcoach)
self.rbasic.coaches.add(self.rcoach)
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
self.assertTrue(login)
@@ -486,12 +499,31 @@ class PermissionsViewTests(TestCase):
self.assertEqual(response.status_code,200)
@patch('rowers.dataprep.read_cols_df_sql', side_effect = mocked_read_df_cols_sql_multistats)
def test_coach_edit_athlete_analysis_not(self,mocked_df):
self.rbasic.team.add(self.teamcoach)
## Coach can upload on behalf of athlete
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
self.assertTrue(login)
url = reverse('cumstats',
kwargs={
'theuser':self.ubasic.id,
}
)
response = self.c.get(url)
self.assertEqual(response.status_code,403)
## Coach can upload on behalf of athlete - if team allows
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db)
def test_coach_edit_athlete_upload(self,mocked_sqlalchemy,mocked_getsmallrowdata_db):
self.rbasic.team.add(self.teamcoach)
self.rbasic.coaches.add(self.rcoach)
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
self.assertTrue(login)
@@ -531,6 +563,50 @@ class PermissionsViewTests(TestCase):
self.assertEqual(aantal2,aantal+1)
## Coach can upload on behalf of athlete - if team allows
@patch('rowers.dataprep.create_engine')
@patch('rowers.dataprep.getsmallrowdata_db',side_effect=mocked_getsmallrowdata_db)
def test_coach_edit_athlete_uploadnot(self,mocked_sqlalchemy,mocked_getsmallrowdata_db):
self.rbasic.team.add(self.teamcoach)
login = self.c.login(username=self.ucoach.username, password=self.ucoachpassword)
self.assertTrue(login)
url = reverse('team_workout_upload_view')
aantal = len(Workout.objects.filter(user=self.rbasic))
response = self.c.get(url)
self.assertEqual(response.status_code,200)
filename = 'rowers/tests/testdata/testdata.csv'
f = open(filename,'rb')
file_data = {'file': f}
form_data = {
'title':'test',
'workouttype':'rower',
'boattype':'1x',
'notes':'aap noot mies',
'make_plot':False,
'upload_to_c2':False,
'plottype':'timeplot',
'file': f,
'user': self.ubasic.id
}
response = self.c.post(url, form_data, follow=True)
f.close()
self.assertEqual(response.status_code,200)
self.assertRedirects(response,
expected_url = url,
status_code=302,target_status_code=200)
aantal2 = len(Workout.objects.filter(user=self.rbasic))
self.assertEqual(aantal2,aantal)
## Coach can edit athlete's workout
def test_coach_edit_athlete_workout(self):
self.rbasic.team.add(self.teamcoach)

View File

@@ -404,6 +404,12 @@ def isprorower(r):
result = r.rowerplan == 'basic' and r.protrialexpires >= datetime.date.today()
return result
def iscoach(m,r):
result = False
result = m in r.coaches
return result
# Exponentially weighted moving average
# Used for data smoothing of the jagged data obtained by Strava

View File

@@ -267,6 +267,7 @@ def team_requestmembership_view(request,teamid,userid):
messages.info(request,text)
else:
messages.error(request,text)
url = reverse('team_view',kwargs={
'id':int(teamid),

View File

@@ -4235,16 +4235,18 @@ def team_workout_upload_view(request,message="",
rowerform = TeamInviteForm(request.POST)
rowerform.fields.pop('email')
rowerform.fields['user'].queryset = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct()
rowers = Rower.objects.filter(coaches__in=[request.user.rower]).distinct()
rowerform.fields['user'].queryset = User.objects.filter(rower__in=rowers).distinct()
if form.is_valid():
f = request.FILES['file']
res = handle_uploaded_file(f)
t = form.cleaned_data['title']
offline = form.cleaned_data['offline']
boattype = form.cleaned_data['boattype']
workouttype = form.cleaned_data['workouttype']
if rowerform.is_valid():
u = rowerform.cleaned_data['user']
if u:
if u and request.user.rower in u.rower.coaches.all():
r = getrower(u)
else:
message = 'Please select a rower'