Exemplo n.º 1
0
    def _get_credentials(self):
        """Returns two lists of credentials: a course list and a program list"""
        # Get the content types for course and program certs, query for both in single query
        course_cert_content_types = ContentType.objects.filter(
            app_label="credentials",
            model__in=["coursecertificate", "programcertificate"])
        course_certificate_type = None
        program_certificate_type = None
        for course_cert_content_type in course_cert_content_types:
            if course_cert_content_type.model == "coursecertificate":
                course_certificate_type = course_cert_content_type
            elif course_cert_content_type.model == "programcertificate":
                program_certificate_type = course_cert_content_type

        # Get all user credentials, then sort them out to course/programs
        user_credentials = filter_visible(
            UserCredential.objects.filter(
                username=self.request.user.username,
                status=UserCredential.AWARDED,
                credential_content_type__in=course_cert_content_types,
            ))
        course_credentials = []
        program_credentials = []
        for credential in user_credentials:
            if credential.credential_content_type_id == course_certificate_type.id:
                course_credentials.append(credential)
            elif credential.credential_content_type_id == program_certificate_type.id:
                program_credentials.append(credential)

        return course_credentials, program_credentials
Exemplo n.º 2
0
def handle_only_visible(qs, _name, value):
    return filter_visible(qs) if value else qs
Exemplo n.º 3
0
def get_record_data(user, program_uuid, site, platform_name=None):
    program = Program.objects.prefetch_related("course_runs__course").get(
        uuid=program_uuid, site=site)
    program_course_runs = program.course_runs.all()
    program_course_runs_set = frozenset(program_course_runs)

    # Get all pathway organizations and their statuses
    program_pathways = program.pathways.all()
    program_pathways_set = frozenset(program_pathways)
    user_credit_pathways = (
        UserCreditPathway.objects.select_related("pathway").filter(
            user=user, pathway__in=program_pathways_set).all())
    user_credit_pathways_dict = {
        user_pathway.pathway: user_pathway.status
        for user_pathway in user_credit_pathways
    }
    pathways = [(pathway, user_credit_pathways_dict.setdefault(pathway, ""))
                for pathway in program_pathways]

    # Find program credential if it exists (indicates if user has completed this program)
    program_credential_query = filter_visible(
        UserCredential.objects.filter(
            username=user.username,
            status=UserCredential.AWARDED,
            program_credentials__program_uuid=program_uuid))

    # Get all of the user course-certificates associated with the program courses (including not AWARDED ones)
    course_certificate_content_type = ContentType.objects.get(
        app_label="credentials", model="coursecertificate")
    course_user_credentials = filter_visible(
        UserCredential.objects.prefetch_related("credential").filter(
            username=user.username,
            credential_content_type=course_certificate_content_type,
        ))

    # Maps course run key to the associated credential
    user_credential_dict = {
        user_credential.credential.course_id: user_credential
        for user_credential in course_user_credentials
    }

    # Maps credentials to visible_date datetimes (a date when the cert becomes valid)
    visible_dates = get_credential_visible_dates(course_user_credentials)

    # Get all (verified) user grades relevant to this program
    course_grades = UserGrade.objects.select_related(
        "course_run__course").filter(username=user.username,
                                     course_run__in=program_course_runs_set,
                                     verified=True)

    # Keep track of number of attempts and best attempt per course
    num_attempts_dict = defaultdict(int)
    highest_attempt_dict = {}  # Maps course -> highest grade earned
    last_updated = None

    # Find the highest course cert grades for each course
    for course_grade in course_grades:
        course_run = course_grade.course_run
        course = course_run.course
        user_credential = user_credential_dict.get(course_run.key)

        if user_credential is not None:
            num_attempts_dict[course] += 1
            visible_date = visible_dates[user_credential]
            last_updated = max(
                filter(None,
                       [visible_date, course_grade.modified, last_updated]))

            # Update grade if grade is higher and part of awarded cert
            if user_credential.status == UserCredential.AWARDED:
                current = highest_attempt_dict.setdefault(course, course_grade)
                if course_grade.percent_grade > current.percent_grade:
                    highest_attempt_dict[course] = course_grade

    last_updated = last_updated or datetime.datetime.today()

    learner_data = {
        "full_name": user.get_full_name(),
        "username": user.username,
        "email": user.email,
    }

    program_data = {
        "name":
        program.title,
        "type":
        slugify(program.type),
        "type_name":
        program.type,
        "completed":
        program_credential_query.exists(),
        "empty":
        not highest_attempt_dict,
        "last_updated":
        last_updated.isoformat(),
        "school":
        ", ".join(
            program.authoring_organizations.values_list("name", flat=True)),
    }

    pathway_data = [{
        "name": pathway[0].name,
        "id": pathway[0].id,
        "status": pathway[1],
        "is_active": bool(pathway[0].email),
        "pathway_type": pathway[0].pathway_type,
    } for pathway in pathways]

    # Add course-run data to the response in the order that is maintained by the Program's sorted field
    course_data = []
    added_courses = set()
    for course_run in program_course_runs:
        course = course_run.course
        grade = highest_attempt_dict.get(course)

        # If user hasn't taken this course yet, or doesn't have a cert, we want to show empty values
        if grade is None and course not in added_courses:
            course_data.append({
                "name":
                course.title,
                "school":
                ", ".join(course.owners.values_list("name", flat=True)),
                "attempts":
                0,
                "course_id":
                "",
                "issue_date":
                "",
                "percent_grade":
                0.0,
                "letter_grade":
                "",
            })
            added_courses.add(course)

        # If the user has taken the course, show the course_run info for the highest grade
        elif grade is not None and grade.course_run == course_run:
            issue_date = visible_dates[user_credential_dict[course_run.key]]
            course_data.append({
                "name":
                course_run.title,
                "school":
                ", ".join(course.owners.values_list("name", flat=True)),
                "attempts":
                num_attempts_dict[course],
                "course_id":
                course_run.key,
                "issue_date":
                issue_date.isoformat(),
                "percent_grade":
                float(grade.percent_grade),
                "letter_grade":
                grade.letter_grade or _("N/A"),
            })
            added_courses.add(course)

    return {
        "learner": learner_data,
        "program": program_data,
        "platform_name": platform_name,
        "grades": course_data,
        "pathways": pathway_data,
    }