Projet

Général

Profil

0001-manager-configuer-user-block-on-check-page-53237.patch

Lauréline Guérin, 29 avril 2021 12:26

Télécharger (14,6 ko)

Voir les différences:

Subject: [PATCH] manager: configuer user block on check page (#53237)

 .../0083_booking_user_block_template.py       | 23 +++++++++++
 chrono/agendas/models.py                      | 24 ++++++++++++
 chrono/manager/forms.py                       | 16 +++++++-
 .../templates/chrono/manager_event_check.html | 16 ++++----
 .../manager_event_check_booking_fragment.html |  2 +-
 .../manager_events_agenda_settings.html       | 31 ++++++++-------
 chrono/manager/urls.py                        |  6 +--
 chrono/manager/views.py                       | 13 ++++---
 tests/manager/test_absence_reason.py          |  7 ++--
 tests/manager/test_all.py                     | 38 ++++++++++++++++++-
 tests/manager/test_event.py                   |  6 +++
 11 files changed, 146 insertions(+), 36 deletions(-)
 create mode 100644 chrono/agendas/migrations/0083_booking_user_block_template.py
chrono/agendas/migrations/0083_booking_user_block_template.py
1
from django.db import migrations, models
2

  
3
import chrono.agendas.models
4

  
5

  
6
class Migration(migrations.Migration):
7

  
8
    dependencies = [
9
        ('agendas', '0082_text_to_jsonb'),
10
    ]
11

  
12
    operations = [
13
        migrations.AddField(
14
            model_name='agenda',
15
            name='booking_user_block_template',
16
            field=models.TextField(
17
                blank=True,
18
                help_text='Displayed for each booking in event check page',
19
                verbose_name='User block template',
20
                validators=[chrono.agendas.models.django_template_validator],
21
            ),
22
        ),
23
    ]
chrono/agendas/models.py
204 204
        _('Booking form URL'), max_length=200, blank=True, validators=[django_template_validator]
205 205
    )
206 206
    desk_simple_management = models.BooleanField(default=False)
207
    booking_user_block_template = models.TextField(
208
        _('User block template'),
209
        help_text=_('Displayed for each booking in event check page'),
210
        blank=True,
211
        validators=[django_template_validator],
212
    )
207 213

  
208 214
    class Meta:
209 215
        ordering = ['label']
......
714 720
        except (VariableDoesNotExist, TemplateSyntaxError):
715 721
            return
716 722

  
723
    def get_booking_user_block_template(self):
724
        return (
725
            self.booking_user_block_template
726
            or '{{ booking.user_name|default:booking.label|default:"%s" }}' % _('Unknown')
727
        )
728

  
717 729
    def get_recurrence_exceptions(self, min_start, max_start):
