Projet

Général

Profil

0004-agendas-add-resource-to-agenda-38942.patch

Lauréline Guérin, 29 mai 2020 17:10

Télécharger (11,4 ko)

Voir les différences:

Subject: [PATCH 4/8] agendas: add resource to agenda (#38942)

 chrono/manager/forms.py                       |  8 +++
 .../chrono/manager_agenda_resource_form.html  | 23 ++++++++
 .../manager_meetings_agenda_settings.html     | 31 ++++++++++
 .../chrono/manager_resource_detail.html       | 29 ++++++++++
 chrono/manager/urls.py                        | 10 ++++
 chrono/manager/views.py                       | 36 ++++++++++++
 tests/test_manager.py                         | 58 +++++++++++++++++++
 7 files changed, 195 insertions(+)
 create mode 100644 chrono/manager/templates/chrono/manager_agenda_resource_form.html
chrono/manager/forms.py
102 102
        exclude = ['full', 'meeting_type', 'desk', 'resources']
103 103

  
104 104

  
105
class AgendaResourceForm(forms.Form):
106
    resource = forms.ModelChoiceField(label=_('Resource'), queryset=Resource.objects.none())
107

  
108
    def __init__(self, *args, **kwargs):
109
        super().__init__(*args, **kwargs)
110
        self.fields['resource'].queryset = Resource.objects.exclude(agenda=self.initial['agenda'])
111

  
112

  
105 113
class NewMeetingTypeForm(forms.ModelForm):
106 114
    class Meta:
107 115
        model = MeetingType
chrono/manager/templates/chrono/manager_agenda_resource_form.html
1
{% extends "chrono/manager_agenda_view.html" %}
2
{% load i18n %}
3

  
4
{% block breadcrumb %}
5
{{ block.super }}
6
<a href="">{% trans "Add resource" %}</a>
7
{% endblock %}
8

  
9
{% block appbar %}
10
<h2>{% trans "Add resource" %}</h2>
11
{% endblock %}
12

  
13
{% block content %}
14

  
15
<form method="post" enctype="multipart/form-data">
16
  {% csrf_token %}
17
  {{ form.as_p }}
18
  <div class="buttons">
19
    <button class="submit-button">{% trans "Save" %}</button>
20
    <a class="cancel" href="{% url 'chrono-manager-agenda-settings' pk=agenda.pk %}">{% trans 'Cancel' %}</a>
21
  </div>
22
</form>
23
{% endblock %}
chrono/manager/templates/chrono/manager_meetings_agenda_settings.html
13 13
{% endblock %}
14 14

  
15 15
{% block agenda-extra-management-actions %}
16
  {% if has_resources %}<a rel="popup" href="{% url 'chrono-manager-agenda-add-resource' pk=object.pk %}">{% trans 'Add resource' %}</a>{% endif %}
16 17
  <a rel="popup" href="{% url 'chrono-manager-agenda-add-meeting-type' pk=object.id %}">{% trans 'New Meeting Type' %}</a>
17 18
  <a rel="popup" href="{% url 'chrono-manager-agenda-add-desk' pk=object.id %}">{% trans 'New Desk' %}</a>
18 19
{% endblock %}
......
97 98
</div>
98 99
</div>
99 100

  
101
{% with object.resources.all as agenda_resources %}
102
{% if has_resources %}
103
<div class="section">
104
<h3>{% trans 'Resources' %}</h3>
105
<div>
106
{% if agenda_resources %}
107
  <ul class="objects-list single-links">
108
    {% for resource in agenda_resources %}
109
    <li>
110
        <a href="{% url 'chrono-manager-resource-view' pk=resource.pk %}">
111
            {{ resource.label }}
112
            <span class="identifier">[{% trans "identifier:" %} {{ resource.slug }}]</span>
113
        </a>
114
        <a rel="popup" class="delete" href="{% url 'chrono-manager-agenda-delete-resource' pk=object.pk resource_pk=resource.pk %}">{% trans "remove" %}</a>
115
    </li>
116
    {% endfor %}
117
  </ul>
118
{% else %}
119
<div class="big-msg-info">
120
  {% blocktrans %}
121
  This agenda doesn't have any resource yet. Click on the "Add resource" button in
122
  the top right of the page to add a first one.
123
  {% endblocktrans %}
124
</div>
125
{% endif %}
126
</div>
127
</div>
128
{% endif %}
129
{% endwith %}
130

  
100 131
{% endblock %}
chrono/manager/templates/chrono/manager_resource_detail.html
17 17
<a rel="popup" href="{% url 'chrono-manager-resource-delete' pk=object.pk %}">{% trans 'Delete' %}</a>
18 18
</span>
19 19
{% endblock %}
20

  
21
{% block content %}
22

  
23
<div class="section">
24
<h3>{% trans 'Used in meetings agendas' %}</h3>
25
<div>
26
{% with object.agenda_set.all as agendas %}
27
{% if agendas %}
28
  <ul class="objects-list single-links">
29
    {% for agenda in agendas %}
30
    <li>
31
        <a href="{% url 'chrono-manager-agenda-settings' pk=agenda.pk %}">
32
            {{ agenda.label }}
33
        </a>
34
    </li>
35
    {% endfor %}
36
  </ul>
37
{% else %}
38
<div class="big-msg-info">
39
  {% blocktrans %}
40
  This resource is not used yet.
41
  {% endblocktrans %}
42
</div>
43
{% endif %}
44
{% endwith %}
45
</div>
46
</div>
47

  
48
{% endblock %}
chrono/manager/urls.py
63 63
        views.event_delete,
64 64
        name='chrono-manager-event-delete',
65 65
    ),
