agendas: a check_type can be disabled (#63847)

This commit is contained in:
Lauréline Guérin 2022-04-15 16:09:19 +02:00
parent 0b38a91b2e
commit f70aa2063a
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
8 changed files with 77 additions and 12 deletions

View File

@ -0,0 +1,16 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('agendas', '0123_user_check_type'),
]
operations = [
migrations.AddField(
model_name='checktype',
name='disabled',
field=models.BooleanField(default=False, verbose_name='Disabled'),
),
]

View File

@ -3079,10 +3079,10 @@ class CheckTypeGroup(models.Model):
class CheckTypeManager(models.Manager):
def absences(self):
return self.filter(kind='absence')
return self.filter(kind='absence', disabled=False)
def presences(self):
return self.filter(kind='presence')
return self.filter(kind='presence', disabled=False)
class CheckType(models.Model):
@ -3101,6 +3101,7 @@ class CheckType(models.Model):
pricing_rate = models.PositiveIntegerField(
_('Pricing rate'), help_text=_('Percentage rate'), blank=True, null=True
)
disabled = models.BooleanField(_('Disabled'), default=False)
objects = CheckTypeManager()
class Meta:

View File

@ -172,7 +172,9 @@ class BookingSerializer(serializers.ModelSerializer):
if not self.instance.event.agenda.check_type_group:
raise serializers.ValidationError(error_messages[kind])
check_types_qs = self.instance.event.agenda.check_type_group.check_types.filter(kind=kind)
check_types_qs = self.instance.event.agenda.check_type_group.check_types.filter(
kind=kind, disabled=False
)
try:
return check_types_qs.get(slug=value)
except CheckType.DoesNotExist:

View File

@ -89,7 +89,7 @@ class NewCheckTypeForm(forms.ModelForm):
class CheckTypeForm(NewCheckTypeForm):
class Meta:
model = CheckType
fields = ['label', 'slug', 'pricing', 'pricing_rate']
fields = ['label', 'slug', 'pricing', 'pricing_rate', 'disabled']
def clean_slug(self):
slug = self.cleaned_data['slug']
@ -464,14 +464,14 @@ class BookingCheckFilterSet(django_filters.FilterSet):
status_choices += [
('presence-%s' % r.pk, _('Presence (%s)') % r.label)
for r in self.agenda.check_type_group.check_types.all()
if r.kind == 'presence'
if r.kind == 'presence' and not r.disabled
]
status_choices += [('absence', _('Absence'))]
if self.agenda.check_type_group:
status_choices += [
('absence-%s' % r.pk, _('Absence (%s)') % r.label)
for r in self.agenda.check_type_group.check_types.all()
if r.kind == 'absence'
if r.kind == 'absence' and not r.disabled
]
self.filters['booking-status'] = django_filters.ChoiceFilter(
label=_('Filter by status'),
@ -525,7 +525,9 @@ class BookingCheckAbsenceForm(forms.Form):
super().__init__(*args, **kwargs)
if agenda.check_type_group:
self.fields['check_type'].choices = [('', '---------')] + [
(r.pk, r.label) for r in agenda.check_type_group.check_types.all() if r.kind == 'absence'
(r.pk, r.label)
for r in agenda.check_type_group.check_types.all()
if r.kind == 'absence' and not r.disabled
]
@ -537,7 +539,9 @@ class BookingCheckPresenceForm(forms.Form):
super().__init__(*args, **kwargs)
if agenda.check_type_group:
self.fields['check_type'].choices = [('', '---------')] + [
(r.pk, r.label) for r in agenda.check_type_group.check_types.all() if r.kind == 'presence'
(r.pk, r.label)
for r in agenda.check_type_group.check_types.all()
if r.kind == 'presence' and not r.disabled
]

View File

@ -28,17 +28,21 @@
</h3>
<div>
<ul class="objects-list single-links">
{% for check_type in object.check_types.absences %}
{% for check_type in object.check_types.all %}
{% if check_type.kind == 'absence' %}
<li>
<a rel="popup" href="{% url 'chrono-manager-check-type-edit' object.pk check_type.pk %}">{% trans "Absence" %} - {{ check_type }}</a>
<a rel="popup" href="{% url 'chrono-manager-check-type-edit' object.pk check_type.pk %}">{% trans "Absence" %} - {{ check_type }}{% if check_type.disabled %}<span class="extra-info"> ({% trans "disabled" %})</span>{% endif %}</a>
<a class="delete" rel="popup" href="{% url 'chrono-manager-check-type-delete' object.pk check_type.pk %}">{% trans "delete"%}</a>
</li>
{% endif %}
{% endfor %}
{% for check_type in object.check_types.presences %}
{% for check_type in object.check_types.all %}
{% if check_type.kind == 'presence' %}
<li>
<a rel="popup" href="{% url 'chrono-manager-check-type-edit' object.pk check_type.pk %}">{% trans "Presence" %} - {{ check_type }}</a>
<a rel="popup" href="{% url 'chrono-manager-check-type-edit' object.pk check_type.pk %}">{% trans "Presence" %} - {{ check_type }}{% if check_type.disabled %}<span class="extra-info"> ({% trans "disabled" %})</span>{% endif %}</a>
<a class="delete" rel="popup" href="{% url 'chrono-manager-check-type-delete' object.pk check_type.pk %}">{% trans "delete"%}</a>
</li>
{% endif %}
{% endfor %}
<li><a class="add" rel="popup" href="{% url 'chrono-manager-check-type-add' object.pk %}">{% trans "Add a check type" %}</a></li>
</ul>

View File

@ -613,6 +613,9 @@ def test_booking_patch_api_absence_reason(app, user):
group = CheckTypeGroup.objects.create(label='Foo')
check_type_absence = CheckType.objects.create(group=group, label='Foo bar', kind='absence')
check_type_presence = CheckType.objects.create(group=group, label='Foo baz', kind='presence')
check_type_absence_disabled = CheckType.objects.create(
label='disabled', group=group, kind='absence', disabled=True
)
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_absence_reason': 'foobar'}, status=400
@ -640,6 +643,15 @@ def test_booking_patch_api_absence_reason(app, user):
booking.refresh_from_db()
assert booking.user_check_type == check_type_absence
# disabled
resp = app.patch_json(
'/api/booking/%s/' % booking.pk,
params={'user_absence_reason': check_type_absence_disabled.slug},
status=400,
)
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
# reset
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_absence_reason': ''})
booking.refresh_from_db()
@ -721,6 +733,9 @@ def test_booking_patch_api_presence_reason(app, user):
group = CheckTypeGroup.objects.create(label='Foo')
check_type_presence = CheckType.objects.create(group=group, label='Foo bar', kind='presence')
check_type_absence = CheckType.objects.create(group=group, label='Foo baz', kind='absence')
check_type_presence_disabled = CheckType.objects.create(
label='disabled', group=group, kind='presence', disabled=True
)
resp = app.patch_json(
'/api/booking/%s/' % booking.pk, params={'user_presence_reason': 'foobar'}, status=400
@ -748,6 +763,15 @@ def test_booking_patch_api_presence_reason(app, user):
booking.refresh_from_db()
assert booking.user_check_type == check_type_presence
# disabled
resp = app.patch_json(
'/api/booking/%s/' % booking.pk,
params={'user_presence_reason': check_type_presence_disabled.slug},
status=400,
)
assert resp.json['err'] == 4
assert resp.json['err_desc'] == 'invalid payload'
# reset
app.patch_json('/api/booking/%s/' % booking.pk, params={'user_presence_reason': ''})
booking.refresh_from_db()

View File

@ -110,6 +110,8 @@ def test_add_check_type(app, admin_user):
resp = resp.click('Check types')
resp = resp.click('Add a check type')
resp.form['label'] = 'Foo reason'
assert 'slug' not in resp.context['form'].fields
assert 'disabled' not in resp.context['form'].fields
resp = resp.form.submit()
check_type = CheckType.objects.latest('pk')
assert resp.location.endswith('/manage/check-types/')
@ -187,6 +189,7 @@ def test_edit_check_type(app, admin_user):
assert 'This check type is set on some existing bookings, modify it with caution.' not in resp
resp.form['label'] = 'Foo bar reason'
resp.form['slug'] = check_type2.slug
resp.form['disabled'] = True
assert 'kind' not in resp.context['form'].fields
resp = resp.form.submit()
assert resp.context['form'].errors['slug'] == ['Another check type exists with the same identifier.']
@ -200,6 +203,7 @@ def test_edit_check_type(app, admin_user):
assert check_type.kind == 'presence'
assert check_type.pricing is None
assert check_type.pricing_rate is None
assert check_type.disabled is True
# check_type is used
Booking.objects.update(user_check_type=check_type)

View File

@ -1623,6 +1623,12 @@ def test_event_check_filters(app, admin_user):
group = CheckTypeGroup.objects.create(label='Foo bar')
check_type_absence = CheckType.objects.create(label='Foo reason', group=group, kind='absence')
check_type_presence = CheckType.objects.create(label='Bar reason', group=group, kind='presence')
check_type_absence_disabled = CheckType.objects.create(
label='disabled', group=group, kind='absence', disabled=True
)
check_type_presence_disabled = CheckType.objects.create(
label='disabled too', group=group, kind='presence', disabled=True
)
agenda = Agenda.objects.create(
label='Events', kind='events', booking_check_filters='foo,bar', check_type_group=group
)
@ -1781,6 +1787,8 @@ def test_event_check_filters(app, admin_user):
assert 'Subscription foo-val2 bar-val1' in resp
assert 'Subscription foo-val1 bar-val2' in resp
assert 'Subscription foo-none bar-val2' in resp
assert len(resp.pyquery.find('input[value=absence-%s]' % check_type_absence_disabled.pk)) == 0
assert len(resp.pyquery.find('input[value=absence-%s]' % check_type_presence_disabled.pk)) == 0
with CaptureQueriesContext(connection) as ctx:
resp = app.get(
@ -2099,6 +2107,8 @@ def test_event_check_booking(app, admin_user):
agenda.check_type_group = group
agenda.save()
CheckType.objects.create(label='disabled', group=group, kind='absence', disabled=True)
CheckType.objects.create(label='disabled too', group=group, kind='presence', disabled=True)
resp = app.get('/manage/agendas/%s/events/%s/check' % (agenda.pk, event.pk))
assert len(resp.pyquery.find('td.booking-actions form.absence select')) == 0
assert len(resp.pyquery.find('td.booking-actions form.presence select')) == 0