Skip to content

Commit

Permalink
feat: sort by Overage in sales dashboard (#3858)
Browse files Browse the repository at this point in the history
Co-authored-by: Zach Aysan <zachaysan@gmail.com>
  • Loading branch information
rolodato and zachaysan committed Apr 30, 2024
1 parent b93a544 commit 2417f57
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 31 deletions.
7 changes: 0 additions & 7 deletions api/organisations/models.py
Expand Up @@ -400,13 +400,6 @@ def add_single_seat(self):

add_single_seat(self.subscription_id)

def get_api_call_overage(self):
subscription_info = self.organisation.subscription_information_cache
overage = (
subscription_info.api_calls_30d - subscription_info.allowed_30d_api_calls
)
return overage if overage > 0 else 0

def is_in_trial(self) -> bool:
return self.subscription_id == TRIAL_SUBSCRIPTION_ID

Expand Down
5 changes: 3 additions & 2 deletions api/sales_dashboard/templates/sales_dashboard/home.html
Expand Up @@ -44,7 +44,8 @@ <h1 class="h2">Organisations</h1>
<option value="num_features" {% if sort_field == "num_features" %}selected{% endif %}>Flags</option>
<option value="subscription_information_cache__api_calls_24h" {% if sort_field == "subscription_information_cache__api_calls_24h" %}selected{% endif %}>24h API calls</option>
<option value="subscription_information_cache__api_calls_7d" {% if sort_field == "subscription_information_cache__api_calls_7d" %}selected{% endif %}>7d API calls</option>
<option value="subscription_information_cache__api_calls_30d" {% if sort_field == "subscription_information_cache__api_calls_30d" or not sort_field %}selected{% endif %}>30d API calls</option>
<option value="subscription_information_cache__api_calls_30d" {% if sort_field == "subscription_information_cache__a pi_calls_30d" or not sort_field %}selected{% endif %}>30d API calls</option>
<option value="overage" {% if sort_field == "overage"%}selected{% endif %}>Overage</option>
</select>
<select name="sort_direction" id="sort-direction" class="custom-select m-1">
<option value="DESC" {% if not sort_direction or sort_direction == "DESC" %}selected{% endif %}>Descending</option>
Expand Down Expand Up @@ -91,7 +92,7 @@ <h1 class="h2">Organisations</h1>
<td>{{org.subscription_information_cache.api_calls_24h|intcomma|default:0}}</td>
<td>{{org.subscription_information_cache.api_calls_7d|intcomma|default:0}}</td>
<td><span class="{% if org.subscription_information_cache.api_calls_30d > org.subscription_information_cache.allowed_30d_api_calls %}badge badge-danger{% endif %}">{{org.subscription_information_cache.api_calls_30d|intcomma|default:0}}</span></td>
<td><span {% if org.subscription.get_api_call_overage > 0 %}class="badge badge-danger"{% endif %}>{{org.subscription.get_api_call_overage|intcomma}}</span></td>
<td><span class="{% if org.overage > 0 %}badge badge-danger{% endif %}">{{org.overage|intcomma}}</span></td>
</tr>
{% endfor %}
</tbody>
Expand Down
8 changes: 7 additions & 1 deletion api/sales_dashboard/views.py
Expand Up @@ -7,7 +7,8 @@
from django.conf import settings
from django.contrib.admin.views.decorators import staff_member_required
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models import Count, F, Q
from django.db.models import Count, F, Q, Value
from django.db.models.functions import Greatest
from django.http import (
HttpRequest,
HttpResponse,
Expand Down Expand Up @@ -57,6 +58,11 @@ def get_queryset(self):
num_projects=Count("projects", distinct=True),
num_users=Count("users", distinct=True),
num_features=Count("projects__features", distinct=True),
overage=Greatest(
Value(0),
F("subscription_information_cache__api_calls_30d")
- F("subscription_information_cache__allowed_30d_api_calls"),
),
).select_related("subscription", "subscription_information_cache")

if self.request.GET.get("search"):
Expand Down
21 changes: 0 additions & 21 deletions api/tests/unit/organisations/test_unit_organisations_models.py
Expand Up @@ -516,27 +516,6 @@ def test_organisation_update_clears_environment_caches(
mock_environment_cache.delete_many.assert_called_once_with([environment.api_key])


@pytest.mark.parametrize(
"allowed_calls_30d, actual_calls_30d, expected_overage",
((1000000, 500000, 0), (1000000, 1100000, 100000), (0, 100000, 100000)),
)
def test_organisation_subscription_get_api_call_overage(
organisation, subscription, allowed_calls_30d, actual_calls_30d, expected_overage
):
# Given
OrganisationSubscriptionInformationCache.objects.create(
organisation=organisation,
allowed_30d_api_calls=allowed_calls_30d,
api_calls_30d=actual_calls_30d,
)

# When
overage = subscription.get_api_call_overage()

# Then
assert overage == expected_overage


def test_reset_of_api_notifications(organisation: Organisation) -> None:
# Given
now = timezone.now()
Expand Down
Empty file.
32 changes: 32 additions & 0 deletions api/tests/unit/sales_dashboard/test_unit_sales_dashboard_views.py
@@ -0,0 +1,32 @@
import pytest
from django.test import RequestFactory

from organisations.models import (
Organisation,
OrganisationSubscriptionInformationCache,
)
from sales_dashboard.views import OrganisationList


@pytest.mark.parametrize(
"allowed_calls_30d, actual_calls_30d, expected_overage",
((1000000, 500000, 0), (1000000, 1100000, 100000), (0, 100000, 100000)),
)
def test_organisation_subscription_get_api_call_overage(
organisation: Organisation,
allowed_calls_30d: int,
actual_calls_30d: int,
expected_overage: int,
) -> None:
OrganisationSubscriptionInformationCache.objects.create(
organisation=organisation,
allowed_30d_api_calls=allowed_calls_30d,
api_calls_30d=actual_calls_30d,
)

request = RequestFactory().get("/sales-dashboard")
view = OrganisationList()
view.request = request
result = view.get_queryset().get(pk=organisation.id)

assert result.overage == expected_overage

0 comments on commit 2417f57

Please sign in to comment.