Skip to content

Commit

Permalink
feat: Updating enterprise-customer-support endpoint (#2199)
Browse files Browse the repository at this point in the history
* feat: adding search and ranking criteria for enterprise-customer-support endpoint

* feat: adding search and ranking criteria for enterprise-customer-support endpoint

* feat: updating ordering criteria

* style: lint fix

* chore: updating ordering logic

* style: lint fix

* feat: updating secondary sorting criteria to include first name

* chore: bumping up version num
  • Loading branch information
pmakwana93 authored Aug 13, 2024
1 parent d5d9e5a commit 67bb8e2
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ Unreleased
----------
* nothing unreleased

[4.23.8]
----------
* feat: updating enterprise-customer-support endpoint

[4.23.7]
---------
* feat: add migration for model updateroleassignmentswithcustomersconfig
Expand Down
2 changes: 1 addition & 1 deletion enterprise/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Your project description goes here.
"""

__version__ = "4.23.7"
__version__ = "4.23.8"
94 changes: 82 additions & 12 deletions enterprise/api/v1/views/enterprise_customer_support.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@
from collections import OrderedDict

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import permissions, response, status
from rest_framework import filters, permissions, response, status
from rest_framework.pagination import PageNumberPagination

from django.contrib import auth
from django.core.exceptions import ValidationError
from django.db.models import Q

from enterprise import models
from enterprise.api.v1 import serializers
from enterprise.api.v1.views.base_views import EnterpriseReadOnlyModelViewSet
from enterprise.logging import getEnterpriseLogger

User = auth.get_user_model()

LOGGER = getEnterpriseLogger(__name__)


Expand All @@ -40,9 +44,6 @@ def paginate_queryset(self, queryset, request, view=None):
Paginate a queryset if required, either returning a page object,
or `None` if pagination is not configured for this view.
This method is a modified version of the original `paginate_queryset` method
from the `PageNumberPagination` class. The original method was modified to
handle the case where the `queryset` is a `filter` object.
"""
if isinstance(queryset, filter):
queryset = list(queryset)
Expand All @@ -52,47 +53,116 @@ def paginate_queryset(self, queryset, request, view=None):

class EnterpriseCustomerSupportViewSet(EnterpriseReadOnlyModelViewSet):
"""
API views for the ``enterprise-user`` API endpoint.
API views for the ``enterprise-customer-support`` API endpoint.
"""
queryset = models.EnterpriseCustomerUser.objects.all()
filter_backends = (DjangoFilterBackend,)
queryset = models.PendingEnterpriseCustomerUser.objects.all()
filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
permission_classes = (permissions.IsAuthenticated,)
paginator = EnterpriseCustomerSupportPaginator()

USER_ID_FILTER = 'enterprise_customer_users__user_id'
ordering_fields = ['id']
filterset_fields = ['user_email']

def filter_queryset_by_email(self, queryset, is_pending_user=False):
"""
Filter queryset based on user provided email address
"""
filter_email = self.request.query_params.get('user_email', None)

if filter_email:
if not is_pending_user:
queryset = queryset.filter(
user_id__in=User.objects.filter(Q(email__icontains=filter_email))
)
else:
queryset = queryset.filter(user_email=filter_email)

return queryset

def retrieve(self, request, *args, **kwargs):
"""
- Filter down the queryset of groups available to the requesting uuid.
Filter down the queryset of groups available to the requesting uuid.
"""
enterprise_uuid = kwargs.get('enterprise_uuid', None)
users = []

try:
enterprise_customer_queryset = models.EnterpriseCustomerUser.objects.filter(
enterprise_customer__uuid=enterprise_uuid,
)
enterprise_customer_queryset = self.filter_queryset_by_email(enterprise_customer_queryset)
users.extend(enterprise_customer_queryset)

pending_enterprise_customer_queryset = models.PendingEnterpriseCustomerUser.objects.filter(
enterprise_customer__uuid=enterprise_uuid
).order_by('user_email')
pending_enterprise_customer_queryset = self.filter_queryset_by_email(
pending_enterprise_customer_queryset,
is_pending_user=True
)
users.extend(pending_enterprise_customer_queryset)

except ValidationError:
# did not find UUID match in either EnterpriseCustomerUser or PendingEnterpriseCustomerUser
# did not find UUID match in either EnterpriseCustomerUser or PendingEnterpriseCustomerUser
return response.Response(
{'detail': 'Could not find enterprise uuid {}'.format(enterprise_uuid)},
status=status.HTTP_404_NOT_FOUND
)

# default sort criteria
is_reversed = False
sort_field = 'first_name'

ordering_criteria = self.request.query_params.get('ordering', None)

# apply pre-serialization ordering by user criteria before the users
# get divvied up by pagination
if ordering_criteria:
is_reversed = '-' in ordering_criteria
sort_field = 'user_id'

# sort the users by default or specified criteria since the queryset will get
# split up during pagination and the post-serialization sort operations
# will be only applied to a single page of results
users = sorted(
users,
key=(
lambda k:
getattr(k, sort_field)
if hasattr(k, sort_field)
else k.id
),
reverse=is_reversed
)

# paginate the queryset
users_page = self.paginator.paginate_queryset(
users,
request,
view=self
)

# serialize the paged dataset
serializer = serializers.EnterpriseUserSerializer(
users_page,
many=True
)
serializer_data = sorted(
serializer.data, key=lambda k: k['is_admin'], reverse=True)
serializer_data = serializer.data

# Apply post-serialization default ordering criteria (first by is_admin,
# then first name) only if user does not specify ordering criteria;
# Process this after the data has been serialized since the is_admin
# field is computed/available only after serialization step
if not ordering_criteria:
serializer_data = sorted(
serializer_data,
key=lambda k: (
# sort by is_admin = True first (i.e. -1),
# then sort by first_name lexicographically
(-1 * k['is_admin'], k['enterprise_customer_user']['first_name'])
if k['enterprise_customer_user'] is not None
else -1 * k['is_admin']
)
)

return self.paginator.get_paginated_response(serializer_data)

0 comments on commit 67bb8e2

Please sign in to comment.