From 5766a52a9a16e002cd16bbbb6aba50b4e9cbf4ac Mon Sep 17 00:00:00 2001
From: muhammad-ammar <mammar@gmail.com>
Date: Fri, 1 Nov 2024 12:18:01 +0500
Subject: [PATCH] feat: unlink learners from enterprise if their licenses are
 expired

---
 .../commands/expire_subscriptions.py          | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/license_manager/apps/subscriptions/management/commands/expire_subscriptions.py b/license_manager/apps/subscriptions/management/commands/expire_subscriptions.py
index d10cc209..b13048d6 100644
--- a/license_manager/apps/subscriptions/management/commands/expire_subscriptions.py
+++ b/license_manager/apps/subscriptions/management/commands/expire_subscriptions.py
@@ -1,9 +1,11 @@
 import logging
 from datetime import datetime, timedelta
 
+from django.conf import settings
 from django.core.management.base import BaseCommand
 
 from license_manager.apps.api.tasks import license_expiration_task
+from license_manager.apps.api_client.enterprise import EnterpriseApiClient
 from license_manager.apps.subscriptions.constants import (
     ACTIVATED,
     ASSIGNED,
@@ -70,6 +72,36 @@ def add_arguments(self, parser):
             default=False,
         )
 
+    def _unlink_expired_licenses_users(self, expired_subscription_plan, expired_licenses):
+        """
+        Unlinks the users from the enterprise customer for the expired licenses.
+        """
+        user_emails = []
+        license_uuids = []
+
+        enterprise_customer_uuid = expired_subscription_plan.customer_agreement.enterprise_customer_uuid
+        # only unlink users if the enterprise is in the list of customers with unlinking enabled
+        if enterprise_customer_uuid not in settings.CUSTOMERS_WITH_EXPIRED_LICENSES_UNLINKING_ENABLED:
+            return
+
+        for license in expired_licenses:
+            user_emails.append(license.user_email)
+            license_uuids.append(license.uuid)
+
+        EnterpriseApiClient().bulk_unlink_enterprise_users(
+            enterprise_customer_uuid,
+            {
+                'user_emails': user_emails,
+                'is_relinkable': False
+            },
+        )
+
+        logger.info(
+            "[EXPIRE_SUBSCRIPTIONS] Learners unlinked. Enterprise: [%s], LicenseUUIDs: [%s].",
+            enterprise_customer_uuid,
+            license_uuids
+        )
+
     def _expire_subscription_plan(self, expired_subscription_plan):
         """
         Expires a single subscription plan.
@@ -97,6 +129,7 @@ def _expire_subscription_plan(self, expired_subscription_plan):
                     license_chunk_uuids,
                     ignore_enrollments_modified_after=ignore_enrollments_modified_after
                 )
+                self._unlink_expired_licenses_users(expired_subscription_plan, license_chunk)
             except Exception:  # pylint: disable=broad-except
                 any_failures = True
                 msg = 'Failed to terminate course enrollments for learners in subscription: {}'.format(