mirror of https://github.com/zulip/zulip.git
billing: Standardize remote server plan type IDs.
This will likely save us at least one headache.
This commit is contained in:
parent
89545891f6
commit
6308e07e53
|
@ -75,7 +75,8 @@ def get_plan_type_string(plan_type: int) -> str:
|
|||
Realm.PLAN_TYPE_STANDARD: "Standard",
|
||||
Realm.PLAN_TYPE_STANDARD_FREE: "Standard free",
|
||||
Realm.PLAN_TYPE_PLUS: "Plus",
|
||||
RemoteZulipServer.PLAN_TYPE_SELF_HOSTED: "Self-hosted",
|
||||
RemoteZulipServer.PLAN_TYPE_SELF_MANAGED: "Self-managed",
|
||||
RemoteZulipServer.PLAN_TYPE_SELF_MANAGED_LEGACY: "Self-managed (legacy)",
|
||||
RemoteZulipServer.PLAN_TYPE_COMMUNITY: "Community",
|
||||
RemoteZulipServer.PLAN_TYPE_BUSINESS: "Business",
|
||||
RemoteZulipServer.PLAN_TYPE_ENTERPRISE: "Enterprise",
|
||||
|
|
|
@ -3177,10 +3177,6 @@ class RemoteRealmBillingSession(BillingSession):
|
|||
plan_type = RemoteRealm.PLAN_TYPE_COMMUNITY
|
||||
elif tier == CustomerPlan.TIER_SELF_HOSTED_BUSINESS:
|
||||
plan_type = RemoteRealm.PLAN_TYPE_BUSINESS
|
||||
elif (
|
||||
tier == CustomerPlan.TIER_SELF_HOSTED_PLUS
|
||||
): # nocoverage # Plus plan doesn't use this code path yet.
|
||||
plan_type = RemoteRealm.PLAN_TYPE_ENTERPRISE
|
||||
else:
|
||||
raise AssertionError("Unexpected tier")
|
||||
|
||||
|
@ -3259,7 +3255,7 @@ class RemoteRealmBillingSession(BillingSession):
|
|||
def process_downgrade(self, plan: CustomerPlan) -> None: # nocoverage
|
||||
with transaction.atomic():
|
||||
old_plan_type = self.remote_realm.plan_type
|
||||
new_plan_type = RemoteRealm.PLAN_TYPE_SELF_HOSTED
|
||||
new_plan_type = RemoteRealm.PLAN_TYPE_SELF_MANAGED
|
||||
self.remote_realm.plan_type = new_plan_type
|
||||
self.remote_realm.save(update_fields=["plan_type"])
|
||||
self.write_to_audit_log(
|
||||
|
@ -3565,18 +3561,12 @@ class RemoteServerBillingSession(BillingSession):
|
|||
def do_change_plan_type(
|
||||
self, *, tier: Optional[int], is_sponsored: bool = False
|
||||
) -> None: # nocoverage
|
||||
# TODO: Create actual plan types.
|
||||
|
||||
# This function needs to translate between the different
|
||||
# formats of CustomerPlan.tier and RealmZulipServer.plan_type.
|
||||
if is_sponsored:
|
||||
plan_type = RemoteZulipServer.PLAN_TYPE_COMMUNITY
|
||||
elif tier == CustomerPlan.TIER_SELF_HOSTED_BUSINESS:
|
||||
plan_type = RemoteZulipServer.PLAN_TYPE_BUSINESS
|
||||
elif (
|
||||
tier == CustomerPlan.TIER_SELF_HOSTED_PLUS
|
||||
): # nocoverage # Plus plan doesn't use this code path yet.
|
||||
plan_type = RemoteZulipServer.PLAN_TYPE_ENTERPRISE
|
||||
else:
|
||||
raise AssertionError("Unexpected tier")
|
||||
|
||||
|
@ -3628,7 +3618,7 @@ class RemoteServerBillingSession(BillingSession):
|
|||
def process_downgrade(self, plan: CustomerPlan) -> None: # nocoverage
|
||||
with transaction.atomic():
|
||||
old_plan_type = self.remote_server.plan_type
|
||||
new_plan_type = RemoteZulipServer.PLAN_TYPE_SELF_HOSTED
|
||||
new_plan_type = RemoteZulipServer.PLAN_TYPE_SELF_MANAGED
|
||||
self.remote_server.plan_type = new_plan_type
|
||||
self.remote_server.save(update_fields=["plan_type"])
|
||||
self.write_to_audit_log(
|
||||
|
|
|
@ -4578,7 +4578,7 @@ class BillingHelpersTest(ZulipTestCase):
|
|||
hostname="demo.example.com",
|
||||
contact_email="email@example.com",
|
||||
)
|
||||
self.assertEqual(remote_server.plan_type, RemoteZulipServer.PLAN_TYPE_SELF_HOSTED)
|
||||
self.assertEqual(remote_server.plan_type, RemoteZulipServer.PLAN_TYPE_SELF_MANAGED)
|
||||
|
||||
do_change_remote_server_plan_type(remote_server, RemoteZulipServer.PLAN_TYPE_BUSINESS)
|
||||
|
||||
|
@ -4588,7 +4588,7 @@ class BillingHelpersTest(ZulipTestCase):
|
|||
).last()
|
||||
assert remote_realm_audit_log is not None
|
||||
expected_extra_data = {
|
||||
"old_value": RemoteZulipServer.PLAN_TYPE_SELF_HOSTED,
|
||||
"old_value": RemoteZulipServer.PLAN_TYPE_SELF_MANAGED,
|
||||
"new_value": RemoteZulipServer.PLAN_TYPE_BUSINESS,
|
||||
}
|
||||
self.assertEqual(remote_realm_audit_log.extra_data, expected_extra_data)
|
||||
|
|
|
@ -127,7 +127,11 @@ def remote_realm_billing_page(
|
|||
or get_current_plan_by_customer(customer) is None
|
||||
or (
|
||||
billing_session.get_legacy_remote_server_next_plan_name(customer) is None
|
||||
and billing_session.remote_realm.plan_type == RemoteRealm.PLAN_TYPE_SELF_HOSTED
|
||||
and billing_session.remote_realm.plan_type
|
||||
in [
|
||||
RemoteRealm.PLAN_TYPE_SELF_MANAGED,
|
||||
RemoteRealm.PLAN_TYPE_SELF_MANAGED_LEGACY,
|
||||
]
|
||||
)
|
||||
):
|
||||
return HttpResponseRedirect(reverse("remote_realm_plans_page", args=(realm_uuid,)))
|
||||
|
@ -186,7 +190,11 @@ def remote_server_billing_page(
|
|||
or get_current_plan_by_customer(customer) is None
|
||||
or (
|
||||
billing_session.get_legacy_remote_server_next_plan_name(customer) is None
|
||||
and billing_session.remote_server.plan_type == RemoteZulipServer.PLAN_TYPE_SELF_HOSTED
|
||||
and billing_session.remote_server.plan_type
|
||||
in [
|
||||
RemoteZulipServer.PLAN_TYPE_SELF_MANAGED,
|
||||
RemoteZulipServer.PLAN_TYPE_SELF_MANAGED_LEGACY,
|
||||
]
|
||||
)
|
||||
):
|
||||
return HttpResponseRedirect(
|
||||
|
|
|
@ -268,7 +268,10 @@ def remote_realm_billing_finalize_login(
|
|||
return HttpResponseRedirect(
|
||||
reverse(f"remote_realm_{next_page}_page", args=(remote_realm_uuid,))
|
||||
)
|
||||
elif remote_realm.plan_type == RemoteRealm.PLAN_TYPE_SELF_HOSTED:
|
||||
elif remote_realm.plan_type in [
|
||||
RemoteRealm.PLAN_TYPE_SELF_MANAGED,
|
||||
RemoteRealm.PLAN_TYPE_SELF_MANAGED_LEGACY,
|
||||
]:
|
||||
# If they have a scheduled upgrade, redirect to billing page.
|
||||
billing_session = RemoteRealmBillingSession(remote_realm)
|
||||
customer = billing_session.get_customer()
|
||||
|
@ -657,7 +660,10 @@ def remote_billing_legacy_server_from_login_confirmation_link(
|
|||
return HttpResponseRedirect(
|
||||
reverse(f"remote_server_{next_page}_page", args=(remote_server_uuid,))
|
||||
)
|
||||
elif remote_server.plan_type == RemoteZulipServer.PLAN_TYPE_SELF_HOSTED:
|
||||
elif remote_server.plan_type in [
|
||||
RemoteZulipServer.PLAN_TYPE_SELF_MANAGED,
|
||||
RemoteZulipServer.PLAN_TYPE_SELF_MANAGED_LEGACY,
|
||||
]:
|
||||
# If they have a scheduled upgrade, redirect to billing page.
|
||||
billing_session = RemoteServerBillingSession(remote_server)
|
||||
customer = billing_session.get_customer()
|
||||
|
|
|
@ -1171,7 +1171,7 @@ class AnalyticsBouncerTest(BouncerTestCase):
|
|||
"realm_date_created": realm.date_created,
|
||||
"registration_deactivated": False,
|
||||
"realm_deactivated": False,
|
||||
"plan_type": RemoteRealm.PLAN_TYPE_SELF_HOSTED,
|
||||
"plan_type": RemoteRealm.PLAN_TYPE_SELF_MANAGED,
|
||||
"is_system_bot_realm": realm.string_id == "zulipinternal",
|
||||
}
|
||||
for realm in Realm.objects.order_by("id")
|
||||
|
@ -1613,7 +1613,7 @@ class AnalyticsBouncerTest(BouncerTestCase):
|
|||
realm_date_created=realm.date_created,
|
||||
registration_deactivated=False,
|
||||
realm_deactivated=False,
|
||||
plan_type=RemoteRealm.PLAN_TYPE_SELF_HOSTED,
|
||||
plan_type=RemoteRealm.PLAN_TYPE_SELF_MANAGED,
|
||||
)
|
||||
|
||||
with transaction.atomic(), self.assertLogs("zulip.analytics", level="WARNING") as m:
|
||||
|
@ -1903,7 +1903,7 @@ class AnalyticsBouncerTest(BouncerTestCase):
|
|||
"realm_date_created": realm.date_created,
|
||||
"registration_deactivated": False,
|
||||
"realm_deactivated": False,
|
||||
"plan_type": RemoteRealm.PLAN_TYPE_SELF_HOSTED,
|
||||
"plan_type": RemoteRealm.PLAN_TYPE_SELF_MANAGED,
|
||||
}
|
||||
for realm in Realm.objects.order_by("id")
|
||||
],
|
||||
|
|
|
@ -394,11 +394,11 @@ def populate_remote_server(customer_profile: CustomerProfile) -> Dict[str, str]:
|
|||
):
|
||||
plan_type = RemoteZulipServer.PLAN_TYPE_COMMUNITY
|
||||
elif customer_profile.tier == CustomerPlan.TIER_SELF_HOSTED_LEGACY:
|
||||
plan_type = RemoteZulipServer.PLAN_TYPE_SELF_HOSTED
|
||||
plan_type = RemoteZulipServer.PLAN_TYPE_SELF_MANAGED_LEGACY
|
||||
elif customer_profile.tier == CustomerPlan.TIER_SELF_HOSTED_BUSINESS:
|
||||
plan_type = RemoteZulipServer.PLAN_TYPE_BUSINESS
|
||||
elif customer_profile.tier is CustomerPlan.TIER_SELF_HOSTED_BASE:
|
||||
plan_type = RemoteZulipServer.PLAN_TYPE_SELF_HOSTED
|
||||
plan_type = RemoteZulipServer.PLAN_TYPE_SELF_MANAGED
|
||||
else:
|
||||
raise AssertionError("Unexpected tier!")
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# Generated by Django 4.2.8 on 2023-12-13 23:20
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
||||
from django.db.migrations.state import StateApps
|
||||
|
||||
PLAN_TYPE_SELF_HOSTED = 1
|
||||
PLAN_TYPE_SELF_MANAGED = 100
|
||||
|
||||
|
||||
def renumber_plan_types(apps: StateApps, schema_editor: BaseDatabaseSchemaEditor) -> None:
|
||||
RemoteZulipServer = apps.get_model("zilencer", "RemoteZulipServer")
|
||||
RemoteRealm = apps.get_model("zilencer", "RemoteRealm")
|
||||
RemoteRealm.objects.filter(plan_type=PLAN_TYPE_SELF_HOSTED).update(
|
||||
plan_type=PLAN_TYPE_SELF_MANAGED
|
||||
)
|
||||
RemoteZulipServer.objects.filter(plan_type=PLAN_TYPE_SELF_HOSTED).update(
|
||||
plan_type=PLAN_TYPE_SELF_MANAGED
|
||||
)
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("zilencer", "0051_remoterealm_is_system_bot_realm"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="remoterealm",
|
||||
name="plan_type",
|
||||
field=models.PositiveSmallIntegerField(db_index=True, default=PLAN_TYPE_SELF_MANAGED),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="remotezulipserver",
|
||||
name="plan_type",
|
||||
field=models.PositiveSmallIntegerField(default=PLAN_TYPE_SELF_MANAGED),
|
||||
),
|
||||
migrations.RunPython(renumber_plan_types, reverse_code=migrations.RunPython.noop),
|
||||
]
|
|
@ -54,13 +54,22 @@ class RemoteZulipServer(models.Model):
|
|||
deactivated = models.BooleanField(default=False)
|
||||
|
||||
# Plan types for self-hosted customers
|
||||
#
|
||||
# We reserve PLAN_TYPE_SELF_HOSTED=Realm.PLAN_TYPE_SELF_HOSTED for
|
||||
# self-hosted installations that aren't using the notifications
|
||||
# service.
|
||||
#
|
||||
# The other values align with, e.g., CustomerPlan.TIER_SELF_HOSTED_BASE
|
||||
PLAN_TYPE_SELF_HOSTED = 1
|
||||
PLAN_TYPE_COMMUNITY = 100
|
||||
PLAN_TYPE_BUSINESS = 101
|
||||
PLAN_TYPE_ENTERPRISE = 102
|
||||
PLAN_TYPE_SELF_MANAGED = 100
|
||||
PLAN_TYPE_SELF_MANAGED_LEGACY = 101
|
||||
PLAN_TYPE_COMMUNITY = 102
|
||||
PLAN_TYPE_BUSINESS = 103
|
||||
PLAN_TYPE_PLUS = 104
|
||||
PLAN_TYPE_ENTERPRISE = 105
|
||||
|
||||
# The current billing plan for the remote server, similar to Realm.plan_type.
|
||||
plan_type = models.PositiveSmallIntegerField(default=PLAN_TYPE_SELF_HOSTED)
|
||||
plan_type = models.PositiveSmallIntegerField(default=PLAN_TYPE_SELF_MANAGED)
|
||||
|
||||
# This is not synced with the remote server, but only filled for sponsorship requests.
|
||||
org_type = models.PositiveSmallIntegerField(
|
||||
|
@ -143,13 +152,20 @@ class RemoteRealm(models.Model):
|
|||
realm_date_created = models.DateTimeField()
|
||||
|
||||
# Plan types for self-hosted customers
|
||||
#
|
||||
# We reserve PLAN_TYPE_SELF_HOSTED=Realm.PLAN_TYPE_SELF_HOSTED for
|
||||
# self-hosted installations that aren't using the notifications
|
||||
# service.
|
||||
#
|
||||
# The other values align with, e.g., CustomerPlan.TIER_SELF_HOSTED_BASE
|
||||
PLAN_TYPE_SELF_HOSTED = 1
|
||||
PLAN_TYPE_COMMUNITY = 100
|
||||
PLAN_TYPE_BUSINESS = 101
|
||||
PLAN_TYPE_ENTERPRISE = 102
|
||||
|
||||
# The current billing plan for the remote server, similar to Realm.plan_type.
|
||||
plan_type = models.PositiveSmallIntegerField(default=PLAN_TYPE_SELF_HOSTED, db_index=True)
|
||||
PLAN_TYPE_SELF_MANAGED = 100
|
||||
PLAN_TYPE_SELF_MANAGED_LEGACY = 101
|
||||
PLAN_TYPE_COMMUNITY = 102
|
||||
PLAN_TYPE_BUSINESS = 103
|
||||
PLAN_TYPE_PLUS = 104
|
||||
PLAN_TYPE_ENTERPRISE = 105
|
||||
plan_type = models.PositiveSmallIntegerField(default=PLAN_TYPE_SELF_MANAGED, db_index=True)
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
|
|
|
@ -768,10 +768,10 @@ def handle_customer_migration_from_server_to_realms(
|
|||
and server_plan.tier == CustomerPlan.TIER_SELF_HOSTED_LEGACY
|
||||
and server_plan.status == CustomerPlan.ACTIVE
|
||||
):
|
||||
assert server.plan_type == RemoteZulipServer.PLAN_TYPE_SELF_HOSTED
|
||||
assert server.plan_type == RemoteZulipServer.PLAN_TYPE_SELF_MANAGED
|
||||
assert server_plan.end_date is not None
|
||||
remote_realms = RemoteRealm.objects.filter(
|
||||
uuid__in=realm_uuids, server=server, plan_type=RemoteRealm.PLAN_TYPE_SELF_HOSTED
|
||||
uuid__in=realm_uuids, server=server, plan_type=RemoteRealm.PLAN_TYPE_SELF_MANAGED
|
||||
)
|
||||
|
||||
# Verify that all the realms are on self hosted plan.
|
||||
|
@ -799,7 +799,7 @@ def handle_customer_migration_from_server_to_realms(
|
|||
# We only do this migration if there is only one realm besides the system bot realm.
|
||||
elif len(realm_uuids) == 1:
|
||||
remote_realm = RemoteRealm.objects.get(
|
||||
uuid=realm_uuids[0], plan_type=RemoteRealm.PLAN_TYPE_SELF_HOSTED
|
||||
uuid=realm_uuids[0], plan_type=RemoteRealm.PLAN_TYPE_SELF_MANAGED
|
||||
)
|
||||
# Migrate customer from server to remote realm if there is only one realm.
|
||||
server_customer.remote_realm = remote_realm
|
||||
|
@ -809,7 +809,7 @@ def handle_customer_migration_from_server_to_realms(
|
|||
# Might be better to call do_change_plan_type here.
|
||||
remote_realm.plan_type = server.plan_type
|
||||
remote_realm.save(update_fields=["plan_type"])
|
||||
server.plan_type = RemoteZulipServer.PLAN_TYPE_SELF_HOSTED
|
||||
server.plan_type = RemoteZulipServer.PLAN_TYPE_SELF_MANAGED
|
||||
server.save(update_fields=["plan_type"])
|
||||
remote_realm_audit_logs.append(
|
||||
RemoteRealmAuditLog(
|
||||
|
@ -819,7 +819,7 @@ def handle_customer_migration_from_server_to_realms(
|
|||
event_time=event_time,
|
||||
extra_data={
|
||||
"attr_name": "plan_type",
|
||||
"old_value": RemoteRealm.PLAN_TYPE_SELF_HOSTED,
|
||||
"old_value": RemoteRealm.PLAN_TYPE_SELF_MANAGED,
|
||||
"new_value": remote_realm.plan_type,
|
||||
},
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue