Commit Graph

467 Commits

Author SHA1 Message Date
Lauryn Menard fca9ff1ae7 support: Show date for start of next billing cycle for current plan.
Instead of showing the next invoice date for the plan, show the
date for the next billing cycle start (e.g. the next plan renewal
charge date), except for plans currently on a free trial.

For plans on a free trial, the next plan renewal date will be when
the free trial ends, which is stored as the next invoice date on
the plan.
2024-01-22 10:09:00 -08:00
Lauryn Menard 76b26612a0 remote-activity: Get user counts for all servers and realms.
Instead of querying the database for every remote server and realm
in the remote activity chart, we now get the server and realm data
for the installation in two queries.
2024-01-19 11:46:13 -08:00
Lauryn Menard 536aef854c remote-activity: Display rows for remote realms.
Adds columns for remote realm ID, name and organization type. If
a remote server has remote realms attached that are not marked
as deactivated by the remote server, then there will be a row in
the chart for each remote realm (which duplicates some remote
server data).

Updates the plan data, revenue and user counts to be for the realm
if present and otherwise for the server.

Updates the user counts to be total users and guest users, instead
of non guest and guest users.

The total row for mobile data (users and pushes forwarded) sums
each remote server's data once, so while the column duplicates
data, the total row should be an accurate total for the installation.

Adds 5 queries to the remote activity page test. One is for the
additional query for the remote realm plans. The other four are
getting the remote realm object and then the user count data for
the two remote realms in the test.
2024-01-19 11:46:13 -08:00
Aman Agrawal 5a97a4d8dc stripe: End legacy plan on end_date. 2024-01-19 09:34:36 -08:00
Aman Agrawal 884c44d3cb stripe: Avoid redirects from `event_status` to `event_status/`. 2024-01-17 12:46:44 -08:00
Lauryn Menard 7e1d0adb6e support-tests: Add coverage for discount actions when upgrade scheduled. 2024-01-15 03:10:04 -08:00
Lauryn Menard a5f2883a75 remote-support: Add ability to set a required plan tier for customer. 2024-01-15 03:10:04 -08:00
Lauryn Menard fbe7145231 corporate: Check plan tier for new plan discount calculations.
Now that a customer discount may require a particular plan tier to
be applied, update the billing code to check the plan tier when
getting the customer default_discount field/information for a new
plan.

For billing schedule changes and displaying billing information for
current plans, we explicitly use the discount set on the current,
active plan and do not check the customer object for these actions.
2024-01-15 03:10:04 -08:00
Lauryn Menard f27b6d896a audit-logs: Add generic property changed for Customer and CustomerPlan.
Change audit logs for changing a Customer or CustomerPlan property
to use a generic event type and specify the property name in the
extra data.
2024-01-15 03:10:04 -08:00
Prakhar Pratyush 89f9e097db stripe: Add cron-based plan invoicing to remote server billing system. 2024-01-14 15:47:55 -08:00
Prakhar Pratyush 11908c4c2e stripe: Add cron-based plan invoicing to remote realm billing system. 2024-01-14 15:47:55 -08:00
Prakhar Pratyush 6088186223 stripe: Add flat discount while invoicing self-hosted realm/server.
This prep commit adds logic to calculate discount based
on flat_discount and flat_discounted_months. Creates
a stripe invoice item for the discount.

This will be used by remote realm/server billing system
while invoicing via cron job.
2024-01-14 15:47:55 -08:00
Aman Agrawal f285de39e9 populate_realms: Allow billing page access without stripe_api_key. 2024-01-12 08:47:43 -08:00
Prakhar Pratyush 976354dbda stripe: Fix the invoice item description for flat discounts.
Earlier, in process_initial_upgrade, the flat_discount value
wasn't converted into dollars when specified in the invoice
description, resulting in showing the incorrect value of $2000
as a discount.

This commit converts the value in cents to dollars and adds tests
to verify the invoice generated.
2024-01-11 12:35:58 -08:00
Lauryn Menard 787d64e327 support: Update validation for adding or updating a discount.
Updates the HTML input field to have a min of 0, max of 99.99 and
allow increments of 0.01.

Also, use format_discount_percentage for displaying the customer
default discount in the support form.
2024-01-11 09:20:41 -08:00
Lauryn Menard 2994685399 support: Add admin support for updating end date of active plan.
This currently will only apply to tier.SELF_HOSTED_LEGACY plans.
2024-01-09 10:13:21 -08:00
Aman Agrawal 37c1b88917 stripe: Only enable free trial for basic plan. 2024-01-08 14:41:22 -08:00
Aman Agrawal 073f432a69 stripe: Set min license count based on flat discount.
For self hosted basic plan, we need to allow customers to subscribe
without purchasing 10 licenses and also we need to allow customer
take fully use the available discount so that if the add more
users in the future, the full discount was already applied.

To fix above, we set minimum user count to the least number
of licenses we require for the charge to be positive after applying
the complete discount.
2024-01-08 14:17:56 -08:00
Lauryn Menard 63dd057298 support: Include mobile users and mobile push data.
Adds the count for mobile users and mobile pushes forwarded to
the remote support view for both servers and realms.
2024-01-05 16:55:38 -08:00
Lauryn Menard f3d0ec15ca support: Clarify what missing data caused MissingDataError.
Update strings for support views to indicate if analytics data or
audit log data was missing and caused a MissingDataError.
2024-01-05 16:55:38 -08:00
Sahil Batra 63363ba50a push_notification: Check users count for plans to be downgraded.
We return expected_end_timestamp as "None" for the plans to be
downgraded if number of users is not more than MAX_USERS_WITHOUT_PLAN
since they will be downgraded to self-managed plan and would
have push notifications enabled.
2024-01-05 13:30:57 -08:00
Lauryn Menard fb29a35262 support: Add updating minimum licenses requirement after discount.
Adds a support action for updating the minimum licenses on a
customer object once a default discount has also been set.

In the case that the current billing entity has a current active
plan or a scheduled upgrade to a new plan, then the minimum
licenses will not be updated.
2024-01-04 18:42:07 -08:00
Lauryn Menard cc957e92f4 support: Raise errors for support requests that are not processed.
Previously, the message string was sent as a success response to
the context, which could have been confusing or ignored when shown
in the support admin view.
2024-01-04 18:42:07 -08:00
Tim Abbott 219df72d07 billing: Require no realm plans when approving server sponsorship. 2024-01-04 18:31:16 -08:00
Lauryn Menard b9ca60ab9e support: Add date created field to remove server information.
Removes the last updated field and replaces it with the date the
remote server was created based on the audit log data.
2024-01-02 13:16:35 -08:00
Mateusz Mandera 367d552052 billing: Improve make_end_of_cycle_... interactions with audit logs.
- Make `self.write_to_audit_log` support a `background_update:
  bool=False` parameter that can be passed when code that might have an
  acting user happens to trigger a background update.
- Make `make_end_of_cycle_updates_if_needed` pass that parameter for its
  direct audit log writes.
- Audit code that `make_end_of_cycle_updates_if_needed` calls and make
  sure those write audit logs this way too.
- Pass the user in the `billing_page` code that had to avoid it as a
  workaround:
```
    # BUG: This should pass the acting_user; this is just working
    # around that make_end_of_cycle_updates_if_needed doesn't do audit
    # logging not using the session user properly.
    billing_session = RealmBillingSession(user=None, realm=user.realm)
```
2024-01-02 10:59:05 -08:00
Lauryn Menard 9f009a2e63 support: Reformat percentages in attach discount success message. 2023-12-30 11:22:30 -08:00
Lauryn Menard ffd708ecaf support: Display next plan data on remote support view.
Currently, this will only be the case for legacy self-managed plans
that have scheduled a switch to either the Basic or Business plan.
2023-12-30 11:22:02 -08:00
Aman Agrawal e192aef23d billing: Apply a flat discount for self hosted plans. 2023-12-20 23:09:21 -08:00
Karl Stolley a37354f92a corporate: Add a Basic plan. 2023-12-20 23:09:21 -08:00
Lauryn Menard 653901fc30 support: Update remote server support search test.
Creates some reusable helper functions and adds remote realms to
the search results that are checked, which gives coverage for the
remote realm user counts in the support view.
2023-12-19 14:44:26 -08:00
Lauryn Menard f56923fafa support: Format ARR column as dollar amount in remote activity view. 2023-12-19 14:44:26 -08:00
Lauryn Menard 9e9fec68a1 support: Add plan's estimated annual revenue to remote support view.
Also fixes formatting for per license price and moves the billing
schedule to be above this line so that it's clearer the per license
price is based on the billing schedule.
2023-12-19 14:44:26 -08:00
Lauryn Menard fb3bd0cde1 support: Add user count data to remote support view. 2023-12-19 14:44:26 -08:00
Prakhar Pratyush 63bb63ad80 corporate: Remove '#nocoverage' comments.
This commit removes '#nocoverage' comment as we have added
few E2E tests in 'test_stripe.py'.
2023-12-19 10:59:38 -08:00
Aman Agrawal b2faa5c5bb stripe: Add a CustomerPlan for self hosted sponsored customers. 2023-12-18 12:55:34 -08:00
Aman Agrawal d4a852e97c stripe: Save a query to get CustomerPlan for sponsored customers. 2023-12-18 12:55:34 -08:00
Aman Agrawal d962814a30 upgrade: Make it possible to upgrade to a provided tier.
Main work is maintaining context during various redirects and
and passing the context to the final upgrade process.
2023-12-18 12:23:46 -08:00
Aman Agrawal 1326619b77 stripe: Provide min license count to template as per tier. 2023-12-18 12:23:46 -08:00
Tim Abbott 5dc1d36f73 zilencer: Fix community plan push notifications. 2023-12-17 09:36:47 -08:00
Aman Agrawal 311a645c5a sponsorship_request: Minor changes.
* Show if requested org is hosted on Zulip Cloud.
* Change how user numbers are displayed.
2023-12-17 09:33:37 -08:00
Anders Kaseorg cd96193768 models: Extract zerver.models.realms.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -08:00
Anders Kaseorg 45bb8d2580 models: Extract zerver.models.users.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2023-12-16 22:08:44 -08:00
Sahil Batra 03323b0124 push_notifications: Enforce max user count on self managed plan.
We do not support sending push notifications for realms having
more than 10 users on self managed plan.
2023-12-15 11:03:42 -08:00
Tim Abbott 10862451ef billing: Refactor code to compute push status.
This moves the function which computes can_push and
expected_end_timestamp outside RemoteRealmBillingSession
because we might use this function for RemoteZulipServer
as well and also renames it.
2023-12-15 11:03:42 -08:00
Tim Abbott 97799b279b billing: Enable billing system in production. 2023-12-15 11:03:42 -08:00
Prakhar Pratyush 1588f49b4f test_stripe: Add end-to-end test for RemoteRealm billing flow. 2023-12-15 09:08:48 -08:00
Prakhar Pratyush c12a9eeb9c stripe: Fix 'get_billable_licenses_for_customer' not using event_time.
The call to 'get_billable_licenses_for_customer' during the
'sync_license_ledger_if_needed' step should use the audit_log's
event_time while calculating 'current_count_for_billed_licenses'.

Earlier, it used timezone_now(), resulting in the latest user count
recorded corresponding to each audit log.
2023-12-15 08:09:31 -08:00
Aman Agrawal 34a1be80a4 model: Use same name for legacy plan across the app. 2023-12-14 08:22:25 -08:00
Lauryn Menard 8bce83709f corporate: Add billing support email constant.
Adds BILLING_SUPPORT_EMAIL to `stripe.py` with a value of
"sales@zulip.com" so that it can be consistently used in
billing code.
2023-12-14 08:12:01 -08:00
Mateusz Mandera 651590c49a remote_billing: Store acting users in remote user audit logs. 2023-12-14 08:11:04 -08:00
Aman Agrawal a5311c8032 stripe: End legacy plan before approving full sponsorship. 2023-12-13 22:29:30 -08:00
Tim Abbott d040664952 billing: Set the legacy plan type when migrating. 2023-12-13 16:40:44 -08:00
Tim Abbott 6308e07e53 billing: Standardize remote server plan type IDs.
This will likely save us at least one headache.
2023-12-13 16:40:44 -08:00
Lauryn Menard 89545891f6 support: Filter remote realm data query for customer realm None. 2023-12-13 14:36:23 -08:00
Lauryn Menard a897d68d93 support: Add active plan information to remote server activity.
Adds three columns to the remote server activity chart and updates
the chart key for the third of those columns.

The first is the plan name. If there are multiple plans with a
status under the live threshhold, then we send "See support view".

The second is the plan status. If there are multiple plans, then
we send "Multiple plans".

The third is the estimated annual revenue for the plan. Note that
for free trials, this will be calculated as if the plan was paid
for 12 months (so a full year).

If there is no plan for the server under the live threshold or at
all then "---" is inserted into the table row. Note that 100%
sponsored servers/realms would fall into this category.
2023-12-13 13:43:00 -08:00
Lauryn Menard 484c0df076 corporate: Move renewal_amount to BillingSession framework. 2023-12-13 13:43:00 -08:00
Lauryn Menard e8500fbdb0 support: Include sponsorship request for remote server support view.
Preparation for updating the sponsorship forms template to include
information about the latest sponsorship request if sponsorship is
pending.
2023-12-13 10:28:11 -08:00
Aman Agrawal 081d94c4e8 stripe: Add user and org metadata to stripe payments. 2023-12-13 08:13:33 -08:00
Aman Agrawal 0c99420ceb stripe: Don't approve sponsorship for customers on paid plan.
This would avoid us accidentally approving sponsorship for customers
on paid plan.
2023-12-13 08:13:33 -08:00
Tim Abbott 95f4b31ce7 billing: Don't require data to add to legacy plan. 2023-12-13 00:44:50 -08:00
Tim Abbott af83093a65 billing: Remove some stale TODOs. 2023-12-13 00:33:37 -08:00
Aman Agrawal 45a2f7eac1 portico: Pass requested sponsorship context to plan page. 2023-12-12 23:27:39 -08:00
Tim Abbott f281199d2f billing_session: Push nocoverage comments down a layer. 2023-12-12 22:03:24 -08:00
Aman Agrawal 63f4fc51de server_deactivate: Show error message for server on active plan. 2023-12-12 21:00:42 -08:00
Lauryn Menard aebafcc43f corporate: Show error page if mobile push data has not been uploaded.
Adds a template that displays an error message when the billing
or upgrade context for a remote server or remote realm raises a
MissingDataError.
2023-12-12 19:36:06 -08:00
Mateusz Mandera e515574b3e remote_billing: Add endpoint and a helper to make deactivation links.
This is a general link for logging into the billing system on behalf of
a server, but it's tied to the .contact_email and takes the user
straight to the /deactivate/ page via the next_page mechanism.
2023-12-12 13:31:59 -08:00
Prakhar Pratyush 4ad03804cf stripe: Add `sync_license_ledger...` for RemoteServerBillingSession.
This commit implements the 'sync_license_ledger_if_needed' method
for RemoteServerBillingSession.
2023-12-12 12:15:32 -08:00
Prakhar Pratyush 1d515a57cd stripe: Make 'sync_license_ledger_if_needed' abstract method.
This prep commit makes 'sync_license_ledger_if_needed'
function a 'BillingSession' abstract method.

We'll override the method for RemoteServerBillingSession
in the next commit.
2023-12-12 12:15:32 -08:00
Prakhar Pratyush 88fb3b735a stripe: Add 'get_last_ledger_for_automanaged_plan_if_exists' method.
This prep commit extracts out the code block that determines the
last license ledger for the customer plan having automanage_licenses
set to True into a new BillingSession method named
'get_last_ledger_for_automanaged_plan_if_exists'.

We'll be using this function while implementing the
'sync_license_ledger_if_needed' method for RemoteServerBillingSession.
2023-12-12 12:15:31 -08:00
Aman Agrawal fba49ca33d stripe: Implement various TODOs. 2023-12-12 11:45:14 -08:00
Aman Agrawal ccaef86e20 stripe: Fix manual licenses not being propagated to next plan.
We already calculate the correct `billed_licenses` early in the
function, so just used that to fix the bug where a legacy server
scheduled for upgrade doesn't respect the manual license count
set by the user.
2023-12-12 11:45:14 -08:00
Aman Agrawal 7587ee2289 Revert "stripe: Remove non-relevant context override."
This reverts commit 4bf018f09f.

While `payment_method` is attached to customer, the type of
payment method used is attached to plan.
2023-12-12 11:45:14 -08:00
Aman Agrawal 20a1037b92 stripe: Fix incorrect licenses at next renewal for legacy customers.
When a legacy plan is scheduled for an upgrade, licenses at
next renewal should reflect the licenses according to the next plan.
2023-12-12 09:30:17 -08:00
Aman Agrawal 4bf018f09f stripe: Remove non-relevant context override.
`payment_method` is attached to customer so we don't need to
override it here.
2023-12-12 09:30:17 -08:00
Aman Agrawal 689aa12fce stripe: Enforce min license for plan throughout.
I missed a some places to check on last pass:
* For automanaged licenses when the license updates.
* When plan is changed.
* When migrating existing customers to legacy plan.
2023-12-12 09:30:17 -08:00
Aman Agrawal 89a28f6577 stripe: Allow customers without a plan to upgrade.
I am not sure why I added this silly assert statement. Probably
related to legacy customers always having a plan.
2023-12-12 09:30:17 -08:00
Aman Agrawal c61275cab2 upgrade: Show sponsorship requested banner like billing page. 2023-12-12 09:30:17 -08:00
Aman Agrawal e829e52c56 stripe: Allow sponsorship pending user to upgrade to business plan. 2023-12-12 09:30:17 -08:00
Mateusz Mandera c1988a14a7 zilencer: Return can_push info at the push/notify endpoint.
This provides the remote server this information to refresh it on its
Realm attributes whenever it sends a push notification.

Fixes #27483.
2023-12-12 08:06:12 -08:00
Aman Agrawal eb92b31e1d stripe: Disable free trial for self hosted customers. 2023-12-11 13:23:49 -08:00
Aman Agrawal 23d712391e post_analytics: Migrate plan from server to realm after upgrade. 2023-12-11 13:23:49 -08:00
Aman Agrawal 64517a7ad3 stripe: Move migrate_customer_to_legacy_plan to `BillingSession`.
This will he helpful to call it for both remote realm and remote
server billing sessions.
2023-12-11 13:23:49 -08:00
Aman Agrawal 8e617f5df8 stripe: Fix customer charged for upgrade during free trial.
I accidentally free trials for both cloud and self hosted
enabled while testing, hence didn't catch it.

This mostly involves fixing `is_free_trial_offer_enabled` to
return the correct value and providing it the correct input.
2023-12-11 13:23:49 -08:00
Aman Agrawal df23701475 stripe: Rename add_server_to_legacy_plan.
This function will not also be used to migrate remote realms
to legacy plan.
2023-12-11 13:23:49 -08:00
Aman Agrawal a8fd350630 stripe: Use session specific method to create customer. 2023-12-11 13:23:49 -08:00
Lauryn Menard c2a76ccb3e support: Clean up template variables for remote server support. 2023-12-11 10:33:50 -08:00
Mateusz Mandera 7d62471d0b remote_realm: Plumb RemoteRealmBillingUser into BillingSession.
Adds the RemoteRealmBillingUser object to the BillingSession in the
views decorated by authenticated_remote_realm_management_endpoint.
2023-12-10 16:15:28 -08:00
Mateusz Mandera 423aebf98e remote_billing: Implement confirmation flow for RemoteRealm auth.
The way the flow goes now is this:
1. The user initiaties login via "Billing" in the gear menu.
2. That takes them to `/self-hosted-billing/` (possibly with a
   `next_page` param if we use that for some gear menu options).
