198 lines
6.7 KiB
Python
198 lines
6.7 KiB
Python
from django.utils import timezone
|
|
from rowers.models import Workout, VirtualRaceResult, CourseTestResult
|
|
|
|
def timefield_to_seconds_duration(t):
|
|
duration = t.hour*3600.
|
|
duration += t.minute * 60.
|
|
duration += t.second
|
|
duration += t.microsecond/1.e6
|
|
|
|
return duration
|
|
|
|
|
|
|
|
def is_session_complete_ws(ws, ps):
|
|
ws = ws.order_by("date")
|
|
if ws.count() == 0:
|
|
today = timezone.now()
|
|
if today.date() > ps.enddate:
|
|
verdict = 'missed'
|
|
ratio = 0
|
|
return ratio, verdict, None
|
|
else:
|
|
return 0, 'not done', None
|
|
|
|
value = ps.sessionvalue
|
|
if ps.sessionunit == 'min':
|
|
value *= 60.
|
|
elif ps.sessionunit == 'km': # pragma: no cover
|
|
value *= 1000.
|
|
|
|
cratiomin = 1
|
|
# cratiomax = 1
|
|
|
|
cratios = {
|
|
'better than nothing': 0,
|
|
'partial': 0.6,
|
|
'on target': 0.8,
|
|
'over target': 1.2,
|
|
'way over target': 1.5
|
|
}
|
|
|
|
if ps.criterium == 'none':
|
|
if ps.sessiontype == 'session':
|
|
cratiomin = 0.8
|
|
# cratiomax = 1.2
|
|
else:
|
|
cratios['on target'] = 0.9167
|
|
cratios['over target'] = 1.0833
|
|
cratiomin = 0.9167
|
|
# cratiomax = 1.0833
|
|
|
|
score = 0
|
|
completiondate = None
|
|
for w in ws:
|
|
if ps.sessionmode == 'distance':
|
|
score += w.distance
|
|
elif ps.sessionmode == 'time':
|
|
durationseconds = timefield_to_seconds_duration(w.duration)
|
|
score += durationseconds
|
|
elif ps.sessionmode == 'TRIMP':
|
|
score += w.trimp
|
|
elif ps.sessionmode == 'rScore':
|
|
score += w.rscore
|
|
if not completiondate and score >= cratiomin*value:
|
|
completiondate = w.date
|
|
|
|
try:
|
|
ratio = score/float(int(value))
|
|
except ZeroDivisionError: # pragma: no cover
|
|
ratio = 0
|
|
|
|
verdict = 'better than nothing'
|
|
|
|
if ps.sessiontype in ['session', 'cycletarget']:
|
|
if ps.criterium == 'exact':
|
|
if ratio == 1.0:
|
|
return ratio, 'on target', completiondate
|
|
else:
|
|
if not completiondate: # pragma: no cover
|
|
completiondate = ws.reverse()[0].date
|
|
return ratio, 'partial', completiondate
|
|
elif ps.criterium == 'minimum': # pragma: no cover
|
|
if ratio >= 1.0:
|
|
return ratio, 'on target', completiondate
|
|
else:
|
|
if not completiondate:
|
|
completiondate = ws.reverse()[0].date
|
|
|
|
return ratio, 'partial', completiondate
|
|
else:
|
|
thevalue = 0
|
|
for key, value in cratios.items():
|
|
if ratio > value and value > thevalue:
|
|
verdict = key
|
|
thevalue = value
|
|
|
|
completiondate = ws.reverse()[0].date
|
|
return ratio, verdict, completiondate
|
|
elif ps.sessiontype == 'test':
|
|
if ratio == 1.0:
|
|
return ratio, 'on target', completiondate
|
|
else:
|
|
return ratio, 'partial', completiondate
|
|
elif ps.sessiontype == 'challenge':
|
|
if ps.criterium == 'exact':
|
|
if ratio == 1.0:
|
|
return ratio, 'on target', completiondate
|
|
else:
|
|
return ratio, 'partial', completiondate
|
|
elif ps.criterium == 'minimum': # pragma: no cover
|
|
if ratio > 1.0:
|
|
return ratio, 'on target', completiondate
|
|
else:
|
|
if not completiondate:
|
|
completiondate = ws.reverse()[0].date
|
|
return ratio, 'partial', completiondate
|
|
else:
|
|
if not completiondate: # pragma: no cover
|
|
completiondate = ws.reverse()[0].date
|
|
return ratio, 'partial', completiondate
|
|
elif ps.sessiontype == 'race': # pragma: no cover
|
|
vs = VirtualRaceResult.objects.filter(race=ps)
|
|
wids = [w.id for w in ws]
|
|
for record in vs:
|
|
if record.workoutid in wids:
|
|
if record.coursecompleted:
|
|
ratio = record.distance/ps.sessionvalue
|
|
return ratio, 'on target', completiondate
|
|
else:
|
|
ratio = record.distance/ps.sessionvalue
|
|
return ratio, 'partial', completiondate
|
|
return (0, 'partial', None)
|
|
elif ps.sessiontype in ['fastest_time', 'fastest_distance']: # pragma: no cover
|
|
vs = CourseTestResult.objects.filter(
|
|
plannedsession=ps, userid=ws[0].user.user.id)
|
|
completiondate = ws.reverse()[0].date
|
|
wids = [w.id for w in ws]
|
|
for record in vs:
|
|
if record.workoutid in wids:
|
|
if record.coursecompleted:
|
|
ratio = 1
|
|
return ratio, 'on target', completiondate
|
|
else:
|
|
return 0, 'partial', completiondate
|
|
if ws:
|
|
record = CourseTestResult(
|
|
userid=ws[0].user.id,
|
|
plannedsession=ps,
|
|
workoutid=ws[0].id,
|
|
duration=dt.time(0, 0),
|
|
coursecompleted=False
|
|
)
|
|
record.save()
|
|
return (0, 'not done', None)
|
|
elif ps.sessiontype == 'coursetest': # pragma: no cover
|
|
vs = CourseTestResult.objects.filter(plannedsession=ps)
|
|
wids = [w.id for w in ws]
|
|
for record in vs:
|
|
if record.workoutid in wids:
|
|
if record.coursecompleted:
|
|
ratio = record.distance/float(ps.sessionvalue)
|
|
return ratio, 'on target', completiondate
|
|
else:
|
|
ratio = record.distance/float(ps.sessionvalue)
|
|
return ratio, 'partial', completiondate
|
|
|
|
# we're still here - no record, need to create one
|
|
if ws:
|
|
record = CourseTestResult(
|
|
userid=ws[0].user.id,
|
|
plannedsession=ps,
|
|
workoutid=ws[0].id,
|
|
duration=dt.time(0, 0),
|
|
coursecompleted=False,
|
|
)
|
|
record.save()
|
|
_ = myqueue(queue, handle_check_race_course, ws[0].csvfilename,
|
|
ws[0].id, ps.course.id, record.id,
|
|
ws[0].user.user.email, ws[0].user.user.first_name,
|
|
mode='coursetest')
|
|
|
|
return (0, 'not done', None)
|
|
|
|
else: # pragma: no cover
|
|
if not completiondate:
|
|
completiondate = ws.reverse()[0].date
|
|
return ratio, verdict, completiondate
|
|
|
|
|
|
def is_session_complete(r, ps):
|
|
if r not in ps.rower.all(): # pragma: no cover
|
|
return 0, 'not assigned', None
|
|
|
|
ws = Workout.objects.filter(user=r, plannedsession=ps)
|
|
|
|
return is_session_complete_ws(ws, ps)
|
|
|