Skip to content

Commit

Permalink
feat: REST APIs (list/retrieve + learner-status) for `DefaultEnterp…
Browse files Browse the repository at this point in the history
…riseEnrollmentIntention` (#2274)
  • Loading branch information
adamstankiewicz authored Oct 29, 2024
1 parent 3e127f4 commit b9025f8
Show file tree
Hide file tree
Showing 23 changed files with 1,436 additions and 97 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.30.0]
--------
* feat: REST APIs for default-enterprise-enrollment-intentions

[4.29.0]
--------
* feat: Create django admin for default enrollments
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.29.0"
__version__ = "4.30.0"
2 changes: 1 addition & 1 deletion enterprise/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1394,7 +1394,7 @@ class DefaultEnterpriseEnrollmentIntentionAdmin(admin.ModelAdmin):
class Meta:
model = models.DefaultEnterpriseEnrollmentIntention

def get_queryset(self, request): # pylint: disable=unused-argument
def get_queryset(self, request):
"""
Return a QuerySet of all model instances.
"""
Expand Down
167 changes: 167 additions & 0 deletions enterprise/api/v1/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1894,3 +1894,170 @@ def get_role_assignments(self, obj):
return role_assignments_by_ecu_id
else:
return None


class DefaultEnterpriseEnrollmentIntentionSerializer(serializers.ModelSerializer):
"""
Serializer for the DefaultEnterpriseEnrollmentIntention model.
"""

course_run_key = serializers.SerializerMethodField()
is_course_run_enrollable = serializers.SerializerMethodField()
course_run_normalized_metadata = serializers.SerializerMethodField()
applicable_enterprise_catalog_uuids = serializers.SerializerMethodField()

class Meta:
model = models.DefaultEnterpriseEnrollmentIntention
fields = (
'uuid',
'content_key',
'enterprise_customer',
'course_key',
'course_run_key',
'is_course_run_enrollable',
'applicable_enterprise_catalog_uuids',
'course_run_normalized_metadata',
'created',
'modified',
)

def get_course_run_key(self, obj):
"""
Get the course run key for the enrollment intention
"""
return obj.course_run_key

def get_is_course_run_enrollable(self, obj):
"""
Get the course run enrollable status for the enrollment intention
"""
return obj.is_course_run_enrollable

def get_course_run_normalized_metadata(self, obj):
"""
Get the course run for the enrollment intention
"""
return obj.course_run_normalized_metadata

def get_applicable_enterprise_catalog_uuids(self, obj):
return obj.applicable_enterprise_catalog_uuids


class DefaultEnterpriseEnrollmentIntentionWithEnrollmentStateSerializer(DefaultEnterpriseEnrollmentIntentionSerializer):
"""
Serializer for the DefaultEnterpriseEnrollmentIntention model with enrollment state.
"""
has_existing_enrollment = serializers.SerializerMethodField()
is_existing_enrollment_active = serializers.SerializerMethodField()
is_existing_enrollment_audit = serializers.SerializerMethodField()

class Meta(DefaultEnterpriseEnrollmentIntentionSerializer.Meta):
fields = DefaultEnterpriseEnrollmentIntentionSerializer.Meta.fields + (
'has_existing_enrollment',
'is_existing_enrollment_active',
'is_existing_enrollment_audit',
)

def get_has_existing_enrollment(self, obj): # pylint: disable=unused-argument
return bool(self.context.get('existing_enrollment', None))

def get_is_existing_enrollment_active(self, obj): # pylint: disable=unused-argument
existing_enrollment = self.context.get('existing_enrollment', None)
if not existing_enrollment:
return None
return existing_enrollment.is_active

def get_is_existing_enrollment_audit(self, obj): # pylint: disable=unused-argument
existing_enrollment = self.context.get('existing_enrollment', None)
if not existing_enrollment:
return None
return existing_enrollment.is_audit_enrollment


class DefaultEnterpriseEnrollmentIntentionLearnerStatusSerializer(serializers.Serializer):
"""
Serializer for the DefaultEnterpriseEnrollmentIntentionLearnerStatus model.
"""

lms_user_id = serializers.IntegerField()
user_email = serializers.EmailField()
enterprise_customer_uuid = serializers.UUIDField()
enrollment_statuses = serializers.SerializerMethodField()
metadata = serializers.SerializerMethodField()

def needs_enrollment_counts(self):
"""
Return the counts of needs_enrollment.
"""
needs_enrollment = self.context.get('needs_enrollment', {})
needs_enrollment_enrollable = needs_enrollment.get('enrollable', [])
needs_enrollment_not_enrollable = needs_enrollment.get('not_enrollable', [])

return {
'enrollable': len(needs_enrollment_enrollable),
'not_enrollable': len(needs_enrollment_not_enrollable),
}

def already_enrolled_count(self):
"""
Return the count of already enrolled.
"""
already_enrolled = self.context.get('already_enrolled', {})
return len(already_enrolled)

def total_default_enrollment_intention_count(self):
"""
Return the total count of default enrollment intentions.
"""
needs_enrollment_counts = self.needs_enrollment_counts()
total_needs_enrollment_enrollable = needs_enrollment_counts['enrollable']
total_needs_enrollment_not_enrollable = needs_enrollment_counts['not_enrollable']
return total_needs_enrollment_enrollable + total_needs_enrollment_not_enrollable + self.already_enrolled_count()

def serialize_intentions(self, default_enrollment_intentions):
"""
Helper function to handle tuple unpacking and serialization.
"""
serialized_data = []
for intention_tuple in default_enrollment_intentions:
intention, existing_enrollment = intention_tuple
data = DefaultEnterpriseEnrollmentIntentionWithEnrollmentStateSerializer(
intention,
context={'existing_enrollment': existing_enrollment},
).data
serialized_data.append(data)
return serialized_data

def get_enrollment_statuses(self, obj): # pylint: disable=unused-argument
"""
Return default enterprise enrollment intentions partitioned by
the enrollment statuses for the learner.
"""
needs_enrollment = self.context.get('needs_enrollment', {})
needs_enrollment_enrollable = needs_enrollment.get('enrollable', [])
needs_enrollment_not_enrollable = needs_enrollment.get('not_enrollable', [])
already_enrolled = self.context.get('already_enrolled', {})

needs_enrollment_enrollable_data = self.serialize_intentions(needs_enrollment_enrollable)
needs_enrollment_not_enrollable_data = self.serialize_intentions(needs_enrollment_not_enrollable)
already_enrolled_data = self.serialize_intentions(already_enrolled)

return {
'needs_enrollment': {
'enrollable': needs_enrollment_enrollable_data,
'not_enrollable': needs_enrollment_not_enrollable_data,
},
'already_enrolled': already_enrolled_data,
}

def get_metadata(self, obj): # pylint: disable=unused-argument
"""
Return the metadata for the default enterprise enrollment intention, including
number of default enterprise enrollment intentions that need enrollment, are already
enrolled by the learner.
"""
return {
'total_default_enterprise_course_enrollments': self.total_default_enrollment_intention_count(),
'total_needs_enrollment': self.needs_enrollment_counts(),
'total_already_enrolled': self.already_enrolled_count(),
}
6 changes: 6 additions & 0 deletions enterprise/api/v1/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from enterprise.api.v1.views import (
analytics_summary,
coupon_codes,
default_enterprise_enrollments,
enterprise_catalog_query,
enterprise_course_enrollment,
enterprise_customer,
Expand Down Expand Up @@ -82,6 +83,11 @@
router.register(
"enterprise_group", enterprise_group.EnterpriseGroupViewSet, 'enterprise-group'
)
router.register(
"default-enterprise-enrollment-intentions",
default_enterprise_enrollments.DefaultEnterpriseEnrollmentIntentionViewSet,
'default-enterprise-enrollment-intentions'
)


urlpatterns = [
Expand Down
Loading

0 comments on commit b9025f8

Please sign in to comment.