Commit c41a8877 by Matt Drayer

Merge pull request #10805 from edx/saleem-latif/SOL-1435

SOL-1435: Add Certificate Regeneration history table.
parents 68423989 1e16e873
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
from django.conf import settings
import model_utils.fields
import xmodule_django.models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('instructor_task', '0001_initial'),
('certificates', '0003_data__default_modes'),
]
operations = [
migrations.CreateModel(
name='CertificateGenerationHistory',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, verbose_name='created', editable=False)),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, verbose_name='modified', editable=False)),
('course_id', xmodule_django.models.CourseKeyField(max_length=255)),
('is_regeneration', models.BooleanField(default=False)),
('generated_by', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
('instructor_task', models.ForeignKey(to='instructor_task.InstructorTask')),
],
),
]
......@@ -68,6 +68,7 @@ from config_models.models import ConfigurationModel
from xmodule_django.models import CourseKeyField, NoneToEmptyManager
from util.milestones_helpers import fulfill_course_milestone, is_prerequisite_courses_enabled
from course_modes.models import CourseMode
from instructor_task.models import InstructorTask
LOGGER = logging.getLogger(__name__)
......@@ -236,6 +237,24 @@ class GeneratedCertificate(models.Model):
self.save()
class CertificateGenerationHistory(TimeStampedModel):
"""
Model for storing Certificate Generation History.
"""
course_id = CourseKeyField(max_length=255)
generated_by = models.ForeignKey(User)
instructor_task = models.ForeignKey(InstructorTask)
is_regeneration = models.BooleanField(default=False)
class Meta(object):
app_label = "certificates"
def __unicode__(self):
return u"certificates %s by %s on %s for %s" % \
("regenerated" if self.is_regeneration else "generated", self.generated_by, self.created, self.course_id)
@receiver(post_save, sender=GeneratedCertificate)
def handle_post_cert_generated(sender, instance, **kwargs): # pylint: disable=unused-argument
"""
......
......@@ -2679,7 +2679,7 @@ def start_certificate_generation(request, course_id):
Start generating certificates for all students enrolled in given course.
"""
course_key = CourseKey.from_string(course_id)
task = instructor_task.api.generate_certificates_for_all_students(request, course_key)
task = instructor_task.api.generate_certificates_for_students(request, course_key)
message = _('Certificate generation task for all students of this course has been started. '
'You can view the status of the generation task in the "Pending Tasks" section.')
response_payload = {
......
......@@ -31,6 +31,8 @@ from instructor_task.tasks import (
proctored_exam_results_csv
)
from certificates.models import CertificateGenerationHistory
from instructor_task.api_helper import (
check_arguments_for_rescoring,
encode_problem_and_student_input,
......@@ -422,20 +424,6 @@ def submit_cohort_students(request, course_key, file_name):
return submit_task(request, task_type, task_class, course_key, task_input, task_key)
def generate_certificates_for_all_students(request, course_key): # pylint: disable=invalid-name
"""
Submits a task to generate certificates for all students enrolled in the course.
Raises AlreadyRunningError if certificates are currently being generated.
"""
task_type = 'generate_certificates_all_student'
task_class = generate_certificates
task_input = {}
task_key = ""
return submit_task(request, task_type, task_class, course_key, task_input, task_key)
def generate_certificates_for_students(request, course_key, students=None): # pylint: disable=invalid-name
"""
Submits a task to generate certificates for given students enrolled in the course or
......@@ -453,8 +441,16 @@ def generate_certificates_for_students(request, course_key, students=None): # p
task_class = generate_certificates
task_key = ""
instructor_task = submit_task(request, task_type, task_class, course_key, task_input, task_key)
return submit_task(request, task_type, task_class, course_key, task_input, task_key)
CertificateGenerationHistory.objects.create(
course_id=course_key,
generated_by=request.user,
instructor_task=instructor_task,
is_regeneration=False
)
return instructor_task
def regenerate_certificates(request, course_key, statuses_to_regenerate, students=None):
......@@ -478,4 +474,13 @@ def regenerate_certificates(request, course_key, statuses_to_regenerate, student
task_class = generate_certificates
task_key = ""
return submit_task(request, task_type, task_class, course_key, task_input, task_key)
instructor_task = submit_task(request, task_type, task_class, course_key, task_input, task_key)
CertificateGenerationHistory.objects.create(
course_id=course_key,
generated_by=request.user,
instructor_task=instructor_task,
is_regeneration=True
)
return instructor_task
......@@ -21,7 +21,7 @@ from instructor_task.api import (
submit_calculate_may_enroll_csv,
submit_executive_summary_report,
submit_course_survey_report,
generate_certificates_for_all_students,
generate_certificates_for_students,
regenerate_certificates
)
......@@ -32,7 +32,7 @@ from instructor_task.tests.test_base import (InstructorTaskTestCase,
InstructorTaskModuleTestCase,
TestReportMixin,
TEST_COURSE_KEY)
from certificates.models import CertificateStatuses
from certificates.models import CertificateStatuses, CertificateGenerationHistory
class InstructorTaskReportTest(InstructorTaskTestCase):
......@@ -260,7 +260,7 @@ class InstructorTaskCourseSubmitTest(TestReportMixin, InstructorTaskCourseTestCa
"""
Tests certificates generation task submission api
"""
api_call = lambda: generate_certificates_for_all_students(
api_call = lambda: generate_certificates_for_students(
self.create_task_request(self.instructor),
self.course.id
)
......@@ -280,3 +280,36 @@ class InstructorTaskCourseSubmitTest(TestReportMixin, InstructorTaskCourseTestCa
[CertificateStatuses.downloadable, CertificateStatuses.generating]
)
self._test_resubmission(api_call)
def test_certificate_generation_history(self):
"""
Tests that a new record is added whenever certificate generation/regeneration task is submitted.
"""
instructor_task = generate_certificates_for_students(
self.create_task_request(self.instructor),
self.course.id
)
certificate_generation_history = CertificateGenerationHistory.objects.filter(
course_id=self.course.id,
generated_by=self.instructor,
instructor_task=instructor_task,
is_regeneration=False
)
# Validate that record was added to CertificateGenerationHistory
self.assertTrue(certificate_generation_history.exists())
instructor_task = regenerate_certificates(
self.create_task_request(self.instructor),
self.course.id,
[CertificateStatuses.downloadable, CertificateStatuses.generating]
)
certificate_generation_history = CertificateGenerationHistory.objects.filter(
course_id=self.course.id,
generated_by=self.instructor,
instructor_task=instructor_task,
is_regeneration=True
)
# Validate that record was added to CertificateGenerationHistory
self.assertTrue(certificate_generation_history.exists())
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment