mirror of https://github.com/zulip/zulip.git
models: Add plan_type to Realm.
This commit is contained in:
parent
6031ccff5c
commit
9bb338be11
|
@ -3018,6 +3018,15 @@ def do_change_icon_source(realm: Realm, icon_source: str, log: bool=True) -> Non
|
|||
icon_url=realm_icon_url(realm))),
|
||||
active_user_ids(realm.id))
|
||||
|
||||
def do_change_plan_type(user: UserProfile, plan_type: int) -> None:
|
||||
realm = user.realm
|
||||
old_value = realm.plan_type
|
||||
realm.plan_type = plan_type
|
||||
realm.save(update_fields=['plan_type'])
|
||||
RealmAuditLog.objects.create(event_type=RealmAuditLog.REALM_PLAN_TYPE_CHANGED,
|
||||
realm=realm, acting_user=user, event_time=timezone_now(),
|
||||
extra_data={'old_value': old_value, 'new_value': plan_type})
|
||||
|
||||
def do_change_default_sending_stream(user_profile: UserProfile, stream: Optional[Stream],
|
||||
log: bool=True) -> None:
|
||||
user_profile.default_sending_stream = stream
|
||||
|
@ -3194,6 +3203,8 @@ def do_create_realm(string_id: str, name: str,
|
|||
kwargs = {} # type: Dict[str, Any]
|
||||
if emails_restricted_to_domains is not None:
|
||||
kwargs['emails_restricted_to_domains'] = emails_restricted_to_domains
|
||||
if settings.BILLING_ENABLED:
|
||||
kwargs['plan_type'] = Realm.LIMITED
|
||||
realm = Realm(string_id=string_id, name=name, **kwargs)
|
||||
realm.save()
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.14 on 2018-08-10 21:36
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import zerver.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('zerver', '0184_rename_custom_field_types'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='realm',
|
||||
name='plan_type',
|
||||
# Realm.SELF_HOSTED
|
||||
field=models.PositiveSmallIntegerField(default=1),
|
||||
),
|
||||
]
|
|
@ -223,6 +223,15 @@ class Realm(models.Model):
|
|||
COMMUNITY = 2
|
||||
org_type = models.PositiveSmallIntegerField(default=CORPORATE) # type: int
|
||||
|
||||
# plan_type controls various features around resource/feature
|
||||
# limitations for a Zulip organization on multi-tenant servers
|
||||
# like zulipchat.com.
|
||||
SELF_HOSTED = 1
|
||||
LIMITED = 2
|
||||
PREMIUM = 3
|
||||
PREMIUM_FREE = 4
|
||||
plan_type = models.PositiveSmallIntegerField(default=SELF_HOSTED) # type: int
|
||||
|
||||
# This value is also being used in static/js/settings_bots.bot_creation_policy_values.
|
||||
# On updating it here, update it there as well.
|
||||
BOT_CREATION_EVERYONE = 1
|
||||
|
@ -2189,6 +2198,7 @@ class RealmAuditLog(models.Model):
|
|||
|
||||
REALM_DEACTIVATED = 'realm_deactivated'
|
||||
REALM_REACTIVATED = 'realm_reactivated'
|
||||
REALM_PLAN_TYPE_CHANGED = 'realm_plan_type_changed'
|
||||
|
||||
SUBSCRIPTION_CREATED = 'subscription_created'
|
||||
SUBSCRIPTION_ACTIVATED = 'subscription_activated'
|
||||
|
|
|
@ -11,6 +11,7 @@ from zerver.lib.actions import (
|
|||
do_set_realm_property,
|
||||
do_deactivate_realm,
|
||||
do_deactivate_stream,
|
||||
do_create_realm,
|
||||
)
|
||||
|
||||
from zerver.lib.send_email import send_future_email
|
||||
|
@ -334,6 +335,12 @@ class RealmTest(ZulipTestCase):
|
|||
self.assert_json_success(result)
|
||||
self.assertEqual(get_realm('zulip').video_chat_provider, "Jitsi")
|
||||
|
||||
def test_initial_plan_type(self) -> None:
|
||||
with self.settings(BILLING_ENABLED=True):
|
||||
self.assertEqual(Realm.LIMITED, do_create_realm('hosted', 'hosted').plan_type)
|
||||
with self.settings(BILLING_ENABLED=False):
|
||||
self.assertEqual(Realm.SELF_HOSTED, do_create_realm('onpremise', 'onpremise').plan_type)
|
||||
|
||||
class RealmAPITest(ZulipTestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
|
|
|
@ -16,6 +16,7 @@ from zerver.lib.exceptions import JsonableError
|
|||
from zerver.lib.logging_util import log_to_file
|
||||
from zerver.lib.timestamp import datetime_to_timestamp, timestamp_to_datetime
|
||||
from zerver.lib.utils import generate_random_token
|
||||
from zerver.lib.actions import do_change_plan_type
|
||||
from zerver.models import Realm, UserProfile, RealmAuditLog
|
||||
from zilencer.models import Customer, Plan, BillingProcessor
|
||||
from zproject.settings import get_secret
|
||||
|
@ -228,6 +229,7 @@ def process_initial_upgrade(user: UserProfile, plan: Plan, seat_count: int, stri
|
|||
# TODO: billing address details are passed to us in the request;
|
||||
# use that to calculate taxes.
|
||||
tax_percent=0)
|
||||
do_change_plan_type(user, Realm.PREMIUM)
|
||||
|
||||
## Process RealmAuditLog
|
||||
|
||||
|
|
|
@ -50,6 +50,12 @@ def mock_customer_with_cancel_at_period_end_subscription(*args: Any, **kwargs: A
|
|||
def mock_upcoming_invoice(*args: Any, **kwargs: Any) -> stripe.Invoice:
|
||||
return stripe.util.convert_to_stripe_object(fixture_data["upcoming_invoice"])
|
||||
|
||||
# A Kandra is a fictional character that can become anything. Used as a
|
||||
# wildcard when testing for equality.
|
||||
class Kandra(object):
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
return True
|
||||
|
||||
class StripeTest(ZulipTestCase):
|
||||
def setUp(self) -> None:
|
||||
self.token = 'token'
|
||||
|
@ -103,6 +109,7 @@ class StripeTest(ZulipTestCase):
|
|||
response = self.client_get("/upgrade/")
|
||||
self.assert_in_success_response(['We can also bill by invoice'], response)
|
||||
self.assertFalse(user.realm.has_seat_based_plan)
|
||||
self.assertNotEqual(user.realm.plan_type, Realm.PREMIUM)
|
||||
|
||||
# Click "Make payment" in Stripe Checkout
|
||||
self.client_post("/upgrade/", {
|
||||
|
@ -135,10 +142,12 @@ class StripeTest(ZulipTestCase):
|
|||
(RealmAuditLog.STRIPE_CUSTOMER_CREATED, timestamp_to_datetime(self.customer_created)),
|
||||
(RealmAuditLog.STRIPE_CARD_ADDED, timestamp_to_datetime(self.customer_created)),
|
||||
(RealmAuditLog.STRIPE_PLAN_CHANGED, timestamp_to_datetime(self.subscription_created)),
|
||||
(RealmAuditLog.REALM_PLAN_TYPE_CHANGED, Kandra()),
|
||||
])
|
||||
# Check that we correctly updated Realm
|
||||
realm = get_realm("zulip")
|
||||
self.assertTrue(realm.has_seat_based_plan)
|
||||
self.assertEqual(realm.plan_type, Realm.PREMIUM)
|
||||
# Check that we can no longer access /upgrade
|
||||
response = self.client_get("/upgrade/")
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
@ -202,12 +211,13 @@ class StripeTest(ZulipTestCase):
|
|||
# correctly handled the requires_billing_update field
|
||||
audit_log_entries = list(RealmAuditLog.objects.order_by('-id')
|
||||
.values_list('event_type', 'event_time',
|
||||
'requires_billing_update')[:4])[::-1]
|
||||
'requires_billing_update')[:5])[::-1]
|
||||
self.assertEqual(audit_log_entries, [
|
||||
(RealmAuditLog.STRIPE_CUSTOMER_CREATED, timestamp_to_datetime(self.customer_created), False),
|
||||
(RealmAuditLog.STRIPE_CARD_ADDED, timestamp_to_datetime(self.customer_created), False),
|
||||
(RealmAuditLog.STRIPE_PLAN_CHANGED, timestamp_to_datetime(self.subscription_created), False),
|
||||
(RealmAuditLog.STRIPE_PLAN_QUANTITY_RESET, timestamp_to_datetime(self.subscription_created), True),
|
||||
(RealmAuditLog.REALM_PLAN_TYPE_CHANGED, Kandra(), False),
|
||||
])
|
||||
self.assertEqual(ujson.loads(RealmAuditLog.objects.filter(
|
||||
event_type=RealmAuditLog.STRIPE_PLAN_QUANTITY_RESET).values_list('extra_data', flat=True).first()),
|
||||
|
@ -261,7 +271,8 @@ class StripeTest(ZulipTestCase):
|
|||
self.assertEqual(audit_log_entries, [RealmAuditLog.STRIPE_CUSTOMER_CREATED,
|
||||
RealmAuditLog.STRIPE_CARD_ADDED,
|
||||
RealmAuditLog.STRIPE_CARD_ADDED,
|
||||
RealmAuditLog.STRIPE_PLAN_CHANGED])
|
||||
RealmAuditLog.STRIPE_PLAN_CHANGED,
|
||||
RealmAuditLog.REALM_PLAN_TYPE_CHANGED])
|
||||
# Check that we correctly updated Realm
|
||||
realm = get_realm("zulip")
|
||||
self.assertTrue(realm.has_seat_based_plan)
|
||||
|
|
|
@ -123,3 +123,5 @@ if FAKE_LDAP_MODE:
|
|||
THUMBOR_URL = 'http://127.0.0.1:9995'
|
||||
|
||||
SEARCH_PILLS_ENABLED = os.getenv('SEARCH_PILLS_ENABLED', False)
|
||||
|
||||
BILLING_ENABLED = True
|
||||
|
|
|
@ -437,6 +437,10 @@ DEFAULT_SETTINGS.update({
|
|||
# DEFAULT_SETTINGS, since it likely isn't usefully user-configurable.
|
||||
'OFFLINE_THRESHOLD_SECS': 5 * 60,
|
||||
|
||||
# Enables billing pages and plan-based feature gates. If False, all features
|
||||
# are available to all realms.
|
||||
'BILLING_ENABLED': False,
|
||||
|
||||
# Controls whether we run the worker that syncs billing-related updates
|
||||
# into Stripe. Should be True on at most one machine.
|
||||
'BILLING_PROCESSOR_ENABLED': False,
|
||||
|
|
Loading…
Reference in New Issue