def get_user_main_organization(self, user):
     main_user_organization = None
     mapped_user_organization =  user.user_attributes.all().filter(is_main_company=True).first()
     if mapped_user_organization:
         try:
             main_user_organization = Organization.objects.get(id=mapped_user_organization.organization_id)
         except ObjectDoesNotExist:
             pass
     main_user_organization = [main_user_organization] if main_user_organization else []
     return BasicOrganizationSerializer(main_user_organization, many=True, context=self.context).data
class UserSerializer(DynamicFieldsModelSerializer):
    """ Serializer for User model interactions """
    organizations = BasicOrganizationSerializer(many=True, required=False)
    created = serializers.DateTimeField(source='date_joined', required=False)
    avatar_url = serializers.CharField(source='profile.avatar_url')
    city = serializers.CharField(source='profile.city')
    title = serializers.CharField(source='profile.title')
    country = serializers.CharField(source='profile.country')
    full_name = serializers.CharField(source='profile.name')
    courses_enrolled = serializers.SerializerMethodField(
        'get_courses_enrolled')
    roles = serializers.SerializerMethodField('get_user_roles')
    grades = serializers.SerializerMethodField('get_user_grades')

    def get_courses_enrolled(self, user):
        """ Serialize user enrolled courses """
        if hasattr(user, 'courses_enrolled'):
            return user.courses_enrolled

        return user.courseenrollment_set.count

    def get_user_roles(self, user):
        """ returns list of user roles """
        queryset = CourseAccessRole.objects.filter(user=user)
        if 'course_id' in self.context:
            course_id = self.context['course_id']
            queryset = queryset.filter(course_id=course_id)

        return queryset.values_list('role', flat=True).distinct()

    def get_user_grades(self, user):
        """ returns user proforma_grade, grade and grade_summary """
        grade, proforma_grade, section_breakdown = None, None, None
        if 'course_id' in self.context:
            course_id = self.context['course_id']
            try:
                gradebook = StudentGradebook.objects.get(user=user,
                                                         course_id=course_id)
                grade = gradebook.grade
                proforma_grade = gradebook.proforma_grade
                section_breakdown = json.loads(
                    gradebook.grade_summary)["section_breakdown"]
            except ObjectDoesNotExist:
                pass

        return {
            'grade': grade,
            'proforma_grade': proforma_grade,
            'section_breakdown': section_breakdown
        }

    class Meta(object):
        """ Serializer/field specification """
        model = APIUser
        fields = (
            "id",
            "email",
            "username",
            "first_name",
            "last_name",
            "created",
            "is_active",
            "avatar_url",
            "city",
            "title",
            "country",
            "full_name",
            "is_staff",
            "last_login",
            "courses_enrolled",
            "organizations",
            "roles",
            "grades",
        )
        read_only_fields = ("id", "email", "username")
class UserSerializer(DynamicFieldsModelSerializer):
    """ Serializer for User model interactions """
    organizations = BasicOrganizationSerializer(many=True, required=False)
    created = serializers.DateTimeField(source='date_joined', required=False)
    profile_image = serializers.SerializerMethodField()
    city = serializers.CharField(source='profile.city')
    title = serializers.CharField(source='profile.title')
    country = serializers.CharField(source='profile.country')
    full_name = serializers.CharField(source='profile.name')
    courses_enrolled = serializers.SerializerMethodField()
    roles = serializers.SerializerMethodField('get_user_roles')
    grades = serializers.SerializerMethodField('get_user_grades')
    attributes = serializers.SerializerMethodField(
        'get_organization_attributes')
    course_groups = serializers.SerializerMethodField('get_user_course_groups')
    organization_groups = serializers.SerializerMethodField(
        'get_user_organization_groups')

    def get_user_organization_groups(self, user):
        """
        Return a list of user organization groups.
        """
        organization_groups = [{
            'organization_id': group.organization_id,
            'group_id': group.group_id,
        } for group in user.organizationgroupuser_set.all()]
        return organization_groups

    def get_user_course_groups(self, user):
        """Return a list of course groups of the users, optionally filtered by course id."""
        course_groups = user.course_groups.all()
        if 'course_id' in self.context:
            course_id = self.context['course_id']
            course_groups = [
                group.name for group in course_groups
                if group.course_id == course_id
            ]
        else:
            course_groups = [group.name for group in course_groups]
        return course_groups

    def get_organization_attributes(self, user):
        """
        Returns metadata about a user's attributes
        """
        attributes = []
        if 'active_attributes' in self.context:
            active_keys = [
                item['key'] for item in self.context['active_attributes']
            ]
            attributes = [{
                'key': item.key,
                'value': item.value,
                'organization_id': item.organization_id,
            } for item in user.user_attributes.all()
                          if item.key in active_keys]
        return attributes

    def get_profile_image(self, user):
        """
        Returns metadata about a user's profile image
        """
        try:
            profile_image_uploaded_at = user.profile.profile_image_uploaded_at
        except ObjectDoesNotExist:
            profile_image_uploaded_at = None
        return get_profile_image_urls_by_username(user.username,
                                                  profile_image_uploaded_at)

    def get_courses_enrolled(self, user):
        """ Serialize user enrolled courses """
        courses = user.courseenrollment_set.filter(is_active=True).values_list(
            'course_id', flat=True)
        return [str(course_id) for course_id in courses]

    def get_user_roles(self, user):
        """ returns list of user roles """
        access_roles = user.courseaccessrole_set.all()
        if 'course_id' in self.context:
            course_id = self.context['course_id']
            roles = [
                access_role.role for access_role in access_roles
                if access_role.course_id == course_id
            ]
        else:
            roles = [access_role.role for access_role in access_roles]

        return roles

    def get_user_grades(self, user):
        """ returns user proforma_grade, grade and grade_summary """
        grade, proforma_grade, section_breakdown = None, None, None
        gradebooks = user.studentgradebook_set.all()
        if 'course_id' in self.context and gradebooks:
            course_id = self.context['course_id']
            course_gradebook = next((gradebook for gradebook in gradebooks
                                     if gradebook.course_id == course_id),
                                    None)
            if course_gradebook:
                try:
                    grade = course_gradebook.grade
                    proforma_grade = course_gradebook.proforma_grade
                    grade_summary = json.loads(course_gradebook.grade_summary)
                    if "section_breakdown" in grade_summary:
                        section_breakdown = grade_summary["section_breakdown"]
                except (ObjectDoesNotExist, ValueError):
                    pass

        return {
            'grade': grade,
            'proforma_grade': proforma_grade,
            'section_breakdown': section_breakdown
        }

    class Meta:
        """ Serializer/field specification """
        model = APIUser
        fields = (
            "id",
            "email",
            "username",
            "first_name",
            "last_name",
            "created",
            "is_active",
            "profile_image",
            "city",
            "title",
            "country",
            "full_name",
            "is_staff",
            "last_login",
            "courses_enrolled",
            "organizations",
            "roles",
            "grades",
            "attributes",
            "course_groups",
            "organization_groups",
        )
        read_only_fields = ("id", "email", "username")
