From 936a524804da28d87c36b78206ecd68674b5b353 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Wed, 24 Aug 2022 13:32:53 +0200 Subject: [PATCH] adding coach trial functionality --- rowers/models.py | 1 + rowers/rower_rules.py | 41 ++++++++++++++++++++++--- rowers/templates/coachtrialwelcome.html | 34 ++++++++++++++++++++ rowers/templates/paidplans.html | 16 +++++++++- rowers/urls.py | 2 ++ rowers/views/planviews.py | 9 +++--- rowers/views/statements.py | 5 +-- rowers/views/teamviews.py | 6 ++-- rowers/views/userviews.py | 34 ++++++++++++++++++++ templates/newbase.html | 7 +++++ 10 files changed, 140 insertions(+), 15 deletions(-) create mode 100644 rowers/templates/coachtrialwelcome.html diff --git a/rowers/models.py b/rowers/models.py index 1da7fc3f..a5ea5506 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -905,6 +905,7 @@ class Rower(models.Model): clubsize = models.IntegerField(default=0) protrialexpires = models.DateField(default=datetime.date(1970, 1, 1)) plantrialexpires = models.DateField(default=datetime.date(1970, 1, 1)) + coachtrialexpires = models.DateField(default=datetime.date(1970, 1, 1)) offercoaching = models.BooleanField( default=False, verbose_name='Offer Remote Coaching') diff --git a/rowers/rower_rules.py b/rowers/rower_rules.py index 33724ef2..c323369f 100644 --- a/rowers/rower_rules.py +++ b/rowers/rower_rules.py @@ -84,6 +84,13 @@ def user_is_not_basic(user): if user.rower.protrialexpires >= timezone.now().date(): return True # pragma: no cover + if user.rower.plantrialexpires >= timezone.now().date(): + return True # pragma: no cover + + if user.rower.coachtrialexpires >= timezone.now().date(): + return True # pragma: no cover + + return False @rules.predicate @@ -116,6 +123,13 @@ def can_start_plantrial(user): return user.rower.plantrialexpires == datetime.date(1970, 1, 1) +@rules.predicate +def can_start_coachtrial(user): + if user.is_anonymous: # pragma: no cover + return False + + return user.rower.coachtrialexpires == datetime.date(1970, 1, 1) + @rules.predicate def is_staff(user): # pragma: no cover @@ -171,11 +185,23 @@ def is_protrial(user): return False # pragma: no cover +@rules.predicate +def is_coachtrial(user): + try: + r = user.rower + except AttributeError: + return False + + if r.rowerplan == 'basic': + return r.coachtrialexpires >= timezone.now().date() + + return False # pragma: no cover + ispromember = is_promember | is_protrial -can_have_teams = ispromember | is_coach +can_have_teams = ispromember | is_coach | is_coachtrial @rules.predicate @@ -188,6 +214,9 @@ def can_add_team(user): if otherteams.count() == 0: return True + if is_coachtrial(user): + return True + return False @@ -222,10 +251,12 @@ def is_plantrial(user): isplanmember = is_planmember | is_plantrial +iscoachmember = is_coach | is_coachtrial + @rules.predicate def can_add_session(user): - return isplanmember(user) or is_coach(user) + return isplanmember(user) or is_coach(user) or is_coachtrial(user) # User / Coach relationships (Rower object) @@ -237,7 +268,7 @@ def can_plan(user): if user.rower.rowerplan in ['plan', 'coach']: return True if user.rower.rowerplan in ['basic', 'pro']: - return user.rower.plantrialexpires >= timezone.now().date() + return user.rower.plantrialexpires >= timezone.now().date() or user.rower.coachtrialexpires >= timezone.now().date() if user.rower.rowerplan == 'freecoach': # pragma: no cover if user.rower.mycoachgroup is not None: return len(user.rower.mycoachgroup) >= 4 @@ -620,7 +651,7 @@ def can_view_session(user, session): return True # coach users can view sessions created by their team members # below untested - if is_coach(user): # pragma: no cover + if is_coach(user) or is_coachtrial(user): # pragma: no cover teams = user.rower.get_managed_teams() for t in teams: teamusers = [member.u for member in t.rower.all()] @@ -711,7 +742,7 @@ def is_team_member(user, team): # pragma: no cover def can_view_team(user, team): # user based - below untested if user.rower.rowerplan == 'basic' and team.manager.rower.rowerplan != 'coach': # pragma: no cover - return is_plantrial(user) or is_protrial(user) + return is_plantrial(user) or is_protrial(user) or is_coachtrial(user) # team is public if team.private == 'open': return True diff --git a/rowers/templates/coachtrialwelcome.html b/rowers/templates/coachtrialwelcome.html new file mode 100644 index 00000000..b1844848 --- /dev/null +++ b/rowers/templates/coachtrialwelcome.html @@ -0,0 +1,34 @@ +{% extends "emailbase.html" %} + +{% block body %} +

Dear {{ first_name }},

+ +

+ Welcome on the trial for the Coach plan. You are now able to test coaching + functionality for two weeks, with two coachees. +

+

+As the developer of the Rowsandall.com site I am very interested to know +what you think of Rowsandall.com. +Especially, I'd like to understand how you started using the site, +what you are looking for, and what you think could be improved. +

+ +

+I'd also love to hear a bit about your rowing background. +

+ +

+ So don't hesitate to respond to this email and let me know. I will read and respond to each + email. +

+ +

+Thank you very much for your help and for supporting rowsandall.com. +

+ + +

+ Best Regards, the Rowsandall Team +

+{% endblock %} diff --git a/rowers/templates/paidplans.html b/rowers/templates/paidplans.html index 3fe2c01e..836d4e44 100644 --- a/rowers/templates/paidplans.html +++ b/rowers/templates/paidplans.html @@ -249,7 +249,21 @@ {% endif %} -   + {% if user.is_anonymous %} + + {% elif rower and rower.rowerplan == 'basic' and rower.coachtrialexpires|date_dif == 1 %} + + {% elif rower and rower.rowerplan == 'pro' and rower.coachtrialexpires|date_dif == 1 %} + + {% else %} +   + {% endif %} diff --git a/rowers/urls.py b/rowers/urls.py index 6d5c9073..7041168a 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -848,6 +848,8 @@ urlpatterns = [ re_path(r'^starttrial/$', views.start_trial_view, name='start_trial_view'), re_path(r'^startplantrial/$', views.start_plantrial_view, name='start_plantrial_view'), + re_path(r'^startcoachtrial/$', views.start_coachtrial_view, + name='start_coachtrial_view'), re_path(r'^legal', TemplateView.as_view( template_name='legal.html'), name='legal'), re_path(r'^register/$', views.rower_register_view, diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index 9d858d5c..c39f886b 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -1289,7 +1289,7 @@ def plannedsessions_coach_view(request, else: theteam = False - if 'coach' in request.user.rower.rowerplan: + if is_coach(request.user) or is_coachtrial(request.user): sps = get_sessions_manager(request.user, teamid=teamid, enddate=enddate, startdate=startdate) @@ -1303,7 +1303,7 @@ def plannedsessions_coach_view(request, rowers = [] for ps in sps: - if 'coach' in request.user.rower.rowerplan: + if is_coach(request.user) or is_coachtrial(request.user): rowers += ps.rower.all().exclude(rowerplan='freecoach') else: # pragma: no cover rowers += ps.rower.filter( @@ -1539,8 +1539,9 @@ def plannedsessions_view(request, totals['actualtrimp'] += thetrimp if not sps and request.user.rower.rowerplan == 'basic': # pragma: no cover - messages.error(request, - "You must purchase Coach or Self-coach plans or be part of a team to get planned sessions") + if user_is_basic(request.user): + messages.error(request, + "You must purchase Coach or Self-coach plans or be part of a team to get planned sessions") for ps in sps: ratio, status, cdate = is_session_complete(r, ps) diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 5448ff02..05def1df 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -77,8 +77,9 @@ from rowers.rower_rules import ( can_view_plan, can_change_plan, can_delete_plan, can_view_cycle, can_change_cycle, can_delete_cycle, can_add_workout_member, can_plan_user, is_paid_coach, - can_start_trial, can_start_plantrial, can_plan, is_workout_team, - is_promember, + can_start_trial, can_start_plantrial, can_start_coachtrial, + can_plan, is_workout_team, + is_promember,user_is_basic, is_coachtrial, is_coach ) from django.shortcuts import render diff --git a/rowers/views/teamviews.py b/rowers/views/teamviews.py index 9354c538..019e259d 100644 --- a/rowers/views/teamviews.py +++ b/rowers/views/teamviews.py @@ -175,7 +175,7 @@ def get_teams(request): private='open').exclude( rower=r).exclude(manager=request.user).order_by('name') - if r.rowerplan == 'basic': + if user_is_basic(request.user): otherteams = otherteams.filter(manager__rower__rowerplan='coach') return myteams, memberteams, otherteams @@ -234,7 +234,7 @@ def rower_teams_view(request): # pragma: no cover coachees = teams.coach_getcoachees(request.user.rower) - if request.user.rower.rowerplan == 'coach': + if is_coach(request.user) or is_coachtrial(request.user): potentialathletes = Rower.objects.filter( team__in=myteams).exclude( user__in=invitedathletes).exclude( @@ -471,7 +471,7 @@ def team_requestmembership_view(request, teamid, userid): def request_coaching_view(request, coachid): coach = User.objects.get(id=coachid).rower - if 'coach' in coach.rowerplan: + if is_coach(coach.user) or is_coachtrial(request.user): res, text = teams.create_coaching_request(coach, request.user) if res: messages.info(request, text) diff --git a/rowers/views/userviews.py b/rowers/views/userviews.py index d7d36255..392545af 100644 --- a/rowers/views/userviews.py +++ b/rowers/views/userviews.py @@ -143,6 +143,40 @@ def survey(request): # pragma: no cover return render(request, 'survey.html', context) +@login_required() +def start_coachtrial_view(request): + r = getrower(request.user) + + if not can_start_coachtrial(request.user): # pragma: no cover + messages.error(request, 'You do not qualify for a coach trial') + url = '/rowers/paidplans' + return HttpResponseRedirect(url) + + r.coachtrialexpires = timezone.now()+datetime.timedelta(13) + r.clubsize = 2 + r.save() + + url = reverse('workouts_view') + + messages.info(request, 'We have started your 14 day coach trial period') + + subject2 = "User started Coach Trial" + message2 = "User Started Coach Trial.\n" + message2 += request.user.email + "\n" + message2 += "User name: "+request.user.username + + send_mail(subject2, message2, + 'Rowsandall Server ', + ['roosendaalsander@gmail.com']) + + send_template_email('Rowsandall ', + [r.user.email], + 'Welcome to the Rowsandall Coach Trial', + 'coachtrialwelcome.html', + {'first_name': r.user.first_name, + 'last_name': r.user.last_name}) + + return HttpResponseRedirect(url) @login_required() def start_trial_view(request): diff --git a/templates/newbase.html b/templates/newbase.html index 243de2dd..bba499a9 100644 --- a/templates/newbase.html +++ b/templates/newbase.html @@ -261,6 +261,13 @@ {% endif %} {% endif %} + {% endif %} + {% if user.rower.coachtrialexpires and user.rower.coachtrialexpires|is_future_date and user.rower.rowerplan != 'coach' %} +
  • +

    + {{ user.rower.coachtrialexpires|date_dif|ddays }} days left of your Coach trial - Would you like to upgrade now? +

    +
  • {% endif %} {% if user.rower.emailbounced %}