Skip to content

Commit

Permalink
feat: usability improvements to forced redemption admin experience
Browse files Browse the repository at this point in the history
ENT-8703
  • Loading branch information
iloveagent57 committed Apr 5, 2024
1 parent 9bf7179 commit bfd6b28
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 5 deletions.
37 changes: 36 additions & 1 deletion enterprise_access/apps/subsidy_access_policy/admin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import logging

from django.conf import settings
from django.contrib import admin
from django.contrib import admin, messages
from django.http import HttpResponseRedirect
from django.urls import re_path, reverse
from django.utils.safestring import mark_safe
from django.utils.text import Truncator # for shortening a text
from django.utils.translation import gettext_lazy
from django_object_actions import DjangoObjectActions, action
from djangoql.admin import DjangoQLSearchMixin
from pygments import highlight
Expand Down Expand Up @@ -369,10 +370,44 @@ def has_change_permission(self, request, obj=None):

@admin.register(models.ForcedPolicyRedemption)
class ForcedPolicyRedemptionAdmin(DjangoQLSearchMixin, SimpleHistoryAdmin):
"""
Admin class for the forced redemption model/logic.
"""
autocomplete_fields = [
'subsidy_access_policy',
]
readonly_fields = [
'redeemed_at',
'errored_at',
'transaction_uuid',
'traceback',
]

def save_model(self, request, obj, form, change):
"""
If this record has not been successfully redeemed yet,
and if ``wait_to_redeem`` is false, then call ``force_redeem()`` on
the record.
"""
super().save_model(request, obj, form, change)
obj.refresh_from_db()

if obj.transaction_uuid:
message = gettext_lazy("{} has already been redeemed".format(obj))
self.message_user(request, message, messages.SUCCESS)
return

if obj.wait_to_redeem:
message = gettext_lazy(
"{} has wait_to_redeem set to true, redemption will not occur "
"until this is changed to false".format(obj)
)
self.message_user(request, message, messages.WARNING)
return

try:
obj.force_redeem()
except Exception as exc: # pylint: disable=broad-except
message = gettext_lazy("{} Failure reason: {}".format(obj, exc))
self.message_user(request, message, messages.ERROR)
logger.exception('Force redemption failed for %s', obj)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 4.2.11 on 2024-04-05 14:45

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('subsidy_access_policy', '0025_forced_policy_redemption_model'),
]

operations = [
migrations.AlterField(
model_name='forcedpolicyredemption',
name='transaction_uuid',
field=models.UUIDField(blank=True, db_index=True, editable=False, help_text=('The transaction uuid caused by successful redemption.',), null=True),
),
migrations.AlterField(
model_name='historicalforcedpolicyredemption',
name='transaction_uuid',
field=models.UUIDField(blank=True, db_index=True, editable=False, help_text=('The transaction uuid caused by successful redemption.',), null=True),
),
]
13 changes: 9 additions & 4 deletions enterprise_access/apps/subsidy_access_policy/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,8 @@ class ForcedPolicyRedemption(TimeStampedModel):
)
transaction_uuid = models.UUIDField(
null=True,
blank=True,
editable=False,
db_index=True,
help_text=(
"The transaction uuid caused by successful redemption.",
Expand All @@ -1592,8 +1594,9 @@ class ForcedPolicyRedemption(TimeStampedModel):

def __str__(self):
return (
f'policy_uuid={self.subsidy_access_policy.uuid}, transaction_uuid={self.transaction_uuid}, '
f'lms_user_id={self.lms_user_id}, course_run_key={self.course_run_key}'
f'<{self.__class__.__name__} policy_uuid={self.subsidy_access_policy.uuid}, '
f'transaction_uuid={self.transaction_uuid}, '
f'lms_user_id={self.lms_user_id}, course_run_key={self.course_run_key}>'
)

def create_assignment(self):
Expand All @@ -1609,7 +1612,7 @@ def create_assignment(self):
course_key = content_metadata.get('content_key')
user_record = User.objects.filter(lms_user_id=self.lms_user_id).first()
if not user_record:
raise Exception(f'No email for {self.lms_user_id}')
raise Exception(f'No email could be found for lms_user_id {self.lms_user_id}')

return assignments_api.allocate_assignments(
assignment_configuration,
Expand All @@ -1631,7 +1634,7 @@ def force_redeem(self):

try:
with self.subsidy_access_policy.lock():
can_redeem, _, existing_transactions = self.subsidy_access_policy.can_redeem(
can_redeem, reason, existing_transactions = self.subsidy_access_policy.can_redeem(
self.lms_user_id, self.course_run_key,
)
if can_redeem:
Expand All @@ -1643,6 +1646,8 @@ def force_redeem(self):
self.transaction_uuid = result['uuid']
self.redeemed_at = result['modified']
self.save()
else:
raise Exception(f'Failed forced redemption: {reason}')
except SubsidyAccessPolicyLockAttemptFailed as exc:
logger.exception(exc)
self.errored_at = localized_utcnow()
Expand Down

0 comments on commit bfd6b28

Please sign in to comment.