Private
Public Access
1
0
Files
rowsandall/rowers/teams.py

754 lines
22 KiB
Python

from rowers.rower_rules import is_team_manager, is_team_member, is_coach, user_is_basic
from rowers.models import ValidationError, PlannedSession
from rowers.tasks import (
handle_sendemail_invite,
handle_sendemail_request,
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,
handle_sendemail_coachoffer_rejected,
handle_sendemail_coachoffer_accepted,
handle_sendemail_coachrequest_rejected,
handle_sendemail_coachrequest_accepted,
handle_sendemail_message,
)
from rowers.models import (
Rower, Workout, Team, TeamInvite, User, TeamRequest, CoachRequest, CoachOffer,
CoachingGroup
)
# All the Team related methods
# Python
from django.utils import timezone
from datetime import datetime
from datetime import date as ddate
from datetime import timedelta
import time
from django.db import IntegrityError
import uuid
from django.conf import settings
from rowers.utils import myqueue
import django_rq
queue = django_rq.get_queue('default')
queuelow = django_rq.get_queue('low')
queuehigh = django_rq.get_queue('low')
# Low level functions - to be called by higher level methods
inviteduration = 14 # days
from rowers.tasks import handle_remove_workouts_team, handle_add_workouts_team
def update_team(t, name, manager, private, notes, viewing):
if not is_team_manager(manager, t):
return (0, 'You are not the manager of this team')
try:
t.name = name
t.manager = manager
t.private = private
t.notes = notes
t.viewing = viewing
t.save()
except IntegrityError:
return (0, 'Team name duplication')
return (1, 'Team Updated')
def create_team(name, manager, private='open', notes='', viewing='allmembers'):
# needs some error testing
if user_is_basic(manager.rower.user): # pragma: no cover
return (0, 'You need to upgrade to a paid plan to establish a team')
if not is_coach(manager):
ts = Team.objects.filter(manager=manager)
if len(ts) >= 1: # pragma: no cover
return (0, 'You need to upgrade to the Coach plan to have more than one team')
try:
t = Team(name=name, manager=manager, notes=notes,
private=private, viewing=viewing)
t.save()
r = Rower.objects.get(user=manager)
_ = add_member(t.id, r)
except IntegrityError:
return (0, 'Team name duplication')
return (t.id, 'Team created')
def remove_team(id):
t = Team.objects.get(id=id)
for r in Rower.objects.filter(team=t):
send_team_delete_mail(t, r)
return t.delete()
return (1, 'Updated rower team expiry') # pragma: no cover
def add_coach(coach, rower):
# get coaching group
coachgroup = coach.mycoachgroup
if coachgroup is None: # pragma: no cover
coachgroup = CoachingGroup(name=coach.user.first_name)
coachgroup.save()
coach.mycoachgroup = coachgroup
coach.save()
if get_coach_club_size(coach) < coach.clubsize:
rower.coachinggroups.add(coach.mycoachgroup)
return (1, "Added Coach")
else: # pragma: no cover
return (0, "Maximum number of athletes reached")
def add_member(id, rower):
t = Team.objects.get(id=id)
try:
rower.team.add(t)
except ValidationError as e: # pragma: no cover
return(0, "Couldn't add member: "+str(e.message))
# if team manager is coach
if is_coach(t.manager):
result = add_coach(t.manager.rower, rower)
# code to add all workouts
ws = Workout.objects.filter(user=rower)
_ = myqueue(
queuehigh,
handle_add_workouts_team,
ws, t)
# code to add plannedsessions
plannedsessions = PlannedSession.objects.filter(
team=t, enddate__gte=timezone.now().date())
for ps in plannedsessions: # pragma: no cover
_ = ps.rower.add(rower)
# set_teamplanexpires(rower)
# code for Stuck At Home Team (temporary)
if id == 52 and rower.rowerplan == 'basic': # pragma: no cover
rower.protrialexpires = ddate(2020, 9, 1)
rower.save()
return (id, 'Member added')
def remove_member(id, rower):
t = Team.objects.get(id=id)
rower.team.remove(t)
# remove the team from rower's workouts:
ws = Workout.objects.filter(user=rower, team=t)
_ = myqueue(queuehigh,handle_remove_workouts_team,ws, t)
# set_teamplanexpires(rower)
return (id, 'Member removed')
def remove_coach(coach, rower): # pragma: no cover
try:
coachgroup = coach.mycoachgroup
except CoachingGroup.DoesNotExist: # pragma: no cover
coachgroup = CoachingGroup()
coachgroup.save()
coach.mycoachgroup = coachgroup
coach.save()
rower.coachinggroups.remove(coachgroup)
return (1, 'Coach removed')
def rower_get_managers(rower):
managers = []
for team in rower.team.all():
managers.append(team.manager.rower)
return managers
def rower_get_coaches(rower):
return rower.get_coaches()
def coach_getcoachees(coach):
rowers = []
if coach.mycoachgroup and is_coach(coach.user):
rs = Rower.objects.filter(
coachinggroups__in=[coach.mycoachgroup]
).distinct().order_by("user__last_name", "user__first_name")
for r in rs:
rowers.append(r)
return rowers
def coach_remove_athlete(coach, rower):
try:
coachgroup = coach.mycoachgroup
except CoachingGroup.DoesNotExist: # pragma: no cover
coachgroup = CoachingGroup()
coachgroup.save()
coach.mycoachgroup = coachgroup
coach.save()
rower.coachinggroups.remove(coachgroup)
return (1, 'Coach removed')
def mgr_remove_member(id, manager, rower):
t = Team.objects.get(id=id)
if is_team_manager(manager, t):
remove_member(id, rower)
send_email_member_dropped(id, rower)
return (id, 'Member removed')
else: # pragma: no cover
return (0, 'You are not the team manager')
return (0, '') # pragma: no cover
def count_invites(manager): # pragma: no cover
ts = Team.objects.filter(manager=manager)
count = 0
for t in ts:
count += TeamInvite.objects.filter(team=t).count()
return count
def count_club_members(manager): # pragma: no cover
ts = Team.objects.filter(manager=manager)
return Rower.objects.filter(team__in=ts).distinct().count()
# Medium level functionality
# request by user to be coached by coach
def create_coaching_request(coach, user): # pragma: no cover
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: # pragma: no cover
code = uuid.uuid4().hex[:10].upper()
if coach.rowerplan == 'pro':
rekwest = CoachRequest(coach=coach, user=user, code=code)
rekwest.save()
send_coachrequest_email(rekwest)
return (rekwest.id, 'The request was created')
else: # pragma: no cover
return (0, 'That person is not a coach')
def send_coachrequest_email(rekwest):
name = rekwest.user.first_name + " " + rekwest.user.last_name
email = rekwest.coach.user.email
code = rekwest.code
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
_ = 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
_ = myqueue(queuehigh,
handle_sendemail_coacheerequest,
email, name, code, coachname)
def create_request(team, user):
r2 = Rower.objects.get(user=user)
if r2 in Rower.objects.filter(team=team): # pragma: no cover
return (0, 'Already a member of that team')
# if count_club_members(team.manager)+count_invites(team.manager) <= r.clubsize:
codes = [i.code for i in TeamRequest.objects.all()]
code = uuid.uuid4().hex[:10].upper()
# prevent duplicates
while code in codes: # pragma: no cover
code = uuid.uuid4().hex[:10].upper()
u = User.objects.get(id=user)
rekwest = TeamRequest(team=team, user=u, code=code)
rekwest.save()
send_request_email(rekwest)
return (rekwest.id, 'The request was created')
return (0, 'Something went wrong in create_request') # pragma: no cover
def get_coach_club_size(coach):
rs = Rower.objects.filter(coachinggroups__in=[coach.mycoachgroup])
rekwests = CoachOffer.objects.filter(coach=coach)
result = len(rs)+len(rekwests)
return result
# request by coach to coach user
def create_coaching_offer(coach, user):
if coach in rower_get_coaches(user.rower): # pragma: no cover
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: # pragma: no cover
code = uuid.uuid4().hex[:10].upper()
if is_coach(coach.user) and get_coach_club_size(coach) < coach.clubsize:
rekwest = CoachOffer(coach=coach, user=user, code=code)
rekwest.save()
send_coacheerequest_email(rekwest)
return (rekwest.id, 'The request was created')
elif get_coach_club_size(coach) >= coach.clubsize: # pragma: no cover
return(0, 'You have reached the maximum number of athletes')
else: # pragma: no cover
return (0, 'You are not a coach')
def create_invite(team, manager, user=None, email=''):
if not is_team_manager(manager, team):
return (0, 'Not the team manager')
if user:
try:
r2 = Rower.objects.get(user=user)
email = r2.user.email
except Rower.DoesNotExist: # pragma: no cover
return (0, 'Rower does not exist')
if r2 in Rower.objects.filter(team=team):
return (0, 'Already member of that team')
elif email is None or email == '': # pragma: no cover
return (0, 'Invalid request - missing email or user')
else:
try:
r2 = Rower.objects.get(user__email=email)
user = User.objects.get(rower=r2)
except Rower.DoesNotExist: # pragma: no cover
user = None
except Rower.MultipleObjectsReturned: # pragma: no cover
return (0, 'There is more than one user with that email address')
# if count_club_members(team.manager)+count_invites(team.manager) <= r.clubsize:
codes = [i.code for i in TeamInvite.objects.all()]
code = uuid.uuid4().hex[:10].upper()
# prevent duplicates
while code in codes: # pragma: no cover
code = uuid.uuid4().hex[:10].upper()
invite = TeamInvite(team=team, code=code, user=user, email=email)
invite.save()
return (invite.id, 'Invitation created')
return (0, 'Nothing done') # pragma: no cover
def revoke_request(user, id):
try:
rekwest = TeamRequest.objects.get(id=id)
except TeamRequest.DoesNotExist: # pragma: no cover
return (0, 'The request is invalid')
if rekwest.user == user:
rekwest.delete()
return (1, 'Request revoked')
return (0, 'You are not the requestor') # pragma: no cover
def reject_revoke_coach_offer(user, id):
try:
rekwest = CoachOffer.objects.get(id=id)
except CoachOffer.DoesNotExist: # pragma: no cover
return (0, 'The request is invalid')
if rekwest.coach.user == user:
rekwest.delete()
return (1, 'Request removed')
elif rekwest.user == user:
send_coachoffer_rejected_email(rekwest)
rekwest.delete()
return (1, 'Request removed')
else: # pragma: no cover
return (0, 'Not permitted')
def reject_revoke_coach_request(user, id):
try:
rekwest = CoachRequest.objects.get(id=id)
except CoachRequest.DoesNotExist: # pragma: no cover
return (0, 'The request is invalid')
if rekwest.coach.user == user:
send_coachrequest_rejected_email(rekwest)
rekwest.delete()
return (1, 'Request rejected')
elif rekwest.user == user:
rekwest.delete()
return (1, 'Request rejected')
else: # pragma: no cover
return (0, 'Not permitted')
def revoke_invite(manager, id):
try:
invite = TeamInvite.objects.get(id=id)
except TeamInvite.DoesNotExist: # pragma: no cover
return (0, 'The invitation is invalid')
if is_team_manager(manager, invite.team):
invite.delete()
return (1, 'Invitation revoked')
else: # pragma: no cover
return (0, 'You are not the team manager')
def reject_request(manager, id):
try:
rekwest = TeamRequest.objects.get(id=id)
except TeamRequest.DoesNotExist: # pragma: no cover
return (0, 'The request is invalid')
if is_team_manager(manager, rekwest.team):
send_request_reject_email(rekwest)
rekwest.delete()
return (1, 'Request rejected')
else: # pragma: no cover
return (0, 'You are not the manager for this request')
def reject_invitation(user, id):
try:
invite = TeamInvite.objects.get(id=id)
except TeamInvite.DoesNotExist: # pragma: no cover
return (0, 'The invitation is invalid')
if invite.user == user:
send_invite_reject_email(invite)
invite.delete()
return (1, 'Invitation rejected')
else: # pragma: no cover
return (0, 'This request was not for you')
def send_invite_email(id):
try:
invitation = TeamInvite.objects.get(id=id)
except TeamInvite.DoesNotExist: # pragma: no cover
return (0, 'Invitation doesn not exist')
if invitation.user:
email = invitation.user.email
name = invitation.user.first_name + " " + invitation.user.last_name
else: # pragma: no cover
email = invitation.email
name = ''
code = invitation.code
teamname = invitation.team.name
manager = invitation.team.manager.first_name + \
' '+invitation.team.manager.last_name
_ = myqueue(queuehigh,
handle_sendemail_invite,
email, name, code, teamname, manager)
return (1, 'Invitation email sent')
def send_team_delete_mail(t, rower):
u = rower.user
teamname = t.name
email = u.email
name = u.first_name+' '+u.last_name
manager = t.manager.first_name+' '+t.manager.last_name
_ = myqueue(queuehigh,
handle_sendemail_team_removed,
email, name, teamname, manager)
return (1, 'Team delete email sent')
def send_email_member_dropped(teamid, rower):
t = Team.objects.get(id=teamid)
u = rower.user
teamname = t.name
email = u.email
name = u.first_name+' '+u.last_name
manager = t.manager.first_name+' '+t.manager.last_name
_ = myqueue(queuehigh, handle_sendemail_member_dropped,
email, name, teamname, manager)
return (1, 'Member dropped email sent')
def send_request_accept_email(rekwest): # pragma: no cover
email = rekwest.user.email
teamname = rekwest.team.name
name = rekwest.user.first_name+' '+rekwest.user.last_name
manager = rekwest.team.manager.first_name+' '+rekwest.team.manager.last_name
_ = myqueue(queuehigh,
handle_sendemail_request_accept,
email, name, teamname, manager)
return (1, 'Invitation email sent')
def send_request_reject_email(rekwest):
teamname = rekwest.team.name
email = rekwest.user.email
name = rekwest.user.first_name+' '+rekwest.user.last_name
manager = rekwest.team.manager.first_name+' '+rekwest.team.manager.last_name
_ = myqueue(queuehigh,
handle_sendemail_request_reject,
email, name, teamname, manager)
return (1, 'Invitation email sent')
def send_invite_reject_email(invitation):
email = invitation.team.manager.email
if invitation.user:
name = invitation.user.first_name+' '+invitation.user.last_name
else: # pragma: no cover
name = invitation.email
teamname = invitation.team.name
manager = invitation.team.manager.first_name + \
' '+invitation.team.manager.last_name
_ = myqueue(queuehigh,
handle_sendemail_invite_reject,
email, name, teamname, manager)
return (1, 'Invitation email sent')
def send_invite_accept_email(invitation): # pragma: no cover
email = invitation.team.manager.email
if invitation.user:
name = invitation.user.first_name+' '+invitation.user.last_name
else:
name = invitation.email
teamname = invitation.team.name
manager = invitation.team.manager.first_name + \
' '+invitation.team.manager.last_name
_ = myqueue(queuehigh,
handle_sendemail_invite_accept,
email, name, teamname, manager)
return (1, 'Invitation email sent')
def send_team_message(team, message): # pragma: no cover
rowers = team.rower.all()
managername = team.manager.first_name + " " + team.manager.last_name
for rower in rowers:
rowername = rower.user.first_name + " " + rower.user.last_name
_ = myqueue(queuehigh,
handle_sendemail_message,
rower.user.email, team.manager.email, rowername, message, team.name, managername)
return (1, 'message sent')
def send_request_email(rekwest):
email = rekwest.team.manager.email
id = rekwest.id
name = rekwest.team.manager.first_name + " " + rekwest.team.manager.last_name
code = rekwest.code
teamname = rekwest.team.name
requestor = rekwest.user.first_name+' '+rekwest.user.last_name
_ = myqueue(queuehigh,
handle_sendemail_request,
email, name, code, teamname, requestor, id)
return (1, 'Invitation email sent')
def process_request_code(manager, code): # pragma: no cover
code = code.upper()
try:
rekwest = TeamRequest.objects.get(code=code)
except TeamRequest.DoesNotExist:
return (0, 'The request has been revoked or the code is invalid')
r = Rower.objects.get(user=rekwest.user)
t = rekwest.team
if rekwest.team.manager != manager:
return (0, 'You are not the manager of this team')
result, comment = add_member(t.id, r)
if not result:
return (result, "The member couldn't be added")
send_request_accept_email(rekwest)
rekwest.delete()
return (result, 'The member was added')
def process_invite_code(user, code): # pragma: no cover
code = code.upper()
try:
invitation = TeamInvite.objects.get(code=code)
except TeamInvite.DoesNotExist:
return (0, 'The invitation has expired or the code is invalid')
r = Rower.objects.get(user=user)
nu = datetime.date(timezone.now())
if nu > invitation.issuedate+timedelta(days=inviteduration):
revoke_invite(invitation.team.manager, invitation.id)
return (0, 'The invitation has expired')
t = invitation.team
result, comment = add_member(t.id, r)
if not result:
return (result, "The member couldn't be added")
send_invite_accept_email(invitation)
invitation.delete()
return (result, 'You were added to the team')
def remove_expired_invites(): # pragma: no cover
issuedate = timezone.now()-timedelta(days=inviteduration)
issuedate = datetime.date(issuedate)
invitations = TeamInvite.objects.filter(issuedate__lt=issuedate)
for i in invitations:
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: # pragma: no cover
return (0, 'The request has been revoked or is invalid')
if rekwest.coach != coach: # pragma: no cover
return (0, 'The request is invalid')
result = add_coach(coach, rekwest.user.rower)
if not result: # pragma: no cover
return result
else:
send_coachrequest_accepted_email(rekwest)
rekwest.delete()
return result
def process_coachoffer_code(user, code):
code = code.upper()
try:
rekwest = CoachOffer.objects.get(code=code)
except CoachOffer.DoesNotExist: # pragma: no cover
return (0, 'The request has been revoked or is invalid')
if rekwest.user != user: # pragma: no cover
return (0, 'The request is invalid')
result = add_coach(rekwest.coach, rekwest.user.rower)
if not result: # pragma: no cover
return result
else:
send_coachoffer_accepted_email(rekwest)
rekwest.delete()
return result
def send_coachoffer_rejected_email(rekwest):
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
coachemail = rekwest.coach.user.email
name = rekwest.user.first_name + " " + rekwest.user.last_name
_ = myqueue(queuehigh,
handle_sendemail_coachoffer_rejected,
coachemail, coachname, name)
def send_coachrequest_rejected_email(rekwest):
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
email = rekwest.user.email
name = rekwest.user.first_name + " " + rekwest.user.last_name
_ = myqueue(queuehigh,
handle_sendemail_coachrequest_rejected,
email, coachname, name)
def send_coachrequest_accepted_email(rekwest):
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
email = rekwest.user.email
name = rekwest.user.first_name + " " + rekwest.user.last_name
_ = myqueue(queuehigh,
handle_sendemail_coachrequest_accepted,
email, coachname, name)
def send_coachoffer_accepted_email(rekwest):
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
coachemail = rekwest.coach.user.email
name = rekwest.user.first_name + " " + rekwest.user.last_name
_ = myqueue(queuehigh,
handle_sendemail_coachoffer_accepted,
coachemail, coachname, name)