get service and usage

This commit is contained in:
Beverly Nguyen
2025-10-21 12:26:56 -07:00
parent ba01e6e388
commit 0a3d21215c
3 changed files with 48 additions and 5 deletions

View File

@@ -25,6 +25,7 @@ from app.main.views.dashboard import (
from app.models.organization import AllOrganizations, Organization from app.models.organization import AllOrganizations, Organization
from app.models.user import InvitedOrgUser, User from app.models.user import InvitedOrgUser, User
from app.utils.csv import Spreadsheet from app.utils.csv import Spreadsheet
from app.utils.time import parse_naive_dt
from app.utils.user import user_has_permissions, user_is_platform_admin from app.utils.user import user_has_permissions, user_is_platform_admin
from notifications_python_client.errors import HTTPError from notifications_python_client.errors import HTTPError
@@ -76,6 +77,46 @@ def get_organization_message_allowance(org_id):
} }
def get_services_usage(organization, year):
try:
services_and_usage = organization.services_and_usage(financial_year=year, include_all_services=True)["services"]
except Exception as e:
current_app.logger.error(f"Error fetching services and usage: {e}")
return []
services = []
for service in services_and_usage:
service["id"] = service.get("service_id")
service["name"] = service.get("service_name")
emails_sent = service.get("emails_sent", 0)
sms_sent = service.get("sms_billable_units", 0)
sms_remainder = service.get("sms_remainder", 0)
sms_cost = service.get("sms_cost", 0)
usage_parts = []
if emails_sent > 0:
usage_parts.append(f"{emails_sent:,} emails")
if sms_sent > 0 or sms_remainder > 0:
if sms_cost > 0:
usage_parts.append(f"{sms_sent:,} sms ({sms_remainder:,} remaining, ${sms_cost:,.2f})")
else:
usage_parts.append(f"{sms_sent:,} sms ({sms_remainder:,} remaining)")
service["usage"] = ", ".join(usage_parts) if usage_parts else "No usage"
if "created_at" in service and isinstance(service["created_at"], str):
try:
service["created_at"] = parse_naive_dt(service["created_at"])
except (ValueError, TypeError):
service["created_at"] = None
services.append(service)
return services
@main.route("/organizations/<uuid:org_id>", methods=["GET"]) @main.route("/organizations/<uuid:org_id>", methods=["GET"])
@user_has_permissions() @user_has_permissions()
def organization_dashboard(org_id): def organization_dashboard(org_id):
@@ -86,10 +127,12 @@ def organization_dashboard(org_id):
message_allowance = get_organization_message_allowance(org_id) message_allowance = get_organization_message_allowance(org_id)
services_with_usage = get_services_usage(current_organization, year)
return render_template( return render_template(
"views/organizations/organization/index.html", "views/organizations/organization/index.html",
selected_year=year, selected_year=year,
services=current_organization.services, services=services_with_usage,
live_services=len(current_organization.live_services), live_services=len(current_organization.live_services),
trial_services=len(current_organization.trial_services), trial_services=len(current_organization.trial_services),
suspended_services=len(current_organization.suspended_services), suspended_services=len(current_organization.suspended_services),

View File

@@ -139,8 +139,8 @@ class Organization(JSONModel, SortByNameMixin):
def associate_service(self, service_id): def associate_service(self, service_id):
organizations_client.update_service_organization(service_id, self.id) organizations_client.update_service_organization(service_id, self.id)
def services_and_usage(self, financial_year): def services_and_usage(self, financial_year, include_all_services=False):
return organizations_client.get_services_and_usage(self.id, financial_year) return organizations_client.get_services_and_usage(self.id, financial_year, include_all_services)
class Organizations(SerialisedModelCollection): class Organizations(SerialisedModelCollection):

View File

@@ -72,10 +72,10 @@ class OrganizationsClient(NotifyAdminAPIClient):
def remove_user_from_organization(self, org_id, user_id): def remove_user_from_organization(self, org_id, user_id):
return self.delete(f"/organizations/{org_id}/users/{user_id}") return self.delete(f"/organizations/{org_id}/users/{user_id}")
def get_services_and_usage(self, org_id, year): def get_services_and_usage(self, org_id, year, include_all_services=False):
return self.get( return self.get(
url=f"/organizations/{org_id}/services-with-usage", url=f"/organizations/{org_id}/services-with-usage",
params={"year": str(year)}, params={"year": str(year), "include_all_services": str(include_all_services).lower()},
) )
def get_organization_message_usage(self, org_id): def get_organization_message_usage(self, org_id):