diff --git a/rowers/forms.py b/rowers/forms.py index a63d62cb..3d5281d5 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -1,6 +1,6 @@ from django import forms from django.contrib.admin.widgets import FilteredSelectMultiple -from rowers.models import Workout,Rower,Team +from rowers.models import Workout,Rower,Team,PlannedSession from rowers.rows import validate_file_extension,must_be_csv,validate_image_extension from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User @@ -338,6 +338,15 @@ class DateRangeForm(forms.Form): class Meta: fields = ['startdate','enddate'] +class SessionDateShiftForm(forms.Form): + shiftstartdate = forms.DateField( + initial=timezone.now(), + widget=AdminDateWidget(), + label='Shift to start on') + + class Meta: + fields = ['shiftstartdate'] + # Form used to select workouts for the past N days class DeltaDaysForm(forms.Form): deltadays = forms.IntegerField(initial=7,required=False,label='') @@ -490,6 +499,13 @@ class WorkoutMultipleCompareForm(forms.Form): workouts = forms.ModelMultipleChoiceField(queryset=Workout.objects.all(), widget=forms.CheckboxSelectMultiple()) +class PlannedSessionMultipleCloneForm(forms.Form): + plannedsessions = forms.ModelMultipleChoiceField( + queryset=PlannedSession.objects.all(), + widget=forms.CheckboxSelectMultiple(), + label='Planned Sessions' + ) + from rowers.metrics import axlabels formaxlabels = axlabels.copy() diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 713e4145..b2b7811a 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -288,6 +288,10 @@ def get_dates_timeperiod(timeperiod): today = date.today() enddate = today-timezone.timedelta(days=today.weekday())-timezone.timedelta(days=1) startdate = enddate-timezone.timedelta(days=6) + elif timeperiod=='nextweek': + today = date.today() + enddate = today-timezone.timedelta(days=today.weekday())-timezone.timedelta(days=1)+timezone.timedelta(days=7) + startdate = enddate-timezone.timedelta(days=13) elif timeperiod=='lastmonth': today = date.today() startdate = today.replace(day=1) @@ -296,6 +300,14 @@ def get_dates_timeperiod(timeperiod): enddate = startdate+timezone.timedelta(days=32) enddate = enddate.replace(day=1) enddate = enddate-timezone.timedelta(days=1) + elif timeperiod=='nextmonth': + today = date.today() + startdate = today.replace(day=1) + startdate = startdate+timezone.timedelta(days=32) + startdate = startdate.replace(day=1) + enddate = startdate+timezone.timedelta(days=32) + enddate = enddate.replace(day=1) + enddate = enddate-timezone.timedelta(days=1) else: startdate = date.today() enddate = date.today() diff --git a/rowers/templates/histo.html b/rowers/templates/histo.html index 5de2516b..f03c3414 100644 --- a/rowers/templates/histo.html +++ b/rowers/templates/histo.html @@ -100,7 +100,7 @@ {% endif %} - +

Warning: Large date ranges may take a long time to load. Huge date ranges may crash your browser.

diff --git a/rowers/templates/plannedsession_multicreate.html b/rowers/templates/plannedsession_multicreate.html index 5abb9384..b5afa83d 100644 --- a/rowers/templates/plannedsession_multicreate.html +++ b/rowers/templates/plannedsession_multicreate.html @@ -36,6 +36,14 @@ href="/rowers/sessions/multicreate/lastmonth/rower/{{ rower.id }}"> Last Month + + Next Week + + + Next Month +
{% if user.is_authenticated and user|is_manager %} diff --git a/rowers/templates/plannedsessioncreate.html b/rowers/templates/plannedsessioncreate.html index b99a9860..7cc32aab 100644 --- a/rowers/templates/plannedsessioncreate.html +++ b/rowers/templates/plannedsessioncreate.html @@ -36,6 +36,14 @@ href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}"> Last Month + + Next Week + + + Next Month + {% if user.is_authenticated and user|is_manager %} diff --git a/rowers/templates/plannedsessionedit.html b/rowers/templates/plannedsessionedit.html index 9d82ed58..4abbe83b 100644 --- a/rowers/templates/plannedsessionedit.html +++ b/rowers/templates/plannedsessionedit.html @@ -36,6 +36,14 @@ href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}"> Last Month + + Next Week + + + Next Month + {% if user.is_authenticated and user|is_manager %} diff --git a/rowers/templates/plannedsessions.html b/rowers/templates/plannedsessions.html index 72065862..2e229d97 100644 --- a/rowers/templates/plannedsessions.html +++ b/rowers/templates/plannedsessions.html @@ -34,6 +34,14 @@ href="/rowers/sessions/lastmonth/rower/{{ rower.id }}"> Last Month + + Next Week + + + Next Month + {% if user.is_authenticated and user|is_manager %} diff --git a/rowers/templates/plannedsessions_multiclone_select.html b/rowers/templates/plannedsessions_multiclone_select.html new file mode 100644 index 00000000..7ee2b39a --- /dev/null +++ b/rowers/templates/plannedsessions_multiclone_select.html @@ -0,0 +1,190 @@ +{% extends "base.html" %} +{% load staticfiles %} +{% load rowerfilters %} + +{% block title %}Workouts{% endblock %} + +{% block content %} + + + + + + +
+ {% include "planningbuttons.html" %} +
+
+ {% if theteam %} +

