Private
Public Access
1
0

get dates timeperiod updates to work better with local time zones

This commit is contained in:
Sander Roosendaal
2021-09-21 11:04:36 +02:00
parent 8205fd3c3f
commit 5b11413068
8 changed files with 170 additions and 27 deletions

View File

@@ -100,17 +100,25 @@ smoothingchoices = (
(16,16), (16,16),
) )
def half_year_from_now(): def half_year_from_now(ttz=None):
return (datetime.datetime.now(tz=timezone.utc)+timezone.timedelta(days=182)).date() if ttz is None:
return (datetime.datetime.now(tz=timezone.utc)+timezone.timedelta(days=182)).date()
return (datetime.datetime.utcnow()+timezone.timedelta(days=182)).astimezone(pytz.timezone(ttz)).date()
def a_week_from_now(): def a_week_from_now(ttz=None):
return (datetime.datetime.now(tz=timezone.utc)+timezone.timedelta(days=7)).date() if ttz is None:
return (datetime.datetime.now(tz=timezone.utc)+timezone.timedelta(days=7)).date()
return (datetime.datetime.utcnow()+timezone.timedelta(days=7)).astimezone(pytz.timezone(ttz)).date()
def current_day(): def current_day(ttz=None):
return (datetime.datetime.now(tz=timezone.utc)).date() if ttz is None:
return (datetime.datetime.now(tz=timezone.utc)).date()
return datetime.datetime.utcnow().astimezone(pytz.timezone(ttz)).date()
def current_time(): # pragma: no cover def current_time(ttz=None): # pragma: no cover
return datetime.datetime.now(tz=timezone.utc) if ttz is None:
return datetime.datetime.now(tz=timezone.utc)
return (datetime.datetime.utcnow()).astimezone(pytz.timezone(ttz))
class UserFullnameChoiceField(forms.ModelChoiceField): class UserFullnameChoiceField(forms.ModelChoiceField):

View File

