api: list agenda's check types (#66008)
This commit is contained in:
parent
713216742c
commit
ba77a40f73
|
@ -0,0 +1,27 @@
|
||||||
|
# lingo - payment and billing system
|
||||||
|
# Copyright (C) 2022 Entr'ouvert
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Affero General Public License as published
|
||||||
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from django.conf.urls import url
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(
|
||||||
|
r'^agenda/(?P<agenda_identifier>[\w-]+)/check-types/$',
|
||||||
|
views.agenda_check_type_list,
|
||||||
|
name='api-agenda-check-types',
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,51 @@
|
||||||
|
# lingo - payment and billing system
|
||||||
|
# Copyright (C) 2022 Entr'ouvert
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Affero General Public License as published
|
||||||
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.views import exception_handler as DRF_exception_handler
|
||||||
|
|
||||||
|
|
||||||
|
class APIError(Exception):
|
||||||
|
http_status = 200
|
||||||
|
|
||||||
|
def __init__(self, message, *args, err=1, err_class=None, errors=None):
|
||||||
|
self.err_desc = _(message) % args
|
||||||
|
self.err = err
|
||||||
|
self.err_class = err_class or message % args
|
||||||
|
self.errors = errors
|
||||||
|
super().__init__(self.err_desc)
|
||||||
|
|
||||||
|
def to_response(self):
|
||||||
|
data = {
|
||||||
|
'err': self.err,
|
||||||
|
'err_class': self.err_class,
|
||||||
|
'err_desc': self.err_desc,
|
||||||
|
}
|
||||||
|
if self.errors:
|
||||||
|
data['errors'] = self.errors
|
||||||
|
return Response(data, status=self.http_status)
|
||||||
|
|
||||||
|
|
||||||
|
class APIErrorBadRequest(APIError):
|
||||||
|
http_status = 400
|
||||||
|
|
||||||
|
|
||||||
|
def exception_handler(exc, context):
|
||||||
|
if isinstance(exc, APIError):
|
||||||
|
return exc.to_response()
|
||||||
|
|
||||||
|
return DRF_exception_handler(exc, context)
|
|
@ -0,0 +1,39 @@
|
||||||
|
# lingo - payment and billing system
|
||||||
|
# Copyright (C) 2022 Entr'ouvert
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU Affero General Public License as published
|
||||||
|
# by the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
from rest_framework.views import APIView
|
||||||
|
|
||||||
|
from lingo.agendas.models import Agenda
|
||||||
|
from lingo.api.utils import Response
|
||||||
|
|
||||||
|
|
||||||
|
class AgendaCheckTypeList(APIView):
|
||||||
|
permission_classes = ()
|
||||||
|
|
||||||
|
def get(self, request, agenda_identifier=None, format=None):
|
||||||
|
agenda = get_object_or_404(Agenda, slug=agenda_identifier)
|
||||||
|
|
||||||
|
check_types = []
|
||||||
|
if agenda.check_type_group:
|
||||||
|
check_types = [
|
||||||
|
{'id': x.slug, 'text': x.label, 'kind': x.kind}
|
||||||
|
for x in agenda.check_type_group.check_types.filter(disabled=False)
|
||||||
|
]
|
||||||
|
return Response({'data': check_types})
|
||||||
|
|
||||||
|
|
||||||
|
agenda_check_type_list = AgendaCheckTypeList.as_view()
|
|
@ -55,6 +55,7 @@ INSTALLED_APPS = (
|
||||||
'eopayment',
|
'eopayment',
|
||||||
'gadjo',
|
'gadjo',
|
||||||
'lingo.agendas',
|
'lingo.agendas',
|
||||||
|
'lingo.api',
|
||||||
'lingo.manager',
|
'lingo.manager',
|
||||||
'lingo.pricing',
|
'lingo.pricing',
|
||||||
)
|
)
|
||||||
|
@ -194,6 +195,7 @@ def debug_show_toolbar(request):
|
||||||
|
|
||||||
DEBUG_TOOLBAR_CONFIG = {'SHOW_TOOLBAR_CALLBACK': debug_show_toolbar}
|
DEBUG_TOOLBAR_CONFIG = {'SHOW_TOOLBAR_CALLBACK': debug_show_toolbar}
|
||||||
|
|
||||||
|
REST_FRAMEWORK = {'EXCEPTION_HANDLER': 'lingo.api.utils.exception_handler'}
|
||||||
|
|
||||||
local_settings_file = os.environ.get(
|
local_settings_file = os.environ.get(
|
||||||
'LINGO_SETTINGS_FILE', os.path.join(os.path.dirname(__file__), 'local_settings.py')
|
'LINGO_SETTINGS_FILE', os.path.join(os.path.dirname(__file__), 'local_settings.py')
|
||||||
|
|
|
@ -19,6 +19,7 @@ from django.conf.urls import include, url
|
||||||
from django.conf.urls.static import static
|
from django.conf.urls.static import static
|
||||||
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
|
||||||
|
|
||||||
|
from .api.urls import urlpatterns as lingo_api_urls
|
||||||
from .manager.urls import urlpatterns as lingo_manager_urls
|
from .manager.urls import urlpatterns as lingo_manager_urls
|
||||||
from .pricing.urls import urlpatterns as lingo_pricing_urls
|
from .pricing.urls import urlpatterns as lingo_pricing_urls
|
||||||
from .urls_utils import decorated_includes, manager_required
|
from .urls_utils import decorated_includes, manager_required
|
||||||
|
@ -28,6 +29,7 @@ urlpatterns = [
|
||||||
url(r'^$', homepage, name='homepage'),
|
url(r'^$', homepage, name='homepage'),
|
||||||
url(r'^manage/', decorated_includes(manager_required, include(lingo_manager_urls))),
|
url(r'^manage/', decorated_includes(manager_required, include(lingo_manager_urls))),
|
||||||
url(r'^manage/pricing/', decorated_includes(manager_required, include(lingo_pricing_urls))),
|
url(r'^manage/pricing/', decorated_includes(manager_required, include(lingo_pricing_urls))),
|
||||||
|
url(r'^api/', include(lingo_api_urls)),
|
||||||
url(r'^login/$', login, name='auth_login'),
|
url(r'^login/$', login, name='auth_login'),
|
||||||
url(r'^logout/$', logout, name='auth_logout'),
|
url(r'^logout/$', logout, name='auth_logout'),
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from lingo.agendas.models import Agenda, CheckType, CheckTypeGroup
|
||||||
|
|
||||||
|
pytestmark = pytest.mark.django_db
|
||||||
|
|
||||||
|
|
||||||
|
def test_agendas_check_types_api(app):
|
||||||
|
agenda = Agenda.objects.create(label='Foo bar')
|
||||||
|
group = CheckTypeGroup.objects.create(label='Foo bar')
|
||||||
|
CheckType.objects.create(label='Foo reason', group=group, kind='absence')
|
||||||
|
CheckType.objects.create(label='Bar reason', group=group, kind='presence')
|
||||||
|
CheckType.objects.create(label='Baz reason', group=group, kind='presence', disabled=True)
|
||||||
|
group2 = CheckTypeGroup.objects.create(label='Foo bar 2')
|
||||||
|
|
||||||
|
resp = app.get('/api/agenda/%s/check-types/' % agenda.slug)
|
||||||
|
assert resp.json == {'data': []}
|
||||||
|
|
||||||
|
agenda.check_type_group = group2
|
||||||
|
agenda.save()
|
||||||
|
resp = app.get('/api/agenda/%s/check-types/' % agenda.slug)
|
||||||
|
assert resp.json == {'data': []}
|
||||||
|
|
||||||
|
agenda.check_type_group = group
|
||||||
|
agenda.save()
|
||||||
|
resp = app.get('/api/agenda/%s/check-types/' % agenda.slug)
|
||||||
|
assert resp.json == {
|
||||||
|
'data': [
|
||||||
|
{'id': 'bar-reason', 'kind': 'presence', 'text': 'Bar reason'},
|
||||||
|
{'id': 'foo-reason', 'kind': 'absence', 'text': 'Foo reason'},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
# unknown
|
||||||
|
resp = app.get('/api/agenda/xxxx/resources/', status=404)
|
Loading…
Reference in New Issue