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 ( from corporate.lib.stripe import (
BillingSession, BillingSession,
PushNotificationsEnabledStatus, PushNotificationsEnabledStatus,
RealmBillingSession,
RemoteRealmBillingSession, RemoteRealmBillingSession,
RemoteServerBillingSession, RemoteServerBillingSession,
get_configured_fixed_price_plan_offer, get_configured_fixed_price_plan_offer,
@ -95,7 +96,7 @@ class MobilePushData:
@dataclass @dataclass
class SupportData: class RemoteSupportData:
date_created: datetime date_created: datetime
plan_data: PlanData plan_data: PlanData
sponsorship_data: SponsorshipData sponsorship_data: SponsorshipData
@ -103,6 +104,12 @@ class SupportData:
mobile_push_data: MobilePushData mobile_push_data: MobilePushData
@dataclass
class CloudSupportData:
plan_data: PlanData
sponsorship_data: SponsorshipData
def get_realm_support_url(realm: Realm) -> str: def get_realm_support_url(realm: Realm) -> str:
support_realm_uri = get_realm(settings.STAFF_SUBDOMAIN).uri support_realm_uri = get_realm(settings.STAFF_SUBDOMAIN).uri
support_url = urljoin( support_url = urljoin(
@ -112,14 +119,6 @@ def get_realm_support_url(realm: Realm) -> str:
return support_url 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: def get_customer_sponsorship_data(customer: Customer) -> SponsorshipData:
pending = customer.sponsorship_pending pending = customer.sponsorship_pending
discount = customer.default_discount 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): if isinstance(billing_session, RemoteServerBillingSession):
user_data = get_remote_server_guest_and_non_guest_count(billing_session.remote_server.id) 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) 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: else:
sponsorship_data = SponsorshipData() sponsorship_data = SponsorshipData()
return SupportData( return RemoteSupportData(
date_created=date_created, date_created=date_created,
plan_data=plan_data, plan_data=plan_data,
sponsorship_data=sponsorship_data, sponsorship_data=sponsorship_data,
user_data=user_data, user_data=user_data,
mobile_push_data=mobile_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, format_discount_percentage,
) )
from corporate.lib.support import ( from corporate.lib.support import (
PlanData, CloudSupportData,
SupportData, RemoteSupportData,
get_customer_discount_for_support_view, get_data_for_cloud_support_view,
get_data_for_support_view, get_data_for_remote_support_view,
get_plan_data_for_support_view,
get_realm_support_url, get_realm_support_url,
) )
from corporate.models import CustomerPlan from corporate.models import CustomerPlan
@ -454,12 +453,12 @@ def support(
] ]
+ [user.realm for user in users] + [user.realm for user in users]
) )
plan_data: Dict[int, PlanData] = {} realm_support_data: Dict[int, CloudSupportData] = {}
for realm in all_realms: for realm in all_realms:
billing_session = RealmBillingSession(user=None, realm=realm) billing_session = RealmBillingSession(user=None, realm=realm)
realm_plan_data = get_plan_data_for_support_view(billing_session) realm_data = get_data_for_cloud_support_view(billing_session)
plan_data[realm.id] = realm_plan_data realm_support_data[realm.id] = realm_data
context["plan_data"] = plan_data context["realm_support_data"] = realm_support_data
def get_realm_owner_emails_as_string(realm: Realm) -> str: def get_realm_owner_emails_as_string(realm: Realm) -> str:
return ", ".join( return ", ".join(
@ -477,7 +476,6 @@ def support(
context["get_realm_owner_emails_as_string"] = get_realm_owner_emails_as_string 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_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["format_discount"] = format_discount_percentage
context["dollar_amount"] = cents_to_dollar_string context["dollar_amount"] = cents_to_dollar_string
context["realm_icon_url"] = realm_icon_url context["realm_icon_url"] = realm_icon_url
@ -691,8 +689,8 @@ def remote_servers_support(
hostname_to_search=hostname_to_search, hostname_to_search=hostname_to_search,
) )
remote_server_to_max_monthly_messages: Dict[int, Union[int, str]] = dict() remote_server_to_max_monthly_messages: Dict[int, Union[int, str]] = dict()
server_support_data: Dict[int, SupportData] = {} server_support_data: Dict[int, RemoteSupportData] = {}
realm_support_data: Dict[int, SupportData] = {} realm_support_data: Dict[int, RemoteSupportData] = {}
remote_realms: Dict[int, List[RemoteRealm]] = {} remote_realms: Dict[int, List[RemoteRealm]] = {}
for remote_server in remote_servers: for remote_server in remote_servers:
# Get remote realms attached to remote server # Get remote realms attached to remote server
@ -703,11 +701,11 @@ def remote_servers_support(
# Get plan data for remote realms # Get plan data for remote realms
for remote_realm in remote_realms_for_server: for remote_realm in remote_realms_for_server:
realm_billing_session = RemoteRealmBillingSession(remote_realm=remote_realm) 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 realm_support_data[remote_realm.id] = remote_realm_data
# Get plan data for remote server # Get plan data for remote server
server_billing_session = RemoteServerBillingSession(remote_server=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 server_support_data[remote_server.id] = remote_server_data
# Get max monthly messages # Get max monthly messages
try: try:

View File

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

View File

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