3. The server queries the bouncer to give the user a link with a signed
   access token.
4. The user is redirected to that link (on `selfhosting.zulipchat.com`).
Now we have two cases, either the user is logging in for the first time
and already did in the past.
If this is the first time, we have:
5. The user is asked to fill in their email in a form that's shown,
   pre-filled with the value provided inside the signed access token.
   They POST this to the next endpoint.
6. The next endpoint sends a confirmation email to that address and asks
   the user to go check their email.
7. The user clicks the link in their email is taken to the
   from_confirmation endpoint.
8. Their initial RemoteBillingUser is created, a new signed link like in
   (3) is generated and they're transparently taken back to (4),
   where now that they have a RemoteBillingUser, they're handled
   just like a user who already logged in before:
If the user already logged in before, they go straight here:
9. "Confirm login" page - they're shown their information (email and
   full_name), can update
   their full name in the form if they want. They also accept ToS here
   if necessary. They POST this form back to
   the endpoint and finally have a logged in session.
10. They're redirected to billing (or `next_page`) now that they have
    access.
2023-12-10 16:15:28 -08:00
Aman Agrawal ce56e19d1c stripe: Separate activation of free trial for remote realm/server.
Add a separate setting to only enable free trial for remote
realm / server.
2023-12-10 15:18:01 -08:00
Aman Agrawal ccd60bc7e2 settings: Use original FREE_TRIAL_DAYS for cloud free trials.
* Renamed FREE_TRIAL_DAYS to CLOUD_FREE_TRIAL_DAYS.
* Used `cloud_free_trial_days` to get free trial days secret.
2023-12-10 15:18:01 -08:00
Aman Agrawal 34704daee7 stripe: Use a function to get free trial days. 2023-12-10 15:18:01 -08:00
Aman Agrawal ec86114330 stripe: Fix discounts for legacy server with upgrade scheduled.
We simply apply discount to both the plans.

Since the discount is saved in `customer.default_discount` it
will applied now to any future plans as well, even if customer
downgrades and the upgrades again.
2023-12-09 12:50:05 -08:00
Aman Agrawal 121e5ad3dc stripe: Extract function to get next plan for legacy customers. 2023-12-09 12:50:05 -08:00
Aman Agrawal e44f3d448d stripe: Use `next_plan` instead of `new_plan` for legacy upgrades. 2023-12-09 12:50:05 -08:00
Aman Agrawal 5d3eafcdd4 support: Fix error on discount applied on legacy server.
This is for legacy server **not** scheduled for an upgrade.
2023-12-09 12:50:05 -08:00
Aman Agrawal dca7e654ca billing: Enforce min license for plan on upgrade and billing page. 2023-12-09 12:50:05 -08:00
Mateusz Mandera abdfdeffe4 remote_billing: Implement confirmation flow for legacy servers.
For the last form (with Full Name and ToS consent field), this pretty
shamelessly re-uses and directly renders the
corporate/remote_realm_billing_finalize_login_confirmation.html
template. That's probably good in terms of re-use, but calls for a
clean-up commit that will generalize the name of this template and the
classes/ids in the HTML.
2023-12-08 23:49:10 -08:00
Prakhar Pratyush bf4fdbff12 stripe: Update LicenseLedger for remote realms.
When a remote server uploads statistics, we update the
LicenseLedger using the audit logs uploaded.

We iterate over the RemoteRealmAuditlog data for the concerned
realm starting from the event_time of the last LicenseLedger
created for that customer and update the ledger based on each event.
2023-12-08 12:58:21 -08:00
Prakhar Pratyush ed9b0d330d stripe: Raise 'MissingDataError' while fetching license count.
If the RemoteRealmAuditLog has stale data, it means the server
stopped or never uploaded data. We raise MissingDataError in such
cases when a user action led to calculating licenses count from
stale data.
2023-12-08 12:58:21 -08:00