diff --git a/rowers/forms.py b/rowers/forms.py index 014bb968..3dc3a222 100644 --- a/rowers/forms.py +++ b/rowers/forms.py @@ -122,7 +122,9 @@ class EmailForm(forms.Form): lastname = forms.CharField(max_length=255) email = forms.EmailField() subject = forms.CharField(max_length=255) - message = forms.CharField() + message = forms.CharField(widget=forms.Textarea()) + + disqualificationreasons = ( ('noimage','No monitor screenshot or data evidence was included'), diff --git a/rowers/models.py b/rowers/models.py index 992f2173..dd533aa0 100644 --- a/rowers/models.py +++ b/rowers/models.py @@ -2353,6 +2353,23 @@ class PlannedSessionForm(ModelForm): self.fields['course'].queryset = GeoCourse.objects.all().order_by("country","name") self.fields['sessiontype'].choices = regularsessiontypechoices +class VirtualRaceAthleteForm(ModelForm): + class Meta: + model = PlannedSession + + fields = ['rower'] + + + widgets = { + 'rower':forms.CheckboxSelectMultiple, + } + + def __init__(self, *args, **kwargs): + super(VirtualRaceAthleteForm, self).__init__(*args, **kwargs) + self.fields['rower'].queryset = self.instance.rower.all() + self.fields['subject']= forms.CharField(max_length=255) + self.fields['message'] = forms.CharField(widget=forms.Textarea()) + class PlannedSessionTemplateForm(ModelForm): diff --git a/rowers/tasks.py b/rowers/tasks.py index b91faff1..9c74aab9 100644 --- a/rowers/tasks.py +++ b/rowers/tasks.py @@ -2333,6 +2333,18 @@ def handle_sendemailnewcomment(first_name, return 1 +@app.task +def handle_send_template_email(template,email,fromemail,rowername, + subject,message,debug=False,**kwargs): + fullemail = [email] + d = { + 'message':message, + 'rowername':rowername, + } + + res = send_template_email(fromemail,fullemail,subject, + template,d,**kwargs) + @app.task def handle_sendemail_message(email,fromemail,rowername,message,teamname,managername, debug=False,**kwargs): diff --git a/rowers/templates/plannedsession_message.html b/rowers/templates/plannedsession_message.html new file mode 100644 index 00000000..db759697 --- /dev/null +++ b/rowers/templates/plannedsession_message.html @@ -0,0 +1,38 @@ +{% extends "newbase.html" %} +{% load staticfiles %} +{% load rowerfilters %} +{% load tz %} + +{% block scripts %} +{% include "monitorjobs.html" %} +{% endblock %} + +{% block title %}Comment Session {% endblock %} + +{% block main %} + +

Messages {{ plannedession.name }}

+ +

With this form, you can send an email message to selected Challenge participants

+ +
    +
  • +
    + + {{ userform.as_table }} +
    + {% csrf_token %} + +
    +
  • +
+ +{% endblock %} + +{% block sidebar %} +{% if 'racing' in active %} +{% include 'menu_racing.html' %} +{% else %} +{% include 'menu_plan.html' %} +{% endif %} +{% endblock %} diff --git a/rowers/templates/virtualevent.html b/rowers/templates/virtualevent.html index 3b8c6c57..fc4936a9 100644 --- a/rowers/templates/virtualevent.html +++ b/rowers/templates/virtualevent.html @@ -383,14 +383,21 @@ {% endif %}

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

Download Results +

{% endif %} {% else %}

No results yet

{% endif %} + {% if race.manager == request.user %} +

+ Message to participant(s) +

+ {% endif %} {% if form %} diff --git a/rowers/templates/virtualracemessage.html b/rowers/templates/virtualracemessage.html new file mode 100644 index 00000000..0319f093 --- /dev/null +++ b/rowers/templates/virtualracemessage.html @@ -0,0 +1,10 @@ +{% extends "emailbase.html" %} +{% block body %} +

Dear {{ rowername }},

+ +

+ {{ message }} +

+ + +{% endblock %} diff --git a/rowers/tpstuff.py b/rowers/tpstuff.py index 86cd1340..3263d109 100644 --- a/rowers/tpstuff.py +++ b/rowers/tpstuff.py @@ -69,9 +69,9 @@ def get_token(code): response = requests.post( "https://oauth.trainingpeaks.com/oauth/token", - data=post_data + data=post_data,verify=False, ) - + try: token_json = response.json() diff --git a/rowers/urls.py b/rowers/urls.py index 150a947c..257162e1 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -735,6 +735,8 @@ urlpatterns = [ name='plannedsession_comment_view'), re_path(r'^sessions/print/user/(?P\d+)/$',views.plannedsessions_print_view, name='plannedsessions_print_view'), + re_path(r'^sessions/(?P\d+)/message/$',views.plannedsession_message_view, + name='plannedsession_message_view'), re_path(r'^sessions/print/user/(?P\d+)/(?P\d+-\d+-\d+)/(?P\d+-\d+-\d+)/$',views.plannedsessions_print_view, name='plannedsessions_print_view'), re_path(r'^sessions/sendcalendar/$',views.plannedsessions_icsemail_view, diff --git a/rowers/views/planviews.py b/rowers/views/planviews.py index a280afb4..3a5e5764 100644 --- a/rowers/views/planviews.py +++ b/rowers/views/planviews.py @@ -172,6 +172,87 @@ def plannedsession_comment_view(request,id=0,userid=0): 'form':form, }) +@login_required +@permission_required('plannedsession.edit_session',fn=get_session_by_pk,raise_exception=True) +def plannedsession_message_view(request,id=0,userid=0): + r = getrequestplanrower(request,userid=userid) + ps = get_object_or_404(PlannedSession,pk=id) + + userform = VirtualRaceAthleteForm(instance=ps) + + if request.method == 'POST': + userform = VirtualRaceAthleteForm(request.POST,instance=ps) + if userform.is_valid(): + subject = userform.cleaned_data['subject'] + message = userform.cleaned_data['message'] + rowers = userform.cleaned_data['rower'] + + for participant in rowers: + rowername = participant.user.first_name + fromemail = ps.manager.email + + job = myqueue( + queue, + handle_send_template_email, + 'virtualracemessage.html', + participant.user.email, + fromemail, + rowername, + subject, + message, + ) + + + url = reverse('virtualevent_view',kwargs={'id':ps.id}) + return HttpResponseRedirect(url) + + + if ps.sessiontype in ['race','indoorrace']: + breadcrumbs = [ + { + 'url':reverse('virtualevents_view'), + 'name': 'Races' + }, + { + 'url': reverse('virtualevent_view',kwargs={'id':ps.id}), + 'name': ps.name + }, + { + 'url':reverse('plannedsession_comment_view',kwargs={'id':ps.id}), + 'name': 'Comments' + } + ] + + active = 'nav-racing' + + else: + breadcrumbs = [ + { + 'url':reverse('plannedsessions_view'), + 'name': 'Sessions' + }, + { + 'url': reverse('plannedsession_view',kwargs={'id':ps.id}), + 'name': ps.name + }, + { + 'url':reverse('plannedsession_comment_view',kwargs={'id':ps.id}), + 'name': 'Comments' + } + ] + + active = 'nav-plan' + + return render(request, + 'plannedsession_message.html', + {'plannedsession':ps, + 'rower':r, + 'breadcrumbs':breadcrumbs, + 'active':active, + 'userform':userform, + }) + + # Cloning sessions @user_passes_test(can_plan,login_url="/rowers/paidplans/", message="This functionality requires a Coach or Self-Coach plan", diff --git a/rowers/views/statements.py b/rowers/views/statements.py index 24c3290d..6ce222f9 100644 --- a/rowers/views/statements.py +++ b/rowers/views/statements.py @@ -131,7 +131,7 @@ from rowers.models import ( IndoorVirtualRaceResultForm,IndoorVirtualRaceResult, IndoorVirtualRaceForm,PlannedSessionCommentForm, Alert, Condition, StaticChartRowerForm, - FollowerForm, + FollowerForm,VirtualRaceAthleteForm, ) from rowers.models import ( FavoriteForm,BaseFavoriteFormSet,SiteAnnouncement,BasePlannedSessionFormSet, @@ -198,6 +198,7 @@ from rowers.tasks import handle_makeplot,handle_otwsetpower,handle_sendemailtcx, from rowers.tasks import ( handle_sendemail_unrecognized,handle_sendemailnewcomment, handle_sendemailsummary, + handle_send_template_email, handle_send_disqualification_email, handle_send_withdraw_email, handle_sendemailfile,