From 3739cdbda9003f31acf09dd799e7261b3b09ce77 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 25 Oct 2018 15:08:44 +0200 Subject: [PATCH 01/11] comparison with preselected workout --- rowers/templates/menu_workout.html | 10 ++-- rowers/templates/team_compare_select.html | 61 ++++++++++------------- rowers/urls.py | 8 ++- rowers/views.py | 60 +++++++++++++++++----- 4 files changed, 84 insertions(+), 55 deletions(-) diff --git a/rowers/templates/menu_workout.html b/rowers/templates/menu_workout.html index d79def7f..937218e7 100644 --- a/rowers/templates/menu_workout.html +++ b/rowers/templates/menu_workout.html @@ -41,13 +41,11 @@  Statistics - + {% if user.is_authenticated and workout|may_edit:request %}
  • diff --git a/rowers/templates/team_compare_select.html b/rowers/templates/team_compare_select.html index abdde333..133f62e4 100644 --- a/rowers/templates/team_compare_select.html +++ b/rowers/templates/team_compare_select.html @@ -83,6 +83,31 @@ your workouts. That makes it easy to search.

  • +
  • +
    + + {{ dateform.as_table }} +
    + + {{ modalityform.as_table }} +
    + {% csrf_token %} +

    + +

    +
    +
  • +
  • +
    + + +
    +
  • {% if workouts %}
    @@ -109,42 +134,6 @@

  • -
  • - {% if team %} -
    - {% else %} - - {% endif %} - - {{ dateform.as_table }} -
    - - {{ modalityform.as_table }} -
    - {% csrf_token %} -

    - -

    -
    -
  • -
  • - {% if team %} -
    - {% else %} - - {% endif %} - - -
    -
  • {% endblock %} diff --git a/rowers/urls.py b/rowers/urls.py index d9856a97..18cc1ae3 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -156,8 +156,13 @@ urlpatterns = [ url(r'^courses/upload$',views.course_upload_view), url(r'^addmanual/$',views.addmanual_view), url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)$',views.team_comparison_select), - url(r'^team-compare-select/team/(?P\d+)/$',views.team_comparison_select), + url(r'^team-compare-select/workout/(?P\d+)/team/(?P\d+)/$',views.team_comparison_select), + url(r'^team-compare-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)$',views.team_comparison_select), + url(r'^team-compare-select/workout/(?P\d+)/team/(?P\d+)/$',views.team_comparison_select), + url(r'^team-compare-select/workout/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)$',views.team_comparison_select), url(r'^team-compare-select/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)$',views.team_comparison_select), + url(r'^team-compare-select/workout/(?P\d+)/$',views.team_comparison_select), + url(r'^team-compare-select/team/(?P\d+)$',views.team_comparison_select), url(r'^team-compare-select/$',views.team_comparison_select), url(r'^workouts-join-select/team/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)$',views.workouts_join_select), url(r'^workouts-join$',views.workouts_join_view), @@ -328,6 +333,7 @@ urlpatterns = [ url(r'^workout/(?P\d+)/runkeeperuploadw/$',views.workout_runkeeper_upload_view), url(r'^workout/(?P\d+)/underarmouruploadw/$',views.workout_underarmour_upload_view), url(r'^workout/(?P\d+)/tpuploadw/$',views.workout_tp_upload_view), + url(r'^multi-compare/workout/(?P\d+)$',views.multi_compare_view), url(r'^multi-compare$',views.multi_compare_view), url(r'^user-boxplot/user/(?P\d+)$',views.boxplot_view), url(r'^user-boxplot$',views.boxplot_view), diff --git a/rowers/views.py b/rowers/views.py index 98b2d564..f0cda92f 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -5250,6 +5250,7 @@ def team_comparison_select(request, successmessage='', startdate=timezone.now()-datetime.timedelta(days=30), enddate=timezone.now(), + id=0, teamid=0): try: @@ -5371,7 +5372,7 @@ def team_comparison_select(request, if rankingonly: workouts = [w for w in workouts if w.rankingpiece] - + query = request.GET.get('q') if query: query_list = query.split() @@ -5382,8 +5383,22 @@ def team_comparison_select(request, (Q(notes__icontains=q) for q in query_list)) ) + if id: + firstworkout = get_workout(id) + if not checkworkoutuser(request.user,firstworkout): + raise PermissionDenied("You are not allowed to sue this workout") + + firstworkoutquery = Workout.objects.filter(id=id) + workouts = firstworkoutquery | workouts + else: + firstworkout = None + form = WorkoutMultipleCompareForm() form.fields["workouts"].queryset = workouts + if id: + form.fields["workouts"].initial = [firstworkout] + + if theteam: theid = theteam.id @@ -5396,20 +5411,38 @@ def team_comparison_select(request, messages.error(request,message) r = getrower(request.user) - breadcrumbs = [ - { - 'url':'/rowers/list-workouts', - 'name':'Workouts' - }, - { - 'url':reverse(team_comparison_select,kwargs={'teamid':teamid}), - 'name': 'Compare Select' - }, + if id: + breadcrumbs = [ + { + 'url':'/rowers/list-workouts', + 'name':'Workouts' + }, + { + 'url':get_workout_default_page(request,id), + 'name': str(id) + }, + { + 'url':reverse(team_comparison_select,kwargs={'id':id,'teamid':teamid}), + 'name':'Compare Select' + }, ] + else: + breadcrumbs = [ + { + 'url':'/rowers/list-workouts', + 'name':'Workouts' + }, + { + 'url':reverse(team_comparison_select,kwargs={'teamid':teamid}), + 'name': 'Compare Select' + }, + + ] return render(request, 'team_compare_select.html', {'workouts': workouts, + 'workout':firstworkout, 'dateform':dateform, 'startdate':startdate, 'enddate':enddate, @@ -5426,7 +5459,7 @@ def team_comparison_select(request, # Team comparison @login_required() -def multi_compare_view(request): +def multi_compare_view(request,id=0): promember=0 if not request.user.is_anonymous(): r = getrower(request.user) @@ -5542,7 +5575,10 @@ def multi_compare_view(request): }) else: - url = reverse(workouts_view) + url = reverse(team_comparison_select, + kwargs={ + 'id':id, + 'teamid':0}) return HttpResponseRedirect(url) # Multi Flex Chart with Grouping From 929144cc560a9589c3944078d50b2eb12cc3422d Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Thu, 25 Oct 2018 15:16:26 +0200 Subject: [PATCH 02/11] added new url to tests.py --- rowers/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rowers/tests.py b/rowers/tests.py index cab8224b..dde45976 100644 --- a/rowers/tests.py +++ b/rowers/tests.py @@ -2137,6 +2137,7 @@ class URLTests(TestCase): '/rowers/sessions/teamcreate/', '/rowers/sessions/user/1', '/rowers/team-compare-select/', + '/rowers/team-compare-select/workout/1', '/rowers/team-compare-select/2016-01-01/2016-12-31', '/rowers/test-job/2', '/rowers/test-job2/2', From 4e0db6e2e0f8938521b7acacbe31815d37d183eb Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 26 Oct 2018 08:10:01 +0200 Subject: [PATCH 03/11] replaced i with em in sessions table --- rowers/templates/plannedsessions.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rowers/templates/plannedsessions.html b/rowers/templates/plannedsessions.html index cbff280b..e4c7e514 100644 --- a/rowers/templates/plannedsessions.html +++ b/rowers/templates/plannedsessions.html @@ -100,7 +100,7 @@ {{ actualvalue|lookup:ps.id }} {{ ps.sessionunit }} {% if completeness|lookup:ps.id == 'partial' %} - {{ completiondate|lookup:ps.id|date:"Y-m-d" }} + {{ completiondate|lookup:ps.id|date:"Y-m-d" }} {% else %} {{ completiondate|lookup:ps.id|date:"Y-m-d" }} {% endif %} From d85a1a70453fccc57a35ac3f6e6b780ced2dfef6 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 26 Oct 2018 09:17:19 +0200 Subject: [PATCH 04/11] favorite charts by workout source --- rowers/models.py | 10 ++++-- rowers/mytypes.py | 7 +++-- rowers/templates/workout_form.html | 4 ++- rowers/uploads.py | 2 +- rowers/views.py | 49 +++++++++++++++++++----------- templates/newbase.html | 2 +- 6 files changed, 47 insertions(+), 27 deletions(-) diff --git a/rowers/models.py b/rowers/models.py index 4d968e96..880efd19 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -751,11 +751,14 @@ parchoicesx = list(sorted(favchartlabelsx.items(), key = lambda x:x[1])) # Saving a chart as a favorite chart class FavoriteChart(models.Model): - workouttypechoices = ( + workouttypechoices = [ ('ote','Erg/SkiErg'), ('otw','On The Water'), - ('both','both') - ) + ('all','All') + ] + + for workoutsource in mytypes.workoutsources: + workouttypechoices.append(workoutsource) plottypes = ( ('line','Line Chart'), @@ -771,6 +774,7 @@ class FavoriteChart(models.Model): workouttype = models.CharField(max_length=50,choices=workouttypechoices, default='both', verbose_name='Workout Type') + reststrokes = models.BooleanField(default=True,verbose_name="Incl. Rest") notes = models.CharField(max_length=300,verbose_name='Chart Notes', default='Flex Chart Notes',blank=True) diff --git a/rowers/mytypes.py b/rowers/mytypes.py index c6a2165c..df0709ba 100644 --- a/rowers/mytypes.py +++ b/rowers/mytypes.py @@ -30,14 +30,14 @@ workoutsources = ( ('mapmyfitness','mapmyfitness'), ('csv','painsled'), ('tcx','tcx'), - ('rp','rp'), + ('rp','rowperfect'), ('mystery','mystery'), - ('tcxnohr','tcx (no HR)'), +# ('tcxnohr','tcx (no HR)'), ('rowperfect3','rowperfect3'), ('ergdata','ergdata'), ('boatcoach','boatcoach'), ('boatcoachotw','boatcoachotw'), - ('bcmike','boatcoach (develop)'), +# ('bcmike','boatcoach (develop)'), ('painsleddesktop','painsleddesktop'), ('speedcoach','speedcoach'), ('speedcoach2','speedcoach2'), @@ -52,6 +52,7 @@ boattypes = ( ('2-', '2- (pair)'), ('2+', '2+ (coxed pair)'), ('3x+','3x+ (coxed triple)'), + ('3x-','3x- (triple)'), ('4x', '4x (quad)'), ('4x+', '4x+ (coxed quad)'), ('4-', '4- (four)'), diff --git a/rowers/templates/workout_form.html b/rowers/templates/workout_form.html index 026721ab..72a8a0fe 100644 --- a/rowers/templates/workout_form.html +++ b/rowers/templates/workout_form.html @@ -74,7 +74,9 @@ $('#id_workouttype').change(); Duration:{{ workout.duration |durationprint:"%H:%M:%S.%f" }} - Public link to this workout + Source:{{ workout.workoutsource }} + + Public link to this workout:
    https://rowsandall.com/rowers/workout/{{ workout.id }} diff --git a/rowers/uploads.py b/rowers/uploads.py index 676e481c..cce0324a 100644 --- a/rowers/uploads.py +++ b/rowers/uploads.py @@ -26,7 +26,7 @@ queue = django_rq.get_queue('default') queuelow = django_rq.get_queue('low') queuehigh = django_rq.get_queue('low') -from mytypes import workouttypes,boattypes,otwtypes +from mytypes import workouttypes,boattypes,otwtypes,workoutsources try: from cStringIO import StringIO diff --git a/rowers/views.py b/rowers/views.py index f0cda92f..ad6d06cc 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -8755,6 +8755,34 @@ def workout_workflow_config2_view(request,userid=0): }) +def getfavorites(r,row): + workouttype = 'ote' + if row.workouttype in mytypes.otwtypes: + workouttype = 'otw' + + matchworkouttypes = [workouttype,'all'] + + workoutsource = row.workoutsource + if 'speedcoach2' in row.workoutsource: + workoutsource = 'speedcoach2' + + try: + favorites = FavoriteChart.objects.filter(user=r, + workouttype__in=matchworkouttypes).order_by("id") + favorites2 = FavoriteChart.objects.filter(user=r, + workouttype__in=[workoutsource]).order_by("id") + + favorites = favorites | favorites2 + + + maxfav = len(favorites)-1 + except: + favorites = None + maxfav = 0 + + return favorites,maxfav + + # Workflow View @login_required() def workout_workflow_view(request,id): @@ -8774,17 +8802,8 @@ def workout_workflow_view(request,id): aantalcomments = len(comments) - workouttype = 'ote' - if row.workouttype in mytypes.otwtypes: - workouttype = 'otw' - - try: - favorites = FavoriteChart.objects.filter(user=r, - workouttype__in=[workouttype,'both']).order_by("id") - maxfav = len(favorites)-1 - except: - favorites = None - maxfav = 0 + favorites,maxfav = getfavorites(r,row) + charts = get_call() @@ -8889,13 +8908,7 @@ def workout_flexchart3_view(request,*args,**kwargs): if row.workouttype in mytypes.otwtypes: workouttype = 'otw' - try: - favorites = FavoriteChart.objects.filter(user=r, - workouttype__in=[workouttype,'both']).order_by("id") - maxfav = len(favorites)-1 - except: - favorites = None - maxfav = 0 + favorites,maxfav = getfavorites(r,row) # check if favoritenr is not out of range if favorites: diff --git a/templates/newbase.html b/templates/newbase.html index c9390afa..adc34d96 100644 --- a/templates/newbase.html +++ b/templates/newbase.html @@ -149,7 +149,7 @@ {% if user.is_authenticated %}
  • - + {% if user.rower.rowerplan == 'pro' %} {% elif user.rower.rowerplan == 'coach' %} From c8bcf55cd57a1d72886c832f11adc546a7dbc5f3 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 26 Oct 2018 09:34:13 +0200 Subject: [PATCH 05/11] adding workoutsource where forgotten --- rowers/dataprep.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rowers/dataprep.py b/rowers/dataprep.py index 70537eeb..06005873 100644 --- a/rowers/dataprep.py +++ b/rowers/dataprep.py @@ -846,7 +846,8 @@ def save_workout_database(f2, r, dosmooth=True, workouttype='rower', pass return new_workout_from_df(r, newdf, title=title,boattype=boattype, - workouttype=workouttype) + workouttype=workouttype, + workoutsource=workoutsource) try: checks = row.check_consistency() allchecks = 1 @@ -1403,7 +1404,7 @@ def new_workout_from_df(r, df, oarlength = parent.oarlength inboard = parent.inboard - + workoutsource = parent.workoutsource workouttype = parent.workouttype boattype = parent.boattype notes = parent.notes @@ -1451,6 +1452,7 @@ def new_workout_from_df(r, df, workouttype=workouttype, boattype=boattype, title=title, + workoutsource=workoutsource, notes=notes, oarlength=oarlength, inboard=inboard, From 96ff340bb3c7b39f5395c50a1abec4594a69bab5 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 26 Oct 2018 12:33:57 +0200 Subject: [PATCH 06/11] distinguishing between plan manager and plan athlete --- rowers/models.py | 6 +++-- rowers/templates/trainingplan.html | 14 ++++++++++ rowers/templatetags/rowerfilters.py | 28 +++++++++++++++++-- rowers/views.py | 42 ++++++++++++++++++++++------- 4 files changed, 76 insertions(+), 14 deletions(-) diff --git a/rowers/models.py b/rowers/models.py index 880efd19..f45fea10 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -934,7 +934,8 @@ def a_week_from_now(): # models related to training planning - draft # Do we need a separate class TestTarget? class TrainingTarget(models.Model): - rower = models.ForeignKey(Rower) + rower = models.ForeignKey(Rower,related_name='targetathlete') + manager = models.ForeignKey(Rower,related_name='targetmanager',null=True) name = models.CharField(max_length=150,blank=True) date = models.DateField( default=half_year_from_now) @@ -982,7 +983,8 @@ class TrainingTargetForm(ModelForm): class TrainingPlan(models.Model): - rower = models.ForeignKey(Rower) + rower = models.ForeignKey(Rower,related_name='planathlete') + manager = models.ForeignKey(Rower,related_name='planmanager',null=True) name = models.CharField(max_length=150,blank=True) target = models.ForeignKey(TrainingTarget,blank=True,null=True) startdate = models.DateField(default=timezone.now) diff --git a/rowers/templates/trainingplan.html b/rowers/templates/trainingplan.html index a7cdab89..3d1b853a 100644 --- a/rowers/templates/trainingplan.html +++ b/rowers/templates/trainingplan.html @@ -12,7 +12,9 @@ The training plan target is: {{ plan.target.name }} on {{ plan.target.date }}. {% endif %}

    +{% if plan|mayeditplan:request %}

    Edit the plan

    +{% endif %}

    Plan Macro, Meso and Micro Cycles

    @@ -39,10 +41,12 @@ + {% if macrocycle.0|mayeditplan:request %} edit / delete / + {% endif %} sessions @@ -95,10 +99,12 @@ + {% if macrocycle.0|mayeditplan:request %} edit / delete / + {% endif %} sessions @@ -140,10 +146,12 @@ + {% if mesocycle.0|mayeditplan:request %} edit / delete / + {% endif %} sessions @@ -197,10 +205,12 @@ + {% if mesocycle.0|mayeditplan:request %} edit / delete / + {% endif %} sessions @@ -247,10 +257,12 @@ + {% if microcycle|mayeditplan:request %} edit / delete / + {% endif %} sessions @@ -306,10 +318,12 @@ + {% if microcycle|mayeditplan:request %} edit / delete / + {% endif %} sessions diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index cad2e1f6..b52f9f5b 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -10,7 +10,8 @@ register = template.Library() from rowers.utils import calculate_age from rowers.models import ( course_length,WorkoutComment, - TrainingMacroCycle,TrainingMesoCycle, TrainingMicroCycle + TrainingMacroCycle,TrainingMesoCycle, TrainingMicroCycle, + Rower ) from rowers.plannedsessions import ( race_can_register, race_can_submit,race_rower_status @@ -19,7 +20,7 @@ from rowers.plannedsessions import ( from rowers import c2stuff, runkeeperstuff from rowers.c2stuff import c2_open from rowers.runkeeperstuff import runkeeper_open - +from rowers.models import checkaccessuser from rowers.mytypes import otwtypes from rowers.utils import NoTokenError @@ -182,6 +183,29 @@ def may_edit(workout,request): return mayedit + + +@register.filter +def mayeditplan(obj,request): + + if obj is None: + return False + + if hasattr(obj,'plan'): + return mayeditplan(obj.plan,request) + + if hasattr(obj,'manager'): + if obj.manager is not None: + return request.user == obj.manager.user + + rr = Rower.objects.get(user=request.user) + if checkaccessuser(request.user,obj.rower) and rr.rowerplan not in ['basic','pro']: + mayedit = True + + + return mayedit + + @register.filter(name='times') def times(number): return range(number) diff --git a/rowers/views.py b/rowers/views.py index ad6d06cc..20b6288a 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -9017,7 +9017,6 @@ def workout_flexchart3_view(request,*args,**kwargs): else: print flexaxesform.errors - print xparam,yparam1,yparam2 if not promember: for name,d in rowingmetrics: @@ -16089,6 +16088,7 @@ def rower_create_trainingplan(request,userid=0): therower = getrequestrower(request,userid=userid) theuser = therower.user + themanager = getrower(request.user) if request.method == 'POST' and 'date' in request.POST: targetform = TrainingTargetForm(request.POST) @@ -16100,6 +16100,7 @@ def rower_create_trainingplan(request,userid=0): t = TrainingTarget(rower=therower, name=name, date=date, + manager=themanager, notes=notes) t.save() @@ -16116,6 +16117,7 @@ def rower_create_trainingplan(request,userid=0): name=name, rower=therower, target=target, + manager=themanager, startdate=startdate, enddate=enddate, ) @@ -16164,7 +16166,7 @@ def rower_delete_trainingtarget(request,id=0): except TrainingPlan.DoesNotExist: raise Http404("Training Plan Does Not Exist") - if checkaccessuser(request.user,target.rower): + if checkaccessuser(request.user,target.manager): target.delete() messages.info(request,"We have deleted the training target") else: @@ -16184,7 +16186,7 @@ def rower_delete_trainingplan(request,id=0): except TrainingPlan.DoesNotExist: raise Http404("Training Plan Does Not Exist") - if checkaccessuser(request.user,plan.rower): + if checkaccessuser(request.user,plan.manager): plan.delete() messages.info(request,"We have deleted the training plan") else: @@ -16201,7 +16203,7 @@ class TrainingPlanDelete(DeleteView): def get_object(self, *args, **kwargs): obj = super(TrainingPlanDelete, self).get_object(*args, **kwargs) - if not checkaccessuser(self.request.user,obj.rower): + if not checkaccessuser(self.request.user,obj.manager): raise PermissionDenied('You are not allowed to delete this training plan') return obj @@ -16267,7 +16269,7 @@ class MicroCycleDelete(DeleteView): def get_object(self, *args, **kwargs): obj = super(MicroCycleDelete, self).get_object(*args, **kwargs) - if not checkaccessuser(self.request.user,obj.plan.plan.plan.rower): + if not checkaccessuser(self.request.user,obj.plan.plan.plan.manager): raise PermissionDenied('You are not allowed to delete this training plan cycle') return obj @@ -16328,7 +16330,8 @@ class MesoCycleDelete(DeleteView): def get_object(self, *args, **kwargs): obj = super(MesoCycleDelete, self).get_object(*args, **kwargs) - if not checkaccessuser(self.request.user,obj.plan.plan.rower): + + if not checkaccessuser(self.request.user,obj.plan.plan.manager): raise PermissionDenied('You are not allowed to delete this training plan cycle') return obj @@ -16481,15 +16484,12 @@ class MacroCycleDelete(DeleteView): def get_object(self, *args, **kwargs): obj = super(MacroCycleDelete, self).get_object(*args, **kwargs) - if not checkaccessuser(self.request.user,obj.plan.rower): + if not checkaccessuser(self.request.user,obj.plan.manager): raise PermissionDenied('You are not allowed to delete this training plan cycle') return obj -@user_passes_test(hasplannedsessions,login_url="/rowers/promembership", - message="This functionality requires a Coach or Self-Coach plan", - redirect_field_name=None) def rower_trainingplan_view(request, id=0, userid=0, @@ -16725,6 +16725,9 @@ class TrainingMacroCycleUpdate(UpdateView): def get_object(self, *args, **kwargs): obj = super(TrainingMacroCycleUpdate, self).get_object(*args, **kwargs) + if obj.plan.manager is not None and self.request.user != obj.plan.manager: + raise PermissionDenied('You are not allowed to edit this training plan cycle') + if not checkaccessuser(self.request.user,obj.plan.rower): raise PermissionDenied('You are not allowed to edit this training plan cycle') else: @@ -16797,6 +16800,9 @@ class TrainingMesoCycleUpdate(UpdateView): def get_object(self, *args, **kwargs): obj = super(TrainingMesoCycleUpdate, self).get_object(*args, **kwargs) r = obj.plan.plan.rower + if obj.plan.plan.manager is not None and self.request.user != obj.plan.plan.manager: + raise PermissionDenied('You are not allowed to edit this training plan cycle') + if not checkaccessuser(self.request.user,r): raise PermissionDenied('You are not allowed to edit this training plan cycle') else: @@ -16875,6 +16881,9 @@ class TrainingMicroCycleUpdate(UpdateView): def get_object(self, *args, **kwargs): obj = super(TrainingMicroCycleUpdate, self).get_object(*args, **kwargs) r = obj.plan.plan.plan.rower + if obj.plan.plan.plan.manager is not None and self.request.user != obj.plan.plan.plan.manager.user: + raise PermissionDenied('You are not allowed to edit this training plan cycle') + if not checkaccessuser(self.request.user,r): raise PermissionDenied('You are not allowed to edit this training plan cycle') else: @@ -16896,11 +16905,16 @@ class TrainingPlanUpdate(UpdateView): form.instance.user = self.request.user form.instance.post_date = datetime.datetime.now() plan = form.save() + plan.manager = self.request.user.rower + plan.save() macrocyclecheckdates(plan) return super(TrainingPlanUpdate, self).form_valid(form) def get_object(self, *args, **kwargs): obj = super(TrainingPlanUpdate, self).get_object(*args, **kwargs) + if obj.manager is not None and self.request.user != obj.manager.user: + raise PermissionDenied('You are not allowed to edit this training plan cycle') + if not checkaccessuser(self.request.user,obj.rower): raise PermissionDenied('You are not allowed to edit this training plan cycle') return obj @@ -16921,7 +16935,15 @@ class TrainingTargetUpdate(UpdateView): def get_object(self, *args, **kwargs): obj = super(TrainingTargetUpdate, self).get_object(*args, **kwargs) + if obj.manager is not None and self.request.user != obj.manager.user: + raise PermissionDenied('You are not allowed to edit this training plan cycle') + if not checkaccessuser(self.request.user,obj.rower): raise PermissionDenied('You are not allowed to edit this training plan target') return obj +@user_passes_test(hasplannedsessions,login_url="/rowers/promembership", + message="This functionality requires a Coach or Self-Coach plan", + redirect_field_name=None) +def bla(): + pass From 8617156db5ac8fd01ca655c8329df86517d6fc69 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 26 Oct 2018 13:47:29 +0200 Subject: [PATCH 07/11] replan meso cycle by weeks --- rowers/templates/trainingplan.html | 4 ++ rowers/templatetags/rowerfilters.py | 2 +- rowers/urls.py | 2 + rowers/views.py | 96 ++++++++++++++++++++++++++--- 4 files changed, 96 insertions(+), 8 deletions(-) diff --git a/rowers/templates/trainingplan.html b/rowers/templates/trainingplan.html index 3d1b853a..97ffdffa 100644 --- a/rowers/templates/trainingplan.html +++ b/rowers/templates/trainingplan.html @@ -210,6 +210,10 @@ / delete / + + Replan by Weeks + + / {% endif %} sessions diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index b52f9f5b..c8f67040 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -187,7 +187,7 @@ def may_edit(workout,request): @register.filter def mayeditplan(obj,request): - + if obj is None: return False diff --git a/rowers/urls.py b/rowers/urls.py index 18cc1ae3..17401d1d 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -441,6 +441,8 @@ urlpatterns = [ name='macrocycle_update_view'), url(r'^mesocycle/(?P\d+)/$',views.TrainingMesoCycleUpdate.as_view(), name='mesocycle_update_view'), + url(r'^mesocycle/(?P\d+)/planbyweeks/$',views.planmesocyclebyweek), + url(r'^mesocycle/(?P\d+)/planbyweeks/user/(?P\d+)/$',views.planmesocyclebyweek), url(r'^microcycle/(?P\d+)/$',views.TrainingMicroCycleUpdate.as_view(), name='microcycle_update_view'), url(r'^deletetarget/(?P\d+)/$',views.rower_delete_trainingtarget), diff --git a/rowers/views.py b/rowers/views.py index 20b6288a..e2dc12fa 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -16725,7 +16725,7 @@ class TrainingMacroCycleUpdate(UpdateView): def get_object(self, *args, **kwargs): obj = super(TrainingMacroCycleUpdate, self).get_object(*args, **kwargs) - if obj.plan.manager is not None and self.request.user != obj.plan.manager: + if obj.plan.manager is not None and self.request.user.rower != obj.plan.manager: raise PermissionDenied('You are not allowed to edit this training plan cycle') if not checkaccessuser(self.request.user,obj.plan.rower): @@ -16800,7 +16800,7 @@ class TrainingMesoCycleUpdate(UpdateView): def get_object(self, *args, **kwargs): obj = super(TrainingMesoCycleUpdate, self).get_object(*args, **kwargs) r = obj.plan.plan.rower - if obj.plan.plan.manager is not None and self.request.user != obj.plan.plan.manager: + if obj.plan.plan.manager is not None and self.request.user.rower != obj.plan.plan.manager: raise PermissionDenied('You are not allowed to edit this training plan cycle') if not checkaccessuser(self.request.user,r): @@ -16881,7 +16881,7 @@ class TrainingMicroCycleUpdate(UpdateView): def get_object(self, *args, **kwargs): obj = super(TrainingMicroCycleUpdate, self).get_object(*args, **kwargs) r = obj.plan.plan.plan.rower - if obj.plan.plan.plan.manager is not None and self.request.user != obj.plan.plan.plan.manager.user: + if obj.plan.plan.plan.manager is not None and self.request.user.rower != obj.plan.plan.plan.manager: raise PermissionDenied('You are not allowed to edit this training plan cycle') if not checkaccessuser(self.request.user,r): @@ -16898,6 +16898,41 @@ class TrainingPlanUpdate(UpdateView): 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) @@ -16912,7 +16947,7 @@ class TrainingPlanUpdate(UpdateView): def get_object(self, *args, **kwargs): obj = super(TrainingPlanUpdate, self).get_object(*args, **kwargs) - if obj.manager is not None and self.request.user != obj.manager.user: + if obj.manager is not None and self.request.user.rower != obj.manager.user: raise PermissionDenied('You are not allowed to edit this training plan cycle') if not checkaccessuser(self.request.user,obj.rower): @@ -16935,15 +16970,62 @@ class TrainingTargetUpdate(UpdateView): def get_object(self, *args, **kwargs): obj = super(TrainingTargetUpdate, self).get_object(*args, **kwargs) - if obj.manager is not None and self.request.user != obj.manager.user: + if obj.manager is not None and self.request.user.rower != obj.manager.user: raise PermissionDenied('You are not allowed to edit this training plan cycle') if not checkaccessuser(self.request.user,obj.rower): raise PermissionDenied('You are not allowed to edit this training plan target') return obj +def allsundays(startdate,enddate): + d = startdate + d += timedelta(days = 6 - d.weekday()) # first Sunday + while d cycle.startdate: + monday = cycle.startdate + if nextsunday < cycle.enddate and i == len(sundays)-2: + nextsunday = cycle.enddate + micro = TrainingMicroCycle(startdate = monday, + enddate = nextsunday, + plan = cycle, + name = 'Week %s' % sundays[i+1].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 0a9b448e0481e3a52dec12d40b42acd84655669b Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Fri, 26 Oct 2018 15:06:30 +0200 Subject: [PATCH 08/11] added plan macro by months --- rowers/templates/trainingplan.html | 4 +++ rowers/urls.py | 2 ++ rowers/views.py | 53 ++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/rowers/templates/trainingplan.html b/rowers/templates/trainingplan.html index 97ffdffa..0af1b9e2 100644 --- a/rowers/templates/trainingplan.html +++ b/rowers/templates/trainingplan.html @@ -104,6 +104,10 @@ / delete / + + Replan by Months + + / {% endif %} sessions diff --git a/rowers/urls.py b/rowers/urls.py index 17401d1d..b9812719 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -441,6 +441,8 @@ urlpatterns = [ name='macrocycle_update_view'), url(r'^mesocycle/(?P\d+)/$',views.TrainingMesoCycleUpdate.as_view(), name='mesocycle_update_view'), + url(r'^macrocycle/(?P\d+)/planbymonths/$',views.planmacrocyclebymonth), + url(r'^macrocycle/(?P\d+)/planbymonths/user/(?P\d+)/$',views.planmacrocyclebymonth), url(r'^mesocycle/(?P\d+)/planbyweeks/$',views.planmesocyclebyweek), url(r'^mesocycle/(?P\d+)/planbyweeks/user/(?P\d+)/$',views.planmesocyclebyweek), url(r'^microcycle/(?P\d+)/$',views.TrainingMicroCycleUpdate.as_view(), diff --git a/rowers/views.py b/rowers/views.py index e2dc12fa..83f435a5 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -17027,5 +17027,58 @@ def planmesocyclebyweek(request,id=0,userid=0): 'thismicroid':str(micros[0].id)}) return HttpResponseRedirect(url) + + +def allmonths(startdate,enddate): + d = startdate + while d Date: Fri, 26 Oct 2018 15:10:59 +0200 Subject: [PATCH 09/11] small change --- rowers/views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/rowers/views.py b/rowers/views.py index 83f435a5..823e5e9d 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -17063,7 +17063,6 @@ def planmacrocyclebymonth(request,id=0,userid=0): if lastday < cycle.enddate and i == len(monthstarts)-2: lastday = cycle.enddate - print i,firstday,lastday,monthstarts[i],monthstarts[i+1] meso = TrainingMesoCycle(startdate = firstday, enddate = lastday, From f36cef9f7131c48ef85caf8d0c5aefd1083c546a Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 27 Oct 2018 17:10:52 +0200 Subject: [PATCH 10/11] menu unfolding on trainingplan --- rowers/templates/trainingplan.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rowers/templates/trainingplan.html b/rowers/templates/trainingplan.html index 0af1b9e2..ad728fb0 100644 --- a/rowers/templates/trainingplan.html +++ b/rowers/templates/trainingplan.html @@ -21,7 +21,7 @@
      {% for key, macrocycle in cycles.items %} -
    • +
      • @@ -127,7 +127,7 @@ {% endif %} -
      • +
        • @@ -237,7 +237,7 @@ {% endif %} -
        • +