diff --git a/rowers/courses.py b/rowers/courses.py
index 7a3066a2..cfe3ac45 100644
--- a/rowers/courses.py
+++ b/rowers/courses.py
@@ -33,7 +33,7 @@ from rowers.models import (
)
from utils import geo_distance
-from rowers.courseutils import coursetime_paths, coursetime_first
+from rowers.courseutils import coursetime_paths, coursetime_first,time_in_path
@@ -199,12 +199,16 @@ def get_time_course(ws,course):
rowdata = rowdata.resample('100ms',on='dt').mean()
rowdata = rowdata.interpolate()
+ # create path
polygons = GeoPolygon.objects.filter(course=course).order_by("order_in_course")
paths = []
for polygon in polygons:
path = polygon_to_path(polygon)
paths.append(path)
+
+
+
(
coursetimeseconds,
coursemeters,
diff --git a/rowers/courseutils.py b/rowers/courseutils.py
index d3b8d636..75130af5 100644
--- a/rowers/courseutils.py
+++ b/rowers/courseutils.py
@@ -10,7 +10,7 @@ class InvalidTrajectoryError(Exception):
def __str__(self):
return repr(self.value)
-def time_in_path(df,p,maxmin='max'):
+def time_in_path(df,p,maxmin='max',getall=False):
if df.empty:
return 0
@@ -29,7 +29,10 @@ def time_in_path(df,p,maxmin='max'):
if len(df[b==2]):
- return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()
+ if getall:
+ return df[b==2]['time'],df[b==2]['cum_dist']
+ else:
+ return df[b==2]['time'].min(),df[b==2]['cum_dist'].min()
raise InvalidTrajectoryError("Trajectory doesn't go through path")
diff --git a/rowers/forms.py b/rowers/forms.py
index 1f1687dc..27b7ce35 100644
--- a/rowers/forms.py
+++ b/rowers/forms.py
@@ -699,17 +699,17 @@ 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)
+# 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):
+ def __init__(self, workoutdata,entries, *args, **kwargs):
super(WorkoutRaceSelectForm, self).__init__(*args, **kwargs)
@@ -720,6 +720,12 @@ class WorkoutRaceSelectForm(forms.Form):
widget=forms.RadioSelect,
)
+ self.fields['record'] = forms.ChoiceField(
+ label = 'Entry',
+ choices = entries['choices'],
+ initial = entries['initial'],
+ )
+
# self.fields['evaluate_after'] =
class PlannedSessionTeamForm(forms.Form):
diff --git a/rowers/models.py b/rowers/models.py
index f4d59ded..d6811a12 100644
--- a/rowers/models.py
+++ b/rowers/models.py
@@ -1587,6 +1587,19 @@ class VirtualRaceResult(models.Model):
age = models.IntegerField(null=True)
+ def __unicode__(self):
+ rr = Rower.objects.get(id=self.userid)
+ name = '{u1} {u2}'.format(
+ u1 = rr.user.first_name,
+ u2 = rr.user.last_name,
+ )
+ return u'Entry for {n} for "{r}" in {d}'.format(
+ n = name,
+ r = self.race,
+ d = self.boattype,
+ )
+
+
class CourseTestResult(models.Model):
userid = models.IntegerField(default=0)
workoutid = models.IntegerField(null=True)
@@ -1600,6 +1613,13 @@ class VirtualRaceResultForm(ModelForm):
model = VirtualRaceResult
fields = ['teamname','weightcategory','boattype','age']
+
+ def __init__(self, *args, **kwargs):
+ boattypes = kwargs.pop('boattypes',None)
+ super(VirtualRaceResultForm, self).__init__(*args, **kwargs)
+
+ if boattypes:
+ self.fields['boattype'].choices = boattypes
from rowers.metrics import rowingmetrics
diff --git a/rowers/plannedsessions.py b/rowers/plannedsessions.py
index a6cb7a56..ffc8837a 100644
--- a/rowers/plannedsessions.py
+++ b/rowers/plannedsessions.py
@@ -630,7 +630,12 @@ def race_can_submit(r,race):
return False
def race_can_resubmit(r,race):
- if r not in race.rower.all():
+ records = VirtualRaceResult.objects.filter(
+ userid=r.id,
+ race=race)
+
+
+ if not records:
return False
start_time = race.start_time
@@ -651,8 +656,44 @@ def race_can_resubmit(r,race):
return False
+def race_can_adddiscipline(r,race):
+ records = VirtualRaceResult.objects.filter(
+ userid=r.id,
+ race=race)
+
+
+ if not records:
+ return False
+
+ start_time = race.start_time
+ start_date = race.startdate
+ startdatetime = datetime.combine(start_date,start_time)
+ startdatetime = pytz.timezone(race.timezone).localize(
+ startdatetime
+ )
+ evaluation_closure = race.evaluation_closure
+
+
+
+ if timezone.now() < evaluation_closure:
+ is_complete,has_registered = race_rower_status(r,race)
+ if has_registered:
+ return True
+ else:
+ return False
+ else:
+ return False
+
+ return False
+
+
def race_can_withdraw(r,race):
- if r not in race.rower.all():
+ records = VirtualRaceResult.objects.filter(
+ userid=r.id,
+ race=race
+ )
+
+ if not records:
return False
start_time = race.start_time
@@ -674,7 +715,11 @@ def race_can_withdraw(r,race):
return True
def race_can_register(r,race):
- if r in race.rower.all():
+ records = VirtualRaceResult.objects.filter(
+ userid=r.id,
+ race=race)
+
+ if records:
return False
start_time = race.start_time
@@ -699,20 +744,25 @@ def add_rower_race(r,race):
return 1
-def remove_rower_race(r,race):
+def remove_rower_race(r,race,recordid=None):
race.rower.remove(r)
- records = VirtualRaceResult.objects.filter(userid=r.id,
- workoutid__isnull=True,
- race=race)
-
+ if recordid:
+ records = VirtualRaceResult.objects.filter(userid=r.id,
+ workoutid__isnull=True,
+ race=race,
+ id=recordid)
+ else:
+ records = VirtualRaceResult.objects.filter(userid=r.id,
+ workoutid__isnull=True,
+ race=race,)
for r in records:
r.delete()
return 1
# Low Level functions - to be called by higher level methods
-def add_workout_race(ws,race,r,splitsecond=0):
+def add_workout_race(ws,race,r,splitsecond=0,recordid=0):
result = 0
comments = []
errors = []
@@ -758,12 +808,21 @@ def add_workout_race(ws,race,r,splitsecond=0):
else:
age = None
+ record = VirtualRaceResult.objects.get(
+ userid=r.id,
+ race=race,
+ id=recordid
+ )
+
records = VirtualRaceResult.objects.filter(
userid=r.id,
- race=race
- )
-
- record = records[0]
+ race=race,
+ workoutid = ws[0].id
+ )
+
+ if not record:
+ errors.append("Couldn't find this entry")
+ return result,comments,errors,0
if ws[0].boattype != record.boattype:
errors.append('Your workout boat type did not match the boat type you registered')
@@ -774,18 +833,22 @@ def add_workout_race(ws,race,r,splitsecond=0):
return 0,comments, errors,0
# start adding sessions
- for w in ws:
- if w.startdatetime>=startdatetime and w.startdatetime<=enddatetime:
- w.plannedsession = race
- w.save()
- result += 1
+ if ws[0].startdatetime>=startdatetime and ws[0].startdatetime<=enddatetime:
+ ws[0].plannedsession = race
+ ws[0].save()
+ result += 1
- else:
- errors.append('Workout %i did not match the race window' % w.id)
- return result,comments,errors,0
+ else:
+ errors.append('Workout %i did not match the race window' % ws[0].id)
+ return result,comments,errors,0
if result>0:
-
+ for otherrecord in records:
+ print otherrecord
+ otherrecord.workoutid = None
+ otherrecord.coursecompleted = False
+ otherrecord.save()
+
job = myqueue(queue,handle_check_race_course,ws[0].csvfilename,
ws[0].id,race.course.id,record.id,splitsecond=splitsecond)
diff --git a/rowers/tasks.py b/rowers/tasks.py
index 139f8908..8739e307 100644
--- a/rowers/tasks.py
+++ b/rowers/tasks.py
@@ -70,7 +70,7 @@ siteurl = SITE_URL
# testing task
from rowers.emails import send_template_email
-from rowers.courseutils import coursetime_paths, coursetime_first
+from rowers.courseutils import coursetime_paths, coursetime_first, time_in_path
@app.task
def add(x, y):
@@ -276,21 +276,56 @@ def handle_check_race_course(self,
path = polygon_to_path(polygon,debug=debug)
paths.append(path)
- (
- coursetimeseconds,
- coursemeters,
- coursecompleted,
-
- ) = coursetime_paths(rowdata,paths)
- (
- coursetimefirst,
- coursemetersfirst,
- firstcompleted
- ) = coursetime_first(
- rowdata,paths)
+ # check how many times went through start polygon
+ entrytimes,entrydistances = time_in_path(rowdata,paths[0],maxmin='max',getall=True)
- coursetimeseconds = coursetimeseconds-coursetimefirst
- coursemeters = coursemeters-coursemetersfirst
+ cseconds = []
+ cmeters = []
+ ccomplete = []
+
+ for startt in entrytimes:
+
+ rowdata2 = rowdata[rowdata['time']>(startt-10.)]
+
+ (
+ coursetimeseconds,
+ coursemeters,
+ coursecompleted,
+
+ ) = coursetime_paths(rowdata2,paths)
+ (
+ coursetimefirst,
+ coursemetersfirst,
+ firstcompleted
+ ) = coursetime_first(
+ rowdata2,paths)
+
+
+
+ coursetimeseconds = coursetimeseconds-coursetimefirst
+ coursemeters = coursemeters-coursemetersfirst
+
+ cseconds.append(coursetimeseconds)
+ cmeters.append(coursemeters)
+ ccomplete.append(coursecompleted)
+
+
+ records = pd.DataFrame({
+ 'coursetimeseconds':cseconds,
+ 'coursecompleted': ccomplete,
+ 'coursemeters': cmeters
+ })
+
+ records = records[records['coursecompleted'] == True]
+
+ if len(records):
+ coursecompleted = True
+ mintime = records['coursetimeseconds'].min()
+ coursetimeseconds = records[records['coursetimeseconds'] == mintime]['coursetimeseconds'].min()
+ coursemeters = records[records['coursetimeseconds'] == mintime]['coursemeters'].min()
+ else:
+ coursecompleted = False
+
if coursecompleted:
query = 'UPDATE rowers_virtualraceresult SET coursecompleted = 1, duration = "{duration}", distance = {distance}, workoutid = {workoutid} WHERE id={recordid}'.format(
diff --git a/rowers/templates/email.html b/rowers/templates/email.html
index c98b4357..02f23929 100644
--- a/rowers/templates/email.html
+++ b/rowers/templates/email.html
@@ -92,6 +92,7 @@ When the site is down, this is the appropriate channel to look for apologies, up
602 00 Brno
Czech Republic
IČ: 070 48 572
+ DIČ: CZ 070 48 572
Datová schránka: 7897syr
Email: info@rowsandall.com
The company is registered in the business register at the
diff --git a/rowers/templates/race_submit.html b/rowers/templates/race_submit.html
index 9ba26637..4b4b397b 100644
--- a/rowers/templates/race_submit.html
+++ b/rowers/templates/race_submit.html
@@ -27,7 +27,6 @@