66
    url(
67
        r'^agendas/(?P<pk>\d+)/add-resource/$',
68
        views.agenda_add_resource,
69
        name='chrono-manager-agenda-add-resource',
70
    ),
71
    url(
72
        r'^agendas/(?P<pk>\d+)/resource/(?P<resource_pk>\d+)/delete/$',
73
        views.agenda_delete_resource,
74
        name='chrono-manager-agenda-delete-resource',
75
    ),
66 76
    url(
67 77
        r'^agendas/(?P<pk>\d+)/add-meeting-type$',
68 78
        views.agenda_add_meeting_type,
chrono/manager/views.py
79 79
    VirtualMemberForm,
80 80
    ResourceAddForm,
81 81
    ResourceEditForm,
82
    AgendaResourceForm,
82 83
)
83 84
from .utils import import_site
84 85

  
......
787 788
                for virtual_member in self.object.get_virtual_members()
788 789
            ]
789 790
            context['meeting_types'] = self.object.iter_meetingtypes()
791
        if self.agenda.kind == 'meetings':
792
            context['has_resources'] = Resource.objects.exists()
790 793
        return context
791 794

  
792 795
    def get_events(self):
......
933 936
event_delete = EventDeleteView.as_view()
934 937

  
935 938

  
939
class AgendaAddResourceView(ManagedAgendaMixin, FormView):
940
    template_name = 'chrono/manager_agenda_resource_form.html'
941
    model = Event
942
    form_class = AgendaResourceForm
943

  
944
    def set_agenda(self, **kwargs):
945
        self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'), kind='meetings')
946

  
947
    def form_valid(self, form):
948
        self.agenda.resources.add(form.cleaned_data['resource'])
949
        return super().form_valid(form)
950

  
951

  
952
agenda_add_resource = AgendaAddResourceView.as_view()
953

  
954

  
955
class AgendaResourceDeleteView(ManagedAgendaMixin, DeleteView):
956
    template_name = 'chrono/manager_confirm_delete.html'
957
    model = Resource
958
    pk_url_kwarg = 'resource_pk'
959

  
960
    def set_agenda(self, **kwargs):
961
        self.agenda = get_object_or_404(Agenda, id=kwargs.get('pk'), kind='meetings')
