mirror of https://github.com/zulip/zulip.git
billing: Rename Zulip Premium to Zulip Standard.
This commit is contained in:
parent
53f1714613
commit
458169928c
|
@ -471,7 +471,7 @@ def realm_summary_table(realm_minutes: Dict[str, float]) -> str:
|
|||
for row in rows:
|
||||
row['date_created_day'] = row['date_created'].strftime('%Y-%m-%d')
|
||||
row['plan_type_string'] = [
|
||||
'', 'self hosted', 'limited', 'premium', 'premium free'][row['plan_type']]
|
||||
'', 'self hosted', 'limited', 'standard', 'standard free'][row['plan_type']]
|
||||
row['age_days'] = int((now - row['date_created']).total_seconds()
|
||||
/ 86400)
|
||||
row['is_new'] = row['age_days'] < 12 * 7
|
||||
|
|
|
@ -277,7 +277,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)
|
||||
do_change_plan_type(user, Realm.STANDARD)
|
||||
|
||||
def attach_discount_to_realm(user: UserProfile, percent_off: int) -> None:
|
||||
coupon = Coupon.objects.get(percent_off=percent_off)
|
||||
|
|
|
@ -17,9 +17,9 @@ class Command(ZulipBaseCommand):
|
|||
|
||||
# Zulip Cloud offerings
|
||||
product = stripe.Product.create(
|
||||
name="Zulip Cloud Premium",
|
||||
name="Zulip Cloud Standard",
|
||||
type='service',
|
||||
statement_descriptor="Zulip Cloud Premium",
|
||||
statement_descriptor="Zulip Cloud Standard",
|
||||
unit_label="user")
|
||||
|
||||
plan = stripe.Plan.create(
|
||||
|
|
|
@ -347,7 +347,7 @@
|
|||
{
|
||||
"amount": 64000,
|
||||
"currency": "usd",
|
||||
"description": "8 user \u00d7 Zulip Cloud Premium (at $80.00 / year)",
|
||||
"description": "8 user \u00d7 Zulip Cloud Standard (at $80.00 / year)",
|
||||
"discountable": true,
|
||||
"id": "sub_D7OTT8FZbOPxah",
|
||||
"livemode": false,
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -203,7 +203,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)
|
||||
self.assertNotEqual(user.realm.plan_type, Realm.STANDARD)
|
||||
self.assertFalse(Customer.objects.filter(realm=user.realm).exists())
|
||||
|
||||
# Click "Make payment" in Stripe Checkout
|
||||
|
@ -246,8 +246,8 @@ class StripeTest(ZulipTestCase):
|
|||
# Check that we correctly updated Realm
|
||||
realm = get_realm("zulip")
|
||||
self.assertTrue(realm.has_seat_based_plan)
|
||||
self.assertEqual(realm.plan_type, Realm.PREMIUM)
|
||||
self.assertEqual(realm.max_invites, Realm.INVITES_PREMIUM_REALM_DAILY_MAX)
|
||||
self.assertEqual(realm.plan_type, Realm.STANDARD)
|
||||
self.assertEqual(realm.max_invites, Realm.INVITES_STANDARD_REALM_DAILY_MAX)
|
||||
# Check that we can no longer access /upgrade
|
||||
response = self.client_get("/upgrade/")
|
||||
self.assertEqual(response.status_code, 302)
|
||||
|
@ -393,7 +393,7 @@ class StripeTest(ZulipTestCase):
|
|||
'salt': self.salt,
|
||||
'plan': Plan.CLOUD_ANNUAL
|
||||
})
|
||||
self.assert_in_success_response(["Upgrade to Zulip Premium"], response)
|
||||
self.assert_in_success_response(["Upgrade to Zulip Standard"], response)
|
||||
self.assertEqual(response['error_description'], 'tampered seat count')
|
||||
|
||||
def test_upgrade_with_tampered_plan(self) -> None:
|
||||
|
@ -404,7 +404,7 @@ class StripeTest(ZulipTestCase):
|
|||
'salt': self.salt,
|
||||
'plan': "invalid"
|
||||
})
|
||||
self.assert_in_success_response(["Upgrade to Zulip Premium"], response)
|
||||
self.assert_in_success_response(["Upgrade to Zulip Standard"], response)
|
||||
self.assertEqual(response['error_description'], 'tampered plan')
|
||||
|
||||
@patch("stripe.Customer.retrieve", side_effect=mock_customer_with_subscription)
|
||||
|
@ -491,7 +491,7 @@ class StripeTest(ZulipTestCase):
|
|||
mock_save_customer: Mock, mock_delete_subscription: Mock) -> None:
|
||||
realm = get_realm('zulip')
|
||||
realm.has_seat_based_plan = True
|
||||
realm.plan_type = Realm.PREMIUM
|
||||
realm.plan_type = Realm.STANDARD
|
||||
realm.save(update_fields=['has_seat_based_plan', 'plan_type'])
|
||||
Customer.objects.create(
|
||||
realm=realm, stripe_customer_id=self.stripe_customer_id, has_billing_relationship=True)
|
||||
|
|
|
@ -74,7 +74,7 @@ def initial_upgrade(request: HttpRequest) -> HttpResponse:
|
|||
'seat_count': seat_count,
|
||||
'signed_seat_count': signed_seat_count,
|
||||
'salt': salt,
|
||||
'plan': "Zulip Premium",
|
||||
'plan': "Zulip Standard",
|
||||
'nickname_monthly': Plan.CLOUD_MONTHLY,
|
||||
'nickname_annual': Plan.CLOUD_ANNUAL,
|
||||
'error_message': error_message,
|
||||
|
@ -87,8 +87,8 @@ def initial_upgrade(request: HttpRequest) -> HttpResponse:
|
|||
return response
|
||||
|
||||
PLAN_NAMES = {
|
||||
Plan.CLOUD_ANNUAL: "Zulip Premium (billed annually)",
|
||||
Plan.CLOUD_MONTHLY: "Zulip Premium (billed monthly)",
|
||||
Plan.CLOUD_ANNUAL: "Zulip Standard (billed annually)",
|
||||
Plan.CLOUD_MONTHLY: "Zulip Standard (billed monthly)",
|
||||
}
|
||||
|
||||
@zulip_login_required
|
||||
|
|
|
@ -2913,7 +2913,7 @@ nav ul li.active::after {
|
|||
animation: box-shadow-pulse 2s infinite;
|
||||
}
|
||||
|
||||
.pricing-model .pricing-container .text-content .premium-price-box {
|
||||
.pricing-model .pricing-container .text-content .standard-price-box {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
data-key="{{ publishable_key }}"
|
||||
data-image="/static/images/logo/zulip-icon-128x128.png"
|
||||
data-name="Zulip"
|
||||
data-description="Zulip Cloud Premium"
|
||||
data-description="Zulip Cloud Standard"
|
||||
data-locale="auto"
|
||||
data-zip-code="true"
|
||||
data-billing-address="true"
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
entities?
|
||||
</div>
|
||||
<p class="answer">
|
||||
Yes! Zulip Cloud Premium is free for open source
|
||||
Yes! Zulip Cloud Standard is free for open source
|
||||
projects and affiliated institutions. We also offer
|
||||
steep discounts to non-profits, educational
|
||||
institutions, groups of friends, and in scenarios where
|
||||
|
|
|
@ -19,7 +19,7 @@ three types of zulipchat.com exports.
|
|||
* **Full export without member consent**: All the data in the organization.
|
||||
|
||||
All organizations have access to the first two kinds of export. Only corporate
|
||||
Zulip Premium customers have access to **full export without member consent**.
|
||||
Zulip Standard customers have access to **full export without member consent**.
|
||||
|
||||
## Request an export
|
||||
|
||||
|
@ -64,7 +64,7 @@ in place. Note that many countries have laws that require employers to
|
|||
notify employees of their use of such an export.
|
||||
|
||||
**Full export without member consent** is additionally limited to paid
|
||||
Zulip Premium customers, though in rare cases may be available to
|
||||
Zulip Standard customers, though in rare cases may be available to
|
||||
other organizations in case of due legal process.
|
||||
|
||||
## Related articles
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
<div class="price-box" tabindex="-1">
|
||||
<div class="text-content">
|
||||
<h2>Premium</h2>
|
||||
<h2>Standard</h2>
|
||||
<div class="description">
|
||||
Make Zulip your home
|
||||
</div>
|
||||
|
@ -75,7 +75,7 @@
|
|||
</div>
|
||||
<div class="bottom">
|
||||
<div class="text-content">
|
||||
<div class="premium-price-box">
|
||||
<div class="standard-price-box">
|
||||
<div class="price">6<span class="price-cents">.67</span></div>
|
||||
<div class="details">
|
||||
per active user per month
|
||||
|
@ -90,13 +90,13 @@
|
|||
{% elif realm_plan_type == 2 %}
|
||||
<a href="/upgrade">
|
||||
<button class="green" type="button">
|
||||
Buy Premium
|
||||
Buy Standard
|
||||
</button>
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="/new">
|
||||
<button class="green" type="button">
|
||||
Buy Premium
|
||||
Buy Standard
|
||||
</button>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
@ -121,7 +121,7 @@
|
|||
<li>Easy self-service installation</li>
|
||||
<li>Free and open source forever under Apache 2.0 license</li>
|
||||
<li>LDAP/Active directory integration</li>
|
||||
<li>All Premium/Enterprise features included</li>
|
||||
<li>All Standard/Enterprise features included</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
|
|
|
@ -3069,10 +3069,10 @@ def do_change_plan_type(user: UserProfile, plan_type: int) -> None:
|
|||
realm=realm, acting_user=user, event_time=timezone_now(),
|
||||
extra_data={'old_value': old_value, 'new_value': plan_type})
|
||||
|
||||
if plan_type == Realm.PREMIUM:
|
||||
realm.max_invites = Realm.INVITES_PREMIUM_REALM_DAILY_MAX
|
||||
elif plan_type == Realm.PREMIUM_FREE:
|
||||
realm.max_invites = Realm.INVITES_PREMIUM_REALM_DAILY_MAX
|
||||
if plan_type == Realm.STANDARD:
|
||||
realm.max_invites = Realm.INVITES_STANDARD_REALM_DAILY_MAX
|
||||
elif plan_type == Realm.STANDARD_FREE:
|
||||
realm.max_invites = Realm.INVITES_STANDARD_REALM_DAILY_MAX
|
||||
elif plan_type == Realm.LIMITED:
|
||||
realm.max_invites = settings.INVITES_DEFAULT_REALM_DAILY_MAX
|
||||
realm.save(update_fields=['_max_invites'])
|
||||
|
|
|
@ -143,7 +143,7 @@ class Realm(models.Model):
|
|||
MAX_REALM_SUBDOMAIN_LENGTH = 40
|
||||
MAX_VIDEO_CHAT_PROVIDER_LENGTH = 40
|
||||
MAX_GOOGLE_HANGOUTS_DOMAIN_LENGTH = 255 # This is just the maximum domain length by RFC
|
||||
INVITES_PREMIUM_REALM_DAILY_MAX = 3000
|
||||
INVITES_STANDARD_REALM_DAILY_MAX = 3000
|
||||
VIDEO_CHAT_PROVIDERS = [u"Jitsi", u"Google Hangouts"]
|
||||
AUTHENTICATION_FLAGS = [u'Google', u'Email', u'GitHub', u'LDAP', u'Dev', u'RemoteUser']
|
||||
SUBDOMAIN_FOR_ROOT_DOMAIN = ''
|
||||
|
@ -229,8 +229,8 @@ class Realm(models.Model):
|
|||
# like zulipchat.com.
|
||||
SELF_HOSTED = 1
|
||||
LIMITED = 2
|
||||
PREMIUM = 3
|
||||
PREMIUM_FREE = 4
|
||||
STANDARD = 3
|
||||
STANDARD_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.
|
||||
|
|
|
@ -331,7 +331,7 @@ class PlansPageTest(ZulipTestCase):
|
|||
self.assert_in_success_response(["does not exist"], result)
|
||||
# Test valid domain, no login
|
||||
realm = get_realm("zulip")
|
||||
realm.plan_type = Realm.PREMIUM_FREE
|
||||
realm.plan_type = Realm.STANDARD_FREE
|
||||
realm.save(update_fields=["plan_type"])
|
||||
result = self.client_get("/plans/", subdomain="zulip")
|
||||
self.assertEqual(result.status_code, 302)
|
||||
|
@ -348,12 +348,12 @@ class PlansPageTest(ZulipTestCase):
|
|||
|
||||
def test_CTA_text_by_plan_type(self) -> None:
|
||||
sign_up_now = "Sign up now"
|
||||
buy_premium = "Buy Premium"
|
||||
buy_standard = "Buy Standard"
|
||||
current_plan = "Current plan"
|
||||
|
||||
# Root domain
|
||||
result = self.client_get("/plans/", subdomain="")
|
||||
self.assert_in_success_response([sign_up_now, buy_premium], result)
|
||||
self.assert_in_success_response([sign_up_now, buy_standard], result)
|
||||
self.assert_not_in_success_response([current_plan], result)
|
||||
|
||||
realm = get_realm("zulip")
|
||||
|
@ -373,17 +373,17 @@ class PlansPageTest(ZulipTestCase):
|
|||
realm.plan_type = Realm.LIMITED
|
||||
realm.save(update_fields=["plan_type"])
|
||||
result = self.client_get("/plans/", subdomain="zulip")
|
||||
self.assert_in_success_response([current_plan, buy_premium], result)
|
||||
self.assert_in_success_response([current_plan, buy_standard], result)
|
||||
self.assert_not_in_success_response([sign_up_now], result)
|
||||
|
||||
realm.plan_type = Realm.PREMIUM_FREE
|
||||
realm.plan_type = Realm.STANDARD_FREE
|
||||
realm.save(update_fields=["plan_type"])
|
||||
result = self.client_get("/plans/", subdomain="zulip")
|
||||
self.assert_in_success_response([current_plan], result)
|
||||
self.assert_not_in_success_response([sign_up_now, buy_premium], result)
|
||||
self.assert_not_in_success_response([sign_up_now, buy_standard], result)
|
||||
|
||||
realm.plan_type = Realm.PREMIUM
|
||||
realm.plan_type = Realm.STANDARD
|
||||
realm.save(update_fields=["plan_type"])
|
||||
result = self.client_get("/plans/", subdomain="zulip")
|
||||
self.assert_in_success_response([current_plan], result)
|
||||
self.assert_not_in_success_response([sign_up_now, buy_premium], result)
|
||||
self.assert_not_in_success_response([sign_up_now, buy_standard], result)
|
||||
|
|
|
@ -672,13 +672,13 @@ class HomeTest(ZulipTestCase):
|
|||
result_html = self._get_home_page().content.decode('utf-8')
|
||||
self.assertIn('Plans', result_html)
|
||||
|
||||
# Show plans link to no one, including admins, if SELF_HOSTED or PREMIUM
|
||||
# Show plans link to no one, including admins, if SELF_HOSTED or STANDARD
|
||||
realm.plan_type = Realm.SELF_HOSTED
|
||||
realm.save(update_fields=["plan_type"])
|
||||
result_html = self._get_home_page().content.decode('utf-8')
|
||||
self.assertNotIn('Plans', result_html)
|
||||
|
||||
realm.plan_type = Realm.PREMIUM
|
||||
realm.plan_type = Realm.STANDARD
|
||||
realm.save(update_fields=["plan_type"])
|
||||
result_html = self._get_home_page().content.decode('utf-8')
|
||||
self.assertNotIn('Plans', result_html)
|
||||
|
|
|
@ -824,7 +824,7 @@ class ImportExportTest(ZulipTestCase):
|
|||
|
||||
def test_plan_type(self) -> None:
|
||||
realm = get_realm('zulip')
|
||||
realm.plan_type = Realm.PREMIUM
|
||||
realm.plan_type = Realm.STANDARD
|
||||
realm.save(update_fields=['plan_type'])
|
||||
|
||||
self._setup_export_files()
|
||||
|
|
|
@ -351,12 +351,12 @@ class RealmTest(ZulipTestCase):
|
|||
def test_change_plan_type(self) -> None:
|
||||
user = self.example_user('iago')
|
||||
self.assertEqual(get_realm('zulip').max_invites, settings.INVITES_DEFAULT_REALM_DAILY_MAX)
|
||||
do_change_plan_type(user, Realm.PREMIUM)
|
||||
self.assertEqual(get_realm('zulip').max_invites, Realm.INVITES_PREMIUM_REALM_DAILY_MAX)
|
||||
do_change_plan_type(user, Realm.STANDARD)
|
||||
self.assertEqual(get_realm('zulip').max_invites, Realm.INVITES_STANDARD_REALM_DAILY_MAX)
|
||||
do_change_plan_type(user, Realm.LIMITED)
|
||||
self.assertEqual(get_realm('zulip').max_invites, settings.INVITES_DEFAULT_REALM_DAILY_MAX)
|
||||
do_change_plan_type(user, Realm.PREMIUM_FREE)
|
||||
self.assertEqual(get_realm('zulip').max_invites, Realm.INVITES_PREMIUM_REALM_DAILY_MAX)
|
||||
do_change_plan_type(user, Realm.STANDARD_FREE)
|
||||
self.assertEqual(get_realm('zulip').max_invites, Realm.INVITES_STANDARD_REALM_DAILY_MAX)
|
||||
|
||||
class RealmAPITest(ZulipTestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue