Skip to content

Commit

Permalink
fix: Add logic to handle grace period breached for paid accounts (#4512)
Browse files Browse the repository at this point in the history
Co-authored-by: Matthew Elwell <[email protected]>
  • Loading branch information
zachaysan and matthewelwell authored Aug 19, 2024
1 parent 19bc58e commit ba8ae60
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
11 changes: 10 additions & 1 deletion api/organisations/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,17 @@ def charge_for_api_call_count_overages():
api_usage = get_current_api_usage(organisation.id)

# Grace period for organisations < 200% of usage.
if api_usage / subscription_cache.allowed_30d_api_calls < 2.0:
if (
not hasattr(organisation, "breached_grace_period")
and api_usage / subscription_cache.allowed_30d_api_calls < 2.0
):
logger.info("API Usage below normal usage or grace period.")

# Set organisation grace period breach for following months.
if api_usage / subscription_cache.allowed_30d_api_calls > 1.0:
OrganisationBreachedGracePeriod.objects.get_or_create(
organisation=organisation
)
continue

api_billings = OrganisationAPIBilling.objects.filter(
Expand Down
59 changes: 59 additions & 0 deletions api/tests/unit/organisations/test_unit_organisations_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -928,6 +928,65 @@ def test_charge_for_api_call_count_overages_grace_period(
# Then
mock_chargebee_update.assert_not_called()
assert OrganisationAPIBilling.objects.count() == 0
assert organisation.breached_grace_period


@pytest.mark.freeze_time("2023-01-19T09:09:47.325132+00:00")
def test_charge_for_api_call_count_overages_grace_period_over(
organisation: Organisation,
mocker: MockerFixture,
) -> None:
# Given
now = timezone.now()
OrganisationSubscriptionInformationCache.objects.create(
organisation=organisation,
allowed_seats=10,
allowed_projects=3,
allowed_30d_api_calls=100_000,
chargebee_email="[email protected]",
current_billing_term_starts_at=now - timedelta(days=30),
current_billing_term_ends_at=now + timedelta(minutes=30),
)
organisation.subscription.subscription_id = "fancy_sub_id23"
organisation.subscription.plan = "scale-up-v2"
organisation.subscription.save()
OrganisationAPIUsageNotification.objects.create(
organisation=organisation,
percent_usage=100,
notified_at=now,
)

OrganisationBreachedGracePeriod.objects.create(organisation=organisation)
get_client_mock = mocker.patch("organisations.tasks.get_client")
client_mock = MagicMock()
get_client_mock.return_value = client_mock
client_mock.get_identity_flags.return_value.is_feature_enabled.return_value = True

mock_chargebee_update = mocker.patch(
"organisations.chargebee.chargebee.chargebee.Subscription.update"
)
mock_api_usage = mocker.patch(
"organisations.tasks.get_current_api_usage",
)
# Set the return value to something less than 200% of base rate
mock_api_usage.return_value = 115_000
assert OrganisationAPIBilling.objects.count() == 0

# When
charge_for_api_call_count_overages()

# Then
# Since the OrganisationBreachedGracePeriod was created already
# the charges go through.
mock_chargebee_update.assert_called_once_with(
"fancy_sub_id23",
{
"addons": [{"id": "additional-api-scale-up-monthly", "quantity": 1}],
"prorate": False,
"invoice_immediately": False,
},
)
assert OrganisationAPIBilling.objects.count() == 1


@pytest.mark.freeze_time("2023-01-19T09:09:47.325132+00:00")
Expand Down

0 comments on commit ba8ae60

Please sign in to comment.