From ccdf24f671d2feb8c528befc23446ecf03303deb Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Sat, 16 Feb 2019 17:15:25 +0100 Subject: [PATCH] not sure if this works --- rowers/models.py | 24 ++- rowers/tasks.py | 51 ++++++ rowers/teams.py | 195 +++++++++++++++++++++- rowers/templates/coacheerequestemail.html | 32 ++++ rowers/templates/coachrequestemail.html | 33 ++++ rowers/templates/menu_analytics.html | 2 +- rowers/templates/menu_plan.html | 2 +- rowers/templates/menu_profile.html | 2 +- rowers/templates/menu_teams.html | 2 +- rowers/templates/menu_workouts.html | 2 +- rowers/templates/team.html | 2 +- rowers/templates/teams.html | 128 +++++++++++++- rowers/tests/testdata/testdata.csv.gz | Bin 12525 -> 12525 bytes rowers/urls.py | 16 ++ rowers/views/statements.py | 2 +- rowers/views/teamviews.py | 123 +++++++++++++- 16 files changed, 599 insertions(+), 17 deletions(-) create mode 100644 rowers/templates/coacheerequestemail.html create mode 100644 rowers/templates/coachrequestemail.html diff --git a/rowers/models.py b/rowers/models.py index ca7f3869..b4426431 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -386,7 +386,6 @@ class TeamInviteForm(ModelForm): - class TeamRequest(models.Model): team = models.ForeignKey(Team) @@ -633,6 +632,8 @@ class PaidPlan(models.Model): paymentprocessor = self.paymentprocessor, ) +class CoachingGroup(models.Model): + pass # Extension of User with rowing specific data class Rower(models.Model): @@ -832,7 +833,8 @@ class Rower(models.Model): # Friends/Team friends = models.ManyToManyField("self",blank=True) - coaches = models.ManyToManyField("self",blank=True) + mycoachgroup = models.ForeignKey(CoachingGroup,related_name='coachingrole',null=True) + coachinggroups = models.ManyToManyField(CoachingGroup,related_name='coaches') privacy = models.CharField(default='visible',max_length=30, choices=privacychoices) @@ -870,6 +872,19 @@ class DeleteUserForm(forms.ModelForm): model = User fields = [] +# requestor is user +class CoachRequest(models.Model): + coach = models.ForeignKey(Rower) + user = models.ForeignKey(User,null=True) + issuedate = models.DateField(default=current_day) + code = models.CharField(max_length=150,unique=True) + +# requestor is coach +class CoachOffer(models.Model): + coach = models.ForeignKey(Rower) + user = models.ForeignKey(User,null=True) + issuedate = models.DateField(default=current_day) + code = models.CharField(max_length=150,unique=True) from django.db.models.signals import m2m_changed @@ -988,7 +1003,7 @@ def checkworkoutuser(user,workout): return False try: r = Rower.objects.get(user=user) - coaches = user.rower.coaches.filter(rowerplan='coach') + coaches = rower_get_coaches(user.rower) if workout.user == r: return True elif coaches: @@ -1007,7 +1022,7 @@ def checkaccessuser(user,rower): r = Rower.objects.get(user=user) if rower == r: return True - coaches = rower.coaches.filter(rowerplan='coach') + coaches = rower_get_coaches(rower) if coaches: for coach in coaches: if user.rower == coach: @@ -3434,3 +3449,4 @@ class PlannedSessionCommentForm(ModelForm): 'comment': forms.Textarea, } + diff --git a/rowers/tasks.py b/rowers/tasks.py index 7f4b756c..21531d98 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -1699,6 +1699,57 @@ def handle_makeplot(f1, f2, t, hrdata, plotnr, imagename, # Team related remote tasks +@app.task +def handle_sendemail_coachrequest(email,name,code,coachname, + debug=False,**kwargs): + + fullemail = email + subject = 'Invitation to add {n} to your athletes'.format(n=name) + + siteurl = SITE_URL + if debug: + siteurl = SITE_URL_DEV + + d = { + 'name':name, + 'coach':coachname, + 'code':code, + 'siteurl':siteurl + } + + form_email = 'Rowsandall ' + + res = send_template_email(from_email,[fullemail], + subject,'coachrequestemail.html',d, + **kwargs) + + return 1 + +@app.task +def handle_sendemail_coacheerequest(email,name,code,coachname, + debug=False,**kwargs): + + fullemail = email + subject = '{n} asks coach access to your data on rowsandall.com'.format(n=coachname) + + siteurl = SITE_URL + if debug: + siteurl = SITE_URL_DEV + + d = { + 'name':name, + 'coach':coachname, + 'code':code, + 'siteurl':siteurl + } + + form_email = 'Rowsandall ' + + res = send_template_email(from_email,[fullemail], + subject,'coacheerequestemail.html',d, + **kwargs) + + return 1 @app.task def handle_sendemail_invite(email, name, code, teamname, manager, diff --git a/rowers/teams.py b/rowers/teams.py index e6604f98..91b9e75d 100644 --- a/rowers/teams.py +++ b/rowers/teams.py @@ -17,7 +17,7 @@ queuelow = django_rq.get_queue('low') queuehigh = django_rq.get_queue('low') from rowers.models import ( - Rower, Workout, Team, TeamInvite,User,TeamRequest + Rower, Workout, Team, TeamInvite,User,TeamRequest, CoachRequest, CoachOffer ) from rowers.tasks import ( @@ -26,6 +26,7 @@ from rowers.tasks import ( handle_sendemail_member_dropped,handle_sendemail_request_accept, handle_sendemail_request_reject,handle_sendemail_invite_reject, handle_sendemail_invite_accept,handle_sendemail_team_removed, + handle_sendemail_coachrequest,handle_sendemail_coacheerequest, ) from rowers.models import ValidationError @@ -102,8 +103,17 @@ def remove_team(id): return (1,'Updated rower team expiry') -def add_coach(manager,rower): - rower.coaches.add(m) +def add_coach(coach,rower): + # get coaching group + try: + coachgroup = coach.mycoachgroup + except CoachingGroup.DoesNotExist: + coachgroup = CoachingGroup() + coachgroup.save() + coach.mycoachgroup = coachgroup + coach.save() + + rower.coachinggroups.add(coach) return (1,"Added Coach") @@ -134,6 +144,44 @@ def remove_member(id,rower): # set_teamplanexpires(rower) return (id,'Member removed') +def remove_coach(coach,rower): + try: + coachgroup = coach.mycoachgroup + except CoachingGroup.DoesNotExist: + coachgroup = CoachingGroup() + coachgroup.save() + coach.mycoachgroup = coachgroup + coach.save() + + rower.coachinggroups.remove(coachgroup) + + return (1,'Coach removed') + +def rower_get_coaches(rower): + coaches = [] + for group in rower.coachinggroups: + coach = Rower.objects.get(mycoachgroup=group) + coaches.append(coach) + + return coaches + + +def coach_getcoachees(coach): + return Rower.objects.filter(coachinggroups__in=[coach.mycoachgroup]) + +def coach_remove_athlete(coach,rower): + try: + coachgroup = coach.mycoachgroup + except CoachingGroup.DoesNotExist: + coachgroup = CoachingGroup() + coachgroup.save() + coach.mycoachgroup = coachgroup + coach.save() + + rower.coachingrgroups.remove(coachgroup) + + return (1,'Coach removed') + def mgr_remove_member(id,manager,rower): t = Team.objects.get(id=id) if t.manager == manager: @@ -161,6 +209,51 @@ def count_club_members(manager): # Medium level functionality +# request by user to be coached by coach +def create_coaching_request(coach,user): + if coach in rower_get_coaches(user.rower): + return (0,'Already coached by that coach') + + codes = [i.code for i in CoachRequest.objects.all()] + code = uuid.uuid4().hex[:10].upper() + while code in codes: + code = uuid.uuid4().hex[:10].upper() + + if coach.rowerplan == 'coach': + rekwest = CoachRequest(coach=coach,user=user,code=code) + rekwest.save() + + send_coachrequest_email(rekwest) + + return (rekwest.id,'The request was created') + + else: + return (0,'That person is not a coach') + +def send_coachrequest_email(rekwest): + name = rekwest.user.first_name + " " + rekwest.user.last_name + email = rekwest.user.email + + code = rekwest.code + + coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name + + res = myqueue(queuehigh, + handle_sendemail_coachrequest, + email,name,code,coachname) + +def send_coacheerequest_email(rekwest): + name = rekwest.user.first_name + " " + rekwest.user.last_name + email = rekwest.user.email + + code = rekwest.code + + coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name + + res = myqueue(queuehigh, + handle_sendemail_coacheerequest, + email,name,code,coachname) + def create_request(team,user): r2 = Rower.objects.get(user=user) r = Rower.objects.get(user=team.manager) @@ -183,7 +276,33 @@ def create_request(team,user): return (rekwest.id,'The request was created') return (0,'Something went wrong in create_request') + +# request by coach to coach user +def create_coaching_offer(coach,user): + r = user.rower + + if coach in rower_get_coaches(user.rower): + return (0,'You are already coaching this person.') + + codes = [i.code for i in CoachOffer.objects.all()] + code = uuid.uuid4().hex[:10].upper() + while code in codes: + code = uuid.uuid4().hex[:10].upper() + + if coach.rowerplan == 'coach': + rekwest = CoachOffer(coach=coach,user=user,code=code) + rekwest.save() + + send_coacheerequest_email(rekwest) + + return (rekwest.id,'The request was created') + + else: + return (0,'You are not a coach') + + + def create_invite(team,manager,user=None,email=''): r = Rower.objects.get(user=manager) if team.manager != manager: @@ -235,6 +354,36 @@ def revoke_request(user,id): else: return (0,'You are not the requestor') +def reject_revoke_coach_offer(user,id): + try: + rekwest = CoachOffer.objects.get(id=id) + except CoachOffer.DoesNotExist: + return (0,'The request is invalid') + + if rekwest.coach.user == user: + rekwest.delete() + return (1,'Request removed') + elif rekwest.user == user: + rekwest.delete() + return (1,'Request removed') + else: + return (0,'Not permitted') + +def reject_revoke_coach_request(user,id): + try: + rekwest = CoachRequest.objects.get(id=id) + except CoachRequest.DoesNotExist: + return (0,'The request is invalid') + + if rekwest.coach.user == user: + rekwest.delete() + return (1,'Request rejected') + elif rekwest.user == user: + rekwest.delete() + return (1,'Request rejected') + else: + return (0,'Not permitted') + def revoke_invite(manager,id): try: invite = TeamInvite.objects.get(id=id) @@ -458,3 +607,43 @@ def remove_expired_invites(): revoke_invite(i.team.manager,i.id) return (1,'Expired invitations deleted') + +def process_coachrequest_code(coach,code): + code = code.upper() + + try: + rekwest = CoachRequest.objects.get(code=code) + except CoachRequest.DoesNotExist: + return (0,'The request has been revoked or is invalid') + + if rekwest.coach != coach: + return (0,'The request is invalid') + + result = add_coach(coach,rekwest.user.rower) + if not result: + return (result,"Something went wrong") + + rekwest.delete() + + return result + +def process_coachoffer_code(user,code): + code = code.upper() + + try: + rekwest = CoachOffer.objects.get(code=code) + except CoachOffer.DoesNotExist: + return (0,'The request has been revoked or is invalid') + + if rekwest.user != user: + return (0,'The request is invalid') + + result = add_coach(rekwest.coach,rekwest.user.rower) + if not result: + return (result,"Something went wrong") + + rekwest.delete() + + return result + + diff --git a/rowers/templates/coacheerequestemail.html b/rowers/templates/coacheerequestemail.html new file mode 100644 index 00000000..fd0fbaa5 --- /dev/null +++ b/rowers/templates/coacheerequestemail.html @@ -0,0 +1,32 @@ +{% extends "emailbase.html" %} + +{% block body %} +

Dear {{ name }},

+ +

+ {{ coachname }} is inviting you to become your coach on rowsandall.com. +

+

+ By accepting the invite, {{ coachname }} will have access to your + data and will be able to upload workouts and run analysis on rowsandall.com + on behalf of you. +

+

+ By accepting the invite, you are agreeing with the sharing + of personal data according to our privacy policy. +

+

+ To accept, login to the + site and you will find the invitation here on the Teams page: + {{ siteurl }}/rowers/me/teams +

+

+ You can also click the direct link: + + {{ siteurl }}/rowers/me/coacheeinvitation/{{ code }} +

+ +

+ Best Regards, the Rowsandall Team +

+{% endblock %} diff --git a/rowers/templates/coachrequestemail.html b/rowers/templates/coachrequestemail.html new file mode 100644 index 00000000..4523aa66 --- /dev/null +++ b/rowers/templates/coachrequestemail.html @@ -0,0 +1,33 @@ +{% extends "emailbase.html" %} + +{% block body %} +

Dear {{ coachname }},

+ +

+ {{ name }} is inviting you to become his/her coach + on rowsandall.com +

+

+ By accepting the invite, you will have access to {{ name }}'s + data and will be able to upload workouts and run analysis on rowsandall.com + on behalf of {{ name }}. +

