Skip to content
Snippets Groups Projects
models.py 46.3 KiB
Newer Older
            if (expiration_datetime - datetime.now(pytz.UTC)).days <= settings.VERIFY_STUDENT.get(
                    "EXPIRING_SOON_WINDOW"):
                return True

        return False

class VerificationDeadline(TimeStampedModel):
    """
    Represent a verification deadline for a particular course.

    The verification deadline is the datetime after which
    users are no longer allowed to submit photos for initial verification
    in a course.

    Note that this is NOT the same as the "upgrade" deadline, after
    which a user is no longer allowed to upgrade to a verified enrollment.

    If no verification deadline record exists for a course,
    then that course does not have a deadline.  This means that users
    can submit photos at any time.
    """
    class Meta(object):
        app_label = "verify_student"

    course_key = CourseKeyField(
        max_length=255,
        db_index=True,
        unique=True,
        help_text=ugettext_lazy(u"The course for which this deadline applies"),
    )

    deadline = models.DateTimeField(
        help_text=ugettext_lazy(
            u"The datetime after which users are no longer allowed "
            u"to submit photos for verification."
        )
    )

    # The system prefers to set this automatically based on default settings. But
    # if the field is set manually we want a way to indicate that so we don't
    # overwrite the manual setting of the field.
    deadline_is_explicit = models.BooleanField(default=False)
    ALL_DEADLINES_CACHE_KEY = "verify_student.all_verification_deadlines"

    @classmethod
    def set_deadline(cls, course_key, deadline, is_explicit=False):
        """
        Configure the verification deadline for a course.

        If `deadline` is `None`, then the course will have no verification
        deadline.  In this case, users will be able to verify for the course
        at any time.

        Arguments:
            course_key (CourseKey): Identifier for the course.
            deadline (datetime or None): The verification deadline.

        """
        if deadline is None:
            VerificationDeadline.objects.filter(course_key=course_key).delete()
        else:
            record, created = VerificationDeadline.objects.get_or_create(
                course_key=course_key,
                defaults={"deadline": deadline, "deadline_is_explicit": is_explicit}
            )

            if not created:
                record.deadline = deadline
                record.deadline_is_explicit = is_explicit
                record.save()

    @classmethod
    def deadlines_for_courses(cls, course_keys):
        """
        Retrieve verification deadlines for particular courses.

        Arguments:
            course_keys (list): List of `CourseKey`s.

        Returns:
            dict: Map of course keys to datetimes (verification deadlines)

        """
        all_deadlines = cache.get(cls.ALL_DEADLINES_CACHE_KEY)
        if all_deadlines is None:
            all_deadlines = {
                deadline.course_key: deadline.deadline
                for deadline in VerificationDeadline.objects.all()
            }
            cache.set(cls.ALL_DEADLINES_CACHE_KEY, all_deadlines)

        return {
            course_key: all_deadlines[course_key]
            for course_key in course_keys
            if course_key in all_deadlines
        }

    @classmethod
    def deadline_for_course(cls, course_key):
        """
        Retrieve the verification deadline for a particular course.

        Arguments:
            course_key (CourseKey): The identifier for the course.

        Returns:
            datetime or None

        """
        try:
            deadline = cls.objects.get(course_key=course_key)
            return deadline.deadline
        except cls.DoesNotExist:
            return None


@receiver(models.signals.post_save, sender=VerificationDeadline)
@receiver(models.signals.post_delete, sender=VerificationDeadline)
def invalidate_deadline_caches(sender, **kwargs):  # pylint: disable=unused-argument
    """Invalidate the cached verification deadline information. """
    cache.delete(VerificationDeadline.ALL_DEADLINES_CACHE_KEY)


Eric Fischer's avatar
Eric Fischer committed
class VerificationCheckpoint(DeprecatedModelMixin, models.Model):  # pylint: disable=model-missing-unicode
    """
    DEPRECATED - do not use. To be removed in a future Open edX release (Hawthorn).
    course_id = CourseKeyField(max_length=255, db_index=True)
    checkpoint_location = models.CharField(max_length=255)
    photo_verification = models.ManyToManyField(SoftwareSecurePhotoVerification)

    class Meta(object):
        app_label = "verify_student"
        unique_together = ('course_id', 'checkpoint_location')
Eric Fischer's avatar
Eric Fischer committed
class VerificationStatus(DeprecatedModelMixin, models.Model):  # pylint: disable=model-missing-unicode
    """
    DEPRECATED - do not use. To be removed in a future Open edX release (Hawthorn).
    SUBMITTED_STATUS = "submitted"
    APPROVED_STATUS = "approved"
    DENIED_STATUS = "denied"
    ERROR_STATUS = "error"

    VERIFICATION_STATUS_CHOICES = (
        (SUBMITTED_STATUS, SUBMITTED_STATUS),
        (APPROVED_STATUS, APPROVED_STATUS),
        (DENIED_STATUS, DENIED_STATUS),
        (ERROR_STATUS, ERROR_STATUS)
    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)

    class Meta(object):
        app_label = "verify_student"
        verbose_name = "Verification Status"
        verbose_name_plural = "Verification Statuses"
Eric Fischer's avatar
Eric Fischer committed
class InCourseReverificationConfiguration(DeprecatedModelMixin, ConfigurationModel):  # pylint: disable=model-missing-unicode
    """
    DEPRECATED - do not use. To be removed in a future Open edX release (Hawthorn).
Eric Fischer's avatar
Eric Fischer committed
class IcrvStatusEmailsConfiguration(DeprecatedModelMixin, ConfigurationModel):  # pylint: disable=model-missing-unicode
    """
    DEPRECATED - do not use. To be removed in a future Open edX release (Hawthorn).
Eric Fischer's avatar
Eric Fischer committed
class SkippedReverification(DeprecatedModelMixin, models.Model):  # pylint: disable=model-missing-unicode
    """
    DEPRECATED - do not use. To be removed in a future Open edX release (Hawthorn).
    """
    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(object):
        app_label = "verify_student"
        unique_together = (('user', 'course_id'),)