From 82bddb2c1351ba38e4cfab700b6660d5e61586aa Mon Sep 17 00:00:00 2001 From: Kyrylo Kholodenko Date: Mon, 9 Dec 2024 13:18:17 +0200 Subject: [PATCH] feat: [AXM-1169] adapt VC composition to course credentials --- .../composition/schemas.py | 29 +++++++++++++++++++ .../verifiable_credentials/issuance/models.py | 6 ++++ 2 files changed, 35 insertions(+) diff --git a/credentials/apps/verifiable_credentials/composition/schemas.py b/credentials/apps/verifiable_credentials/composition/schemas.py index ade36631c..42459674f 100644 --- a/credentials/apps/verifiable_credentials/composition/schemas.py +++ b/credentials/apps/verifiable_credentials/composition/schemas.py @@ -3,6 +3,7 @@ """ from rest_framework import serializers +from django.contrib.contenttypes.models import ContentType class EducationalOccupationalProgramSchema(serializers.Serializer): # pylint: disable=abstract-method @@ -20,6 +21,21 @@ class Meta: read_only_fields = "__all__" +class EducationalOccupationalCourseSchema(serializers.Serializer): # pylint: disable=abstract-method + """ + Defines Open edX Course. + """ + + TYPE = "Course" + + id = serializers.CharField(default=TYPE, help_text="https://schema.org/Course") + name = serializers.CharField(source="course.title") + courseCode = serializers.CharField(source="user_credential.credential.course_id") + + class Meta: + read_only_fields = "__all__" + + class EducationalOccupationalCredentialSchema(serializers.Serializer): # pylint: disable=abstract-method """ Defines Open edX user credential. @@ -31,6 +47,19 @@ class EducationalOccupationalCredentialSchema(serializers.Serializer): # pylint name = serializers.CharField(source="user_credential.credential.title") description = serializers.CharField(source="user_credential.uuid") program = EducationalOccupationalProgramSchema(source="*") + course = EducationalOccupationalCourseSchema(source="*") + + def to_representation(self, instance): + """ + Dynamically remove fields based on the type before serialization. + """ + program_content_type = ContentType.objects.get(app_label="credentials", model="programcertificate") + if instance.user_credential.credential_content_type == program_content_type: + self.fields.pop("course", None) + else: + self.fields.pop("program", None) + + return super().to_representation(instance) class Meta: read_only_fields = "__all__" diff --git a/credentials/apps/verifiable_credentials/issuance/models.py b/credentials/apps/verifiable_credentials/issuance/models.py index aaea75bb2..10ad3f246 100644 --- a/credentials/apps/verifiable_credentials/issuance/models.py +++ b/credentials/apps/verifiable_credentials/issuance/models.py @@ -12,6 +12,7 @@ from django.utils.translation import gettext_lazy as _ from django_extensions.db.models import TimeStampedModel +from credentials.apps.catalog.models import Course from credentials.apps.credentials.models import UserCredential from credentials.apps.verifiable_credentials.utils import capitalize_first @@ -183,6 +184,11 @@ def credential_content_type(self): def program(self): return getattr(self.user_credential.credential, "program", None) + @property + def course(self): + course_id = getattr(self.user_credential.credential, "course_id", None) + return Course.objects.filter(course_runs__key=course_id).first() + @property def platform_name(self): if not (site_configuration := getattr(self.user_credential.credential.site, "siteconfiguration", "")):