billing: User FREE_TRIAL_DAYS instead of FREE_TRIAL_MONTHS.

This commit is contained in:
Vishnu Ks 2020-05-14 21:51:23 +05:30 committed by Tim Abbott
parent 6528226a80
commit 66b1ad7002
8 changed files with 49 additions and 45 deletions

View File

@ -1,4 +1,4 @@
from datetime import datetime
from datetime import datetime, timedelta
from decimal import Decimal
from functools import wraps
import logging
@ -291,7 +291,7 @@ def compute_plan_parameters(
if automanage_licenses:
next_invoice_date = add_months(billing_cycle_anchor, 1)
if free_trial:
period_end = add_months(billing_cycle_anchor, settings.FREE_TRIAL_MONTHS)
period_end = billing_cycle_anchor + timedelta(days=settings.FREE_TRIAL_DAYS)
next_invoice_date = period_end
return billing_cycle_anchor, next_invoice_date, period_end, price_per_license
@ -302,7 +302,7 @@ def process_initial_upgrade(user: UserProfile, licenses: int, automanage_license
realm = user.realm
customer = update_or_create_stripe_customer(user, stripe_token=stripe_token)
charge_automatically = stripe_token is not None
free_trial = settings.FREE_TRIAL_MONTHS not in (None, 0)
free_trial = settings.FREE_TRIAL_DAYS not in (None, 0)
if get_current_plan_by_customer(customer) is not None:
# Unlikely race condition from two people upgrading (clicking "Make payment")

View File

@ -534,10 +534,11 @@ class StripeTest(StripeTestCase):
user = self.example_user("hamlet")
self.login_user(user)
with self.settings(FREE_TRIAL_MONTHS=2):
with self.settings(FREE_TRIAL_DAYS=60):
response = self.client_get("/upgrade/")
free_trial_end_date = self.now + timedelta(days=60)
self.assert_in_success_response(['Pay annually', 'Free Trial', '2 month'], response)
self.assert_in_success_response(['Pay annually', 'Free Trial', '60 day'], response)
self.assertNotEqual(user.realm.plan_type, Realm.STANDARD)
self.assertFalse(Customer.objects.filter(realm=user.realm).exists())
@ -567,7 +568,7 @@ class StripeTest(StripeTestCase):
customer=customer, automanage_licenses=True,
price_per_license=8000, fixed_price=None, discount=None, billing_cycle_anchor=self.now,
billing_schedule=CustomerPlan.ANNUAL, invoiced_through=LicenseLedger.objects.first(),
next_invoice_date=add_months(self.now, 2), tier=CustomerPlan.STANDARD,
next_invoice_date=free_trial_end_date, tier=CustomerPlan.STANDARD,
status=CustomerPlan.FREE_TRIAL)
LicenseLedger.objects.get(
plan=plan, is_renewal=True, event_time=self.now, licenses=self.seat_count,
@ -619,13 +620,13 @@ class StripeTest(StripeTestCase):
self.assertEqual(len(invoices), 0)
customer_plan = CustomerPlan.objects.get(customer=customer)
self.assertEqual(customer_plan.status, CustomerPlan.FREE_TRIAL)
self.assertEqual(customer_plan.next_invoice_date, add_months(self.now, 2))
self.assertEqual(customer_plan.next_invoice_date, free_trial_end_date)
invoice_plans_as_needed(add_months(self.now, 2))
invoice_plans_as_needed(free_trial_end_date)
customer_plan.refresh_from_db()
realm.refresh_from_db()
self.assertEqual(customer_plan.status, CustomerPlan.ACTIVE)
self.assertEqual(customer_plan.next_invoice_date, add_months(self.now, 3))
self.assertEqual(customer_plan.next_invoice_date, add_months(free_trial_end_date, 1))
self.assertEqual(realm.plan_type, Realm.STANDARD)
invoices = [invoice for invoice in stripe.Invoice.list(customer=stripe_customer.id)]
self.assertEqual(len(invoices), 1)
@ -643,24 +644,24 @@ class StripeTest(StripeTestCase):
"amount": 15 * 80 * 100, "description": "Zulip Standard - renewal",
"plan": None, "quantity": 15, "subscription": None, "discountable": False,
"period": {
"start": datetime_to_timestamp(add_months(self.now, 2)),
"end": datetime_to_timestamp(add_months(self.now, 14))
"start": datetime_to_timestamp(free_trial_end_date),
"end": datetime_to_timestamp(add_months(free_trial_end_date, 12))
},
}
for key, value in invoice_item_params.items():
self.assertEqual(invoice_items[0][key], value)
invoice_plans_as_needed(add_months(self.now, 3))
invoice_plans_as_needed(add_months(free_trial_end_date, 1))
invoices = [invoice for invoice in stripe.Invoice.list(customer=stripe_customer.id)]
self.assertEqual(len(invoices), 1)
with patch('corporate.lib.stripe.get_latest_seat_count', return_value=19):
update_license_ledger_if_needed(realm, add_months(self.now, 12))
update_license_ledger_if_needed(realm, add_months(free_trial_end_date, 10))
self.assertEqual(
LicenseLedger.objects.order_by('-id').values_list('licenses', 'licenses_at_next_renewal').first(),
(19, 19)
)
invoice_plans_as_needed(add_months(self.now, 12))
invoice_plans_as_needed(add_months(free_trial_end_date, 10))
invoices = [invoice for invoice in stripe.Invoice.list(customer=stripe_customer.id)]
self.assertEqual(len(invoices), 2)
invoice_params = {
@ -673,12 +674,12 @@ class StripeTest(StripeTestCase):
"amount": 5172, "description": "Additional license (Jan 2, 2013 - Mar 2, 2013)",
"discountable": False, "quantity": 4,
"period": {
"start": datetime_to_timestamp(add_months(self.now, 12)),
"end": datetime_to_timestamp(add_months(self.now, 14))
"start": datetime_to_timestamp(add_months(free_trial_end_date, 10)),
"end": datetime_to_timestamp(add_months(free_trial_end_date, 12))
}
}
invoice_plans_as_needed(add_months(self.now, 14))
invoice_plans_as_needed(add_months(free_trial_end_date, 12))
invoices = [invoice for invoice in stripe.Invoice.list(customer=stripe_customer.id)]
self.assertEqual(len(invoices), 3)
@ -687,10 +688,11 @@ class StripeTest(StripeTestCase):
user = self.example_user("hamlet")
self.login_user(user)
with self.settings(FREE_TRIAL_MONTHS=2):
free_trial_end_date = self.now + timedelta(days=60)
with self.settings(FREE_TRIAL_DAYS=60):
response = self.client_get("/upgrade/")
self.assert_in_success_response(['Pay annually', 'Free Trial', '2 month'], response)
self.assert_in_success_response(['Pay annually', 'Free Trial', '60 day'], response)
self.assertNotEqual(user.realm.plan_type, Realm.STANDARD)
self.assertFalse(Customer.objects.filter(realm=user.realm).exists())
@ -715,7 +717,7 @@ class StripeTest(StripeTestCase):
customer=customer, automanage_licenses=False,
price_per_license=8000, fixed_price=None, discount=None, billing_cycle_anchor=self.now,
billing_schedule=CustomerPlan.ANNUAL, invoiced_through=LicenseLedger.objects.first(),
next_invoice_date=add_months(self.now, 2), tier=CustomerPlan.STANDARD,
next_invoice_date=free_trial_end_date, tier=CustomerPlan.STANDARD,
status=CustomerPlan.FREE_TRIAL)
LicenseLedger.objects.get(
@ -754,13 +756,13 @@ class StripeTest(StripeTestCase):
mocked.reset_mock()
customer_plan = CustomerPlan.objects.get(customer=customer)
self.assertEqual(customer_plan.status, CustomerPlan.FREE_TRIAL)
self.assertEqual(customer_plan.next_invoice_date, add_months(self.now, 2))
self.assertEqual(customer_plan.next_invoice_date, free_trial_end_date)
invoice_plans_as_needed(add_months(self.now, 2))
invoice_plans_as_needed(free_trial_end_date)
customer_plan.refresh_from_db()
realm.refresh_from_db()
self.assertEqual(customer_plan.status, CustomerPlan.ACTIVE)
self.assertEqual(customer_plan.next_invoice_date, add_months(self.now, 14))
self.assertEqual(customer_plan.next_invoice_date, add_months(free_trial_end_date, 12))
self.assertEqual(realm.plan_type, Realm.STANDARD)
invoices = [invoice for invoice in stripe.Invoice.list(customer=stripe_customer.id)]
self.assertEqual(len(invoices), 1)
@ -778,22 +780,22 @@ class StripeTest(StripeTestCase):
"amount": 123 * 80 * 100, "description": "Zulip Standard - renewal",
"plan": None, "quantity": 123, "subscription": None, "discountable": False,
"period": {
"start": datetime_to_timestamp(add_months(self.now, 2)),
"end": datetime_to_timestamp(add_months(self.now, 14))
"start": datetime_to_timestamp(free_trial_end_date),
"end": datetime_to_timestamp(add_months(free_trial_end_date, 12))
},
}
for key, value in invoice_item_params.items():
self.assertEqual(invoice_items[0][key], value)
invoice_plans_as_needed(add_months(self.now, 3))
invoice_plans_as_needed(add_months(free_trial_end_date, 1))
invoices = [invoice for invoice in stripe.Invoice.list(customer=stripe_customer.id)]
self.assertEqual(len(invoices), 1)
invoice_plans_as_needed(add_months(self.now, 12))
invoice_plans_as_needed(add_months(free_trial_end_date, 10))
invoices = [invoice for invoice in stripe.Invoice.list(customer=stripe_customer.id)]
self.assertEqual(len(invoices), 1)
invoice_plans_as_needed(add_months(self.now, 14))
invoice_plans_as_needed(add_months(free_trial_end_date, 12))
invoices = [invoice for invoice in stripe.Invoice.list(customer=stripe_customer.id)]
self.assertEqual(len(invoices), 2)
@ -1284,12 +1286,14 @@ class StripeTest(StripeTestCase):
@patch("corporate.lib.stripe.billing_logger.info")
def test_downgrade_free_trial(self, mock_: Mock) -> None:
user = self.example_user("hamlet")
with self.settings(FREE_TRIAL_MONTHS=2):
free_trial_end_date = self.now + timedelta(days=60)
with self.settings(FREE_TRIAL_DAYS=60):
with patch("corporate.lib.stripe.timezone_now", return_value=self.now):
self.local_upgrade(self.seat_count, True, CustomerPlan.ANNUAL, 'token')
plan = CustomerPlan.objects.get()
self.assertEqual(plan.next_invoice_date, add_months(self.now, 2))
self.assertEqual(plan.next_invoice_date, free_trial_end_date)
self.assertEqual(get_realm('zulip').plan_type, Realm.STANDARD)
self.assertEqual(plan.status, CustomerPlan.FREE_TRIAL)

