diff --git a/api/organisations/models.py b/api/organisations/models.py index 27e9c85ee9c8..4fd467002a95 100644 --- a/api/organisations/models.py +++ b/api/organisations/models.py @@ -196,12 +196,17 @@ def cancel_users(self): # type: ignore[no-untyped-def] .order_by("date_joined") .first() ) + if not remaining_seat_holder: + remaining_seat_holder = ( + UserOrganisation.objects.filter(organisation=self) + .order_by("date_joined") + .first() + ) - UserOrganisation.objects.filter( - organisation=self, - ).exclude( - id=remaining_seat_holder.id # type: ignore[union-attr] - ).delete() + user_organisations = UserOrganisation.objects.filter(organisation=self) + if remaining_seat_holder: + user_organisations = user_organisations.exclude(id=remaining_seat_holder.id) + user_organisations.delete() class UserOrganisation(LifecycleModelMixin, models.Model): # type: ignore[misc] diff --git a/api/tests/unit/organisations/test_unit_organisations_tasks.py b/api/tests/unit/organisations/test_unit_organisations_tasks.py index d953ed2845e3..a3ab94197645 100644 --- a/api/tests/unit/organisations/test_unit_organisations_tasks.py +++ b/api/tests/unit/organisations/test_unit_organisations_tasks.py @@ -264,6 +264,56 @@ def test_finish_subscription_cancellation__multiple_organisations__removes_exces assert organisation4.num_seats == organisation_user_count +def test_finish_subscription_cancellation__no_admin__resets_to_free_plan( + db: None, +) -> None: + # Given + organisation = Organisation.objects.create() + UserOrganisation.objects.create( + organisation=organisation, + user=FFAdminUser.objects.create(email=f"{uuid.uuid4()}@example.com"), + role=OrganisationRole.USER, + ) + + subscription = organisation.subscription + subscription.subscription_id = "id" + subscription.plan = "plan_code" + subscription.cancellation_date = timezone.now() - timedelta(hours=1) + subscription.save() + + # When + finish_subscription_cancellation() + + # Then + organisation.refresh_from_db() + subscription.refresh_from_db() + + assert subscription.plan == FREE_PLAN_ID + assert UserOrganisation.objects.filter(organisation=organisation).count() == 1 + + +def test_finish_subscription_cancellation__no_members__resets_to_free_plan( + db: None, +) -> None: + # Given + organisation = Organisation.objects.create() + subscription = organisation.subscription + subscription.subscription_id = "id" + subscription.plan = "plan_code" + subscription.cancellation_date = timezone.now() - timedelta(hours=1) + subscription.save() + + # When + finish_subscription_cancellation() + + # Then + organisation.refresh_from_db() + subscription.refresh_from_db() + + assert subscription.plan == FREE_PLAN_ID + assert UserOrganisation.objects.filter(organisation=organisation).count() == 0 + + def test_send_org_subscription_cancelled_alert__valid_organisation__sends_cancellation_email( mocker: MockerFixture, settings: SettingsWrapper ) -> None: