support: Extract PlanData as a dataclass.

This avoids monkey-patching `CustomerPlan` and other related information
onto the `Realm` object by having a separate dictionary with the realm
id as the key, each corresponds to a `PlandData` dataclass.

This is a part of the django-stubs refactorings.

Signed-off-by: Zixuan James Li <p359101898@gmail.com>
This commit is contained in:
Zixuan James Li 2022-06-30 11:36:52 -04:00 committed by Tim Abbott
parent 74f59bd8d0
commit 0d93257111
2 changed files with 35 additions and 22 deletions

View File

@ -1,4 +1,5 @@
import urllib
from dataclasses import dataclass
from datetime import timedelta
from decimal import Decimal
from typing import Any, Dict, Iterable, List, Optional
@ -16,6 +17,7 @@ from django.utils.translation import gettext as _
from confirmation.models import Confirmation, confirmation_url
from confirmation.settings import STATUS_ACTIVE
from corporate.models import Customer, CustomerPlan
from zerver.actions.create_realm import do_change_realm_subdomain
from zerver.actions.realm_settings import (
do_change_realm_org_type,
@ -129,6 +131,14 @@ VALID_BILLING_METHODS = [
]
@dataclass
class PlanData:
customer: Optional[Customer] = None
current_plan: Optional[CustomerPlan] = None
licenses: Optional[int] = None
licenses_used: Optional[int] = None
@require_server_admin
@has_request_variables
def support(
@ -277,27 +287,30 @@ def support(
except ValidationError:
users.update(UserProfile.objects.filter(full_name__iexact=key_word))
plan_data: Dict[int, PlanData] = {}
for realm in realms:
realm.customer = get_customer_by_realm(realm)
current_plan = get_current_plan_by_realm(realm)
plan_data[realm.id] = PlanData(
customer=get_customer_by_realm(realm),
current_plan=current_plan,
)
if current_plan is not None:
new_plan, last_ledger_entry = make_end_of_cycle_updates_if_needed(
current_plan, timezone_now()
)
if last_ledger_entry is not None:
if new_plan is not None:
realm.current_plan = new_plan
plan_data[realm.id].current_plan = new_plan
else:
realm.current_plan = current_plan
realm.current_plan.licenses = last_ledger_entry.licenses
realm.current_plan.licenses_used = get_latest_seat_count(realm)
plan_data[realm.id].current_plan = current_plan
plan_data[realm.id].licenses = last_ledger_entry.licenses
plan_data[realm.id].licenses_used = get_latest_seat_count(realm)
# full_names can have , in them
users.update(UserProfile.objects.filter(full_name__iexact=query))
context["users"] = users
context["realms"] = realms
context["plan_data"] = plan_data
confirmations: List[Dict[str, Any]] = []

View File

@ -80,13 +80,13 @@
{{ csrf_input }}
<input type="hidden" name="realm_id" value="{{ realm.id }}" />
<select name="sponsorship_pending">
<option value="true" {% if realm.customer and realm.customer.sponsorship_pending %}selected{% endif %}>Yes</option>
<option value="false" {% if not realm.customer or not realm.customer.sponsorship_pending %}selected{% endif %}>No</option>
<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>
</select>
<button type="submit" class="btn btn-default support-submit-button">Update</button>
</form>
{% if realm.customer and realm.customer.sponsorship_pending %}
{% if plan_data[realm.id].customer and plan_data[realm.id].customer.sponsorship_pending %}
<form method="POST" class="approve-sponsorship-form">
{{ csrf_input }}
<input type="hidden" name="realm_id" value="{{ realm.id }}" />
@ -102,7 +102,7 @@
<b>Discount (use 85 for nonprofits)</b>:<br />
{{ csrf_input }}
<input type="hidden" name="realm_id" value="{{ realm.id }}" />
{% if realm.current_plan and realm.current_plan.fixed_price %}
{% if plan_data[realm.id].current_plan and plan_data[realm.id].current_plan.fixed_price %}
<input type="number" name="discount" value="{{ get_discount_for_realm(realm) }}" disabled />
<button type="submit" class="btn btn-default support-submit-button" disabled>Update</button>
{% else %}
@ -110,19 +110,19 @@
<button type="submit" class="btn btn-default support-submit-button">Update</button>
{% endif %}
</form>
{% if realm.current_plan %}
{% if plan_data[realm.id].current_plan %}
<div class="current-plan-details">
<h3>📅 Current plan</h3>
<b>Name</b>: {{ realm.current_plan.name }}<br />
<b>Status</b>: {{realm.current_plan.get_plan_status_as_text()}}<br />
<b>Billing schedule</b>: {% if realm.current_plan.billing_schedule == realm.current_plan.ANNUAL %}Annual{% else %}Monthly{% endif %}<br />
<b>Licenses</b>: {{ realm.current_plan.licenses_used }}/{{ realm.current_plan.licenses }} ({% if realm.current_plan.automanage_licenses %}Automatic{% else %}Manual{% endif %})<br />
{% if realm.current_plan.price_per_license %}
<b>Price per license</b>: ${{ realm.current_plan.price_per_license/100 }}<br />
<b>Name</b>: {{ plan_data[realm.id].current_plan.name }}<br />
<b>Status</b>: {{plan_data[realm.id].current_plan.get_plan_status_as_text()}}<br />
<b>Billing schedule</b>: {% if plan_data[realm.id].current_plan.billing_schedule == plan_data[realm.id].current_plan.ANNUAL %}Annual{% else %}Monthly{% endif %}<br />
<b>Licenses</b>: {{ plan_data[realm.id].licenses_used }}/{{ plan_data[realm.id].licenses }} ({% if plan_data[realm.id].current_plan.automanage_licenses %}Automatic{% else %}Manual{% endif %})<br />
{% if plan_data[realm.id].current_plan.price_per_license %}
<b>Price per license</b>: ${{ plan_data[realm.id].current_plan.price_per_license/100 }}<br />
{% else %}
<b>Fixed price</b>: ${{ realm.current_plan.fixed_price/100 }}<br />
<b>Fixed price</b>: ${{ plan_data[realm.id].current_plan.fixed_price/100 }}<br />
{% endif %}
<b>Next invoice date</b>: {{ realm.current_plan.next_invoice_date.strftime('%d %B %Y') }}<br />
<b>Next invoice date</b>: {{ plan_data[realm.id].current_plan.next_invoice_date.strftime('%d %B %Y') }}<br />
</div>
<form method="POST" class="billing-method-form">
@ -131,8 +131,8 @@
{{ csrf_input }}
<input type="hidden" name="realm_id" value="{{ realm.id }}" />
<select name="billing_method" class="billing-method-select" required>
<option value="charge_automatically" {% if realm.current_plan.charge_automatically %}selected{% endif %}>Charge automatically</option>
<option value="send_invoice" {% if not realm.current_plan.charge_automatically %}selected{% endif %}>Pay by invoice</option>
<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>
</select>
<button type="submit" class="btn btn-default support-submit-button">Update</button>
</form>