diff --git a/license_manager/apps/subscriptions/management/commands/process_expired_licenses.py b/license_manager/apps/subscriptions/management/commands/unlink_expired_licenses.py similarity index 73% rename from license_manager/apps/subscriptions/management/commands/process_expired_licenses.py rename to license_manager/apps/subscriptions/management/commands/unlink_expired_licenses.py index c3602089..e2d11992 100644 --- a/license_manager/apps/subscriptions/management/commands/process_expired_licenses.py +++ b/license_manager/apps/subscriptions/management/commands/unlink_expired_licenses.py @@ -1,5 +1,6 @@ import logging +from datetime import timedelta from django.conf import settings from django.core.management.base import BaseCommand @@ -26,7 +27,7 @@ class Command(BaseCommand): help = ( - 'Process expired licenses.' + 'Unlink expired licenses.' ) def add_arguments(self, parser): @@ -50,10 +51,11 @@ def expired_licenses(self, enterprise_customer_uuid): customer_agreement = CustomerAgreement.objects.get(enterprise_customer_uuid=enterprise_customer_uuid) + # fetch expired subscription plans where the expiration date is older than 90 days. expired_subscription_plans = list( SubscriptionPlan.objects.filter( customer_agreement=customer_agreement, - expiration_date__lt=now, + expiration_date__lt=now - timedelta(days=90), ).select_related( 'customer_agreement' ).prefetch_related( @@ -80,24 +82,24 @@ def expired_licenses(self, enterprise_customer_uuid): 'subscription_plan', ).values('uuid', 'lms_user_id', 'user_email') - # Subquery to check for the existence of `EXPIRED_LICENSE_PROCESSED` + # subquery to check for the existence of `EXPIRED_LICENSE_PROCESSED` event_exists_subquery = LicenseEvent.objects.filter( license=OuterRef('pk'), event_name=EXPIRED_LICENSE_PROCESSED ).values('pk') - # Exclude previously processed licenses. + # exclude previously processed licenses. queryset = queryset.exclude(Exists(event_exists_subquery)) return queryset def handle(self, *args, **options): """ - Process expired licenses and un-link learners. + Unlink expired licenses. """ unlink = not options['dry_run'] - log_prefix = '[PROCESS_EXPIRED_LICENSES]' + log_prefix = '[UNLINK_EXPIRED_LICENSES]' if not unlink: log_prefix = '[DRY RUN]' @@ -105,15 +107,15 @@ def handle(self, *args, **options): enterprise_customer_uuids = settings.CUSTOMERS_WITH_EXPIRED_LICENSES_UNLINKING_ENABLED for enterprise_customer_uuid in enterprise_customer_uuids: - logger.info('%s Processing started for licenses. Enterprise: [%s]', log_prefix, enterprise_customer_uuid) - self.process_expired_licenses(enterprise_customer_uuid, log_prefix, unlink) - logger.info('%s Processing completed for licenses. Enterprise: [%s]', log_prefix, enterprise_customer_uuid) + logger.info('%s Unlinking started for licenses. Enterprise: [%s]', log_prefix, enterprise_customer_uuid) + self.unlink_expired_licenses(enterprise_customer_uuid, log_prefix, unlink) + logger.info('%s Unlinking completed for licenses. Enterprise: [%s]', log_prefix, enterprise_customer_uuid) logger.info('%s Command completed.', log_prefix) - def process_expired_licenses(self, enterprise_customer_uuid, log_prefix, unlink): + def unlink_expired_licenses(self, enterprise_customer_uuid, log_prefix, unlink): """ - Process expired licenses and un-link learners. + Unlink expired licenses. """ expired_licenses = self.expired_licenses(enterprise_customer_uuid) @@ -128,8 +130,24 @@ def process_expired_licenses(self, enterprise_customer_uuid, log_prefix, unlink) for page_number in paginator.page_range: licenses = paginator.page(page_number) - license_uuids = [license.get('uuid') for license in licenses] - user_emails = [license.get('user_email') for license in licenses] + license_uuids = [] + user_emails = [] + + for license in licenses: + # check if the user associated with the expired license + # has any other active licenses with the same customer + other_active_licenses = License.for_user_and_customer( + user_email=license.user_email, + lms_user_id=license.lms_user_id, + enterprise_customer_uuid=enterprise_customer_uuid, + active_plans_only=True, + current_plans_only=True, + ).exists() + if other_active_licenses: + continue + + license_uuids.append(license.get('uuid')) + user_emails.append(license.get('user_email')) if unlink: EnterpriseApiClient().bulk_unlink_enterprise_users(