From a9255d3cdc438a53aaafc138bf116fef19fd7529 Mon Sep 17 00:00:00 2001 From: Alexander Dusenbery Date: Thu, 5 Dec 2024 15:14:14 -0500 Subject: [PATCH] feat: pick the most recently start plan as auto-applicable ENT-9734 --- license_manager/apps/subscriptions/forms.py | 21 ++++++-- license_manager/apps/subscriptions/models.py | 2 +- .../apps/subscriptions/tests/test_models.py | 49 +++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/license_manager/apps/subscriptions/forms.py b/license_manager/apps/subscriptions/forms.py index 4e96753e..fd4c4fd6 100644 --- a/license_manager/apps/subscriptions/forms.py +++ b/license_manager/apps/subscriptions/forms.py @@ -46,7 +46,13 @@ class SubscriptionPlanForm(forms.ModelForm): choices=SubscriptionPlanShouldAutoApplyLicensesChoices.CHOICES, required=False, label="Should auto apply licenses", - help_text="Whether licenses from this Subscription Plan should be auto applied." + help_text=( + """ + Whether licenses from this Subscription Plan should be auto applied. + It it possible and acceptable for more than one plan in a single + customer agreement to have this field enabled. + """ + ) ) # Extra form field to specify the number of licenses to be associated with the subscription plan @@ -292,8 +298,17 @@ def populate_subscription_for_auto_applied_licenses_choices(self, instance): choices=choices, required=False, initial=empty_choice if not current_plan else (current_plan.uuid, current_plan.title), - help_text="The subscription plan to be associated with auto apply licenses. Selecting a license" - " will automatically enable the \"Should auto apply licenses\" field on the subscription plan" + help_text=( + """ + The subscription plan from which licenses will be auto-applied, if any. + If you do not manually modify this field, it will be automatically set, chosen as the + most recently started plan that is active, current, and has 'should_auto_apply_licenses' + set to true. Manually selecting/modifying the plan for this field will have two effects: + It will automatically enable the \"Should auto apply licenses\" field on the selected plan, + and it will automatically *disable* that field on all other plans + associated with this customer agreement. + """ + ), ) self.fields['subscription_for_auto_applied_licenses'] = choice_field diff --git a/license_manager/apps/subscriptions/models.py b/license_manager/apps/subscriptions/models.py index 5c0c4877..3945abbc 100644 --- a/license_manager/apps/subscriptions/models.py +++ b/license_manager/apps/subscriptions/models.py @@ -237,7 +237,7 @@ def auto_applicable_subscription(self): is_active=True, start_date__lte=now, expiration_date__gte=now - ).first() + ).order_by('-start_date').first() return plan diff --git a/license_manager/apps/subscriptions/tests/test_models.py b/license_manager/apps/subscriptions/tests/test_models.py index fe65ec00..29f8325b 100644 --- a/license_manager/apps/subscriptions/tests/test_models.py +++ b/license_manager/apps/subscriptions/tests/test_models.py @@ -117,6 +117,55 @@ def test_is_locked_for_renewal_processing(self, is_locked_for_renewal_processing renewed_subscription_plan.is_locked_for_renewal_processing, is_locked_for_renewal_processing, ) + def test_auto_applicable_subscription(self): + """ + Tests that we pick the most recent auto-applicable plan for a CustomerAgreement. + """ + agreement = CustomerAgreementFactory.create() + SubscriptionPlanFactory.create( + customer_agreement=agreement, + start_date=localized_datetime(2020, 1, 1), + should_auto_apply_licenses=True, + ) + SubscriptionPlanFactory.create( + customer_agreement=agreement, + start_date=localized_datetime(2020, 4, 1), + should_auto_apply_licenses=True, + ) + plan_3 = SubscriptionPlanFactory.create( + customer_agreement=agreement, + start_date=localized_datetime(2020, 12, 1), + should_auto_apply_licenses=True, + ) + # make one plan that hasn't started yet + SubscriptionPlanFactory.create( + customer_agreement=agreement, + start_date=localized_utcnow() + timedelta(days=1), + should_auto_apply_licenses=True, + ) + self.assertEqual(agreement.auto_applicable_subscription, plan_3) + + def test_auto_applicable_subscription_none_available(self): + """ + Tests that when no current, auto-applicable plan is available, + CustomerAgreement.auto_applicable_subscription evaluates to null. + """ + agreement = CustomerAgreementFactory.create() + # make a plan that's expired + SubscriptionPlanFactory.create( + customer_agreement=agreement, + start_date=localized_datetime(2020, 1, 1), + expiration_date=localized_utcnow() + timedelta(days=-1), + should_auto_apply_licenses=True, + ) + # make one plan that hasn't started yet + SubscriptionPlanFactory.create( + customer_agreement=agreement, + start_date=localized_utcnow() + timedelta(days=1), + should_auto_apply_licenses=True, + ) + self.assertIsNone(agreement.auto_applicable_subscription) + def test_auto_apply_licenses_turned_on_at(self): """ Tests that auto_apply_licenses_turned_on_at returns the correct time.