Skip to content

Commit

Permalink
feat: add default enrollment models
Browse files Browse the repository at this point in the history
Adds two models, `DefaultEnterpriseEnrollmentIntention` and
`DefaultEnterpriseEnrollmentRealization`. The former defines, for a customer,
a course/run that associated users should be automatically enrolled into.
The latter represents the relationship between that intention record
and a realized EnterpriseCourseEnrollment; persisting realized enrollments
in this way will help to make read operations related to default enrollments
much more efficient.
ENT-9577
  • Loading branch information
iloveagent57 committed Oct 10, 2024
1 parent 4ff2441 commit fe71e9d
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 0 deletions.
31 changes: 31 additions & 0 deletions enterprise/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1316,3 +1316,34 @@ class LearnerCreditEnterpriseCourseEnrollmentAdmin(admin.ModelAdmin):
class Meta:
fields = '__all__'
model = models.LearnerCreditEnterpriseCourseEnrollment


@admin.register(models.DefaultEnterpriseEnrollmentIntention)
class DefaultEnterpriseEnrollmentIntentionAdmin(admin.ModelAdmin):
"""
Django admin model for DefaultEnterpriseEnrollmentIntentions.
"""
list_display = (
'uuid',
'enterprise_customer',
'content_type',
'content_key',
)

readonly_fields = (
'current_course_run_key',
'current_course_run_enrollable',
'current_course_run_enroll_by_date',
)

search_fields = (
'uuid',
'enterprise_customer__uuid',
'content_key',
)

ordering = ('-modified',)

class Meta:
fields = '__all__'
model = models.DefaultEnterpriseEnrollmentIntention
99 changes: 99 additions & 0 deletions enterprise/migrations/0223_default_enrollments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Generated by Django 4.2.15 on 2024-10-10 15:02

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
import uuid


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('enterprise', '0222_alter_enterprisegroup_group_type_and_more'),
]

operations = [
migrations.CreateModel(
name='DefaultEnterpriseEnrollmentIntention',
fields=[
('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')),
('is_removed', models.BooleanField(default=False)),
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('content_type', models.CharField(choices=[('course', 'Course'), ('course_run', 'Course Run')], help_text='The type of content (e.g. a course vs. a course run).', max_length=127)),
('content_key', models.CharField(help_text='A course or course run that related users should be automatically enrolled into.', max_length=255)),
('enterprise_customer', models.ForeignKey(help_text='The customer for which this default enrollment will be realized.', on_delete=django.db.models.deletion.CASCADE, related_name='default_course_enrollments', to='enterprise.enterprisecustomer')),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='HistoricalDefaultEnterpriseEnrollmentRealization',
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')),
('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)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('intended_enrollment', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='enterprise.defaultenterpriseenrollmentintention')),
('realized_enrollment', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='enterprise.enterprisecourseenrollment')),
],
options={
'verbose_name': 'historical default enterprise enrollment realization',
'verbose_name_plural': 'historical default enterprise enrollment realizations',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='HistoricalDefaultEnterpriseEnrollmentIntention',
fields=[
('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')),
('is_removed', models.BooleanField(default=False)),
('uuid', models.UUIDField(db_index=True, default=uuid.uuid4, editable=False)),
('content_type', models.CharField(choices=[('course', 'Course'), ('course_run', 'Course Run')], help_text='The type of content (e.g. a course vs. a course run).', max_length=127)),
('content_key', models.CharField(help_text='A course or course run that related users should be automatically enrolled into.', max_length=255)),
('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)),
('enterprise_customer', models.ForeignKey(blank=True, db_constraint=False, help_text='The customer for which this default enrollment will be realized.', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='enterprise.enterprisecustomer')),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'historical default enterprise enrollment intention',
'verbose_name_plural': 'historical default enterprise enrollment intentions',
'ordering': ('-history_date', '-history_id'),
'get_latest_by': ('history_date', 'history_id'),
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='DefaultEnterpriseEnrollmentRealization',
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')),
('intended_enrollment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='enterprise.defaultenterpriseenrollmentintention')),
('realized_enrollment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='enterprise.enterprisecourseenrollment')),
],
options={
'abstract': False,
},
),
migrations.AddField(
model_name='defaultenterpriseenrollmentintention',
name='realized_enrollments',
field=models.ManyToManyField(through='enterprise.DefaultEnterpriseEnrollmentRealization', to='enterprise.enterprisecourseenrollment'),
),
]
93 changes: 93 additions & 0 deletions enterprise/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2461,6 +2461,99 @@ class LicensedEnterpriseCourseEnrollment(EnterpriseFulfillmentSource):
)


class DefaultEnterpriseEnrollmentIntention(TimeStampedModel, SoftDeletableModel):
"""
Specific to an enterprise customer, this model defines a course or course run
that should be auto-enrolled for any enterprise customer user linked to the customer.
"""
DEFAULT_ENROLLMENT_CONTENT_TYPE_CHOICES = [
('course', 'Course'),
('course_run', 'Course Run'),
]
uuid = models.UUIDField(
primary_key=True,
default=uuid4,
editable=False,
)
enterprise_customer = models.ForeignKey(
EnterpriseCustomer,
blank=False,
null=False,
related_name="default_course_enrollments",
on_delete=models.deletion.CASCADE,
help_text=_(
"The customer for which this default enrollment will be realized.",
)
)
content_type = models.CharField(
max_length=127,
blank=False,
null=False,
choices=DEFAULT_ENROLLMENT_CONTENT_TYPE_CHOICES,
help_text=_(
"The type of content (e.g. a course vs. a course run)."
),
)
content_key = models.CharField(
max_length=255,
blank=False,
null=False,
help_text=_(
"A course or course run that related users should be automatically enrolled into."
),
)
realized_enrollments = models.ManyToManyField(
EnterpriseCourseEnrollment,
through='DefaultEnterpriseEnrollmentRealization',
through_fields=("intended_enrollment", "realized_enrollment"),
)
history = HistoricalRecords()

@cached_property
def current_course_run(self): # pragma: no cover
"""
Metadata describing the current course run for this default enrollment intention.
"""
return {}

@property
def current_course_run_key(self): # pragma: no cover
"""
The current course run key to use for realized course enrollments.
"""
return self.current_course_run.get('key')

@property
def current_course_run_enrollable(self): # pragma: no cover
"""
Whether the current course run is enrollable.
"""
return False

@property
def current_course_run_enroll_by_date(self): # pragma: no cover
"""
The enrollment deadline for this course.
"""
return datetime.datetime.min


class DefaultEnterpriseEnrollmentRealization(TimeStampedModel):
"""
Represents the relationship between a `DefaultEnterpriseEnrollmentIntention`
and a realized course enrollment that exists because of that intention record.
"""
intended_enrollment = models.ForeignKey(
DefaultEnterpriseEnrollmentIntention,
on_delete=models.CASCADE,
)
realized_enrollment = models.ForeignKey(
EnterpriseCourseEnrollment,
on_delete=models.CASCADE,
)
history = HistoricalRecords()


class EnterpriseCatalogQuery(TimeStampedModel):
"""
Stores a re-usable catalog query.
Expand Down

0 comments on commit fe71e9d

Please sign in to comment.