Add form for inviting people to an event. Allows both invite by email, and directly to team members. Fixes #74
This commit is contained in:
parent
5626065fe5
commit
376c06200b
7 changed files with 184 additions and 3 deletions
|
@ -259,6 +259,12 @@ class NewTeamEventForm(forms.ModelForm):
|
|||
class DeleteEventForm(forms.Form):
|
||||
confirm = forms.BooleanField(label="Yes, delete event", required=True)
|
||||
|
||||
class EventInviteMemberForm(forms.Form):
|
||||
member = forms.ChoiceField(label=_(""))
|
||||
|
||||
class EventInviteEmailForm(forms.Form):
|
||||
emails = MultiEmailField(label=_(""), widget=forms.widgets.Textarea)
|
||||
|
||||
class EventSeriesForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = EventSeries
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
{% extends "get_together/emails/base.html" %}
|
||||
|
||||
{% block content %}
|
||||
<h3>You've been invited to attend {{event.name|striptags}}</h3>
|
||||
|
||||
<p>{{ sender }} has invited you to an event by <b>{{team.name}}</b>.</p>
|
||||
|
||||
<h4>{{event.name|striptags}}</h4>
|
||||
<p>{{event.summary|striptags}}</p>
|
||||
<br>
|
||||
<a href="{{event.get_full_url}}" title="{{ event.name|striptags }} page.">View this event.</a>
|
||||
</p>
|
||||
{% endblock %}
|
|
@ -0,0 +1,11 @@
|
|||
{% block content %}
|
||||
== You've been invited to attend {{event.name|striptags}} ==
|
||||
|
||||
{{ sender }} has invited you to an event by {{team.name}}
|
||||
|
||||
=== {{event.name|striptags}} ===
|
||||
{{event.summary}}
|
||||
|
||||
Click here to view this event: {{event.get_full_url}}
|
||||
|
||||
{% endblock %}
|
|
@ -0,0 +1,58 @@
|
|||
{% extends "get_together/base.html" %}
|
||||
{% load markup tz %}
|
||||
|
||||
{% block add_to_title %} | {{event.name}}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="fluid-container">
|
||||
<h2>Invite people to <a href="{{event.get_absolute_url}}">{{ event.name }}</a></h2>
|
||||
<div class="row">
|
||||
|
||||
{% if is_email_confirmed %}
|
||||
<div class="col-sm-6">
|
||||
<hr />
|
||||
<h4>By email</h4>
|
||||
<p>Add a list of emails, separated by commas</p>
|
||||
<form action="{% url 'invite-attendees' event.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ email_form.as_p }}
|
||||
<button type="submit" name="form" value="email" class="btn btn-primary btn-sm">Send Invites</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if can_edit_team %}
|
||||
<div class="col-sm-6">
|
||||
<hr />
|
||||
<h4>Team members</h4>
|
||||
{% if member_choice_count > 0 %}
|
||||
<p>Select team member of members to invite</p>
|
||||
<form action="{% url 'invite-attendees' event.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
{{ team_form.as_p }}
|
||||
<button type="submit" name="form" value="team" class="btn btn-primary btn-sm">Invite members</button>
|
||||
</form>
|
||||
{% else %}
|
||||
<div class="alert alert-success">All invitable team members have responded.</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if not can_edit_team and not is_email_confirmed %}
|
||||
<div class="col-sm-12">
|
||||
<div class="alert alert-danger">You can not send invites for this event.</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block javascript %}
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
$("#id_member").selectmenu();
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -102,6 +102,9 @@
|
|||
<h2>{{ event.name }}
|
||||
</h2>
|
||||
<p class="text-muted">Hosted by <a href="{% url "show-team" team.id %}">{{ team.name }}</a></p>
|
||||
{% if can_edit_team or is_email_confirmed %}
|
||||
<a href="{% url 'invite-attendees' event.id %}" class="btn btn-danger btn-sm"><i class="fa fa-envelope"></i> Invite</a>
|
||||
{% endif %}
|
||||
{% if settings.SOCIAL_AUTH_TWITTER_KEY %}
|
||||
<a href="https://twitter.com/intent/tweet?text=I'm+having+a+get+together!%0D{{event.name|urlencode}}&original_referer={{event.get_full_url|urlencode}}&url={{event.get_full_url|urlencode}}&hashtags=gettogether" data-size="large" class="btn btn-twitter btn-sm"><i class="fa fa-twitter"></i> Tweet</a>
|
||||
{% endif %}
|
||||
|
@ -121,7 +124,7 @@
|
|||
</button>
|
||||
<div class="dropdown-menu" aria-labelledby="editMenuButton">
|
||||
<a href="{% url 'edit-event' event.id %}" class="dropdown-item">Event Details</a>
|
||||
<a href="{% url 'schedule-event-talks' event.id %}" class="dropdown-item">Talks</a>
|
||||
<a href="{% url 'schedule-event-talks' event.id %}" class="dropdown-item">Manage Talks</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -79,6 +79,7 @@ urlpatterns = [
|
|||
path('team/<int:team_id>/+create-event/', views.create_event, name='create-event'),
|
||||
path('events/<int:event_id>/+edit/', views.edit_event, name='edit-event'),
|
||||
path('events/<int:event_id>/+attend/', event_views.attend_event, name='attend-event'),
|
||||
path('events/<int:event_id>/+invite/', views.invite_attendees, name='invite-attendees'),
|
||||
path('events/<int:event_id>/+delete/', views.delete_event, name='delete-event'),
|
||||
path('events/<int:event_id>/+add_place/', views.add_place_to_event, name='add-place'),
|
||||
path('events/<int:event_id>/+comment/', event_views.comment_event, name='comment-event'),
|
||||
|
|
|
@ -4,8 +4,11 @@ from django.contrib import messages
|
|||
from django.contrib.auth import logout as logout_user
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.shortcuts import render, redirect, reverse, get_object_or_404
|
||||
from django.http import HttpResponse, JsonResponse
|
||||
from django.contrib.sites.models import Site
|
||||
from django.utils import timezone
|
||||
from django.core.mail import send_mail
|
||||
from django.template.loader import get_template, render_to_string
|
||||
from django.conf import settings
|
||||
|
||||
from events.models.events import (
|
||||
Event,
|
||||
|
@ -28,7 +31,9 @@ from events.forms import (
|
|||
EventCommentForm,
|
||||
NewPlaceForm,
|
||||
UploadEventPhotoForm,
|
||||
NewCommonEventForm
|
||||
NewCommonEventForm,
|
||||
EventInviteEmailForm,
|
||||
EventInviteMemberForm,
|
||||
)
|
||||
from events import location
|
||||
|
||||
|
@ -68,6 +73,8 @@ def show_event(request, event_id, event_slug):
|
|||
'presentation_list': event.presentations.filter(status=Presentation.ACCEPTED).order_by('start_time'),
|
||||
'pending_presentations': event.presentations.filter(status=Presentation.PROPOSED).count(),
|
||||
'can_edit_event': request.user.profile.can_edit_event(event),
|
||||
'can_edit_team': request.user.profile.can_edit_team(event.team),
|
||||
'is_email_confirmed': request.user.account.is_email_confirmed,
|
||||
}
|
||||
return render(request, 'get_together/events/show_event.html', context)
|
||||
|
||||
|
@ -136,6 +143,88 @@ def create_event(request, team_id):
|
|||
else:
|
||||
return redirect('home')
|
||||
|
||||
|
||||
@login_required
|
||||
def invite_attendees(request, event_id):
|
||||
event = get_object_or_404(Event, id=event_id)
|
||||
attendee_userids = [attendee.user.id for attendee in Attendee.objects.filter(event=event)]
|
||||
members = Member.objects.filter(team=event.team, ).order_by('user__realname')
|
||||
member_choices = [(member.id, member.user) for member in members if member.user.user.account.is_email_confirmed and member.user.id not in attendee_userids]
|
||||
default_choices = [('all', 'All Members (%s)' % len(member_choices))]
|
||||
|
||||
if request.method == 'POST' and request.POST.get('form', None) == 'email':
|
||||
email_form = EventInviteEmailForm(request.POST)
|
||||
if email_form.is_valid():
|
||||
to = email_form.cleaned_data['emails']
|
||||
for email in to:
|
||||
invite_attendee(email, event, request.user.profile)
|
||||
messages.add_message(request, messages.SUCCESS, message=_('Sent %s invites' % len(to)))
|
||||
return redirect(event.get_absolute_url())
|
||||
team_form = EventInviteMemberForm()
|
||||
team_form.fields['member'].choices = default_choices + member_choices
|
||||
elif request.method == 'POST' and request.POST.get('form', None) == 'team':
|
||||
team_form = EventInviteMemberForm(request.POST)
|
||||
team_form.fields['member'].choices = default_choices + member_choices
|
||||
if team_form.is_valid():
|
||||
to = team_form.cleaned_data['member']
|
||||
if to == 'all':
|
||||
for (member_id, user) in member_choices:
|
||||
try:
|
||||
attendee = Attendee.objects.get(event=event, user=user)
|
||||
except:
|
||||
# No attendee record found, so send the invite
|
||||
invite_attendee(user.user.email, event, request.user.profile)
|
||||
messages.add_message(request, messages.SUCCESS, message=_('Sent %s invites' % len(member_choices)))
|
||||
return redirect(event.get_absolute_url())
|
||||
else:
|
||||
member = get_object_or_404(Member, id=to)
|
||||
try:
|
||||
attendee = Attendee.objects.get(event=event, user=member.user)
|
||||
except:
|
||||
# No attendee record found, so send the invite
|
||||
invite_attendee(member.user.user.email, event, request.user.profile)
|
||||
messages.add_message(request, messages.SUCCESS, message=_('Invited %s' % member.user))
|
||||
return redirect(event.get_absolute_url())
|
||||
email_form = EventInviteEmailForm()
|
||||
else:
|
||||
email_form = EventInviteEmailForm()
|
||||
team_form = EventInviteMemberForm()
|
||||
team_form.fields['member'].choices = default_choices + member_choices
|
||||
|
||||
context = {
|
||||
'event': event,
|
||||
'email_form': email_form,
|
||||
'team_form': team_form,
|
||||
'member_choice_count': len(member_choices),
|
||||
'can_edit_team': request.user.profile.can_edit_team(event.team),
|
||||
'is_email_confirmed': request.user.account.is_email_confirmed,
|
||||
}
|
||||
return render(request, 'get_together/events/invite_attendees.html', context)
|
||||
|
||||
|
||||
def invite_attendee(email, event, sender):
|
||||
context = {
|
||||
'sender': sender,
|
||||
'team': event.team,
|
||||
'event': event,
|
||||
'site': Site.objects.get(id=1),
|
||||
}
|
||||
email_subject = '[GetTogether] Invite to attend %s' % event.name
|
||||
email_body_text = render_to_string('get_together/emails/attendee_invite.txt', context)
|
||||
email_body_html = render_to_string('get_together/emails/attendee_invite.html', context)
|
||||
email_recipients = [email]
|
||||
email_from = getattr(settings, 'DEFAULT_FROM_EMAIL', 'noreply@gettogether.community')
|
||||
|
||||
send_mail(
|
||||
from_email=email_from,
|
||||
html_message=email_body_html,
|
||||
message=email_body_text,
|
||||
recipient_list=email_recipients,
|
||||
subject=email_subject,
|
||||
fail_silently=True,
|
||||
)
|
||||
|
||||
|
||||
@login_required
|
||||
def add_event_photo(request, event_id):
|
||||
event = get_object_or_404(Event, id=event_id)
|
||||
|
|
Loading…
Reference in a new issue