stats, ne pas afficher « Grouper par : Présence/Absence » pour un agenda de type rdv (#74327) #39
|
@ -304,7 +304,6 @@ class StatisticsFiltersSerializer(serializers.Serializer):
|
||||||
time_interval = serializers.ChoiceField(choices=('day', _('Day')), default='day')
|
time_interval = serializers.ChoiceField(choices=('day', _('Day')), default='day')
|
||||||
start = serializers.DateTimeField(required=False, input_formats=['iso-8601', '%Y-%m-%d'])
|
start = serializers.DateTimeField(required=False, input_formats=['iso-8601', '%Y-%m-%d'])
|
||||||
end = serializers.DateTimeField(required=False, input_formats=['iso-8601', '%Y-%m-%d'])
|
end = serializers.DateTimeField(required=False, input_formats=['iso-8601', '%Y-%m-%d'])
|
||||||
category = serializers.SlugField(required=False, allow_blank=False, max_length=256)
|
|
||||||
agenda = serializers.CharField(required=False, allow_blank=False, max_length=256)
|
agenda = serializers.CharField(required=False, allow_blank=False, max_length=256)
|
||||||
group_by = serializers.ListField(
|
group_by = serializers.ListField(
|
||||||
required=False, child=serializers.SlugField(allow_blank=False, max_length=256)
|
required=False, child=serializers.SlugField(allow_blank=False, max_length=256)
|
||||||
|
|
|
@ -47,7 +47,6 @@ from chrono.agendas.models import (
|
||||||
Agenda,
|
Agenda,
|
||||||
Booking,
|
Booking,
|
||||||
BookingColor,
|
BookingColor,
|
||||||
Category,
|
|
||||||
Desk,
|
Desk,
|
||||||
Event,
|
Event,
|
||||||
MeetingType,
|
MeetingType,
|
||||||
|
@ -3072,10 +3071,6 @@ class StatisticsList(APIView):
|
||||||
permission_classes = (permissions.IsAuthenticated,)
|
permission_classes = (permissions.IsAuthenticated,)
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
categories = Category.objects.all()
|
|
||||||
category_options = [{'id': '_all', 'label': pgettext('categories', 'All')}] + [
|
|
||||||
{'id': x.slug, 'label': x.label} for x in categories
|
|
||||||
]
|
|
||||||
return Response(
|
return Response(
|
||||||
{
|
{
|
||||||
'data': [
|
'data': [
|
||||||
|
@ -3092,18 +3087,6 @@ class StatisticsList(APIView):
|
||||||
'required': True,
|
'required': True,
|
||||||
'default': 'day',
|
'default': 'day',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
'id': 'category',
|
|
||||||
'label': _('Category'),
|
|
||||||
'options': category_options,
|
|
||||||
'required': True,
|
|
||||||
'default': '_all',
|
|
||||||
'has_subfilters': True,
|
|
||||||
'deprecated': True,
|
|
||||||
'deprecation_hint': _(
|
|
||||||
'Category should now be selected using the Agenda field below.'
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
'id': 'agenda',
|
'id': 'agenda',
|
||||||
'label': _('Agenda'),
|
'label': _('Agenda'),
|
||||||
|
@ -3122,7 +3105,7 @@ class StatisticsList(APIView):
|
||||||
def get_agenda_options():
|
def get_agenda_options():
|
||||||
all_agendas_option = [{'id': '_all', 'label': pgettext('agendas', 'All')}]
|
all_agendas_option = [{'id': '_all', 'label': pgettext('agendas', 'All')}]
|
||||||
|
|
||||||
agendas = Agenda.objects.all().order_by('category__name')
|
agendas = Agenda.objects.all().order_by('category__name', 'label')
|
||||||
agendas_with_category = [x for x in agendas if x.category]
|
agendas_with_category = [x for x in agendas if x.category]
|
||||||
if not agendas_with_category:
|
if not agendas_with_category:
|
||||||
return all_agendas_option + [{'id': x.slug, 'label': x.label} for x in agendas]
|
return all_agendas_option + [{'id': x.slug, 'label': x.label} for x in agendas]
|
||||||
|
@ -3168,16 +3151,18 @@ class BookingsStatistics(APIView):
|
||||||
bookings = bookings.filter(event__start_datetime__lte=data['end'])
|
bookings = bookings.filter(event__start_datetime__lte=data['end'])
|
||||||
|
|
||||||
agenda_slug = data.get('agenda', '_all')
|
agenda_slug = data.get('agenda', '_all')
|
||||||
category_slug = data.get('category', '_all')
|
if agenda_slug != '_all':
|
||||||
if agenda_slug.startswith('category:'):
|
if agenda_slug.startswith('category:'):
|
||||||
category_slug = agenda_slug.split(':', 1)[1]
|
category_slug = agenda_slug.split(':', 1)[1]
|
||||||
|
agendas = Agenda.objects.filter(category__slug=category_slug)
|
||||||
|
else:
|
||||||
|
agendas = Agenda.objects.filter(slug=agenda_slug)
|
||||||
|
|
||||||
if category_slug != '_all':
|
if not agendas:
|
||||||
bookings = bookings.filter(event__agenda__category__slug=category_slug)
|
raise APIErrorBadRequest(_('No agendas found.'))
|
||||||
subfilters = self.get_subfilters(agendas=Agenda.objects.filter(category__slug=category_slug))
|
|
||||||
elif agenda_slug != '_all':
|
bookings = bookings.filter(event__agenda__in=agendas)
|
||||||
bookings = bookings.filter(event__agenda__slug=agenda_slug)
|
subfilters = self.get_subfilters(agendas=agendas)
|
||||||
subfilters = self.get_subfilters(agendas=Agenda.objects.filter(slug=agenda_slug))
|
|
||||||
|
|
||||||
bookings = bookings.annotate(day=TruncDay('event__start_datetime'))
|
bookings = bookings.annotate(day=TruncDay('event__start_datetime'))
|
||||||
|
|
||||||
|
@ -3255,9 +3240,14 @@ class BookingsStatistics(APIView):
|
||||||
.values_list('extra_data_keys', flat=True)
|
.values_list('extra_data_keys', flat=True)
|
||||||
)
|
)
|
||||||
|
|
||||||
group_by_options = [{'id': 'user_was_present', 'label': _('Presence/Absence')}] + [
|
group_by_options = [{'id': x, 'label': x.capitalize()} for x in extra_data_keys]
|
||||||
{'id': x, 'label': x.capitalize()} for x in extra_data_keys
|
|
||||||
]
|
if any(x.kind == 'events' for x in agendas):
|
||||||
|
group_by_options = [{'id': 'user_was_present', 'label': _('Presence/Absence')}] + group_by_options
|
||||||
|
|
||||||
|
if not group_by_options:
|
||||||
|
return []
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
'id': 'group_by',
|
'id': 'group_by',
|
||||||
|
|
|
@ -17,8 +17,6 @@ def test_statistics_list(app, user):
|
||||||
|
|
||||||
app.authorization = ('Basic', ('john.doe', 'password'))
|
app.authorization = ('Basic', ('john.doe', 'password'))
|
||||||
resp = app.get('/api/statistics/')
|
resp = app.get('/api/statistics/')
|
||||||
category_filter = [x for x in resp.json['data'][0]['filters'] if x['id'] == 'category'][0]
|
|
||||||
assert len(category_filter['options']) == 3
|
|
||||||
agenda_filter = [x for x in resp.json['data'][0]['filters'] if x['id'] == 'agenda'][0]
|
agenda_filter = [x for x in resp.json['data'][0]['filters'] if x['id'] == 'agenda'][0]
|
||||||
assert agenda_filter['options'] == [
|
assert agenda_filter['options'] == [
|
||||||
{'id': '_all', 'label': 'All'},
|
{'id': '_all', 'label': 'All'},
|
||||||
|
@ -106,11 +104,6 @@ def test_statistics_bookings(app, user, freezer):
|
||||||
assert resp.json['data']['x_labels'] == ['2020-10-25']
|
assert resp.json['data']['x_labels'] == ['2020-10-25']
|
||||||
assert resp.json['data']['series'] == [{'label': 'Bookings Count', 'data': [1]}]
|
assert resp.json['data']['series'] == [{'label': 'Bookings Count', 'data': [1]}]
|
||||||
|
|
||||||
# legacy, category filter
|
|
||||||
resp = app.get(url + '?category=category-a')
|
|
||||||
assert resp.json['data']['x_labels'] == ['2020-10-25']
|
|
||||||
assert resp.json['data']['series'] == [{'label': 'Bookings Count', 'data': [1]}]
|
|
||||||
|
|
||||||
# agenda filter
|
# agenda filter
|
||||||
resp = app.get(url + '?agenda=bar-foo')
|
resp = app.get(url + '?agenda=bar-foo')
|
||||||
assert resp.json['data']['x_labels'] == ['2020-10-25']
|
assert resp.json['data']['x_labels'] == ['2020-10-25']
|
||||||
|
@ -198,14 +191,28 @@ def test_statistics_bookings_subfilters_list(app, user):
|
||||||
}
|
}
|
||||||
assert resp.json['data']['subfilters'][0]['options'][1] == {'id': 'test', 'label': 'Test'}
|
assert resp.json['data']['subfilters'][0]['options'][1] == {'id': 'test', 'label': 'Test'}
|
||||||
|
|
||||||
resp = app.get(url + '?category=category-a')
|
resp = app.get(url + '?agenda=category:category-a')
|
||||||
assert len(resp.json['data']['subfilters'][0]['options']) == 2
|
assert len(resp.json['data']['subfilters'][0]['options']) == 2
|
||||||
|
|
||||||
Category.objects.create(label='Category B')
|
category_b = Category.objects.create(label='Category B')
|
||||||
Agenda.objects.create(label='Other', kind='events', category=category)
|
Agenda.objects.create(label='Other', kind='events', category=category_b)
|
||||||
|
|
||||||
resp = app.get(url + '?agenda=other-agenda')
|
resp = app.get(url + '?agenda=other')
|
||||||
assert len(resp.json['data']['subfilters'][0]['options']) == 1
|
assert len(resp.json['data']['subfilters'][0]['options']) == 1
|
||||||
|
|
||||||
resp = app.get(url + '?category=category-b')
|
resp = app.get(url + '?agenda=category:category-b')
|
||||||
assert len(resp.json['data']['subfilters'][0]['options']) == 1
|
assert len(resp.json['data']['subfilters'][0]['options']) == 1
|
||||||
|
|
||||||
|
Agenda.objects.create(label='Meetings', kind='meetings', category=category_b)
|
||||||
|
|
||||||
|
resp = app.get(url + '?agenda=meetings')
|
||||||
|
assert resp.json['data']['subfilters'] == []
|
||||||
|
|
||||||
|
resp = app.get(url + '?agenda=category:category-b')
|
||||||
|
assert len(resp.json['data']['subfilters'][0]['options']) == 1
|
||||||
|
|
||||||
|
resp = app.get(url + '?agenda=xxx', status=400)
|
||||||
|
assert resp.json['err_desc'] == 'No agendas found.'
|
||||||
|
|
||||||
|
resp = app.get(url + '?agenda=category:xxx', status=400)
|
||||||
|
assert resp.json['err_desc'] == 'No agendas found.'
|
||||||
|
|
Loading…
Reference in New Issue