class UserSerializer(DynamicFieldsModelSerializer):
    """ Serializer for User model interactions """
    organizations = BasicOrganizationSerializer(many=True, required=False)
    created = serializers.DateTimeField(source='date_joined', required=False)
    profile_image = serializers.SerializerMethodField()
    city = serializers.CharField(source='profile.city')
    title = serializers.CharField(source='profile.title')
    country = serializers.CharField(source='profile.country')
    full_name = serializers.CharField(source='profile.name')
    courses_enrolled = serializers.SerializerMethodField()
    roles = serializers.SerializerMethodField('get_user_roles')
    grades = serializers.SerializerMethodField('get_user_grades')
    progress = serializers.SerializerMethodField('get_user_progress')

    def get_profile_image(self, user):
        """
        Returns metadata about a user's profile image
        """
        try:
            profile_image_uploaded_at = user.profile.profile_image_uploaded_at
        except ObjectDoesNotExist:
            profile_image_uploaded_at = None
        return get_profile_image_urls_by_username(user.username,
                                                  profile_image_uploaded_at)

    def get_courses_enrolled(self, user):
        """ Serialize user enrolled courses """
        enrollments = user.courseenrollment_set.all()
        return [unicode(enrollment.course_id) for enrollment in enrollments]

    def get_user_roles(self, user):
        """ returns list of user roles """
        access_roles = user.courseaccessrole_set.all()
        if 'course_id' in self.context:
            course_id = self.context['course_id']
            roles = [
                access_role.role for access_role in access_roles
                if access_role.course_id == course_id
            ]
        else:
            roles = [access_role.role for access_role in access_roles]

        return roles

    def get_user_grades(self, user):
        """ returns user proforma_grade, grade and grade_summary """
        grade, proforma_grade, section_breakdown = None, None, None
        gradebooks = user.studentgradebook_set.all()
        if 'course_id' in self.context and gradebooks:
            course_id = self.context['course_id']
            course_gradebook = next((gradebook for gradebook in gradebooks
                                     if gradebook.course_id == course_id),
                                    None)
            if course_gradebook:
                try:
                    grade = course_gradebook.grade
                    proforma_grade = course_gradebook.proforma_grade
                    grade_summary = json.loads(course_gradebook.grade_summary)
                    if "section_breakdown" in grade_summary:
                        section_breakdown = grade_summary["section_breakdown"]
                except (ObjectDoesNotExist, ValueError):
                    pass

        return {
            'grade': grade,
            'proforma_grade': proforma_grade,
            'section_breakdown': section_breakdown
        }

    def get_user_progress(self, user):
        """ returns user progress against course """
        completion_percentage = 0
        progress = user.studentprogress_set.all()
        if 'course_id' in self.context and progress:
            course_id = self.context['course_id']
            actual_completions = next(
                (progress_item.completions for progress_item in progress
                 if progress_item.course_id == course_id), 0)
            if self.context['course_meta_data']:
                total_possible_completions = self.context[
                    'course_meta_data'].total_assessments
                if total_possible_completions > 0:
                    completion_percentage = min(
                        int(
                            round(100 * actual_completions /
                                  float(total_possible_completions))), 100)
        return completion_percentage

    class Meta(object):
        """ Serializer/field specification """
        model = APIUser
        fields = (
            "id",
            "email",
            "username",
            "first_name",
            "last_name",
            "created",
            "is_active",
            "profile_image",
            "city",
            "title",
            "country",
            "full_name",
            "is_staff",
            "last_login",
            "courses_enrolled",
            "organizations",
            "roles",
            "grades",
            "progress",
        )
        read_only_fields = ("id", "email", "username")