Skip to content

fix(usage notifications): handle plans with billing terms longer than 12 months #5415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion api/organisations/task_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def handle_api_usage_notification_for_organisation(organisation: Organisation) -
return

# Truncate to the closest active month to get start of current period.
month_delta = relativedelta(now, billing_starts_at).months
month_delta = _get_total_months(relativedelta(now, billing_starts_at))
period_starts_at = relativedelta(months=month_delta) + billing_starts_at

allowed_api_calls = subscription_cache.allowed_30d_api_calls
Expand Down Expand Up @@ -160,3 +160,7 @@ def handle_api_usage_notification_for_organisation(organisation: Organisation) -
return

_send_api_usage_notification(organisation, matched_threshold)


def _get_total_months(rd: relativedelta) -> int:
return rd.months + rd.years * 12
33 changes: 31 additions & 2 deletions api/tests/unit/organisations/test_unit_organisations_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,16 +330,45 @@ def test_handle_api_usage_notification_for_organisation_when_cancellation_date_i
logger.addHandler(inspecting_handler)

# When
result = handle_api_usage_notification_for_organisation(organisation) # type: ignore[func-returns-value]
handle_api_usage_notification_for_organisation(organisation)

# Then
assert result is None
assert OrganisationAPIUsageNotification.objects.count() == 0

# Check to ensure that error messages haven't been set.
assert inspecting_handler.messages == [] # type: ignore[attr-defined]


def test_handle_api_usage_notification_for_organisation_when_billing_starts_at_is_more_than_12_months_ago(
organisation: Organisation,
mocker: MockerFixture,
) -> None:
# Given
organisation.subscription.plan = SCALE_UP
organisation.subscription.subscription_id = "fancy_id"
organisation.subscription.save()

billing_term_starts_at = timezone.now() - relativedelta(days=367)
OrganisationSubscriptionInformationCache.objects.create(
organisation=organisation,
allowed_30d_api_calls=1_000_000,
current_billing_term_starts_at=billing_term_starts_at,
)

mock_api_usage = mocker.patch("organisations.task_helpers.get_current_api_usage")
mock_api_usage.return_value = 25

organisation.refresh_from_db()

# When
handle_api_usage_notification_for_organisation(organisation)

# Then
mock_api_usage.assert_called_once_with(
organisation.id, billing_term_starts_at + relativedelta(months=12)
)


@pytest.mark.freeze_time("2023-01-19T09:09:47.325132+00:00")
def test_handle_api_usage_notifications_when_feature_flag_is_off(
mocker: MockerFixture,
Expand Down
Loading