diff --git a/rowers/admin.py b/rowers/admin.py
index fad8795b..7ef887fb 100644
--- a/rowers/admin.py
+++ b/rowers/admin.py
@@ -24,7 +24,7 @@ class RowerInline(admin.StackedInline):
('Billing Details',
{'fields':('street_address','city','postal_code','country','paymentprocessor','customer_id')}),
('Rower Plan',
- {'fields':('paidplan','rowerplan','paymenttype','planexpires','teamplanexpires','protrialexpires','plantrialexpires',)}),
+ {'fields':('paidplan','rowerplan','paymenttype','planexpires','teamplanexpires','protrialexpires','plantrialexpires','clubsize','offercoaching')}),
('Rower Settings',
{'fields':
('gdproptin','gdproptindate','weightcategory','sex','adaptiveclass','birthdate','getemailnotifications',
@@ -60,7 +60,7 @@ class RowerInline(admin.StackedInline):
#class UserAdmin(UserAdmin):
class UserAdmin(admin.ModelAdmin):
inlines = (RowerInline,)
- list_display = ('username','email','first_name','last_name','rowerplan')
+ list_display = ('username','email','first_name','last_name','rowerplan','clubsize')
fieldsets = (
('Personal info',
@@ -75,6 +75,9 @@ class UserAdmin(admin.ModelAdmin):
def rowerplan(self, obj):
return obj.rower.rowerplan
+ def clubsize(self, obj):
+ return obj.rower.clubsize
+
class WorkoutAdmin(admin.ModelAdmin):
list_display = ('date','user','name','workouttype','boattype')
diff --git a/rowers/management/commands/processemail.py b/rowers/management/commands/processemail.py
index 52022e06..7bf213f7 100644
--- a/rowers/management/commands/processemail.py
+++ b/rowers/management/commands/processemail.py
@@ -188,7 +188,7 @@ class Command(BaseCommand):
res = polarstuff.get_all_new_workouts(polar_available)
# Concept2
- rowers = Rower.objects.filter(c2_auto_import=True)
+ rowers = Rower.objects.filter(c2_auto_import=True).exclude(rowerplan='basic')
for r in rowers:
c2stuff.get_c2_workouts(r)
@@ -287,7 +287,7 @@ class Command(BaseCommand):
message.delete()
# Strava
- rowers = Rower.objects.filter(strava_auto_import=True)
+ rowers = Rower.objects.filter(strava_auto_import=True).exclude(rowerplan='basic')
for r in rowers:
stravastuff.get_strava_workouts(r)
diff --git a/rowers/models.py b/rowers/models.py
index 93dcfa58..ac7b00d1 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -1024,6 +1024,25 @@ def checkworkoutuser(user,workout):
except Rower.DoesNotExist:
return False
+# Check if workout may be viewed by this user
+def checkworkoutuserview(user,workout):
+ if user.is_anonymous():
+ return False
+ try:
+ r = Rower.objects.get(user=user)
+ if workout.user == r:
+ return True
+ teams = workout.user.team.all()
+
+ for team in teams:
+ if team in r.team.all():
+ return True
+ return False
+ except Rower.DoesNotExist:
+ return False
+
+ return False
+
def checkviewworkouts(user,rower):
try:
r = user.rower
diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py
index 756cf751..c8a2e2a8 100644
--- a/rowers/plannedsessions.py
+++ b/rowers/plannedsessions.py
@@ -473,13 +473,14 @@ def remove_rower_session(r,ps):
return 1
-def get_dates_timeperiod(request,startdatestring='',enddatestring=''):
+def get_dates_timeperiod(request,startdatestring='',enddatestring='',
+ defaulttimeperiod='thisweek'):
# set start end date according timeperiod
timeperiod = request.GET.get('when')
if not timeperiod:
- timeperiod = 'thisweek'
+ timeperiod = defaulttimeperiod
startdatestring = request.GET.get('startdate')
enddatestring = request.GET.get('enddate')
@@ -536,6 +537,10 @@ def get_dates_timeperiod(request,startdatestring='',enddatestring=''):
enddate = startdate+timezone.timedelta(days=32)
enddate = enddate.replace(day=1)
enddate = enddate-timezone.timedelta(days=1)
+ elif timeperiod=='lastyear':
+ today = date.today()
+ startdate = today-timezone.timedelta(days=365)
+ enddate = today+timezone.timedelta(days=1)
elif daterangetester.match(timeperiod):
tstartdatestring = daterangetester.match(timeperiod).group(1)
tenddatestring = daterangetester.match(timeperiod).group(2)
diff --git a/rowers/tasks.py b/rowers/tasks.py
index cbf98d8d..efc0cf44 100644
--- a/rowers/tasks.py
+++ b/rowers/tasks.py
@@ -68,6 +68,7 @@ from rowers.dataprepnodjango import (
# create_strava_stroke_data_db
)
+from rowers.opaque import encoder
from django.core.mail import (
send_mail,
@@ -1890,7 +1891,8 @@ def handle_sendemailnewresponse(first_name, last_name,
if 'sessiontype' in kwargs:
sessiontype=kwargs.pop('sessiontype')
- commentlink = '/rowers/workout/{workoutid}/comment/'.format(workoutid=workoutid)
+ commentlink = '/rowers/workout/{workoutid}/comment/'.format(
+ workoutid=encoder.encode_hex(workoutid))
if 'commentlink' in kwargs:
commentlink = kwargs.pop('commentlink')
@@ -1940,7 +1942,8 @@ def handle_sendemailnewcomment(first_name,
if 'sessiontype' in kwargs:
sessiontype=kwargs.pop('sessiontype')
- commentlink = '/rowers/workout/{workoutid}/comment/'.format(workoutid=workoutid)
+ commentlink = '/rowers/workout/{workoutid}/comment/'.format(
+ workoutid=encoder.encode_hex(workoutid))
if 'commentlink' in kwargs:
commentlink = kwargs.pop('commentlink')
@@ -1951,7 +1954,7 @@ def handle_sendemailnewcomment(first_name,
'comment':comment,
'workoutname':workoutname,
'siteurl':siteurl,
- 'workoutid':workoutid,
+ 'workoutid':encoder.encode_hex(workoutid),
'sessiontype':sessiontype,
'commentlink':commentlink,
}
diff --git a/rowers/teams.py b/rowers/teams.py
index d934b446..8980e8a8 100644
--- a/rowers/teams.py
+++ b/rowers/teams.py
@@ -111,16 +111,20 @@ def remove_team(id):
def add_coach(coach,rower):
# get coaching group
+
coachgroup = coach.mycoachgroup
if coachgroup is None:
coachgroup = CoachingGroup(name=coach.user.first_name)
coachgroup.save()
coach.mycoachgroup = coachgroup
coach.save()
-
- rower.coachinggroups.add(coach.mycoachgroup)
- return (1,"Added Coach")
+ if get_coach_club_size(coach)
- Looking for the downgrade option? + Looking for the upgrade option?
+ + Add, remove or change workouts for this session +
Please correct the error{{ form.errors|pluralize }} below.
diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py
index 83269444..e44015eb 100644
--- a/rowers/templatetags/rowerfilters.py
+++ b/rowers/templatetags/rowerfilters.py
@@ -470,7 +470,7 @@ def userurl(path,member):
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)
@@ -478,7 +478,7 @@ def userurl(path,member):
replaced = pattern.sub(userstring,path)
else:
replaced = path+userstring
-
+
return replaced
@register.filter
@@ -489,7 +489,7 @@ def teamurl(path,team):
# remove user
upattern = re.compile('\/user\/\d+/')
if upattern.search(path) is not None:
- path = upattern.sub('',path)
+ path = upattern.sub('/',path)
if pattern.search(path) is not None:
@@ -497,6 +497,7 @@ def teamurl(path,team):
else:
replaced = path+teamstring
+
return replaced
@register.filter
diff --git a/rowers/tests/test_permissions.py b/rowers/tests/test_permissions.py
index 4b1122fd..a84f7982 100644
--- a/rowers/tests/test_permissions.py
+++ b/rowers/tests/test_permissions.py
@@ -20,7 +20,7 @@ class PermissionsBasicsTests(TestCase):
self.rcoach = Rower.objects.create(user=self.ucoach,
birthdate=faker.profile()['birthdate'],
gdproptin=True,gdproptindate=timezone.now(),
- rowerplan='coach')
+ rowerplan='coach',clubsize=10)
self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach)
self.coachinggroup = CoachingGroup.objects.create()
@@ -280,7 +280,7 @@ class PermissionsViewTests(TestCase):
self.rcoach = Rower.objects.create(user=self.ucoach,
birthdate=faker.profile()['birthdate'],
gdproptin=True,gdproptindate=timezone.now(),
- rowerplan='coach')
+ rowerplan='coach',clubsize=10)
self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach)
self.coachinggroup = CoachingGroup.objects.create()
@@ -958,6 +958,31 @@ class PermissionsViewTests(TestCase):
response = self.c.get(url)
self.assertEqual(response.status_code,200)
+
+ # stats
+ url = reverse('workout_view',
+ kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)}
+ )
+
+ response = self.c.get(url)
+ self.assertEqual(response.status_code,200)
+
+ # workflow
+ url = reverse('workout_workflow_view',
+ kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)}
+ )
+
+ response = self.c.get(url)
+ self.assertEqual(response.status_code,200)
+
+ # stats
+ url = reverse('workout_stats_view',
+ kwargs={'id':encoder.encode_hex(self.uplan2_workouts[0].id)}
+ )
+
+ response = self.c.get(url)
+ self.assertEqual(response.status_code,200)
+
## Pro users (and higher) can join group led by other Pro (or higher) user
def test_team_member_request_pro_pro(self):
@@ -1009,7 +1034,7 @@ class PermissionsCoachingTests(TestCase):
self.rcoach = Rower.objects.create(user=self.ucoach,
birthdate=faker.profile()['birthdate'],
gdproptin=True,gdproptindate=timezone.now(),
- rowerplan='coach')
+ rowerplan='coach',clubsize=10)
self.ucoach_workouts = WorkoutFactory.create_batch(5, user=self.rcoach)
self.coachinggroup = CoachingGroup.objects.create()
@@ -1416,8 +1441,7 @@ class PermissionsCoachingTests(TestCase):
## 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
diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz
index ea8b8ca5..b6e2d423 100644
Binary files a/rowers/tests/testdata/testdata.csv.gz and b/rowers/tests/testdata/testdata.csv.gz differ
diff --git a/rowers/views/statements.py b/rowers/views/statements.py
index e7e2305e..3f1ec013 100644
--- a/rowers/views/statements.py
+++ b/rowers/views/statements.py
@@ -367,6 +367,14 @@ def get_workout_permitted(user,id):
return w
+def get_workout_permittedview(user,id):
+ w = get_workout(id)
+
+ if (checkworkoutuserview(user,w)==False):
+ raise PermissionDenied("Access denied")
+
+ return w
+
def getvalue(data):
perc = 0
total = 1
@@ -944,7 +952,9 @@ from rowers.utils import (
import rowers.datautils as datautils
-from rowers.models import checkworkoutuser,checkaccessuser,checkviewworkouts
+from rowers.models import (
+ checkworkoutuser,checkaccessuser,checkviewworkouts,checkworkoutuserview
+ )
# Check if a user is a Coach member
def iscoachmember(user):
diff --git a/rowers/views/teamviews.py b/rowers/views/teamviews.py
index 224a2ef7..0fff0eb4 100644
--- a/rowers/views/teamviews.py
+++ b/rowers/views/teamviews.py
@@ -189,7 +189,9 @@ def rower_teams_view(request,message='',successmessage=''):
coachrequests = CoachRequest.objects.filter(coach=r)
invitedathletes = [rekwest.user for rekwest in mycoachoffers]
- invitedcoaches = [rekwest.coach for rekwest in mycoachrequests]
+ invitedcoaches = [rekwest.coach for rekwest in mycoachrequests ]
+ invitedcoaches += [rekwest.coach for rekwest in coachoffers]
+ invitingathletes = [rekwest.user for rekwest in coachrequests]
coaches = teams.rower_get_coaches(r)
@@ -200,6 +202,7 @@ def rower_teams_view(request,message='',successmessage=''):
]
potentialcoaches = list(set(potentialcoaches+offercoaches))
potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches+coaches]
+ potentialcoaches = [c for c in potentialcoaches if teams.get_coach_club_size(c.rower)