718 730
        return TimePeriodException.objects.filter(
719 731
            Q(desk__slug='_exceptions_holder', desk__agenda=self)
......
1637 1649
            self.secondary_booking_set.update(in_waiting_list=True)
1638 1650
            self.save()
1639 1651

  
1652
    def get_user_block(self):
1653
        template_vars = Context(settings.TEMPLATE_VARS)
1654
        template_vars.update(
1655
            {
1656
                'booking': self,
1657
            }
1658
        )
1659
        try:
1660
            return Template(self.event.agenda.get_booking_user_block_template()).render(template_vars)
1661
        except (VariableDoesNotExist, TemplateSyntaxError):
1662
            return
1663

  
1640 1664
    @classmethod
1641 1665
    def anonymize_bookings(cls, bookings_queryset):
1642 1666
        bookings_queryset.update(
chrono/manager/forms.py
27 27
from django.forms import ValidationError
28 28
from django.utils.encoding import force_text
29 29
from django.utils.six import StringIO
30
from django.utils.timezone import make_aware, make_naive, now
30
from django.utils.timezone import make_aware, now
31 31
from django.utils.translation import ugettext_lazy as _
32 32

  
33 33
from chrono.agendas.models import (
34 34
    WEEKDAYS_LIST,
35
    AbsenceReason,
35
    AbsenceReasonGroup,
36 36
    Agenda,
37 37
    AgendaNotificationsSettings,
38 38
    AgendaReminderSettings,
......
729 729
        fields = []
730 730

  
731 731

  
732
class AgendaBookingCheckSettingsForm(forms.ModelForm):
733
    class Meta:
734
        model = Agenda
735
        fields = ['absence_reasons_group', 'booking_user_block_template']
736
        widgets = {'booking_user_block_template': forms.Textarea(attrs={'rows': 3})}
737

  
738
    def __init__(self, *args, **kwargs):
739
        super().__init__(*args, **kwargs)
740
        if not AbsenceReasonGroup.objects.exists():
741
            del self.fields['absence_reasons_group']
742

  
743

  
732 744
class AgendaNotificationsForm(forms.ModelForm):
733 745
    class Meta:
734 746
        model = AgendaNotificationsSettings
chrono/manager/templates/chrono/manager_event_check.html
55 55
  <h3>
56 56
    {% blocktrans with places=object.waiting_list_places booked_places=waiting|length %}Waiting List ({{ booked_places }}/{{ places }}){% endblocktrans %}
57 57
  </h3>
58
<div>
59
  <ul class="objects-list single-links">
60
    {% for booking in waiting %}
61
    <li><a>{{ booking.user_name|default:booking.label|default:_('Unknown') }}</a></li>
62
    {% endfor %}
63
  </ul>
64
</div>
58
  <div>
59
    <table class="main check-bookings">
60
      <tbody>
61
        {% for booking in waiting %}
62
        <tr><td class="booking-username">{{ booking.get_user_block }}</td></tr>
63
        {% endfor %}
64
      </tbody>
65
    </table>
66
  </div>
65 67
</div>
66 68
{% endif %}
67 69
{% endblock %}
chrono/manager/templates/chrono/manager_event_check_booking_fragment.html
1 1
{% load i18n %}
2 2

  
3
<td class="booking-username">{{ booking.user_name|default:booking.label|default:_('Unknown') }}</td>
3
<td class="booking-username">{{ booking.get_user_block }}</td>
4 4
<td class="booking-status {% if booking.user_was_present is None %}without-status{% endif %}">
5 5
  {{ booking.user_was_present|yesno:_('Present,Absent,-') }}
6 6
  {% if booking.user_was_present is False and booking.user_absence_reason %}
chrono/manager/templates/chrono/manager_events_agenda_settings.html
30 30
</div>
31 31
</div>
32 32

  
33
{% if has_absence_reasons %}
34 33
<div class="section">
35
<h3>{% trans "Absence reasons" %}
36
<a rel="popup" class="button" href="{% url 'chrono-manager-agenda-absence-reasons' pk=object.id %}">{% trans 'Configure' %}</a>
34
<h3>{% trans "Booking check options" %}
35
    <a rel="popup" class="button" href="{% url 'chrono-manager-agenda-booking-check-settings' pk=object.pk %}">{% trans 'Configure' %}</a>
37 36
</h3>
38 37
<div>
39
{% if agenda.absence_reasons_group %}
40
<p>{% trans "Absence reasons group:" %} {{ agenda.absence_reasons_group }}</p>
41
<ul>
42
  {% for reason in agenda.absence_reasons_group.absence_reasons.all %}
43
  <li>{{ reason }}</li>
44
  {% endfor %}
45
</ul>
46
{% else %}
47
<p>{% trans "No absence reasons configured for this agenda." %}</p>
48
{% endif %}
38
    {% if has_absence_reasons %}
39
        {% if agenda.absence_reasons_group %}
40
        <p>{% trans "Absence reasons group:" %} {{ agenda.absence_reasons_group }}</p>
41
        <ul>
42
          {% for reason in agenda.absence_reasons_group.absence_reasons.all %}
43
          <li>{{ reason }}</li>
44
          {% endfor %}
45
        </ul>
46
        {% else %}
47
        <p>{% trans "No absence reasons configured for this agenda." %}</p>
48
        {% endif %}
49
    {% endif %}
50

  
51
    <p>{% trans "User block template" %}:</p>
52
    <pre>{{ agenda.get_booking_user_block_template }}</pre>
49 53
</div>
50 54
</div>
51
{% endif %}
52 55

  
53 56
<div class="section">
54 57
<h3>{% trans "Notifications" %}
chrono/manager/urls.py
148 148
    ),
149 149
    url(r'^agendas/(?P<pk>\d+)/roles$', views.agenda_roles, name='chrono-manager-agenda-roles'),
150 150
    url(
151
        r'^agendas/(?P<pk>\d+)/absence-reasons$',
152
        views.agenda_absence_reasons,
153
        name='chrono-manager-agenda-absence-reasons',
151
        r'^agendas/(?P<pk>\d+)/check-options$',
152
        views.agenda_booking_check_settings,
153
        name='chrono-manager-agenda-booking-check-settings',
154 154
    ),
155 155
    url(r'^agendas/(?P<pk>\d+)/delete$', views.agenda_delete, name='chrono-manager-agenda-delete'),
156 156
    url(r'^agendas/(?P<pk>\d+)/export$', views.agenda_export, name='chrono-manager-agenda-export'),
chrono/manager/views.py
77 77

  
78 78
from .forms import (
79 79
    AgendaAddForm,
80
    AgendaBookingCheckSettingsForm,
80 81
    AgendaBookingDelaysForm,
81 82
    AgendaDuplicateForm,
82 83
    AgendaEditForm,
......
912 913
agenda_roles = AgendaRolesView.as_view()
913 914

  
914 915

  
915
class AgendaAbsenceReasonsView(AgendaEditView):
916
    form_class = None
917
    fields = ['absence_reasons_group']
918
    title = _('Configure absence reasons')
916
class AgendaBookingCheckSettingsView(AgendaEditView):
917
    form_class = AgendaBookingCheckSettingsForm
918
    title = _("Configure booking check options")
919 919

  
920 920
    def set_agenda(self, **kwargs):
921 921
        self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'), kind='events')
922 922

  
923
    def get_initial(self):
924
        return {'booking_user_block_template': self.agenda.get_booking_user_block_template()}
923 925

  
924
agenda_absence_reasons = AgendaAbsenceReasonsView.as_view()
926

  
927
agenda_booking_check_settings = AgendaBookingCheckSettingsView.as_view()
925 928

  
926 929

  
927 930
class AgendaDeleteView(DeleteView):
tests/manager/test_absence_reason.py
198 198
    resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
199 199
    assert 'has_absence_reasons' in resp.context
200 200
    assert resp.context['has_absence_reasons'] is False
201
    assert 'Absence reasons' not in resp
201
    assert 'No absence reasons configured for this agenda.' not in resp
202 202
    assert '/manage/agendas/%s/absence-reasons' % agenda.pk not in resp
203
    resp = resp.click(href='/manage/agendas/%s/check-options' % agenda.pk)
204
    assert 'absence_reasons_group' not in resp.context['form'].fields
203 205

  
204 206
    group = AbsenceReasonGroup.objects.create(label='Foo bar')
205 207
    resp = app.get('/manage/agendas/%s/settings' % agenda.pk)
206 208
    assert 'has_absence_reasons' in resp.context
207 209
    assert resp.context['has_absence_reasons'] is True
208
    assert 'Absence reasons' in resp
209 210
    assert 'No absence reasons configured for this agenda.' in resp
210
    resp = resp.click(href='/manage/agendas/%s/absence-reasons' % agenda.pk)
211
    resp = resp.click(href='/manage/agendas/%s/check-options' % agenda.pk)
211 212
    resp.form['absence_reasons_group'] = group.pk
212 213
    resp = resp.form.submit().follow()
213 214
    assert 'Absence reasons group: Foo bar' in resp
tests/manager/test_all.py
507 507
    assert agenda.minimal_booking_delay == 1
508 508

  
509 509

  
510
def test_options_virtuale_agenda_can_unset_delays(app, admin_user):
510
def test_options_virtual_agenda_can_unset_delays(app, admin_user):
511 511
    agenda = Agenda.objects.create(label=u'Foo bar', kind='virtual', maximal_booking_delay=2)
512 512
    assert agenda.maximal_booking_delay == 2
513 513
    app = login(app)
......
519 519
    assert agenda.maximal_booking_delay is None
520 520

  
521 521

  
522
def test_options_agenda_booking_user_block_template(app, admin_user):
523
    agenda = Agenda.objects.create(label='Foo bar', kind='events')
524
    assert agenda.booking_user_block_template == ''
525
    assert (
526
        agenda.get_booking_user_block_template()
527
        == '{{ booking.user_name|default:booking.label|default:"Unknown" }}'
528
    )
529

  
530
    app = login(app)
531
    url = '/manage/agendas/%s/check-options' % agenda.pk
532
    resp = app.get(url)
533
    resp.form['booking_user_block_template'] = '{{ booking.user_name }} Foo Bar'
534
    resp = resp.form.submit()
535
    agenda.refresh_from_db()
536
    assert agenda.booking_user_block_template == '{{ booking.user_name }} Foo Bar'
537
    assert agenda.get_booking_user_block_template() == '{{ booking.user_name }} Foo Bar'
538

  
539
    resp = app.get(url)
540
    resp.form['booking_user_block_template'] = ''
541
    resp = resp.form.submit()
542
    agenda.refresh_from_db()
543
    assert agenda.booking_user_block_template == ''
544
    assert (
545
        agenda.get_booking_user_block_template()
546
        == '{{ booking.user_name|default:booking.label|default:"Unknown" }}'
547
    )
548

  
549
    # check kind
550
    agenda.kind = 'meetings'
551
    agenda.save()
552
    app.get(url, status=404)
553
    agenda.kind = 'virtual'
554
    agenda.save()
555
    app.get(url, status=404)
556

  
557

  
522 558
def test_options_agenda_as_manager(app, manager_user):
523 559
    agenda = Agenda(label=u'Foo bar')
524 560
    agenda.view_role = manager_user.groups.all()[0]
tests/manager/test_event.py
1108 1108
    )  # user ordering is not optimal ...
1109 1109
    assert 'User Cancelled' not in resp
1110 1110

  
1111
    agenda.booking_user_block_template = '{{ booking.user_name }} Foo Bar'
1112
    agenda.save()
1113
    resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
1114
    assert 'User 1 Foo Bar' in resp
1115
    assert 'User Waiting Foo Bar' in resp
1116

  
1111 1117
    # cancelled booking
1112 1118
    token = resp.context['csrf_token']
1113 1119
    app.post(
1114
-