Skip to content
Snippets Groups Projects
models.py 46.9 KiB
Newer Older
        Returns:
            VerificationStatus object if found any else None
        """
        try:
            return self.checkpoint_status.filter(user_id=user_id).latest()  # pylint: disable=E1101
        except ObjectDoesNotExist:
            return None

    @classmethod
    def get_verification_checkpoint(cls, course_id, checkpoint_name):
        """Get the verification checkpoint for given course_id and checkpoint name

        Arguments:
            course_id(CourseKey): CourseKey
            checkpoint_name(str): checkpoint name

        Returns:
            VerificationCheckpoint object if exists otherwise None
        """
        try:
            return cls.objects.get(course_id=course_id, checkpoint_name=checkpoint_name)
        except cls.DoesNotExist:
            return None


class VerificationStatus(models.Model):
    """A verification status represents a user’s progress
    through the verification process for a particular checkpoint
    Model is an append-only table that represents the user status changes in
    verification process
    """

    VERIFICATION_STATUS_CHOICES = (
        ("submitted", "submitted"),
        ("approved", "approved"),
        ("denied", "denied"),
        ("error", "error")
    )

    checkpoint = models.ForeignKey(VerificationCheckpoint, related_name="checkpoint_status")
    user = models.ForeignKey(User)
    status = models.CharField(choices=VERIFICATION_STATUS_CHOICES, db_index=True, max_length=32)
    timestamp = models.DateTimeField(auto_now_add=True)
    response = models.TextField(null=True, blank=True)
    error = models.TextField(null=True, blank=True)

    # This field is used to save location of Reverification module in courseware
    location_id = models.CharField(
        null=True,
        blank=True,
        max_length=255,
        help_text=ugettext_lazy("Usage id of Reverification XBlock.")
    )

    class Meta(object):  # pylint: disable=missing-docstring
        get_latest_by = "timestamp"
        verbose_name = "Verification Status"
        verbose_name_plural = "Verification Statuses"
    @classmethod
    def add_verification_status(cls, checkpoint, user, status, location_id=None):
        """ Create new verification status object

        Arguments:
            checkpoint(VerificationCheckpoint): VerificationCheckpoint object
            user(User): user object
            status(str): String representing the status from VERIFICATION_STATUS_CHOICES
            location_id(str): Usage key of Reverification XBlock
        Returns:
            None
        """
        cls.objects.create(checkpoint=checkpoint, user=user, status=status, location_id=location_id)

    @classmethod
    def add_status_from_checkpoints(cls, checkpoints, user, status):
        """ Create new verification status objects against the given checkpoints

        Arguments:
            checkpoints(list): list of VerificationCheckpoint objects
            user(User): user object
            status(str): String representing the status from VERIFICATION_STATUS_CHOICES
        Returns:
            None
        """
        for checkpoint in checkpoints:
            # get 'location_id' from last entry (if it exists) and add it in
            # new entry
            try:
                location_id = cls.objects.filter(checkpoint=checkpoint).latest().location_id
            except cls.DoesNotExist:

            cls.objects.create(checkpoint=checkpoint, user=user, status=status, location_id=location_id)
    @classmethod
    def get_user_attempts(cls, user_id, course_key, related_assessment, location_id):
        """
        Get re-verification attempts against a user for a given 'checkpoint'
        and 'course_id'.

        Arguments:
            user_id(str): User Id string
            course_key(str): A CourseKey of a course
            related_assessment(str): Verification checkpoint name
            location_id(str): Location of Reverification XBlock in courseware

        Returns:
            count of re-verification attempts
        """

        return cls.objects.filter(
            user_id=user_id,
            checkpoint__course_id=course_key,
            checkpoint__checkpoint_name=related_assessment,
            location_id=location_id,
            status="submitted"
        ).count()

    @classmethod
    def get_location_id(cls, photo_verification):
        """ Return the location id of xblock

        Args:
            photo_verification(SoftwareSecurePhotoVerification): SoftwareSecurePhotoVerification object

        Return:
            Location Id of xblock if any else empty string
        """
        try:
            ver_status = cls.objects.filter(checkpoint__photo_verification=photo_verification).latest()
            return ver_status.location_id
        except cls.DoesNotExist:
            return ""


class InCourseReverificationConfiguration(ConfigurationModel):
    """Configure in-course re-verification.

    Enable or disable in-course re-verification feature.
    When this flag is disabled, the "in-course re-verification" feature
    will be disabled.

    When the flag is enabled, the "in-course re-verification" feature
    will be enabled.

    """
    pass


class SkippedReverification(models.Model):
    """
    Model for tracking skipped Reverification of a user against a specific
    course.
    If user skipped the Reverification for a specific course then in future
    user cannot see the reverification link.
    """
    user = models.ForeignKey(User)
    course_id = CourseKeyField(max_length=255, db_index=True)
    checkpoint = models.ForeignKey(VerificationCheckpoint, related_name="skipped_checkpoint")
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:  # pylint: disable=missing-docstring, old-style-class
        unique_together = (('user', 'course_id'),)

    @classmethod
    def add_skipped_reverification_attempt(cls, checkpoint, user_id, course_id):
        """ Create skipped reverification object

        Arguments:
            checkpoint(VerificationCheckpoint): VerificationCheckpoint object
            user_id(str): User Id of currently logged in user
            course_id(CourseKey): CourseKey
        Returns:
            None
        """
        cls.objects.create(checkpoint=checkpoint, user_id=user_id, course_id=course_id)

    @classmethod
    def check_user_skipped_reverification_exists(cls, user, course_id):
        """Check user skipped re-verification attempt exists against specific course

        Arguments:
            user(User): user object
            course_id(CourseKey): CourseKey
        Returns:
            Boolean
        """
        return cls.objects.filter(user=user, course_id=course_id).exists()