reenable mails to Content team when speaker/eventproposals are created/updated, change so proposal URLs are opened in new window, add a message in browser when proposals are approved in the admin
This commit is contained in:
parent
eb807a6853
commit
24371b629a
|
@ -24,7 +24,7 @@ from .models import (
|
|||
class SpeakerProposalAdmin(admin.ModelAdmin):
|
||||
def mark_speakerproposal_as_approved(self, request, queryset):
|
||||
for sp in queryset:
|
||||
sp.mark_as_approved()
|
||||
sp.mark_as_approved(request)
|
||||
mark_speakerproposal_as_approved.description = 'Approve and create Speaker object(s)'
|
||||
|
||||
actions = ['mark_speakerproposal_as_approved']
|
||||
|
@ -43,7 +43,7 @@ class EventProposalAdmin(admin.ModelAdmin):
|
|||
return False
|
||||
else:
|
||||
try:
|
||||
ep.mark_as_approved()
|
||||
ep.mark_as_approved(request)
|
||||
except ValidationError as e:
|
||||
messages.error(request, e)
|
||||
return False
|
||||
|
|
|
@ -247,7 +247,7 @@ class SpeakerProposal(UserSubmittedModel):
|
|||
def get_absolute_url(self):
|
||||
return reverse_lazy('program:speakerproposal_detail', kwargs={'camp_slug': self.camp.slug, 'pk': self.uuid})
|
||||
|
||||
def mark_as_approved(self):
|
||||
def mark_as_approved(self, request):
|
||||
speakermodel = apps.get_model('program', 'speaker')
|
||||
speakerproposalmodel = apps.get_model('program', 'speakerproposal')
|
||||
speaker = speakermodel()
|
||||
|
@ -261,6 +261,16 @@ class SpeakerProposal(UserSubmittedModel):
|
|||
self.proposal_status = speakerproposalmodel.PROPOSAL_APPROVED
|
||||
self.save()
|
||||
|
||||
# copy all the URLs too
|
||||
for url in self.urls.all():
|
||||
Url.objects.create(
|
||||
url=url.url,
|
||||
urltype=url.urltype,
|
||||
speaker=speaker
|
||||
)
|
||||
|
||||
messages.success(request, "Speaker object %s has been created" % speaker)
|
||||
|
||||
|
||||
class EventProposal(UserSubmittedModel):
|
||||
""" An event proposal """
|
||||
|
@ -336,11 +346,11 @@ class EventProposal(UserSubmittedModel):
|
|||
user=self.user
|
||||
).exclude(uuid__in=self.speakers.all().values_list('uuid'))
|
||||
|
||||
def mark_as_approved(self):
|
||||
def mark_as_approved(self, request):
|
||||
eventmodel = apps.get_model('program', 'event')
|
||||
eventproposalmodel = apps.get_model('program', 'eventproposal')
|
||||
event = eventmodel()
|
||||
event.camp = self.camp
|
||||
event.track = self.track
|
||||
event.title = self.title
|
||||
event.abstract = self.abstract
|
||||
event.event_type = self.event_type
|
||||
|
@ -358,6 +368,15 @@ class EventProposal(UserSubmittedModel):
|
|||
self.proposal_status = eventproposalmodel.PROPOSAL_APPROVED
|
||||
self.save()
|
||||
|
||||
# copy all the URLs too
|
||||
for url in self.urls.all():
|
||||
Url.objects.create(
|
||||
url=url.url,
|
||||
urltype=url.urltype,
|
||||
event=event
|
||||
)
|
||||
|
||||
messages.success(request, "Event object %s has been created" % event)
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<tr>
|
||||
<td><span class="h4">{{ eventproposal.title }}</span></td>
|
||||
<td><i class="fas fa-{{ eventproposal.event_type.icon }} fa-lg" style="color: {{ eventproposal.event_type.color }};"></i><span class="h4"> {{ eventproposal.event_type }}</span></td>
|
||||
<td><span class="h4">{% for url in eventproposal.urls.all %}<a href="{{ url.url }}"><i class="fas fa-{{ url.urltype.icon }}" data-toggle="tooltip" title="{{ url.urltype.name }}"></i></a> {% empty %}N/A{% endfor %}</span></td>
|
||||
<td><span class="h4">{% for url in eventproposal.urls.all %}<a href="{{ url.url }}" target="_blank"><i class="fas fa-{{ url.urltype.icon }}" data-toggle="tooltip" title="{{ url.urltype.name }}"></i></a> {% empty %}N/A{% endfor %}</span></td>
|
||||
<td><span class="h4">{% for person in eventproposal.speakers.all %}<a href="{% url 'program:speakerproposal_detail' camp_slug=camp.slug pk=person.uuid %}"><i class="fas fa-user" data-toggle="tooltip" title="{{ person.name }}"></i></a> {% endfor %}</span></td>
|
||||
<td><span class="h4">{{ eventproposal.track.name }}</span></td>
|
||||
<td><span class="badge">{{ eventproposal.proposal_status }}</span></td>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{% for url in eventproposal.urls.all %}
|
||||
<tr>
|
||||
<td><i class="fas fa-{{ url.urltype.icon }} fa-lg"></i><span class="h4"> {{ url.urltype.name }}</span></td>
|
||||
<td><span class="h4"><a href="{{ url.url }}">{{ url }}</a></span></td>
|
||||
<td><span class="h4"><a href="{{ url.url }}" target="_blank">{{ url }}</a></span></td>
|
||||
<td class='text-right'>
|
||||
{% if not camp.read_only %}
|
||||
<a href="{% url 'program:eventproposalurl_update' camp_slug=camp.slug event_uuid=eventproposal.uuid url_uuid=url.uuid %}" class="btn btn-success btn-sm"><i class="fas fa-edit"></i><span class="h5"> Update</span></a>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</td>
|
||||
<td class="text-center">
|
||||
{% for url in speakerproposal.urls.all %}
|
||||
<a href="{{ url.url }}" data-toggle="tooltip" title="{{ url.urltype }}"><i class="fas fa-{{ url.urltype.icon }}"></i></a>
|
||||
<a href="{{ url.url }}" target="_blank" data-toggle="tooltip" title="{{ url.urltype }}"><i class="fas fa-{{ url.urltype.icon }}"></i></a>
|
||||
{% empty %}
|
||||
N/A
|
||||
{% endfor %}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
{% for url in speakerproposal.urls.all %}
|
||||
<tr>
|
||||
<td><i class="fas fa-{{ url.urltype.icon }} fa-lg"></i><span class="h4"> {{ url.urltype.name }}</span></td>
|
||||
<td><span class="h4"><a href="{{ url.url }}">{{ url }}</a></span></td>
|
||||
<td><span class="h4"><a href="{{ url.url }}" target="_blank">{{ url }}</a></span></td>
|
||||
<td class='text-right'>
|
||||
{% if not camp.read_only %}
|
||||
<a href="{% url 'program:speakerproposalurl_update' camp_slug=camp.slug speaker_uuid=speakerproposal.uuid url_uuid=url.uuid %}" class="btn btn-success btn-sm"><i class="fas fa-edit"></i><span class="h5"> Update</span></a>
|
||||
|
|
|
@ -28,6 +28,8 @@ from .mixins import (
|
|||
UrlViewMixin,
|
||||
)
|
||||
from .email import (
|
||||
add_new_eventproposal_email,
|
||||
add_new_speakerproposal_email,
|
||||
add_speakerproposal_updated_email,
|
||||
add_eventproposal_updated_email
|
||||
)
|
||||
|
@ -151,6 +153,10 @@ class SpeakerProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritabl
|
|||
# add speakerproposal to eventproposal
|
||||
self.eventproposal.speakers.add(speakerproposal)
|
||||
|
||||
# send mail to content team
|
||||
if not add_new_speakerproposal_email(speakerproposal):
|
||||
logger.error("Unable to send email to content team after new speakerproposal")
|
||||
|
||||
return redirect(
|
||||
reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})
|
||||
)
|
||||
|
@ -163,8 +169,6 @@ class SpeakerProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritabl
|
|||
model = models.SpeakerProposal
|
||||
template_name = 'speakerproposal_form.html'
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})
|
||||
|
||||
def get_form_class(self):
|
||||
""" Get the appropriate form class based on the eventtype """
|
||||
|
@ -181,6 +185,22 @@ class SpeakerProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritabl
|
|||
# more than one type of event for this person, return the generic speakerproposal form
|
||||
return BaseSpeakerProposalForm
|
||||
|
||||
def form_valid(self, form):
|
||||
"""
|
||||
Change the speakerproposal status to pending
|
||||
"""
|
||||
# set proposal status to pending
|
||||
form.instance.proposal_status = models.SpeakerProposal.PROPOSAL_PENDING
|
||||
speakerproposal = form.save()
|
||||
|
||||
# send mail to content team
|
||||
if not add_speakerproposal_updated_email(speakerproposal):
|
||||
logger.error("Unable to send email to content team after speakerproposal update")
|
||||
|
||||
# message user and redirect
|
||||
messages.info(self.request, "Your proposal is now pending approval by the content team.")
|
||||
return redirect(reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}))
|
||||
|
||||
|
||||
class SpeakerProposalDeleteView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureUserOwnsProposalMixin, EnsureCFPOpenMixin, DeleteView):
|
||||
"""
|
||||
|
@ -391,6 +411,10 @@ class EventProposalCreateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC
|
|||
# add the speakerproposal to the eventproposal
|
||||
eventproposal.speakers.add(self.speakerproposal)
|
||||
|
||||
# send mail to content team
|
||||
if not add_new_eventproposal_email(eventproposal):
|
||||
logger.error("Unable to send email to content team after new eventproposal")
|
||||
|
||||
# all good
|
||||
return redirect(self.get_success_url())
|
||||
|
||||
|
@ -406,8 +430,6 @@ class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC
|
|||
""" Get the appropriate form class based on the eventtype """
|
||||
return get_eventproposal_form_class(self.get_object().event_type)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug})
|
||||
|
||||
def get_context_data(self, *args, **kwargs):
|
||||
""" Make speakerproposal and eventtype objects available in the template """
|
||||
|
@ -425,6 +447,19 @@ class EventProposalUpdateView(LoginRequiredMixin, CampViewMixin, EnsureWritableC
|
|||
form.fields['track'].queryset = models.EventTrack.objects.filter(camp=self.camp)
|
||||
return form
|
||||
|
||||
def form_valid(self, form):
|
||||
# set status to pending and save eventproposal
|
||||
form.instance.proposal_status = models.EventProposal.PROPOSAL_PENDING
|
||||
eventproposal = form.save()
|
||||
|
||||
# send email to content team
|
||||
if not add_eventproposal_updated_email(eventproposal):
|
||||
logger.error("Unable to send email to content team after eventproposal update")
|
||||
|
||||
# message for the user and redirect
|
||||
messages.info(self.request, "Your proposal is now pending approval by the content team.")
|
||||
return redirect(reverse('program:proposal_list', kwargs={'camp_slug': self.camp.slug}))
|
||||
|
||||
|
||||
class EventProposalDeleteView(LoginRequiredMixin, CampViewMixin, EnsureWritableCampMixin, EnsureUserOwnsProposalMixin, EnsureCFPOpenMixin, DeleteView):
|
||||
model = models.EventProposal
|
||||
|
@ -543,6 +578,13 @@ class CombinedProposalSubmitView(LoginRequiredMixin, CampViewMixin, CreateView):
|
|||
# add the speakerproposal to the eventproposal
|
||||
eventproposal.speakers.add(speakerproposal)
|
||||
|
||||
# send mail(s) to content team
|
||||
if not add_new_eventproposal_email(eventproposal):
|
||||
logger.error("Unable to send email to content team after new eventproposal")
|
||||
if not hasattr(self, 'speakerproposal'):
|
||||
if not add_new_speakerproposal_email(speakerproposal):
|
||||
logger.error("Unable to send email to content team after new speakerproposal")
|
||||
|
||||
# all good
|
||||
return redirect(reverse_lazy('program:proposal_list', kwargs={'camp_slug': self.camp.slug}))
|
||||
|
||||
|
|
Loading…
Reference in a new issue