0003-manager-add-detail-view-for-events-20279.patch
chrono/manager/templates/chrono/manager_event_detail.html | ||
---|---|---|
1 |
{% extends "chrono/manager_home.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block page-title-extra-label %} |
|
5 |
- {% firstof agenda.label object.label %} |
|
6 |
{% endblock %} |
|
7 | ||
8 |
{% block breadcrumb %} |
|
9 |
{{ block.super }} |
|
10 |
<a href="{% url 'chrono-manager-agenda-month-view' pk=agenda.id year=object.start_datetime.year month=object.start_datetime.month %}">{{agenda.label}}</a> |
|
11 |
<a href="{% url 'chrono-manager-event-view' pk=agenda.id event_pk=object.id %}">{{object}}</a> |
|
12 |
{% endblock %} |
|
13 | ||
14 |
{% block appbar %} |
|
15 |
{% if object.label %}<h2>{{ object.label }} — {{object.start_datetime|date:"DATETIME_FORMAT"}}</h2> |
|
16 |
{% else %}<h2>{{ object.start_datetime|date:"DATETIME_FORMAT"}}</h2> |
|
17 |
{% endif %} |
|
18 |
{% endblock %} |
|
19 | ||
20 |
{% block content %} |
|
21 | ||
22 |
{% if object.description %} |
|
23 |
<div class="section"> |
|
24 |
<div><p>{{ object.description }}</p></div> |
|
25 |
</div> |
|
26 |
{% endif %} |
|
27 | ||
28 |
<div class="section"> |
|
29 |
<h3>{% trans "Bookings" %} ({{booked|length}}/{{object.places}})</h3> |
|
30 |
<div> |
|
31 | ||
32 |
{% if event.booked_places > event.places %} |
|
33 |
<div class="errornotice"><p>{% trans "This event is overbooked." %}</p></div> |
|
34 |
{% endif %} |
|
35 | ||
36 |
<ul class="objects-list single-links"> |
|
37 |
{% for booking in booked %} |
|
38 |
<li><a {% if booking.backoffice_url %}href="{{ booking.backoffice_url }}"{% endif %}>{% if booking.user_name %}{{ booking.user_name }}{% else %}{% trans "Unknown" %}{% endif %}, |
|
39 |
{{ booking.creation_datetime|date:"DATETIME_FORMAT" }}</a></li> |
|
40 |
{% endfor %} |
|
41 |
</ul> |
|
42 |
</div> |
|
43 |
</div> |
|
44 | ||
45 |
{% if object.waiting_list_places %} |
|
46 |
<div class="section"> |
|
47 |
<h3>{% trans "Waiting List" %} ({{waiting|length}}/{{object.waiting_list_places}})</h3> |
|
48 |
<div> |
|
49 |
<ul class="objects-list single-links"> |
|
50 |
{% for booking in waiting %} |
|
51 |
<li><a {% if booking.backoffice_url %}href="{{ booking.backoffice_url }}"{% endif %}>{% if booking.user_name %}{{ booking.user_name }}{% else %}{% trans "Unknown" %}{% endif %}, |
|
52 |
{{ booking.creation_datetime|date:"DATETIME_FORMAT" }}</a></li> |
|
53 |
{% endfor %} |
|
54 |
</ul> |
|
55 |
</div> |
|
56 |
</div> |
|
57 |
{% endif %} |
|
58 | ||
59 |
{% endblock %} |
chrono/manager/templates/chrono/manager_events_agenda_month_view.html | ||
---|---|---|
16 | 16 |
{% elif event.waiting_list_places %} |
17 | 17 |
data-total="{{event.waiting_list_places}}" data-booked="{{event.waiting_list}}" |
18 | 18 |
{% endif %} |
19 |
><a> |
|
19 |
><a href="{% url 'chrono-manager-event-view' pk=agenda.id event_pk=event.id %}">
|
|
20 | 20 |
{% if event.label %}{{event.label}} / {% endif %} |
21 | 21 |
{{ event.start_datetime }} |
22 | 22 |
{% if event.full %}/ <span class="full">{% trans "full" %}</span>{% endif %} |
chrono/manager/urls.py | ||
---|---|---|
43 | 43 |
views.agenda_import_events, |
44 | 44 |
name='chrono-manager-agenda-import-events', |
45 | 45 |
), |
46 |
url( |
|
47 |
r'^agendas/(?P<pk>\d+)/events/(?P<event_pk>\d+)/$', |
|
48 |
views.event_view, |
|
49 |
name='chrono-manager-event-view', |
|
50 |
), |
|
46 | 51 |
url( |
47 | 52 |
r'^agendas/(?P<pk>\d+)/events/(?P<event_pk>\d+)/edit$', |
48 | 53 |
views.event_edit, |
chrono/manager/views.py | ||
---|---|---|
683 | 683 |
agenda_import_events = AgendaImportEventsView.as_view() |
684 | 684 | |
685 | 685 | |
686 |
class EventDetailView(ViewableAgendaMixin, DetailView): |
|
687 |
template_name = 'chrono/manager_event_detail.html' |
|
688 |
model = Event |
|
689 |
pk_url_kwarg = 'event_pk' |
|
690 | ||
691 |
def get_context_data(self, **kwargs): |
|
692 |
context = super(EventDetailView, self).get_context_data(**kwargs) |
|
693 |
event = self.get_object() |
|
694 |
context['booked'] = event.booking_set.filter( |
|
695 |
cancellation_datetime__isnull=True, in_waiting_list=False |
|
696 |
) |
|
697 |
context['waiting'] = event.booking_set.filter( |
|
698 |
cancellation_datetime__isnull=True, in_waiting_list=True |
|
699 |
) |
|
700 |
return context |
|
701 | ||
702 | ||
703 |
event_view = EventDetailView.as_view() |
|
704 | ||
705 | ||
686 | 706 |
class EventEditView(ManagedAgendaMixin, UpdateView): |
687 | 707 |
template_name = 'chrono/manager_event_form.html' |
688 | 708 |
model = Event |
tests/test_manager.py | ||
---|---|---|
1853 | 1853 |
assert resp.text.count('height:33.0%;top:100.0%;') == 2 |
1854 | 1854 | |
1855 | 1855 | |
1856 |
def test_agenda_view_event(app, manager_user): |
|
1857 |
agenda = Agenda(label=u'Foo bar') |
|
1858 |
agenda.view_role = manager_user.groups.all()[0] |
|
1859 |
agenda.save() |
|
1860 |
event = Event( |
|
1861 |
label='xyz', |
|
1862 |
start_datetime=make_aware(datetime.datetime(2019, 12, 22, 17, 0)), |
|
1863 |
places=10, |
|
1864 |
agenda=agenda, |
|
1865 |
) |
|
1866 |
event.save() |
|
1867 |
for i in range(8): |
|
1868 |
Booking(event=event).save() |
|
1869 |
app = login(app, username='manager', password='manager') |
|
1870 |
resp = app.get('/manage/agendas/%s/2019/12/' % agenda.id, status=200) |
|
1871 |
resp = resp.click('xyz') |
|
1872 |
assert 'Bookings (8/10)' in resp.text |
|
1873 |
assert 'Waiting' not in resp.text |
|
1874 |
assert 'overbooked' not in resp.text |
|
1875 |
event.waiting_list_places = 5 |
|
1876 |
event.save() |
|
1877 |
resp = app.get(resp.request.url) |
|
1878 |
assert 'Waiting List (0/5)' in resp.text |
|
1879 | ||
1880 |
event.places = 5 |
|
1881 |
event.save() |
|
1882 |
resp = app.get(resp.request.url) |
|
1883 |
assert 'overbooked' in resp.text |
|
1884 | ||
1885 | ||
1856 | 1886 |
def test_import_agenda_as_manager(app, manager_user): |
1857 | 1887 |
# open /manage/ access to manager_user, and check agenda import is not |
1858 | 1888 |
# allowed. |
1859 |
- |