Merged in [15328] from rcross@amsl.com:

Give secretariat the ability to cancel non-working group sessions. Fixes #2537.
 - Legacy-Id: 15363
Note: SVN reference [15328] has been migrated to Git commit ec279682d2
This commit is contained in:
Henrik Levkowetz 2018-07-15 20:08:44 +00:00
commit 1504c6b13e
6 changed files with 46 additions and 6 deletions

View file

@ -335,6 +335,19 @@ class SecrMeetingTestCase(TestCase):
self.assertRedirects(response, target)
self.assertFalse(meeting.agenda.assignments.filter(timeslot=slot))
def test_meetings_non_session_cancel(self):
meeting = make_meeting_test_data()
slot = meeting.agenda.assignments.filter(timeslot__type='reg').first().timeslot
url = reverse('ietf.secr.meetings.views.non_session_cancel', kwargs={'meeting_id':meeting.number,'schedule_name':meeting.agenda.name,'slot_id':slot.id})
redirect_url = reverse('ietf.secr.meetings.views.non_session', kwargs={'meeting_id':meeting.number,'schedule_name':meeting.agenda.name})
self.client.login(username="secretary", password="secretary+password")
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
response = self.client.post(url, {'post':'yes'})
self.assertRedirects(response, redirect_url)
session = slot.sessionassignments.filter(schedule=meeting.agenda).first().session
self.assertEqual(session.status_id, 'canceled')
def test_meetings_select_group(self):
make_meeting_test_data()
url = reverse('ietf.secr.meetings.views.select_group',kwargs={'meeting_id':42,'schedule_name':'test-agenda'})

View file

@ -14,6 +14,7 @@ urlpatterns = [
url(r'^(?P<meeting_id>\d{1,6})/notifications/$', views.notifications),
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/$', views.select),
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/non_session/$', views.non_session),
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/non_session/cancel/(?P<slot_id>\d{1,6})/$', views.non_session_cancel),
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/non_session/edit/(?P<slot_id>\d{1,6})/$', views.non_session_edit),
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/non_session/delete/(?P<slot_id>\d{1,6})/$', views.non_session_delete),
url(r'^(?P<meeting_id>\d{1,6})/(?P<schedule_name>[A-Za-z0-9_\-]+)/rooms/$', views.rooms),

View file

@ -491,6 +491,25 @@ def non_session(request, meeting_id, schedule_name):
'schedule': schedule},
)
@role_required('Secretariat')
def non_session_cancel(request, meeting_id, schedule_name, slot_id):
'''
This function cancels the non-session TimeSlot. Check for uploaded
material first. SchedTimeSessAssignment objects get cancelled as well.
'''
slot = get_object_or_404(TimeSlot, id=slot_id)
meeting = get_object_or_404(Meeting, number=meeting_id)
schedule = get_object_or_404(Schedule, meeting=meeting, name=schedule_name)
if request.method == 'POST' and request.POST['post'] == 'yes':
assignments = slot.sessionassignments.filter(schedule=schedule)
Session.objects.filter(pk__in=[x.session.pk for x in assignments]).update(status_id='canceled')
messages.success(request, 'The session was cancelled successfully')
return redirect('ietf.secr.meetings.views.non_session', meeting_id=meeting_id, schedule_name=schedule_name)
return render(request, 'confirm_cancel.html', {'object': slot})
@role_required('Secretariat')
def non_session_delete(request, meeting_id, schedule_name, slot_id):
'''
@ -844,7 +863,7 @@ def session_edit(request, meeting_id, schedule_name, session_id):
if button_text == 'Cancel':
session.status = SessionStatusName.objects.get(slug='canceled')
session.save()
messages.success(request, 'Session canceled')
messages.success(request, 'Session cancelled')
else:
form.save()
messages.success(request, 'Session saved')

View file

@ -213,7 +213,7 @@ def cancel(request, acronym):
{'requester':get_requester_text(login,group),
'meeting':meeting}, cc=cc_list)
messages.success(request, 'The %s Session Request has been canceled' % group.acronym)
messages.success(request, 'The %s Session Request has been cancelled' % group.acronym)
return redirect('ietf.secr.sreq.views.main')
@role_required(*AUTHORIZED_ROLES)
@ -242,12 +242,12 @@ def confirm(request, acronym):
button_text = request.POST.get('submit', '')
if button_text == 'Cancel':
messages.success(request, 'Session Request has been canceled')
messages.success(request, 'Session Request has been cancelled')
return redirect('ietf.secr.sreq.views.main')
button_text = request.POST.get('submit', '')
if button_text == 'Cancel':
messages.success(request, 'Session Request has been canceled')
messages.success(request, 'Session Request has been cancelled')
return redirect('ietf.secr.sreq.views.main')
if request.method == 'POST' and button_text == 'Submit':

View file

@ -490,6 +490,11 @@ tr.break td {
border-top: 2px solid black;
}
tr.cancelled {
background-color: #e12817;
color: white;
}
#id_schedule_selector {
display: inline;
}

View file

@ -6,7 +6,7 @@
<h2>TimeSlots</h2>
{% if slots %}
<table class="full-width">
<table id="nonsessions" class="full-width">
<thead>
<tr>
<th>Day</th>
@ -19,11 +19,12 @@
<th>Type</th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{% for item in slots %}
<tr class="{% cycle row1 row2 %}{% ifchanged item.type %} break{% endifchanged %}">
<tr class="{% cycle row1 row2 %}{% ifchanged item.type %} break{% endifchanged %}{% if item.session.status.slug == "canceled" %} cancelled{% endif %}">
<td>{{ item.time|date:"D" }}</td>
<td>{{ item.time|date:"H:i" }}-{{ item.end_time|date:"H:i" }}</td>
<td>{{ item.name }}</td>
@ -33,6 +34,7 @@
<td>{{ item.show_location }}</td>
<td>{{ item.type }}</td>
<td><a href="{% url "ietf.secr.meetings.views.non_session_edit" meeting_id=meeting.number schedule_name=schedule.name slot_id=item.id %}">Edit</a></td>
<td><a href="{% url "ietf.secr.meetings.views.non_session_cancel" meeting_id=meeting.number schedule_name=schedule.name slot_id=item.id %}">Cancel</a></td>
<td><a href="{% url "ietf.secr.meetings.views.non_session_delete" meeting_id=meeting.number schedule_name=schedule.name slot_id=item.id %}">Delete</a></td>
</tr>
{% endfor %}