+

+ By accepting the invite, you are agreeing with the sharing + of personal data according to our privacy policy. +

+

+ To accept the login to the + site and you will find the invitation here on the Teams page: + {{ siteurl }}/rowers/me/teams +

+

+ You can also click the direct link: + + {{ siteurl }}/rowers/me/coachinvitation/{{ code }} +

+ +

+ Best Regards, the Rowsandall Team +

+{% endblock %} diff --git a/rowers/templates/menu_analytics.html b/rowers/templates/menu_analytics.html index ac847155..07c6d218 100644 --- a/rowers/templates/menu_analytics.html +++ b/rowers/templates/menu_analytics.html @@ -78,7 +78,7 @@
    {% for member in user|coach_rowers %} - + {% if member.user == rower.user %} • diff --git a/rowers/templates/menu_plan.html b/rowers/templates/menu_plan.html index fc82f23a..8dc3add6 100644 --- a/rowers/templates/menu_plan.html +++ b/rowers/templates/menu_plan.html @@ -94,7 +94,7 @@
      {% for member in user|coach_rowers %} - + {% if member.user == rower.user %} • diff --git a/rowers/templates/menu_profile.html b/rowers/templates/menu_profile.html index 19d370b8..3863b35e 100644 --- a/rowers/templates/menu_profile.html +++ b/rowers/templates/menu_profile.html @@ -46,7 +46,7 @@ diff --git a/rowers/templates/menu_workouts.html b/rowers/templates/menu_workouts.html index 20084c21..211e9167 100644 --- a/rowers/templates/menu_workouts.html +++ b/rowers/templates/menu_workouts.html @@ -55,7 +55,7 @@
        {% for member in user|coach_rowers %}
      • - + {% if member.user == rower.user and not team %} • diff --git a/rowers/templates/team.html b/rowers/templates/team.html index 3f31596f..242abdd5 100644 --- a/rowers/templates/team.html +++ b/rowers/templates/team.html @@ -39,7 +39,7 @@ {% for member in members %} {% if team.manager == user %} - {{ member.user.first_name }} {{ member.user.last_name }} + {{ member.user.first_name }} {{ member.user.last_name }} Drop {% else %} {{ member.user.first_name }} {{ member.user.last_name }} diff --git a/rowers/templates/teams.html b/rowers/templates/teams.html index 333e9888..d31b6ae4 100644 --- a/rowers/templates/teams.html +++ b/rowers/templates/teams.html @@ -80,7 +80,7 @@ {% endif %} - New Team + New Training Group
      • {% if coaches %}
      • @@ -136,7 +136,7 @@ {% endif %} {% if invites or requests or myrequests or myinvites %}
      • -

        Invitations and Requests

        +

        Group Invitations and Requests

        This section lists open invites to join a group. By accepting a group invite, you are agreeing with the sharing of personal data between group members and coaches according to @@ -221,7 +221,131 @@ {% endif %} + {% if mycoachrequests or mycoachoffers or coachoffers or coachrequests %} +

      • +

        Coaching Invitations and Requests

        +

        This section lists open invites related to coaching. + By accepting a coaching invite, the coach can run + analysis, add workouts and edit settings on behalf of the athlete. + You agree to the sharing + of personal data between athletes and coaches according to + our privacy policy. +

        + + + + + + + + + + + {% for i in coachrequests %} + + + + + + + {% endfor %} + {% for i in mycoachoffers %} + + + + + + + {% endfor %} + {% for i in mycoachrequests %} + + + + + + + {% endfor %} + {% for i in coachoffers %} + + + + + + + {% endfor %} + +
        CoachUserAction 
        {{ i.coach.user.first_name }} {{ i.coach.user.last_name }}{{ i.user.first_name }} {{ i.user.last_name }}Accept + + Reject +
        {{ i.coach.user.first_name }} {{ i.coach.user.last_name }}{{ i.user.first_name }} {{ i.user.last_name }}  + + Revoke +
        {{ i.coach.user.first_name }} {{ i.coach.user.last_name }}{{ i.user.first_name }} {{ i.user.last_name }}  + Revoke +
        {{ i.coach.user.first_name }} {{ i.coach.user.last_name }}{{ i.user.first_name }} {{ i.user.last_name }}Accept + + Reject +
        + {% endif %}
      • + {% if potentialathletes %} +
      • +

        Rowers you could coach

        + + + + + + + + + {% for a in potentialathletes %} + + + + + {% endfor %} + +
        UserAction
        {{ a.user.first_name }} {{ a.user.last_name }} + Offer Coaching +
        +
      • + {% endif %} + {% if potentialcoaches %} +
      • +

        Coaches who could coach you

        + + + + + + + + + {% for c in potentialcoaches %} + + + + + {% endfor %} + +
        UserAction
        {{ c.first_name }} {{ c.last_name }} + Request Coaching +
        +
      • + {% endif %}
      diff --git a/rowers/tests/testdata/testdata.csv.gz b/rowers/tests/testdata/testdata.csv.gz index bf3c1415543a64f250ce74d86c5ffe9180892b41..7256d94144270203437770568d2c04f40f5a37da 100644 GIT binary patch delta 15 WcmaEx_%@MEzMF$%?URjc&kX=K{sz1N delta 15 WcmaEx_%@MEzMF$X`2I$==LP^YNd_GN diff --git a/rowers/urls.py b/rowers/urls.py index ddd2ebb1..c36f4a5b 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -410,6 +410,22 @@ urlpatterns = [ url(r'^team/(?P\d+)/leave/$',views.team_leave_view,name='team_leave_view'), url(r'^team/(?P\d+)/deleteconfirm/$',views.team_deleteconfirm_view,name='team_deleteconfirm_view'), url(r'^team/(?P\d+)/requestmembership/(?P\d+)/$',views.team_requestmembership_view,name='team_requestmembership_view'), + url(r'^me/coachrequest/(?P\d+)/reject/$',views.reject_revoke_coach_request, + name='reject_revoke_coach_request'), + url(r'^me/coachrequest/(?P\d+)/revoke/$',views.reject_revoke_coach_request, + name='reject_revoke_coach_request'), + url(r'^me/coachoffer/(?P\d+)/reject/$',views.reject_revoke_coach_offer, + name='reject_revoke_coach_offer'), + url(r'^me/coachoffer/(?P\d+)/revoke/$',views.reject_revoke_coach_offer, + name='reject_revoke_coach_offer'), + url(r'^me/coachrequest/(?P\d+)/$',views.request_coaching_view, + name='request_coaching_view'), + url(r'^me/coachoffer/(?P\d+)/$',views.offer_coaching_view, + name='offer_coaching_view'), + url(r'^me/coachrequest/(\w+.*)/accept/$',views.coach_accept_coachrequest_view, + name='coach_accept_coachrequest_view'), + url(r'^me/coachoffer/(\w+.*)/accept/$',views.rower_accept_coachoffer_view, + name='rower_accept_coachofer_view'), url(r'^team/(?P\d+)/delete/$',views.team_delete_view,name='team_delete_view'), url(r'^team/create/$',views.team_create_view,name='team_create_view'), url(r'^me/team/(?P\d+)/drop/(?P\d+)/$',views.manager_member_drop_view,name='manager_member_drop_view'), diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 7dff9589..1a8ee0ae 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -88,7 +88,7 @@ from rowers.models import ( microcyclecheckdates,mesocyclecheckdates,macrocyclecheckdates, TrainingMesoCycleForm, TrainingMicroCycleForm, RaceLogo,RowerBillingAddressForm,PaidPlan, - PlannedSessionComment, + PlannedSessionComment,CoachRequest,CoachOffer, ) from rowers.models import ( RowerPowerForm,RowerForm,GraphImage,AdvancedWorkoutForm, diff --git a/rowers/views/teamviews.py b/rowers/views/teamviews.py index 0bce82e3..77827712 100644 --- a/rowers/views/teamviews.py +++ b/rowers/views/teamviews.py @@ -166,12 +166,35 @@ def rower_teams_view(request,message='',successmessage=''): myteams, memberteams, otherteams = get_teams(request) teams.remove_expired_invites() - invites = TeamInvite.objects.filter(user=request.user) requests = TeamRequest.objects.filter(user=request.user) myrequests = TeamRequest.objects.filter(team__in=myteams) myinvites = TeamInvite.objects.filter(team__in=myteams) + + # user invites (as coach) + mycoachoffers = CoachOffer.objects.filter(coach=r) + # user is invited (by coach) + coachoffers = CoachOffer.objects.filter(user=r.user) + + # user requests a coach + mycoachrequests = CoachRequest.objects.filter(user=r.user) + # user is requested to coach + coachrequests = CoachRequest.objects.filter(coach=r) + + invitedathletes = [rekwest.user for rekwest in mycoachoffers] + invitedcoaches = [rekwest.coach for rekwest in mycoachrequests] + + coaches = rower_get_coaches(r) + potentialcoaches = [t.manager for t in memberteams if t.manager not in coaches ] + potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches] + coachees = teams.coach_getcoachees(r) + + potentialathletes = Rower.objects.filter( + team__in=myteams).exclude( + user__in=invitedathletes).exclude(user=request.user) + + # clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user) # max_clubsize = r.clubsize @@ -184,6 +207,7 @@ def rower_teams_view(request,message='',successmessage=''): 'name': 'Teams' } ] + return render(request, 'teams.html', { @@ -198,6 +222,14 @@ def rower_teams_view(request,message='',successmessage=''): 'myrequests':myrequests, 'form':form, 'myinvites':myinvites, + 'mycoachrequests':mycoachrequests, + 'mycoachoffers':mycoachoffers, + 'coachrequests':coachrequests, + 'coachoffers':coachoffers, + 'coaches':coaches, + 'potentialcoaches':potentialcoaches, + 'coachees':coachees, + 'potentialathletes':potentialathletes, }) @login_required() @@ -276,6 +308,71 @@ def team_requestmembership_view(request,teamid,userid): return HttpResponseRedirect(url) +@login_required() +def request_coaching_view(request,coachid): + r = getrequestrower(request) + + coach = User.objects.get(id=coachid).rower + + if coach.rowerplan == 'coach': + res,text = teams.create_coaching_request(coach,request.user) + if res: + messages.info(request,text) + else: + messages.error(request,text) + else: + messages.error(request,'That person is not a coach') + + url = reverse('rower_teams_view') + + return HttpResponseRedirect(url) + +@user_passes_test(iscoachmember,login_url="/rowers/paidplans",redirect_field_name=None) +def offer_coaching_view(request,userid): + try: + u = User.objects.get(id=userid) + except User.DoesNotExist: + raise Http404("This user doesn't exist") + + coach = getrequestrower(request) + + res,text = teams.create_coaching_invite(coach,u) + + if res: + message.info(request,text) + else: + messages.error(request,text) + + url = reverse('rower_teams_view') + + return HttpResponseRedirecet(url) + +@login_required() +def reject_revoke_coach_request(request,id=0): + res, text = teams.reject_revoke_coach_request(request.user,id) + + if res: + messages.info(request,text) + else: + messages.error(request,text) + + url = reverse('rower_teams_view') + + return HttpResponseRedirect(url) + +@login_required() +def reject_revoke_coach_offer(request,id=0): + res, text = teams.reject_revoke_coach_offer(request.user,id) + + if res: + messages.info(request,text) + else: + messages.error(request,text) + + url = reverse('rower_teams_view') + + return HttpResponseRedirect(url) + @login_required() def request_revoke_view(request,id=0): res,text = teams.revoke_request(request.user,id) @@ -559,3 +656,27 @@ def team_members_stats_view(request,id): }) return response + +@login_required() +def rower_accept_coachoffer_view(request,code=None): + if code: + res, text = teams.process_coachoffer_code(request.user,code) + if res: + message.info(request,text) + else: + messages.error(request,text) + + url = reverse('rower_teams_view') + return HttpResponseRedirect(url) + +@login_required() +def coach_accept_coachrequest_view(request,code=None): + if code: + res, text = teams.process_coachrequest_code(request.user.rower,code) + if res: + messages.info(request,text) + else: + messages.error(request,text) + + url = reverse('rower_teams_view') + return HttpResponseRedirect(url)