@@ -888,8 +888,17 @@ def get_dates_timeperiod(request,startdatestring='',enddatestring='',
tz = pytz.timezone(rower.defaulttimezone) tz = pytz.timezone(rower.defaulttimezone)
startdate = arrow.get(startdate) startdate = arrow.get(startdate)
enddate = arrow.get(enddate) enddate = arrow.get(enddate)
startdate = startdate.astimezone(tz) startdate = startdate.replace(tzinfo=tz)
enddate = enddate.astimezone(tz) enddate = enddate.replace(tzinfo=tz)
else:
startdate = dt.datetime.combine(startdate,dt.datetime.min.time())
enddate = dt.datetime.combine(enddate,dt.datetime.min.time())
startdate = startdate.astimezone(pytz.utc)
enddate = enddate.astimezone(pytz.utc)
# set time to 00:00 in local time
startdate = startdate.replace(hour=0,minute=0,second=0,microsecond=0)
enddate = enddate.replace(hour=0,minute=0,second=0,microsecond=0)
return startdate,enddate return startdate,enddate
@@ -949,6 +958,8 @@ def get_dates_timeperiod(request,startdatestring='',enddatestring='',
try: try:
startdate = dt.datetime.strptime(tstartdatestring,'%Y-%m-%d').date() startdate = dt.datetime.strptime(tstartdatestring,'%Y-%m-%d').date()
enddate = dt.datetime.strptime(tenddatestring,'%Y-%m-%d').date() enddate = dt.datetime.strptime(tenddatestring,'%Y-%m-%d').date()
startdate = dt.datetime.combine(startdate,dt.datetime.min.time())
enddate = dt.datetime.combine(enddate,dt.datetime.min.time())
if startdate > enddate: # pragma: no cover if startdate > enddate: # pragma: no cover
startdate2 = enddate startdate2 = enddate
enddate = startdate enddate = startdate
@@ -981,6 +992,10 @@ def get_dates_timeperiod(request,startdatestring='',enddatestring='',
enddate = enddate.astimezone(tz) enddate = enddate.astimezone(tz)
# set time to 00:00 in local time
startdate = startdate.replace(hour=0,minute=0,second=0,microsecond=0)
enddate = enddate.replace(hour=0,minute=0,second=0,microsecond=0)
return startdate,enddate return startdate,enddate
def get_sessions_manager(m,teamid=0,startdate=timezone.now(), def get_sessions_manager(m,teamid=0,startdate=timezone.now(),

View File

@@ -30,6 +30,7 @@ class TrainingPlanTest(TestCase):
self.r = Rower.objects.create(user=self.u, self.r = Rower.objects.create(user=self.u,
birthdate=faker.profile()['birthdate'], birthdate=faker.profile()['birthdate'],
gdproptin=True,surveydone=True, gdproptin=True,surveydone=True,
defaulttimezone='US/Pacific',
gdproptindate=timezone.now(), gdproptindate=timezone.now(),
rowerplan='coach') rowerplan='coach')
@@ -1238,6 +1239,7 @@ class PlannedSessionsView(TestCase):
birthdate=faker.profile()['birthdate'], birthdate=faker.profile()['birthdate'],
gdproptin=True,surveydone=True, gdproptin=True,surveydone=True,
gdproptindate=timezone.now(), gdproptindate=timezone.now(),
defaulttimezone='US/Pacific',
rowerplan='coach') rowerplan='coach')
self.r.save() self.r.save()
self.c = Client() self.c = Client()

View File

@@ -32,6 +32,7 @@ class OtherUnitTests(TestCase):
birthdate=faker.profile()['birthdate'], birthdate=faker.profile()['birthdate'],
gdproptin=True,surveydone=True, gdproptin=True,surveydone=True,
gdproptindate=timezone.now(), gdproptindate=timezone.now(),
defaulttimezone='US/Pacific',
rowerplan='coach') rowerplan='coach')
workoutsbox = Mailbox.objects.create(name='workouts') workoutsbox = Mailbox.objects.create(name='workouts')
@@ -39,6 +40,64 @@ class OtherUnitTests(TestCase):
failbox = Mailbox.objects.create(name='Failed') failbox = Mailbox.objects.create(name='Failed')
failbox.save() failbox.save()
# Test get_dates_timeperiod
def test_get_dates_timeperiod(self):
rq = RequestFactory().get('/rowers/plannedsessions/')
middleware = SessionMiddleware()
middleware.process_request(rq)
# blanco should just run
startdate,enddate = get_dates_timeperiod(rq,rower=self.r)
# time should be midnight
self.assertEqual(startdate.strftime('%H:%M:%S'),'00:00:00')
# tzinfo should be present
self.assertTrue(startdate.tzinfo is not None)
# time zone should be US/Pacific
self.assertTrue('US/Pacific' in str(startdate.tzinfo))
# now with dates
startdatestring = '2021-09-26'
enddatestring = '2021-10-02'
startdate,enddate = get_dates_timeperiod(rq,startdatestring=startdatestring,
enddatestring=enddatestring)
# time should be midnight
self.assertEqual(startdate.strftime('%H:%M:%S'),'00:00:00')
# startdate and enddate should match
self.assertEqual(startdate.strftime('%m-%d'),'09-26')
self.assertEqual(enddate.strftime('%m-%d'),'10-02')
# tzinfo should be present
self.assertTrue(startdate.tzinfo is not None)
# time zone should be US/Pacific
self.assertTrue('UTC' in str(startdate.tzinfo))
# now with dates and rower
startdatestring = '2021-09-26'
enddatestring = '2021-10-02'
startdate,enddate = get_dates_timeperiod(rq,startdatestring=startdatestring,
enddatestring=enddatestring,rower=self.r)
# time should be midnight
self.assertEqual(startdate.strftime('%H:%M:%S'),'00:00:00')
# startdate and enddate should match
self.assertEqual(startdate.strftime('%m-%d'),'09-26')
self.assertEqual(enddate.strftime('%m-%d'),'10-02')
# tzinfo should be present
self.assertTrue(startdate.tzinfo is not None)
# time zone should be US/Pacific
self.assertTrue('US/Pacific' in str(startdate.tzinfo))
@patch('rowers.tasks.requests.get',side_effect=mocked_requests) @patch('rowers.tasks.requests.get',side_effect=mocked_requests)
def test_strava_asyncworkout(self,mock_get): def test_strava_asyncworkout(self,mock_get):

View File

@@ -2511,7 +2511,10 @@ def history_view_data(request,userid=0):
ddict['hrmax'] = 0 ddict['hrmax'] = 0
ddict['powermean'] = int(wavg(ddf,'power','deltat')) ddict['powermean'] = int(wavg(ddf,'power','deltat'))
ddict['powermax'] = ddf['power'].max().astype(int) try:
ddict['powermax'] = ddf['power'].max().astype(int)
except KeyError:
ddict['powermax'] = 0
ddict['nrworkouts'] = a_workouts.count() ddict['nrworkouts'] = a_workouts.count()
listofdicts.append(ddict) listofdicts.append(ddict)

View File

@@ -32,6 +32,8 @@ def workout_tcxemail_view(request,id=0):
def plannedsessions_icsemail_view(request,userid=0): def plannedsessions_icsemail_view(request,userid=0):
r = getrequestrower(request,userid=userid) r = getrequestrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
sps = get_sessions(r,startdate=startdate,enddate=enddate) sps = get_sessions(r,startdate=startdate,enddate=enddate)
@@ -69,7 +71,8 @@ def plannedsessions_icsemail_view(request,userid=0):
def plannedsessions_coach_icsemail_view(request,userid=0): def plannedsessions_coach_icsemail_view(request,userid=0):
therower = getrequestplanrower(request,userid=userid) therower = getrequestplanrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
if 'coach' in request.user.rower.rowerplan: if 'coach' in request.user.rower.rowerplan:
sps = get_sessions_manager(request.user,teamid=0, sps = get_sessions_manager(request.user,teamid=0,
enddate=enddate, enddate=enddate,
@@ -195,9 +198,9 @@ def workouts_summaries_email_view(request):
messages.error(request, message) messages.error(request, message)
return HttpResponseRedirect( return HttpResponseRedirect(
reverse(r.defaultlandingpage, reverse(r.defaultlandingpage,
kwargs = { kwargs = {
'id':str(w.id), 'id':str(w.id),
}) })
) )
if request.method == 'POST': if request.method == 'POST':
@@ -247,7 +250,7 @@ def workout_csvemail_view(request,id=0):
df[' ElapsedTime (sec)'] = df['TimeStamp (sec)'] df[' ElapsedTime (sec)'] = df['TimeStamp (sec)']
df['TimeStamp (sec)'] = df['TimeStamp (sec)'] + starttimeunix df['TimeStamp (sec)'] = df['TimeStamp (sec)'] + starttimeunix
except KeyError: except KeyError:
pass pass
response = HttpResponse(df.to_csv()) response = HttpResponse(df.to_csv())
response['Content-Disposition'] = 'attachment; filename="%s"' % filename response['Content-Disposition'] = 'attachment; filename="%s"' % filename
@@ -276,9 +279,9 @@ def workout_csvtoadmin_view(request,id=0): # pragma: no cover
successmessage = "The CSV file was sent to the site admin per email" successmessage = "The CSV file was sent to the site admin per email"
messages.info(request,successmessage) messages.info(request,successmessage)
url = reverse('workout_view', url = reverse('workout_view',
kwargs = { kwargs = {
'id':encoder.encode_hex(w.id), 'id':encoder.encode_hex(w.id),
}) })
response = HttpResponseRedirect(url) response = HttpResponseRedirect(url)
return response return response

View File

@@ -512,6 +512,9 @@ def rower_process_nkcallback(request): # pragma: no cover
@login_required() @login_required()
def workout_getnkworkout_all(request,startdatestring='',enddatestring=''): def workout_getnkworkout_all(request,startdatestring='',enddatestring=''):
startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring,enddatestring=enddatestring) startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring,enddatestring=enddatestring)
startdate = startdate.date()
enddate = enddate.date()
before = arrow.get(enddate) before = arrow.get(enddate)
before = str(int(before.timestamp()*1000)) before = str(int(before.timestamp()*1000))
@@ -540,6 +543,8 @@ def workout_getnkworkout_all(request,startdatestring='',enddatestring=''):
@permission_required('rower.is_not_freecoach',fn=get_user_by_userid, raise_exception=True) @permission_required('rower.is_not_freecoach',fn=get_user_by_userid, raise_exception=True)
def workout_nkimport_view(request,userid=0,after=0,before=0): def workout_nkimport_view(request,userid=0,after=0,before=0):
startdate,enddate = get_dates_timeperiod(request,defaulttimeperiod='last30') startdate,enddate = get_dates_timeperiod(request,defaulttimeperiod='last30')
startdate = startdate.date()
enddate = enddate.date()
r = getrequestrower(request,userid=userid) r = getrequestrower(request,userid=userid)
if r.user != request.user: # pragma: no cover if r.user != request.user: # pragma: no cover
messages.error(request,'You can only access your own workouts on the NK Logbook, not those of your athletes') messages.error(request,'You can only access your own workouts on the NK Logbook, not those of your athletes')

View File

@@ -275,6 +275,8 @@ def plannedsession_multiclone_view(
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
teamid = get_team(request) teamid = get_team(request)
if request.method == 'POST' and 'daterange' in request.POST: # pragma: no cover if request.method == 'POST' and 'daterange' in request.POST: # pragma: no cover
@@ -455,6 +457,8 @@ def template_library_view(request,userid=0):
templates = templates | templates2 templates = templates | templates2
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
@@ -515,6 +519,8 @@ def plannedsession_create_view(request,
startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring, startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring,
enddatestring=enddatestring) enddatestring=enddatestring)
startdate = startdate.date()
enddate = enddate.date()
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d') timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
@@ -610,7 +616,8 @@ def plannedsession_create_view(request,
if request.GET.get('startdate') or request.GET.get('when'): if request.GET.get('startdate') or request.GET.get('when'):
startdate, enddate = get_dates_timeperiod(request) startdate, enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
sps = get_sessions(r,startdate=startdate,enddate=enddate).exclude( sps = get_sessions(r,startdate=startdate,enddate=enddate).exclude(
@@ -696,7 +703,8 @@ def plannedsession_createtemplate_view(request,
r = getrequestplanrower(request,userid=userid) r = getrequestplanrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
if request.method == 'POST': if request.method == 'POST':
@@ -790,6 +798,8 @@ def plannedsession_multicreate_view(request,
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
teamid = get_team(request) teamid = get_team(request)
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
@@ -923,6 +933,8 @@ def plannedsession_teamcreate_view(request,
therower = getrequestplanrower(request,userid=userid) therower = getrequestplanrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d') timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
teams = Team.objects.filter(manager=request.user) teams = Team.objects.filter(manager=request.user)
@@ -1101,6 +1113,8 @@ def plannedsession_teamedit_view(request,
ps = get_object_or_404(PlannedSession,pk=id) ps = get_object_or_404(PlannedSession,pk=id)
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d') timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
@@ -1110,6 +1124,8 @@ def plannedsession_teamedit_view(request,
teaminitial = ps.team.all() teaminitial = ps.team.all()
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
@@ -1278,7 +1294,8 @@ def plannedsessions_coach_view(request,
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
trainingplan = None trainingplan = None
@@ -1412,17 +1429,18 @@ def plannedsessions_view(request,
startdatestring=startdatestring, startdatestring=startdatestring,
enddatestring=enddatestring, enddatestring=enddatestring,
rower=r) rower=r)
startdate = startdate.date()
enddate = enddate.date()
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
startdate__lte = startdate, startdate__lte = startdate,
rowers = r, rowers = r,
enddate__gte = enddate)[0] enddate__gte = enddate
)[0]
except IndexError: except IndexError:
trainingplan = None trainingplan = None
sps = get_sessions(r,startdate=startdate,enddate=enddate) sps = get_sessions(r,startdate=startdate,enddate=enddate)
completeness = {} completeness = {}
@@ -1447,7 +1465,9 @@ def plannedsessions_view(request,
ws = Workout.objects.filter( ws = Workout.objects.filter(
user=r, user=r,
date__gte=startdate,date__lte=enddate) date__gte=startdate,
date__lte=enddate,
)
for w in ws: for w in ws:
thetrimp,hrtss = dataprep.workout_trimp(w) thetrimp,hrtss = dataprep.workout_trimp(w)
@@ -1512,7 +1532,9 @@ def plannedsessions_view(request,
unmatchedworkouts = Workout.objects.filter( unmatchedworkouts = Workout.objects.filter(
user=r, user=r,
plannedsession=None, plannedsession=None,
date__gte=startdate,date__lte=enddate) date__gte=startdate,
date__lte=enddate
)
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d') timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
breadcrumbs = [ breadcrumbs = [
@@ -1558,6 +1580,8 @@ def plannedsessions_print_view(request,userid=0,startdatestring='',enddatestring
startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring, startdate,enddate = get_dates_timeperiod(request,startdatestring=startdatestring,
enddatestring=enddatestring) enddatestring=enddatestring)
startdate = startdate.date()
enddate = enddate.date()
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
@@ -1599,6 +1623,8 @@ def plannedsessions_manage_view(request,userid=0,
r = getrequestrower(request,userid=userid) r = getrequestrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
@@ -1761,6 +1787,8 @@ def plannedsession_clone_view(request,id=0,userid=0):
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
@@ -1834,6 +1862,8 @@ def plannedsession_teamclone_view(request,id=0):
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
@@ -1882,6 +1912,8 @@ redirect_field_name=None)
def plannedsession_templateedit_view(request,id=0): def plannedsession_templateedit_view(request,id=0):
r = getrequestrower(request) r = getrequestrower(request)
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
startdate__lte = startdate, startdate__lte = startdate,
@@ -1992,6 +2024,8 @@ def plannedsession_togarmin_view(request,id=0):
r = getrequestplanrower(request) r = getrequestplanrower(request)
startdate, enddate = get_dates_timeperiod(request) startdate, enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
ps = get_object_or_404(PlannedSession,pk=id) ps = get_object_or_404(PlannedSession,pk=id)
@@ -2023,6 +2057,8 @@ def plannedsession_totemplate_view(request,id=0):
r = getrequestplanrower(request) r = getrequestplanrower(request)
startdate, enddate = get_dates_timeperiod(request) startdate, enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
ps = get_object_or_404(PlannedSession,pk=id) ps = get_object_or_404(PlannedSession,pk=id)
@@ -2054,6 +2090,9 @@ def plannedsession_edit_view(request,id=0,userid=0):
r = getrequestplanrower(request,userid=userid) r = getrequestplanrower(request,userid=userid)
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d') timeperiod = startdate.strftime('%Y-%m-%d')+'/'+enddate.strftime('%Y-%m-%d')
@@ -2381,6 +2420,9 @@ def plannedsession_view(request,id=0,userid=0):
# if coursetest, need to reorder the ranking # if coursetest, need to reorder the ranking
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
try: try:
trainingplan = TrainingPlan.objects.filter( trainingplan = TrainingPlan.objects.filter(
startdate__lte = startdate, startdate__lte = startdate,
@@ -3125,6 +3167,8 @@ def rower_trainingplan_execution_view(request,
userid=0): userid=0):
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
r = getrequestrower(request,userid=userid) r = getrequestrower(request,userid=userid)
@@ -3147,6 +3191,8 @@ def rower_trainingplan_execution_view(request,
else: else:
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
if int(id)>0: if int(id)>0:
data,message = get_execution_report(r,startdate,enddate,plan=plan) data,message = get_execution_report(r,startdate,enddate,plan=plan)
@@ -3221,6 +3267,8 @@ def rower_trainingplan_view(request,
startdate,enddate = get_dates_timeperiod(request) startdate,enddate = get_dates_timeperiod(request)
startdate = startdate.date()
enddate = enddate.date()
plan = get_object_or_404(TrainingPlan,pk=id) plan = get_object_or_404(TrainingPlan,pk=id)
r = getrequestrower(request,userid=userid) r = getrequestrower(request,userid=userid)