Skip to content

Commit 4820e9a

Browse files
committed
fixup! feat: implement enrollment audit
1 parent 9bd6ab8 commit 4820e9a

File tree

4 files changed

+57
-51
lines changed

4 files changed

+57
-51
lines changed

learning_paths/migrations/0013_enrollment_audit.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,15 @@ class Migration(migrations.Migration):
155155
"abstract": False,
156156
},
157157
),
158+
migrations.AddField(
159+
model_name="learningpathenrollmentallowed",
160+
name="is_active",
161+
field=models.BooleanField(
162+
db_index=True, default=True, help_text="Indicates if the enrollment allowance is active"
163+
),
164+
),
165+
migrations.RemoveField(
166+
model_name="learningpathenrollment",
167+
name="enrolled_at",
168+
),
158169
]

learning_paths/migrations/0014_learningpathenrollmentallowed_is_active.py

Lines changed: 0 additions & 20 deletions
This file was deleted.

learning_paths/migrations/0015_remove_learningpathenrollment_enrolled_at.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

learning_paths/models.py

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,15 @@ def get_paths_visible_to_user(self, user: User) -> models.QuerySet:
5353
enrollment_subquery = LearningPathEnrollment.objects.filter(
5454
learning_path=OuterRef("pk"), user=user, is_active=True
5555
).values("created")[:1]
56-
queryset = queryset.annotate(enrollment_date=models.Subquery(enrollment_subquery))
56+
queryset = queryset.annotate(
57+
enrollment_date=models.Subquery(enrollment_subquery)
58+
)
5759

5860
# Apply visibility filtering based on the user role.
5961
if not user.is_staff:
60-
queryset = queryset.filter(Q(invite_only=False) | Q(enrollment_date__isnull=False))
62+
queryset = queryset.filter(
63+
Q(invite_only=False) | Q(enrollment_date__isnull=False)
64+
)
6165

6266
# Order by enrollment date (the most recent first), with null values at the end.
6367
return queryset.order_by(models.F("enrollment_date").desc(nulls_last=True))
@@ -115,12 +119,16 @@ def _learning_path_image_upload_path(self, filename: str) -> str:
115119
blank=True,
116120
null=True,
117121
verbose_name=_("Duration (days)"),
118-
help_text=_("Approximate time (in days) it should take to complete this Learning Path."),
122+
help_text=_(
123+
"Approximate time (in days) it should take to complete this Learning Path."
124+
),
119125
)
120126
sequential = models.BooleanField(
121127
default=False,
122128
verbose_name=_("Is sequential"),
123-
help_text=_("Whether the courses in this Learning Path are meant to be taken sequentially."),
129+
help_text=_(
130+
"Whether the courses in this Learning Path are meant to be taken sequentially."
131+
),
124132
)
125133
# Note: the enrolled learners will be able to self-enroll in all courses
126134
# (steps) of the learning path. To avoid mistakes of making the courses
@@ -129,7 +137,9 @@ def _learning_path_image_upload_path(self, filename: str) -> str:
129137
invite_only = models.BooleanField(
130138
default=True,
131139
verbose_name=_("Invite only"),
132-
help_text=_("If enabled, only staff can enroll users and only enrolled users can see the learning path."),
140+
help_text=_(
141+
"If enabled, only staff can enroll users and only enrolled users can see the learning path."
142+
),
133143
)
134144
enrolled_users = models.ManyToManyField(User, through="LearningPathEnrollment")
135145
tracker = FieldTracker(fields=["image"])
@@ -188,12 +198,16 @@ class Meta:
188198
unique_together = ("learning_path", "course_key")
189199

190200
course_key = CourseKeyField(max_length=255)
191-
learning_path = models.ForeignKey(LearningPath, related_name="steps", on_delete=models.CASCADE)
201+
learning_path = models.ForeignKey(
202+
LearningPath, related_name="steps", on_delete=models.CASCADE
203+
)
192204
order = models.PositiveIntegerField(
193205
blank=True,
194206
null=True,
195207
verbose_name=_("Sequential order"),
196-
help_text=_("Ordinal position of this step in the sequence of the Learning Path, if applicable."),
208+
help_text=_(
209+
"Ordinal position of this step in the sequence of the Learning Path, if applicable."
210+
),
197211
)
198212
weight = models.FloatField(
199213
default=1.0,
@@ -250,7 +264,9 @@ class Meta:
250264

251265
learning_path = models.ForeignKey(LearningPath, on_delete=models.CASCADE)
252266
skill = models.ForeignKey(Skill, on_delete=models.CASCADE)
253-
level = models.PositiveIntegerField(help_text=_("The skill level associated with this course."))
267+
level = models.PositiveIntegerField(
268+
help_text=_("The skill level associated with this course.")
269+
)
254270

255271
def __str__(self):
256272
"""User-friendly string representation of this model."""
@@ -312,7 +328,9 @@ class LearningPathGradingCriteria(models.Model):
312328
.. no_pii:
313329
"""
314330

315-
learning_path = models.OneToOneField(LearningPath, related_name="grading_criteria", on_delete=models.CASCADE)
331+
learning_path = models.OneToOneField(
332+
LearningPath, related_name="grading_criteria", on_delete=models.CASCADE
333+
)
316334
required_completion = models.FloatField(
317335
default=0.80,
318336
help_text=(
@@ -369,7 +387,9 @@ class Meta:
369387
learning_path = models.ForeignKey(LearningPath, on_delete=models.CASCADE)
370388
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True)
371389
is_active = models.BooleanField(
372-
default=True, db_index=True, help_text=_("Indicates if the enrollment allowance is active")
390+
default=True,
391+
db_index=True,
392+
help_text=_("Indicates if the enrollment allowance is active"),
373393
)
374394

375395
def __str__(self):
@@ -405,12 +425,24 @@ class LearningPathEnrollmentAudit(TimeStampedModel):
405425
(DEFAULT_TRANSITION_STATE, DEFAULT_TRANSITION_STATE),
406426
)
407427

408-
enrolled_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name="learning_path_audit")
409-
enrollment = models.ForeignKey(LearningPathEnrollment, on_delete=models.CASCADE, null=True, related_name="audit")
428+
enrolled_by = models.ForeignKey(
429+
User, on_delete=models.CASCADE, null=True, related_name="learning_path_audit"
430+
)
431+
enrollment = models.ForeignKey(
432+
LearningPathEnrollment,
433+
on_delete=models.CASCADE,
434+
null=True,
435+
related_name="audit",
436+
)
410437
enrollment_allowed = models.ForeignKey(
411-
LearningPathEnrollmentAllowed, on_delete=models.CASCADE, null=True, related_name="audit"
438+
LearningPathEnrollmentAllowed,
439+
on_delete=models.CASCADE,
440+
null=True,
441+
related_name="audit",
442+
)
443+
state_transition = models.CharField(
444+
max_length=255, choices=TRANSITION_STATES, default=DEFAULT_TRANSITION_STATE
412445
)
413-
state_transition = models.CharField(max_length=255, choices=TRANSITION_STATES, default=DEFAULT_TRANSITION_STATE)
414446
reason = models.TextField(blank=True)
415447
org = models.CharField(max_length=255, blank=True, db_index=True)
416448
role = models.CharField(max_length=255, blank=True)

0 commit comments

Comments
 (0)