Facturation: avoir un flag sur Event pour noter que l'événement est verrouillé (#75416) #56

Merged
lguerin merged 2 commits from wip/75416-event-lock-check into main 2023-04-03 16:27:27 +02:00
11 changed files with 462 additions and 31 deletions

View File

@ -0,0 +1,15 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('agendas', '0149_booking_extra_user_block'),
]
operations = [
migrations.AddField(
model_name='event',
name='check_locked',
field=models.BooleanField(default=False),
),
]

View File

@ -1521,6 +1521,7 @@ class Event(models.Model):
cancelled = models.BooleanField(default=False)
cancellation_scheduled = models.BooleanField(default=False)
checked = models.BooleanField(default=False)
check_locked = models.BooleanField(default=False)
meeting_type = models.ForeignKey(MeetingType, null=True, on_delete=models.CASCADE)
desk = models.ForeignKey('Desk', null=True, on_delete=models.CASCADE)
resources = models.ManyToManyField('Resource')

View File

@ -157,6 +157,18 @@ class MultipleAgendasEventsCheckStatusSerializer(AgendaSlugsMixin, DateRangeMixi
return get_objects_from_slugs(value, qs=self.get_agenda_qs())
class MultipleAgendasEventsCheckLockSerializer(AgendaSlugsMixin, DateRangeMixin, serializers.Serializer):
check_locked = serializers.BooleanField()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in ['agendas', 'date_start', 'date_end', 'check_locked']:
self.fields[field].required = True
def validate_agendas(self, value):
return get_objects_from_slugs(value, qs=self.get_agenda_qs())
class RecurringFillslotsSerializer(MultipleAgendasEventsFillSlotsSerializer):
include_booked_events_detail = serializers.BooleanField(default=False)
check_overlaps = CommaSeparatedStringField(
@ -437,8 +449,10 @@ class EventSerializer(serializers.ModelSerializer):
'url',
'primary_event',
'agenda',
'checked',
'check_locked',
]
read_only_fields = ['slug']
read_only_fields = ['slug', 'checked', 'check_locked']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

View File

@ -38,6 +38,11 @@ urlpatterns = [
views.agendas_events_check_status,
name='api-agendas-events-check-status',
),
path(
'agendas/events/check-lock/',
views.agendas_events_check_lock,
name='api-agendas-events-check-lock',
),
re_path(r'^agenda/(?P<agenda_identifier>[\w-]+)/$', views.agenda),
re_path(
r'^agenda/(?P<agenda_identifier>[\w-]+)/datetimes/$', views.datetimes, name='api-agenda-datetimes'

View File

@ -502,6 +502,7 @@ def get_event_detail(
'url': event.url,
'duration': event.duration,
'checked': event.checked,
'check_locked': event.check_locked,
}
for key, value in event.get_custom_fields().items():
details['custom_field_%s' % key] = value
@ -2296,6 +2297,35 @@ class MultipleAgendasEventsCheckStatus(APIView):
agendas_events_check_status = MultipleAgendasEventsCheckStatus.as_view()
class MultipleAgendasEventsCheckLock(APIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = serializers.MultipleAgendasEventsCheckLockSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
if not serializer.is_valid():
raise APIErrorBadRequest(N_('invalid payload'), errors=serializer.errors, err=1)
agendas = serializer.validated_data['agendas']
date_start = serializer.validated_data['date_start']
date_end = serializer.validated_data['date_end']
check_locked = serializer.validated_data['check_locked']
events = Event.objects.filter(
agenda__in=agendas,
recurrence_days__isnull=True,
cancelled=False,
start_datetime__gte=date_start,
start_datetime__lt=date_end,
)
events.update(check_locked=check_locked)
return Response({'err': 0})
agendas_events_check_lock = MultipleAgendasEventsCheckLock.as_view()
class SubscriptionFilter(filters.FilterSet):
date_start = filters.DateFilter(method='do_nothing')
date_end = filters.DateFilter(method='do_nothing')

View File

@ -49,6 +49,9 @@
{% if event.main_list_full %}
<span class="full tag">{% trans "Full" %}</span>
{% endif %}
{% if event.check_locked %}
<span class="check-locked tag">{% trans "Check locked" %}</span>
{% endif %}
{% if event.checked %}
<span class="checked tag">{% trans "Checked" %}</span>
{% endif %}

View File

@ -16,7 +16,7 @@
({% trans "Cancelled" %})
{% endif %}
{% if not event.checked or not agenda.disable_check_update %}
{% if booking.user_was_present is not None %}
{% if booking.user_was_present is not None and not event.check_locked %}
<form method="post" action="{% url 'chrono-manager-booking-reset' pk=agenda.pk booking_pk=booking.pk %}" class="with-ajax reset">
{% csrf_token %}
<a href="#">{% trans "Reset" context "check" %}</a>
@ -33,45 +33,47 @@
{% endif %}
{% endif %}
</td>
{% if not event.checked or not agenda.disable_check_update %}
<td class="booking-actions" data-{{ booking.kind }}-id="{{ booking.id }}">
{% if not event.check_locked %}

le diff est vraiment très moche, en pratique c'est juste un ajout de {% if not event.check_locked %}...{% endif %}

le diff est vraiment très moche, en pratique c'est juste un ajout de {% if not event.check_locked %}...{% endif %}
{% if not event.checked or not agenda.disable_check_update %}
<td class="booking-actions" data-{{ booking.kind }}-id="{{ booking.id }}">
{% if booking.kind == "subscription" %}
<form method="post" action="{% url 'chrono-manager-subscription-presence' pk=agenda.pk subscription_pk=booking.pk event_pk=event.pk %}" class="with-ajax presence">
{% else %}
<form method="post" action="{% url 'chrono-manager-booking-presence' pk=agenda.pk booking_pk=booking.pk %}" class="with-ajax presence">
{% endif %}
{% csrf_token %}
<button class="submit-button"
{% if booking.user_was_present is True %}disabled{% endif %}
>{% trans "Presence" %}</button>
{% if booking.presence_form.check_type.field.choices.1 %}{{ booking.presence_form.check_type }}{% endif %}
<script>
$(function() {
$('td.booking-actions[data-{{ booking.kind }}-id="{{ booking.id }}"] form.presence select').on('change',
function() {
$(this).parents('form.presence').submit();
});
});
</script>
</form>
{% if booking.kind == "subscription" %}
<form method="post" action="{% url 'chrono-manager-subscription-presence' pk=agenda.pk subscription_pk=booking.pk event_pk=event.pk %}" class="with-ajax presence">
<form method="post" action="{% url 'chrono-manager-subscription-absence' pk=agenda.pk subscription_pk=booking.pk event_pk=event.pk %}" class="with-ajax absence">
{% else %}
<form method="post" action="{% url 'chrono-manager-booking-presence' pk=agenda.pk booking_pk=booking.pk %}" class="with-ajax presence">
<form method="post" action="{% url 'chrono-manager-booking-absence' pk=agenda.pk booking_pk=booking.pk %}" class="with-ajax absence">
{% endif %}
{% csrf_token %}
<button class="submit-button"
{% if booking.user_was_present is True %}disabled{% endif %}
>{% trans "Presence" %}</button>
{% if booking.presence_form.check_type.field.choices.1 %}{{ booking.presence_form.check_type }}{% endif %}
{% if booking.user_was_present is False %}disabled{% endif %}
>{% trans "Absence" %}</button>
{% if booking.absence_form.check_type.field.choices.1 %}{{ booking.absence_form.check_type }}{% endif %}
<script>
$(function() {
$('td.booking-actions[data-{{ booking.kind }}-id="{{ booking.id }}"] form.presence select').on('change',
$('td.booking-actions[data-{{ booking.kind }}-id="{{ booking.id }}"] form.absence select').on('change',
function() {
$(this).parents('form.presence').submit();
$(this).parents('form.absence').submit();
});
});
</script>
</form>
{% if booking.kind == "subscription" %}
<form method="post" action="{% url 'chrono-manager-subscription-absence' pk=agenda.pk subscription_pk=booking.pk event_pk=event.pk %}" class="with-ajax absence">
{% else %}
<form method="post" action="{% url 'chrono-manager-booking-absence' pk=agenda.pk booking_pk=booking.pk %}" class="with-ajax absence">
</form>
</td>
{% endif %}
{% csrf_token %}
<button class="submit-button"
{% if booking.user_was_present is False %}disabled{% endif %}
>{% trans "Absence" %}</button>
{% if booking.absence_form.check_type.field.choices.1 %}{{ booking.absence_form.check_type }}{% endif %}
<script>
$(function() {
$('td.booking-actions[data-{{ booking.kind }}-id="{{ booking.id }}"] form.absence select').on('change',
function() {
$(this).parents('form.absence').submit();
});
});
</script>
</form>
</td>
{% endif %}

View File

@ -27,6 +27,7 @@
<div class="event-title-meta">
{% if event.cancellation_status %}<span class="tag">{{ event.cancellation_status }}</span>{% endif %}
{% if event.main_list_full %}<span class="tag">{% trans "Full" %}</span>{% endif %}
{% if event.check_locked %}<span class="check-locked tag">{% trans "Check locked" %}</span>{% endif %}
{% if event.checked %}<span class="checked tag">{% trans "Checked" %}</span>{% endif %}
{% if event.is_day_past and not event.cancelled %}
{% if event.present_count %}<span class="meta meta-success">{% blocktrans with count=event.present_count %}Presents {{ count }}{% endblocktrans %}</span>{% endif %}

View File

@ -2671,6 +2671,7 @@ class EventCheckMixin:
pk=kwargs.get('event_pk'),
agenda=self.agenda,
cancelled=False,
check_locked=False,
)
def get_bookings(self):
@ -3495,6 +3496,7 @@ class BookingCheckMixin:
pk=kwargs['booking_pk'],
event__agenda=self.agenda,
event__cancelled=False,
event__check_locked=False,
in_waiting_list=False,
primary_booking__isnull=True,
)
@ -3596,6 +3598,7 @@ class SubscriptionCheckMixin(BookingCheckMixin):
Q(start_datetime__date__lte=now().date()) | Q(agenda__enable_check_for_future_events=True),
agenda=self.agenda,
cancelled=False,
check_locked=False,
pk=kwargs['event_pk'],
)
subscription = get_object_or_404(

View File

@ -54,6 +54,7 @@ def test_status(app, user):
'disabled': False,
'duration': None,
'checked': False,
'check_locked': False,
'api': {
'bookings_url': 'http://testserver/api/agenda/foo-bar/bookings/event-slug/',
'fillslot_url': 'http://testserver/api/agenda/foo-bar/fillslot/event-slug/',
@ -92,6 +93,7 @@ def test_status(app, user):
'disabled': False,
'duration': None,
'checked': False,
'check_locked': False,
'custom_field_text': 'foo',
'custom_field_textarea': 'foo bar',
'custom_field_bool': True,
@ -880,6 +882,7 @@ def test_events(app, user):
places=10,
agenda=agenda2,
checked=True,
check_locked=True,
)
# cancelled event, not returned
Event.objects.create(
@ -939,6 +942,8 @@ def test_events(app, user):
assert resp.json['data'] == [
{
'agenda': 'bar',
'check_locked': True,
'checked': True,
'description': None,
'duration': None,
'label': 'Event Label',
@ -956,6 +961,8 @@ def test_events(app, user):
},
{
'agenda': 'foo',
'check_locked': False,
'checked': False,
'description': None,
'duration': None,
'label': 'Recurring Event Label',
@ -973,6 +980,8 @@ def test_events(app, user):
},
{
'agenda': 'foo',
'check_locked': False,
'checked': False,
'description': None,
'duration': None,
'label': 'Recurring Event Label',
@ -1301,6 +1310,7 @@ def test_events_check_status_events(app, user):
places=10,
agenda=agenda,
checked=True,
check_locked=True,
)
# not checked event
notchecked_event = Event.objects.create(
@ -1366,6 +1376,8 @@ def test_events_check_status_events(app, user):
'waiting_list_places': 0,
'agenda': agenda.slug,
'primary_event': None,
'check_locked': False,
'checked': False,
'custom_field_bool': None,
'custom_field_text': '',
'custom_field_textarea': '',
@ -1390,6 +1402,8 @@ def test_events_check_status_events(app, user):
'waiting_list_places': 0,
'agenda': agenda.slug,
'primary_event': None,
'check_locked': True,
'checked': True,
'custom_field_bool': None,
'custom_field_text': '',
'custom_field_textarea': '',
@ -1429,6 +1443,8 @@ def test_events_check_status_events(app, user):
'waiting_list_places': 0,
'agenda': agenda.slug,
'primary_event': recurring_event.slug,
'check_locked': False,
'checked': True,
'custom_field_text': 'foo',
'custom_field_textarea': 'foo bar',
'custom_field_bool': True,
@ -1595,3 +1611,279 @@ def test_events_check_status_subscription_filter(app, user, freezer, event_date,
}
resp = app.get(url, params=params)
assert len(resp.json['data']) == int(expected)
def test_events_check_lock_params(app, user):
app.authorization = ('Basic', ('john.doe', 'password'))
# missing check_locked
lguerin marked this conversation as resolved Outdated

c'est plutôt missing check_locked, non ?

c'est plutôt missing check_locked, non ?

yes

yes
resp = app.post_json(
'/api/agendas/events/check-lock/',
params={'agendas': 'foo', 'date_start': '2022-05-01', 'date_end': '2022-06-01'},
status=400,
)
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'invalid payload'
assert resp.json['errors']['check_locked'] == ['This field is required.']
# missing agendas
resp = app.post_json(
'/api/agendas/events/check-lock/',
params={'check_locked': True, 'date_start': '2022-05-01', 'date_end': '2022-06-01'},
status=400,
)
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'invalid payload'
assert resp.json['errors']['agendas'] == ['This field is required.']
# unknown agenda
resp = app.post_json(
'/api/agendas/events/check-lock/',
params={
'check_locked': True,
'agendas': 'foo, bar',

Je comprends que c'est parce qu'on partage du code (AgendaSlugsMixin) avec des bouts appelés depuis w.c.s. mais je note que peut-être là-dedans un jour on pourrait imaginer une évolution pour également accepter une liste de chaines.

Je comprends que c'est parce qu'on partage du code (AgendaSlugsMixin) avec des bouts appelés depuis w.c.s. mais je note que peut-être là-dedans un jour on pourrait imaginer une évolution pour également accepter une liste de chaines.
'date_start': '2022-05-01',
'date_end': '2022-06-01',
},
status=400,
)
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'invalid payload'
assert resp.json['errors']['agendas'] == ['invalid slugs: bar, foo']
Agenda.objects.create(label='Foo')
resp = app.post_json(
'/api/agendas/events/check-lock/',
params={
'check_locked': True,
'agendas': 'foo, bar',
'date_start': '2022-05-01',
'date_end': '2022-06-01',
},
status=400,
)
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'invalid payload'
assert resp.json['errors']['agendas'] == ['invalid slugs: bar']
# wrong kind
wrong_agenda = Agenda.objects.create(label='Bar')
for kind in ['meetings', 'virtual']:
wrong_agenda.kind = kind
wrong_agenda.save()
resp = app.post_json(
'/api/agendas/events/check-lock/',
params={
'check_locked': True,
'agendas': 'foo, bar',
'date_start': '2022-05-01',
'date_end': '2022-06-01',
},
status=400,
)
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'invalid payload'
assert resp.json['errors']['agendas'] == ['invalid slugs: bar']
# missing date_start
resp = app.post_json(
'/api/agendas/events/check-lock/',
params={'check_locked': True, 'agendas': 'foo', 'date_end': '2022-06-01'},
status=400,
)
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'invalid payload'
assert resp.json['errors']['date_start'] == ['This field is required.']
# missing date_end
resp = app.post_json(
'/api/agendas/events/check-lock/',
params={'check_locked': True, 'agendas': 'foo', 'date_start': '2022-05-01'},
status=400,
)
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'invalid payload'
assert resp.json['errors']['date_end'] == ['This field is required.']
# bad date format
resp = app.post_json(
'/api/agendas/events/check-lock/',
params={'check_locked': True, 'agendas': 'foo', 'date_start': 'wrong', 'date_end': 'wrong'},
status=400,
)
assert resp.json['err'] == 1
assert resp.json['err_desc'] == 'invalid payload'
assert 'wrong format' in resp.json['errors']['date_start'][0]
assert 'wrong format' in resp.json['errors']['date_end'][0]
@pytest.mark.freeze_time('2022-05-30 14:00')
def test_events_check_lock(app, user):
agenda = Agenda.objects.create(label='Foo')
event = Event.objects.create(
slug='event-slug',
label='Event Label',
start_datetime=now(),
places=10,
agenda=agenda,
checked=True,
)
app.authorization = ('Basic', ('john.doe', 'password'))
url = '/api/agendas/events/check-lock/'
params = {
'check_locked': True,
'agendas': 'foo',
'date_start': '2022-05-01',
'date_end': '2022-06-01',
}
resp = app.post_json(url, params=params)
assert resp.json['err'] == 0
event.refresh_from_db()
assert event.check_locked is True
params['check_locked'] = False
resp = app.post_json(url, params=params)
assert resp.json['err'] == 0
event.refresh_from_db()
assert event.check_locked is False
@pytest.mark.freeze_time('2022-05-30 14:00')
def test_events_check_lock_events(app, user):
events_type = EventsType.objects.create(
label='Foo',
)
agenda = Agenda.objects.create(label='Foo', events_type=events_type)
start_datetime = now()
# recurring event
recurring_event = Event.objects.create(
slug='recurring-event-slug',
label='Recurring Event Label',
start_datetime=start_datetime,
recurrence_days=[start_datetime.weekday()],
recurrence_end_date=start_datetime + datetime.timedelta(days=7),
places=10,
agenda=agenda,
)
recurring_event.create_all_recurrences()
first_event = recurring_event.recurrences.get()
event = Event.objects.create(
slug='event-slug',
label='Event Label',
start_datetime=start_datetime - datetime.timedelta(days=1),
places=10,
agenda=agenda,
)
# cancelled event, not updated
cancelled_event = Event.objects.create(
slug='cancelled',
label='Cancelled',
start_datetime=start_datetime,
places=10,
agenda=agenda,
cancelled=True,
)
app.authorization = ('Basic', ('john.doe', 'password'))
url = '/api/agendas/events/check-lock/'
params = {
'check_locked': True,
'agendas': 'foo',
'date_start': '2022-05-01',
'date_end': '2022-06-01',
}
resp = app.post_json(url, params=params)
assert resp.json['err'] == 0
recurring_event.refresh_from_db()
assert recurring_event.check_locked is False
first_event.refresh_from_db()
assert first_event.check_locked is True
event.refresh_from_db()
assert event.check_locked is True
cancelled_event.refresh_from_db()
assert cancelled_event.check_locked is False
@pytest.mark.freeze_time('2022-05-30 14:00')
def test_events_check_lock_agendas_filter(app, user):
agenda1 = Agenda.objects.create(label='Foo')
agenda2 = Agenda.objects.create(label='Foo 2')
event1 = Event.objects.create(
slug='event-1',
label='Event 1',
start_datetime=now(),
places=10,
agenda=agenda1,
)
event2 = Event.objects.create(
slug='event-2',
label='Event 2',
start_datetime=now(),
places=10,
agenda=agenda2,
)
app.authorization = ('Basic', ('john.doe', 'password'))
url = '/api/agendas/events/check-lock/'
params = {
'check_locked': True,
'agendas': 'foo, foo-2',
'date_start': '2022-05-01',
'date_end': '2022-06-01',
}
app.post_json(url, params=params)
event1.refresh_from_db()
assert event1.check_locked is True
event2.refresh_from_db()
assert event2.check_locked is True
params['agendas'] = 'foo'
params['check_locked'] = False
app.post_json(url, params=params)
event1.refresh_from_db()
assert event1.check_locked is False
event2.refresh_from_db()
assert event2.check_locked is True
params['agendas'] = 'foo-2'
app.post_json(url, params=params)
event1.refresh_from_db()
assert event1.check_locked is False
event2.refresh_from_db()
assert event2.check_locked is False
@pytest.mark.parametrize(
'event_date, expected',
[
# just before first day
((2022, 4, 30, 12, 0), False),
# first day
((2022, 5, 1, 12, 0), True),
# last day
((2022, 5, 31, 12, 0), True),
# just after last day
((2022, 6, 1, 12, 0), False),
],
)
def test_events_check_lock_date_filter(app, user, event_date, expected):
agenda = Agenda.objects.create(label='Foo')
event = Event.objects.create(
slug='event',
label='Event',
start_datetime=make_aware(datetime.datetime(*event_date)),
places=10,
agenda=agenda,
)
app.authorization = ('Basic', ('john.doe', 'password'))
url = '/api/agendas/events/check-lock/'
params = {
'check_locked': True,
'agendas': 'foo',
'date_start': '2022-05-01',
'date_end': '2022-06-01',
}
app.post_json(url, params=params)
event.refresh_from_db()
assert event.check_locked == expected

View File

@ -1716,6 +1716,7 @@ def test_event_checked(app, admin_user):
for url in urls:
resp = app.get(url)
assert '<span class="checked tag">Checked</span>' not in resp
assert 'check-locked' not in resp
assert '<span class="meta meta-success">Presents 3</span>' in resp
assert '<span class="meta meta-error">Absents 4</span>' in resp
assert '<span class="meta meta-disabled">Not checked 1</span>' in resp
@ -1736,6 +1737,7 @@ def test_event_checked(app, admin_user):
for url in urls:
resp = app.get(url)
assert '<span class="checked tag">Checked</span>' in resp
assert 'check-locked' not in resp
assert '<span class="meta meta-success">Presents 4</span>' in resp
assert '<span class="meta meta-error">Absents 4</span>' in resp
assert 'meta meta-disabled' not in resp
@ -1761,6 +1763,29 @@ def test_event_checked(app, admin_user):
status=302,
)
# event check is locked
event.checked = False
event.check_locked = True
event.save()
urls = [
'/manage/agendas/%s/events/%s/' % (agenda.pk, event.pk),
'/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk),
'/manage/agendas/%s/month/%d/%d/%d/'
% (agenda.pk, event.start_datetime.year, event.start_datetime.month, event.start_datetime.day),
'/manage/agendas/%s/week/%d/%d/%d/'
% (agenda.pk, event.start_datetime.year, event.start_datetime.month, event.start_datetime.day),
'/manage/agendas/%s/day/%d/%d/%d/'
% (agenda.pk, event.start_datetime.year, event.start_datetime.month, event.start_datetime.day),
]
for url in urls:
resp = app.get(url)
assert '<span class="check-locked tag">Check locked</span>' in resp
app.post(
'/manage/agendas/%s/events/%s/checked' % (agenda.pk, event.pk),
params={'csrfmiddlewaretoken': token},
status=404,
)
@mock.patch('chrono.manager.forms.get_agenda_check_types')
def test_event_check_filters(check_types, app, admin_user):
@ -2416,7 +2441,32 @@ def test_event_check_booking(check_types, app, admin_user):
status=302,
)
# event check is locked
event.check_locked = True
event.save()
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert '/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk) not in resp
assert '/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk) not in resp
assert '/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk) not in resp
app.post(
'/manage/agendas/%s/bookings/%s/absence' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token},
status=404,
)
app.post(
'/manage/agendas/%s/bookings/%s/presence' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token},
status=404,
)
app.post(
'/manage/agendas/%s/bookings/%s/reset' % (agenda.pk, booking.pk),
params={'csrfmiddlewaretoken': token},
status=404,
)
# now disable check update
event.check_locked = False
event.save()
agenda.disable_check_update = True
agenda.save()
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
@ -2790,6 +2840,21 @@ def test_event_check_subscription(check_types, app, admin_user):
params={'csrfmiddlewaretoken': token},
status=302,
)
Booking.objects.all().delete()
# event check is locked
event.check_locked = True
event.save()
app.post(
'/manage/agendas/%s/subscriptions/%s/absence/%s' % (agenda.pk, subscription.pk, event.pk),
params={'csrfmiddlewaretoken': token},
status=404,
)
app.post(
'/manage/agendas/%s/subscriptions/%s/presence/%s' % (agenda.pk, subscription.pk, event.pk),
params={'csrfmiddlewaretoken': token},
status=404,
)
@mock.patch('chrono.manager.forms.get_agenda_check_types')