manager: don't allow deletion of busy agenda/events (#13214)

This commit is contained in:
Frédéric Péters 2016-09-18 19:03:01 +02:00
parent fcdf6cff93
commit b0322e6050
3 changed files with 106 additions and 3 deletions

View File

@ -8,9 +8,16 @@
{% block content %}
<form method="post">
{% csrf_token %}
<p>
{% if cannot_delete %}
{% blocktrans %}This cannot be removed as there are bookings for a future date.
{% endblocktrans %}
{% else %}
{% blocktrans %}Are you sure you want to delete this?{% endblocktrans %}
{% endif %}
</p>
<div class="buttons">
<button>{% trans 'Confirm Deletion' %}</button>
<button {% if cannot_delete %}disabled="disabled"{% endif %}>{% trans 'Confirm Deletion' %}</button>
<a class="cancel" href="{{ object.get_absolute_url }}">{% trans 'Cancel' %}</a>
</div>
</form>

View File

@ -21,12 +21,13 @@ from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse, reverse_lazy
from django.db.models import Q
from django.http import HttpResponse, Http404
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import force_text
from django.views.generic import (DetailView, CreateView, UpdateView,
ListView, DeleteView, FormView, TemplateView)
from chrono.agendas.models import Agenda, Event, MeetingType, TimePeriod
from chrono.agendas.models import Agenda, Event, MeetingType, TimePeriod, Booking
from .forms import EventForm, MeetingTypeForm, TimePeriodForm, ImportEventsForm
@ -82,6 +83,21 @@ class AgendaDeleteView(DeleteView):
raise PermissionDenied()
return super(AgendaDeleteView, self).dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(AgendaDeleteView, self).get_context_data(**kwargs)
context['cannot_delete'] = Booking.objects.filter(
event__agenda=self.get_object(),
event__start_datetime__gt=now(),
cancellation_datetime__isnull=True).exists()
return context
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data()
if context['cannot_delete']:
raise PermissionDenied()
return super(AgendaDeleteView, self).delete(request, *args, **kwargs)
agenda_delete = AgendaDeleteView.as_view()
@ -186,6 +202,20 @@ class EventDeleteView(ManagedAgendaSubobjectMixin, DeleteView):
template_name = 'chrono/manager_confirm_delete.html'
model = Event
def get_context_data(self, **kwargs):
context = super(ManagedAgendaSubobjectMixin, self).get_context_data(**kwargs)
context['cannot_delete'] = bool(
self.object.booking_set.filter(cancellation_datetime__isnull=True).exists() and
self.object.start_datetime > now())
return context
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
context = self.get_context_data()
if context['cannot_delete']:
raise PermissionDenied()
return super(EventDeleteView, self).delete(request, *args, **kwargs)
event_delete = EventDeleteView.as_view()

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from django.contrib.auth.models import User, Group
from django.utils.timezone import make_aware
from django.utils.timezone import make_aware, now
import datetime
import pytest
from webtest import TestApp, Upload
@ -192,6 +192,39 @@ def test_delete_agenda(app, admin_user):
resp = resp.follow()
assert not 'Foo bar' in resp.body
def test_delete_busy_agenda(app, admin_user):
agenda = Agenda(label=u'Foo bar')
agenda.save()
event = Event(start_datetime=now() + datetime.timedelta(days=10),
places=10, agenda=agenda)
event.save()
app = login(app)
resp = app.get('/manage/', status=200)
resp = resp.click('Foo bar')
resp = resp.click('Delete')
assert 'Are you sure you want to delete this?' in resp.body
booking = Booking(event=event)
booking.save()
resp = app.get('/manage/', status=200)
resp = resp.click('Foo bar')
resp = resp.click('Delete')
assert 'This cannot be removed' in resp.body
booking.cancellation_datetime = now()
booking.save()
resp = app.get('/manage/', status=200)
resp = resp.click('Foo bar')
resp = resp.click('Delete')
assert 'Are you sure you want to delete this?' in resp.body
# suddenly the booking is no longer cancelled, but the admin clicks on the
# delete button.
booking.cancellation_datetime = None
booking.save()
resp = resp.form.submit(status=403)
def test_delete_agenda_as_manager(app, manager_user):
agenda = Agenda(label=u'Foo bar')
agenda.edit_role = manager_user.groups.all()[0]
@ -350,6 +383,39 @@ def test_delete_event(app, admin_user):
assert resp.location == 'http://localhost:80/manage/agendas/%s/' % agenda.id
assert Event.objects.count() == 0
def test_delete_busy_event(app, admin_user):
agenda = Agenda(label=u'Foo bar')
agenda.save()
event = Event(start_datetime=now() + datetime.timedelta(days=10),
places=10, agenda=agenda)
event.save()
app = login(app)
resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
resp = resp.click(href='/manage/events/%s' % event.id)
resp = resp.click('Delete')
assert 'Are you sure you want to delete this?' in resp.body
booking = Booking(event=event)
booking.save()
resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
resp = resp.click(href='/manage/events/%s' % event.id)
resp = resp.click('Delete')
assert 'This cannot be removed' in resp.body
booking.cancellation_datetime = now()
booking.save()
resp = app.get('/manage/agendas/%s/' % agenda.id, status=200)
resp = resp.click(href='/manage/events/%s' % event.id)
resp = resp.click('Delete')
assert 'Are you sure you want to delete this?' in resp.body
# suddenly the booking is no longer cancelled, but the admin clicks on the
# delete button.
booking.cancellation_datetime = None
booking.save()
resp = resp.form.submit(status=403)
def test_delete_event_as_manager(app, manager_user):
agenda = Agenda(label=u'Foo bar')
agenda.edit_role = manager_user.groups.all()[0]