962

  
963
    def delete(self, request, *args, **kwargs):
964
        self.object = self.get_object()
965
        self.agenda.resources.remove(self.object)
966
        return HttpResponseRedirect(self.get_success_url())
967

  
968

  
969
agenda_delete_resource = AgendaResourceDeleteView.as_view()
970

  
971

  
936 972
class AgendaAddMeetingTypeView(ManagedAgendaMixin, CreateView):
937 973
    template_name = 'chrono/manager_meeting_type_form.html'
938 974
    model = Event
tests/test_manager.py
193 193
    assert resource.slug == 'foo-bar'
194 194

  
195 195

  
196
def test_view_resource(app, admin_user):
197
    agenda = Agenda.objects.create(label=u'Foo Bar', kind='meetings')
198
    resource = Resource.objects.create(label='Resource 1')
199

  
200
    app = login(app)
201
    resp = app.get('/manage/resource/%s/' % resource.pk, status=200)
202
    assert '/manage/agendas/%s/settings' % agenda.pk not in resp.text
203

  
204
    agenda.resources.add(resource)
205
    resp = app.get('/manage/resource/%s/' % resource.pk, status=200)
206
    assert '/manage/agendas/%s/settings' % agenda.pk in resp.text
207

  
208

  
196 209
def test_edit_resource(app, admin_user):
197 210
    resource = Resource.objects.create(label='Foo bar')
198 211

  
......
259 272
    resp = resp.form.submit()
260 273
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.id)
261 274
    resp = resp.follow()
275
    assert 'has_resources' not in resp.context
262 276
    assert 'Foo baz' in resp.text
263 277
    assert '<h2>Settings' in resp.text
264 278

  
......
322 336
    assert '<h2>Settings' in resp.text
323 337

  
324 338

  
339
def test_agenda_resources(app, admin_user):
340
    agenda = Agenda.objects.create(label=u'Foo bar', kind='events')
341
    resource = Resource.objects.create(label='Resource 1')
342
    app = login(app)
343
    # not for events agenda
344
    app.get('/manage/agendas/%s/add-resource/' % agenda.pk, status=404)
345
    app.get('/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk), status=404)
346

  
347

  
348
def test_meetings_agenda_resources(app, admin_user):
349
    agenda = Agenda.objects.create(label=u'Foo bar', kind='meetings')
350
    app = login(app)
351
    resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
352
    assert 'has_resources' in resp.context
353
    assert resp.context['has_resources'] is False
354
    assert 'Add resource' not in resp.text
355

  
356
    resource = Resource.objects.create(label='Resource 1')
357
    resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
358
    assert 'has_resources' in resp.context
359
    assert resp.context['has_resources'] is True
360
    assert '/manage/resource/%s/' % resource.pk not in resp.text
361
    assert '/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk) not in resp.text
362
    resp = resp.click('Add resource')
363
    assert list(resp.context['form'].fields['resource'].queryset) == [resource]
364
    resp.form['resource'] = resource.pk
365
    resp = resp.form.submit()
366
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
367
    assert list(agenda.resources.all()) == [resource]
368
    resp = resp.follow()
369
    assert '/manage/resource/%s/' % resource.pk in resp.text
370
    assert '/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk) in resp.text
371
    resp = resp.click('Add resource')
372
    assert list(resp.context['form'].fields['resource'].queryset) == []
373

  
374
    resp = app.get('/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk))
375
    resp = resp.form.submit()
376
    assert resp.location.endswith('/manage/agendas/%s/settings' % agenda.pk)
377
    assert list(agenda.resources.all()) == []
378
    resp = resp.follow()
379
    assert '/manage/resource/%s/' % resource.pk not in resp.text
380
    assert '/manage/agendas/%s/resource/%s/delete/' % (agenda.pk, resource.pk) not in resp.text
381

  
382

  
325 383
def test_delete_agenda(app, admin_user):
326 384
    agenda = Agenda(label=u'Foo bar')
327 385
    agenda.save()
328
-