diff --git a/lms/djangoapps/certificates/migrations/0031_certificatedateoverride_historicalcertificatedateoverride.py b/lms/djangoapps/certificates/migrations/0031_certificatedateoverride_historicalcertificatedateoverride.py new file mode 100644 index 0000000000000000000000000000000000000000..b8532a29e770b123f3cbcf137f38dea0f938fab6 --- /dev/null +++ b/lms/djangoapps/certificates/migrations/0031_certificatedateoverride_historicalcertificatedateoverride.py @@ -0,0 +1,54 @@ +# Generated by Django 2.2.24 on 2021-08-02 17:24 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import django.utils.timezone +import model_utils.fields +import simple_history.models + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('certificates', '0030_delete_certificatewhitelist'), + ] + + operations = [ + migrations.CreateModel( + name='HistoricalCertificateDateOverride', + fields=[ + ('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')), + ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')), + ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')), + ('date', models.DateField(help_text='The date to display on the certificate')), + ('reason', models.TextField(help_text='The reason why you are overriding the certificate date (Update this when you add OR edit the date.)')), + ('history_id', models.AutoField(primary_key=True, serialize=False)), + ('history_date', models.DateTimeField()), + ('history_change_reason', models.CharField(max_length=100, null=True)), + ('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)), + ('generated_certificate', models.ForeignKey(blank=True, db_constraint=False, help_text='The id of the Generated Certificate to override', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='certificates.GeneratedCertificate')), + ('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)), + ('overridden_by', models.ForeignKey(blank=True, db_constraint=False, help_text='The last person to save this record', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)), + ], + options={ + 'verbose_name': 'historical certificate date override', + 'ordering': ('-history_date', '-history_id'), + 'get_latest_by': 'history_date', + }, + bases=(simple_history.models.HistoricalChanges, models.Model), + ), + migrations.CreateModel( + name='CertificateDateOverride', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')), + ('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')), + ('date', models.DateField(help_text='The date to display on the certificate')), + ('reason', models.TextField(help_text='The reason why you are overriding the certificate date (Update this when you add OR edit the date.)')), + ('generated_certificate', models.OneToOneField(help_text='The id of the Generated Certificate to override', on_delete=django.db.models.deletion.CASCADE, related_name='date_override', to='certificates.GeneratedCertificate')), + ('overridden_by', models.ForeignKey(help_text='The last person to save this record', on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py index 6b6fd684687f4743275938450d79842874ca6f7c..225b166164be83df7f9dd9f4f9a9e8030ebf9013 100644 --- a/lms/djangoapps/certificates/models.py +++ b/lms/djangoapps/certificates/models.py @@ -1158,3 +1158,42 @@ class CertificateGenerationCommandConfiguration(ConfigurationModel): def __str__(self): return str(self.arguments) + + +class CertificateDateOverride(TimeStampedModel): + """ + Model to manually override a given certificate date with the given date. + + .. no_pii: + """ + generated_certificate = models.OneToOneField( + GeneratedCertificate, + on_delete=models.CASCADE, + related_name='date_override', + help_text="The id of the Generated Certificate to override", + ) + date = models.DateField( + help_text="The date to display on the certificate", + ) + reason = models.TextField( + help_text="The reason why you are overriding the certificate date (Update this when you add OR edit the date.)", + ) + overridden_by = models.ForeignKey( + User, + on_delete=models.DO_NOTHING, + help_text="The last person to save this record", + ) + + # This is necessary because CMS does not install the certificates app, but + # this code is run when other models in this file are imported there (or in + # common code). Simple History will attempt to connect to the installed + # model in the certificates app, which will fail. + if 'certificates' in apps.app_configs: + history = HistoricalRecords() + + class Meta: + app_label = "certificates" + + def __str__(self): + return "Certificate %s, date overridden to %s by %s on %s." % \ + (self.generated_certificate, self.date, self.overridden_by, self.created)