cloud-support: Display most recent sponsorship request information.

Refactors the Cloud support view to pass in any sponsorship or
discount information about the Customer object for the realm,
which allows us to display any information submitted in a
sponsorship request.
This commit is contained in:
Lauryn Menard 2024-03-07 18:06:14 +01:00 committed by Tim Abbott
parent c9caad20d0
commit 4e1e490b40
4 changed files with 55 additions and 35 deletions

View File

@ -12,6 +12,7 @@ from django.utils.timezone import now as timezone_now
from corporate.lib.stripe import (
BillingSession,
PushNotificationsEnabledStatus,
RealmBillingSession,
RemoteRealmBillingSession,
RemoteServerBillingSession,
get_configured_fixed_price_plan_offer,
@ -95,7 +96,7 @@ class MobilePushData:
@dataclass
class SupportData:
class RemoteSupportData:
date_created: datetime
plan_data: PlanData
sponsorship_data: SponsorshipData
@ -103,6 +104,12 @@ class SupportData:
mobile_push_data: MobilePushData
@dataclass
class CloudSupportData:
plan_data: PlanData
sponsorship_data: SponsorshipData
def get_realm_support_url(realm: Realm) -> str:
support_realm_uri = get_realm(settings.STAFF_SUBDOMAIN).uri
support_url = urljoin(
@ -112,14 +119,6 @@ def get_realm_support_url(realm: Realm) -> str:
return support_url
def get_customer_discount_for_support_view(
customer: Optional[Customer] = None,
) -> Optional[Decimal]:
if customer is None:
return None
return customer.default_discount
def get_customer_sponsorship_data(customer: Customer) -> SponsorshipData:
pending = customer.sponsorship_pending
discount = customer.default_discount
@ -353,7 +352,7 @@ def get_mobile_push_data(remote_entity: Union[RemoteZulipServer, RemoteRealm]) -
)
def get_data_for_support_view(billing_session: BillingSession) -> SupportData:
def get_data_for_remote_support_view(billing_session: BillingSession) -> RemoteSupportData:
if isinstance(billing_session, RemoteServerBillingSession):
user_data = get_remote_server_guest_and_non_guest_count(billing_session.remote_server.id)
stale_audit_log_data = has_stale_audit_log(billing_session.remote_server)
@ -375,10 +374,24 @@ def get_data_for_support_view(billing_session: BillingSession) -> SupportData:
else:
sponsorship_data = SponsorshipData()
return SupportData(
return RemoteSupportData(
date_created=date_created,
plan_data=plan_data,
sponsorship_data=sponsorship_data,
user_data=user_data,
mobile_push_data=mobile_data,
)
def get_data_for_cloud_support_view(billing_session: BillingSession) -> CloudSupportData:
assert isinstance(billing_session, RealmBillingSession)
plan_data = get_plan_data_for_support_view(billing_session)
if plan_data.customer is not None:
sponsorship_data = get_customer_sponsorship_data(plan_data.customer)
else:
sponsorship_data = SponsorshipData()
return CloudSupportData(
plan_data=plan_data,
sponsorship_data=sponsorship_data,
)

View File

@ -36,11 +36,10 @@ from corporate.lib.stripe import (
format_discount_percentage,
)
from corporate.lib.support import (
PlanData,
SupportData,
get_customer_discount_for_support_view,
get_data_for_support_view,
get_plan_data_for_support_view,
CloudSupportData,
RemoteSupportData,
get_data_for_cloud_support_view,
get_data_for_remote_support_view,
get_realm_support_url,
)
from corporate.models import CustomerPlan
@ -454,12 +453,12 @@ def support(
]
+ [user.realm for user in users]
)
plan_data: Dict[int, PlanData] = {}
realm_support_data: Dict[int, CloudSupportData] = {}
for realm in all_realms:
billing_session = RealmBillingSession(user=None, realm=realm)
realm_plan_data = get_plan_data_for_support_view(billing_session)
plan_data[realm.id] = realm_plan_data
context["plan_data"] = plan_data
realm_data = get_data_for_cloud_support_view(billing_session)
realm_support_data[realm.id] = realm_data
context["realm_support_data"] = realm_support_data
def get_realm_owner_emails_as_string(realm: Realm) -> str:
return ", ".join(
@ -477,7 +476,6 @@ def support(
context["get_realm_owner_emails_as_string"] = get_realm_owner_emails_as_string
context["get_realm_admin_emails_as_string"] = get_realm_admin_emails_as_string
context["get_discount"] = get_customer_discount_for_support_view
context["format_discount"] = format_discount_percentage
context["dollar_amount"] = cents_to_dollar_string
context["realm_icon_url"] = realm_icon_url
@ -691,8 +689,8 @@ def remote_servers_support(
hostname_to_search=hostname_to_search,
)
remote_server_to_max_monthly_messages: Dict[int, Union[int, str]] = dict()
server_support_data: Dict[int, SupportData] = {}
realm_support_data: Dict[int, SupportData] = {}
server_support_data: Dict[int, RemoteSupportData] = {}
realm_support_data: Dict[int, RemoteSupportData] = {}
remote_realms: Dict[int, List[RemoteRealm]] = {}
for remote_server in remote_servers:
# Get remote realms attached to remote server
@ -703,11 +701,11 @@ def remote_servers_support(
# Get plan data for remote realms
for remote_realm in remote_realms_for_server:
realm_billing_session = RemoteRealmBillingSession(remote_realm=remote_realm)
remote_realm_data = get_data_for_support_view(realm_billing_session)
remote_realm_data = get_data_for_remote_support_view(realm_billing_session)
realm_support_data[remote_realm.id] = remote_realm_data
# Get plan data for remote server
server_billing_session = RemoteServerBillingSession(remote_server=remote_server)
remote_server_data = get_data_for_support_view(server_billing_session)
remote_server_data = get_data_for_remote_support_view(server_billing_session)
server_support_data[remote_server.id] = remote_server_data
# Get max monthly messages
try:

View File

@ -85,13 +85,13 @@
{{ csrf_input }}
<input type="hidden" name="realm_id" value="{{ realm.id }}" />
<select name="sponsorship_pending">
<option value="true" {% if plan_data[realm.id].customer and plan_data[realm.id].customer.sponsorship_pending %}selected{% endif %}>Yes</option>
<option value="false" {% if not plan_data[realm.id].customer or not plan_data[realm.id].customer.sponsorship_pending %}selected{% endif %}>No</option>
<option value="true" {% if realm_support_data[realm.id].sponsorship_data.sponsorship_pending %}selected{% endif %}>Yes</option>
<option value="false" {% if not realm_support_data[realm.id].sponsorship_data.sponsorship_pending %}selected{% endif %}>No</option>
</select>
<button type="submit" class="support-submit-button">Update</button>
</form>
{% if plan_data[realm.id].customer and plan_data[realm.id].customer.sponsorship_pending %}
{% if realm_support_data[realm.id].sponsorship_data.sponsorship_pending %}
<form method="POST" class="approve-sponsorship-form support-form">
{{ csrf_input }}
<input type="hidden" name="realm_id" value="{{ realm.id }}" />
@ -107,19 +107,26 @@
<b>Discount (use 85 for nonprofits)</b>:<br />
{{ csrf_input }}
<input type="hidden" name="realm_id" value="{{ realm.id }}" />
{% if plan_data[realm.id].current_plan and plan_data[realm.id].current_plan.fixed_price %}
<input type="number" name="discount" value="{{ format_discount(get_discount(plan_data[realm.id].customer)) }}" step="0.01" min="0" max="99.99" disabled />
{% if realm_support_data[realm.id].plan_data.current_plan and realm_support_data[realm.id].plan_data.current_plan.fixed_price %}
<input type="number" name="discount" value="{{ format_discount(realm_support_data[realm.id].sponsorship_data.default_discount) }}" step="0.01" min="0" max="99.99" disabled />
<button type="submit" class="support-submit-button" disabled>Update</button>
{% else %}
<input type="number" name="discount" value="{{ format_discount(get_discount(plan_data[realm.id].customer)) }}" step="0.01" min="0" max="99.99" required />
<input type="number" name="discount" value="{{ format_discount(realm_support_data[realm.id].sponsorship_data.default_discount) }}" step="0.01" min="0" max="99.99" required />
<button type="submit" class="support-submit-button">Update</button>
{% endif %}
</form>
{% if realm_support_data[realm.id].sponsorship_data.sponsorship_pending %}
{% with %}
{% set latest_sponsorship_request = realm_support_data[realm.id].sponsorship_data.latest_sponsorship_request %}
{% include 'corporate/support/sponsorship_request_details.html' %}
{% endwith %}
{% endif %}
</div>
{% if plan_data[realm.id].current_plan %}
{% if realm_support_data[realm.id].plan_data.current_plan %}
<div class="current-plan-container">
{% with %}
{% set plan_data = plan_data[realm.id] %}
{% set plan_data = realm_support_data[realm.id].plan_data %}
{% set format_discount = format_discount %}
{% set dollar_amount = dollar_amount %}
{% include 'corporate/support/current_plan_details.html' %}
@ -130,8 +137,8 @@
{{ csrf_input }}
<input type="hidden" name="realm_id" value="{{ realm.id }}" />
<select name="billing_modality" class="billing-modality-select" required>
<option value="charge_automatically" {% if plan_data[realm.id].current_plan.charge_automatically %}selected{% endif %}>Charge automatically</option>
<option value="send_invoice" {% if not plan_data[realm.id].current_plan.charge_automatically %}selected{% endif %}>Pay by invoice</option>
<option value="charge_automatically" {% if realm_support_data[realm.id].plan_data.current_plan.charge_automatically %}selected{% endif %}>Charge automatically</option>
<option value="send_invoice" {% if not realm_support_data[realm.id].plan_data.current_plan.charge_automatically %}selected{% endif %}>Pay by invoice</option>
</select>
<button type="submit" class="support-submit-button">Update</button>
</form>

View File

@ -8,7 +8,9 @@
<li><b>Estimated total users</b>: {{ latest_sponsorship_request.total_users }}</li>
<li><b>Paid staff</b>: {{ latest_sponsorship_request.paid_users }}</li>
<li><b>Description of paid staff</b>: {{ latest_sponsorship_request.paid_users_description }}</li>
{% if latest_sponsorship_request.requested_plan != "" %}
<li><b>Requested plan</b>: {{ latest_sponsorship_request.requested_plan }}</li>
{% endif %}
</ul>
{% else %}
<b>No sponsorship requests have been submitted.</b>