Coach Overview. Team {{ theteam.name }}

+ {% else %} +

Coach Overview

+ {% endif %} +
+ +{% if user.is_authenticated and user|is_manager %} + +
+
+
+ {% endif %} +
+ + {{ dateform.as_table }} +
+ {% csrf_token %} +
+
+ +
+
+
+
+
+
+ +
+
+ +
+
+
+ +
+ + +
+
+ + + {% if plannedsessions %} + + Toggle All
+ + + {{ form.as_table }} +
+ +{% else %} +

No sessions found

+{% endif %} +
+
+

Select two or more planned sessions on the left, + select the date when the new cycle starts below + and press submit

+ {% csrf_token %} + + {{ dateshiftform.as_table }} +
+
+

+ +

+
+
+

You can use the date and search forms above to search through all + sessions.

+
+
+
+ + +{% endblock %} diff --git a/rowers/templates/plannedsessionscoach.html b/rowers/templates/plannedsessionscoach.html index e9047273..2217824c 100644 --- a/rowers/templates/plannedsessionscoach.html +++ b/rowers/templates/plannedsessionscoach.html @@ -38,6 +38,14 @@ href="/rowers/sessions/coach/lastmonth/"> Last Month + + Next Week + + + Next Month + {% if user.is_authenticated and user|is_manager %} diff --git a/rowers/templates/plannedsessionsmanage.html b/rowers/templates/plannedsessionsmanage.html index 1362cab2..4b9e19b0 100644 --- a/rowers/templates/plannedsessionsmanage.html +++ b/rowers/templates/plannedsessionsmanage.html @@ -48,6 +48,14 @@ href="/rowers/sessions/manage/lastmonth/rower/{{ rower.id }}"> Last Month + + Next Week + + + Next Month + {% if user.is_authenticated and user|is_manager %} diff --git a/rowers/templates/plannedsessionteamcreate.html b/rowers/templates/plannedsessionteamcreate.html index bbe17b60..c45a0694 100644 --- a/rowers/templates/plannedsessionteamcreate.html +++ b/rowers/templates/plannedsessionteamcreate.html @@ -36,6 +36,14 @@ href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}"> Last Month + + Next Week + + + Next Month + diff --git a/rowers/templates/plannedsessionteamedit.html b/rowers/templates/plannedsessionteamedit.html index 4987af67..b5878edd 100644 --- a/rowers/templates/plannedsessionteamedit.html +++ b/rowers/templates/plannedsessionteamedit.html @@ -36,6 +36,14 @@ href="/rowers/sessions/create/lastmonth/rower/{{ rower.id }}"> Last Month + + Next Week + + + Next Month + diff --git a/rowers/templates/team_compare_select.html b/rowers/templates/team_compare_select.html index 176f5c69..7fb527e5 100644 --- a/rowers/templates/team_compare_select.html +++ b/rowers/templates/team_compare_select.html @@ -144,7 +144,6 @@ {% endif %}
-

Warning: You are on an experimental part of the site. Use at your own risk.

Select two or more workouts on the left, set your plot settings below, and press submit

{% csrf_token %} diff --git a/rowers/templatetags/rowerfilters.py b/rowers/templatetags/rowerfilters.py index cd9acd8b..1adc0f89 100644 --- a/rowers/templatetags/rowerfilters.py +++ b/rowers/templatetags/rowerfilters.py @@ -193,6 +193,8 @@ def verbosetimeperiod(timeperiod): 'thismonth': 'This Month', 'lastmonth': 'Last Month', 'lastweek': 'Last Week', + 'nextweek': 'Next Week', + 'nextmonth': 'Next Month', } try: diff --git a/rowers/urls.py b/rowers/urls.py index 635be9a9..e2772640 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -419,6 +419,17 @@ urlpatterns = [ url(r'^sessions/create/(?P[\w\ ]+.*)$', views.plannedsession_create_view), + url(r'^sessions/multiclone$',views.plannedsession_multiclone_view), + url(r'^sessions/multiclone/(?P[\w\ ]+.*)/rower/(?P\d+)/extra/(?P\d+)$', + views.plannedsession_multiclone_view), + url(r'^sessions/multiclone/rower/(?P\d+)$', + views.plannedsession_multiclone_view), + url( + r'^sessions/multiclone/(?P[\w\ ]+.*)/rower/(?P\d+)$', + views.plannedsession_multiclone_view), + url(r'^sessions/multiclone/(?P[\w\ ]+.*)$', + views.plannedsession_multiclone_view), + url(r'^sessions/multicreate$',views.plannedsession_multicreate_view), url(r'^sessions/multicreate/(?P[\w\ ]+.*)/rower/(?P\d+)/extra/(?P\d+)$', views.plannedsession_multicreate_view), diff --git a/rowers/views.py b/rowers/views.py index 02d7f365..8c912f98 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -50,6 +50,7 @@ from rowers.forms import ( UpdateStreamForm,WorkoutMultipleCompareForm,ChartParamChoiceForm, FusionMetricChoiceForm,BoxPlotChoiceForm,MultiFlexChoiceForm, TrendFlexModalForm,WorkoutSplitForm,WorkoutJoinParamForm, + PlannedSessionMultipleCloneForm,SessionDateShiftForm, ) from rowers.models import ( Workout, User, Rower, WorkoutForm,FavoriteChart, @@ -11576,6 +11577,113 @@ def agegrouprecordview(request,sex='male',weightcategory='hwt', 'the_div':div, }) +# Cloning sessions +@user_passes_test(hasplannedsessions,login_url="/rowers/planmembership/", + redirect_field_name=None) +def plannedsession_multiclone_view( + request,timeperiod='nextweek', + rowerid=0, + startdate=timezone.now()-datetime.timedelta(days=30), + enddate=timezone.now()+datetime.timedelta(days=1)): + + if rowerid==0: + r = getrower(request.user) + else: + try: + r = Rower.objects.get(id=rowerid) + except Rower.DoesNotExist: + raise Http404("This rower doesn't exist") + if not checkaccessuser(request.user,r): + raise PermissionDenied("You don't have access to this plan") + + if 'startdate' in request.session: + startdate = iso8601.parse_date(request.session['startdate']) + + + if 'enddate' in request.session: + enddate = iso8601.parse_date(request.session['enddate']) + + 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 + for ps in sps: + rowers = ps.rower.all() + teams = ps.team.all() + ps.pk = None + ps.startdate += delta + ps.enddate += delta + ps.save() + for rower in rowers: + add_rower_session(rower,ps) + for team in teams: + add_team_session(team,ps) + + url = reverse(plannedsession_multicreate_view, + kwargs = { + 'rowerid':r.id, + 'timeperiod':timeperiod, + }) + + return HttpResponseRedirect(url) + + startdate = datetime.datetime.combine(startdate,datetime.time()) + enddate = datetime.datetime.combine(enddate,datetime.time(23,59,59)) + enddate = enddate+datetime.timedelta(days=1) + + sps = PlannedSession.objects.filter( + manager=request.user, + rower__in=[r], + startdate__lte=enddate, + enddate__gte=startdate).order_by("startdate","enddate") + + 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() + + return render(request, 'plannedsessions_multiclone_select.html', + {'plannedsessions':sps, + 'dateform':dateform, + 'startdate':startdate, + 'enddate':enddate, + 'form':form, + 'dateshiftform':dateshiftform, + 'rower':r, + 'timeperiod':timeperiod, + } + ) + # Individual user creates training for himself @user_passes_test(hasplannedsessions,login_url="/rowers/planmembership/", redirect_field_name=None) diff --git a/templates/basebase.html b/templates/basebase.html index edc15f57..892868f6 100644 --- a/templates/basebase.html +++ b/templates/basebase.html @@ -205,6 +205,13 @@

 

{% endif %}
+
+ {% if user.is_authenticated %} +

Plans

+ {% else %} +

 

+ {% endif %} +
{% if user.is_authenticated %}

@@ -219,13 +226,6 @@ {% block teams %} {% endblock %}

-
- {% if user.is_authenticated %} -

Plans

- {% else %} -

 

- {% endif %} -
{% block challenges %} {% endblock %}