mirror of https://github.com/zulip/zulip.git
server_deactivate: Show error message for server on active plan.
This commit is contained in:
parent
c2636354a5
commit
63f4fc51de
|
@ -424,6 +424,14 @@ class StripeConnectionError(BillingError):
|
|||
pass
|
||||
|
||||
|
||||
class ServerDeactivateWithExistingPlanError(BillingError): # nocoverage
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
"server deactivation with existing plan",
|
||||
"",
|
||||
)
|
||||
|
||||
|
||||
class UpgradeWithExistingPlanError(BillingError):
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
|
@ -3853,10 +3861,9 @@ def do_change_remote_server_plan_type(remote_server: RemoteZulipServer, plan_typ
|
|||
|
||||
|
||||
@transaction.atomic
|
||||
def do_deactivate_remote_server(remote_server: RemoteZulipServer) -> None:
|
||||
# TODO: This should also ensure that the server doesn't have an active plan,
|
||||
# and deactivate it otherwise. (Like do_deactivate_realm does.)
|
||||
|
||||
def do_deactivate_remote_server(
|
||||
remote_server: RemoteZulipServer, billing_session: RemoteServerBillingSession
|
||||
) -> None:
|
||||
if remote_server.deactivated:
|
||||
billing_logger.warning(
|
||||
"Cannot deactivate remote server with ID %d, server has already been deactivated.",
|
||||
|
@ -3864,6 +3871,36 @@ def do_deactivate_remote_server(remote_server: RemoteZulipServer) -> None:
|
|||
)
|
||||
return
|
||||
|
||||
server_plans_to_consider = CustomerPlan.objects.filter(
|
||||
customer__remote_server=remote_server
|
||||
).exclude(status=CustomerPlan.ENDED)
|
||||
realm_plans_to_consider = CustomerPlan.objects.filter(
|
||||
customer__remote_realm__server=remote_server
|
||||
).exclude(status=CustomerPlan.ENDED)
|
||||
|
||||
for possible_plan in list(server_plans_to_consider) + list(realm_plans_to_consider):
|
||||
if possible_plan.tier in [
|
||||
CustomerPlan.TIER_SELF_HOSTED_BASE,
|
||||
CustomerPlan.TIER_SELF_HOSTED_LEGACY,
|
||||
CustomerPlan.TIER_SELF_HOSTED_COMMUNITY,
|
||||
]: # nocoverage
|
||||
# No action required for free plans.
|
||||
continue
|
||||
|
||||
if possible_plan.status in [
|
||||
CustomerPlan.DOWNGRADE_AT_END_OF_FREE_TRIAL,
|
||||
CustomerPlan.DOWNGRADE_AT_END_OF_CYCLE,
|
||||
]: # nocoverage
|
||||
# No action required for plans scheduled to downgrade
|
||||
# automatically.
|
||||
continue
|
||||
|
||||
# This customer has some sort of paid plan; ask the customer
|
||||
# to downgrade their paid plan so that they get the
|
||||
# communication in that flow, and then they can come back and
|
||||
# deactivate their server.
|
||||
raise ServerDeactivateWithExistingPlanError # nocoverage
|
||||
|
||||
remote_server.deactivated = True
|
||||
remote_server.save(update_fields=["deactivated"])
|
||||
RemoteZulipServerAuditLog.objects.create(
|
||||
|
|
|
@ -4604,7 +4604,8 @@ class BillingHelpersTest(ZulipTestCase):
|
|||
)
|
||||
self.assertFalse(remote_server.deactivated)
|
||||
|
||||
do_deactivate_remote_server(remote_server)
|
||||
billing_session = RemoteServerBillingSession(remote_server)
|
||||
do_deactivate_remote_server(remote_server, billing_session)
|
||||
|
||||
remote_server = RemoteZulipServer.objects.get(uuid=server_uuid)
|
||||
remote_realm_audit_log = RemoteZulipServerAuditLog.objects.filter(
|
||||
|
@ -4615,7 +4616,7 @@ class BillingHelpersTest(ZulipTestCase):
|
|||
|
||||
# Try to deactivate a remote server that is already deactivated
|
||||
with self.assertLogs("corporate.stripe", "WARN") as warning_log:
|
||||
do_deactivate_remote_server(remote_server)
|
||||
do_deactivate_remote_server(remote_server, billing_session)
|
||||
self.assertEqual(
|
||||
warning_log.output,
|
||||
[
|
||||
|
|
|
@ -14,6 +14,7 @@ from corporate.lib.stripe import (
|
|||
RealmBillingSession,
|
||||
RemoteRealmBillingSession,
|
||||
RemoteServerBillingSession,
|
||||
ServerDeactivateWithExistingPlanError,
|
||||
UpdatePlanRequest,
|
||||
do_deactivate_remote_server,
|
||||
)
|
||||
|
@ -300,11 +301,11 @@ def remote_server_deactivate_page(
|
|||
return HttpResponseNotAllowed(["GET", "POST"])
|
||||
|
||||
remote_server = billing_session.remote_server
|
||||
if request.method == "GET":
|
||||
context = {
|
||||
"server_hostname": remote_server.hostname,
|
||||
"action_url": reverse(remote_server_deactivate_page, args=[str(remote_server.uuid)]),
|
||||
}
|
||||
if request.method == "GET":
|
||||
return render(request, "corporate/remote_billing_server_deactivate.html", context=context)
|
||||
|
||||
assert request.method == "POST"
|
||||
|
@ -312,7 +313,12 @@ def remote_server_deactivate_page(
|
|||
# Should be impossible if the user is using the UI.
|
||||
raise JsonableError(_("Parameter 'confirmed' is required"))
|
||||
|
||||
do_deactivate_remote_server(remote_server)
|
||||
try:
|
||||
do_deactivate_remote_server(remote_server, billing_session)
|
||||
except ServerDeactivateWithExistingPlanError: # nocoverage
|
||||
context["show_existing_plan_error"] = "true"
|
||||
return render(request, "corporate/remote_billing_server_deactivate.html", context=context)
|
||||
|
||||
return render(
|
||||
request,
|
||||
"corporate/remote_billing_server_deactivated_success.html",
|
||||
|
|
|
@ -15,6 +15,13 @@
|
|||
</div>
|
||||
<div class="white-box">
|
||||
<div id="server-deactivate-details">
|
||||
{% if show_existing_plan_error %}
|
||||
<div id="server-deactivate-error" class="alert alert-danger">
|
||||
Could not deactivate registration. You must first
|
||||
<a href="https://zulip.com/help/self-hosted-billing#cancel-paid-plan">cancel</a>
|
||||
all paid plans associated with this server, including scheduled plan upgrades.
|
||||
</div>
|
||||
{% endif %}
|
||||
<form id="server-deactivate-form" method="post" action="{{ action_url }}">
|
||||
{{ csrf_input }}
|
||||
<div id="server-deactivate-form-top-description" class="input-box server-deactivate-form-field no-validation">
|
||||
|
|
|
@ -669,6 +669,7 @@ input[name="licenses"] {
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
#server-deactivate-error,
|
||||
#server-login-error,
|
||||
#autopay-error {
|
||||
font-weight: 400;
|
||||
|
@ -697,6 +698,7 @@ input[name="licenses"] {
|
|||
top: 5px;
|
||||
}
|
||||
|
||||
#server-deactivate-error,
|
||||
#server-login-error {
|
||||
text-align: left;
|
||||
margin: 0 auto;
|
||||
|
|
|
@ -479,6 +479,7 @@ html {
|
|||
|
||||
.alert {
|
||||
&:not(
|
||||
#server-deactivate-error,
|
||||
#server-login-error,
|
||||
.alert-info,
|
||||
.billing-page-success,
|
||||
|
|
|
@ -92,7 +92,8 @@ def deactivate_remote_server(
|
|||
request: HttpRequest,
|
||||
remote_server: RemoteZulipServer,
|
||||
) -> HttpResponse:
|
||||
do_deactivate_remote_server(remote_server)
|
||||
billing_session = RemoteServerBillingSession(remote_server)
|
||||
do_deactivate_remote_server(remote_server, billing_session)
|
||||
return json_success(request)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue