Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: REST APIs (list/retrieve + learner-status) for DefaultEnterpriseEnrollmentIntention #2274

Merged
merged 8 commits into from
Oct 29, 2024
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
Loading