diff --git a/corporate/views/support.py b/corporate/views/support.py index 9e55b0a5cc..0acb144b1d 100644 --- a/corporate/views/support.py +++ b/corporate/views/support.py @@ -661,6 +661,20 @@ def remote_servers_support( "Recent analytics data missing" ) + def get_remote_server_billing_user_emails_as_string(remote_server: RemoteZulipServer) -> str: + return ", ".join( + remote_server.get_remote_server_billing_users() + .order_by("email") + .values_list("email", flat=True) + ) + + def get_remote_realm_billing_user_emails_as_string(remote_realm: RemoteRealm) -> str: + return ", ".join( + remote_realm.get_remote_realm_billing_users() + .order_by("email") + .values_list("email", flat=True) + ) + context["remote_servers"] = remote_servers context["remote_servers_support_data"] = server_support_data context["remote_server_to_max_monthly_messages"] = remote_server_to_max_monthly_messages @@ -673,6 +687,10 @@ def remote_servers_support( context["dollar_amount"] = cents_to_dollar_string context["server_analytics_link"] = remote_installation_stats_link context["REMOTE_PLAN_TIERS"] = get_remote_plan_tier_options() + context["get_remote_server_billing_user_emails"] = ( + get_remote_server_billing_user_emails_as_string + ) + context["get_remote_realm_billing_user_emails"] = get_remote_realm_billing_user_emails_as_string context["SPONSORED_PLAN_TYPE"] = RemoteZulipServer.PLAN_TYPE_COMMUNITY return render( diff --git a/templates/corporate/support/remote_realm_details.html b/templates/corporate/support/remote_realm_details.html index d8c2cef7f8..bcc4cf7fb6 100644 --- a/templates/corporate/support/remote_realm_details.html +++ b/templates/corporate/support/remote_realm_details.html @@ -18,6 +18,14 @@

Has a discount 💸

{% endif %} Remote realm host: {{ remote_realm.host }}
+ {% set billing_emails_string = get_remote_realm_billing_user_emails(remote_realm) %} + Billing users: {{ billing_emails_string }} + {% if billing_emails_string %} + + + + {% endif %} +
Date created: {{ support_data[remote_realm.id].date_created.strftime('%d %B %Y') }}
Org type: {{ get_org_type_display_name(remote_realm.org_type) }}
Plan type: {{ get_plan_type_name(remote_realm.plan_type) }}
diff --git a/templates/corporate/support/remote_server_support.html b/templates/corporate/support/remote_server_support.html index 93fa7729bb..5a5b8abc18 100644 --- a/templates/corporate/support/remote_server_support.html +++ b/templates/corporate/support/remote_server_support.html @@ -49,6 +49,14 @@
+ {% set billing_emails_string = get_remote_server_billing_user_emails(remote_server) %} + Billing users: {{ billing_emails_string }} + {% if billing_emails_string %} + + + + {% endif %} +
UUID: {{ remote_server.uuid }}
Date created: {{ remote_servers_support_data[remote_server.id].date_created.strftime('%d %B %Y') }}
Zulip version: {{ remote_server.last_version }}
diff --git a/tools/linter_lib/custom_check.py b/tools/linter_lib/custom_check.py index 93acb9c731..7ce19f6209 100644 --- a/tools/linter_lib/custom_check.py +++ b/tools/linter_lib/custom_check.py @@ -631,6 +631,7 @@ html_rules: List["Rule"] = [ "templates/corporate/support/realm_details.html", "templates/corporate/support/remote_server_support.html", "templates/corporate/support/support.html", + "templates/corporate/support/remote_realm_details.html", }, "description": "`title` value should be translatable.", }, diff --git a/zilencer/models.py b/zilencer/models.py index 5fdb5591eb..75870a6e08 100644 --- a/zilencer/models.py +++ b/zilencer/models.py @@ -8,7 +8,7 @@ from typing import List, Tuple from django.conf import settings from django.core.exceptions import ValidationError from django.db import models -from django.db.models import Max, Q, UniqueConstraint +from django.db.models import Max, Q, QuerySet, UniqueConstraint from django.utils.timezone import now as timezone_now from typing_extensions import override @@ -88,6 +88,12 @@ class RemoteZulipServer(models.Model): def format_requester_for_logs(self) -> str: return "zulip-server:" + str(self.uuid) + def get_remote_server_billing_users(self) -> QuerySet["RemoteServerBillingUser"]: + return RemoteServerBillingUser.objects.filter( + remote_server=self, + is_active=True, + ) + class RemotePushDeviceToken(AbstractPushDeviceToken): """Like PushDeviceToken, but for a device connected to a remote server.""" @@ -176,6 +182,12 @@ class RemoteRealm(models.Model): def __str__(self) -> str: return f"{self.host} {str(self.uuid)[0:12]}" + def get_remote_realm_billing_users(self) -> QuerySet["RemoteRealmBillingUser"]: + return RemoteRealmBillingUser.objects.filter( + remote_realm=self, + is_active=True, + ) + class AbstractRemoteRealmBillingUser(models.Model): remote_realm = models.ForeignKey(RemoteRealm, on_delete=models.CASCADE)