From dae9c80f6fb44aea38fb5dfea4282afaec530fa9 Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Mon, 12 Nov 2018 11:50:52 +0100
Subject: [PATCH 1/8] adding athlete selector for coaches when creating
target/plan
---
rowers/models.py | 36 +++++++++++++++++++++++-------------
rowers/views.py | 23 +++++++++++++++--------
2 files changed, 38 insertions(+), 21 deletions(-)
diff --git a/rowers/models.py b/rowers/models.py
index 1db6d745..b5326f42 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -973,18 +973,24 @@ class TrainingTargetForm(ModelForm):
}
def __init__(self,*args, **kwargs):
+ user = kwargs.pop('user',None)
super(TrainingTargetForm, self).__init__(*args, **kwargs)
try:
teams = Team.objects.filter(manager=self.instance.manager.user)
- if not teams:
- self.fields.pop('rowers')
- else:
- self.fields['rowers'].queryset = Rower.objects.filter(
- team__in=teams
- ).distinct().order_by("user__last_name","user__first_name")
except AttributeError:
+ if user:
+ teams = Team.objects.filter(manager=user)
+ else:
+ teams = []
+
+ if not teams:
self.fields.pop('rowers')
+ else:
+ self.fields['rowers'].queryset = Rower.objects.filter(
+ team__in=teams
+ ).distinct().order_by("user__last_name","user__first_name")
+
# SportTracks has a TrainingGoal like this
@@ -1095,6 +1101,7 @@ class TrainingPlanForm(ModelForm):
def __init__(self,*args, **kwargs):
targets = kwargs.pop('targets',None)
+ user = kwargs.pop('user',None)
super(TrainingPlanForm, self).__init__(*args, **kwargs)
if targets:
@@ -1110,15 +1117,18 @@ class TrainingPlanForm(ModelForm):
try:
teams = Team.objects.filter(manager=self.instance.manager.user)
-
- if not teams:
- self.fields.pop('rowers')
- else:
- self.fields['rowers'].queryset = Rower.objects.filter(
- team__in=teams
- ).distinct().order_by("user__last_name","user__first_name")
except AttributeError:
+ if user:
+ teams = Team.objects.filter(manager=user)
+ else:
+ teams = []
+
+ if not teams:
self.fields.pop('rowers')
+ else:
+ self.fields['rowers'].queryset = Rower.objects.filter(
+ team__in=teams
+ ).distinct().order_by("user__last_name","user__first_name")
cycletypechoices = (
('filler','System Defined'),
diff --git a/rowers/views.py b/rowers/views.py
index 75754ac2..cc854b2a 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -16263,7 +16263,7 @@ def rower_create_trainingplan(request,userid=0):
themanager = getrower(request.user)
if request.method == 'POST' and 'date' in request.POST:
- targetform = TrainingTargetForm(request.POST)
+ targetform = TrainingTargetForm(request.POST,user=request.user)
if targetform.is_valid():
name = targetform.cleaned_data['name']
date = targetform.cleaned_data['date']
@@ -16281,22 +16281,26 @@ def rower_create_trainingplan(request,userid=0):
t.save()
elif request.method == 'POST' and 'startdate' in request.POST:
- form = TrainingPlanForm(request.POST)
+ form = TrainingPlanForm(request.POST,user=request.user)
if form.is_valid():
-
name = form.cleaned_data['name']
try:
target = form.cleaned_data['target']
except KeyError:
try:
targetid = request.POST['target']
- target = TrainingTarget.objects.get(id=targetid)
+ if targetid != '':
+ target = TrainingTarget.objects.get(id=int(targetid))
+ else:
+ target = None
except KeyError:
target = None
startdate = form.cleaned_data['startdate']
enddate = form.cleaned_data['enddate']
+
+ athletes = form.cleaned_data['rowers']
p = TrainingPlan(
name=name,
@@ -16307,20 +16311,23 @@ def rower_create_trainingplan(request,userid=0):
)
p.save()
-
- p.rowers.add(therower)
+
+ for athlete in athletes:
+ p.rowers.add(athlete)
targets = TrainingTarget.objects.filter(
rowers=therower,
date__gte=datetime.date.today(),
).order_by("date")
- targetform = TrainingTargetForm()
+ targetform = TrainingTargetForm(user=request.user)
plans = TrainingPlan.objects.filter(rowers=therower).order_by("-startdate")
- form = TrainingPlanForm(targets=targets,initial={'status':False})
+ form = TrainingPlanForm(targets=targets,
+ initial={'status':False,'rowers':[therower]},
+ user=request.user)
breadcrumbs = [
{
From 15555402d2f8e15cf3e59726b2a917a1b436bf58 Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Mon, 12 Nov 2018 12:08:56 +0100
Subject: [PATCH 2/8] adding unfold/fold all checkbox in trainingplan view
---
rowers/templates/trainingplan.html | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/rowers/templates/trainingplan.html b/rowers/templates/trainingplan.html
index 8e2e57d0..a281c5f2 100644
--- a/rowers/templates/trainingplan.html
+++ b/rowers/templates/trainingplan.html
@@ -6,6 +6,17 @@
{% block main %}
+
+
Training Plan - {{ plan.name }}
This plan starts on {{ plan.startdate }} and ends on {{ plan.enddate }}.
{% if plan.target %}
@@ -18,6 +29,7 @@
Plan Macro, Meso and Micro Cycles
+Unfold/Fold all
+
{% if unmatchedworkouts %}
diff --git a/rowers/urls.py b/rowers/urls.py
index eeb3a70e..37a0354b 100644
--- a/rowers/urls.py
+++ b/rowers/urls.py
@@ -507,6 +507,8 @@ urlpatterns = [
url(r'^sessions/coach/user/\d+/$',views.plannedsessions_coach_view),
url(r'^sessions/print/?$',views.plannedsessions_print_view),
url(r'^sessions/print/user/(?P\d+)/$',views.plannedsessions_print_view),
+ url(r'^sessions/sendcalendar/$',views.plannedsessions_icsemail_view),
+ url(r'^sessions/sendcalendar/user/(?P\d+)/$',views.plannedsessions_icsemail_view),
url(r'^sessions/$',views.plannedsessions_view),
url(r'^sessions/user/(?P\d+)$',views.plannedsessions_view),
url(r'^sessions/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)$',
diff --git a/rowers/views.py b/rowers/views.py
index c412e2a8..b2ab8752 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -27,7 +27,7 @@ import codecs
import isodate
import re
import cgi
-
+from icalendar import Calendar, Event
from django.shortcuts import render
from django.template.loader import render_to_string
@@ -160,6 +160,7 @@ from rowers.tasks import (
handle_zip_file,handle_getagegrouprecords,
handle_updatefitnessmetric,
handle_update_empower,
+ handle_sendemailics,
handle_sendemail_userdeleted,
)
@@ -1431,6 +1432,60 @@ def workout_tcxemail_view(request,id=0):
return response
+@login_required()
+def plannedsessions_icsemail_view(request,userid=0):
+ r = getrequestrower(request,userid=userid)
+ startdate,enddate = get_dates_timeperiod(request)
+
+ sps = get_sessions(r,startdate=startdate,enddate=enddate)
+
+ cal = Calendar()
+ cal.add('prodid','rowsandall')
+ cal.add('version','1.0')
+
+ for ps in sps:
+ event = Event()
+ comment = '{d} {u} {c}'.format(
+ d=ps.sessionvalue,
+ u = ps.sessionunit,
+ c = ps.criterium)
+ event.add('summary',ps.name)
+ event.add('dtstart',ps.preferreddate)
+ event.add('dtend',ps.preferreddate)
+ event['uid'] = 'plannedsession_'+str(ps.id)
+ event.add('description',ps.comment)
+ event.add('comment',comment)
+ cal.add_component(event)
+
+ icsfilename = 'calendar_{id}.ics'.format(id=request.user.id)
+
+ with open(icsfilename,'wb') as f:
+ f.write(cal.to_ical())
+
+ res = myqueue(queuehigh,handle_sendemailics,
+ request.user.first_name,
+ request.user.last_name,
+ request.user.email,icsfilename,
+ emailbounced = r.emailbounced
+ )
+
+
+ successmessage = "The calendar file was sent to you per email"
+ messages.info(request,successmessage)
+ url = reverse(plannedsessions_view,
+ kwargs = {
+ 'userid':r.user.id,
+ })
+ startdatestring = startdate.strftime('%Y-%m-%d')
+ enddatestring = enddate.strftime('%Y-%m-%d')
+ url+='?when='+startdatestring+'/'+enddatestring
+
+
+ response = HttpResponseRedirect(url)
+
+ return response
+
+
@login_required()
def course_kmlemail_view(request,id=0):
r = getrower(request.user)
@@ -14542,7 +14597,6 @@ def plannedsession_teamedit_view(request,
r = getrequestrower(request,userid=userid)
-
try:
ps = PlannedSession.objects.get(id=sessionid)
except PlannedSession.DoesNotExist:
@@ -14576,7 +14630,7 @@ def plannedsession_teamedit_view(request,
sps = list(set(sps))
- ids = [ps.id for ps in sps]
+ ids = [pps.id for pps in sps]
sps = PlannedSession.objects.filter(id__in=ids).order_by(
"preferreddate","startdate","enddate")
From c7a335c33ff924d18a95c0fa4617680005233dd7 Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Mon, 12 Nov 2018 17:41:24 +0100
Subject: [PATCH 5/8] some print media css
---
static/css/styles2.css | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/static/css/styles2.css b/static/css/styles2.css
index 96d7bb23..69099bdf 100644
--- a/static/css/styles2.css
+++ b/static/css/styles2.css
@@ -660,10 +660,45 @@
}
@media print {
- header, user, nav, aside, footer {
+ .wrapper {
+ display: grid;
+ grid-template-areas:
+ "content"
+ "ad"
+ }
+
+ header, ad, user, nav, aside, footer {
display: none;
}
+ body {
+ color:#000;
+ background: #fff;
+ }
+
+ body, content {
+ width: 100%;
+ display: block;
+ min-height: 100%;
+ }
+
+ @page {
+ margin: 2cm;
+ }
+
+ h1, h2, h3 {
+ page-break-after: avoid;
+ }
+
+ ul, img {
+ page-break-inside: avoid;
+ }
+
+ table tr td {
+ vertical-align: middle;
+ }
+}
+
aside .cd-accordion-menu.animated label::before {
/* this class is used if you're using jquery to animate the accordion */
-webkit-transition: -webkit-transform 0.3s;
From 25f543f969ad5422e1b57f332fe207f9cbc4bf84 Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Mon, 12 Nov 2018 17:45:18 +0100
Subject: [PATCH 6/8] print media
---
static/css/styles2.css | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/static/css/styles2.css b/static/css/styles2.css
index 69099bdf..7569b131 100644
--- a/static/css/styles2.css
+++ b/static/css/styles2.css
@@ -662,9 +662,9 @@
@media print {
.wrapper {
display: grid;
+ grid-template-columns: repeat(4,1fr);
grid-template-areas:
- "content"
- "ad"
+ "content content content content"
}
header, ad, user, nav, aside, footer {
From 8e9a8d8957048ebcedd4d739d64c3636866b347f Mon Sep 17 00:00:00 2001
From: Sander Roosendaal
Date: Mon, 12 Nov 2018 19:51:18 +0100
Subject: [PATCH 7/8] ics is now download file
---
rowers/views.py | 27 +++------------------------
templates/newbase.html | 4 ++--
2 files changed, 5 insertions(+), 26 deletions(-)
diff --git a/rowers/views.py b/rowers/views.py
index b2ab8752..15f51f08 100644
--- a/rowers/views.py
+++ b/rowers/views.py
@@ -103,6 +103,7 @@ import rowers.uploads as uploads
from django.forms.formsets import formset_factory
from django.forms import modelformset_factory
import StringIO
+import cStringIO
from django.contrib.auth.decorators import login_required #,user_passes_test
from rowers.decorators import user_passes_test
from time import strftime,strptime,mktime,time,daylight
@@ -1457,31 +1458,9 @@ def plannedsessions_icsemail_view(request,userid=0):
event.add('comment',comment)
cal.add_component(event)
- icsfilename = 'calendar_{id}.ics'.format(id=request.user.id)
-
- with open(icsfilename,'wb') as f:
- f.write(cal.to_ical())
- res = myqueue(queuehigh,handle_sendemailics,
- request.user.first_name,
- request.user.last_name,
- request.user.email,icsfilename,
- emailbounced = r.emailbounced
- )
-
-
- successmessage = "The calendar file was sent to you per email"
- messages.info(request,successmessage)
- url = reverse(plannedsessions_view,
- kwargs = {
- 'userid':r.user.id,
- })
- startdatestring = startdate.strftime('%Y-%m-%d')
- enddatestring = enddate.strftime('%Y-%m-%d')
- url+='?when='+startdatestring+'/'+enddatestring
-
-
- response = HttpResponseRedirect(url)
+ response = HttpResponse(cal.to_ical(),content_type = 'text/plain')
+ response['Content-Disposition'] = 'attachment; filename="training_plan_%s.ics"' % request.user.id
return response
diff --git a/templates/newbase.html b/templates/newbase.html
index ebeb7bb6..11a5ece0 100644
--- a/templates/newbase.html
+++ b/templates/newbase.html
@@ -289,14 +289,14 @@
{% endblock %}
-
+