diff --git a/rowers/forms.py b/rowers/forms.py index 1231a1d7..1f1687dc 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -699,6 +699,15 @@ class WorkoutSessionSelectForm(forms.Form): ) class WorkoutRaceSelectForm(forms.Form): + evaluate_after = forms.TimeField( + input_formats=['%H:%M:%S.%f', + '%H:%M:%S', + '%H:%M:%S', + '%M:%S.%f', + '%M:%S', + '%M'], + label = 'Only Evaluate After:', + required=False) def __init__(self, workoutdata, *args, **kwargs): @@ -710,7 +719,9 @@ class WorkoutRaceSelectForm(forms.Form): initial=workoutdata['initial'], widget=forms.RadioSelect, ) - + +# self.fields['evaluate_after'] = + class PlannedSessionTeamForm(forms.Form): team = forms.ModelMultipleChoiceField( queryset=Team.objects.all(), diff --git a/rowers/models.py b/rowers/models.py index c5dd1270..491bda83 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -1367,8 +1367,14 @@ class VirtualRaceForm(ModelForm): course = cd['course'] geocourse = GeoCourse.objects.get(id=course.id) timezone_str = get_course_timezone(geocourse) - + start_time = cd['start_time'] + if start_time is None: + raise forms.ValidationError( + 'Must have start time', + code='missing_yparam1' + ) + start_date = cd['startdate'] startdatetime = datetime.datetime.combine(start_date,start_time) startdatetime = pytz.timezone(timezone_str).localize( @@ -1376,6 +1382,12 @@ class VirtualRaceForm(ModelForm): ) end_time = cd['end_time'] + if end_time is None: + raise forms.ValidationError( + 'Must have end time', + code='missing endtime' + ) + end_date = cd['enddate'] enddatetime = datetime.datetime.combine(end_date,end_time) enddatetime = pytz.timezone(timezone_str).localize( diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py index 7f01d08c..a6cb7a56 100644 --- a/rowers/plannedsessions.py +++ b/rowers/plannedsessions.py @@ -712,7 +712,7 @@ def remove_rower_race(r,race): return 1 # Low Level functions - to be called by higher level methods -def add_workout_race(ws,race,r): +def add_workout_race(ws,race,r,splitsecond=0): result = 0 comments = [] errors = [] @@ -750,6 +750,29 @@ def add_workout_race(ws,race,r): errors.append('For tests, you can only attach one workout') return result,comments,errors,0 + + + username = r.user.first_name+' '+r.user.last_name + if r.birthdate: + age = calculate_age(r.birthdate) + else: + age = None + + records = VirtualRaceResult.objects.filter( + userid=r.id, + race=race + ) + + record = records[0] + + if ws[0].boattype != record.boattype: + errors.append('Your workout boat type did not match the boat type you registered') + return 0,comments,errors,0 + + if ws[0].weightcategory != record.weightcategory: + errors.append('Your workout weight category did not match the weight category you registered') + return 0,comments, errors,0 + # start adding sessions for w in ws: if w.startdatetime>=startdatetime and w.startdatetime<=enddatetime: @@ -762,30 +785,9 @@ def add_workout_race(ws,race,r): return result,comments,errors,0 if result>0: - username = r.user.first_name+' '+r.user.last_name - if r.birthdate: - age = calculate_age(r.birthdate) - else: - age = None - - records = VirtualRaceResult.objects.filter( - userid=r.id, - race=race - ) - - record = records[0] - - if ws[0].boattype != record.boattype: - errors.append('Your workout boat type did not match the boat type you registered') - return result,comments,errors,0 - - if ws[0].weightcategory != record.weightcategory: - errors.append('Your workout weight category did not match the weight category you registered') - return result,comments, errors,0 - job = myqueue(queue,handle_check_race_course,ws[0].csvfilename, - ws[0].id,race.course.id,record.id) + ws[0].id,race.course.id,record.id,splitsecond=splitsecond) add_workouts_plannedsession(ws,race,r) diff --git a/rowers/tasks.py b/rowers/tasks.py index cc6005ae..139f8908 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -210,6 +210,11 @@ def handle_check_race_course(self, else: debug = False + if 'splitsecond' in kwargs: + splitsecond = kwargs['splitsecond'] + else: + splitsecond = 0 + mode = 'race' if 'mode' in kwargs: mode = kwargs['mode'] @@ -236,10 +241,10 @@ def handle_check_race_course(self, ' ElapsedTime (sec)': 'time', }, inplace=True) - rowdata.fillna(method='backfill',inplace=True) rowdata['time'] = rowdata['time']-rowdata.ix[0,'time'] + rowdata = rowdata[rowdata['time']>splitsecond] # we may want to expand the time (interpolate) rowdata['dt'] = rowdata['time'].apply( lambda x: timedelta(seconds=x) diff --git a/rowers/templates/race_submit.html b/rowers/templates/race_submit.html index b51538b0..9ba26637 100644 --- a/rowers/templates/race_submit.html +++ b/rowers/templates/race_submit.html @@ -31,17 +31,35 @@

Select one of the following workouts that you rowed within the race window

- {% for field in w_form.hidden_fields %} - {{ field }} - {% endfor %} - {% for field in w_form.visible_fields %} - + {% endfor %} + {% for field in w_form.visible_fields %} + {% endfor %}
+ {% for field in w_form.hidden_fields %} {{ field }} - + {{ field.label }} + {{ field }} +
+
+

The "Only Evaluate After" field allows you to tell the site to + discard the first N minutes fo the workout. This is useful if you + paddled through the start polygon as part of your warming up. + Fill out the + time at which you want to start the evaluation, or leave empty to + evaluate the entire workout.

+

Use any of the following formats: +

+

+ +
{% csrf_token %} diff --git a/rowers/views.py b/rowers/views.py index 565bd793..ae511b83 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -13797,22 +13797,30 @@ def virtualevent_submit_result_view(request,id=0): if w_form.is_valid(): selectedworkout = w_form.cleaned_data['workouts'] + splittime = w_form.cleaned_data['evaluate_after'] + if splittime is not None: + splitsecond = splittime.hour*3600 + splitsecond += splittime.minute*60 + splitsecond += splittime.second + splitsecond += splittime.microsecond/1.e6 + else: + splitsecond = 0 else: selectedworkout = None - for w in ws: - remove_workout_plannedsession(w,race) - if selectedworkout is not None: - for w in ws: - remove_workout_plannedsession(w,race) - delete_race_result(w,race) workouts = Workout.objects.filter(id=selectedworkout) - result,comments,errors,jobid = add_workout_race(workouts,race,r) + result,comments,errors,jobid = add_workout_race( + workouts,race,r, + splitsecond=splitsecond) + if result: + for w in ws: + remove_workout_plannedsession(w,race) + delete_race_result(w,race) for c in comments: messages.info(request,c)