Projet

Général

Profil

0001-agenda-option-to-have-min-delay-in-working-days-5504.patch

Lauréline Guérin, 05 juillet 2021 16:05

Télécharger (11,7 ko)

Voir les différences:

Subject: [PATCH] agenda: option to have min delay in working days (#55049)

 .../0089_agenda_event_display_template.py     | 13 ++++++--
 .../0096_min_booking_delay_working_days.py    | 16 ++++++++++
 chrono/agendas/models.py                      | 18 +++++++++--
 chrono/manager/forms.py                       |  3 ++
 .../chrono/manager_agenda_settings.html       | 10 ++++--
 chrono/settings.py                            |  4 ++-
 tests/manager/test_all.py                     | 31 ++++++++++++++++---
 tests/test_agendas.py                         | 21 +++++++++++++
 8 files changed, 103 insertions(+), 13 deletions(-)
 create mode 100644 chrono/agendas/migrations/0096_min_booking_delay_working_days.py
chrono/agendas/migrations/0089_agenda_event_display_template.py
1
# Generated by Django 2.2.19 on 2021-05-19 12:23
2

  
3 1
from django.db import migrations, models
4 2

  
3
import chrono.agendas.models
4

  
5 5

  
6 6
class Migration(migrations.Migration):
7 7

  
......
15 15
            name='event_display_template',
16 16
            field=models.CharField(
17 17
                blank=True,
18
                help_text='By default event labels will be displayed to users. This allows for a custom template to include additional informations. For example, "{{ event.label }} - {{ event.start_datetime }}" will show event datetime after label. Available variables: event.label (label), event.start_datetime (start date/time), event.places (places), event.remaining_places (remaining places), event.duration (duration), event.pricing (pricing).',
18
                help_text=(
19
                    'By default event labels will be displayed to users. '
20
                    'This allows for a custom template to include additional informations. '
21
                    'For example, "{{ event.label }} - {{ event.start_datetime }}" will show event datetime after label. '
22
                    'Available variables: event.label (label), event.start_datetime (start date/time), event.places (places), '
23
                    'event.remaining_places (remaining places), event.duration (duration), event.pricing (pricing).'
24
                ),
19 25
                max_length=256,
26
                validators=[chrono.agendas.models.event_template_validator],
20 27
                verbose_name='Event display template',
21 28
            ),
22 29
        ),
chrono/agendas/migrations/0096_min_booking_delay_working_days.py
1
from django.db import migrations, models
2

  
3

  
4
class Migration(migrations.Migration):
5

  
6
    dependencies = [
7
        ('agendas', '0095_checked'),
8
    ]
9

  
10
    operations = [
11
        migrations.AddField(
12
            model_name='agenda',
13
            name='minimal_booking_delay_in_working_days',
14
            field=models.BooleanField(default=False, verbose_name='Minimal booking delay in working days'),
15
        ),
16
    ]
chrono/agendas/models.py
164 164
        blank=True,
165 165
        validators=[MaxValueValidator(10000)],
166 166
    )
167
    minimal_booking_delay_in_working_days = models.BooleanField(
168
        _('Minimal booking delay in working days'),
169
        default=False,
170
    )
167 171
    maximal_booking_delay = models.PositiveIntegerField(
168 172
        _('Maximal booking delay (in days)'),
169 173
        default=None,
......
610 614
        # compute middle of today with localtime
611 615
        # 28 Mar 2021 12:00 +01:00
612 616
        t = localtime(now()).replace(hour=12, minute=0)
613
        # advance of self.maximal_booking_delay - 1 days
614
        # 28 Mar 2021 12:00 +01:00 == 28 Mars 2021 13:00 +02:00 as DST happend on 28 Mar 2021.
615
        t += datetime.timedelta(days=self.minimal_booking_delay)
617

  
618
        if settings.WORKING_DAY_CALENDAR is not None and self.minimal_booking_delay_in_working_days:
619
            source_class = import_string(settings.WORKING_DAY_CALENDAR)
620
            calendar = source_class()
621
            t = calendar.add_working_days(t, self.minimal_booking_delay)
622
            t = make_aware(datetime.datetime.combine(t, datetime.time(12, 0)))
623
        else:
624
            # advance of self.maximal_booking_delay - 1 days
625
            # 28 Mar 2021 12:00 +01:00 == 28 Mars 2021 13:00 +02:00 as DST happend on 28 Mar 2021.
626
            t += datetime.timedelta(days=self.minimal_booking_delay)
627

  
616 628
        # move to midnight of the day before, DST happen between 2h/3h so it
617 629
        # always exists because +/- timedelta does not move the timezone, only
618 630
        # localtime() does it.
chrono/manager/forms.py
121 121
        model = Agenda
122 122
        fields = [
123 123
            'minimal_booking_delay',
124
            'minimal_booking_delay_in_working_days',
124 125
            'maximal_booking_delay',
125 126
        ]
126 127

  
......
129 130
        if kwargs['instance'].kind != 'virtual':
130 131
            self.fields['minimal_booking_delay'].required = True
131 132
            self.fields['maximal_booking_delay'].required = True
133
        if kwargs['instance'].kind != 'events' or settings.WORKING_DAY_CALENDAR is None:
134
            del self.fields['minimal_booking_delay_in_working_days']
132 135

  
133 136

  
134 137
class AgendaRolesForm(AgendaAddForm):
chrono/manager/templates/chrono/manager_agenda_settings.html
85 85
<div>
86 86
<ul>
87 87
  <li>{% trans "Minimal booking delay:" %}
88
      {% if agenda.minimal_booking_delay is not None %}{{ agenda.minimal_booking_delay }} {% trans "days" %}
88
      {% if agenda.minimal_booking_delay is not None %}
89
        {% if agenda.minimal_booking_delay_in_working_days %}
90
        {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} working day{% plural %}{{ count }} working days{% endblocktrans %}
91
        {% else %}
92
        {% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
93
        {% endif %}
89 94
      {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
90 95
  <li>{% trans "Maximal booking delay:" %}
91
      {% if agenda.maximal_booking_delay is not None %}{{ agenda.maximal_booking_delay }} {% trans "days" %}
96
      {% if agenda.maximal_booking_delay is not None %}
97
        {% blocktrans count count=agenda.maximal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
92 98
      {% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
93 99
</ul>
94 100
</div>
chrono/settings.py
176 176
try:
177 177
    import workalendar
178 178

  
179
    WORKING_DAY_CALENDAR = 'workalendar.europe.France'
179 180
    EXCEPTIONS_SOURCES = {
180
        'holidays': {'class': 'workalendar.europe.France', 'label': _('Holidays')},
181
        'holidays': {'class': WORKING_DAY_CALENDAR, 'label': _('Holidays')},
181 182
    }
182 183
except ImportError:
184
    WORKING_DAY_CALENDAR = None
183 185
    EXCEPTIONS_SOURCES = {}
184 186

  
185 187
TEMPLATE_VARS = {}
tests/manager/test_all.py
499 499
    assert 'open_events' not in [k for k, v in resp.context['form'].fields['default_view'].choices]
500 500

  
501 501

  
502
def test_options_agenda_cant_unset_delays(app, admin_user):
502
def test_options_events_agenda_delays(settings, app, admin_user):
503
    settings.WORKING_DAY_CALENDAR = None
503 504
    agenda = Agenda.objects.create(label=u'Foo bar')
504 505
    assert agenda.minimal_booking_delay == 1
505 506
    app = login(app)
506 507
    url = '/manage/agendas/%s/booking-delays' % agenda.pk
507 508
    resp = app.get(url)
509
    assert 'minimal_booking_delay_in_working_days' not in resp.context['form'].fields
508 510
    resp.form['minimal_booking_delay'] = None
509 511
    resp = resp.form.submit()
510
    agenda = Agenda.objects.get(label=u'Foo bar')
512
    agenda.refresh_from_db()
511 513
    assert agenda.minimal_booking_delay == 1
512 514

  
515
    settings.WORKING_DAY_CALENDAR = 'workalendar.europe.France'
516
    resp = app.get(url)
517
    resp.form['minimal_booking_delay_in_working_days'] = True
518
    resp = resp.form.submit()
519
    agenda.refresh_from_db()
520
    assert agenda.minimal_booking_delay_in_working_days is True
521

  
522

  
523
def test_options_meetings_agenda_delays(app, admin_user):
524
    agenda = Agenda.objects.create(label=u'Foo bar', kind='meetings', maximal_booking_delay=2)
525
    assert agenda.maximal_booking_delay == 2
526
    app = login(app)
527
    url = '/manage/agendas/%s/booking-delays' % agenda.pk
528
    resp = app.get(url)
529
    assert 'minimal_booking_delay_in_working_days' not in resp.context['form'].fields
530
    resp.form['maximal_booking_delay'] = None
531
    resp = resp.form.submit()
532
    agenda.refresh_from_db()
533
    assert agenda.maximal_booking_delay == 2
534

  
513 535

  
514
def test_options_virtual_agenda_can_unset_delays(app, admin_user):
536
def test_options_virtual_agenda_delays(app, admin_user):
515 537
    agenda = Agenda.objects.create(label=u'Foo bar', kind='virtual', maximal_booking_delay=2)
516 538
    assert agenda.maximal_booking_delay == 2
517 539
    app = login(app)
518 540
    url = '/manage/agendas/%s/booking-delays' % agenda.pk
519 541
    resp = app.get(url)
542
    assert 'minimal_booking_delay_in_working_days' not in resp.context['form'].fields
520 543
    resp.form['maximal_booking_delay'] = None
521 544
    resp = resp.form.submit()
522
    agenda = Agenda.objects.get(label=u'Foo bar')
545
    agenda.refresh_from_db()
523 546
    assert agenda.maximal_booking_delay is None
524 547

  
525 548

  
tests/test_agendas.py
196 196
    assert group.slug == 'foo-baz-2'
197 197

  
198 198

  
199
@pytest.mark.freeze_time('2021-07-09')
200
def test_agenda_minimal_booking_delay_in_working_days(settings):
201
    agenda = Agenda.objects.create(label='Agenda', minimal_booking_delay=1)
202

  
203
    settings.WORKING_DAY_CALENDAR = None
204
    agenda.minimal_booking_delay_in_working_days = True
205
    agenda.save()
206
    assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)
207
    agenda.minimal_booking_delay_in_working_days = False
208
    agenda.save()
209
    assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)
210

  
211
    settings.WORKING_DAY_CALENDAR = 'workalendar.europe.France'
212
    agenda.minimal_booking_delay_in_working_days = True
213
    agenda.save()
214
    assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 12)
215
    agenda.minimal_booking_delay_in_working_days = False
216
    agenda.save()
217
    assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)
218

  
219

  
199 220
@pytest.mark.parametrize('with_prefetch', [True, False])
200 221
def test_agenda_is_available_for_simple_management(settings, with_prefetch):
201 222
    settings.EXCEPTIONS_SOURCES = {
202
-