Commit Graph

229 Commits

Author SHA1 Message Date
Prakhar Pratyush c9d25b2a95 stripe: Redirect to /plans if plans downgraded on /billing page visit.
When a customer with plan's status 'DOWNGRADE_AT_END_OF_FREE_TRIAL'
visits /billing page on the free-trial end date before the invoice
cron runs, the 'make_end_of_cycle_updates_if_needed' downgrades the
plan.

Earlier, when such a customer visited /billing page in this time window
it resulted in an assertion error.

This commit fixes the incorrect behaviour by redirecting to '/plans'
page in such cases.
2024-03-19 09:25:07 -07:00
Aman Agrawal e10f81197f upgrade: Fix allowed free trails for ended legacy plans on server.
If the remote realm registered after the legacy plan on server
ENDED, we never migrate the plan to the remote realm. So, we need
to check the server of remote realm whenever we are check remote
realm for legacy plan.
2024-03-15 08:38:46 -07:00
Aman Agrawal c84b9cbc97 upgrade: Allow payment by invoice. 2024-03-14 16:43:52 -07:00
Alex Vandiver d460743705 realm_activity: Correct the "messages sent" column. 2024-03-11 14:39:03 -07:00
Lauryn Menard 4e1e490b40 cloud-support: Display most recent sponsorship request information.
Refactors the Cloud support view to pass in any sponsorship or
discount information about the Customer object for the realm,
which allows us to display any information submitted in a
sponsorship request.
2024-03-08 09:40:43 -08:00
Lauryn Menard ef11619e73 support: Clean up options for realm plan_type and org_type.
Removes adding get_org_type_display_name to support context as
its use was removed in commit f25230c7d4.
2024-03-08 09:40:43 -08:00
Lauryn Menard f3906f4a2f remote-support: Add ability to deactivate and reactivate remote servers. 2024-03-07 11:51:00 -08:00
Lauryn Menard 666041e480 remote-support: Show deactivated servers in search results.
The remote support view now returns results for deactivated remote
servers with those results sorted to the end and formatted to
visually stand out.

Forms to change sponsorship and discount fields on the customer
for the remote server or realm are not shown, but the data stored
on the customer object is shown, including any sponsorship request
information (if the customer had a sponsorship request pending when
it was deactivated).

Forms to schedule a plan are also not shown for deactivated servers
and their associated remote realms.

Forms and information for any current plan or scheduled plan, for
either the deactivated remote server or its associated remote
realms, are shown so that support staff can update those plans if
necessary.
2024-03-01 14:11:19 -08:00
Lauryn Menard 26e305e27d remote-support: Show remote realm matches if deactivated.
As a follow-up to commit d66b7ad853, where we send internal emails
when an active paid plan is on a locally deleted remote realm, we
need search queries in the remote support view to return results
for these deactivated remote realms, instead of excluding them.
2024-03-01 09:30:31 -08:00
Anders Kaseorg 570f3dd447 python: Reformat with Ruff formatter.
https://docs.astral.sh/ruff/formatter/

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-02-29 17:07:16 -08:00
Lauryn Menard 1914b881d9 remote-support: Add ability to search by billing user email. 2024-02-23 13:21:54 -08:00
Lauryn Menard 1f72ab5133 remote-support: Show active billing user emails. 2024-02-23 13:21:54 -08:00
Aman Agrawal bddb44eebf stripe: Disable free trial for legacy customer with ended plan.
This ensures that customer who had legacy plan any time in the past
cannot avail free trial.
2024-02-21 21:40:47 -08:00
Lauryn Menard 907c209296 remote-support: Add search results for remote server/realm uuid. 2024-02-21 12:40:34 -08:00
Lauryn Menard 1eca9b3f6e remote-support: Return server results for realms with host match.
Checks for remote realm hosts that match the search query. Adds a
database query to getting the initial search results.
2024-02-21 12:40:34 -08:00
Lauryn Menard aec02d18af remote-support: Improve getting remote realm/server data.
Only get the customer information once from the database.

Extract logic for any next plan (either scheduled or an offer) data
into a separate function and do not hit database twice when getting
the number of licenses at the next plan renewal.
2024-02-21 12:40:34 -08:00
Lauryn Menard 8189b94a70 remote-support: Improve search results in view code.
Removes prefetch of remote realms on the remote server query
because, by excluding the system bot realm when this is referenced,
we end up hitting the database again.

Strips whitespace from query string and makes a few small updates
for readability.
2024-02-21 12:40:34 -08:00
Mateusz Mandera ea863bab5b remote_billing: Remove code migrating Legacy plan from server to realms.
We no longer want to migrate Legacy plans from server to realms, since
Legacy plans are not really a thing in the original sense anymore, since
February 15th.

