From ce51bbc26c14d276c0bfabb75b07810803f14e54 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Tue, 23 Jun 2020 21:48:33 +0200 Subject: [PATCH] race entry self service --- rowers/models.py | 53 +++++++ rowers/templates/entryedit.html | 71 +++++++++ rowers/templates/virtualevent.html | 62 ++++---- rowers/urls.py | 2 + rowers/views/racesviews.py | 225 +++++++++++++++++++++++++++++ 5 files changed, 388 insertions(+), 25 deletions(-) create mode 100644 rowers/templates/entryedit.html diff --git a/rowers/models.py b/rowers/models.py index 8e9ed3f8..a3f0d391 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -3002,6 +3002,34 @@ class VirtualRaceResult(models.Model): acceptsocialmedia = models.BooleanField(default=True, verbose_name = 'I agree with sharing my name in challenge related social media posts (unchecking this does not prevent you from participation)') + def isduplicate(self,other): + if self.userid != other.userid: + return False + if self.weightcategory != other.weightcategory: + return False + if self.adaptiveclass != other.adaptiveclass: + return False + if self.skillclass != other.skillclass: + return False + if self.race != other.race: + return False + if self.boatclass != other.boatclass: + return False + if self.boattype != other.boattype: + return False + if self.sex != other.sex: + return False + if self.entrycategory is not None and other.entrycategory is not None: + if self.entrycategory != other.entrycategory: + return False + elif self.entrycategory is None and other.entrycateogry is not None: + return False + elif self.entrycategory is not None and other.entrycategory is None: + return False + + return True + + def __str__(self): rr = Rower.objects.get(id=self.userid) name = '{u1} {u2}'.format( @@ -3080,6 +3108,31 @@ class IndoorVirtualRaceResult(models.Model): acceptsocialmedia = models.BooleanField(default=True, verbose_name = 'I agree with sharing my name in challenge related social media posts (unchecking this does not prevent you from participation)') + def isduplicate(self,other): + if self.userid != other.userid: + return False + if self.weightcategory != other.weightcategory: + return False + if self.adaptiveclass != other.adaptiveclass: + return False + if self.skillclass != other.skillclass: + return False + if self.race != other.race: + return False + if self.boatclass != other.boatclass: + return False + if self.sex != other.sex: + return False + if self.entrycategory is not None and other.entrycategory is not None: + if self.entrycategory != other.entrycategory: + return False + elif self.entrycategory is None and other.entrycategory is not None: + return False + elif self.entrycategory is not None and other.entrycategory is None: + return False + + return True + def __str__(self): rr = Rower.objects.get(id=self.userid) name = '{u1} {u2}'.format( diff --git a/rowers/templates/entryedit.html b/rowers/templates/entryedit.html new file mode 100644 index 00000000..fc1d5848 --- /dev/null +++ b/rowers/templates/entryedit.html @@ -0,0 +1,71 @@ +{% extends "newbase.html" %} +{% load staticfiles %} +{% load rowerfilters %} + +{% block title %}Register for a Virtual Race{% endblock %} + +{% block meta %} + + + +{% endblock %} + + +{% block main %} +

Change your entry for {{ race.name }}

+ + + +
+
+

If you are participating in a single, we will take the age and weight + value from your user settings. For other boat types, please fill out + crew weight class and average age. +

+ +

+ You will register as a crew with the gender of your user settings. If + your user settings have gender "not specified", you will be registered + as a Male crew. Check the "Mixed gender" check box to register as a + mixed gender crew (except for 1x where this check box does nothing). +

+

+ The challenge organizer may want to publish about the challenge on social media and + use your name in the results. If you do not want your name to appear on social media, + you can let this know by unchecking the check box in the form. +

+ {% if race.coursestandards %} +

This race uses standard times and limits the race groups to those where + standard times exist. The "Group" form choice will overrule other selections you + make in the form (boat type, weight, etc) and your entry will be rejected + if the age and gender doesn't match. +

+

+ You can check the valid race groups and standard times here. +

+ {% endif %} +
+ + {{ form.as_table }} +
+
+
+ {% csrf_token %} + + + +
+{% endblock %} + +{% block scripts %} +{% endblock %} + +{% block sidebar %} +{% include 'menu_racing.html' %} +{% endblock %} diff --git a/rowers/templates/virtualevent.html b/rowers/templates/virtualevent.html index 6decfc0c..d27b0109 100644 --- a/rowers/templates/virtualevent.html +++ b/rowers/templates/virtualevent.html @@ -263,14 +263,23 @@
  • -

    {% if race|is_final %}

    Final Results

    {% else %}

    Results

    {% endif %} -

    {% if results or dns or dnf %} + + + {% if race.sessiontype == 'race' %} + + {% endif %} + {% if race.manager == request.user %} + +

    @@ -330,14 +339,20 @@ {% endif %} + - @@ -380,7 +395,7 @@ {% endfor %} @@ -415,19 +430,6 @@
    {{ result.points|sigdig:4 }} - - Details + + + + {% if result.userid == request.user.rower.id and not race|is_final %} + + + + {% endif %} {% if race.manager == request.user and not race|is_final %} - - Disqualify + + {% else %}   @@ -345,8 +360,8 @@ {% if result.userid == request.user.rower.id and not race|is_final %} - - Remove + + {% endif %} DNF - Details +

    -

    - Compare Results - {% if race.sessiontype == 'race' %} - Compare Course - {% endif %} -

    - {% if race.manager == request.user %} -

    - Download Results -

    {% endif %} {% else %}

    @@ -506,11 +508,21 @@ {% endif %} {% endif %} - {% if record.userid == rower.id and 'withdrawbutton' in buttons %} + {% if record.userid == request.user.rower.id and not race|is_final %} - Withdraw + + + {% endif %} + {% if record.userid == rower.id and 'withdrawbutton' in buttons %} + + + + + + {% endif %} + {% endfor %} diff --git a/rowers/urls.py b/rowers/urls.py index 257162e1..58829974 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -186,6 +186,8 @@ urlpatterns = [ re_path(r'^virtualevent/(?P\d+)/editindoor/$',views.indoorvirtualevent_edit_view,name='indoorvirtualevent_edit_view'), re_path(r'^virtualevent/(?P\d+)/register/$',views.virtualevent_register_view,name='virtualevent_register_view'), re_path(r'^virtualevent/(?P\d+)/registerindoor/$',views.indoorvirtualevent_register_view,name='indoorvirtualevent_register_view'), + re_path(r'^virtualevent/(?P\d+)/register/edit/(?P\d+)/$',views.virtualevent_entry_edit_view, + name='virtualevent_entry_edit_view'), re_path(r'^virtualevent/(?P\d+)/adddiscipline/$',views.virtualevent_addboat_view,name='virtualevent_addboat_view'), re_path(r'^virtualevent/(?P\d+)/withdraw/(?P\d+)/$',views.virtualevent_withdraw_view,name='virtualevent_withdraw_view'), re_path(r'^virtualevent/(?P\d+)/withdraw/$',views.virtualevent_withdraw_view,name='virtualevent_withdraw_view'), diff --git a/rowers/views/racesviews.py b/rowers/views/racesviews.py index 93df6047..72e832c1 100644 --- a/rowers/views/racesviews.py +++ b/rowers/views/racesviews.py @@ -3103,3 +3103,228 @@ def addfollower_view(request,id=0): 'breadcrumbs':breadcrumbs, } ) + +@login_required() +def virtualevent_entry_edit_view(request,id=0,entryid=0): + r = getrower(request.user) + try: + race = VirtualRace.objects.get(id=id) + except VirtualRace.DoesNotExist: + raise Http404("Virtual Challenge does not exist") + + if not race_can_submit(r,race): + messages.error(request,'You cannot change your entries for this challenge') + url = reverse('virtualevent_view', + kwargs={'id':race.id} + ) + return HttpResponseRedirect(r,race) + + categories = None + if race.coursestandards is not None: + categories = CourseStandard.objects.filter( + standardcollection=race.coursestandards).order_by("name") + + if race.sessiontype == 'race': + resultobj = VirtualRaceResult + formobj = VirtualRaceResultForm + else: + resultobj = IndoorVirtualRaceResult + formobj = IndoorVirtualRaceResultForm + + records = resultobj.objects.filter( + userid = r.id, + race=race + ) + + try: + record = resultobj.objects.get(id=entryid) + except resultobj.DoesNotExist: + raise Http404("Could not find your entry") + + if request.method == 'POST': + form = formobj(request.POST,categories=categories) + if form.is_valid(): + cd = form.cleaned_data + + teamname = cd['teamname'] + try: + boattype = cd['boattype'] + except KeyError: + boattype = None + boatclass = cd['boatclass'] + weightcategory = cd['weightcategory'] + adaptiveclass = cd['adaptiveclass'] + age = cd['age'] + try: + mix = cd['mix'] + except KeyError: + mix = None + acceptsocialmedia = cd['acceptsocialmedia'] + + sex = r.sex + if mix: + sex = 'mixed' + + if boattype == '1x' and r.birthdate: + age = calculate_age(r.birthdate) + sex = r.sex + + if sex == 'not specified': + sex = 'male' + + + coursestandard = None + referencespeed = 5.0 + + returnurl = reverse(virtualevent_entry_edit_view, + kwargs={'id':race.id, + 'entryid':record.id}) + + if race.coursestandards is not None: + coursestandard = cd['entrycategory'] + referencespeed = coursestandard.referencespeed + boattype = coursestandard.boattype + boatclass = coursestandard.boatclass + weightcategory = coursestandard.weightclass + adaptiveclass = coursestandard.adaptiveclass + skillclass = coursestandard.skillclass + + if age < coursestandard.agemin: + messages.error(request,'You are younger than the minimum age for this group') + return HttpResponseRedirect(returnurl) + + if age > coursestandard.agemax: + messages.error(request,'You are older than the maximum age for this group') + return HttpResponseRedirect(returnurl) + + if sex == 'male' and coursestandard.sex != 'male': + messages.error(request,'Men are not allowed to enter this category') + return HttpResponseRedirect(returnurl) + + if sex == 'mixed' and coursestandard.sex not in ['mixed','male']: + messages.error(request,'Mixed crews are not allowed to enter this category') + return HttpResponseRedirect(returnurl) + + if record.workoutid: + try: + w = Workout.objects.get(id=record.workoutid) + except Workout.DoesNotExist: + w = None + + if w is not None: + if boattype != w.boattype: + messages.error(request,'You cannot change boat type to a different one than your row') + return HttpResponseRedirect(returnurl) + if boatclass != w.workouttype: + messages.error(request,'You cannot change the class to a different one than your row') + return HttpResponseRedirect(returnurl) + if weightcategory != w.weightcategory: + messages.error(request,'You cannot change weight class to a different one than your row') + return HttpResponseRedirect(returnurl) + if adaptiveclass != w.adaptiveclass: + messages.error(request,'You cannot change adaptive class to a different one than your row') + return HttpResponseRedirect(returnurl) + else: + if boattype != record.boattype: + messages.error(request,'You cannot change boat type to a different one ') + return HttpResponseRedirect(returnurl) + if boatclass != record.workouttype: + messages.error(request,'You cannot change the class to a different one ') + return HttpResponseRedirect(returnurl) + if weightcategory != record.weightcategory: + messages.error(request,'You cannot change weight class to a different one ') + return HttpResponseRedirect(returnurl) + if adaptiveclass != record.adaptiveclass: + messages.error(request,'You cannot change adaptive class to a different one ') + return HttpResponseRedirect(returnurl) + + if record.points != 0: + record.points = record.points*record.referencespeed/referencespeed + + record.teamname = teamname + record.weightcategory=weightcategory + record.adaptiveclass=adaptiveclass + record.boatclass=boatclass + if race.sessiontype == 'race': + record.boattype = boattype + record.mix = mix + record.sex=sex + record.age=age + record.entrycategory=coursestandard + record.referencespeed=referencespeed + record.acceptsocialmedia=acceptsocialmedia + + duplicates = False + for otherrecord in records: + if record.isduplicate(otherrecord): + duplicates = True + + if duplicates: + messages.error(request,"You have already entered this group") + return HttpResponseRedirect(returnurl) + else: + record.save() + + messages.info( + request, + "You have successfully altered your entry for this race. Good luck!" + ) + + url = reverse('virtualevent_view', + kwargs = { + 'id':race.id + }) + return HttpResponseRedirect(url) + else: + form = formobj(instance=record,categories=categories) + + + breadcrumbs = [ + { + 'url':reverse('virtualevents_view'), + 'name': 'Challenges' + }, + { + 'url':reverse('virtualevent_view', + kwargs={'id':race.id} + ), + 'name': race.name + }, + { + 'url': reverse(virtualevent_entry_edit_view, + kwargs = {'id':race.id, + 'entryid':entryid} + ), + 'name': 'Follow' + } + ] + + buttons = [] + + if not request.user.is_anonymous: + if race_can_register(r,race): + buttons += ['registerbutton'] + + if race_can_adddiscipline(r,race): + buttons += ['adddisciplinebutton'] + + if race_can_submit(r,race): + buttons += ['submitbutton'] + + if race_can_resubmit(r,race): + buttons += ['resubmitbutton'] + + if race_can_withdraw(r,race): + buttons += ['withdrawbutton'] + + if race_can_edit(r,race): + buttons += ['editbutton'] + + return render(request,'entryedit.html', + { + 'form':form, + 'active':'nav-racing', + 'breadcrumbs':breadcrumbs, + 'userid':r.user.id, + 'race':race, + })