Skip to content

Commit

Permalink
feat: edge case of revoking potentially multiple related fulfillments
Browse files Browse the repository at this point in the history
  • Loading branch information
pwnage101 committed Sep 10, 2024
1 parent 5e02896 commit 77e9d35
Showing 1 changed file with 17 additions and 10 deletions.
27 changes: 17 additions & 10 deletions enterprise/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2117,11 +2117,16 @@ def learner_credit_fulfillment(self):
return associated_fulfillment

@property
def fulfillment(self):
def fulfillments(self):
"""
Find and return the related EnterpriseFulfillmentSource subclass, or None.
Find and return the related EnterpriseFulfillmentSource subclass, or empty list if there are none.
Returns:
list of EnterpriseFulfillmentSource subclass instances: all existing related fulfillments
"""
return self.license or self.learner_credit_fulfillment
possible_fulfillments = [self.license, self.learner_credit_fulfillment]
existing_fulfillments = [f for f in possible_fulfillments if f]
return existing_fulfillments

@cached_property
def course_enrollment(self):
Expand Down Expand Up @@ -2245,14 +2250,16 @@ def set_unenrolled(self, desired_unenrolled):
f"and course {self.course_id}"
)
self.save()
# Find and revoke/reactivate any related fulfillment.
# Find and revoke/reactivate any related fulfillment if unenrolling the EnterpriseCourseEnrollment.
# By only updating the related object on updates to self, we prevent infinite recursion.
if fulfillment := self.fulfillment:
if desired_unenrolled and not fulfillment.is_revoked:
fulfillment.revoke()
# Fulfillment reactivation on ECE reenrollment is unsupported. We'd need to collect a
# transaction UUID from the caller, but the caller at the time of writing is not aware of any
# transaction.
if desired_unenrolled:
for fulfillment in self.fulfillments:
if not fulfillment.is_revoked: # redundant base case to terminate loops.
fulfillment.revoke()
# Fulfillment reactivation on ECE reenrollment is unsupported. We'd need to collect a
# transaction UUID from the caller, but the caller at the time of writing is not aware of any
# transaction. Furthermore, we wouldn't know which fulfillment to reactivate, if there were multiple
# related fulfillment types.

def __str__(self):
"""
Expand Down

0 comments on commit 77e9d35

Please sign in to comment.