Private
Public Access
1
0

Merge branch 'release/v18.6.6'

This commit is contained in:
Sander Roosendaal
2022-08-27 22:01:11 +02:00
10 changed files with 140 additions and 15 deletions

View File

@@ -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')

View File

@@ -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

View File

@@ -0,0 +1,34 @@
{% extends "emailbase.html" %}
{% block body %}
<p>Dear <strong>{{ first_name }}</strong>,</p>
<p>
Welcome on the trial for the Coach plan. You are now able to test coaching
functionality for two weeks, with two coachees.
</p>
<p>
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.
</p>
<p>
I'd also love to hear a bit about your rowing background.
</p>
<p>
So don't hesitate to respond to this email and let me know. I will read and respond to each
email.
</p>
<p>
Thank you very much for your help and for supporting <a href="rowsandall.com">rowsandall.com</a>.
</p>
<p>
Best Regards, the Rowsandall Team
</p>
{% endblock %}

View File

@@ -249,7 +249,21 @@
{% endif %}
</td>
<td>
&nbsp;
{% if user.is_anonymous %}
<button style="width:100%">
<a href="/rowers/startcoachtrial/">Free COACH trial</a>
</button>
{% elif rower and rower.rowerplan == 'basic' and rower.coachtrialexpires|date_dif == 1 %}
<button style="width:100%">
<a href="/rowers/startcoachtrial/">Free COACH trial</a>
</button>
{% elif rower and rower.rowerplan == 'pro' and rower.coachtrialexpires|date_dif == 1 %}
<button style="width:100%">
<a href="/rowers/startcoachtrial/">Free COACH trial</a>
</button>
{% else %}
&nbsp;
{% endif %}
</td>
</tr>
<tr>

View File

@@ -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,

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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 <info@rowsandall.com>',
['roosendaalsander@gmail.com'])
send_template_email('Rowsandall <info@rowsandall.com>',
[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):

View File

@@ -261,6 +261,13 @@
</li>
{% endif %}
{% endif %}
{% endif %}
{% if user.rower.coachtrialexpires and user.rower.coachtrialexpires|is_future_date and user.rower.rowerplan != 'coach' %}
<li class="grid_4">
<p class="successmessage">
{{ user.rower.coachtrialexpires|date_dif|ddays }} days left of your Coach trial - Would you like to <a href="/rowers/paidplans/">upgrade now?</a>
</p>
</li>
{% endif %}
{% if user.rower.emailbounced %}
<li class="grid_4">