Now they're just a tool to give temporary extensions of access to the
push notification service for users, when needed. And as such, it makes
no sense to migrate like that.

The remaining code in this function is for migrating (any) plan from the
server object to the realm object, if the server has just a single
realm.
2024-02-21 11:10:45 -08:00
Mateusz Mandera 834dbd552b remote_billing: Make handle_customer_migration_... more robust.
The logic in the case where there's only one realm and the function
tries to migrate the server's plan to it, had two main unhandled edge
cases that would throw exceptions:
1.
```
        remote_realm = RemoteRealm.objects.get(
            uuid=realm_uuids[0], plan_type=RemoteRealm.PLAN_TYPE_SELF_MANAGED
        )
```

This could throw an exception if the RemoteRealm exists, but has an
active e.g. Legacy plan. Then there'd be no object matching the
plan_type in the query, raising RemoteRealm.DoesNotExist.

2. If the RemoteRealm had e.g. a Legacy plan in the past, that's now
   expired, then it'd have a Customer object. Meaning that the attempt
   to move the server's customer to the realm:
   `server_plan.customer = remote_realm_customer`
   would trigger an IntegrityError since a RemoteRealm can't have two
   Customer objects.

In simple cases the situation in (2) can still be easily migrated, by
moving the plan from the server's customer to the realm's customer.
2024-02-20 16:02:03 -08:00
Lauryn Menard 68f02da82e installation-activity: Fix ARR value in total row.
In commit ff8552269d, when we moved the links to the first column
of the activity charts, we missed updating the column for the ARR
total.
2024-02-20 15:57:06 -08:00
Anders Kaseorg a4938d3760 page_params: Parse page_params and state_data with Zod.
This establishes a runtime check that their types continue to reflect
reality going forward.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-02-17 00:02:38 -08:00
Lauryn Menard 05b5295f18 remote-activity: Fix broken support links.
In commit 230294c, the logic for creating the support links in the
remote activity chart were broken. Updates the constants so that
the links have the correct server information for the search query.
2024-02-16 14:49:34 -08:00
Lauryn Menard 230294cfb3 remote-activity: Add column for remote server or realm creation date.
Expands the main query for remote servers to get the audit log
event datetime for when the server was created/registered.

The remote realm object has a field for when the remote realm
was created on the remote server.
2024-02-15 10:29:12 -08:00
Lauryn Menard b275e9c4d6 stripe: Add billing portal for customer name and address.
Adds a link on the upgrade and billing pages that opens a stripe
billing portal for the customer to update their name and address
that will appear on invoices and receipts.

On the billing page, updating the credit card information will
no longer update the customer billing address, since they can
now do this directly through the billing portal. To be consistent
with the credit card form on the upgrade page, we still require
inputting a billing address for the card.

Note that, once an invoice is paid/complete, then changes to the
customer's name and address will not be applied to those invoices.
2024-02-13 14:18:38 -08:00
Aman Agrawal 8cba101e05 support: Add button to delete configured fixed next plan.
This will help us modify the configured plan if we need to.
2024-02-13 09:40:53 -08:00
Aman Agrawal 7b33d660eb billing: Rename self-managed to free. 2024-02-12 21:25:19 -08:00
Aman Agrawal 7ca85bed71 stripe: Fix $0 invoices being generated on upgrade.
Instead of charging the customer using the attached payment
method and then creating the invoice, we create an invoice and
force an immediate payment for the invoice via the attached
payment method.
2024-02-12 15:15:56 -08:00
Prakhar Pratyush 2055dfa83e support: Add support to configure fixed-price plan with pay-by-invoice.
* Manually create & send invoice
* Configure a fixed-price plan with sent invoice-id.
* When customer pays, upgrade them to concerned plan.
2024-02-06 18:43:23 -08:00
Lauryn Menard 5479053a9f remote-support: Add server data for last audit log update time.
This is useful in the support view in case the audit log data is
stale and user counts are not updated for billing.

Also, renames formatting function for optional datetimes that is
used in the support and activity views/charts. And instead of
showing these datetime strings in the eastern US timezone, we
now show and label them as UTC.
2024-02-06 18:09:45 -08:00
Aman Agrawal de33aa4b7b stripe: Add page to show list of past customer invoices. 2024-02-04 17:38:24 -08:00
Aman Agrawal 130aecbf9e stripe: Extract method to get org_name. 2024-02-01 09:29:08 -08:00
Lauryn Menard ff8552269d activity: Move links columns to be first in chart.
Moves links in installation and remote server activity charts
to be the first column.
2024-02-01 09:17:26 -08:00
Lauryn Menard afe0161bc2 remote-activity: Add column for rate paid on displayed plan.
Adds a column with the percentage rate that the remote server
or realm is paying on the displayed plan.

