Skip to content

Commit

Permalink
fix: final changes to sorting
Browse files Browse the repository at this point in the history
  • Loading branch information
kiram15 committed Nov 20, 2024
1 parent 52a91e9 commit 3921683
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 74 deletions.
9 changes: 3 additions & 6 deletions enterprise/api/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1932,14 +1932,11 @@ def get_enterprise_customer_user(self, obj):
"""
Return either the member's name and email if it's the case that the member is realized, otherwise just email
"""

if user := obj:
return {
"user_email": user.user_email,
"name": user.name,
# "first_name": user.first_name,
# "last_name": user.last_name,
"date_joined": user.created.strftime("%Y-%m-%dT%H:%M:%SZ")
"email": user[0],
"joined_org": user[1].strftime("%b %d, %Y"),
"name": user[2],
}
return None

Expand Down
92 changes: 34 additions & 58 deletions enterprise/api/v1/views/enterprise_customer_members.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,14 @@
from rest_framework import 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 Case, CharField, F, Q, Value, When
from django.db import connection

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

try:
from common.djangoapps.student.models import UserProfile
except ImportError:
UserProfile = None

User = auth.get_user_model()
LOGGER = getEnterpriseLogger(__name__)


Expand Down Expand Up @@ -66,63 +59,46 @@ class EnterpriseCustomerMembersViewSet(EnterpriseReadOnlyModelViewSet):
permission_classes = (permissions.IsAuthenticated,)
paginator = EnterpriseCustomerMembersPaginator()

def filter_queryset_by_user_query(self, queryset):
"""
Filter queryset based on user provided query
"""
user_query = self.request.query_params.get("user_query", None)
if user_query:
queryset = queryset.filter(
Q(user_email__icontains=user_query) | Q(name__icontains=user_query)
)
return queryset

def get_members(self, request, *args, **kwargs):
"""
Get all members associated with that enterprise customer
"""
enterprise_uuid = kwargs.get("enterprise_uuid", None)
# Raw sql is picky about uuid format
uuid_no_dashes = str(enterprise_uuid).replace("-", "")
users = []
try:
# Because our main User table is not in this repo, and isn't connected through
# a foreign key (like enterprise_customer) and only the user_id attribute, we
# have to use django's extra() function in order to sort on the name before
# pagination. Not everyone has first and last filled out, so we also have to
# fetch the name from userprofile as well
enterprise_customer_queryset = models.EnterpriseCustomerUser.objects.filter(
enterprise_customer__uuid=enterprise_uuid
).extra(
select={'first_name': 'first_name', 'last_name': 'last_name'},
tables=['auth_user'],
where=['auth_user.id = enterprise_enterprisecustomeruser.user_id'],
).extra(
select={'full_name': 'name'},
tables=['auth_userprofile'],
where=['auth_userprofile.user_id = enterprise_enterprisecustomeruser.user_id']
)
user_query = self.request.query_params.get("user_query", None)

# raise Exception(enterprise_customer_queryset[0].__dir__())
print('hi kira!')
print('first name', enterprise_customer_queryset[0].first_name)
print('last name', enterprise_customer_queryset[0].last_name)
print('full name', enterprise_customer_queryset[0].full_name)


# We need to combine users with first/last and full into one 'name'
# column, so then we can order by that
enterprise_customer_queryset = enterprise_customer_queryset.annotate(
name=Case(
When(full_name__isnull=True,first_name__isnull=False, then=F('first_name') + ' ' + F('last_name')),
When(first_name__isnull=True,full_name__isnull=False, then=F('full_name')),
default=Value(None),
output_field=CharField(),
)
).order_by('name')

enterprise_customer_queryset = self.filter_queryset_by_user_query(
enterprise_customer_queryset
)
users.extend(enterprise_customer_queryset)
# On logistration, the name field of auth_userprofile is populated, but if it's not
# filled in, we check the auth_user model for it's first/last name fields
# https://2u-internal.atlassian.net/wiki/spaces/ENGAGE/pages/747143186/Use+of+full+name+in+edX#Data-on-Name-Field
query = """
WITH users AS (
SELECT
au.email,
au.date_joined,
coalesce(NULLIF(aup.name, ''), concat(au.first_name, ' ', au.last_name)) as full_name
FROM enterprise_enterprisecustomeruser ecu
INNER JOIN auth_user as au on ecu.user_id = au.id
LEFT JOIN auth_userprofile as aup on au.id = aup.user_id
WHERE ecu.enterprise_customer_id = %s
) SELECT * FROM users {user_query_filter} ORDER BY full_name;
"""
try:
with connection.cursor() as cursor:
if user_query:
like_user_query = f"%{user_query}%"
sql_to_execute = query.format(
user_query_filter="WHERE full_name LIKE %s OR email LIKE %s"
)
cursor.execute(
sql_to_execute,
[uuid_no_dashes, like_user_query, like_user_query],
)
else:
sql_to_execute = query.format(user_query_filter="")
cursor.execute(sql_to_execute, [uuid_no_dashes])
users.extend(cursor.fetchall())

except ValidationError:
# did not find UUID match in either EnterpriseCustomerUser
Expand Down
11 changes: 4 additions & 7 deletions tests/test_enterprise/api/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,25 +590,22 @@ def test_serialize_users(self):
expected_user = {
'enrollments': 2,
'enterprise_customer_user': {
'user_email': self.user_1.email,
'email': self.user_1.email,
'joined_org': self.user_1.date_joined.strftime("%b %d, %Y"),
'name': (self.user_1.first_name + ' ' + self.user_1.last_name),
'date_joined': self.enterprise_customer_user_1.created.strftime("%Y-%m-%dT%H:%M:%SZ"),
},
}
serializer = EnterpriseMembersSerializer(self.enterprise_customer_user_1)
serialized_user = serializer.data

print('serialized ', serialized_user)
print('expected ', expected_user)

self.assertEqual(serialized_user, expected_user)

expected_user_2 = {
'enrollments': 1,
'enterprise_customer_user': {
'user_email': self.user_2.email,
'email': self.user_2.email,
'joined_org': self.user_2.date_joined.strftime("%b %d, %Y"),
'name': self.user_2.first_name + ' ' + self.user_2.last_name,
'date_joined': self.enterprise_customer_user_2.created.strftime("%Y-%m-%dT%H:%M:%SZ"),
},
}

Expand Down
17 changes: 14 additions & 3 deletions tests/test_enterprise/api/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -9990,6 +9990,8 @@ def test_get_enterprise_org_members(self):
user_1 = factories.UserFactory(first_name="Rhaenyra", last_name="Targaryen")
user_2 = factories.UserFactory(first_name="Jace", last_name="Targaryen")
user_3 = factories.UserFactory(first_name="Alicent", last_name="Hightower")
user_4 = factories.UserFactory(first_name="Helaena", last_name="Targaryen")
user_5 = factories.UserFactory(first_name="Laenor", last_name="Velaryon")

enterprise_customer = factories.EnterpriseCustomerFactory(uuid=FAKE_UUIDS[0])
factories.EnterpriseCustomerUserFactory(
Expand All @@ -10004,6 +10006,14 @@ def test_get_enterprise_org_members(self):
user_id=user_3.id,
enterprise_customer=enterprise_customer
)
factories.EnterpriseCustomerUserFactory(
user_id=user_4.id,
enterprise_customer=enterprise_customer
)
factories.EnterpriseCustomerUserFactory(
user_id=user_5.id,
enterprise_customer=enterprise_customer
)

# Test invalid UUID
url = reverse(self.ECM_ENDPOINT, kwargs={self.ECM_KWARG: 123})
Expand All @@ -10017,8 +10027,10 @@ def test_get_enterprise_org_members(self):

# list should be sorted alphabetically by name
self.assertEqual(data[0]['enterprise_customer_user']['name'], (user_3.first_name + ' ' + user_3.last_name))
self.assertEqual(data[1]['enterprise_customer_user']['name'], (user_2.first_name + ' ' + user_2.last_name))
self.assertEqual(data[2]['enterprise_customer_user']['name'], (user_1.first_name + ' ' + user_1.last_name))
self.assertEqual(data[1]['enterprise_customer_user']['name'], (user_4.first_name + ' ' + user_4.last_name))
self.assertEqual(data[2]['enterprise_customer_user']['name'], (user_2.first_name + ' ' + user_2.last_name))
self.assertEqual(data[3]['enterprise_customer_user']['name'], (user_5.first_name + ' ' + user_5.last_name))
self.assertEqual(data[4]['enterprise_customer_user']['name'], (user_1.first_name + ' ' + user_1.last_name))

# use user query to filter by name
name_query = f'?user_query={user_2.first_name}'
Expand All @@ -10028,7 +10040,6 @@ def test_get_enterprise_org_members(self):
data = response.json().get('results')
self.assertEqual(len(data), 1)
self.assertEqual(data[0]['enterprise_customer_user']['name'], (user_2.first_name + ' ' + user_2.last_name))
self.assertEqual(1, 2)


@ddt.ddt
Expand Down

0 comments on commit 3921683

Please sign in to comment.