View File

@ -146,7 +146,7 @@ def initial_upgrade(request: HttpRequest) -> HttpResponse:
'min_invoiced_licenses': max(seat_count, MIN_INVOICED_LICENSES),
'default_invoice_days_until_due': DEFAULT_INVOICE_DAYS_UNTIL_DUE,
'plan': "Zulip Standard",
"free_trial_months": settings.FREE_TRIAL_MONTHS,
"free_trial_days": settings.FREE_TRIAL_DAYS,
'page_params': {
'seat_count': seat_count,
'annual_price': 8000,

View File

@ -18,9 +18,9 @@
<div class="page-content">
<div class="main">
<h1>{% trans %}Upgrade to {{ plan }}{% endtrans %}</h1>
{% if free_trial_months %}
{% if free_trial_days %}
<div class="alert alert-info">
Upgrade now to start your {{ free_trial_months }} month Free Trial of Zulip Standard.
Upgrade now to start your {{ free_trial_days }} day Free Trial of Zulip Standard.
</div>
{% endif %}
@ -44,7 +44,7 @@
<input type="hidden" name="signed_seat_count" value="{{ signed_seat_count }}">
<input type="hidden" name="salt" value="{{ salt }}">
<input type="hidden" name="billing_modality" value="charge_automatically">
{% if free_trial_months %}
{% if free_trial_days %}
<p>
You won't be charged during the Free Trial. You can also downgrade back to Zulip Limited
during the Free Trial.
@ -94,7 +94,7 @@
<div id="license-automatic-section">
<p>
{% if free_trial_months %}
{% if free_trial_days %}
After the Free Trial, you&rsquo;ll be charged
<b>$<span id="charged_amount"></span></b> for <b>{{ seat_count }}</b>
users.
@ -116,7 +116,7 @@
<div id="license-manual-section">
<p>
{% if free_trial_months %}
{% if free_trial_days %}
Enter the number of users you would like to pay for after the Free Trial.<br>
You'll need to manually add licenses to add or invite
additional users.
@ -175,7 +175,7 @@
</label>
</div>
<p>
{% if free_trial_months %}
{% if free_trial_days %}
Enter the number of users you would like to pay for.<br>
We'll email you an invoice after the Free Trial.
Invoices can be paid by ACH transfer or credit card.

View File

@ -87,16 +87,16 @@
</a>
{% elif realm_plan_type == 2 %}
<a href="/upgrade" class="button green">
{% if free_trial_months %}
Start {{ free_trial_months }} month Free Trial
{% if free_trial_days %}
Start {{ free_trial_days }} day Free Trial
{% else %}
Buy Standard
{% endif %}
</a>
{% else %}
<a href="/upgrade" class="button green">
{% if free_trial_months %}
Start {{ free_trial_months }} month Free Trial
{% if free_trial_days %}
Start {{ free_trial_days }} day Free Trial
{% else %}
Buy Standard
{% endif %}

View File

@ -26,7 +26,7 @@ def apps_view(request: HttpRequest, _: str) -> HttpResponse:
def plans_view(request: HttpRequest) -> HttpResponse:
realm = get_realm_from_request(request)
realm_plan_type = 0
free_trial_months = settings.FREE_TRIAL_MONTHS
free_trial_days = settings.FREE_TRIAL_DAYS
if realm is not None:
realm_plan_type = realm.plan_type
if realm.plan_type == Realm.SELF_HOSTED and settings.PRODUCTION:
@ -36,7 +36,7 @@ def plans_view(request: HttpRequest) -> HttpResponse:
return TemplateResponse(
request,
"zerver/plans.html",
context={"realm_plan_type": realm_plan_type, 'free_trial_months': free_trial_months},
context={"realm_plan_type": realm_plan_type, 'free_trial_days': free_trial_days},
)
@add_google_analytics

View File

@ -363,7 +363,7 @@ ARCHIVED_DATA_VACUUMING_DELAY_DAYS = 7
# are available to all realms.
BILLING_ENABLED = False
FREE_TRIAL_MONTHS = None
FREE_TRIAL_DAYS = None
# Automatically catch-up soft deactivated users when running the
# `soft-deactivate-users` cron. Turn this off if the server has 10Ks of

View File

@ -155,7 +155,7 @@ THUMBNAIL_IMAGES = True
SEARCH_PILLS_ENABLED = bool(os.getenv('SEARCH_PILLS_ENABLED', False))
BILLING_ENABLED = True
FREE_TRIAL_MONTHS = None
FREE_TRIAL_DAYS = None
# Test Custom TOS template rendering
TERMS_OF_SERVICE = 'corporate/terms.md'