support: Add button to delete configured fixed next plan.

This will help us modify the configured plan if we need to.
This commit is contained in:
Aman Agrawal
2024-02-13 12:23:07 +00:00
committed by Tim Abbott
parent 68c3c6b872
commit 8cba101e05
7 changed files with 84 additions and 0 deletions

View File

@@ -571,6 +571,7 @@ class SupportType(Enum):
update_plan_end_date = 7
update_required_plan_tier = 8
configure_fixed_price_plan = 9
delete_fixed_price_next_plan = 10
class SupportViewRequest(TypedDict, total=False):
@@ -3030,6 +3031,15 @@ class BillingSession(ABC):
assert support_request["new_plan_tier"] is not None
new_plan_tier = support_request["new_plan_tier"]
success_message = self.do_change_plan_to_new_tier(new_plan_tier)
elif support_type == SupportType.delete_fixed_price_next_plan:
customer = self.get_customer()
assert customer is not None
fixed_price_offer = CustomerPlanOffer.objects.filter(
customer=customer, status=CustomerPlanOffer.CONFIGURED
).first()
assert fixed_price_offer is not None
fixed_price_offer.delete()
success_message = "Fixed price offer deleted"
return success_message

View File

@@ -6350,6 +6350,61 @@ class TestRemoteRealmBillingFlow(StripeTestCase, RemoteRealmBillingTestCase):
]:
self.assert_in_response(substring, response)
@responses.activate
@mock_stripe()
def test_delete_configured_fixed_price_plan_offer(self, *mocks: Mock) -> None:
self.login("iago")
self.add_mock_response()
with time_machine.travel(self.now, tick=False):
send_server_data_to_push_bouncer(consider_usage_statistics=False)
self.assertFalse(CustomerPlanOffer.objects.exists())
annual_fixed_price = 1200
# Configure required_plan_tier and fixed_price.
result = self.client_post(
"/activity/remote/support",
{
"remote_realm_id": f"{self.remote_realm.id}",
"required_plan_tier": CustomerPlan.TIER_SELF_HOSTED_BASIC,
},
)
self.assert_in_success_response(
["Required plan tier for Zulip Dev set to Zulip Basic."], result
)
result = self.client_post(
"/activity/remote/support",
{"remote_realm_id": f"{self.remote_realm.id}", "fixed_price": annual_fixed_price},
)
self.assert_in_success_response(
["Customer can now buy a fixed price Zulip Basic plan."], result
)
fixed_price_plan_offer = CustomerPlanOffer.objects.filter(
status=CustomerPlanOffer.CONFIGURED
).first()
assert fixed_price_plan_offer is not None
self.assertEqual(fixed_price_plan_offer.tier, CustomerPlanOffer.TIER_SELF_HOSTED_BASIC)
self.assertEqual(fixed_price_plan_offer.fixed_price, annual_fixed_price * 100)
self.assertEqual(fixed_price_plan_offer.get_plan_status_as_text(), "Configured")
result = self.client_get("/activity/remote/support", {"q": "example.com"})
self.assert_in_success_response(
["Next plan information:", "Zulip Basic", "Configured", "Plan has a fixed price."],
result,
)
billing_session = RemoteRealmBillingSession(remote_realm=self.remote_realm)
support_request = SupportViewRequest(
support_type=SupportType.delete_fixed_price_next_plan,
)
success_message = billing_session.process_support_view_request(support_request)
self.assertEqual(success_message, "Fixed price offer deleted")
result = self.client_get("/activity/remote/support", {"q": "example.com"})
self.assert_not_in_success_response(["Next plan information:"], result)
self.assert_in_success_response(["Fixed price", "Annual amount in dollars"], result)
@responses.activate
@mock_stripe()
def test_upgrade_user_to_fixed_price_plan_pay_by_invoice(self, *mocks: Mock) -> None:

View File

@@ -503,6 +503,7 @@ def remote_servers_support(
modify_plan: Optional[str] = REQ(
default=None, str_validator=check_string_in(VALID_MODIFY_PLAN_METHODS)
),
delete_fixed_price_next_plan: bool = REQ(default=False, json_validator=check_bool),
) -> HttpResponse:
context: Dict[str, Any] = {}
@@ -573,6 +574,10 @@ def remote_servers_support(
support_type=SupportType.modify_plan,
plan_modification=modify_plan,
)
elif delete_fixed_price_next_plan:
support_view_request = SupportViewRequest(
support_type=SupportType.delete_fixed_price_next_plan,
)
if support_view_request is not None:
if remote_realm_support_request:
try:

View File

@@ -16,3 +16,11 @@
{% endif %}
{% endif %}
<b>Estimated annual revenue</b>: ${{ dollar_amount(plan_data.estimated_next_plan_revenue) }}<br />
{% if plan_data.next_plan.fixed_price %}
<form method="POST">
{{ csrf_input }}
<input type="hidden" name="{{ remote_type }}" value="{{ remote_id }}" />
<input type="hidden" name="delete_fixed_price_next_plan" value="true" />
<button type="submit" class="delete-next-fixed-price-plan-button">Delete configured fixed price next plan</button>
</form>
{% endif %}

View File

@@ -63,6 +63,8 @@
{% set plan_data = support_data[remote_realm.id].plan_data %}
{% set format_discount = format_discount %}
{% set dollar_amount = dollar_amount %}
{% set remote_id = remote_realm.id %}
{% set remote_type = "remote_realm_id" %}
{% include 'corporate/support/next_plan_details.html' %}
{% endwith %}
</div>

View File

@@ -103,6 +103,8 @@
{% set plan_data = remote_servers_support_data[remote_server.id].plan_data %}
{% set format_discount = format_discount %}
{% set dollar_amount = dollar_amount %}
{% set remote_id = remote_server.id %}
{% set remote_type = "remote_server_id" %}
{% include 'corporate/support/next_plan_details.html' %}
{% endwith %}
</div>

View File

@@ -170,6 +170,7 @@ tr.admin td:first-child {
}
}
.delete-next-fixed-price-plan-button,
.approve-sponsorship-button,
.support-search-button,
.support-submit-button,
@@ -228,6 +229,7 @@ tr.admin td:first-child {
}
}
.delete-next-fixed-price-plan-button,
.delete-user-button,
.scrub-realm-button {
color: hsl(0deg 0% 100%);