agenda: option to have min delay in working days (#55049)
This commit is contained in:
parent
bd51c5138a
commit
eb2f8b8d48
|
@ -1,5 +1,3 @@
|
|||
# Generated by Django 2.2.19 on 2021-05-19 12:23
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
import chrono.agendas.models
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('agendas', '0096_checked'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='agenda',
|
||||
name='minimal_booking_delay_in_working_days',
|
||||
field=models.BooleanField(default=False, verbose_name='Minimal booking delay in working days'),
|
||||
),
|
||||
]
|
|
@ -164,6 +164,10 @@ class Agenda(models.Model):
|
|||
blank=True,
|
||||
validators=[MaxValueValidator(10000)],
|
||||
)
|
||||
minimal_booking_delay_in_working_days = models.BooleanField(
|
||||
_('Minimal booking delay in working days'),
|
||||
default=False,
|
||||
)
|
||||
maximal_booking_delay = models.PositiveIntegerField(
|
||||
_('Maximal booking delay (in days)'),
|
||||
default=None,
|
||||
|
@ -392,6 +396,7 @@ class Agenda(models.Model):
|
|||
self.absence_reasons_group.slug if self.absence_reasons_group else None
|
||||
)
|
||||
agenda['exceptions_desk'] = self.desk_set.get().export_json()
|
||||
agenda['minimal_booking_delay_in_working_days'] = self.minimal_booking_delay_in_working_days
|
||||
elif self.kind == 'meetings':
|
||||
agenda['meetingtypes'] = [x.export_json() for x in self.meetingtype_set.filter(deleted=False)]
|
||||
agenda['desks'] = [desk.export_json() for desk in self.desk_set.all()]
|
||||
|
@ -613,9 +618,16 @@ class Agenda(models.Model):
|
|||
# compute middle of today with localtime
|
||||
# 28 Mar 2021 12:00 +01:00
|
||||
t = localtime(now()).replace(hour=12, minute=0)
|
||||
# advance of self.maximal_booking_delay - 1 days
|
||||
|
||||
# advance of self.minimal_booking_delay - 1 days
|
||||
# 28 Mar 2021 12:00 +01:00 == 28 Mars 2021 13:00 +02:00 as DST happend on 28 Mar 2021.
|
||||
t += datetime.timedelta(days=self.minimal_booking_delay)
|
||||
if settings.WORKING_DAY_CALENDAR is not None and self.minimal_booking_delay_in_working_days:
|
||||
source_class = import_string(settings.WORKING_DAY_CALENDAR)
|
||||
calendar = source_class()
|
||||
t = calendar.add_working_days(t, self.minimal_booking_delay, keep_datetime=True)
|
||||
else:
|
||||
t += datetime.timedelta(days=self.minimal_booking_delay)
|
||||
|
||||
# move to midnight of the day before, DST happen between 2h/3h so it
|
||||
# always exists because +/- timedelta does not move the timezone, only
|
||||
# localtime() does it.
|
||||
|
|
|
@ -121,6 +121,7 @@ class AgendaBookingDelaysForm(forms.ModelForm):
|
|||
model = Agenda
|
||||
fields = [
|
||||
'minimal_booking_delay',
|
||||
'minimal_booking_delay_in_working_days',
|
||||
'maximal_booking_delay',
|
||||
]
|
||||
|
||||
|
@ -129,6 +130,8 @@ class AgendaBookingDelaysForm(forms.ModelForm):
|
|||
if kwargs['instance'].kind != 'virtual':
|
||||
self.fields['minimal_booking_delay'].required = True
|
||||
self.fields['maximal_booking_delay'].required = True
|
||||
if kwargs['instance'].kind != 'events' or settings.WORKING_DAY_CALENDAR is None:
|
||||
del self.fields['minimal_booking_delay_in_working_days']
|
||||
|
||||
|
||||
class AgendaRolesForm(AgendaAddForm):
|
||||
|
|
|
@ -85,10 +85,16 @@
|
|||
<div>
|
||||
<ul>
|
||||
<li>{% trans "Minimal booking delay:" %}
|
||||
{% if agenda.minimal_booking_delay is not None %}{{ agenda.minimal_booking_delay }} {% trans "days" %}
|
||||
{% if agenda.minimal_booking_delay is not None %}
|
||||
{% if agenda.minimal_booking_delay_in_working_days %}
|
||||
{% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} working day{% plural %}{{ count }} working days{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans count count=agenda.minimal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
|
||||
{% endif %}
|
||||
{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
|
||||
<li>{% trans "Maximal booking delay:" %}
|
||||
{% if agenda.maximal_booking_delay is not None %}{{ agenda.maximal_booking_delay }} {% trans "days" %}
|
||||
{% if agenda.maximal_booking_delay is not None %}
|
||||
{% blocktrans count count=agenda.maximal_booking_delay %}{{ count }} day{% plural %}{{ count }} days{% endblocktrans %}
|
||||
{% else %}<i>{% trans "undefined" %}</i>{% endif %}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -176,10 +176,12 @@ REQUESTS_TIMEOUT = 28
|
|||
try:
|
||||
import workalendar
|
||||
|
||||
WORKING_DAY_CALENDAR = 'workalendar.europe.France'
|
||||
EXCEPTIONS_SOURCES = {
|
||||
'holidays': {'class': 'workalendar.europe.France', 'label': _('Holidays')},
|
||||
'holidays': {'class': WORKING_DAY_CALENDAR, 'label': _('Holidays')},
|
||||
}
|
||||
except ImportError:
|
||||
WORKING_DAY_CALENDAR = None
|
||||
EXCEPTIONS_SOURCES = {}
|
||||
|
||||
TEMPLATE_VARS = {}
|
||||
|
|
|
@ -499,27 +499,50 @@ def test_options_agenda(app, admin_user):
|
|||
assert 'open_events' not in [k for k, v in resp.context['form'].fields['default_view'].choices]
|
||||
|
||||
|
||||
def test_options_agenda_cant_unset_delays(app, admin_user):
|
||||
def test_options_events_agenda_delays(settings, app, admin_user):
|
||||
settings.WORKING_DAY_CALENDAR = None
|
||||
agenda = Agenda.objects.create(label=u'Foo bar')
|
||||
assert agenda.minimal_booking_delay == 1
|
||||
app = login(app)
|
||||
url = '/manage/agendas/%s/booking-delays' % agenda.pk
|
||||
resp = app.get(url)
|
||||
assert 'minimal_booking_delay_in_working_days' not in resp.context['form'].fields
|
||||
resp.form['minimal_booking_delay'] = None
|
||||
resp = resp.form.submit()
|
||||
agenda = Agenda.objects.get(label=u'Foo bar')
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.minimal_booking_delay == 1
|
||||
|
||||
settings.WORKING_DAY_CALENDAR = 'workalendar.europe.France'
|
||||
resp = app.get(url)
|
||||
resp.form['minimal_booking_delay_in_working_days'] = True
|
||||
resp = resp.form.submit()
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.minimal_booking_delay_in_working_days is True
|
||||
|
||||
def test_options_virtual_agenda_can_unset_delays(app, admin_user):
|
||||
|
||||
def test_options_meetings_agenda_delays(app, admin_user):
|
||||
agenda = Agenda.objects.create(label=u'Foo bar', kind='meetings', maximal_booking_delay=2)
|
||||
assert agenda.maximal_booking_delay == 2
|
||||
app = login(app)
|
||||
url = '/manage/agendas/%s/booking-delays' % agenda.pk
|
||||
resp = app.get(url)
|
||||
assert 'minimal_booking_delay_in_working_days' not in resp.context['form'].fields
|
||||
resp.form['maximal_booking_delay'] = None
|
||||
resp = resp.form.submit()
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.maximal_booking_delay == 2
|
||||
|
||||
|
||||
def test_options_virtual_agenda_delays(app, admin_user):
|
||||
agenda = Agenda.objects.create(label=u'Foo bar', kind='virtual', maximal_booking_delay=2)
|
||||
assert agenda.maximal_booking_delay == 2
|
||||
app = login(app)
|
||||
url = '/manage/agendas/%s/booking-delays' % agenda.pk
|
||||
resp = app.get(url)
|
||||
assert 'minimal_booking_delay_in_working_days' not in resp.context['form'].fields
|
||||
resp.form['maximal_booking_delay'] = None
|
||||
resp = resp.form.submit()
|
||||
agenda = Agenda.objects.get(label=u'Foo bar')
|
||||
agenda.refresh_from_db()
|
||||
assert agenda.maximal_booking_delay is None
|
||||
|
||||
|
||||
|
|
|
@ -196,6 +196,27 @@ def test_absence_reason_group_duplicate_slugs():
|
|||
assert group.slug == 'foo-baz-2'
|
||||
|
||||
|
||||
@pytest.mark.freeze_time('2021-07-09')
|
||||
def test_agenda_minimal_booking_delay_in_working_days(settings):
|
||||
agenda = Agenda.objects.create(label='Agenda', minimal_booking_delay=1)
|
||||
|
||||
settings.WORKING_DAY_CALENDAR = None
|
||||
agenda.minimal_booking_delay_in_working_days = True
|
||||
agenda.save()
|
||||
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)
|
||||
agenda.minimal_booking_delay_in_working_days = False
|
||||
agenda.save()
|
||||
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)
|
||||
|
||||
settings.WORKING_DAY_CALENDAR = 'workalendar.europe.France'
|
||||
agenda.minimal_booking_delay_in_working_days = True
|
||||
agenda.save()
|
||||
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 12)
|
||||
agenda.minimal_booking_delay_in_working_days = False
|
||||
agenda.save()
|
||||
assert agenda.min_booking_datetime.date() == datetime.date(2021, 7, 10)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('with_prefetch', [True, False])
|
||||
def test_agenda_is_available_for_simple_management(settings, with_prefetch):
|
||||
settings.EXCEPTIONS_SOURCES = {
|
||||
|
|
|
@ -150,6 +150,7 @@ def test_import_export_events_agenda_options(app):
|
|||
kind='events',
|
||||
default_view='open_events',
|
||||
booking_form_url='{{ eservices_url }}backoffice/submission/inscription-aux-activites/',
|
||||
minimal_booking_delay_in_working_days=True,
|
||||
)
|
||||
Desk.objects.create(agenda=agenda, slug='_exceptions_holder')
|
||||
|
||||
|
@ -166,6 +167,7 @@ def test_import_export_events_agenda_options(app):
|
|||
agenda = Agenda.objects.first()
|
||||
assert agenda.default_view == 'open_events'
|
||||
assert agenda.booking_form_url == '{{ eservices_url }}backoffice/submission/inscription-aux-activites/'
|
||||
assert agenda.minimal_booking_delay_in_working_days is True
|
||||
|
||||
|
||||
def test_import_export_event_details(app):
|
||||
|
|
Loading…
Reference in New Issue