diff --git a/corporate/lib/stripe.py b/corporate/lib/stripe.py index b4057093a5..0b4a3a10ad 100644 --- a/corporate/lib/stripe.py +++ b/corporate/lib/stripe.py @@ -51,6 +51,7 @@ from corporate.models import ( get_customer_by_realm, get_customer_by_remote_realm, get_customer_by_remote_server, + is_legacy_customer, ) from zerver.lib.exceptions import JsonableError from zerver.lib.logging_util import log_to_file @@ -1847,10 +1848,11 @@ class BillingSession(ABC): if fixed_price_plan_offer is not None: free_trial = False + if is_legacy_customer(customer): + # Free trial is not available for legacy customers. + free_trial = False + remote_server_legacy_plan = self.get_remote_server_legacy_plan(customer) - if remote_server_legacy_plan is not None: - # Free trial is not available for legacy customers. - free_trial = False should_schedule_upgrade_for_legacy_remote_server = ( remote_server_legacy_plan is not None and upgrade_request.remote_server_plan_start_date == "billing_cycle_end_date" @@ -2420,6 +2422,9 @@ class BillingSession(ABC): is_self_hosted_billing = not isinstance(self, RealmBillingSession) if fixed_price is None and remote_server_legacy_plan_end_date is None: free_trial_days = get_free_trial_days(is_self_hosted_billing, tier) + if customer is not None and is_legacy_customer(customer): + # Free trial is not available for legacy customers. + free_trial_days = None if free_trial_days is not None: _, _, free_trial_end, _ = compute_plan_parameters( tier, diff --git a/corporate/models.py b/corporate/models.py index 262b869101..7d680d3509 100644 --- a/corporate/models.py +++ b/corporate/models.py @@ -473,6 +473,12 @@ def get_current_plan_by_customer(customer: Customer) -> Optional[CustomerPlan]: ).first() +def is_legacy_customer(customer: Customer) -> bool: + return CustomerPlan.objects.filter( + customer=customer, tier=CustomerPlan.TIER_SELF_HOSTED_LEGACY + ).exists() + + def get_current_plan_by_realm(realm: Realm) -> Optional[CustomerPlan]: customer = get_customer_by_realm(realm) if customer is None: diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.create.1.json new file mode 100644 index 0000000000..f9f5cb6381 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.modify.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.modify.1.json new file mode 100644 index 0000000000..f24ad72920 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.modify.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.1.json new file mode 100644 index 0000000000..ff8e652ab1 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.2.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.2.json new file mode 100644 index 0000000000..ff8e652ab1 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.2.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.3.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.3.json new file mode 100644 index 0000000000..ff8e652ab1 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.3.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.4.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.4.json new file mode 100644 index 0000000000..ff8e652ab1 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.4.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.5.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.5.json new file mode 100644 index 0000000000..9589e51048 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Customer.retrieve.5.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.1.json new file mode 100644 index 0000000000..cc07d736e6 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.2.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.2.json new file mode 100644 index 0000000000..4a4ef298ac Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.2.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.3.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.3.json new file mode 100644 index 0000000000..8ed630ad58 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.3.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.4.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.4.json new file mode 100644 index 0000000000..8fcbc7d4b8 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.4.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.5.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.5.json new file mode 100644 index 0000000000..6d922067af Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Event.list.5.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.create.1.json new file mode 100644 index 0000000000..0b30b9a339 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.finalize_invoice.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.finalize_invoice.1.json new file mode 100644 index 0000000000..39f18ce4ce Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.finalize_invoice.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.list.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.list.1.json new file mode 100644 index 0000000000..e39960ab72 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.list.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.pay.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.pay.1.json new file mode 100644 index 0000000000..74a6e0055d Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--Invoice.pay.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--InvoiceItem.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--InvoiceItem.create.1.json new file mode 100644 index 0000000000..a1d4d901a3 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--InvoiceItem.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--InvoiceItem.create.2.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--InvoiceItem.create.2.json new file mode 100644 index 0000000000..bfcae2e1fa Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--InvoiceItem.create.2.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--SetupIntent.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--SetupIntent.create.1.json new file mode 100644 index 0000000000..f809ca4dc7 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--SetupIntent.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--SetupIntent.list.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--SetupIntent.list.1.json new file mode 100644 index 0000000000..705ebc03b2 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--SetupIntent.list.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--SetupIntent.retrieve.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--SetupIntent.retrieve.1.json new file mode 100644 index 0000000000..f809ca4dc7 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--SetupIntent.retrieve.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--checkout.Session.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--checkout.Session.create.1.json new file mode 100644 index 0000000000..62005867f0 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--checkout.Session.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--checkout.Session.list.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--checkout.Session.list.1.json new file mode 100644 index 0000000000..daeee15a0e Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_active_legacy_customer--checkout.Session.list.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.create.1.json new file mode 100644 index 0000000000..3d6b9bc66c Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.modify.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.modify.1.json new file mode 100644 index 0000000000..53d023ce51 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.modify.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.1.json new file mode 100644 index 0000000000..82a47be188 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.2.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.2.json new file mode 100644 index 0000000000..82a47be188 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.2.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.3.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.3.json new file mode 100644 index 0000000000..82a47be188 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.3.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.4.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.4.json new file mode 100644 index 0000000000..82a47be188 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.4.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.5.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.5.json new file mode 100644 index 0000000000..6e3e5fea10 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Customer.retrieve.5.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.1.json new file mode 100644 index 0000000000..6ec01fdc81 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.2.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.2.json new file mode 100644 index 0000000000..a5e7f51eae Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.2.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.3.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.3.json new file mode 100644 index 0000000000..30345b0325 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.3.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.4.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.4.json new file mode 100644 index 0000000000..2cb9edc25f Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.4.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.5.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.5.json new file mode 100644 index 0000000000..6d922067af Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Event.list.5.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.create.1.json new file mode 100644 index 0000000000..4f060c1df9 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.finalize_invoice.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.finalize_invoice.1.json new file mode 100644 index 0000000000..9513e04f02 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.finalize_invoice.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.list.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.list.1.json new file mode 100644 index 0000000000..e39960ab72 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.list.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.pay.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.pay.1.json new file mode 100644 index 0000000000..ab0d215f27 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--Invoice.pay.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--InvoiceItem.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--InvoiceItem.create.1.json new file mode 100644 index 0000000000..12dc466795 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--InvoiceItem.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--InvoiceItem.create.2.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--InvoiceItem.create.2.json new file mode 100644 index 0000000000..242630a631 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--InvoiceItem.create.2.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--SetupIntent.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--SetupIntent.create.1.json new file mode 100644 index 0000000000..355ce9f41b Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--SetupIntent.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--SetupIntent.list.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--SetupIntent.list.1.json new file mode 100644 index 0000000000..571dbff45f Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--SetupIntent.list.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--SetupIntent.retrieve.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--SetupIntent.retrieve.1.json new file mode 100644 index 0000000000..355ce9f41b Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--SetupIntent.retrieve.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--checkout.Session.create.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--checkout.Session.create.1.json new file mode 100644 index 0000000000..1a9440d877 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--checkout.Session.create.1.json differ diff --git a/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--checkout.Session.list.1.json b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--checkout.Session.list.1.json new file mode 100644 index 0000000000..b96cac7256 Binary files /dev/null and b/corporate/tests/stripe_fixtures/free_trial_not_available_for_ended_legacy_customer--checkout.Session.list.1.json differ diff --git a/corporate/tests/test_stripe.py b/corporate/tests/test_stripe.py index f913c76be7..019b404649 100644 --- a/corporate/tests/test_stripe.py +++ b/corporate/tests/test_stripe.py @@ -92,6 +92,7 @@ from corporate.models import ( get_current_plan_by_realm, get_customer_by_realm, get_customer_by_remote_realm, + is_legacy_customer, ) from corporate.tests.test_remote_billing import RemoteRealmBillingTestCase, RemoteServerTestCase from corporate.views.remote_billing_page import generate_confirmation_link_for_server_deactivation @@ -633,7 +634,18 @@ class StripeTestCase(ZulipTestCase): return upgrade_json_response is_self_hosted_billing = not isinstance(self.billing_session, RealmBillingSession) - if invoice or not talk_to_stripe or is_free_trial_offer_enabled(is_self_hosted_billing): + customer = self.billing_session.get_customer() + assert customer is not None + if ( + invoice + or not talk_to_stripe + or ( + is_free_trial_offer_enabled(is_self_hosted_billing) + and + # Free trial is not applicable for legacy customers. + not is_legacy_customer(customer) + ) + ): # Upgrade already happened for free trial, invoice realms or schedule # upgrade for legacy remote servers. return upgrade_json_response @@ -7729,6 +7741,97 @@ class TestRemoteServerBillingFlow(StripeTestCase, RemoteServerTestCase): f"INFO:corporate.stripe:Change plan status: Customer.id: {customer.id}, CustomerPlan.id: {customer_plan.id}, status: {CustomerPlan.ACTIVE}", ) + @responses.activate + @mock_stripe() + def test_free_trial_not_available_for_active_legacy_customer(self, *mocks: Mock) -> None: + with self.settings(SELF_HOSTING_FREE_TRIAL_DAYS=30): + self.login("hamlet") + hamlet = self.example_user("hamlet") + + self.add_mock_response() + + with time_machine.travel(self.now, tick=False): + send_server_data_to_push_bouncer(consider_usage_statistics=False) + # Test that free trial is not available for customers with active legacy plan. + end_date = add_months(self.now, months=3) + self.billing_session.migrate_customer_to_legacy_plan(self.now, end_date) + + result = self.execute_remote_billing_authentication_flow( + hamlet.delivery_email, hamlet.full_name + ) + self.assertEqual(result.status_code, 302) + self.assertEqual(result["Location"], f"{self.billing_session.billing_base_url}/plans/") + with time_machine.travel(self.now, tick=False): + response = self.client_get( + f"{self.billing_session.billing_base_url}/plans/", subdomain="selfhosting" + ) + self.assert_not_in_success_response(["free trial"], response) + + with time_machine.travel(self.now, tick=False): + result = self.client_get( + f"{self.billing_session.billing_base_url}/upgrade/?tier={CustomerPlan.TIER_SELF_HOSTED_BASIC}", + subdomain="selfhosting", + ) + self.assert_not_in_success_response(["free trial"], response) + + with time_machine.travel(self.now, tick=False): + self.add_card_and_upgrade( + tier=CustomerPlan.TIER_SELF_HOSTED_BASIC, schedule="monthly" + ) + + with time_machine.travel(self.now + timedelta(days=1), tick=False): + response = self.client_get( + f"{self.billing_session.billing_base_url}/billing/", subdomain="selfhosting" + ) + self.assert_not_in_success_response(["(free trial)"], response) + + @responses.activate + @mock_stripe() + def test_free_trial_not_available_for_ended_legacy_customer(self, *mocks: Mock) -> None: + with self.settings(SELF_HOSTING_FREE_TRIAL_DAYS=30): + self.login("hamlet") + hamlet = self.example_user("hamlet") + + self.add_mock_response() + + with time_machine.travel(self.now, tick=False): + send_server_data_to_push_bouncer(consider_usage_statistics=False) + # Test that free trial is not available for customers with active legacy plan. + end_date = add_months(self.now, months=3) + self.billing_session.migrate_customer_to_legacy_plan(self.now, end_date) + CustomerPlan.objects.filter(customer__remote_server=self.remote_server).update( + status=CustomerPlan.ENDED + ) + + result = self.execute_remote_billing_authentication_flow( + hamlet.delivery_email, hamlet.full_name + ) + self.assertEqual(result.status_code, 302) + self.assertEqual(result["Location"], f"{self.billing_session.billing_base_url}/plans/") + with time_machine.travel(self.now, tick=False): + response = self.client_get( + f"{self.billing_session.billing_base_url}/plans/", subdomain="selfhosting" + ) + self.assert_not_in_success_response(["free trial"], response) + + with time_machine.travel(self.now, tick=False): + result = self.client_get( + f"{self.billing_session.billing_base_url}/upgrade/?tier={CustomerPlan.TIER_SELF_HOSTED_BASIC}", + subdomain="selfhosting", + ) + self.assert_not_in_success_response(["free trial"], response) + + with time_machine.travel(self.now, tick=False): + self.add_card_and_upgrade( + tier=CustomerPlan.TIER_SELF_HOSTED_BASIC, schedule="monthly" + ) + + with time_machine.travel(self.now + timedelta(days=1), tick=False): + response = self.client_get( + f"{self.billing_session.billing_base_url}/billing/", subdomain="selfhosting" + ) + self.assert_not_in_success_response(["(free trial)"], response) + @responses.activate @mock_stripe() def test_upgrade_user_to_basic_plan_free_trial_remote_server(self, *mocks: Mock) -> None: diff --git a/corporate/views/portico.py b/corporate/views/portico.py index 9d914f20d8..57f306915e 100644 --- a/corporate/views/portico.py +++ b/corporate/views/portico.py @@ -21,7 +21,12 @@ from corporate.lib.stripe import ( get_configured_fixed_price_plan_offer, get_free_trial_days, ) -from corporate.models import CustomerPlan, get_current_plan_by_customer, get_customer_by_realm +from corporate.models import ( + CustomerPlan, + get_current_plan_by_customer, + get_customer_by_realm, + is_legacy_customer, +) from zerver.context_processors import get_realm_from_request, latest_info_context from zerver.decorator import add_google_analytics, zulip_login_required from zerver.lib.github import ( @@ -168,9 +173,6 @@ def remote_realm_plans_page( if context.customer_plan is None: context.on_free_tier = not context.is_sponsored else: - if context.customer_plan.tier == CustomerPlan.TIER_SELF_HOSTED_LEGACY: - # Free trial is disabled for legacy customers. - context.free_trial_days = None context.on_free_tier = ( context.customer_plan.tier in ( @@ -191,6 +193,10 @@ def remote_realm_plans_page( status=CustomerPlan.NEVER_STARTED, ) + if is_legacy_customer(customer): + # Free trial is disabled for legacy customers. + context.free_trial_days = None + context.is_new_customer = ( not context.on_free_tier and context.customer_plan is None and not context.is_sponsored ) @@ -234,9 +240,6 @@ def remote_server_plans_page( if context.customer_plan is None: context.on_free_tier = not context.is_sponsored else: - if context.customer_plan.tier == CustomerPlan.TIER_SELF_HOSTED_LEGACY: - # Free trial is disabled for legacy customers. - context.free_trial_days = None context.on_free_tier = context.customer_plan.tier in ( CustomerPlan.TIER_SELF_HOSTED_LEGACY, CustomerPlan.TIER_SELF_HOSTED_BASE, @@ -253,6 +256,10 @@ def remote_server_plans_page( status=CustomerPlan.NEVER_STARTED, ) + if is_legacy_customer(customer): + # Free trial is disabled for legacy customers. + context.free_trial_days = None + context.is_new_customer = ( not context.on_free_tier and context.customer_plan is None and not context.is_sponsored )