feat: incorporated feedback comments
This commit is contained in:
committed by
Phillip Shiu
parent
8e2612358d
commit
a0d3c21295
@@ -1,18 +1,30 @@
|
||||
# lint-amnesty, pylint: disable=django-not-configured
|
||||
"""
|
||||
Management command for expiring old entitlements.
|
||||
Management command for expiring entitlements older than 1 year / 18 months.
|
||||
"""
|
||||
|
||||
|
||||
import logging
|
||||
from datetime import date
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from math import ceil
|
||||
from textwrap import dedent
|
||||
|
||||
from django.core.management import BaseCommand
|
||||
|
||||
from common.djangoapps.entitlements.tasks import expire_and_create_entitlements
|
||||
from common.djangoapps.entitlements.models import CourseEntitlement
|
||||
|
||||
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
|
||||
|
||||
#course uuids for which entitlements should be expired after 18 months.
|
||||
MIT_SUPPLY_CHAIN_COURSES = [
|
||||
'0d9b47982e3d486aa3189a7035bbda77',
|
||||
'09532745c837467b9078093b8e1265a8',
|
||||
'324970b703a444d7b39e10bbda6f119f',
|
||||
'5f1c55b4354e4155af4a76450953e10d',
|
||||
'ed927a1a4a95415ba865c3d722ac549c',
|
||||
'6513ed9c112a495182ad7036cbe52831',
|
||||
]
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""
|
||||
@@ -47,11 +59,23 @@ class Command(BaseCommand):
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
logger.info('Looking for entitlements which may be expirable.')
|
||||
|
||||
total = max(1, options.get('count'))
|
||||
current_date = date.today()
|
||||
expiration_period = current_date - relativedelta(years=1)
|
||||
exceptional_expiration_period = current_date - relativedelta(years=1, months=6)
|
||||
normal_entitlements = CourseEntitlement.objects.filter(
|
||||
expired_at__isnull=True, created__lte=expiration_period).exclude(course_uuid__in=MIT_SUPPLY_CHAIN_COURSES)
|
||||
exceptional_entitlements = CourseEntitlement.objects.filter(
|
||||
expired_at__isnull=True, created__lte=exceptional_expiration_period, course_uuid__in=MIT_SUPPLY_CHAIN_COURSES)
|
||||
|
||||
entitlements = normal_entitlements | exceptional_entitlements
|
||||
logger.info('Total entitlements that have reached expiration period are %d ', entitlements)
|
||||
|
||||
entitlements_to_expire = max(1, options.get('count'))
|
||||
batch_size = max(1, options.get('batch_size'))
|
||||
num_batches = ((total - 1) / batch_size + 1) if total > 0 else 0
|
||||
num_batches = ceil(entitlements_to_expire / batch_size) if entitlements else 0
|
||||
|
||||
if options.get('commit'):
|
||||
logger.info('Enqueuing %d entitlement expiration tasks.', num_batches)
|
||||
@@ -62,9 +86,9 @@ class Command(BaseCommand):
|
||||
)
|
||||
return
|
||||
|
||||
while total > 0:
|
||||
total = total - batch_size
|
||||
no_of_entitlements = min(total, batch_size)
|
||||
expire_and_create_entitlements.delay(no_of_entitlements)
|
||||
for batch_num in range(num_batches):
|
||||
start = batch_num * batch_size
|
||||
end = min(start + batch_size, entitlements_to_expire)
|
||||
expire_and_create_entitlements.delay(entitlements[start:end])
|
||||
|
||||
logger.info('Done. Successfully enqueued %d tasks.', num_batches)
|
||||
|
||||
@@ -9,7 +9,7 @@ from celery.utils.log import get_task_logger
|
||||
from django.conf import settings # lint-amnesty, pylint: disable=unused-import
|
||||
from edx_django_utils.monitoring import set_code_owner_attribute
|
||||
|
||||
from common.djangoapps.entitlements.models import CourseEntitlement
|
||||
from common.djangoapps.entitlements.models import CourseEntitlement, CourseEntitlementSupportDetail
|
||||
|
||||
LOGGER = get_task_logger(__name__)
|
||||
|
||||
@@ -18,15 +18,6 @@ LOGGER = get_task_logger(__name__)
|
||||
# time of 2047 seconds (about 30 minutes). Setting this to None could yield
|
||||
# unwanted behavior: infinite retries.
|
||||
MAX_RETRIES = 11
|
||||
#course uuids for which entitlements should be expired after 18 months.
|
||||
MIT_SUPPLY_CHAIN_COURSES = [
|
||||
'0d9b47982e3d486aa3189a7035bbda77',
|
||||
'09532745c837467b9078093b8e1265a8',
|
||||
'324970b703a444d7b39e10bbda6f119f',
|
||||
'5f1c55b4354e4155af4a76450953e10d',
|
||||
'ed927a1a4a95415ba865c3d722ac549c',
|
||||
'6513ed9c112a495182ad7036cbe52831',
|
||||
]
|
||||
|
||||
|
||||
@shared_task(bind=True, ignore_result=True)
|
||||
@@ -76,13 +67,18 @@ def expire_old_entitlements(self, start, end, logid='...'):
|
||||
|
||||
@shared_task(bind=True, ignore_result=True)
|
||||
@set_code_owner_attribute
|
||||
def expire_and_create_entitlements(self, no_of_entitlements):
|
||||
def expire_and_create_entitlements(self, entitlements):
|
||||
"""
|
||||
This task is designed to be called to process and expire bundle of entitlements
|
||||
that are older than one year on in exceptional case 18 months.
|
||||
Expire entitlements older than one year.
|
||||
|
||||
Exception: if the entitlement is for a course in a list of exceptional courses,
|
||||
expire those entitlements if they're older than 18 months instead.
|
||||
|
||||
Then create a copy of the expired entitlement to renew it for another year
|
||||
/ 18 months.
|
||||
|
||||
Args:
|
||||
None
|
||||
no_of_entitlements (int): Limit the operation to this number of entitlements.
|
||||
|
||||
Returns:
|
||||
None
|
||||
@@ -90,31 +86,30 @@ def expire_and_create_entitlements(self, no_of_entitlements):
|
||||
"""
|
||||
LOGGER.info('Running task expire_and_create_entitlements')
|
||||
|
||||
current_date = date.today()
|
||||
expiration_period = current_date - relativedelta(years=1)
|
||||
exceptional_expiration_period = current_date - relativedelta(years=1, months=6)
|
||||
normal_entitlements = CourseEntitlement.objects.filter(
|
||||
expired_at__isnull=True, created__lte=expiration_period).exclude(course_uuid__in=MIT_SUPPLY_CHAIN_COURSES)
|
||||
exceptional_entitlements = CourseEntitlement.objects.filter(
|
||||
expired_at__isnull=True, created__lte=exceptional_expiration_period, course_uuid__in=MIT_SUPPLY_CHAIN_COURSES)
|
||||
|
||||
entitlements = normal_entitlements | exceptional_entitlements
|
||||
countdown = 2 ** self.request.retries
|
||||
|
||||
try:
|
||||
for entitlement in entitlements[:no_of_entitlements]:
|
||||
|
||||
for entitlement in entitlements:
|
||||
LOGGER.info('Started expiring entitlement with id %d', entitlement.id)
|
||||
entitlement.expire_entitlement()
|
||||
LOGGER.info('Expired entitlement with id %d ', entitlement.id)
|
||||
LOGGER.info('Expired entitlement with id %d as expiration period has reached', entitlement.id)
|
||||
|
||||
# Creating new entitlement with old entitlement's data
|
||||
entitlement.pk = None
|
||||
entitlement.id = None
|
||||
entitlement._state.adding = True
|
||||
entitlement.expired_at = None
|
||||
entitlement.modified = None
|
||||
entitlement.refund_locked = True
|
||||
entitlement.save()
|
||||
LOGGER.info('created new entitlement with id %d ', entitlement.id)
|
||||
|
||||
support_detail = {
|
||||
'action': 'CREATE',
|
||||
'comments': 'REV-3574',
|
||||
'entitlement': entitlement,
|
||||
}
|
||||
CourseEntitlementSupportDetail.objects.create(**support_detail)
|
||||
LOGGER.info('created new entitlement with id %d in a correspondence of above expired entitlement', entitlement.id)
|
||||
|
||||
except Exception as exc:
|
||||
LOGGER.exception('Failed to expire entitlements ',)
|
||||
# The call above is idempotent, so retry at will
|
||||
raise self.retry(exc=exc, countdown=countdown, max_retries=MAX_RETRIES)
|
||||
LOGGER.exception('Failed to expire entitlements that reached their expiration period',)
|
||||
|
||||
LOGGER.info('Successfully completed the task expire_and_create_entitlements after examining %d entries', entitlements.count()) # lint-amnesty, pylint: disable=line-too-long
|
||||
LOGGER.info('Successfully completed the task expire_and_create_entitlements after examining %d entries', entitlements.count()) # lint-amnesty, pylint: disable=line-too-long
|
||||
Reference in New Issue
Block a user