We display 0% for community plans that are 100% sponsored.
For legacy plans or plans with a scheduled downgrade, we
display a placeholder, "---". Otherwise, the value is
calculated from the CustomerPlan discount field.
2024-01-31 16:08:15 -08:00
Prakhar Pratyush 82da6abb24 corporate: Restrict free-trial when fixed-price plan is configured.
When fixed-price plan is configured:
* Don't show 'free-trial for 30 days' button on plans page.
* Remove free-trial related texts from /upgrade page.
2024-01-31 12:25:31 -08:00
Lauryn Menard 12ec133224 templates: Move billing templates to /templates/corporate/billing. 2024-01-30 10:06:48 -08:00
Lauryn Menard 916892e437 templates: Move support templates to /templates/corporate/support.
Also, makes small updates to `next_plan_forms_support.html`.
Removes unneeded "btn" and "btn-default" classes, and updates
the placeholder text for the input as not marked for translation.
2024-01-30 10:06:48 -08:00
Lauryn Menard efd0d689fc templates: Move activity templates to /templates/corporate/activity.
Also, renames `ad_hoc_query.html` to `activity_table.html`,
`realm_summary_table.html` to `installation_activity_table.html`,
and `activity_details_template.html` to `activity.html`.

Removes the style attribute in the installation activity template
and uses a CSS class, "installation-activity-header", to center the
h3 and p tags instead. This removes an exception from the custom
lint check.
2024-01-30 10:06:48 -08:00
Lauryn Menard df2f4b6469 corporate: Move support and activity views to /corporate.
View functions in `analytics/views/support.py` are moved to
`corporate/views/support.py`.

Shared activity functions in `analytics/views/activity_common.py`
are moved to `corporate/lib/activity.py`, which was also renamed
from `corporate/lib/analytics.py`.
2024-01-30 10:06:48 -08:00
Anders Kaseorg 93198a19ed requirements: Upgrade Python requirements.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
2024-01-29 10:41:54 -08:00
Mateusz Mandera 4ccddda074 remote_billing: Pass language argument to send_email calls.
This was an oversight in the original implementation.
2024-01-22 18:31:06 -08:00
Mateusz Mandera 649b4885e8 remote_billing: Add rate-limiting for confirmation email sending.
These should be rate-limited by both IP using our regular
sends_email_by_ip bucket as well as by server, using a new bucket
dedicated to this.
2024-01-18 12:06:16 -08:00
Mateusz Mandera 3a12e41c35 remote_billing: Fix handle_customer_migration_from_server_to_realms.
This was a bug from 4715a058b0 where this
was just incorrectly called. get_realms_info_for_push_bouncer() is a
function meant to be called on a self-hosted server - and this
handle_... call happens on the bouncer. Therefore this returns all
zulipchat realms in product.

With the way, handle_... is being called right now, there's no reason
for it to have an argument for passing a list of realms. It should just
fetch the relevant RemoteRealm entries  by itself, given the server arg.
2024-01-12 15:28:41 -08:00
Mateusz Mandera a5538636f0 remote_billing: Remove stale comment about ToS in the server flow.
That comment is stale, now we just do a proper tos_consent check, based
on the last. version the user consented to.
2024-01-12 08:39:48 -08:00
Mateusz Mandera 63254f18ec remote_billing: Handle two confirmation links for same user correctly.
The bug was that a user could do the first part of the flow twice,
receiving two confirmation links, before finishing signup. Then they
could use the first link, followed by the second, which would case an
IntegrityError due to trying to create the RemoteRealmBillingUser
for the second time.

When the second link gets clicked, we should just transparently redirect
the user further into the flow so that they can proceed.
2024-01-12 08:39:48 -08:00
Prakhar Pratyush 4715a058b0 migrate_customers: Migrate customer from server to realms during login.
Earlier, the 'handle_customer_migration_from_server_to_realms'
function was called during the send analytics step.

It resulted in an error for customers having multiple Zulip servers,
one for testing and the others for not-testing, sharing a
push bouncer registration.

The migration step when run in a test instance caused customers to
have their legacy plan migrated to a test realm, resulting in them
losing their legacy plan.

This commit moves the migration step to run during plan management
login step. This reduces the chances of losing legacy
plan as we expect them to only verify that 8.0 upgrade works and
not bother trying to login to plan management from their test instance.
2024-01-05 12:02:54 -08:00
Prakhar Pratyush a03f9078e5 test_stripe: Add migrate customer from server to realms E2E test. 2024-01-02 11:20:56 -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
Karl Stolley a37354f92a corporate: Add a Basic plan. 2023-12-20 23:09:21 -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 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